Skip to content

Commit

Permalink
[SPIR-V] Fix static const in push constants (microsoft#6403)
Browse files Browse the repository at this point in the history
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 microsoft#6006

---------

Signed-off-by: Nathan Gauër <[email protected]>
  • Loading branch information
Keenuts authored Mar 13, 2024
1 parent 3fc84bf commit 63db29e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
7 changes: 7 additions & 0 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,13 @@ SpirvVariable *DeclResultIdMapper::createStructOrStructArrayVarOfExplicitLayout(
const auto *declDecl = cast<DeclaratorDecl>(subDecl);
auto varType = declDecl->getType();
if (const auto *fieldVar = dyn_cast<VarDecl>(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;
Expand Down
34 changes: 34 additions & 0 deletions tools/clang/test/CodeGenSPIRV/vk.push-constant.static.hlsl
Original file line number Diff line number Diff line change
@@ -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]]
}

0 comments on commit 63db29e

Please sign in to comment.