Encode information for ASTC/PVRTC blocks in ResourceFormat

This commit is contained in:
baldurk committed 2026-07-27 11:22:02 +01:00
1 parent e434ebbbba
commit 63b38ef8b4
5 files changed
+813 -189

No files matched your search

+179 -1
View File
@@ -27,6 +27,7 @@
#include "apidefs.h"
#include "rdcarray.h"
#include "rdcpair.h"
#include "replay_enums.h"
#include "resourceid.h"
#include "stringise.h"
@@ -400,6 +401,161 @@ Invalid values will result in 1 being set.
return false;
}
DOCUMENT(R"(Set PVRTC properties. See :meth:`PVRTCVersion` and :meth:`PVRTCBpp`.
Invalid values will result in undefined format properties. Has no effect if the format is
not already set to be PVRTC.
:param int version: The PVRTC version.
:param int bpp: The bits per pixel of the PVRTC blocks.
)");
void SetPVRTC(uint32_t version, uint32_t bpp)
{
if(type != ResourceFormatType::PVRTC)
return;
flags &= ~ResourceFormat_PVRTC_Mask;
flags |= (version == 1) ? ResourceFormat_PVRTC_v1 : ResourceFormat_PVRTC_v2;
flags |= (bpp == 2) ? ResourceFormat_PVRTC_8x4_2bpp : ResourceFormat_PVRTC_4x4_4bpp;
}
DOCUMENT(R"(For PVRTC formats, return the version of PVRTC used either 1 or 2.
Will return 0 if the format is not PVRTC.
:return: The version of the current PVRTC format
:rtype: int
)");
uint32_t PVRTCVersion() const
{
if(type != ResourceFormatType::PVRTC)
return 0;
return (flags & ResourceFormat_PVRTC_v1) ? 1 : 2;
}
DOCUMENT(R"(For PVRTC formats, return the bits per pixel rate either 2 or 4. This can also be
thought of as the block shape since each block is 64-bit. 2bpp is 8x4 and 4bpp is 4x4.
Will return 0 if the format is not PVRTC.
:return: The bpp of the current PVRTC format
:rtype: int
)");
uint32_t PVRTCBpp() const
{
if(type != ResourceFormatType::PVRTC)
return 0;
return (flags & ResourceFormat_PVRTC_8x4_2bpp) ? 2 : 4;
}
DOCUMENT(R"(Set 2D ASTC block properties. See :meth:`ASTCDimension` and :meth:`ASTC2DBlock`.
Invalid values will result in undefined format properties. Has no effect if the format is
not already set to be ASTC.
:param Tuple[int, int] block2D: The 2D block shape.
)");
void SetASTC2D(const rdcpair<uint32_t, uint32_t> &block2D)
{
if(type != ResourceFormatType::ASTC)
return;
flags &= ~ResourceFormat_ASTC_Mask;
flags |= uint16_t(block2D.first << ResourceFormat_ASTC_2DWidth_Shift);
flags |= uint16_t(block2D.second << ResourceFormat_ASTC_2DHeight_Shift);
}
DOCUMENT(R"(Set 3D ASTC block properties. See :meth:`ASTCDimension` and :meth:`ASTC3DBlock`.
Invalid values will result in undefined format properties. Has no effect if the format is
not already set to be ASTC.
:param Tuple[int, int, int] block3D: The 3D block shape.
)");
void SetASTC3D(const rdcfixedarray<uint32_t, 3> &block3D)
{
if(type != ResourceFormatType::ASTC)
return;
flags &= ~ResourceFormat_ASTC_Mask;
flags |= ResourceFormat_ASTC_3D;
uint32_t w = block3D[0] - ResourceFormat_ASTC_3D_Base;
uint32_t h = block3D[1] - ResourceFormat_ASTC_3D_Base;
uint32_t d = block3D[2] - ResourceFormat_ASTC_3D_Base;
w <<= ResourceFormat_ASTC_3DWidth_Shift;
h <<= ResourceFormat_ASTC_3DHeight_Shift;
d <<= ResourceFormat_ASTC_3DDepth_Shift;
w &= ResourceFormat_ASTC_3DWidth_Mask;
h &= ResourceFormat_ASTC_3DHeight_Mask;
d &= ResourceFormat_ASTC_3DDepth_Mask;
flags |= uint16_t(w);
flags |= uint16_t(h);
flags |= uint16_t(d);
}
DOCUMENT(R"(For ASTC formats, return the dimension of the block either 2 or 3.
Will return 0 if the format is not ASTC.
:return: The dimension of the blocks in the current ASTC format
:rtype: int
)");
uint32_t ASTCDimension() const
{
if(type != ResourceFormatType::ASTC)
return 0;
return (flags & ResourceFormat_ASTC_3D) ? 3 : 2;
}
DOCUMENT(R"(For 2D ASTC formats, return the block shape.
Will return all 0s if the format is not ASTC or is not 2D. See :meth:`ASTCDimension`.
:return: The block shape if the format is 2D ASTC
:rtype: Tuple[int, int]
)");
rdcpair<uint32_t, uint32_t> ASTC2DBlock() const
{
if(type != ResourceFormatType::ASTC)
return {0, 0};
return {
uint32_t((flags & ResourceFormat_ASTC_2DWidth_Mask) >> ResourceFormat_ASTC_2DWidth_Shift),
uint32_t((flags & ResourceFormat_ASTC_2DHeight_Mask) >> ResourceFormat_ASTC_2DHeight_Shift),
};
}
DOCUMENT(R"(For 3D ASTC formats, return the block shape.
Will return all 0s if the format is not ASTC or is not 3D. See :meth:`ASTCDimension`.
:return: The block shape if the format is 3D ASTC
:rtype: Tuple[int, int, int]
)");
rdcfixedarray<uint32_t, 3> ASTC3DBlock() const
{
if(type != ResourceFormatType::ASTC)
return {0, 0};
uint32_t w = (flags & ResourceFormat_ASTC_3DWidth_Mask) >> ResourceFormat_ASTC_3DWidth_Shift;
uint32_t h = (flags & ResourceFormat_ASTC_3DHeight_Mask) >> ResourceFormat_ASTC_3DHeight_Shift;
uint32_t d = (flags & ResourceFormat_ASTC_3DDepth_Mask) >> ResourceFormat_ASTC_3DDepth_Shift;
return {
ResourceFormat_ASTC_3D_Base + w,
ResourceFormat_ASTC_3D_Base + h,
ResourceFormat_ASTC_3D_Base + d,
};
}
DOCUMENT(R"(Return the size of a single element in this format, usually a pixel. For regular sized
formats this is just :data:`compByteWidth` times :data:`compCount`, for special packed formats it's
the tightly packed size of a single element, with no padding.
@@ -454,7 +610,7 @@ texel.
case ResourceFormatType::YUV12:
case ResourceFormatType::YUV16: return compCount * 2;
case ResourceFormatType::PVRTC:
return 8; // our representation can't differentiate 2bpp from 4bpp, so guess
return 8; // PVRTC is always 64 bits per block, either 4x4 on 4bpp or 8x4 on 2bpp
}
return 0;
@@ -487,6 +643,7 @@ private:
enum
{
ResourceFormat_BGRA = 0x001,
ResourceFormat_ASTC_3D = 0x0002,
ResourceFormat_444 = 0x004,
ResourceFormat_422 = 0x008,
@@ -496,6 +653,27 @@ private:
ResourceFormat_2Planes = 0x020,
ResourceFormat_3Planes = 0x040,
ResourceFormat_Planes_Mask = 0x060,
ResourceFormat_PVRTC_v1 = 0x0100,
ResourceFormat_PVRTC_v2 = 0x0200,
ResourceFormat_PVRTC_4x4_4bpp = 0x0400,
ResourceFormat_PVRTC_8x4_2bpp = 0x0800,
ResourceFormat_PVRTC_Mask = 0x0f00,
ResourceFormat_ASTC_2DWidth_Shift = 8,
ResourceFormat_ASTC_2DWidth_Mask = (0xf << ResourceFormat_ASTC_2DWidth_Shift),
ResourceFormat_ASTC_2DHeight_Shift = 12,
ResourceFormat_ASTC_2DHeight_Mask = (0xf << ResourceFormat_ASTC_2DHeight_Shift),
ResourceFormat_ASTC_3D_Base = 3,
ResourceFormat_ASTC_3DWidth_Shift = 10,
ResourceFormat_ASTC_3DWidth_Mask = (0x3 << ResourceFormat_ASTC_3DWidth_Shift),
ResourceFormat_ASTC_3DHeight_Shift = 12,
ResourceFormat_ASTC_3DHeight_Mask = (0x3 << ResourceFormat_ASTC_3DHeight_Shift),
ResourceFormat_ASTC_3DDepth_Shift = 14,
ResourceFormat_ASTC_3DDepth_Mask = (0x3 << ResourceFormat_ASTC_3DDepth_Shift),
ResourceFormat_ASTC_Mask = 0xff00,
};
uint16_t flags;