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 ...@@ -27,7 +27,7 @@ class BlockLayoutEncoder
void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields); void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
void encodeInterfaceBlockField(const InterfaceBlockField &field); void encodeInterfaceBlockField(const InterfaceBlockField &field);
void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix); 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 size_t BytesPerComponent = 4u;
static const unsigned int ComponentsPerRegister = 4u; static const unsigned int ComponentsPerRegister = 4u;
......
...@@ -85,31 +85,45 @@ void HLSLBlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool i ...@@ -85,31 +85,45 @@ void HLSLBlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool i
} }
template <class ShaderVarType> template <class ShaderVarType>
unsigned int HLSLRegisterCount(const ShaderVarType &variable) void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
{ {
if (variable.isStruct()) if (variable.isStruct())
{ {
unsigned int totalCount = 0; for (size_t arrayElement = 0; arrayElement < variable.elementCount(); arrayElement++)
for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++)
{ {
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 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) 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) 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 ...@@ -23,9 +23,10 @@ class HLSLBlockEncoder : public BlockLayoutEncoder
public: public:
HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut); HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
protected:
virtual void enterAggregateType(); virtual void enterAggregateType();
virtual void exitAggregateType(); virtual void exitAggregateType();
protected:
virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut); 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); 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