Skip to content

Commit b43660a

Browse files
s-perronKeenuts
andauthored
[SPIRV] Implement WaveOpsIncludeHelperLanes (microsoft#7806)
This commit implements the `[WaveOpsIncludeHelperLanes]` attribute for the SPIR-V backend. When this attribute is applied to a shader entry point, the compiler will: - Add the `SPV_KHR_maximal_reconvergence` and `SPV_KHR_quad_control` extensions. - Add the `QuadControlKHR` capability. - Add the `MaximallyReconvergesKHR` and `RequireFullQuadsKHR` execution modes to the entry point. This change also includes new tests to verify the correctness of the implementation and updates the documentation. Fixes microsoft#7334 --------- Co-authored-by: Nathan Gauër <[email protected]>
1 parent ec9b560 commit b43660a

File tree

5 files changed

+105
-0
lines changed

5 files changed

+105
-0
lines changed

docs/SPIR-V.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,21 @@ Right now the following ``<builtin>`` are supported:
285285
Please see Vulkan spec. `15.9. Built-In Variables <https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#interfaces-builtin-variables>`_
286286
for detailed explanation of these builtins.
287287

288+
Helper Lane Support
289+
~~~~~~~~~~~~~~~~~~~
290+
291+
Shader Model 6.7 introduces the `[WaveOpsIncludeHelperLanes]` attribute. When this
292+
attribute is applied to a shader entry point, the SPIR-V backend will:
293+
294+
1. Add the ``SPV_KHR_maximal_reconvergence`` and ``SPV_KHR_quad_control``
295+
extensions to the module.
296+
2. Add the ``QuadControlKHR`` capability.
297+
3. Add the ``MaximallyReconvergesKHR`` and ``RequireFullQuadsKHR`` execution modes
298+
to the entry point.
299+
300+
This ensures that helper lanes are included in wave operations, which is the
301+
behavior required by the HLSL specification.
302+
288303
Supported extensions
289304
~~~~~~~~~~~~~~~~~~~~
290305

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,32 @@ void SpirvEmitter::HandleTranslationUnit(ASTContext &context) {
862862
SourceLocation());
863863
}
864864

865+
for (const FunctionInfo *entryInfo : workQueue) {
866+
if (!entryInfo->isEntryFunction)
867+
continue;
868+
869+
if (entryInfo->shaderModelKind != hlsl::ShaderModel::Kind::Pixel) {
870+
continue;
871+
}
872+
873+
const auto *funcDecl = entryInfo->funcDecl;
874+
if (!funcDecl->hasAttr<HLSLWaveOpsIncludeHelperLanesAttr>())
875+
continue;
876+
877+
spvBuilder.requireExtension("SPV_KHR_maximal_reconvergence",
878+
funcDecl->getLocation());
879+
spvBuilder.requireExtension("SPV_KHR_quad_control",
880+
funcDecl->getLocation());
881+
spvBuilder.requireCapability(spv::Capability::QuadControlKHR,
882+
funcDecl->getLocation());
883+
spvBuilder.addExecutionMode(entryInfo->entryFunction,
884+
spv::ExecutionMode::MaximallyReconvergesKHR, {},
885+
funcDecl->getLocation());
886+
spvBuilder.addExecutionMode(entryInfo->entryFunction,
887+
spv::ExecutionMode::RequireFullQuadsKHR, {},
888+
funcDecl->getLocation());
889+
}
890+
865891
// For Vulkan 1.2 and later, add SignedZeroInfNanPreserve when -Gis is
866892
// provided to preserve NaN/Inf and signed zeros.
867893
if (spirvOptions.IEEEStrict) {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %dxc -T lib_6_7 -spirv %s | FileCheck %s
2+
3+
// CHECK: OpCapability QuadControlKHR
4+
// CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
5+
// CHECK-DAG: OpExtension "SPV_KHR_quad_control"
6+
7+
// CHECK: OpEntryPoint Fragment %ps_main1 "ps_main1"
8+
// CHECK: OpEntryPoint Fragment %ps_main2 "ps_main2"
9+
// CHECK: OpEntryPoint Fragment %ps_main3 "ps_main3"
10+
11+
// CHECK-DAG: OpExecutionMode %ps_main1 MaximallyReconvergesKHR
12+
// CHECK-DAG: OpExecutionMode %ps_main1 RequireFullQuadsKHR
13+
14+
// CHECK-NOT: OpExecutionMode %ps_main2 MaximallyReconvergesKHR
15+
// CHECK-NOT: OpExecutionMode %ps_main2 RequireFullQuadsKHR
16+
17+
// CHECK-DAG: OpExecutionMode %ps_main3 MaximallyReconvergesKHR
18+
// CHECK-DAG: OpExecutionMode %ps_main3 RequireFullQuadsKHR
19+
20+
[WaveOpsIncludeHelperLanes]
21+
[shader("pixel")]
22+
void ps_main1() : SV_Target0
23+
{
24+
}
25+
26+
[shader("pixel")]
27+
void ps_main2() : SV_Target0
28+
{
29+
}
30+
31+
[WaveOpsIncludeHelperLanes]
32+
[shader("pixel")]
33+
void ps_main3() : SV_Target0
34+
{
35+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %dxc -T vs_6_7 -E main -spirv %s | FileCheck %s
2+
//
3+
// CHECK-NOT: OpCapability QuadControlKHR
4+
// CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
5+
// CHECK-NOT: OpExtension "SPV_KHR_quad_control"
6+
//
7+
// CHECK-NOT: OpExecutionMode %main MaximallyReconvergesKHR
8+
// CHECK-NOT: OpExecutionMode %main RequireFullQuadsKHR
9+
10+
[WaveOpsIncludeHelperLanes]
11+
[shader("vertex")]
12+
float4 main() : SV_Position
13+
{
14+
return float4(0.0, 0.0, 0.0, 0.0);
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %dxc -T ps_6_7 -E main -spirv %s | FileCheck %s
2+
3+
// CHECK: OpCapability QuadControlKHR
4+
// CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
5+
// CHECK-DAG: OpExtension "SPV_KHR_quad_control"
6+
7+
// CHECK: OpExecutionMode %main MaximallyReconvergesKHR
8+
// CHECK: OpExecutionMode %main RequireFullQuadsKHR
9+
10+
[WaveOpsIncludeHelperLanes]
11+
float4 main(float4 pos : SV_Position) : SV_Target
12+
{
13+
return pos;
14+
}

0 commit comments

Comments
 (0)