Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/SPIR-V.rst
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,21 @@ Right now the following ``<builtin>`` are supported:
Please see Vulkan spec. `15.9. Built-In Variables <https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#interfaces-builtin-variables>`_
for detailed explanation of these builtins.

Helper Lane Support
~~~~~~~~~~~~~~~~~~~

Shader Model 6.7 introduces the `[WaveOpsIncludeHelperLanes]` attribute. When this
attribute is applied to a shader entry point, the SPIR-V backend will:

1. Add the ``SPV_KHR_maximal_reconvergence`` and ``SPV_KHR_quad_control``
extensions to the module.
2. Add the ``QuadControlKHR`` capability.
3. Add the ``MaximallyReconvergesKHR`` and ``RequireFullQuadsKHR`` execution modes
to the entry point.

This ensures that helper lanes are included in wave operations, which is the
behavior required by the HLSL specification.

Supported extensions
~~~~~~~~~~~~~~~~~~~~

Expand Down
21 changes: 21 additions & 0 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,27 @@ void SpirvEmitter::HandleTranslationUnit(ASTContext &context) {
SourceLocation());
}

for (uint32_t i = 0; i < workQueue.size(); ++i) {
const FunctionInfo *entryInfo = workQueue[i];
if (entryInfo->isEntryFunction) {
const auto *funcDecl = entryInfo->funcDecl;
if (funcDecl->hasAttr<HLSLWaveOpsIncludeHelperLanesAttr>()) {
spvBuilder.requireExtension("SPV_KHR_maximal_reconvergence",
funcDecl->getLocation());
spvBuilder.requireExtension("SPV_KHR_quad_control",
funcDecl->getLocation());
spvBuilder.requireCapability(spv::Capability::QuadControlKHR,
funcDecl->getLocation());
spvBuilder.addExecutionMode(entryInfo->entryFunction,
spv::ExecutionMode::MaximallyReconvergesKHR,
{}, funcDecl->getLocation());
spvBuilder.addExecutionMode(entryInfo->entryFunction,
spv::ExecutionMode::RequireFullQuadsKHR, {},
funcDecl->getLocation());
}
}
}

// For Vulkan 1.2 and later, add SignedZeroInfNanPreserve when -Gis is
// provided to preserve NaN/Inf and signed zeros.
if (spirvOptions.IEEEStrict) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// RUN: %dxc -T lib_6_7 -spirv %s | FileCheck %s

// CHECK: OpCapability QuadControlKHR
// CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
// CHECK-DAG: OpExtension "SPV_KHR_quad_control"

// CHECK: OpEntryPoint Fragment %ps_main1 "ps_main1"
// CHECK: OpEntryPoint Fragment %ps_main2 "ps_main2"
// CHECK: OpEntryPoint Fragment %ps_main3 "ps_main3"

// CHECK-DAG: OpExecutionMode %ps_main1 MaximallyReconvergesKHR
// CHECK-DAG: OpExecutionMode %ps_main1 RequireFullQuadsKHR

// CHECK-NOT: OpExecutionMode %ps_main2 MaximallyReconvergesKHR
// CHECK-NOT: OpExecutionMode %ps_main2 RequireFullQuadsKHR

// CHECK-DAG: OpExecutionMode %ps_main3 MaximallyReconvergesKHR
// CHECK-DAG: OpExecutionMode %ps_main3 RequireFullQuadsKHR

[WaveOpsIncludeHelperLanes]
[shader("pixel")]
void ps_main1() : SV_Target0
{
}

[shader("pixel")]
void ps_main2() : SV_Target0
{
}

[WaveOpsIncludeHelperLanes]
[shader("pixel")]
void ps_main3() : SV_Target0
{
}
14 changes: 14 additions & 0 deletions tools/clang/test/CodeGenSPIRV/wave-ops-include-helper-lanes.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// RUN: %dxc -T ps_6_7 -E main -spirv %s | FileCheck %s

// CHECK: OpCapability QuadControlKHR
// CHECK-DAG: OpExtension "SPV_KHR_maximal_reconvergence"
// CHECK-DAG: OpExtension "SPV_KHR_quad_control"

// CHECK: OpExecutionMode %main MaximallyReconvergesKHR
// CHECK: OpExecutionMode %main RequireFullQuadsKHR

[WaveOpsIncludeHelperLanes]
float4 main(float4 pos : SV_Position) : SV_Target
{
return pos;
}