Commit b547ddf5 by Jamie Madill

Fix interface block static use tracking.

The current code couldn't handle some uses of interface blocks, such as blocks with instance names. BUG=angle:466 Change-Id: I0a3746f277af0538cede30232532c6788412da1c Reviewed-on: https://chromium-review.googlesource.com/213502Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarNicolas Capens <capn@chromium.org>
parent 42bcf32e
...@@ -128,7 +128,11 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -128,7 +128,11 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
{ {
var = FindVariable(symbolName, mVaryings); var = FindVariable(symbolName, mVaryings);
} }
else if (symbol->getType() != EbtInterfaceBlock) else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
{
UNREACHABLE();
}
else
{ {
switch (symbol->getQualifier()) switch (symbol->getQualifier())
{ {
...@@ -150,6 +154,7 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -150,6 +154,7 @@ 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
{ {
...@@ -314,6 +319,7 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) ...@@ -314,6 +319,7 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
if (typedNode.getBasicType() == EbtInterfaceBlock) if (typedNode.getBasicType() == EbtInterfaceBlock)
{ {
visitInfoList(sequence, mInterfaceBlocks); visitInfoList(sequence, mInterfaceBlocks);
visitChildren = false;
} }
else if (qualifier == EvqAttribute || qualifier == EvqVertexIn || else if (qualifier == EvqAttribute || qualifier == EvqVertexIn ||
qualifier == EvqFragmentOut || qualifier == EvqUniform || qualifier == EvqFragmentOut || qualifier == EvqUniform ||
...@@ -346,6 +352,30 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) ...@@ -346,6 +352,30 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
return visitChildren; return visitChildren;
} }
bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
{
if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
{
TIntermSymbol *symbol = binaryNode->getLeft()->getAsSymbolNode();
ASSERT(symbol);
TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
ASSERT(constantUnion);
const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
sh::InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
ASSERT(namedBlock);
namedBlock->staticUse = true;
unsigned int fieldIndex = constantUnion->getUConst(0);
ASSERT(fieldIndex < namedBlock->fields.size());
namedBlock->fields[fieldIndex].staticUse = true;
return false;
}
return true;
}
template <typename VarT> template <typename VarT>
void ExpandVariables(const std::vector<VarT> &compact, void ExpandVariables(const std::vector<VarT> &compact,
std::vector<sh::ShaderVariable> *expanded) std::vector<sh::ShaderVariable> *expanded)
......
...@@ -24,6 +24,7 @@ class CollectVariables : public TIntermTraverser ...@@ -24,6 +24,7 @@ class CollectVariables : public TIntermTraverser
virtual void visitSymbol(TIntermSymbol *symbol); virtual void visitSymbol(TIntermSymbol *symbol);
virtual bool visitAggregate(Visit, TIntermAggregate *node); virtual bool visitAggregate(Visit, TIntermAggregate *node);
virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode);
private: private:
template <typename VarT> template <typename VarT>
......
...@@ -167,3 +167,128 @@ TEST_F(CollectVertexVariablesTest, SimpleInterfaceBlock) ...@@ -167,3 +167,128 @@ TEST_F(CollectVertexVariablesTest, SimpleInterfaceBlock)
EXPECT_FALSE(field.isRowMajorMatrix); EXPECT_FALSE(field.isRowMajorMatrix);
EXPECT_TRUE(field.fields.empty()); EXPECT_TRUE(field.fields.empty());
} }
TEST_F(CollectVertexVariablesTest, SimpleInstancedInterfaceBlock)
{
const std::string &shaderString =
"#version 300 es\n"
"uniform b {\n"
" float f;\n"
"} blockInstance;"
"void main() {\n"
" gl_Position = vec4(blockInstance.f, 0.0, 0.0, 1.0);\n"
"}\n";
const char *shaderStrings[] = { shaderString.c_str() };
ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
ASSERT_EQ(1u, interfaceBlocks.size());
const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
EXPECT_EQ(0u, interfaceBlock.arraySize);
EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
EXPECT_EQ("b", interfaceBlock.name);
EXPECT_TRUE(interfaceBlock.staticUse);
ASSERT_EQ(1u, interfaceBlock.fields.size());
const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, field.precision);
EXPECT_TRUE(field.staticUse);
EXPECT_GLENUM_EQ(GL_FLOAT, field.type);
EXPECT_EQ("b.f", field.name);
EXPECT_FALSE(field.isRowMajorMatrix);
EXPECT_TRUE(field.fields.empty());
}
TEST_F(CollectVertexVariablesTest, StructInterfaceBlock)
{
const std::string &shaderString =
"#version 300 es\n"
"struct st { float f; };"
"uniform b {\n"
" st s;\n"
"};"
"void main() {\n"
" gl_Position = vec4(s.f, 0.0, 0.0, 1.0);\n"
"}\n";
const char *shaderStrings[] = { shaderString.c_str() };
ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
ASSERT_EQ(1u, interfaceBlocks.size());
const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
EXPECT_EQ(0u, interfaceBlock.arraySize);
EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
EXPECT_EQ("b", interfaceBlock.name);
EXPECT_TRUE(interfaceBlock.staticUse);
ASSERT_EQ(1u, interfaceBlock.fields.size());
const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
EXPECT_TRUE(field.isStruct());
EXPECT_TRUE(field.staticUse);
EXPECT_EQ("s", field.name);
EXPECT_FALSE(field.isRowMajorMatrix);
const sh::ShaderVariable &member = field.fields[0];
// NOTE: we don't currently mark struct members as statically used or not
EXPECT_FALSE(member.isStruct());
EXPECT_EQ("f", member.name);
EXPECT_GLENUM_EQ(GL_FLOAT, member.type);
EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, member.precision);
}
TEST_F(CollectVertexVariablesTest, StructInstancedInterfaceBlock)
{
const std::string &shaderString =
"#version 300 es\n"
"struct st { float f; };"
"uniform b {\n"
" st s;\n"
"} instanceName;"
"void main() {\n"
" gl_Position = vec4(instanceName.s.f, 0.0, 0.0, 1.0);\n"
"}\n";
const char *shaderStrings[] = { shaderString.c_str() };
ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
ASSERT_EQ(1u, interfaceBlocks.size());
const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
EXPECT_EQ(0u, interfaceBlock.arraySize);
EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
EXPECT_EQ("b", interfaceBlock.name);
EXPECT_TRUE(interfaceBlock.staticUse);
ASSERT_EQ(1u, interfaceBlock.fields.size());
const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
EXPECT_TRUE(field.isStruct());
EXPECT_TRUE(field.staticUse);
EXPECT_EQ("b.s", field.name);
EXPECT_FALSE(field.isRowMajorMatrix);
const sh::ShaderVariable &member = field.fields[0];
// NOTE: we don't currently mark struct members as statically used or not
EXPECT_FALSE(member.isStruct());
EXPECT_EQ("f", member.name);
EXPECT_GLENUM_EQ(GL_FLOAT, member.type);
EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, member.precision);
}
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