Commit bf9cce2e by Jamie Madill

Use the block encoder class to store uniform offsets.

This will allow us to use the same code path for assigning register information in all places. Because of this it fixes some long-broken dEQP struct uniform tests. BUG=angle:466 BUG=angle:505 Change-Id: I4161a388503aa09bbe2d21ff47bfb3352ec93881 Reviewed-on: https://chromium-review.googlesource.com/207255Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarNicolas Capens <capn@chromium.org>
parent 9fe25e9e
...@@ -161,6 +161,12 @@ HLSLBlockEncoder::HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut, H ...@@ -161,6 +161,12 @@ HLSLBlockEncoder::HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut, H
{ {
} }
HLSLBlockEncoder::HLSLBlockEncoder(ShShaderOutput outputType)
: BlockLayoutEncoder(NULL),
mEncoderStrategy(GetStrategyFor(outputType))
{
}
void HLSLBlockEncoder::enterAggregateType() void HLSLBlockEncoder::enterAggregateType()
{ {
nextRegister(); nextRegister();
...@@ -245,6 +251,16 @@ void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters) ...@@ -245,6 +251,16 @@ void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters)
mCurrentOffset += (numRegisters * ComponentsPerRegister); mCurrentOffset += (numRegisters * ComponentsPerRegister);
} }
HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(ShShaderOutput outputType)
{
switch (outputType)
{
case SH_HLSL9_OUTPUT: return ENCODE_LOOSE;
case SH_HLSL11_OUTPUT: return ENCODE_PACKED;
default: UNREACHABLE(); return ENCODE_PACKED;
}
}
size_t HLSLInterfaceBlockDataSize(const sh::InterfaceBlock &interfaceBlock) size_t HLSLInterfaceBlockDataSize(const sh::InterfaceBlock &interfaceBlock)
{ {
switch (interfaceBlock.layout) switch (interfaceBlock.layout)
...@@ -353,10 +369,7 @@ unsigned int HLSLVariableRegisterCount(const Varying &variable) ...@@ -353,10 +369,7 @@ unsigned int HLSLVariableRegisterCount(const Varying &variable)
unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType) unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType)
{ {
HLSLBlockEncoder encoder(NULL, HLSLBlockEncoder encoder(outputType);
outputType == SH_HLSL9_OUTPUT ? HLSLBlockEncoder::ENCODE_LOOSE
: HLSLBlockEncoder::ENCODE_PACKED);
HLSLVariableRegisterCount(variable, &encoder); HLSLVariableRegisterCount(variable, &encoder);
const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister); const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
......
...@@ -33,6 +33,8 @@ class BlockLayoutEncoder ...@@ -33,6 +33,8 @@ class BlockLayoutEncoder
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() const { return mCurrentOffset * BytesPerComponent; } size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
size_t getCurrentRegister() const { return mCurrentOffset / ComponentsPerRegister; }
size_t getCurrentElement() const { return mCurrentOffset % ComponentsPerRegister; }
static const size_t BytesPerComponent = 4u; static const size_t BytesPerComponent = 4u;
static const unsigned int ComponentsPerRegister = 4u; static const unsigned int ComponentsPerRegister = 4u;
...@@ -82,6 +84,7 @@ class HLSLBlockEncoder : public BlockLayoutEncoder ...@@ -82,6 +84,7 @@ class HLSLBlockEncoder : public BlockLayoutEncoder
HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut, HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut,
HLSLBlockEncoderStrategy strategy); HLSLBlockEncoderStrategy strategy);
HLSLBlockEncoder(ShShaderOutput outputType);
virtual void enterAggregateType(); virtual void enterAggregateType();
virtual void exitAggregateType(); virtual void exitAggregateType();
...@@ -89,6 +92,8 @@ class HLSLBlockEncoder : public BlockLayoutEncoder ...@@ -89,6 +92,8 @@ class HLSLBlockEncoder : public BlockLayoutEncoder
bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; } bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
protected: 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);
......
...@@ -1648,7 +1648,7 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin ...@@ -1648,7 +1648,7 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
success = false; success = false;
} }
if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms())) if (!linkUniforms(infoLog, *vertexShader, *fragmentShader))
{ {
success = false; success = false;
} }
...@@ -1900,8 +1900,11 @@ bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &u ...@@ -1900,8 +1900,11 @@ bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &u
return true; return true;
} }
bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform> &vertexUniforms, const std::vector<sh::Uniform> &fragmentUniforms) bool ProgramBinary::linkUniforms(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader)
{ {
const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
// Check that uniforms defined in the vertex and fragment shaders are identical // Check that uniforms defined in the vertex and fragment shaders are identical
typedef std::map<std::string, const sh::Uniform*> UniformMap; typedef std::map<std::string, const sh::Uniform*> UniformMap;
UniformMap linkedUniforms; UniformMap linkedUniforms;
...@@ -1929,12 +1932,14 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform ...@@ -1929,12 +1932,14 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform
for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++) for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
{ {
defineUniformBase(GL_VERTEX_SHADER, vertexUniforms[uniformIndex]); const sh::Uniform &uniform = vertexUniforms[uniformIndex];
defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShader.getUniformRegister(uniform.name));
} }
for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++) for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
{ {
defineUniformBase(GL_FRAGMENT_SHADER, fragmentUniforms[uniformIndex]); const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShader.getUniformRegister(uniform.name));
} }
if (!indexUniforms(infoLog)) if (!indexUniforms(infoLog))
...@@ -1947,46 +1952,45 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform ...@@ -1947,46 +1952,45 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform
return true; return true;
} }
void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform) void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
{ {
defineUniform(shader, uniform, uniform.name, uniform.registerIndex); ShShaderOutput outputType = Shader::getCompilerOutputType(shader);
sh::HLSLBlockEncoder encoder(outputType);
encoder.skipRegisters(uniformRegister);
defineUniform(shader, uniform, uniform.name, &encoder);
} }
void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform, void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
const std::string &fullName, unsigned int baseRegisterIndex) const std::string &fullName, sh::HLSLBlockEncoder *encoder)
{ {
if (uniform.isStruct()) if (uniform.isStruct())
{ {
if (uniform.arraySize > 0) for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
{ {
ShShaderOutput outputType = Shader::getCompilerOutputType(shader); const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
const unsigned int elementRegisterCount = HLSLVariableRegisterCount(uniform, outputType) / uniform.arraySize;
for (unsigned int elementIndex = 0; elementIndex < uniform.arraySize; elementIndex++) encoder->enterAggregateType();
{
const unsigned int elementRegisterOffset = elementRegisterCount * elementIndex;
for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
{
const sh::Uniform &field = uniform.fields[fieldIndex];
const std::string &fieldFullName = fullName + ArrayString(elementIndex) + "." + field.name;
const unsigned int fieldRegisterIndex = field.registerIndex + elementRegisterOffset;
defineUniform(shader, field, fieldFullName, fieldRegisterIndex);
}
}
}
else
{
for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
{ {
const sh::Uniform &field = uniform.fields[fieldIndex]; const sh::Uniform &field = uniform.fields[fieldIndex];
const std::string &fieldFullName = fullName + "." + field.name; const std::string &fieldFullName = (fullName + elementString + "." + field.name);
defineUniform(shader, field, fieldFullName, field.registerIndex);
defineUniform(shader, field, fieldFullName, encoder);
} }
encoder->exitAggregateType();
} }
} }
else // Not a struct else // Not a struct
{ {
// Arrays are treated as aggregate types
if (uniform.isArray())
{
encoder->enterAggregateType();
}
LinkedUniform *linkedUniform = getUniformByName(fullName); LinkedUniform *linkedUniform = getUniformByName(fullName);
if (!linkedUniform) if (!linkedUniform)
...@@ -1994,19 +1998,30 @@ void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform, ...@@ -1994,19 +1998,30 @@ void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize, linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
-1, sh::BlockMemberInfo::getDefaultBlockInfo()); -1, sh::BlockMemberInfo::getDefaultBlockInfo());
ASSERT(linkedUniform); ASSERT(linkedUniform);
linkedUniform->registerElement = uniform.elementIndex; linkedUniform->registerElement = encoder->getCurrentElement();
mUniforms.push_back(linkedUniform); mUniforms.push_back(linkedUniform);
} }
ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
if (shader == GL_FRAGMENT_SHADER) if (shader == GL_FRAGMENT_SHADER)
{ {
linkedUniform->psRegisterIndex = baseRegisterIndex; linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
} }
else if (shader == GL_VERTEX_SHADER) else if (shader == GL_VERTEX_SHADER)
{ {
linkedUniform->vsRegisterIndex = baseRegisterIndex; linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
} }
else UNREACHABLE(); else UNREACHABLE();
// Advance the uniform offset, to track registers allocation for structs
encoder->encodeType(uniform.type, uniform.arraySize, false);
// Arrays are treated as aggregate types
if (uniform.isArray())
{
encoder->exitAggregateType();
}
} }
} }
......
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
#include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/DynamicHLSL.h" #include "libGLESv2/DynamicHLSL.h"
namespace sh
{
class HLSLBlockEncoder;
}
namespace rx namespace rx
{ {
class ShaderExecutable; class ShaderExecutable;
...@@ -201,9 +206,9 @@ class ProgramBinary : public RefCountObject ...@@ -201,9 +206,9 @@ class ProgramBinary : public RefCountObject
bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
bool linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying); bool linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
bool linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform> &vertexUniforms, const std::vector<sh::Uniform> &fragmentUniforms); bool linkUniforms(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader);
void defineUniformBase(GLenum shader, const sh::Uniform &uniform); void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
void defineUniform(GLenum shader, const sh::Uniform &uniform, const std::string &fullName, unsigned int baseRegisterIndex); void defineUniform(GLenum shader, const sh::Uniform &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder);
bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog); bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog);
bool indexUniforms(InfoLog &infoLog); bool indexUniforms(InfoLog &infoLog);
static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount, static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
......
...@@ -115,6 +115,12 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) ...@@ -115,6 +115,12 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
getSourceImpl(mHlsl, bufSize, length, buffer); getSourceImpl(mHlsl, bufSize, length, buffer);
} }
unsigned int Shader::getUniformRegister(const std::string &uniformName) const
{
ASSERT(mUniformRegisterMap.count(uniformName) > 0);
return mUniformRegisterMap.find(uniformName)->second;
}
unsigned int Shader::getInterfaceBlockRegister(const std::string &blockName) const unsigned int Shader::getInterfaceBlockRegister(const std::string &blockName) const
{ {
ASSERT(mInterfaceBlockRegisterMap.count(blockName) > 0); ASSERT(mInterfaceBlockRegisterMap.count(blockName) > 0);
...@@ -373,6 +379,18 @@ void Shader::compileToHLSL(void *compiler) ...@@ -373,6 +379,18 @@ void Shader::compileToHLSL(void *compiler)
ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms); ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
mActiveUniforms = *(std::vector<sh::Uniform>*)activeUniforms; mActiveUniforms = *(std::vector<sh::Uniform>*)activeUniforms;
for (size_t uniformIndex = 0; uniformIndex < mActiveUniforms.size(); uniformIndex++)
{
const sh::Uniform &uniform = mActiveUniforms[uniformIndex];
unsigned int index = -1;
bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
mUniformRegisterMap[uniform.name] = index;
}
void *activeInterfaceBlocks; void *activeInterfaceBlocks;
ShGetInfoPointer(compiler, SH_ACTIVE_INTERFACE_BLOCKS_ARRAY, &activeInterfaceBlocks); ShGetInfoPointer(compiler, SH_ACTIVE_INTERFACE_BLOCKS_ARRAY, &activeInterfaceBlocks);
mActiveInterfaceBlocks = *(std::vector<sh::InterfaceBlock>*)activeInterfaceBlocks; mActiveInterfaceBlocks = *(std::vector<sh::InterfaceBlock>*)activeInterfaceBlocks;
......
...@@ -87,6 +87,7 @@ class Shader ...@@ -87,6 +87,7 @@ class Shader
static void releaseCompiler(); static void releaseCompiler();
static ShShaderOutput getCompilerOutputType(GLenum shader); static ShShaderOutput getCompilerOutputType(GLenum shader);
unsigned int getUniformRegister(const std::string &uniformName) const;
unsigned int getInterfaceBlockRegister(const std::string &blockName) const; unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
bool usesDepthRange() const { return mUsesDepthRange; } bool usesDepthRange() const { return mUsesDepthRange; }
...@@ -136,6 +137,7 @@ class Shader ...@@ -136,6 +137,7 @@ class Shader
std::string mInfoLog; std::string mInfoLog;
std::vector<sh::Uniform> mActiveUniforms; std::vector<sh::Uniform> mActiveUniforms;
std::vector<sh::InterfaceBlock> mActiveInterfaceBlocks; std::vector<sh::InterfaceBlock> mActiveInterfaceBlocks;
std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap; std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
ResourceManager *mResourceManager; ResourceManager *mResourceManager;
......
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