Commit d7490967 by Zhenyao Mo Committed by Commit Bot

Fix linkage.html failures on Mac.

The failure is due to when we initialize variables to 0, we re-create the struct TType, and it contains a different unique id from the original struct TType, thus leading to a different hashed name. BUG=chromium:641129 TEST=webgl_conformance,webgl2_conformance Change-Id: I267b97fa496f55ea59dacee93af8f6a90f3e66cb Reviewed-on: https://chromium-review.googlesource.com/409602 Commit-Queue: Zhenyao Mo <zmo@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 4b97d504
......@@ -918,7 +918,7 @@ void TCompiler::initializeGLPosition(TIntermNode* root)
sh::ShaderVariable var(GL_FLOAT_VEC4, 0);
var.name = "gl_Position";
list.push_back(var);
InitializeVariables(root, list);
InitializeVariables(root, list, symbolTable);
}
void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root)
......@@ -934,7 +934,7 @@ void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root)
}
}
sh::UseInterfaceBlockFields(root, list);
sh::UseInterfaceBlockFields(root, list, symbolTable);
}
void TCompiler::initializeOutputVariables(TIntermNode *root)
......@@ -955,7 +955,7 @@ void TCompiler::initializeOutputVariables(TIntermNode *root)
list.push_back(var);
}
}
InitializeVariables(root, list);
InitializeVariables(root, list, symbolTable);
}
const TExtensionBehavior& TCompiler::getExtensionBehavior() const
......
......@@ -9,6 +9,7 @@
#include "angle_gl.h"
#include "common/debug.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
namespace sh
......@@ -20,9 +21,13 @@ namespace
class VariableInitializer : public TIntermTraverser
{
public:
VariableInitializer(const InitVariableList &vars)
: TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false)
VariableInitializer(const InitVariableList &vars, const TSymbolTable &symbolTable)
: TIntermTraverser(true, false, false),
mVariables(vars),
mSymbolTable(symbolTable),
mCodeInserted(false)
{
ASSERT(mSymbolTable.atGlobalLevel());
}
protected:
......@@ -39,6 +44,7 @@ class VariableInitializer : public TIntermTraverser
void insertInitCode(TIntermSequence *sequence);
const InitVariableList &mVariables;
const TSymbolTable &mSymbolTable;
bool mCodeInserted;
};
......@@ -62,23 +68,23 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence)
for (const auto &var : mVariables)
{
TString name = TString(var.name.c_str());
TType type = sh::GetShaderVariableType(var);
// Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
// doesn't have array assignment.
if (var.isArray())
{
// Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
// doesn't have array assignment.
size_t pos = name.find_last_of('[');
if (pos != TString::npos)
{
name = name.substr(0, pos);
}
TType elementType = type;
elementType.clearArrayness();
TType elementType = sh::GetShaderVariableBasicType(var);
TType arrayType = elementType;
arrayType.setArraySize(var.elementCount());
for (unsigned int i = 0; i < var.arraySize; ++i)
{
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type);
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, arrayType);
TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
TIntermTyped::CreateIndexNode(i));
......@@ -88,8 +94,20 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence)
sequence->insert(sequence->begin(), assignment);
}
}
else if (var.isStruct())
{
TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
ASSERT(structInfo);
TIntermSymbol *symbol = new TIntermSymbol(0, name, structInfo->getType());
TIntermTyped *zero = TIntermTyped::CreateZero(structInfo->getType());
TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
sequence->insert(sequence->begin(), assign);
}
else
{
TType type = sh::GetShaderVariableBasicType(var);
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
TIntermTyped *zero = TIntermTyped::CreateZero(type);
......@@ -101,9 +119,11 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence)
} // namespace anonymous
void InitializeVariables(TIntermNode *root, const InitVariableList &vars)
void InitializeVariables(TIntermNode *root,
const InitVariableList &vars,
const TSymbolTable &symbolTable)
{
VariableInitializer initializer(vars);
VariableInitializer initializer(vars, symbolTable);
root->traverse(&initializer);
}
......
......@@ -12,11 +12,20 @@
namespace sh
{
class TIntermNode;
class TSymbolTable;
typedef std::vector<sh::ShaderVariable> InitVariableList;
// This function cannot currently initialize structures containing arrays for an ESSL 1.00 backend.
void InitializeVariables(TIntermNode *root, const InitVariableList &vars);
// Currently this function is only capable of initializing variables of basic types,
// array of basic types, or struct of basic types.
// For now it is used for the following two scenarios:
// 1. initializing gl_Position;
// 2. initializing ESSL 3.00 shaders' output variables (which might be structs).
// Specifically, it's not feasible to make it work for local variables because if their
// types are structs, we can't look into TSymbolTable to find the TType data.
void InitializeVariables(TIntermNode *root,
const InitVariableList &vars,
const TSymbolTable &symbolTable);
} // namespace sh
#endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
......@@ -126,6 +126,12 @@ TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
return symbol;
}
TSymbol *TSymbolTable::findGlobal(const TString &name) const
{
ASSERT(table.size() > GLOBAL_LEVEL);
return table[GLOBAL_LEVEL]->find(name);
}
TSymbol *TSymbolTable::findBuiltIn(
const TString &name, int shaderVersion) const
{
......
......@@ -459,8 +459,11 @@ class TSymbolTable : angle::NonCopyable
TSymbol *find(const TString &name, int shaderVersion,
bool *builtIn = NULL, bool *sameScope = NULL) const;
TSymbol *findGlobal(const TString &name) const;
TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
TSymbolTableLevel *getOuterLevel()
{
assert(currentLevel() >= 1);
......
......@@ -11,6 +11,7 @@
#include "compiler/translator/UseInterfaceBlockFields.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
namespace sh
......@@ -22,9 +23,13 @@ namespace
class UseUniformBlockMembers : public TIntermTraverser
{
public:
UseUniformBlockMembers(const InterfaceBlockList &blocks)
: TIntermTraverser(true, false, false), mBlocks(blocks), mCodeInserted(false)
UseUniformBlockMembers(const InterfaceBlockList &blocks, const TSymbolTable &symbolTable)
: TIntermTraverser(true, false, false),
mBlocks(blocks),
mSymbolTable(symbolTable),
mCodeInserted(false)
{
ASSERT(mSymbolTable.atGlobalLevel());
}
protected:
......@@ -36,6 +41,7 @@ class UseUniformBlockMembers : public TIntermTraverser
void AddFieldUseStatements(const ShaderVariable &var, TIntermSequence *sequence);
const InterfaceBlockList &mBlocks;
const TSymbolTable &mSymbolTable;
bool mCodeInserted;
};
......@@ -57,8 +63,6 @@ void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var,
TIntermSequence *sequence)
{
TString name = TString(var.name.c_str());
TType type = GetShaderVariableType(var);
if (var.isArray())
{
size_t pos = name.find_last_of('[');
......@@ -66,33 +70,35 @@ void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var,
{
name = name.substr(0, pos);
}
TType elementType = type;
elementType.clearArrayness();
}
const TType *type;
TType basicType;
if (var.isStruct())
{
TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
ASSERT(structInfo);
const TType &structType = structInfo->getType();
type = &structType;
}
else
{
basicType = sh::GetShaderVariableBasicType(var);
type = &basicType;
}
ASSERT(type);
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type);
TIntermSymbol *symbol = new TIntermSymbol(0, name, *type);
if (var.isArray())
{
for (unsigned int i = 0; i < var.arraySize; ++i)
{
TIntermBinary *element =
new TIntermBinary(EOpIndexDirect, arraySymbol, TIntermTyped::CreateIndexNode(i));
sequence->insert(sequence->begin(), element);
}
}
else if (var.isStruct())
{
TIntermSymbol *structSymbol = new TIntermSymbol(0, name, type);
for (unsigned int i = 0; i < var.fields.size(); ++i)
{
TIntermBinary *element = new TIntermBinary(EOpIndexDirectStruct, structSymbol,
TIntermTyped::CreateIndexNode(i));
new TIntermBinary(EOpIndexDirect, symbol, TIntermTyped::CreateIndexNode(i));
sequence->insert(sequence->begin(), element);
}
}
else
{
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
sequence->insert(sequence->begin(), symbol);
}
}
......@@ -110,9 +116,10 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
}
else if (block.arraySize > 0)
{
TType type = GetInterfaceBlockType(block);
TString name = TString(block.instanceName.c_str());
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type);
TString name = TString(block.instanceName.c_str());
TVariable *ubInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
ASSERT(ubInfo);
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, ubInfo->getType());
for (unsigned int i = 0; i < block.arraySize; ++i)
{
TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol,
......@@ -128,9 +135,10 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
}
else
{
TType type = GetInterfaceBlockType(block);
TString name = TString(block.instanceName.c_str());
TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, type);
TString name = TString(block.instanceName.c_str());
TVariable *ubInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
ASSERT(ubInfo);
TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
for (unsigned int i = 0; i < block.fields.size(); ++i)
{
TIntermBinary *element = new TIntermBinary(
......@@ -144,9 +152,11 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
} // namespace anonymous
void UseInterfaceBlockFields(TIntermNode *root, const InterfaceBlockList &blocks)
void UseInterfaceBlockFields(TIntermNode *root,
const InterfaceBlockList &blocks,
const TSymbolTable &symbolTable)
{
UseUniformBlockMembers useUniformBlock(blocks);
UseUniformBlockMembers useUniformBlock(blocks, symbolTable);
root->traverse(&useUniformBlock);
}
......
......@@ -17,9 +17,14 @@ class TIntermNode;
namespace sh
{
class TSymbolTable;
using InterfaceBlockList = std::vector<sh::InterfaceBlock>;
void UseInterfaceBlockFields(TIntermNode *root, const InterfaceBlockList &blocks);
void UseInterfaceBlockFields(TIntermNode *root,
const InterfaceBlockList &blocks,
const TSymbolTable &symbolTable);
} // namespace sh
#endif // COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
......@@ -302,27 +302,6 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
}
}
TType GetInterfaceBlockType(const sh::InterfaceBlock &block)
{
TType type;
TFieldList *fields = new TFieldList;
TSourceLoc loc;
for (const auto &field : block.fields)
{
TType *fieldType = new TType(GetShaderVariableType(field));
fields->push_back(new TField(fieldType, new TString(field.name.c_str()), loc));
}
TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
new TString(block.name.c_str()), fields, new TString(block.instanceName.c_str()),
block.arraySize, TLayoutQualifier::create());
type.setBasicType(EbtInterfaceBlock);
type.setInterfaceBlock(interfaceBlock);
type.setArraySize(block.arraySize);
return type;
}
TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
{
switch (var.type)
......@@ -383,35 +362,6 @@ TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
}
}
TType GetShaderVariableType(const sh::ShaderVariable &var)
{
TType type;
if (var.isStruct())
{
TFieldList *fields = new TFieldList;
TSourceLoc loc;
for (const auto &field : var.fields)
{
TType *fieldType = new TType(GetShaderVariableType(field));
fields->push_back(new TField(fieldType, new TString(field.name.c_str()), loc));
}
TStructure *structure = new TStructure(new TString(var.structName.c_str()), fields);
type.setBasicType(EbtStruct);
type.setStruct(structure);
}
else
{
type = GetShaderVariableBasicType(var);
}
if (var.isArray())
{
type.setArraySize(var.elementCount());
}
return type;
}
TOperator TypeToConstructorOperator(const TType &type)
{
switch (type.getBasicType())
......
......@@ -37,9 +37,7 @@ bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier);
TString ArrayString(const TType &type);
TType GetInterfaceBlockType(const sh::InterfaceBlock &block);
TType GetShaderVariableBasicType(const sh::ShaderVariable &var);
TType GetShaderVariableType(const sh::ShaderVariable &var);
TOperator TypeToConstructorOperator(const TType &type);
......
......@@ -433,13 +433,6 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
return;
}
// This case fails on all AMD platforms (Mac, Linux, Win).
if (IsAMD())
{
std::cout << "Test skipped on AMD." << std::endl;
return;
}
const std::string &vertexShaderSource =
"#version 300 es\n"
"in vec2 position;\n"
......@@ -448,13 +441,10 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
" highp ivec3 a;\n"
" mediump ivec2 b[4];\n"
"};\n"
"struct T {\n"
" S c[2];\n"
"};\n"
"layout(std140) uniform blockName0 {\n"
" S s0;\n"
" lowp vec2 v0;\n"
" T t0[2];\n"
" S s1[2];\n"
" highp uint u0;\n"
"};\n"
"layout(std140) uniform blockName1 {\n"
......@@ -483,15 +473,14 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
// Note that the packed |blockName3| might (or might not) be optimized out.
GLint activeUniforms;
glGetProgramiv(program.get(), GL_ACTIVE_UNIFORMS, &activeUniforms);
ASSERT_EQ(15, activeUniforms);
EXPECT_GE(activeUniforms, 11);
GLint activeUniformBlocks;
glGetProgramiv(program.get(), GL_ACTIVE_UNIFORM_BLOCKS, &activeUniformBlocks);
ASSERT_EQ(3, activeUniformBlocks);
EXPECT_GE(activeUniformBlocks, 3);
GLint maxLength, size;
GLenum type;
......@@ -517,59 +506,39 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
glGetActiveUniform(program.get(), 3, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("t0[0].c[0].a", std::string(&strBuffer[0]));
EXPECT_EQ("s1[0].a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 4, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("t0[0].c[0].b[0]", std::string(&strBuffer[0]));
EXPECT_EQ("s1[0].b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 5, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("t0[0].c[1].a", std::string(&strBuffer[0]));
EXPECT_EQ("s1[1].a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 6, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("t0[0].c[1].b[0]", std::string(&strBuffer[0]));
EXPECT_EQ("s1[1].b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 7, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("t0[1].c[0].a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 8, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("t0[1].c[0].b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 9, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("t0[1].c[1].a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 10, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("t0[1].c[1].b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 11, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("u0", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 12, maxLength, &length, &size, &type, &strBuffer[0]);
glGetActiveUniform(program.get(), 8, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("blockName1.f1", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 13, maxLength, &length, &size, &type, &strBuffer[0]);
glGetActiveUniform(program.get(), 9, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("blockName1.b1", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 14, maxLength, &length, &size, &type, &strBuffer[0]);
glGetActiveUniform(program.get(), 10, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("f2", std::string(&strBuffer[0]));
......
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