Skip to content

Commit 94d9a8a

Browse files
[SPIR-V] Add fragment interlock extension by default (microsoft#5646)
Adds the extension `SPV_EXT_fragment_shader_interlock` and the related capabilities - `spv::Capability::FragmentShaderSampleInterlockEXT` - `spv::Capability::FragmentShaderPixelInterlockEXT` - `spv::Capability::FragmentShaderShadingRateInterlockEXT` to every shader by default, and let the `spirv-opt` capability trimming pass remove them if unnecessary.
1 parent bae2325 commit 94d9a8a

File tree

7 files changed

+48
-0
lines changed

7 files changed

+48
-0
lines changed

tools/clang/include/clang/SPIRV/FeatureManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum class Extension {
4343
EXT_descriptor_indexing,
4444
EXT_fragment_fully_covered,
4545
EXT_fragment_invocation_density,
46+
EXT_fragment_shader_interlock,
4647
EXT_mesh_shader,
4748
EXT_shader_stencil_export,
4849
EXT_shader_viewport_index_layer,

tools/clang/lib/SPIRV/CapabilityVisitor.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ void CapabilityVisitor::addExtension(Extension ext, llvm::StringRef target,
2323
spvBuilder.requireExtension(featureManager.getExtensionName(ext), loc);
2424
}
2525

26+
void CapabilityVisitor::addExtensionAndCapabilitiesIfEnabled(
27+
Extension ext, llvm::ArrayRef<spv::Capability> capabilities) {
28+
if (featureManager.isExtensionEnabled(ext)) {
29+
addExtension(ext, "", {});
30+
31+
for (auto cap : capabilities) {
32+
addCapability(cap);
33+
}
34+
}
35+
}
36+
2637
void CapabilityVisitor::addCapability(spv::Capability cap, SourceLocation loc) {
2738
if (cap != spv::Capability::Max) {
2839
spvBuilder.requireCapability(cap, loc);
@@ -869,6 +880,14 @@ bool CapabilityVisitor::visit(SpirvModule *, Visitor::Phase phase) {
869880
// supports only some capabilities. This list should be expanded to match the
870881
// supported capabilities.
871882
addCapability(spv::Capability::MinLod);
883+
884+
addExtensionAndCapabilitiesIfEnabled(
885+
Extension::EXT_fragment_shader_interlock,
886+
{
887+
spv::Capability::FragmentShaderSampleInterlockEXT,
888+
spv::Capability::FragmentShaderPixelInterlockEXT,
889+
spv::Capability::FragmentShaderShadingRateInterlockEXT,
890+
});
872891
return true;
873892
}
874893

tools/clang/lib/SPIRV/CapabilityVisitor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ class CapabilityVisitor : public Visitor {
6464
/// the given extension to the SPIR-V module in memory.
6565
void addExtension(Extension ext, llvm::StringRef target, SourceLocation loc);
6666

67+
/// Checks that the given extension is enabled based on command line arguments
68+
/// before calling addExtension and addCapability.
69+
void addExtensionAndCapabilitiesIfEnabled(
70+
Extension ext, llvm::ArrayRef<spv::Capability> capabilities);
71+
6772
/// Checks that the given capability is a valid capability. And if so,
6873
/// utilizes the SpirvBuilder to add the given capability to the SPIR-V module
6974
/// in memory.

tools/clang/lib/SPIRV/FeatureManager.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ Extension FeatureManager::getExtensionSymbol(llvm::StringRef name) {
172172
Extension::EXT_fragment_fully_covered)
173173
.Case("SPV_EXT_fragment_invocation_density",
174174
Extension::EXT_fragment_invocation_density)
175+
.Case("SPV_EXT_fragment_shader_interlock",
176+
Extension::EXT_fragment_shader_interlock)
175177
.Case("SPV_EXT_mesh_shader", Extension::EXT_mesh_shader)
176178
.Case("SPV_EXT_shader_stencil_export",
177179
Extension::EXT_shader_stencil_export)
@@ -228,6 +230,8 @@ const char *FeatureManager::getExtensionName(Extension symbol) {
228230
return "SPV_EXT_fragment_fully_covered";
229231
case Extension::EXT_fragment_invocation_density:
230232
return "SPV_EXT_fragment_invocation_density";
233+
case Extension::EXT_fragment_shader_interlock:
234+
return "SPV_EXT_fragment_shader_interlock";
231235
case Extension::EXT_mesh_shader:
232236
return "SPV_EXT_mesh_shader";
233237
case Extension::EXT_shader_stencil_export:

tools/clang/test/CodeGenSPIRV_Lit/capability.trimmed.o3.hlsl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ SamplerState gSampler : register(s2);
55

66
// CHECK-NOT: OpCapability MinLod
77

8+
// CHECK-NOT: OpExtension "SPV_EXT_fragment_shader_interlock"
9+
// CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
10+
// CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
11+
// CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
12+
13+
// CHECK-NOT: OpExtension "SPV_EXT_fragment_shader_interlock"
14+
815
float4 main(uint clamp : A) : SV_Target {
916
if (clamp < 0) {
1017
return t.Sample(gSampler, 0.5f, 2, float(clamp));

tools/clang/test/CodeGenSPIRV_Lit/capability.untrimmed.fcgl.hlsl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,10 @@
88
// event if unused.
99

1010
// CHECK: OpCapability MinLod
11+
// CHECK: OpCapability FragmentShaderSampleInterlockEXT
12+
// CHECK: OpCapability FragmentShaderPixelInterlockEXT
13+
// CHECK: OpCapability FragmentShaderShadingRateInterlockEXT
14+
15+
// CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
1116
[numthreads(1, 1, 1)]
1217
void main() { }

tools/clang/test/CodeGenSPIRV_Lit/capability.untrimmed.o0.hlsl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ SamplerState gSampler : register(s2);
55

66
// CHECK: OpCapability MinLod
77

8+
// TODO: add a rasterizer order view and check that these are not trimmed
9+
// once ROVs are supported
10+
// CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
11+
// CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
12+
// CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
13+
14+
// CHECK-NOT: OpExtension "SPV_EXT_fragment_shader_interlock"
815
float4 main(uint clamp : A) : SV_Target {
916
if (clamp < 0) {
1017
return t.Sample(gSampler, 0.5f, 2, float(clamp));

0 commit comments

Comments
 (0)