Don't use constant buffer alignment rules on D3D for SRV/UAV structs

* In particular matrices and array elements are padded to float4 in cbuffers but
  *not* in structured buffers
This commit is contained in:
baldurk
2021-02-08 14:05:04 +00:00
parent 69661b0cbb
commit 3da41af1a9
+16 -9
View File
@@ -28,9 +28,10 @@
#include "dxbc_bytecode.h"
#include "dxbc_container.h"
static ShaderConstant MakeConstantBufferVariable(const DXBC::CBufferVariable &var);
static ShaderConstant MakeConstantBufferVariable(bool cbufferPacking,
const DXBC::CBufferVariable &var);
static ShaderConstantType MakeShaderConstantType(DXBC::CBufferVariableType type)
static ShaderConstantType MakeShaderConstantType(bool cbufferPacking, DXBC::CBufferVariableType type)
{
ShaderConstantType ret;
@@ -45,8 +46,14 @@ static ShaderConstantType MakeShaderConstantType(DXBC::CBufferVariableType type)
uint32_t baseElemSize = (ret.descriptor.type == VarType::Double) ? 8 : 4;
// in D3D matrices always take up a float4 per row/column
ret.descriptor.matrixByteStride = uint8_t(baseElemSize * 4);
// in D3D matrices in cbuffers always take up a float4 per row/column. Structured buffers in
// SRVs/UAVs are tightly packed
if(cbufferPacking)
ret.descriptor.matrixByteStride = uint8_t(baseElemSize * 4);
else
ret.descriptor.matrixByteStride =
uint8_t(baseElemSize *
(ret.descriptor.rowMajorStorage ? ret.descriptor.rows : ret.descriptor.columns));
if(type.descriptor.varClass == DXBC::CLASS_STRUCT)
{
@@ -66,7 +73,7 @@ static ShaderConstantType MakeShaderConstantType(DXBC::CBufferVariableType type)
ret.members.reserve(type.members.size());
for(size_t i = 0; i < type.members.size(); i++)
ret.members.push_back(MakeConstantBufferVariable(type.members[i]));
ret.members.push_back(MakeConstantBufferVariable(cbufferPacking, type.members[i]));
if(!ret.members.empty())
{
@@ -77,14 +84,14 @@ static ShaderConstantType MakeShaderConstantType(DXBC::CBufferVariableType type)
return ret;
}
static ShaderConstant MakeConstantBufferVariable(const DXBC::CBufferVariable &var)
static ShaderConstant MakeConstantBufferVariable(bool cbufferPacking, const DXBC::CBufferVariable &var)
{
ShaderConstant ret;
ret.name = var.name;
ret.byteOffset = var.offset;
ret.defaultValue = 0;
ret.type = MakeShaderConstantType(var.type);
ret.type = MakeShaderConstantType(cbufferPacking, var.type);
return ret;
}
@@ -188,7 +195,7 @@ static void MakeResourceList(bool srv, DXBC::DXBCContainer *dxbc,
auto it = dxbc->GetReflection()->ResourceBinds.find(r.name);
if(it != dxbc->GetReflection()->ResourceBinds.end())
{
res.variableType = MakeShaderConstantType(it->second);
res.variableType = MakeShaderConstantType(false, it->second);
}
else
{
@@ -328,7 +335,7 @@ void MakeShaderReflection(DXBC::DXBCContainer *dxbc, ShaderReflection *refl,
for(size_t v = 0; v < dxbc->GetReflection()->CBuffers[i].variables.size(); v++)
{
cb.variables.push_back(
MakeConstantBufferVariable(dxbc->GetReflection()->CBuffers[i].variables[v]));
MakeConstantBufferVariable(true, dxbc->GetReflection()->CBuffers[i].variables[v]));
}
}