ASTC textures;

I like typing numbers.
This commit is contained in:
bjorn 2019-06-09 09:11:29 -07:00
parent 0b5c609264
commit b0a7d5c122
4 changed files with 356 additions and 214 deletions

View File

@ -174,6 +174,20 @@ const char* TextureFormats[] = {
[FORMAT_DXT1] = "dxt1",
[FORMAT_DXT3] = "dxt3",
[FORMAT_DXT5] = "dxt5",
[FORMAT_ASTC_4x4] = "astc4x4",
[FORMAT_ASTC_5x4] = "astc5x4",
[FORMAT_ASTC_5x5] = "astc5x5",
[FORMAT_ASTC_6x5] = "astc6x5",
[FORMAT_ASTC_6x6] = "astc6x6",
[FORMAT_ASTC_8x5] = "astc8x5",
[FORMAT_ASTC_8x6] = "astc8x6",
[FORMAT_ASTC_8x8] = "astc8x8",
[FORMAT_ASTC_10x5] = "astc10x5",
[FORMAT_ASTC_10x6] = "astc10x6",
[FORMAT_ASTC_10x8] = "astc10x8",
[FORMAT_ASTC_10x10] = "astc10x10",
[FORMAT_ASTC_12x10] = "astc12x10",
[FORMAT_ASTC_12x12] = "astc12x12",
NULL
};

View File

