Arrays of float3 with a stride of 12 is only possible in scalar packing

* Previously this would be treated as std430 due to being 'tight' array packed,
  even though std430 only allows as tight as the base alignment - which for a
  float3 is 16-bytes still.
This commit is contained in:
baldurk
2022-07-11 13:00:18 +01:00
parent 52c00efb75
commit d39197a499
2 changed files with 57 additions and 1 deletions
+56
View File
@@ -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<ShaderConstant> &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;
+1 -1
View File
@@ -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<ShaderConstant> &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<ShaderConstant> &members);
static void EstimatePackingRules(Packing::Rules &pack, const rdcarray<ShaderConstant> &members);
static QString GetTextureFormatString(const TextureDescription &tex);
static QString GetBufferFormatString(Packing::Rules pack, const ShaderResource &res,