opened
aerofly
username_0
I am using MoltenVK successfully on MacOS without any issues. On iOS however I am struggling to get PVR textures to work. I always get the following error:

`-[MTLDebugBlitCommandEncoder validateCopyFromBuffer:sourceOffset:sourceBytesPerRow:sourceBytesPerImage:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:options:]:515: failed assertion `MTLPixelFormatPVRTC_RGBA_4BPP disallowed unless MTLBlitOptionRowLinearPVRTC option is used.'`

I have enabled the extension 'VK_IMG_format_pvrtc', but still get the error.

Any ideas what might be wrong?
How to use PVR textures on iOS?
issue
created
billhollings
username_1
Thanks for reporting this. It's likely a bug. I'll have a look at it.
comment
created
jamesd9
username_2
I've just run into this as well. It seems like it should be high priority to fix as PVR is still the most common format on iOS. I've hacked together my own fix, but I'm reluctant to add it to the repository as it's not fully tested, and I'm not that familar with MoltenVK or GitHub yet (I signed up just to report this issue).

The change I made was to add the following to MVKCmdBufferImageCopy::encode:

`if (_toImage &&
            ((mtlPixFmt == MTLPixelFormatPVRTC_RGBA_4BPP_sRGB) ||
             (mtlPixFmt == MTLPixelFormatPVRTC_RGBA_4BPP) ||
             (mtlPixFmt == MTLPixelFormatPVRTC_RGBA_2BPP) ||
             (mtlPixFmt == MTLPixelFormatPVRTC_RGBA_2BPP_sRGB)))
        {
                blitOptions |= MTLBlitOptionRowLinearPVRTC;
        }`

This then exposes a second problem which is that blockTexelSize.width is wrong for many of the PVR formats in _formatDescriptions. (The 4bpp formats should be 4 texels wide, and the 2bpp formats should be 8 texels wide, previously there were not.) The appropriate part of this declaration becomes:

`// Extension VK_IMG_format_pvrtc
	MVK_MAKE_FMT_STRUCT( VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, MTLPixelFormatPVRTC_RGBA_2BPP, MTLPixelFormatInvalid, 8.0, kMTLFmtNA, 8, 4, 8, MTLVertexFormatInvalid, MTLVertexFormatInvalid, kMTLFmtNA, kMTLFmtNA, kMVKFormatCompressed, MVK_FMT_COMPRESSED_FEATS, MVK_FMT_NO_FEATS ),
	MVK_MAKE_FMT_STRUCT( VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG, MTLPixelFormatPVRTC_RGBA_4BPP, MTLPixelFormatInvalid, 8.0, kMTLFmtNA, 4, 4, 8, MTLVertexFormatInvalid, MTLVertexFormatInvalid, kMTLFmtNA, kMTLFmtNA, kMVKFormatCompressed, MVK_FMT_COMPRESSED_FEATS, MVK_FMT_NO_FEATS ),
	MVK_MAKE_FMT_STRUCT( VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG, MTLPixelFormatInvalid, MTLPixelFormatInvalid, kMTLFmtNA, kMTLFmtNA, 8, 4, 8, MTLVertexFormatInvalid, MTLVertexFormatInvalid, kMTLFmtNA, kMTLFmtNA, kMVKFormatCompressed, MVK_FMT_NO_FEATS, MVK_FMT_NO_FEATS ),
	MVK_MAKE_FMT_STRUCT( VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG, MTLPixelFormatInvalid, MTLPixelFormatInvalid, kMTLFmtNA, kMTLFmtNA, 4, 4, 8, MTLVertexFormatInvalid, MTLVertexFormatInvalid, kMTLFmtNA, kMTLFmtNA, kMVKFormatCompressed, MVK_FMT_NO_FEATS, MVK_FMT_NO_FEATS ),
	MVK_MAKE_FMT_STRUCT( VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG, MTLPixelFormatPVRTC_RGBA_2BPP_sRGB, MTLPixelFormatInvalid, 8.0, kMTLFmtNA, 8, 4, 8, MTLVertexFormatInvalid, MTLVertexFormatInvalid, kMTLFmtNA, kMTLFmtNA, kMVKFormatCompressed, MVK_FMT_COMPRESSED_FEATS, MVK_FMT_NO_FEATS ),
	MVK_MAKE_FMT_STRUCT( VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG, MTLPixelFormatPVRTC_RGBA_4BPP_sRGB, MTLPixelFormatInvalid, 8.0, kMTLFmtNA, 4, 4, 8, MTLVertexFormatInvalid, MTLVertexFormatInvalid, kMTLFmtNA, kMTLFmtNA, kMVKFormatCompressed, MVK_FMT_COMPRESSED_FEATS, MVK_FMT_NO_FEATS ),
	MVK_MAKE_FMT_STRUCT( VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG, MTLPixelFormatInvalid, MTLPixelFormatInvalid, kMTLFmtNA, kMTLFmtNA, 8, 4, 8, MTLVertexFormatInvalid, MTLVertexFormatInvalid, kMTLFmtNA, kMTLFmtNA, kMVKFormatCompressed, MVK_FMT_NO_FEATS, MVK_FMT_NO_FEATS ),
	MVK_MAKE_FMT_STRUCT( VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG, MTLPixelFormatInvalid, MTLPixelFormatInvalid, kMTLFmtNA, kMTLFmtNA, 4, 4, 8, MTLVertexFormatInvalid, MTLVertexFormatInvalid, kMTLFmtNA, kMTLFmtNA, kMVKFormatCompressed, MVK_FMT_NO_FEATS, MVK_FMT_NO_FEATS ),
`
comment
created
billhollings
username_1
@username_2 PR #450 includes your fixes. Thanks for identifying the problem and providing a fix.
comment
closed
billhollings
username_1
issue
created
jamesd9
username_2
@username_1 

