diff --git a/qrenderdoc/Code/BufferFormatter.cpp b/qrenderdoc/Code/BufferFormatter.cpp index 3eae0da12..24174b655 100644 --- a/qrenderdoc/Code/BufferFormatter.cpp +++ b/qrenderdoc/Code/BufferFormatter.cpp @@ -194,6 +194,16 @@ void BufferFormatter::EstimatePackingRules(Packing::Rules &pack, const ShaderCon if(vecSize == 2 && offsModVec != 0 && offsModVec != vec4Size / 2) pack.vector_align_component = true; + if(constant.type.elements > 1) + { + // with arrays we can check the stride as well. If the stride isn't vector-aligned then + // that's the same as vectors being aligned to components (even if we don't see it) + if(vecSize >= 3 && constant.type.arrayByteStride != vec4Size) + pack.vector_align_component = true; + if(vecSize == 3 && constant.type.arrayByteStride != vec4Size / 2) + pack.vector_align_component = true; + } + // while we're here, check if the vector straddles a 16-byte boundary const uint32_t low16b = (constant.byteOffset / 16); @@ -3696,6 +3706,52 @@ QString RowTypeString(const ShaderVariable &v) #include "3rdparty/catch/catch.hpp" +TEST_CASE("round-trip via format", "[formatter]") +{ + BufferFormatter::Init(GraphicsAPI::Vulkan); + + ShaderResource res; + ResourceFormat fmt; + rdcarray &members = res.variableType.members; + ParsedFormat parsed; + + members.push_back({}); + members.back().name = "a"; + members.back().byteOffset = 0; + members.back().type.name = "float"; + members.back().type.flags = ShaderVariableFlags::RowMajorMatrix; + members.back().type.baseType = VarType::Float; + members.back().type.arrayByteStride = 16; + members.back().type.elements = 7; + + // std140 packing + parsed = BufferFormatter::ParseFormatString( + BufferFormatter::GetBufferFormatString(BufferFormatter::EstimatePackingRules(members), res, fmt), + 0, true); + + CHECK((parsed.fixed.type.members == members)); + + // std430 packing + members.back().type.arrayByteStride = 4; + + parsed = BufferFormatter::ParseFormatString( + BufferFormatter::GetBufferFormatString(BufferFormatter::EstimatePackingRules(members), res, fmt), + 0, true); + + CHECK((parsed.fixed.type.members == members)); + + // scalar packing + members.back().type.name = "float3"; + members.back().type.columns = 3; + members.back().type.arrayByteStride = 12; + + parsed = BufferFormatter::ParseFormatString( + BufferFormatter::GetBufferFormatString(BufferFormatter::EstimatePackingRules(members), res, fmt), + 0, true); + + CHECK((parsed.fixed.type.members == members)); +} + TEST_CASE("Buffer format parsing", "[formatter]") { ShaderConstantType float_type; diff --git a/qrenderdoc/Code/QRDUtils.h b/qrenderdoc/Code/QRDUtils.h index 3d77d0abd..8bf6cc7ef 100644 --- a/qrenderdoc/Code/QRDUtils.h +++ b/qrenderdoc/Code/QRDUtils.h @@ -215,6 +215,7 @@ private: static uint32_t GetVarSizeAndTrail(const ShaderConstant &var); static void EstimatePackingRules(Packing::Rules &pack, const ShaderConstant &constant); + static void EstimatePackingRules(Packing::Rules &pack, const rdcarray &members); static QString DeclarePacking(Packing::Rules pack); public: @@ -225,7 +226,6 @@ public: static uint32_t GetVarAdvance(Packing::Rules pack, const ShaderConstant &var); static Packing::Rules EstimatePackingRules(const rdcarray &members); - static void EstimatePackingRules(Packing::Rules &pack, const rdcarray &members); static QString GetTextureFormatString(const TextureDescription &tex); static QString GetBufferFormatString(Packing::Rules pack, const ShaderResource &res,