Commit 86a97a1a by Jamie Madill

Use the proper register count for structs in HLSL uniforms and varyings.

We must respect HLSL packing rules when uploading structs to D3D. TRAC #23748 Signed-off-by: Geoff Lang Signed-off-by: Nicolas Capens
parent 2b538b85
......@@ -27,7 +27,7 @@ class BlockLayoutEncoder
void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
void encodeInterfaceBlockField(const InterfaceBlockField &field);
void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
size_t getBlockSize() { return mCurrentOffset * BytesPerComponent; }
size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
static const size_t BytesPerComponent = 4u;
static const unsigned int ComponentsPerRegister = 4u;
......
......@@ -85,31 +85,45 @@ void HLSLBlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool i
}
template <class ShaderVarType>
unsigned int HLSLRegisterCount(const ShaderVarType &variable)
void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
{
if (variable.isStruct())
{
unsigned int totalCount = 0;
for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++)
for (size_t arrayElement = 0; arrayElement < variable.elementCount(); arrayElement++)
{
totalCount += HLSLVariableRegisterCount(variable.fields[fieldIndex]);
encoder->enterAggregateType();
for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++)
{
HLSLVariableRegisterCount(variable.fields[fieldIndex], encoder);
}
encoder->exitAggregateType();
}
return totalCount * variable.elementCount();
}
else
{
return gl::VariableRowCount(variable.type) * variable.elementCount();
// We operate only on varyings and uniforms, which do not have matrix layout qualifiers
encoder->encodeType(variable.type, variable.arraySize, false);
}
}
unsigned int HLSLVariableRegisterCount(const Varying &variable)
{
return HLSLRegisterCount(variable);
HLSLBlockEncoder encoder(NULL);
HLSLVariableRegisterCount(variable, &encoder);
const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
return rx::roundUp(encoder.getBlockSize(), registerBytes) / registerBytes;
}
unsigned int HLSLVariableRegisterCount(const Uniform &variable)
{
return HLSLRegisterCount(variable);
HLSLBlockEncoder encoder(NULL);
HLSLVariableRegisterCount(variable, &encoder);
const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
return rx::roundUp(encoder.getBlockSize(), registerBytes) / registerBytes;
}
}
......@@ -23,9 +23,10 @@ class HLSLBlockEncoder : public BlockLayoutEncoder
public:
HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
protected:
virtual void enterAggregateType();
virtual void exitAggregateType();
protected:
virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment