Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2021-11-07 17:43:57 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2021-11-07 19:11:46 +0300
commitf1b411c9e87c4048994a899f2758ef78daa45106 (patch)
tree16029b8a658e76b6e7c22cd8e064079a1246e13c /spirv_glsl.cpp
parent1adc53b107f3432f52d97e979b27189b7b955948 (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.cpp38
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);
}
});
}