Handle Vulkan float-to-integer color attachment format mismatch#2702
Handle Vulkan float-to-integer color attachment format mismatch#2702Icehunter wants to merge 1 commit intoKhronosGroup:mainfrom
Conversation
Some Vulkan applications write float data to integer color attachments (e.g. VK_FORMAT_R16G16B16A16_UINT), which is undefined behavior per the Vulkan spec but works on most hardware. Metal requires the shader output type to exactly match the color attachment pixel format and rejects the pipeline with "output of type float4 is not compatible with a MTLPixelFormatRGBA16Uint color attachment". This change adds per-location format matching by reflecting fragment shader SPIR-V outputs to determine each location's base type (float vs uint). When a mismatch is detected (float shader output to integer attachment), the pipeline descriptor's color attachment format is swapped to the corresponding float format (e.g. RGBA16Uint to RGBA16Float) before compilation. Only mismatched locations are swapped, preserving correct behavior for shaders that legitimately output integer types. Known limitation: the pipeline descriptor format may differ from the render pass attachment format. Metal tolerates this for same-size formats but the data may be reinterpreted incorrectly by composition passes that read the attachment as a sampled texture.
Then I'm afraid those applications are broken. "Undefined" means undefined. Literally anything can happen. When you violate the spec, it is legal for the ICD to delete the entire contents of your SSD, and make demons fly out of your nose. What happens when you run Minecraft under the validation layer? See also: KhronosGroup/SPIRV-Cross#2562, which, by the way, is a change that I wrote. It was rejected for this very same reason. |
It quite literally just crashes dead in the water. I've been fighting with it all day, for the insane reason of running bedrock on MacOS. My last hurray tonight well be to enable volumetric lighting and getting realistic waves to render like it does on a mobile phone, but at this point I'm thinking it's just beyond fixes and going into unrealistic patches. |
I assume we don't want to deliberately bring in a fix to make the behaviour de facto defined, per the other implementations? |
Some Vulkan applications write float data to integer color attachments (e.g. VK_FORMAT_R16G16B16A16_UINT), which is undefined behavior per the Vulkan spec but works on most hardware. Metal requires the shader output type to exactly match the color attachment pixel format and rejects the pipeline with "output of type float4 is not compatible with a MTLPixelFormatRGBA16Uint color attachment".
This change adds per-location format matching by reflecting fragment shader SPIR-V outputs to determine each location's base type (float vs uint). When a mismatch is detected (float shader output to integer attachment), the pipeline descriptor's color attachment format is swapped to the corresponding float format (e.g. RGBA16Uint to RGBA16Float) before compilation.
Only mismatched locations are swapped, preserving correct behavior for shaders that legitimately output integer types.
Known limitation: the pipeline descriptor format may differ from the render pass attachment format. Metal tolerates this for same-size formats but the data may be reinterpreted incorrectly by composition passes that read the attachment as a sampled texture.