diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-11-07 17:43:57 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-11-07 19:11:46 +0300 |
commit | f1b411c9e87c4048994a899f2758ef78daa45106 (patch) | |
tree | 16029b8a658e76b6e7c22cd8e064079a1246e13c /spirv_glsl.cpp | |
parent | 1adc53b107f3432f52d97e979b27189b7b955948 (diff) |
GLSL: Deal with buffer_reference_align.
This is somewhat awkward to support, but the best effort we can do here
is to analyze various Load/Store opcodes and deduce the ideal overall
alignment based on this. This is not a 100% perfect solution, but should
be correct for any reasonable use case.
Also fix various nitpicks with BDA support while I'm at it.
Diffstat (limited to 'spirv_glsl.cpp')
-rw-r--r-- | spirv_glsl.cpp | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 61acda6a..9578502c 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -2171,8 +2171,9 @@ void CompilerGLSL::emit_buffer_block_legacy(const SPIRVariable &var) statement(""); } -void CompilerGLSL::emit_buffer_reference_block(SPIRType &type, bool forward_declaration) +void CompilerGLSL::emit_buffer_reference_block(uint32_t type_id, bool forward_declaration) { + auto &type = get<SPIRType>(type_id); string buffer_name; if (forward_declaration) @@ -2215,8 +2216,19 @@ void CompilerGLSL::emit_buffer_reference_block(SPIRType &type, bool forward_decl if (!forward_declaration) { + auto itr = physical_storage_type_to_alignment.find(type_id); + uint32_t alignment = 0; + if (itr != physical_storage_type_to_alignment.end()) + alignment = itr->second.alignment; + if (type.basetype == SPIRType::Struct) { + SmallVector<std::string> attributes; + attributes.push_back("buffer_reference"); + if (alignment) + attributes.push_back(join("buffer_reference_align = ", alignment)); + attributes.push_back(buffer_to_packing_standard(type, true)); + auto flags = ir.get_buffer_block_type_flags(type); string decorations; if (flags.get(DecorationRestrict)) @@ -2227,9 +2239,11 @@ void CompilerGLSL::emit_buffer_reference_block(SPIRType &type, bool forward_decl decorations += " writeonly"; if (flags.get(DecorationNonWritable)) decorations += " readonly"; - statement("layout(buffer_reference, ", buffer_to_packing_standard(type, true), - ")", decorations, " buffer ", buffer_name); + + statement("layout(", merge(attributes), ")", decorations, " buffer ", buffer_name); } + else if (alignment) + statement("layout(buffer_reference, buffer_reference_align = ", alignment, ") buffer ", buffer_name); else statement("layout(buffer_reference) buffer ", buffer_name); @@ -3447,28 +3461,28 @@ void CompilerGLSL::emit_resources() { for (auto type : physical_storage_non_block_pointer_types) { - emit_buffer_reference_block(get<SPIRType>(type), false); + 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, SPIRType &type) { - bool has_block_flags = has_decoration(type.self, DecorationBlock); - if (has_block_flags && type.pointer && type.pointer_depth == 1 && !type_is_array_of_pointers(type) && + ir.for_each_typed_id<SPIRType>([&](uint32_t self, SPIRType &type) { + if (type.basetype == SPIRType::Struct && type.pointer && + type.pointer_depth == 1 && !type_is_array_of_pointers(type) && type.storage == StorageClassPhysicalStorageBufferEXT) { - emit_buffer_reference_block(type, true); + emit_buffer_reference_block(self, true); } }); - ir.for_each_typed_id<SPIRType>([&](uint32_t, SPIRType &type) { - bool has_block_flags = has_decoration(type.self, DecorationBlock); - if (has_block_flags && type.pointer && type.pointer_depth == 1 && !type_is_array_of_pointers(type) && + ir.for_each_typed_id<SPIRType>([&](uint32_t self, SPIRType &type) { + if (type.basetype == SPIRType::Struct && + type.pointer && type.pointer_depth == 1 && !type_is_array_of_pointers(type) && type.storage == StorageClassPhysicalStorageBufferEXT) { - emit_buffer_reference_block(type, false); + emit_buffer_reference_block(self, false); } }); } |