Commit c5e344b1 by Shahbaz Youssefi Committed by Commit Bot

Translator: Fix local var inits vs struct/uniform separation

The declarations outside the global scope were being skipped in this transformation, but if the initializer of a declaration referenced a uniform struct that's being replaced, it should have been visited too. Bug: chromium:1204861 Change-Id: Ie2a743126c785eb7d6e3542ba80faa4defc3509f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2889598 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent ee2f3302
...@@ -31,7 +31,7 @@ class Traverser : public TIntermTraverser ...@@ -31,7 +31,7 @@ class Traverser : public TIntermTraverser
if (!mInGlobalScope) if (!mInGlobalScope)
{ {
return false; return true;
} }
const TIntermSequence &sequence = *(decl->getSequence()); const TIntermSequence &sequence = *(decl->getSequence());
...@@ -61,10 +61,10 @@ class Traverser : public TIntermTraverser ...@@ -61,10 +61,10 @@ class Traverser : public TIntermTraverser
TIntermTyped *declarator, TIntermTyped *declarator,
const TStructure *oldStructure) const TStructure *oldStructure)
{ {
// struct <structName> { ... };
const TStructure *structure = oldStructure; const TStructure *structure = oldStructure;
if (oldStructure->symbolType() == SymbolType::Empty) if (oldStructure->symbolType() == SymbolType::Empty)
{ {
// Handle nameless structs: uniform struct { ... } variable;
structure = new TStructure(mSymbolTable, kEmptyImmutableString, &oldStructure->fields(), structure = new TStructure(mSymbolTable, kEmptyImmutableString, &oldStructure->fields(),
SymbolType::AngleInternal); SymbolType::AngleInternal);
} }
...@@ -80,23 +80,22 @@ class Traverser : public TIntermTraverser ...@@ -80,23 +80,22 @@ class Traverser : public TIntermTraverser
TIntermSequence newSequence; TIntermSequence newSequence;
newSequence.push_back(structDeclaration); newSequence.push_back(structDeclaration);
// uniform <structName> <structUniformName>; // Redeclare the uniform with the (potentially) new struct type
TIntermSymbol *asSymbol = declarator->getAsSymbolNode(); TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
if (asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty) ASSERT(asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty);
{
TIntermDeclaration *namedDecl = new TIntermDeclaration;
TType *uniformType = new TType(structure, false);
uniformType->setQualifier(EvqUniform);
TVariable *newVar = new TVariable(mSymbolTable, asSymbol->getName(), uniformType, TIntermDeclaration *namedDecl = new TIntermDeclaration;
asSymbol->variable().symbolType()); TType *uniformType = new TType(structure, false);
TIntermSymbol *newSymbol = new TIntermSymbol(newVar); uniformType->setQualifier(EvqUniform);
namedDecl->appendDeclarator(newSymbol);
newSequence.push_back(namedDecl); TVariable *newVar = new TVariable(mSymbolTable, asSymbol->getName(), uniformType,
asSymbol->variable().symbolType());
TIntermSymbol *newSymbol = new TIntermSymbol(newVar);
namedDecl->appendDeclarator(newSymbol);
mVariableMap[&asSymbol->variable()] = new TIntermSymbol(newVar); newSequence.push_back(namedDecl);
}
mVariableMap[&asSymbol->variable()] = newSymbol;
mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl, mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
std::move(newSequence)); std::move(newSequence));
......
...@@ -10686,6 +10686,37 @@ void main() ...@@ -10686,6 +10686,37 @@ void main()
GLuint program = CompileProgram(kVS, kFS); GLuint program = CompileProgram(kVS, kFS);
EXPECT_EQ(0u, program); EXPECT_EQ(0u, program);
} }
// Regression test for transformation bug which separates struct declarations from uniform
// declarations. The bug was that the uniform variable usage in the initializer of a new
// declaration (y below) was not being processed.
TEST_P(GLSLTest, UniformStructBug)
{
constexpr char kVS[] = R"(precision highp float;
uniform struct Global
{
float x;
} u_global;
void main() {
float y = u_global.x;
gl_Position = vec4(y);
})";
GLuint shader = glCreateShader(GL_VERTEX_SHADER);
const char *sourceArray[1] = {kVS};
GLint lengths[1] = {static_cast<GLint>(sizeof(kVS) - 1)};
glShaderSource(shader, 1, sourceArray, lengths);
glCompileShader(shader);
GLint compileResult;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
EXPECT_NE(compileResult, 0);
}
} // anonymous namespace } // anonymous namespace
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest);
......
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