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
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
{
uint8_t value;

View File

@ -8,7 +8,8 @@ struct Foo
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;
};

View File

@ -2,6 +2,7 @@
#extension GL_EXT_buffer_reference2 : require
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
{
uvec4 value;

View File

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

View File

@ -7,6 +7,7 @@
#extension GL_EXT_buffer_reference2 : require
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
{
uint value;

View File

@ -7,6 +7,7 @@
#extension GL_EXT_buffer_reference2 : require
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
{
uint value[];

View File

@ -54,6 +54,6 @@
%22 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_Foo %_ %int_1
%23 = OpLoad %_ptr_PhysicalStorageBuffer_Foo %22
%26 = OpAccessChain %_ptr_PhysicalStorageBuffer_uint %23 %int_0
OpStore %26 %uint_1 Aligned 16
OpStore %26 %uint_1 Aligned 8
OpReturn
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);
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 ...
// 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)
{
for (auto type : physical_storage_non_block_pointer_types)
emit_buffer_reference_block(type, false);
// Output buffer reference blocks.
// Do this in two stages, one with forward declaration,
// and one without. Buffer reference blocks can reference themselves
// to support things like linked lists.
ir.for_each_typed_id<SPIRType>([&](uint32_t id, SPIRType &type) {
if (is_physical_pointer_to_buffer_block(type))
emit_buffer_reference_block(id, true);
if (is_physical_pointer(type))
{
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) {
if (is_physical_pointer_to_buffer_block(type))
emit_buffer_reference_block(id, false);