Merge pull request #122 from billhollings/master

Round up row and layer byte counts when copying compressed images with sizes that are not integer multiples of block size.
This commit is contained in:
Bill Hollings 2018-04-03 22:51:50 -04:00 committed by GitHub
commit 794db80bb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 9 deletions

View File

@ -118,29 +118,36 @@ float mvkMTLPixelFormatBytesPerTexel(MTLPixelFormat mtlFormat);
/**
* Returns the size, in bytes, of a row of texels of the specified Vulkan format.
*
* For compressed formats, this takes into consideration the compression block size,
* and texelsPerRow should specify the width in texels, not blocks.
* and texelsPerRow should specify the width in texels, not blocks. The result is rounded
* up if texelsPerRow is not an integer multiple of the compression block width.
*/
size_t mvkVkFormatBytesPerRow(VkFormat vkFormat, uint32_t texelsPerRow);
/**
* Returns the size, in bytes, of a row of texels of the specified Metal format.
* Returns the size, in bytes, of a row of texels of the specified Metal format.
*
* For compressed formats, this takes into consideration the compression block size,
* and texelsPerRow should specify the width in texels, not blocks.
* and texelsPerRow should specify the width in texels, not blocks. The result is rounded
* up if texelsPerRow is not an integer multiple of the compression block width.
*/
size_t mvkMTLPixelFormatBytesPerRow(MTLPixelFormat mtlFormat, uint32_t texelsPerRow);
/**
* Returns the size, in bytes, of a texture layer of the specified Vulkan format.
*
* For compressed formats, this takes into consideration the compression block size,
* and texelRowsPerLayer should specify the height in texels, not blocks.
* and texelRowsPerLayer should specify the height in texels, not blocks. The result is
* rounded up if texelRowsPerLayer is not an integer multiple of the compression block height.
*/
size_t mvkVkFormatBytesPerLayer(VkFormat vkFormat, size_t bytesPerRow, uint32_t texelRowsPerLayer);
/**
* Returns the size, in bytes, of a texture layer of the specified Metal format.
* For compressed formats, this takes into consideration the compression block size,
* and texelRowsPerLayer should specify the height in texels, not blocks.
* and texelRowsPerLayer should specify the height in texels, not blocks. The result is
* rounded up if texelRowsPerLayer is not an integer multiple of the compression block height.
*/
size_t mvkMTLPixelFormatBytesPerLayer(MTLPixelFormat mtlFormat, size_t bytesPerRow, uint32_t texelRowsPerLayer);

View File

@ -110,6 +110,12 @@ VkResult mvkNotifyErrorWithText(VkResult vkErr, const char* errFmt, ...) __print
#pragma mark -
#pragma mark Alignment functions
/** Returns the result of an unsigned integer division, rounded up. */
static inline size_t mvkCeilingDivide(size_t numerator, size_t denominator) {
if (denominator == 1) { return numerator; } // Short circuit for this very common usecase.
return (numerator + denominator - 1) / denominator;
}
/** Returns whether the specified value is a power-of-two. */
static inline bool mvkIsPowerOfTwo(uintptr_t value) {
// Test POT: (x != 0) && ((x & (x - 1)) == 0)

View File

@ -554,20 +554,20 @@ MVK_PUBLIC_SYMBOL float mvkMTLPixelFormatBytesPerTexel(MTLPixelFormat mtlFormat)
MVK_PUBLIC_SYMBOL size_t mvkVkFormatBytesPerRow(VkFormat vkFormat, uint32_t texelsPerRow) {
const MVKFormatDesc& fmtDesc = formatDescForVkFormat(vkFormat);
return (texelsPerRow / fmtDesc.blockTexelSize.width) * fmtDesc.bytesPerBlock;
return mvkCeilingDivide(texelsPerRow, fmtDesc.blockTexelSize.width) * fmtDesc.bytesPerBlock;
}
MVK_PUBLIC_SYMBOL size_t mvkMTLPixelFormatBytesPerRow(MTLPixelFormat mtlFormat, uint32_t texelsPerRow) {
const MVKFormatDesc& fmtDesc = formatDescForMTLPixelFormat(mtlFormat);
return (texelsPerRow / fmtDesc.blockTexelSize.width) * fmtDesc.bytesPerBlock;
return mvkCeilingDivide(texelsPerRow, fmtDesc.blockTexelSize.width) * fmtDesc.bytesPerBlock;
}
MVK_PUBLIC_SYMBOL size_t mvkVkFormatBytesPerLayer(VkFormat vkFormat, size_t bytesPerRow, uint32_t texelRowsPerLayer) {
return (texelRowsPerLayer / formatDescForVkFormat(vkFormat).blockTexelSize.height) * bytesPerRow;
return mvkCeilingDivide(texelRowsPerLayer, formatDescForVkFormat(vkFormat).blockTexelSize.height) * bytesPerRow;
}
MVK_PUBLIC_SYMBOL size_t mvkMTLPixelFormatBytesPerLayer(MTLPixelFormat mtlFormat, size_t bytesPerRow, uint32_t texelRowsPerLayer) {
return (texelRowsPerLayer / formatDescForMTLPixelFormat(mtlFormat).blockTexelSize.height) * bytesPerRow;
return mvkCeilingDivide(texelRowsPerLayer, formatDescForMTLPixelFormat(mtlFormat).blockTexelSize.height) * bytesPerRow;
}
MVK_PUBLIC_SYMBOL VkFormatProperties mvkVkFormatProperties(VkFormat vkFormat) {