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
if (!mInGlobalScope)
{
return false;
return true;
}
const TIntermSequence &sequence = *(decl->getSequence());
......@@ -61,10 +61,10 @@ class Traverser : public TIntermTraverser
TIntermTyped *declarator,
const TStructure *oldStructure)
{
// struct <structName> { ... };
const TStructure *structure = oldStructure;
if (oldStructure->symbolType() == SymbolType::Empty)
{
// Handle nameless structs: uniform struct { ... } variable;
structure = new TStructure(mSymbolTable, kEmptyImmutableString, &oldStructure->fields(),
SymbolType::AngleInternal);
}
......@@ -80,10 +80,10 @@ class Traverser : public TIntermTraverser
TIntermSequence newSequence;
newSequence.push_back(structDeclaration);
// uniform <structName> <structUniformName>;
// Redeclare the uniform with the (potentially) new struct type
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);
......@@ -95,8 +95,7 @@ class Traverser : public TIntermTraverser
newSequence.push_back(namedDecl);
mVariableMap[&asSymbol->variable()] = new TIntermSymbol(newVar);
}
mVariableMap[&asSymbol->variable()] = newSymbol;
mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
std::move(newSequence));
......
......@@ -10686,6 +10686,37 @@ void main()
GLuint program = CompileProgram(kVS, kFS);
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
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