diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 75eba81c57..f5fe06f502 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -22,29 +22,32 @@ The included licenses apply to the following files: Place release notes for the upcoming release below this line and remove this line upon naming the release. Refer to previous for appropriate section names. -#### Bug Fixes - -- Fixed derivative operations being moved into divergent control flow, which - could produce incorrect results - [#8001](https://github.com/microsoft/DirectXShaderCompiler/issues/8001). -- SPIR-V: Fixed an invalid `OpSelect` being generated when optimizing for - SPIR-V 1.3 and earlier - [#8603](https://github.com/microsoft/DirectXShaderCompiler/issues/8603). -- Fix a crash generating DXIL from sources containing a dynamic resource heap - access that was discarded. Identified during development of SPIR-V support for - [descriptor heaps](https://github.com/microsoft/DirectXShaderCompiler/pull/8517#discussion_r3752113078). - #### HLSL Language - Casting a scalar to a struct or array containing a resource is now an error instead of crashing [#6661](https://github.com/microsoft/DirectXShaderCompiler/issues/6661). +#### SPIR-V + +- `[[vk::ext_decorate]]`, `[[vk::ext_capability]]`, and `[[vk::ext_extension]]` + are now honored on ordinary functions + [#8719](https://github.com/microsoft/DirectXShaderCompiler/pull/8719). + #### Bug Fixes +- Fixed derivative operations being moved into divergent control flow, which + could produce incorrect results + [#8001](https://github.com/microsoft/DirectXShaderCompiler/issues/8001). +- SPIR-V: Fixed an invalid `OpSelect` being generated when optimizing for + SPIR-V 1.3 and earlier + [#8603](https://github.com/microsoft/DirectXShaderCompiler/issues/8603). - Fixed internal compiler errors when a member method is called on a ray payload or on one of its fields with payload access qualifiers enabled [#6464](https://github.com/microsoft/DirectXShaderCompiler/issues/6464). +- Fix a crash generating DXIL from sources containing a dynamic resource heap + access that was discarded. Identified during development of SPIR-V support for + [descriptor heaps](https://github.com/microsoft/DirectXShaderCompiler/pull/8517#discussion_r3752113078). ### Upcoming Preview Release diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp index 3a88334ffc..6f9d497cad 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp @@ -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 on a function are applied in + // SpirvEmitter::doFunctionDecl. [[vk::ext_decorate]] is applied only to + // non-entry functions; for an entry point it is consumed by the + // stage-variable path (decorating interface variables, not the OpFunction). + // [[vk::ext_capability]] and [[vk::ext_extension]] are applied to every + // function, entry points included. // No need to dereference to get the pointer. Function returns that are // stand-alone aliases are already pointers to values. All other cases should diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index f05c0d9553..2f18e9b6e2 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -1635,6 +1635,19 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) { } } + // Apply [[vk::ext_decorate]] written on an ordinary function to its + // OpFunction. Entry points are excluded: their function-level decorations are + // applied to the interface variables by the stage-variable path, and a + // decoration such as Location is invalid on an OpFunction. + if (!isEntry) + declIdMapper.decorateWithIntrinsicAttrs(decl, func); + + // Register [[vk::ext_capability]]/[[vk::ext_extension]] for every function, + // entry points included. Non-ray-tracing entries are also covered by + // processInlineSpirvAttributes (this is idempotent), but ray-tracing entries + // return before that runs, so this is their only registration path. + declIdMapper.registerCapabilitiesAndExtensionsForDecl(decl); + if (spirvOptions.debugInfoRich) { if (srcDebugFunction) { spvContext.pushDebugLexicalScope(info, srcDebugFunction); diff --git a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.entry.hlsl b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.entry.hlsl new file mode 100644 index 0000000000..28536668b8 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.entry.hlsl @@ -0,0 +1,16 @@ +// 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 in another way, see +// spv.intrinsicDecorate.function.hlsl.) +// +// The --implicit-check-not above asserts the source function (%src_main) was +// not decorated by the inline assembly intended for the stage variables. + +// CHECK: OpDecorate %out_var_SV_Target Location 23 + +[[vk::ext_decorate(/* Location */ 30, 23)]] +float4 main() : SV_Target { + return 1.0; +} diff --git a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.entry.raytracing.hlsl b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.entry.raytracing.hlsl new file mode 100644 index 0000000000..1f3e7ce16c --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.entry.raytracing.hlsl @@ -0,0 +1,15 @@ +// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 -fcgl -Vd %s -spirv | FileCheck %s + +// A ray-tracing entry point returns from emitEntryFunctionWrapper (via the +// isRay() path) before processInlineSpirvAttributes runs, so unlike other entry +// stages its [[vk::ext_capability]]/[[vk::ext_extension]] are registered only by +// the general function path in doFunctionDecl. This guards that they are still +// emitted for ray-tracing entries. + +// CHECK-DAG: OpCapability Int8 +// CHECK-DAG: OpExtension "some_extension" + +[[vk::ext_capability(/* Int8 */ 39)]] +[[vk::ext_extension("some_extension")]] +[shader("raygeneration")] +void main() {} diff --git a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.function.error.hlsl b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.function.error.hlsl index 019628d34b..c209ca7d92 100644 --- a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.function.error.hlsl +++ b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.function.error.hlsl @@ -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 buf; [numthreads(1, 1, 1)] void main(uint3 tid : SV_DispatchThreadID) { - buf[0] = DecorateString(tid.x) + DecorateId(tid.x); + buf[0] = Decorated(tid.x); } diff --git a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.hlsl b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.hlsl index 9e69257956..3380d855ab 100644 --- a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.hlsl +++ b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.hlsl @@ -1,4 +1,8 @@ -// 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 not +// decorated by [[vk::ext_decorate]] (e.g. Location 23 below) intended for the +// interface variable. [[vk::ext_decorate(1, 0)]] bool b0;