Skip to content

Commit c2ed9ad

Browse files
authored
[SPIRV] Avoid invlid SIPR-V (microsoft#7107)
1. Array with the block decoration are not suppose to have an array stride. 2. The CullPrimitive output should be an array of bools.
1 parent b65a931 commit c2ed9ad

6 files changed

+31
-13
lines changed

tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,16 @@ bool isBooleanStageIOVar(const NamedDecl *decl, QualType type,
392392
// [[vk::builtin(...)]] makes the decl a built-in stage variable.
393393
// IsFrontFace (if used as PSIn) is the only known boolean built-in stage
394394
// variable.
395-
const bool isBooleanBuiltin =
396-
(decl->getAttr<VKBuiltInAttr>() != nullptr) ||
397-
(semanticKind == hlsl::Semantic::Kind::IsFrontFace &&
398-
sigPointKind == hlsl::SigPoint::Kind::PSIn);
395+
bool isBooleanBuiltin = false;
396+
397+
if ((decl->getAttr<VKBuiltInAttr>() != nullptr))
398+
isBooleanBuiltin = true;
399+
else if (semanticKind == hlsl::Semantic::Kind::IsFrontFace &&
400+
sigPointKind == hlsl::SigPoint::Kind::PSIn) {
401+
isBooleanBuiltin = true;
402+
} else if (semanticKind == hlsl::Semantic::Kind::CullPrimitive) {
403+
isBooleanBuiltin = true;
404+
}
399405

400406
// TODO: support boolean matrix stage I/O variable if needed.
401407
QualType elemType = {};
@@ -1816,24 +1822,24 @@ void DeclResultIdMapper::createCounterVar(
18161822
}
18171823

18181824
const SpirvType *counterType = spvContext.getACSBufferCounterType();
1825+
llvm::Optional<uint32_t> noArrayStride;
18191826
QualType declType = decl->getType();
18201827
if (declType->isArrayType()) {
18211828
// Vulkan does not support multi-dimentional arrays of resource, so we
18221829
// assume the array is a single dimensional array.
18231830
assert(!declType->getArrayElementTypeNoTypeQual()->isArrayType());
1824-
uint32_t arrayStride = 4;
1831+
18251832
if (const auto *constArrayType =
18261833
astContext.getAsConstantArrayType(declType)) {
18271834
counterType = spvContext.getArrayType(
1828-
counterType, constArrayType->getSize().getZExtValue(), arrayStride);
1835+
counterType, constArrayType->getSize().getZExtValue(), noArrayStride);
18291836
} else {
18301837
assert(declType->isIncompleteArrayType());
1831-
counterType = spvContext.getRuntimeArrayType(counterType, arrayStride);
1838+
counterType = spvContext.getRuntimeArrayType(counterType, noArrayStride);
18321839
}
18331840
} else if (isResourceDescriptorHeap(decl->getType()) ||
18341841
isSamplerDescriptorHeap(decl->getType())) {
1835-
counterType =
1836-
spvContext.getRuntimeArrayType(counterType, /* arrayStride= */ 4);
1842+
counterType = spvContext.getRuntimeArrayType(counterType, noArrayStride);
18371843
}
18381844

18391845
// {RW|Append|Consume}StructuredBuffer are all in Uniform storage class.

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8095,7 +8095,8 @@ void SpirvEmitter::assignToMSOutAttribute(
80958095
// All other attribute writes are handled below.
80968096
auto *varInstr = declIdMapper.getStageVarInstruction(decl);
80978097
QualType valueType = value->getAstResultType();
8098-
if (valueType->isBooleanType()) {
8098+
if (valueType->isBooleanType() &&
8099+
semanticInfo.getKind() != hlsl::Semantic::Kind::CullPrimitive) {
80998100
// Externally visible variables are changed to uint, so we need to cast the
81008101
// value to uint.
81018102
value = castToInt(value, valueType, astContext.UnsignedIntTy, loc);

tools/clang/test/CodeGenSPIRV/meshshading.ext.cullprimative.hlsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct MeshletPrimitiveOut
99
// specification says that externally visible variables cannot be bool.
1010
// CHECK: OpDecorate [[var:%[0-9]+]] BuiltIn CullPrimitiveEXT
1111
// CHECK: OpDecorate [[var]] PerPrimitiveEXT
12-
// CHECK: [[var]] = OpVariable %_ptr_Output__arr_uint_uint_2 Output
12+
// CHECK: [[var]] = OpVariable %_ptr_Output__arr_bool_uint_2 Output
1313

1414
struct VertOut
1515
{
@@ -28,7 +28,7 @@ void main(uint svGroupIndex : SV_GROUPINDEX,
2828

2929
// Make sure that the references to m_cullPrimitive use uints.
3030
// CHECK: [[idx:%[0-9]+]] = OpLoad %uint %gl_LocalInvocationIndex
31-
// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Output_uint [[var]] [[idx]]
32-
// CHECK: OpStore [[ac]] %uint_0
31+
// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Output_bool [[var]] [[idx]]
32+
// CHECK: OpStore [[ac]] %false
3333
primitives[svGroupIndex].m_cullPrimitive = false;
3434
}

tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.acbuffer.hlsl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
// CHECK: OpDecorate [[resource_heap_abuffer]] Binding 0
1010
// CHECK: OpDecorate [[resource_heap_abuffer_counter:%[_a-zA-Z0-9]+]] DescriptorSet 0
1111
// CHECK: OpDecorate [[resource_heap_abuffer_counter]] Binding 1
12+
// CHECK-NOT: OpDecorate %_runtimearr_type_ACSBuffer_counter ArrayStride
13+
// CHECK: OpDecorate %type_ACSBuffer_counter BufferBlock
14+
// CHECK-NOT: OpDecorate %_runtimearr_type_ACSBuffer_counter ArrayStride
1215

1316

1417
// CHECK-DAG: [[ra_uint_t:%[_a-zA-Z0-9]+]] = OpTypeRuntimeArray %uint

tools/clang/test/CodeGenSPIRV/type.rwstructured-buffer.array.counter.hlsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ struct PSInput
77

88
// CHECK: OpDecorate %g_rwbuffer DescriptorSet 2
99
// CHECK: OpDecorate %g_rwbuffer Binding 0
10+
// CHECK-NOT: OpDecorate %_arr_type_ACSBuffer_counter_uint_5 ArrayStride
1011
// CHECK: OpDecorate %counter_var_g_rwbuffer DescriptorSet 2
1112
// CHECK: OpDecorate %counter_var_g_rwbuffer Binding 1
13+
// CHECK-NOT: OpDecorate %_arr_type_ACSBuffer_counter_uint_5 ArrayStride
14+
// CHECK: OpDecorate %type_ACSBuffer_counter BufferBlock
15+
// CHECK-NOT: OpDecorate %_runtimearr_type_ACSBuffer_counter ArrayStride
1216

1317
// CHECK: %g_rwbuffer = OpVariable %_ptr_Uniform__arr_type_RWStructuredBuffer_uint_uint_5 Uniform
1418
// CHECK: %counter_var_g_rwbuffer = OpVariable %_ptr_Uniform__arr_type_ACSBuffer_counter_uint_5 Uniform

tools/clang/test/CodeGenSPIRV/type.rwstructured-buffer.array.unbounded.counter.hlsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ struct PSInput
77

88
// CHECK: OpDecorate %g_rwbuffer DescriptorSet 2
99
// CHECK: OpDecorate %g_rwbuffer Binding 0
10+
// CHECK-NOT: OpDecorate %_runtimearr_type_ACSBuffer_counter ArrayStride
1011
// CHECK: OpDecorate %counter_var_g_rwbuffer DescriptorSet 2
1112
// CHECK: OpDecorate %counter_var_g_rwbuffer Binding 1
13+
// CHECK-NOT: OpDecorate %_runtimearr_type_ACSBuffer_counter ArrayStride
14+
// CHECK: OpDecorate %type_ACSBuffer_counter BufferBlock
15+
// CHECK-NOT: OpDecorate %_runtimearr_type_ACSBuffer_counter ArrayStride
1216

1317
// CHECK: %g_rwbuffer = OpVariable %_ptr_Uniform__runtimearr_type_RWStructuredBuffer_uint Uniform
1418
// CHECK: %counter_var_g_rwbuffer = OpVariable %_ptr_Uniform__runtimearr_type_ACSBuffer_counter Uniform

0 commit comments

Comments
 (0)