Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ first shipped in the 1.10.2605 preview.
[#8281](https://github.com/microsoft/DirectXShaderCompiler/pull/8281).
- Function parameters can now be decorated with inline SPIR-V
[#8103](https://github.com/microsoft/DirectXShaderCompiler/issues/8103).
- Functions can now be decorated with inline SPIR-V, and
`[[vk::ext_capability]]`/`[[vk::ext_extension]]` are honored on ordinary
functions
[#8616](https://github.com/microsoft/DirectXShaderCompiler/pull/8616).
Comment on lines +71 to +74

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to go in the upcoming release section, not the just-release 1.9.2607 one.

- Fixed `vk::BufferPointer` cast methods
[#8365](https://github.com/microsoft/DirectXShaderCompiler/pull/8365).
- Fixed layout-rule propagation for `ConstantBuffer`/`TextureBuffer` function
Expand Down
16 changes: 6 additions & 10 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1826,16 +1826,12 @@ SpirvFunction *DeclResultIdMapper::getOrRegisterFn(const FunctionDecl *fn) {
spv::LinkageType::Export, fn->getLocation());
}

// Honor inline-SPIR-V attributes placed directly on a function. The
// entry-point path handles these only for entry functions, and the
// vk::ext_instruction path only for functions lowered to an instruction, so a
// plain function was previously skipped and these attributes silently
// dropped. These reuse the same helpers as the variable/parameter paths:
// [[vk::ext_decorate(d, ...)]] -> OpDecorate targeting the OpFunction
// [[vk::ext_capability(c)]] -> OpCapability for the module
// [[vk::ext_extension("...")]] -> OpExtension for the module
decorateWithIntrinsicAttrs(fn, spirvFunction);
registerCapabilitiesAndExtensionsForDecl(fn);
// Note: inline-SPIR-V attributes placed directly on a function
// ([[vk::ext_decorate]] / [[vk::ext_capability]] / [[vk::ext_extension]]) are
// applied in SpirvEmitter::doFunctionDecl, which excludes entry points. For an
// entry point, those attributes are consumed by the stage-variable path (they
// decorate the entry's interface variables, not its OpFunction), so they must
// not be applied to the source function here.

// No need to dereference to get the pointer. Function returns that are
// stand-alone aliases are already pointers to values. All other cases should
Expand Down
12 changes: 12 additions & 0 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,18 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
}
}

// Apply inline-SPIR-V attributes written directly on an ordinary function to
// its OpFunction:
// [[vk::ext_decorate(d, ...)]] -> OpDecorate targeting the OpFunction
// [[vk::ext_capability(c)]] -> OpCapability for the module
// [[vk::ext_extension("...")]] -> OpExtension for the module
// Entry points are excluded: their function-level attributes apply to stage-
// variables, not the OpFunction.
if (!isEntry) {
declIdMapper.decorateWithIntrinsicAttrs(decl, func);
declIdMapper.registerCapabilitiesAndExtensionsForDecl(decl);
}
Comment thread
mmoult marked this conversation as resolved.

if (spirvOptions.debugInfoRich) {
if (srcDebugFunction) {
spvContext.pushDebugLexicalScope(info, srcDebugFunction);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %dxc -T ps_6_0 -E main -fcgl -Vd %s -spirv | FileCheck %s --implicit-check-not "OpDecorate %src_main"

// A function-level inline-SPIR-V decoration on an *entry point* is consumed by
// the stage-variable path and applied to the entry's interface variable, not to
// the source OpFunction. (An ordinary function is handled the other way -- the
// decoration lands on its OpFunction; see spv.intrinsicDecorate.function.hlsl.)
//
// The --implicit-check-not above asserts the source function (%src_main) is
// never decorated, which is what regressed when function-target handling was
// first added and was not caught because the check below matches any target.

// CHECK: OpDecorate %out_var_SV_Target Location 23

[[vk::ext_decorate(/* Location */ 30, 23)]]
float4 main() : SV_Target {
return 1.0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

// vk::ext_decorate_id and vk::ext_decorate_string decorate a value-id target
// and have no OpFunction-target form, so applying either to a function must be
// diagnosed rather than silently dropped.
// diagnosed rather than silently dropped. Both are placed on one function so a
// single compilation reports both (translation stops after the first function
// that errors, so separate functions would only surface one).

// CHECK: error: vk::ext_decorate_string is not supported on functions
[[vk::ext_decorate_string(/* UserTypeGOOGLE */ 5636, "myType")]]
[noinline] uint DecorateString(uint x) { return x; }

// CHECK: error: vk::ext_decorate_id is not supported on functions
// CHECK-DAG: error: vk::ext_decorate_id is not supported on functions
// CHECK-DAG: error: vk::ext_decorate_string is not supported on functions
[[vk::ext_decorate_id(/* UniformId */ 27, 13)]]
[noinline] uint DecorateId(uint x) { return x; }
[[vk::ext_decorate_string(/* UserTypeGOOGLE */ 5636, "myType")]]
[noinline] uint Decorated(uint x) { return x; }

RWStructuredBuffer<uint> buf;

[numthreads(1, 1, 1)]
void main(uint3 tid : SV_DispatchThreadID) {
buf[0] = DecorateString(tid.x) + DecorateId(tid.x);
buf[0] = Decorated(tid.x);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// RUN: %dxc -T ps_6_0 -E main -fcgl -Vd -spirv -fcgl %s -spirv | FileCheck %s
// RUN: %dxc -T ps_6_0 -E main -fcgl -Vd -spirv -fcgl %s -spirv | FileCheck %s --implicit-check-not "OpDecorate %src_main"

// The --implicit-check-not above asserts the entry's source function is never
// decorated: its function-level [[vk::ext_decorate]] (e.g. Location 23 below)
// must land on the interface variable via the stage-variable path, not on the
// OpFunction. Without this, an errant OpDecorate %src_main went unnoticed
// because the Location check below matches any target.

[[vk::ext_decorate(1, 0)]]
bool b0;
Expand Down
Loading