GLSL: Forward declare non-block BDA types as well.

With non-block structs, we can have pointers in those types too.
This commit is contained in:
Hans-Kristian Arntzen 2024-01-18 12:56:31 +01:00
parent 871ac0e5b7
commit 3da5bc7a57
8 changed files with 29 additions and 8 deletions

View File

@ -9,6 +9,9 @@
#extension GL_EXT_buffer_reference2 : require #extension GL_EXT_buffer_reference2 : require
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout(buffer_reference) buffer uintPointer;
layout(buffer_reference) buffer uint8_tPointer;
layout(buffer_reference) buffer uint8_t12_Pointer;
layout(buffer_reference) buffer uint8_tPointer layout(buffer_reference) buffer uint8_tPointer
{ {
uint8_t value; uint8_t value;

View File

@ -8,7 +8,8 @@ struct Foo
uint b; uint b;
}; };
layout(std430, buffer_reference, buffer_reference_align = 16) buffer FooPointer layout(buffer_reference) buffer FooPointer;
layout(std430, buffer_reference, buffer_reference_align = 8) buffer FooPointer
{ {
Foo value; Foo value;
}; };

View File

@ -2,6 +2,7 @@
#extension GL_EXT_buffer_reference2 : require #extension GL_EXT_buffer_reference2 : require
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(buffer_reference) buffer uvec4Pointer;
layout(buffer_reference, buffer_reference_align = 8) buffer uvec4Pointer layout(buffer_reference, buffer_reference_align = 8) buffer uvec4Pointer
{ {
uvec4 value; uvec4 value;

View File

@ -2,6 +2,7 @@
#extension GL_EXT_buffer_reference2 : require #extension GL_EXT_buffer_reference2 : require
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(buffer_reference) buffer uvec4Pointer;
layout(buffer_reference) buffer uvec4Pointer layout(buffer_reference) buffer uvec4Pointer
{ {
uvec4 value; uvec4 value;

View File

@ -7,6 +7,7 @@
#extension GL_EXT_buffer_reference2 : require #extension GL_EXT_buffer_reference2 : require
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(buffer_reference) buffer uintPointer;
layout(buffer_reference, buffer_reference_align = 4) buffer uintPointer layout(buffer_reference, buffer_reference_align = 4) buffer uintPointer
{ {
uint value; uint value;

View File

@ -7,6 +7,7 @@
#extension GL_EXT_buffer_reference2 : require #extension GL_EXT_buffer_reference2 : require
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(buffer_reference) buffer uint0_Pointer;
layout(buffer_reference, buffer_reference_align = 4) buffer uint0_Pointer layout(buffer_reference, buffer_reference_align = 4) buffer uint0_Pointer
{ {
uint value[]; uint value[];

View File

@ -54,6 +54,6 @@
%22 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_Foo %_ %int_1 %22 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_Foo %_ %int_1
%23 = OpLoad %_ptr_PhysicalStorageBuffer_Foo %22 %23 = OpLoad %_ptr_PhysicalStorageBuffer_Foo %22
%26 = OpAccessChain %_ptr_PhysicalStorageBuffer_uint %23 %int_0 %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_uint %23 %int_0
OpStore %26 %uint_1 Aligned 16 OpStore %26 %uint_1 Aligned 8
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -2326,7 +2326,7 @@ void CompilerGLSL::emit_buffer_reference_block(uint32_t type_id, bool forward_de
auto &type = get<SPIRType>(type_id); auto &type = get<SPIRType>(type_id);
string buffer_name; string buffer_name;
if (forward_declaration) if (forward_declaration && is_physical_pointer_to_buffer_block(type))
{ {
// Block names should never alias, but from HLSL input they kind of can because block types are reused for UAVs ... // Block names should never alias, but from HLSL input they kind of can because block types are reused for UAVs ...
// Allow aliased name since we might be declaring the block twice. Once with buffer reference (forward declared) and one proper declaration. // Allow aliased name since we might be declaring the block twice. Once with buffer reference (forward declared) and one proper declaration.
@ -3722,18 +3722,31 @@ void CompilerGLSL::emit_resources()
if (ir.addressing_model == AddressingModelPhysicalStorageBuffer64EXT) if (ir.addressing_model == AddressingModelPhysicalStorageBuffer64EXT)
{ {
for (auto type : physical_storage_non_block_pointer_types)
emit_buffer_reference_block(type, false);
// Output buffer reference blocks. // Output buffer reference blocks.
// Do this in two stages, one with forward declaration, // Do this in two stages, one with forward declaration,
// and one without. Buffer reference blocks can reference themselves // and one without. Buffer reference blocks can reference themselves
// to support things like linked lists. // to support things like linked lists.
ir.for_each_typed_id<SPIRType>([&](uint32_t id, SPIRType &type) { ir.for_each_typed_id<SPIRType>([&](uint32_t id, SPIRType &type) {
if (is_physical_pointer_to_buffer_block(type)) if (is_physical_pointer(type))
emit_buffer_reference_block(id, true); {
bool emit_type = true;
if (!is_physical_pointer_to_buffer_block(type))
{
// Only forward-declare if we intend to emit it in the non_block_pointer types.
// Otherwise, these are just "benign" pointer types that exist as a result of access chains.
emit_type = std::find(physical_storage_non_block_pointer_types.begin(),
physical_storage_non_block_pointer_types.end(),
id) != physical_storage_non_block_pointer_types.end();
}
if (emit_type)
emit_buffer_reference_block(id, true);
}
}); });
for (auto type : physical_storage_non_block_pointer_types)
emit_buffer_reference_block(type, false);
ir.for_each_typed_id<SPIRType>([&](uint32_t id, SPIRType &type) { ir.for_each_typed_id<SPIRType>([&](uint32_t id, SPIRType &type) {
if (is_physical_pointer_to_buffer_block(type)) if (is_physical_pointer_to_buffer_block(type))
emit_buffer_reference_block(id, false); emit_buffer_reference_block(id, false);