Skip to content

Commit 2a6bacd

Browse files
authored
[SPIRV] Treat vk::Spirv*Type as opaque when reconstructing (#7454)
It is possible to have two struct types in spir-v that are the same except for the decorations. Sometimes we have to reconstruct the value from one type to another. In the case of a vk::SpirvType, we do not know anything about the type, so this should not happen. When trying to reconstuct the value, we should simply return the original value. Fixes #6963
1 parent 14e1f83 commit 2a6bacd

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7081,14 +7081,17 @@ SpirvInstruction *SpirvEmitter::reconstructValue(SpirvInstruction *srcVal,
70817081

70827082
// Structs
70837083
if (const auto *recordType = valType->getAs<RecordType>()) {
7084-
assert(recordType->isStructureType());
7085-
70867084
if (isTypeInVkNamespace(recordType) &&
7087-
recordType->getDecl()->getName().equals("BufferPointer")) {
7088-
// Uniquely among structs, vk::BufferPointer<T> lowers to a pointer type.
7085+
(recordType->getDecl()->getName().equals("BufferPointer") ||
7086+
recordType->getDecl()->getName().equals("SpirvType") ||
7087+
recordType->getDecl()->getName().equals("SpirvOpaqueType"))) {
7088+
// vk::BufferPointer<T> lowers to a pointer type. No need to reconstruct
7089+
// the value. The vk::Spirv*Type should be treated an opaque type. All we
7090+
// can do is leave it the same.
70897091
return srcVal;
70907092
}
70917093

7094+
assert(recordType->isStructureType());
70927095
LowerTypeVisitor lowerTypeVisitor(astContext, spvContext, spirvOptions,
70937096
spvBuilder);
70947097
const StructType *spirvStructType =

tools/clang/test/CodeGenSPIRV/intrinsics.vkrawbufferload.hlsl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,16 @@ struct BufferData {
1212
float3 v;
1313
};
1414

15+
using MyInt = vk::SpirvType<
16+
/*spv::OpTypeInt*/21,
17+
1,1, // size and alignment
18+
vk::Literal<vk::integral_constant<uint,16> >, // bits
19+
vk::Literal<vk::integral_constant<uint,1> > // signed
20+
>;
21+
1522
uint64_t Address;
23+
24+
[[vk::ext_capability(/* Int16 */ 22)]]
1625
float4 main() : SV_Target0 {
1726
// CHECK: [[addr:%[0-9]+]] = OpLoad %ulong
1827
// CHECK-NEXT: [[buf:%[0-9]+]] = OpBitcast %_ptr_PhysicalStorageBuffer_float [[addr]]
@@ -50,5 +59,10 @@ float4 main() : SV_Target0 {
5059
// CHECK-NEXT: [[load:%[0-9]+]] = OpLoad %BufferData_0 [[buf]] Aligned 4
5160
d = vk::RawBufferLoad<BufferData>(0);
5261

62+
// CHECK: [[buf:%[0-9]+]] = OpBitcast %_ptr_PhysicalStorageBuffer_spirvIntrinsicType %ulong_0
63+
// CHECK-NEXT: [[load:%[0-9]+]] = OpLoad %spirvIntrinsicType [[buf]] Aligned 4
64+
// CHECK-NEXT: OpStore %mi [[load]]
65+
MyInt mi = vk::RawBufferLoad<MyInt>(0);
66+
5367
return float4(w.x, x, y, z);
5468
}

0 commit comments

Comments
 (0)