@ -32,6 +32,191 @@ static size_t getPixelSize(TextureFormat format) {
// Modified from ddsparse (https://bitbucket.org/slime73/ddsparse)
static bool parseDDS(uint8_t* data, size_t size, TextureData* textureData) {
enum {
DDPF_ALPHAPIXELS = 0x000001,
DDPF_ALPHA = 0x000002,
DDPF_FOURCC = 0x000004,
DDPF_RGB = 0x000040,
DDPF_YUV = 0x000200,
DDPF_LUMINANCE = 0x020000
};
typedef enum D3D10ResourceDimension {
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
} D3D10ResourceDimension;
typedef enum DXGIFormat {
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99
} DXGIFormat;
typedef struct DDSPixelFormat {
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t rgbBitCount;
uint32_t rBitMask;
uint32_t gBitMask;
uint32_t bBitMask;
uint32_t aBitMask;
} DDSPixelFormat;
typedef struct DDSHeader {
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth;
uint32_t mipMapCount;
uint32_t reserved[11];
DDSPixelFormat format;
uint32_t caps1;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
} DDSHeader;
typedef struct DDSHeader10 {
DXGIFormat dxgiFormat;
D3D10ResourceDimension resourceDimension;
uint32_t miscFlag;
uint32_t arraySize;
uint32_t reserved;
} DDSHeader10;
if (size < sizeof(uint32_t) + sizeof(DDSHeader) || *(uint32_t*) data != FOUR_CC('D', 'D', 'S', ' ')) {
return false;
}
@ -134,16 +319,33 @@ static bool parseDDS(uint8_t* data, size_t size, TextureData* textureData) {
return true;
}
static bool parseKTX(uint8_t* d, size_t size, TextureData* textureData) {
static bool parseKTX(uint8_t* bytes, size_t size, TextureData* textureData) {
typedef struct {
uint8_t magic[12];
uint32_t endianness;
uint32_t glType;
uint32_t glTypeSize;
uint32_t glFormat;
uint32_t glInternalFormat;
uint32_t glBaseInternalFormat;
uint32_t pixelWidth;
uint32_t pixelHeight;
uint32_t pixelDepth;
uint32_t numberOfArrayElements;
uint32_t numberOfFaces;
uint32_t numberOfMipmapLevels;
uint32_t bytesOfKeyValueData;
} KTXHeader;
union {
uint8_t* u8;
uint32_t* u32;
KTXHeader* ktx;
} data = { .u8 = d };
} data = { .u8 = bytes };
uint8_t magic[] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
if (size < sizeof(magic) || memcmp(data.ktx->header, magic, sizeof(magic))) {
if (size < sizeof(magic) || memcmp(data.ktx->magic, magic, sizeof(magic))) {
return false;
}
@ -181,9 +383,62 @@ static bool parseKTX(uint8_t* d, size_t size, TextureData* textureData) {
return true;
}
static bool parseASTC(uint8_t* bytes, size_t size, TextureData* textureData) {
typedef struct {
uint32_t magic;
uint8_t blockX;
uint8_t blockY;
uint8_t blockZ;
uint8_t width[3];
uint8_t height[3];
uint8_t depth[3];
} ASTCHeader;
union {
uint8_t* u8;
uint32_t* u32;
ASTCHeader* astc;
} data = { .u8 = bytes };
uint32_t magic = 0x5ca1ab13;
if (size <= sizeof(*data.astc) || data.astc->magic != magic) {
return false;
}
uint32_t bx = data.astc->blockX, by = data.astc->blockY, bz = data.astc->blockZ;
if (bx == 4 && by == 4 && bz == 1) { textureData->format = FORMAT_ASTC_4x4; }
else if (bx == 5 && by == 4 && bz == 1) { textureData->format = FORMAT_ASTC_5x4; }
else if (bx == 5 && by == 5 && bz == 1) { textureData->format = FORMAT_ASTC_5x5; }
else if (bx == 6 && by == 5 && bz == 1) { textureData->format = FORMAT_ASTC_6x5; }
else if (bx == 6 && by == 6 && bz == 1) { textureData->format = FORMAT_ASTC_6x6; }
else if (bx == 8 && by == 5 && bz == 1) { textureData->format = FORMAT_ASTC_8x5; }
else if (bx == 8 && by == 6 && bz == 1) { textureData->format = FORMAT_ASTC_8x6; }
else if (bx == 8 && by == 8 && bz == 1) { textureData->format = FORMAT_ASTC_8x8; }
else if (bx == 10 && by == 5 && bz == 1) { textureData->format = FORMAT_ASTC_10x5; }
else if (bx == 10 && by == 6 && bz == 1) { textureData->format = FORMAT_ASTC_10x6; }
else if (bx == 10 && by == 8 && bz == 1) { textureData->format = FORMAT_ASTC_10x8; }
else if (bx == 10 && by == 10 && bz == 1) { textureData->format = FORMAT_ASTC_10x10; }
else if (bx == 12 && by == 10 && bz == 1) { textureData->format = FORMAT_ASTC_12x10; }
else if (bx == 12 && by == 12 && bz == 1) { textureData->format = FORMAT_ASTC_12x12; }
else { lovrThrow("Unsupported ASTC format %dx%dx%d", bx, by, bz); }
textureData->width = data.astc->width[0] + (data.astc->width[1] << 8) + (data.astc->width[2] << 16);
textureData->height = data.astc->height[0] + (data.astc->height[1] << 8) + (data.astc->height[2] << 16);
vec_push(&textureData->mipmaps, ((Mipmap) {
.width = textureData->width,
.height = textureData->height,
.data = data.astc + 1,
.size = size - sizeof(*data.astc)
}));
return true;
}
TextureData* lovrTextureDataInit(TextureData* textureData, uint32_t width, uint32_t height, uint8_t value, TextureFormat format) {
lovrAssert(width > 0 && height > 0, "TextureData dimensions must be positive");
lovrAssert(format != FORMAT_DXT1 && format != FORMAT_DXT3 && format != FORMAT_DXT5, "Blank TextureData cannot be compressed");
lovrAssert(format < FORMAT_DXT1, "Blank TextureData cannot be compressed");
size_t pixelSize = getPixelSize(format);
size_t size = width * height * pixelSize;
textureData->width = width;
@ -208,6 +463,10 @@ TextureData* lovrTextureDataInitFromBlob(TextureData* textureData, Blob* blob, b
textureData->source = blob;
lovrRetain(blob);
return textureData;
} else if (parseASTC(blob->data, blob->size, textureData)) {
textureData->source = blob;
lovrRetain(blob);
return textureData;
}
int width, height;

View File

@ -24,7 +24,21 @@ typedef enum {
FORMAT_D24S8,
FORMAT_DXT1,
FORMAT_DXT3,
FORMAT_DXT5
FORMAT_DXT5,
FORMAT_ASTC_4x4,
FORMAT_ASTC_5x4,
FORMAT_ASTC_5x5,
FORMAT_ASTC_6x5,
FORMAT_ASTC_6x6,
FORMAT_ASTC_8x5,
FORMAT_ASTC_8x6,
FORMAT_ASTC_8x8,
FORMAT_ASTC_10x5,
FORMAT_ASTC_10x6,
FORMAT_ASTC_10x8,
FORMAT_ASTC_10x10,
FORMAT_ASTC_12x10,
FORMAT_ASTC_12x12
} TextureFormat;
typedef struct {
@ -53,209 +67,3 @@ Color lovrTextureDataGetPixel(TextureData* textureData, uint32_t x, uint32_t y);
void lovrTextureDataSetPixel(TextureData* textureData, uint32_t x, uint32_t y, Color color);
bool lovrTextureDataEncode(TextureData* textureData, const char* filename);
void lovrTextureDataDestroy(void* ref);
// DDS structs (modified from ddsparse <https://bitbucket.org/slime73/ddsparse>)
typedef enum DDPF {
DDPF_ALPHAPIXELS = 0x000001,
DDPF_ALPHA = 0x000002,
DDPF_FOURCC = 0x000004,
DDPF_RGB = 0x000040,
DDPF_YUV = 0x000200,
DDPF_LUMINANCE = 0x020000
} DDPF;
typedef enum D3D10ResourceDimension {
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
} D3D10ResourceDimension;
typedef enum DXGIFormat {
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99
} DXGIFormat;
typedef struct DDSPixelFormat {
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t rgbBitCount;
uint32_t rBitMask;
uint32_t gBitMask;
uint32_t bBitMask;
uint32_t aBitMask;
} DDSPixelFormat;
typedef struct DDSHeader {
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth;
uint32_t mipMapCount;
uint32_t reserved[11];
DDSPixelFormat format;
uint32_t caps1;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
} DDSHeader;
typedef struct DDSHeader10 {
DXGIFormat dxgiFormat;
D3D10ResourceDimension resourceDimension;
uint32_t miscFlag;
uint32_t arraySize;
uint32_t reserved;
} DDSHeader10;
// KTX
typedef struct {
uint8_t header[12];
uint32_t endianness;
uint32_t glType;
uint32_t glTypeSize;
uint32_t glFormat;
uint32_t glInternalFormat;
uint32_t glBaseInternalFormat;
uint32_t pixelWidth;
uint32_t pixelHeight;
uint32_t pixelDepth;
uint32_t numberOfArrayElements;
uint32_t numberOfFaces;
uint32_t numberOfMipmapLevels;
uint32_t bytesOfKeyValueData;
} KTXHeader;

View File

@ -143,6 +143,21 @@ static GLenum convertTextureFormat(TextureFormat format) {
case FORMAT_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
case FORMAT_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case FORMAT_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
case FORMAT_ASTC_4x4:
case FORMAT_ASTC_5x4:
case FORMAT_ASTC_5x5:
case FORMAT_ASTC_6x5:
case FORMAT_ASTC_6x6:
case FORMAT_ASTC_8x5:
case FORMAT_ASTC_8x6:
case FORMAT_ASTC_8x8:
case FORMAT_ASTC_10x5:
case FORMAT_ASTC_10x6:
case FORMAT_ASTC_10x8:
case FORMAT_ASTC_10x10:
case FORMAT_ASTC_12x10:
case FORMAT_ASTC_12x12:
return GL_RGBA;
default: lovrThrow("Unreachable");
}
}
@ -167,6 +182,20 @@ static GLenum convertTextureFormatInternal(TextureFormat format, bool srgb) {
case FORMAT_DXT1: return srgb ? GL_COMPRESSED_SRGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
case FORMAT_DXT3: return srgb ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case FORMAT_DXT5: return srgb ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
case FORMAT_ASTC_4x4: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 : GL_COMPRESSED_RGBA_ASTC_4x4;
case FORMAT_ASTC_5x4: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 : GL_COMPRESSED_RGBA_ASTC_5x4;
case FORMAT_ASTC_5x5: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 : GL_COMPRESSED_RGBA_ASTC_5x5;
case FORMAT_ASTC_6x5: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 : GL_COMPRESSED_RGBA_ASTC_6x5;
case FORMAT_ASTC_6x6: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 : GL_COMPRESSED_RGBA_ASTC_6x6;
case FORMAT_ASTC_8x5: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 : GL_COMPRESSED_RGBA_ASTC_8x5;
case FORMAT_ASTC_8x6: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 : GL_COMPRESSED_RGBA_ASTC_8x6;
case FORMAT_ASTC_8x8: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 : GL_COMPRESSED_RGBA_ASTC_8x8;
case FORMAT_ASTC_10x5: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 : GL_COMPRESSED_RGBA_ASTC_10x5;
case FORMAT_ASTC_10x6: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 : GL_COMPRESSED_RGBA_ASTC_10x6;
case FORMAT_ASTC_10x8: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 : GL_COMPRESSED_RGBA_ASTC_10x8;
case FORMAT_ASTC_10x10: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 : GL_COMPRESSED_RGBA_ASTC_10x10;
case FORMAT_ASTC_12x10: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 : GL_COMPRESSED_RGBA_ASTC_12x10;
case FORMAT_ASTC_12x12: return srgb ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 : GL_COMPRESSED_RGBA_ASTC_12x12;
default: lovrThrow("Unreachable");
}
}
@ -191,6 +220,20 @@ static GLenum convertTextureFormatType(TextureFormat format) {
case FORMAT_DXT1:
case FORMAT_DXT3:
case FORMAT_DXT5:
case FORMAT_ASTC_4x4:
case FORMAT_ASTC_5x4:
case FORMAT_ASTC_5x5:
case FORMAT_ASTC_6x5:
case FORMAT_ASTC_6x6:
case FORMAT_ASTC_8x5:
case FORMAT_ASTC_8x6:
case FORMAT_ASTC_8x8:
case FORMAT_ASTC_10x5:
case FORMAT_ASTC_10x6:
case FORMAT_ASTC_10x8:
case FORMAT_ASTC_10x10:
case FORMAT_ASTC_12x10:
case FORMAT_ASTC_12x12:
default:
lovrThrow("Unreachable");
return GL_UNSIGNED_BYTE;
@ -199,8 +242,26 @@ static GLenum convertTextureFormatType(TextureFormat format) {
static bool isTextureFormatCompressed(TextureFormat format) {
switch (format) {
case FORMAT_DXT1: case FORMAT_DXT3: case FORMAT_DXT5: return true;
default: return false;
case FORMAT_DXT1:
case FORMAT_DXT3:
case FORMAT_DXT5:
case FORMAT_ASTC_4x4:
case FORMAT_ASTC_5x4:
case FORMAT_ASTC_5x5:
case FORMAT_ASTC_6x5:
case FORMAT_ASTC_6x6:
case FORMAT_ASTC_8x5:
case FORMAT_ASTC_8x6:
case FORMAT_ASTC_8x8:
case FORMAT_ASTC_10x5:
case FORMAT_ASTC_10x6:
case FORMAT_ASTC_10x8:
case FORMAT_ASTC_10x10:
case FORMAT_ASTC_12x10:
case FORMAT_ASTC_12x12:
return true;
default:
return false;
}
}
@ -1194,7 +1255,7 @@ void lovrGpuTick(const char* label) {
TimerList* timer = map_get(&state.timers, label);
if (!timer) {
map_set(&state.timers, label, ((TimerList) { 0 }));
map_set(&state.timers, label, ((TimerList) { .oldest = 0 }));
timer = map_get(&state.timers, label);
glGenQueries(sizeof(timer->timers) / sizeof(timer->timers[0]), timer->timers);
}