Commit f4780c1c by Jamie Madill

Use correct non-square register count in structs.

For struct varyings with nested structs, we would count registers incorrectly, and produce D3D link errors. This fixes tests in the dEQP's shaders.linkage.varying.struct. BUG=angle:910 Change-Id: I47ea6dba36bf57cf94a7e7f30997c6c9096c2b40 Reviewed-on: https://chromium-review.googlesource.com/247243Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 489ffc4d
......@@ -121,7 +121,8 @@ void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool
}
HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy)
: mEncoderStrategy(strategy)
: mEncoderStrategy(strategy),
mTransposeMatrices(false)
{
}
......@@ -134,8 +135,10 @@ void HLSLBlockEncoder::exitAggregateType()
{
}
void HLSLBlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
{
GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
// We assume we are only dealing with 4 byte components (no doubles or half-words currently)
ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
......@@ -179,8 +182,10 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, b
*arrayStrideOut = arrayStride;
}
void HLSLBlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
void HLSLBlockEncoder::advanceOffset(GLenum typeIn, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
{
GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
if (arraySize > 0)
{
mCurrentOffset += arrayStride * (arraySize - 1);
......@@ -243,9 +248,10 @@ void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *
}
}
unsigned int HLSLVariableRegisterCount(const Varying &variable)
unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices)
{
HLSLBlockEncoder encoder(HLSLBlockEncoder::ENCODE_PACKED);
encoder.setTransposeMatrices(transposeMatrices);
HLSLVariableRegisterCount(variable, &encoder);
const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
......
......@@ -110,6 +110,7 @@ class COMPILER_EXPORT HLSLBlockEncoder : public BlockLayoutEncoder
void skipRegisters(unsigned int numRegisters);
bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
void setTransposeMatrices(bool enabled) { mTransposeMatrices = enabled; }
static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
......@@ -118,11 +119,12 @@ class COMPILER_EXPORT HLSLBlockEncoder : public BlockLayoutEncoder
virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
HLSLBlockEncoderStrategy mEncoderStrategy;
bool mTransposeMatrices;
};
// This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder
// class to count the number of used registers in a struct (which are individually packed according to the same rules).
COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Varying &variable);
COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices);
COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
}
......
......@@ -98,11 +98,21 @@ DynamicHLSL::DynamicHLSL(RendererD3D *const renderer)
static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, VaryingPacking packing)
{
GLenum transposedType = TransposeMatrixType(varying->type);
// Make sure we use transposed matrix types to count registers correctly.
int registers = 0;
int elements = 0;
// matrices within varying structs are not transposed
int registers = (varying->isStruct() ? HLSLVariableRegisterCount(*varying) : VariableRowCount(transposedType)) * varying->elementCount();
int elements = (varying->isStruct() ? 4 : VariableColumnCount(transposedType));
if (varying->isStruct())
{
registers = HLSLVariableRegisterCount(*varying, true) * varying->elementCount();
elements = 4;
}
else
{
GLenum transposedType = TransposeMatrixType(varying->type);
registers = VariableRowCount(transposedType) * varying->elementCount();
elements = VariableColumnCount(transposedType);
}
if (elements >= 2 && elements <= 4)
{
......@@ -340,15 +350,16 @@ std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const
default: UNREACHABLE();
}
unsigned int semanticIndex = elementIndex * variableRows + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + varying.registerIndex + row;
unsigned int semanticIndex = elementIndex * variableRows +
varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors +
varying.registerIndex + row;
std::string n = Str(semanticIndex);
std::string typeString;
if (varying.isStruct())
{
// matrices within structs are not transposed, so
// do not use the special struct prefix "rm"
// TODO(jmadill): pass back translated name from the shader translator
typeString = decorateVariable(varying.structName);
}
else
......
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