Skip to content

Commit

Permalink
Handle PVRTC1 minimum 2 block requirement. Fixes issue KhronosGroup#390
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkCallow authored Apr 15, 2021
1 parent 6c01c3b commit 46e1a2f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 18 deletions.
2 changes: 2 additions & 0 deletions lib/formatsize.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ typedef struct ktxFormatSize {
unsigned int blockWidth; // in texels
unsigned int blockHeight; // in texels
unsigned int blockDepth; // in texels
unsigned int minBlocksX; // Minimum required number of blocks
unsigned int minBlocksY;
} ktxFormatSize;

#ifdef __cplusplus
Expand Down
31 changes: 18 additions & 13 deletions lib/gl_format.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
================================================================================================
Description : OpenGL formats/types and properties.
Expand Down Expand Up @@ -1625,6 +1625,7 @@ static inline unsigned int glGetTypeSizeFromType(GLenum type)

static inline void glGetFormatSize( const GLenum internalFormat, ktxFormatSize * pFormatSize )
{
pFormatSize->minBlocksX = pFormatSize->minBlocksY = 1;
switch ( internalFormat )
{
//
Expand Down Expand Up @@ -2007,27 +2008,31 @@ static inline void glGetFormatSize( const GLenum internalFormat, ktxFormatSize *
//
// PVRTC
//
case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: // 3-component PVRTC, 16x8 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: // 3-component PVRTC, 16x8 blocks, sRGB
case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: // 4-component PVRTC, 16x8 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: // 4-component PVRTC, 16x8 blocks, sRGB
case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: // 3-component PVRTC, 8x4 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: // 3-component PVRTC, 8x4 blocks, sRGB
case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: // 4-component PVRTC, 8x4 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: // 4-component PVRTC, 8x4 blocks, sRGB
pFormatSize->flags = KTX_FORMAT_SIZE_COMPRESSED_BIT;
pFormatSize->paletteSizeInBits = 0;
pFormatSize->blockSizeInBits = 64;
pFormatSize->blockWidth = 16;
pFormatSize->blockHeight = 8;
pFormatSize->blockWidth = 8;
pFormatSize->blockHeight = 4;
pFormatSize->blockDepth = 1;
pFormatSize->minBlocksX = 2;
pFormatSize->minBlocksY = 2;
break;
case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: // 3-component PVRTC, 8x8 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: // 3-component PVRTC, 8x8 blocks, sRGB
case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: // 4-component PVRTC, 8x8 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: // 4-component PVRTC, 8x8 blocks, sRGB
case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: // 3-component PVRTC, 4x4 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: // 3-component PVRTC, 4x4 blocks, sRGB
case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: // 4-component PVRTC, 4x4 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: // 4-component PVRTC, 4x4 blocks, sRGB
pFormatSize->flags = KTX_FORMAT_SIZE_COMPRESSED_BIT;
pFormatSize->paletteSizeInBits = 0;
pFormatSize->blockSizeInBits = 64;
pFormatSize->blockWidth = 8;
pFormatSize->blockHeight = 8;
pFormatSize->blockWidth = 4;
pFormatSize->blockHeight = 4;
pFormatSize->blockDepth = 1;
pFormatSize->minBlocksX = 2;
pFormatSize->minBlocksY = 2;
break;
case GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG: // 4-component PVRTC, 8x4 blocks, unsigned normalized
case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG: // 4-component PVRTC, 8x4 blocks, sRGB
Expand Down
4 changes: 2 additions & 2 deletions lib/texture.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,8 @@ ktxTexture_calcImageSize(ktxTexture* This, ktx_uint32_t level,
= (uint32_t)ceilf(levelWidth / prtctd->_formatSize.blockWidth);
blockCount.y
= (uint32_t)ceilf(levelHeight / prtctd->_formatSize.blockHeight);
blockCount.x = MAX(1, blockCount.x);
blockCount.y = MAX(1, blockCount.y);
blockCount.x = MAX(prtctd->_formatSize.minBlocksX, blockCount.x);
blockCount.y = MAX(prtctd->_formatSize.minBlocksX, blockCount.y);

blockSizeInBytes = prtctd->_formatSize.blockSizeInBits / 8;

Expand Down
10 changes: 7 additions & 3 deletions lib/texture2.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,13 @@ ktxFormatSize_initFromDfd(ktxFormatSize* This, ktx_uint32_t* pDfd)
This->blockSizeInBits = KHR_DFDVAL(pBdb, BYTESPLANE0) * 8;
This->paletteSizeInBits = 0; // No paletted formats in ktx v2.
This->flags = 0;
This->minBlocksX = This->minBlocksY = 1;
if (KHR_DFDVAL(pBdb, MODEL) >= KHR_DF_MODEL_DXT1A) {
// A block compressed format. Entire block is a single sample.
This->flags |= KTX_FORMAT_SIZE_COMPRESSED_BIT;
if (KHR_DFDVAL(pBdb, MODEL) == KHR_DF_MODEL_PVRTC) {
This->minBlocksX = This->minBlocksY = 2;
}
} else {
// An uncompressed format.

Expand Down Expand Up @@ -2001,7 +2005,7 @@ ktxTexture2_IterateLoadLevelFaces(ktxTexture2* This, PFNKTXITERCB iterCb,
// With the exception of non-array cubemaps the entire level
// is passed at once because that is how OpenGL and Vulkan need them.
// Vulkan could take all the faces at once too but we iterate
// them separately or OpenGL.
// them separately for OpenGL.
if (This->isCubemap && !This->isArray) {
ktx_uint8_t* pFace = pData;
struct blockCount {
Expand All @@ -2013,8 +2017,8 @@ ktxTexture2_IterateLoadLevelFaces(ktxTexture2* This, PFNKTXITERCB iterCb,
= (uint32_t)ceilf((float)width / prtctd->_formatSize.blockWidth);
blockCount.y
= (uint32_t)ceilf((float)height / prtctd->_formatSize.blockHeight);
blockCount.x = MAX(1, blockCount.x);
blockCount.y = MAX(1, blockCount.y);
blockCount.x = MAX(prtctd->_formatSize.minBlocksX, blockCount.x);
blockCount.y = MAX(prtctd->_formatSize.minBlocksX, blockCount.y);
faceSize = blockCount.x * blockCount.y
* prtctd->_formatSize.blockSizeInBits / 8;

Expand Down
30 changes: 30 additions & 0 deletions lib/vk_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@ static inline VkFormat vkGetFormatFromOpenGLInternalFormat( const GLenum interna

static inline void vkGetFormatSize( const VkFormat format, ktxFormatSize * pFormatSize )
{
pFormatSize->minBlocksX = pFormatSize->minBlocksY = 1;
switch ( format )
{
case VK_FORMAT_R4G4_UNORM_PACK8:
Expand Down Expand Up @@ -1207,8 +1208,37 @@ static inline void vkGetFormatSize( const VkFormat format, ktxFormatSize * pForm
pFormatSize->blockHeight = 4;
pFormatSize->blockDepth = 1;
break;
case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
pFormatSize->flags = KTX_FORMAT_SIZE_COMPRESSED_BIT;
pFormatSize->paletteSizeInBits = 0;
pFormatSize->blockSizeInBits = 8 * 8;
pFormatSize->blockWidth = 8;
pFormatSize->blockHeight = 4;
pFormatSize->blockDepth = 1;
pFormatSize->minBlocksX = 2;
pFormatSize->minBlocksY = 2;
break;
case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
pFormatSize->flags = KTX_FORMAT_SIZE_COMPRESSED_BIT;
pFormatSize->paletteSizeInBits = 0;
pFormatSize->blockSizeInBits = 8 * 8;
pFormatSize->blockWidth = 8;
pFormatSize->blockHeight = 4;
pFormatSize->blockDepth = 1;
break;
case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
pFormatSize->flags = KTX_FORMAT_SIZE_COMPRESSED_BIT;
pFormatSize->paletteSizeInBits = 0;
pFormatSize->blockSizeInBits = 8 * 8;
pFormatSize->blockWidth = 4;
pFormatSize->blockHeight = 4;
pFormatSize->blockDepth = 1;
pFormatSize->minBlocksX = 2;
pFormatSize->minBlocksY = 2;
break;
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
pFormatSize->flags = KTX_FORMAT_SIZE_COMPRESSED_BIT;
Expand Down

0 comments on commit 46e1a2f

Please sign in to comment.