i’m using this function to load ETC2 texture from KTX on the iOS platform. The KTX texture was converted from jpg with PVRTex tool: PVRTexToolCLI.exe -i tex.jpg -o tex.ktx -f ETC2_RGB -q etcfast -m 9
Get the error:
validateCopyFromBuffer:sourceOffset:sourceBytesPerRow:sourceBytesPerImage:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:options:]:463: failed assertion `sourceOffset (4) must be a multiple of 8 bytes.’
size of texture is 1024 * 1024, with VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK format.
From the Metal document: The byte location in the source buffer where the copying starts. The location must be aligned to the size of the destination texture's pixel format. The value must be a multiple of the destination texture's pixel size, in bytes.
Does it mean my sourceOffset should be a multiple of 3 bytes(R8G8B8)?
And when i use ASTC_6x6 format, got error: `sourceOffset (4) must be a multiple of 16 bytes.’
When copying from a buffer to an image using vkCmdCopyBufferToImage(), both Vulkan and Metal require that the bufferOffset value be a multiple of the image element size…which in the case of compressed formats is its block size.
For example…the block sizes for VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK and VK_FORMAT_ASTC_6x6_UNORM_BLOCK are 8 and 16, respectively…which is why you are seeing those two errors.
From looking at your code sample…given that Metal is complaining about a 4 byte offset…my guess is that your call is expecting that the first 4 bytes of each Mip layer contains the size of the layer…and your function skips those first 4 bytes by incrementing bufferOffset by those 4 bytes. That will then cause bufferOffset to have a value of 4…which is not a multiple of either of the compressed format block sizes you are using.