Sorry, this should probably be re-opened. I am now in a position where I can actually verify that texture data (before I was just trying to get it to run) and it looks as though it has been mangled. My best guess is that the MTLBlitOptionRowLinearPVRTC expects the PVR texture data to be untwiddled, whereas standard PVR data is twiddled. I did have a go at fixing this myself by using the replaceRegion function to upload the data (which seems to be the Apple recommended method, and so I assume it expects the data to be twiddled) but that failed due to the texture being private.
comment
created
jamesd9
username_2
@username_1 

On a related issue - how are RGB PVR textures used? (There doesn't seem to be a VkFormat for them - maybe some should be added to the Vulkan spec if that's possible, and the current ones made explicitly RGBA rather than ambigious.)
comment
created
aerofly
username_0
It's my understanding that both RGB and RGBA PVR 4-bit mode textures map to VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG.
And the same for RGB and RGBA PVR 2-bit mode textures, they map to VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG.

PVR 2 and PVR 4 are both supported on iOS.

It would be indeed great if PVR textures could be supported in MoltenVK.
comment
created
jamesd9
username_2
Ah yes, my mistake, it does seem that RGB and RGBA versions use the same block format. I'm not sure why both metal and opengl distinguish between them then.

Yes, I agree that PVR support is very important, particularly on iOS as it's the only compressed format which works on all current devices. (Hopefully Apple will drop support for non-ASTC devices in iOS 13.)
comment
reopened
billhollings
username_1
I am using MoltenVK successfully on MacOS without any issues. On iOS however I am struggling to get PVR textures to work. I always get the following error:

`-[MTLDebugBlitCommandEncoder validateCopyFromBuffer:sourceOffset:sourceBytesPerRow:sourceBytesPerImage:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:options:]:515: failed assertion `MTLPixelFormatPVRTC_RGBA_4BPP disallowed unless MTLBlitOptionRowLinearPVRTC option is used.'`

I have enabled the extension 'VK_IMG_format_pvrtc', but still get the error.

Any ideas what might be wrong?
How to use PVR textures on iOS?
issue
created
billhollings
username_1
Which would imply a possibly different layout than a standard PVRTC layout (eg. Morton)? 

What is the block layout that you are loading into the buffer?
comment
created
jamesd9
username_2
"Twiddled" is just PVRTC parlance for the blocks being swizzled. PVRTC files are output by pvrtextool in a standard PVRTC layout (I would guess morton) and then uploaded. I'm not aware of any way to get the tool to use a different layout (e.g. row linear). Feeding the standard PVRTC layout files to GLES works correctly.

The name and effect of MTLBlitOptionRowLinearPVRTC imply it is expecting the blocks to be in row linear order (even though this is completely non-standard and not useful AFAIK), but Apple's docs say otherwise. Maybe their docs are just wrong?

I guess the way to work around it is either to unswizzle the data so that the blit can reswizzle it during the copy or to use replaceRegion instead as this is what Apple's example code does so it presumably works.
comment
created
billhollings
username_1
@username_2 

Where do Apple's docs indicate otherwise about a linear block layout? The doc excerpt I quoted above clearly states that is exactly what it is expecting.

Yes...it may be possible for MoltenVK to convert the block layout from Morton to linear either in place in the MTLBuffer...or in a temporary MTLBuffer before sending it to be copied into the texture.
comment
created
jamesd9
username_2
@username_1 

Apologies, I didn't express that very clearly - I meant that Apple's docs say that row linear format is standard for pvrtc and other texture compression formats, when in fact morton order is standard. (Hence the problems when copying using MTLBlitOptionRowLinearPVRTC.)
comment
closed
billhollings
username_1
issue
created
billhollings
username_1
PR #539 includes @abeyn's [fix](https://github.com/KhronosGroup/MoltenVK/issues/461#issuecomment-471575487) to allow host-memory mapped PVRTC image content to be loaded correctly...and documentation to the effect that staging-buffers cannot be used with PVRTC content.

I'm closing this issue now.
comment