You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Prevent DXC from adding Geometry or MultiViewport when the shader already declares one of these capabilities - #9076
I stumbled across an issue with combining PrimitiveId usage with mesh shaders when the Vulkan device does NOT have geometry shaders enabled.
DXC adds OpCapability Geometry to every pixel or mesh shader that reads or writes SV_PrimitiveID or SV_RenderTargetArrayIndex, and OpCapability MultiViewport for SV_ViewportArrayIndex. Geometry requires geometry shaders to be enabled on the device.
Other capabilities also cover these values. Mesh shading covers all three (VUID-PrimitiveId-Fragment-04333 for primitive ID). ShaderViewportIndexLayerEXT, ShaderLayer and ShaderViewportIndex cover the other two.
This change stops DXC from adding Geometry or MultiViewport when the shader already declares one of these capabilities. Mesh shaders never get it. A pixel shader gets it only if it declares none of them (for example, it can declare mesh shading with [[vk::ext_capability(5283)]] and [[vk::ext_extension("SPV_EXT_mesh_shader")]] on the entry point). A plain pixel shader is unchanged.
…ds or writes SV_PrimitiveID or SV_RenderTargetArrayIndex, and OpCapability MultiViewport for SV_ViewportArrayIndex. Geometry requires geometry shaders to be enabled on the device.
Other capabilities also cover these values. Mesh shading covers all three (VUID-PrimitiveId-Fragment-04333 for primitive ID). ShaderViewportIndexLayerEXT, ShaderLayer and ShaderViewportIndex cover the other two.
This change stops DXC from adding Geometry or MultiViewport when the shader already declares one of these capabilities. Mesh shaders never get it. A pixel shader gets it only if it declares none of them (for example, it can declare mesh shading with [[vk::ext_capability(5283)]] and [[vk::ext_extension("SPV_EXT_mesh_shader")]] on the entry point). A plain pixel shader is unchanged.
This PR updates DXC’s SPIR-V capability selection to avoid unnecessary geometry-shader requirements when declared capabilities already support the affected mesh and fragment shader builtins.
Changes:
Defers fragment builtin capability selection until all module capabilities are known.
Uses existing mesh, tessellation, and viewport/layer capabilities instead of adding redundant Geometry or MultiViewport.
Adds regression tests for alternative capabilities, late capability declarations, and preservation of geometry-stage requirements.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The added fragment-shader tests bypass the Tessellation exception, leaving it without regression coverage verifying that Tessellation is retained and Geometry is absent both with and without -fcgl.
No open issues 🎉
1 previously missed issue
In code that hasn't changed since last review
Add pixel-shader regression test for Tessellation capability handling
The new Tessellation exception is not covered by the added fragment-shader tests, which declare mesh-shading capabilities and bypass this branch. Please add an SV_PrimitiveID pixel-shader regression declaring [[vk::ext_capability(3)]] that checks Tessellation is retained and Geometry is absent, both with and without -fcgl.
I received an email that indicated there was a comment on this PR. I don't see the comment here, but maybe GitHub is just broken right now. It asked for more info and a godbolt link.
I expected to be able to compile and use a mesh shader with vulkan that writes to PrimitiveId, without enabling geometry shaders on the device. This change fixes that specific problem and a few similar problems.
The root cause is that DXC puts unnecessary capabilities in the spirv, which limits the conditions under which the shader can be used. There are several examples in the included tests, but here is a specific case of a mesh shader that writes SV_PrimitiveID, and it results in being unable to use it without enabling geometry shaders.
The produced spirv has "OpCapability Geometry". In Vulkan, a module that declares Geometry is invalid unless the device enables the geometryShader feature. So this mesh shader, as compiled by DXC today, can't be used on a device without geometry shader support.
Philip Degarmo (@aclysma) Yeah that was me deleting my message after I had understood a little better and started reviewing (was having a brain fart). If for this PR and future ones, you could file an issue with a body just like you've done here, that would be greatly appreciated and make reviewing easier and quicker. Otherwise, thanks for this PR, I'm still reviewing but it looks good so far!
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR and thanks for your patience. It took me a while to get context, and I still might have gaps in my understanding, but the code looks pretty good. I just have some nits and follow ups on documentation such that it best reflects the new changes.
Thanks for the changes. One small, optional idea: a test where a capability is declared that doesn't enable the builtin (e.g. ShaderLayer with SV_PrimitiveID), to assert that Geometry is still added. Otherwise LGTM!
The reason will be displayed to describe this comment to others. Learn more.
Nothing worth holding up the change, just some better potential clarity and test consolidation.
In the meantime, the merge conflicts need to be resolved. I can't even see what they are I think because you didn't allow maintainers to push to your branch. No shame in that, but it means I can't do anything to merge it until they are resolved.
The reason will be displayed to describe this comment to others. Learn more.
This includes two entry points with different annotations using the same run lines. The following three test files also involve entry points with different annotations, the same run lines, and only slightly different CHECK directives. I won't insist, but you might consider consolidating the entry points into one file, renaming the entry functions differently, and adding run lines with corresponding -E main2 flags as well as --check-prefixes flags to FileCheck where needed.
The reason will be displayed to describe this comment to others. Learn more.
Suggested change
#endif
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I stumbled across an issue with combining PrimitiveId usage with mesh shaders when the Vulkan device does NOT have geometry shaders enabled.
DXC adds OpCapability Geometry to every pixel or mesh shader that reads or writes SV_PrimitiveID or SV_RenderTargetArrayIndex, and OpCapability MultiViewport for SV_ViewportArrayIndex. Geometry requires geometry shaders to be enabled on the device.
Other capabilities also cover these values. Mesh shading covers all three (VUID-PrimitiveId-Fragment-04333 for primitive ID). ShaderViewportIndexLayerEXT, ShaderLayer and ShaderViewportIndex cover the other two.
This change stops DXC from adding Geometry or MultiViewport when the shader already declares one of these capabilities. Mesh shaders never get it. A pixel shader gets it only if it declares none of them (for example, it can declare mesh shading with [[vk::ext_capability(5283)]] and [[vk::ext_extension("SPV_EXT_mesh_shader")]] on the entry point). A plain pixel shader is unchanged.