Skip to content

Commit

Permalink
Add linkage capability based on decorations (#6900)
Browse files Browse the repository at this point in the history
We currently add the linkage attribute only if there are no extry
pointer. However, there are cases where we may want an extry point with
an exported function.

This commit add the linkage capability any time it sees the linkage
attribute decoration. Note I do not add the linkage attribute all of the
time and leave it to the capability trimming pass because having this
capability with vulkan shaders is generally illegal, and I don't want
the unoptimized code to fail validation.

Fixes #6738
  • Loading branch information
s-perron authored Sep 6, 2024
1 parent 0fd84aa commit 937c8c8
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 11 deletions.
13 changes: 6 additions & 7 deletions tools/clang/lib/SPIRV/CapabilityVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,9 @@ bool CapabilityVisitor::visit(SpirvDecoration *decor) {

break;
}
case spv::Decoration::LinkageAttributes:
addCapability(spv::Capability::Linkage);
break;
default:
break;
}
Expand Down Expand Up @@ -847,16 +850,12 @@ bool CapabilityVisitor::visit(SpirvReadClock *inst) {
}

bool CapabilityVisitor::visit(SpirvModule *, Visitor::Phase phase) {
// If there are no entry-points in the module (hence shaderModel is not set),
// add the Linkage capability. This allows library shader models to use
// 'export' attribute on functions, and generate an "incomplete/partial"
// SPIR-V binary.
// ExecutionModel::Max means that no entrypoints exist, therefore we should
// add the Linkage Capability.
// If there are no entry-points in the module add the Shader capability.
// This allows library shader models with no entry pointer and just exported
// function. ExecutionModel::Max means that no entrypoints exist.
if (phase == Visitor::Phase::Done &&
shaderModel == spv::ExecutionModel::Max) {
addCapability(spv::Capability::Shader);
addCapability(spv::Capability::Linkage);
}

// SPIRV-Tools now has a pass to trim superfluous capabilities. This means we
Expand Down
4 changes: 2 additions & 2 deletions tools/clang/test/CodeGenSPIRV/fn.export.hlsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %dxc -T lib_6_3 -fspv-target-env=universal1.5 -fcgl %s -spirv | FileCheck %s

// CHECK: OpCapability Shader
// CHECK: OpCapability Linkage
// CHECK-DAG: OpCapability Shader
// CHECK-DAG: OpCapability Linkage
RWBuffer< float4 > output : register(u1);

// CHECK: OpDecorate %main LinkageAttributes "main" Export
Expand Down
13 changes: 13 additions & 0 deletions tools/clang/test/CodeGenSPIRV/fn.export.with.entrypoint.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %dxc -T as_6_6 -E main -fspv-target-env=vulkan1.3 -fcgl %s -spirv | FileCheck %s

// CHECK: OpCapability Linkage
// CHECK: OpDecorate %external_function LinkageAttributes "external_function" Export
export int external_function() {
return 1;
}

[numthreads(8, 8, 1)]
void main() {
external_function();
return;
}
4 changes: 2 additions & 2 deletions tools/clang/test/CodeGenSPIRV/fn.fixfuncall-linkage.hlsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %dxc -T lib_6_3 -fspv-target-env=universal1.5 -fspv-fix-func-call-arguments -O0 %s -spirv | FileCheck %s

// CHECK: OpCapability Shader
// CHECK: OpCapability Linkage
// CHECK-DAG: OpCapability Shader
// CHECK-DAG: OpCapability Linkage
RWStructuredBuffer< float4 > output : register(u1);

// CHECK: OpDecorate %main LinkageAttributes "main" Export
Expand Down

0 comments on commit 937c8c8

Please sign in to comment.