From 63db29e887f5ceffc00a8bacbbfd2288eec48686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Wed, 13 Mar 2024 16:49:50 +0100 Subject: [PATCH] [SPIR-V] Fix static const in push constants (#6403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Struct lowering is slightly different for push constants, and we didn't checked if the field was static or not. In SPIR-V, when a field is const static, we either replace all loads by a the immediate (when usage is `Struct::field`), or create a global variable we initialize to the correct value and reference instead. The field is then ignored from the struct definition, and this variable is used. This hasn't changed with this commit, I just made push-buffers use the same logic. Fixed #6006 --------- Signed-off-by: Nathan Gauër --- tools/clang/lib/SPIRV/DeclResultIdMapper.cpp | 7 ++++ .../CodeGenSPIRV/vk.push-constant.static.hlsl | 34 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tools/clang/test/CodeGenSPIRV/vk.push-constant.static.hlsl diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp index 1603cc6046..232043323c 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp @@ -1347,6 +1347,13 @@ SpirvVariable *DeclResultIdMapper::createStructOrStructArrayVarOfExplicitLayout( const auto *declDecl = cast(subDecl); auto varType = declDecl->getType(); if (const auto *fieldVar = dyn_cast(subDecl)) { + + // Static variables are not part of the struct from a layout perspective. + // Thus, they should not be listed in the struct fields. + if (fieldVar->getStorageClass() == StorageClass::SC_Static) { + continue; + } + if (isResourceType(varType)) { createExternVar(fieldVar); continue; diff --git a/tools/clang/test/CodeGenSPIRV/vk.push-constant.static.hlsl b/tools/clang/test/CodeGenSPIRV/vk.push-constant.static.hlsl new file mode 100644 index 0000000000..ca9a7167ee --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/vk.push-constant.static.hlsl @@ -0,0 +1,34 @@ +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s + +struct S +{ + const static uint a = 1; + uint b; +}; + +// CHECK: OpMemberName %type_PushConstant_S 0 "b" +// CHECK: %type_PushConstant_S = OpTypeStruct %uint +// CHECK: %_ptr_PushConstant_type_PushConstant_S = OpTypePointer PushConstant %type_PushConstant_S + +[[vk::push_constant]] S s; +// CHECK: %a = OpVariable %_ptr_Private_uint Private +// CHECK: %s = OpVariable %_ptr_PushConstant_type_PushConstant_S PushConstant + +// CHECK: OpStore %a %uint_1 + +[numthreads(1,1,1)] +void main() +{ + uint32_t v = s.b; +// CHECK: %v = OpVariable %_ptr_Function_uint Function +// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_PushConstant_uint %s %int_0 +// CHECK: [[load:%[0-9]+]] = OpLoad %uint [[ptr]] +// CHECK: OpStore %v [[load]] + + uint32_t w = S::a; +// CHECK: OpStore %w %uint_1 + + uint32_t x = s.a; +// CHECK: [[load:%[0-9]+]] = OpLoad %uint %a +// CHECK: OpStore %x [[load]] +}