MVKGraphicsPipeline: Fix color write mask with RGB9E5 RTs.

Metal does not allow color write masks with this format where some but
not all of the channels are disabled. Either all must be enabled or none
must be enabled. Presumably, this is because of the shared exponent.

This is just good enough to stop the validation layer from violently
terminating the program. To implement this properly requires using
framebuffer fetch, with a change to SPIRV-Cross. Luckily, the only GPUs
that support `RGB9E5` rendering also support framebuffer fetch.
Honestly, I don't understand why Apple's drivers don't do this.
This commit is contained in:
Chip Davis 2020-12-09 01:37:14 -06:00
parent a55cf399b5
commit e6a8409b31

View File

@ -1387,7 +1387,15 @@ void MVKGraphicsPipeline::addFragmentOutputToPipeline(MTLRenderPipelineDescripto
MTLRenderPipelineColorAttachmentDescriptor* colorDesc = plDesc.colorAttachments[caIdx];
colorDesc.pixelFormat = getPixelFormats()->getMTLPixelFormat(mvkRenderSubpass->getColorAttachmentFormat(caIdx));
colorDesc.writeMask = mvkMTLColorWriteMaskFromVkChannelFlags(pCA->colorWriteMask);
if (colorDesc.pixelFormat == MTLPixelFormatRGB9E5Float) {
// Metal doesn't allow disabling individual channels for a RGB9E5 render target.
// Either all must be disabled or none must be disabled.
// TODO: Use framebuffer fetch to support this anyway. I don't understand why Apple doesn't
// support it, given that the only GPUs that support this in Metal also support framebuffer fetch.
colorDesc.writeMask = pCA->colorWriteMask ? MTLColorWriteMaskAll : MTLColorWriteMaskNone;
} else {
colorDesc.writeMask = mvkMTLColorWriteMaskFromVkChannelFlags(pCA->colorWriteMask);
}
// Don't set the blend state if we're not using this attachment.
// The pixel format will be MTLPixelFormatInvalid in that case, and
// Metal asserts if we turn on blending with that pixel format.