Commit f1ae954b by Jamie Madill

translator: Fix variable collection for gl_DepthRange.

This built-in uniform wasn't being collected in VariableInfo.cpp. Also remove the existing workaround for D3D gl_DepthRange collection. BUG=angleproject:991 BUG=478570 Change-Id: Ie254132e37c307323ba9e6e1705d138eea67b520 Reviewed-on: https://chromium-review.googlesource.com/268524Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 4c8cae60
...@@ -70,6 +70,8 @@ struct COMPILER_EXPORT ShaderVariable ...@@ -70,6 +70,8 @@ struct COMPILER_EXPORT ShaderVariable
const ShaderVariable **leafVar, const ShaderVariable **leafVar,
std::string* originalFullName) const; std::string* originalFullName) const;
bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
GLenum type; GLenum type;
GLenum precision; GLenum precision;
std::string name; std::string name;
......
...@@ -139,6 +139,7 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs, ...@@ -139,6 +139,7 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
mUniforms(uniforms), mUniforms(uniforms),
mVaryings(varyings), mVaryings(varyings),
mInterfaceBlocks(interfaceBlocks), mInterfaceBlocks(interfaceBlocks),
mDepthRangeAdded(false),
mPointCoordAdded(false), mPointCoordAdded(false),
mFrontFacingAdded(false), mFrontFacingAdded(false),
mFragCoordAdded(false), mFragCoordAdded(false),
...@@ -170,6 +171,56 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -170,6 +171,56 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
{ {
UNREACHABLE(); UNREACHABLE();
} }
else if (symbolName == "gl_DepthRange")
{
ASSERT(symbol->getQualifier() == EvqUniform);
if (!mDepthRangeAdded)
{
Uniform info;
const char kName[] = "gl_DepthRange";
info.name = kName;
info.mappedName = kName;
info.type = GL_STRUCT_ANGLEX;
info.arraySize = 0;
info.precision = GL_NONE;
info.staticUse = true;
ShaderVariable nearInfo;
const char kNearName[] = "near";
nearInfo.name = kNearName;
nearInfo.mappedName = kNearName;
nearInfo.type = GL_FLOAT;
nearInfo.arraySize = 0;
nearInfo.precision = GL_HIGH_FLOAT;
nearInfo.staticUse = true;
ShaderVariable farInfo;
const char kFarName[] = "far";
farInfo.name = kFarName;
farInfo.mappedName = kFarName;
farInfo.type = GL_FLOAT;
farInfo.arraySize = 0;
farInfo.precision = GL_HIGH_FLOAT;
farInfo.staticUse = true;
ShaderVariable diffInfo;
const char kDiffName[] = "diff";
diffInfo.name = kDiffName;
diffInfo.mappedName = kDiffName;
diffInfo.type = GL_FLOAT;
diffInfo.arraySize = 0;
diffInfo.precision = GL_HIGH_FLOAT;
diffInfo.staticUse = true;
info.fields.push_back(nearInfo);
info.fields.push_back(farInfo);
info.fields.push_back(diffInfo);
mUniforms->push_back(info);
mDepthRangeAdded = true;
}
}
else else
{ {
switch (symbol->getQualifier()) switch (symbol->getQualifier())
...@@ -192,7 +243,6 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -192,7 +243,6 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
// Set static use on the parent interface block here // Set static use on the parent interface block here
namedBlock->staticUse = true; namedBlock->staticUse = true;
} }
else else
{ {
...@@ -200,7 +250,7 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -200,7 +250,7 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
} }
// It's an internal error to reference an undefined user uniform // It's an internal error to reference an undefined user uniform
ASSERT(symbolName.compare(0, 3, "gl_") == 0 || var); ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var);
} }
break; break;
case EvqFragCoord: case EvqFragCoord:
......
...@@ -47,6 +47,7 @@ class CollectVariables : public TIntermTraverser ...@@ -47,6 +47,7 @@ class CollectVariables : public TIntermTraverser
std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields; std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
bool mDepthRangeAdded;
bool mPointCoordAdded; bool mPointCoordAdded;
bool mFrontFacingAdded; bool mFrontFacingAdded;
bool mFragCoordAdded; bool mFragCoordAdded;
......
...@@ -45,7 +45,6 @@ struct PackedVarying : public sh::Varying ...@@ -45,7 +45,6 @@ struct PackedVarying : public sh::Varying
{} {}
bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; } bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; }
bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
void resetRegisterAssignment() void resetRegisterAssignment()
{ {
......
...@@ -1375,7 +1375,9 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad ...@@ -1375,7 +1375,9 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
if (uniform.staticUse) if (uniform.staticUse)
{ {
defineUniformBase(vertexShaderD3D, uniform, vertexShaderD3D->getUniformRegister(uniform.name)); unsigned int registerBase = uniform.isBuiltIn() ? GL_INVALID_INDEX :
vertexShaderD3D->getUniformRegister(uniform.name);
defineUniformBase(vertexShaderD3D, uniform, registerBase);
} }
} }
...@@ -1385,7 +1387,9 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad ...@@ -1385,7 +1387,9 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
if (uniform.staticUse) if (uniform.staticUse)
{ {
defineUniformBase(fragmentShaderD3D, uniform, fragmentShaderD3D->getUniformRegister(uniform.name)); unsigned int registerBase = uniform.isBuiltIn() ? GL_INVALID_INDEX :
fragmentShaderD3D->getUniformRegister(uniform.name);
defineUniformBase(fragmentShaderD3D, uniform, registerBase);
} }
} }
...@@ -1396,21 +1400,16 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad ...@@ -1396,21 +1400,16 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
initializeUniformStorage(); initializeUniformStorage();
// special case for gl_DepthRange, the only built-in uniform (also a struct)
if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
{
const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo));
mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo));
mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
}
return true; return true;
} }
void ProgramD3D::defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister) void ProgramD3D::defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister)
{ {
if (uniformRegister == GL_INVALID_INDEX)
{
defineUniform(shader, uniform, uniform.name, nullptr);
}
ShShaderOutput outputType = shader->getCompilerOutputType(); ShShaderOutput outputType = shader->getCompilerOutputType();
sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
encoder.skipRegisters(uniformRegister); encoder.skipRegisters(uniformRegister);
...@@ -1427,7 +1426,8 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable ...@@ -1427,7 +1426,8 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable
{ {
const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
encoder->enterAggregateType(); if (encoder)
encoder->enterAggregateType();
for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
{ {
...@@ -1437,13 +1437,14 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable ...@@ -1437,13 +1437,14 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable
defineUniform(shader, field, fieldFullName, encoder); defineUniform(shader, field, fieldFullName, encoder);
} }
encoder->exitAggregateType(); if (encoder)
encoder->exitAggregateType();
} }
} }
else // Not a struct else // Not a struct
{ {
// Arrays are treated as aggregate types // Arrays are treated as aggregate types
if (uniform.isArray()) if (uniform.isArray() && encoder)
{ {
encoder->enterAggregateType(); encoder->enterAggregateType();
} }
...@@ -1451,29 +1452,36 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable ...@@ -1451,29 +1452,36 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable
gl::LinkedUniform *linkedUniform = getUniformByName(fullName); gl::LinkedUniform *linkedUniform = getUniformByName(fullName);
// Advance the uniform offset, to track registers allocation for structs // Advance the uniform offset, to track registers allocation for structs
sh::BlockMemberInfo blockInfo = encoder->encodeType(uniform.type, uniform.arraySize, false); sh::BlockMemberInfo blockInfo = encoder ?
encoder->encodeType(uniform.type, uniform.arraySize, false) :
sh::BlockMemberInfo::getDefaultBlockInfo();
if (!linkedUniform) if (!linkedUniform)
{ {
linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize, linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
-1, sh::BlockMemberInfo::getDefaultBlockInfo()); -1, sh::BlockMemberInfo::getDefaultBlockInfo());
ASSERT(linkedUniform); ASSERT(linkedUniform);
linkedUniform->registerElement = sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo);
if (encoder)
linkedUniform->registerElement = sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo);
mUniforms.push_back(linkedUniform); mUniforms.push_back(linkedUniform);
} }
if (shader->getShaderType() == GL_FRAGMENT_SHADER) if (encoder)
{
linkedUniform->psRegisterIndex = sh::HLSLBlockEncoder::getBlockRegister(blockInfo);
}
else if (shader->getShaderType() == GL_VERTEX_SHADER)
{ {
linkedUniform->vsRegisterIndex = sh::HLSLBlockEncoder::getBlockRegister(blockInfo); if (shader->getShaderType() == GL_FRAGMENT_SHADER)
{
linkedUniform->psRegisterIndex = sh::HLSLBlockEncoder::getBlockRegister(blockInfo);
}
else if (shader->getShaderType() == GL_VERTEX_SHADER)
{
linkedUniform->vsRegisterIndex = sh::HLSLBlockEncoder::getBlockRegister(blockInfo);
}
else UNREACHABLE();
} }
else UNREACHABLE();
// Arrays are treated as aggregate types // Arrays are treated as aggregate types
if (uniform.isArray()) if (uniform.isArray() && encoder)
{ {
encoder->exitAggregateType(); encoder->exitAggregateType();
} }
......
...@@ -218,7 +218,7 @@ void ShaderD3D::compileToHLSL(ShHandle compiler, const std::string &source) ...@@ -218,7 +218,7 @@ void ShaderD3D::compileToHLSL(ShHandle compiler, const std::string &source)
{ {
const sh::Uniform &uniform = mUniforms[uniformIndex]; const sh::Uniform &uniform = mUniforms[uniformIndex];
if (uniform.staticUse) if (uniform.staticUse && !uniform.isBuiltIn())
{ {
unsigned int index = static_cast<unsigned int>(-1); unsigned int index = static_cast<unsigned int>(-1);
bool getUniformRegisterResult = ShGetUniformRegister(compiler, uniform.name, &index); bool getUniformRegisterResult = ShGetUniformRegister(compiler, uniform.name, &index);
......
...@@ -19,8 +19,10 @@ class CollectVariablesTest : public testing::Test ...@@ -19,8 +19,10 @@ class CollectVariablesTest : public testing::Test
{ {
public: public:
CollectVariablesTest(GLenum shaderType) CollectVariablesTest(GLenum shaderType)
: mShaderType(shaderType) : mShaderType(shaderType),
{} mTranslator(nullptr)
{
}
protected: protected:
virtual void SetUp() virtual void SetUp()
...@@ -29,14 +31,67 @@ class CollectVariablesTest : public testing::Test ...@@ -29,14 +31,67 @@ class CollectVariablesTest : public testing::Test
ShInitBuiltInResources(&resources); ShInitBuiltInResources(&resources);
resources.MaxDrawBuffers = 8; resources.MaxDrawBuffers = 8;
initTranslator(resources);
}
virtual void TearDown()
{
SafeDelete(mTranslator);
}
void initTranslator(const ShBuiltInResources &resources)
{
SafeDelete(mTranslator);
mTranslator = new TranslatorGLSL( mTranslator = new TranslatorGLSL(
mShaderType, SH_GLES3_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT); mShaderType, SH_GLES3_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT);
ASSERT_TRUE(mTranslator->Init(resources)); ASSERT_TRUE(mTranslator->Init(resources));
} }
virtual void TearDown() // For use in the gl_DepthRange tests.
void validateDepthRangeShader(const std::string &shaderString)
{ {
delete mTranslator; const char *shaderStrings[] = { shaderString.c_str() };
ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
const std::vector<sh::Uniform> &uniforms = mTranslator->getUniforms();
ASSERT_EQ(1u, uniforms.size());
const sh::Uniform &uniform = uniforms[0];
EXPECT_EQ("gl_DepthRange", uniform.name);
ASSERT_TRUE(uniform.isStruct());
ASSERT_EQ(3u, uniform.fields.size());
bool foundNear = false;
bool foundFar = false;
bool foundDiff = false;
for (const auto &field : uniform.fields)
{
if (field.name == "near")
{
EXPECT_FALSE(foundNear);
foundNear = true;
}
else if (field.name == "far")
{
EXPECT_FALSE(foundFar);
foundFar = true;
}
else
{
ASSERT_EQ("diff", field.name);
EXPECT_FALSE(foundDiff);
foundDiff = true;
}
EXPECT_EQ(0u, field.arraySize);
EXPECT_FALSE(field.isStruct());
EXPECT_EQ(GL_HIGH_FLOAT, field.precision);
EXPECT_TRUE(field.staticUse);
EXPECT_EQ(GL_FLOAT, field.type);
}
EXPECT_TRUE(foundNear && foundFar && foundDiff);
} }
GLenum mShaderType; GLenum mShaderType;
...@@ -369,3 +424,27 @@ TEST_F(CollectVertexVariablesTest, VaryingInterpolation) ...@@ -369,3 +424,27 @@ TEST_F(CollectVertexVariablesTest, VaryingInterpolation)
EXPECT_EQ("vary", varying->name); EXPECT_EQ("vary", varying->name);
EXPECT_EQ(sh::INTERPOLATION_CENTROID, varying->interpolation); EXPECT_EQ(sh::INTERPOLATION_CENTROID, varying->interpolation);
} }
// Test for builtin uniform "gl_DepthRange" (Vertex shader)
TEST_F(CollectVertexVariablesTest, DepthRange)
{
const std::string &shaderString =
"attribute vec4 position;\n"
"void main() {\n"
" gl_Position = position + vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1.0);\n"
"}\n";
validateDepthRangeShader(shaderString);
}
// Test for builtin uniform "gl_DepthRange" (Fragment shader)
TEST_F(CollectFragmentVariablesTest, DepthRange)
{
const std::string &shaderString =
"precision mediump float;\n"
"void main() {\n"
" gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1.0);\n"
"}\n";
validateDepthRangeShader(shaderString);
}
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