Skip to content

Commit 2196a7e

Browse files
GLSL: Deal with typed OpBufferPointerEXT.
1 parent 2a5f93d commit 2196a7e

4 files changed

Lines changed: 108 additions & 4 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#version 460
2+
#extension GL_EXT_descriptor_heap : require
3+
#extension GL_EXT_nonuniform_qualifier : require
4+
#extension GL_EXT_shader_image_load_formatted : require
5+
6+
layout(location = 0) out vec4 FragColor;
7+
layout(descriptor_heap, std430) buffer SSBO
8+
{
9+
vec4 data[];
10+
} spvSSBOResourceHeap[];
11+
12+
13+
void main()
14+
{
15+
FragColor = vec4(0.0);
16+
FragColor = spvSSBOResourceHeap[2].data[2] + vec4(float(int(uint(spvSSBOResourceHeap[2].data.length()))));
17+
}
18+
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
; SPIR-V
2+
; Version: 1.0
3+
; Generator: Khronos Glslang Reference Front End; 11
4+
; Bound: 31
5+
; Schema: 0
6+
OpCapability Shader
7+
OpCapability UntypedPointersKHR
8+
OpCapability DescriptorHeapEXT
9+
OpExtension "SPV_EXT_descriptor_heap"
10+
OpExtension "SPV_KHR_untyped_pointers"
11+
%1 = OpExtInstImport "GLSL.std.450"
12+
OpMemoryModel Logical GLSL450
13+
OpEntryPoint Fragment %main "main" %FragColor %resource_heap
14+
OpExecutionMode %main OriginUpperLeft
15+
OpSource GLSL 460
16+
OpSourceExtension "GL_EXT_descriptor_heap"
17+
OpSourceExtension "GL_EXT_nonuniform_qualifier"
18+
OpName %main "main"
19+
OpName %FragColor "FragColor"
20+
OpName %resource_heap "resource_heap"
21+
OpName %SSBO "SSBO"
22+
OpMemberName %SSBO 0 "data"
23+
OpDecorate %FragColor Location 0
24+
OpDecorate %resource_heap BuiltIn ResourceHeapEXT
25+
OpDecorate %_runtimearr_v4float ArrayStride 16
26+
OpDecorate %SSBO Block
27+
OpMemberDecorate %SSBO 0 Offset 0
28+
OpDecorateId %_runtimearr_20 ArrayStrideIdEXT %21
29+
%void = OpTypeVoid
30+
%3 = OpTypeFunction %void
31+
%float = OpTypeFloat 32
32+
%v4float = OpTypeVector %float 4
33+
%_ptr_Output_v4float = OpTypePointer Output %v4float
34+
%FragColor = OpVariable %_ptr_Output_v4float Output
35+
%float_0 = OpConstant %float 0
36+
%11 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
37+
%_ptr_UniformConstant = OpTypeUntypedPointerKHR UniformConstant
38+
%resource_heap = OpUntypedVariableKHR %_ptr_UniformConstant UniformConstant
39+
%int = OpTypeInt 32 1
40+
%int_0 = OpConstant %int 0
41+
%int_2 = OpConstant %int 2
42+
%_runtimearr_v4float = OpTypeRuntimeArray %v4float
43+
%SSBO = OpTypeStruct %_runtimearr_v4float
44+
%_ptr_StorageBuffer = OpTypeUntypedPointerKHR StorageBuffer
45+
%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO
46+
%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
47+
%20 = OpTypeBufferEXT StorageBuffer
48+
%21 = OpConstantSizeOfEXT %int %20
49+
%_runtimearr_20 = OpTypeRuntimeArray %20
50+
%uint = OpTypeInt 32 0
51+
%main = OpFunction %void None %3
52+
%5 = OpLabel
53+
OpStore %FragColor %11
54+
%19 = OpUntypedAccessChainKHR %_ptr_UniformConstant %_runtimearr_20 %resource_heap %int_2
55+
%23 = OpBufferPointerEXT %_ptr_StorageBuffer_SSBO %19
56+
%25 = OpArrayLength %uint %23 0
57+
%chain = OpAccessChain %_ptr_StorageBuffer_v4float %23 %int_0 %int_2
58+
%loaded = OpLoad %v4float %chain
59+
%26 = OpBitcast %int %25
60+
%27 = OpConvertSToF %float %26
61+
%28 = OpLoad %v4float %FragColor
62+
%29 = OpCompositeConstruct %v4float %27 %27 %27 %27
63+
%30 = OpFAdd %v4float %loaded %29
64+
OpStore %FragColor %30
65+
OpReturn
66+
OpFunctionEnd

spirv_cross.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5448,8 +5448,15 @@ void Compiler::analyze_descriptor_heap_types()
54485448
switch (opcode)
54495449
{
54505450
case OpBufferPointerEXT:
5451-
buffer_pointers[args[1]] = compiler.get<SPIRType>(args[0]).storage;
5451+
{
5452+
auto &ptr_type = compiler.get<SPIRType>(args[0]);
5453+
// BufferPointerEXT can return untyped or typed pointers.
5454+
// If it's typed, we resolve it here.
5455+
if (ptr_type.basetype == SPIRType::Struct)
5456+
add_unique_type(ptr_type.self, ptr_type.storage);
5457+
buffer_pointers[args[1]] = args[0];
54525458
break;
5459+
}
54535460

54545461
case OpUntypedAccessChainKHR:
54555462
case OpUntypedInBoundsAccessChainKHR:
@@ -5525,7 +5532,13 @@ void Compiler::analyze_descriptor_heap_types()
55255532
{
55265533
SPIRV_CROSS_THROW("BufferPointerEXT must reference a block type.");
55275534
}
5528-
add_unique_type(data_type.self, buffer_pointers[args[3]]);
5535+
5536+
auto &buffer_type = compiler.get<SPIRType>(buffer_pointers[args[3]]);
5537+
if (buffer_type.basetype == SPIRType::Void)
5538+
{
5539+
// This is where the pointer becomes typed, so register it here.
5540+
add_unique_type(data_type.self, buffer_type.storage);
5541+
}
55295542
}
55305543
break;
55315544
}
@@ -5540,7 +5553,7 @@ void Compiler::analyze_descriptor_heap_types()
55405553
explicit HeapHandler(Compiler &compiler_) : OpcodeHandler(compiler_) {}
55415554

55425555
std::vector<std::pair<uint32_t, StorageClass>> heap_types;
5543-
std::unordered_map<uint32_t, StorageClass> buffer_pointers;
5556+
std::unordered_map<uint32_t, TypeID> buffer_pointers;
55445557

55455558
void add_unique_type(uint32_t id, StorageClass storage)
55465559
{

spirv_glsl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13107,7 +13107,14 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
1310713107
if (!chain_expr || !chain_expr->access_chain)
1310813108
SPIRV_CROSS_THROW("Expected to see access chain for BufferPointerEXT.");
1310913109

13110-
auto &expr = set<SPIRExpression>(result_id, to_expression(ptr_id), type_id, true);
13110+
auto e = to_expression(ptr_id);
13111+
13112+
// BufferPointerEXT can return a typed pointer, in which case we need to resolve the heap alias now.
13113+
auto &type = get<SPIRType>(type_id);
13114+
if (type.basetype == SPIRType::Struct)
13115+
e = join("spv", to_name(type.self), e);
13116+
13117+
auto &expr = set<SPIRExpression>(result_id, std::move(e), type_id, true);
1311113118
expr.loaded_from = chain_expr->loaded_from;
1311213119
expr.access_chain = true;
1311313120
expr.buffer_pointer = true;

0 commit comments

Comments
 (0)