From 3e10f4e990de940af2a72b3fdf7d210bdb113aae Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 29 Dec 2023 09:55:18 +0200 Subject: [PATCH] Add default packing qualifiers to uniform and buffer blocks The GLSL spec says they use shared packing by default, and it turns out that on AMD graphics processors this results in large alignment event for primitive types. This threw off applications using storage buffers since their contents are not reflected. --- source/glsl/generate.cpp | 18 +++++++++++++++++- source/glsl/generate.h | 6 ++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index c203c21a..4fb2d7f3 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -394,9 +394,9 @@ void InterfaceGenerator::visit(Passthrough &pass) void LayoutDefaulter::apply(Stage &stage) { + stage.content.visit(*this); if(stage.type==Stage::TESS_EVAL) { - stage.content.visit(*this); if((need_winding || need_spacing) && in_iface) { if(need_winding) @@ -423,6 +423,22 @@ void LayoutDefaulter::visit(InterfaceLayout &iface) } } +void LayoutDefaulter::visit(VariableDeclaration &var) +{ + if(var.block_declaration && (var.interface=="uniform" || var.interface=="buffer")) + { + bool has_packing = false; + if(var.layout) + { + for(auto i = var.layout->qualifiers.begin(); (!has_packing && i!=var.layout->qualifiers.end()); ++i) + has_packing = (i->name=="std140" || i->name=="std430" || i->name=="shared" || i->name=="packed"); + } + + if(!has_packing) + add_layout_qualifier(var.layout, Layout::Qualifier(var.interface=="buffer" ? "std430" : "std140")); + } +} + void ArraySizer::apply(Stage &stage) { diff --git a/source/glsl/generate.h b/source/glsl/generate.h index fac9bc6a..c5274bc3 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -79,8 +79,9 @@ private: }; /** -Adds default global input and output layout qualifiers for stages which need -them (currently tessellation evaluation). +Adds default layout qualifiers when they haven't been specified already. This +includes packing qualifiers for uniform and buffer blocks and global input and +output qualifiers for certain stages (currently tessellation evaluation). */ class LayoutDefaulter: private TraversingVisitor { @@ -94,6 +95,7 @@ public: private: void visit(InterfaceLayout &) override; + void visit(VariableDeclaration &) override; }; /** -- 2.45.2