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) ...@@ -918,7 +918,7 @@ void TCompiler::initializeGLPosition(TIntermNode* root)
sh::ShaderVariable var(GL_FLOAT_VEC4, 0); sh::ShaderVariable var(GL_FLOAT_VEC4, 0);
var.name = "gl_Position"; var.name = "gl_Position";
list.push_back(var); list.push_back(var);
InitializeVariables(root, list); InitializeVariables(root, list, symbolTable);
} }
void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root) void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root)
...@@ -934,7 +934,7 @@ 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) void TCompiler::initializeOutputVariables(TIntermNode *root)
...@@ -955,7 +955,7 @@ void TCompiler::initializeOutputVariables(TIntermNode *root) ...@@ -955,7 +955,7 @@ void TCompiler::initializeOutputVariables(TIntermNode *root)
list.push_back(var); list.push_back(var);
} }
} }
InitializeVariables(root, list); InitializeVariables(root, list, symbolTable);
} }
const TExtensionBehavior& TCompiler::getExtensionBehavior() const const TExtensionBehavior& TCompiler::getExtensionBehavior() const
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "angle_gl.h" #include "angle_gl.h"
#include "common/debug.h" #include "common/debug.h"
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h" #include "compiler/translator/util.h"
namespace sh namespace sh
...@@ -20,9 +21,13 @@ namespace ...@@ -20,9 +21,13 @@ namespace
class VariableInitializer : public TIntermTraverser class VariableInitializer : public TIntermTraverser
{ {
public: public:
VariableInitializer(const InitVariableList &vars) VariableInitializer(const InitVariableList &vars, const TSymbolTable &symbolTable)
: TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false) : TIntermTraverser(true, false, false),
mVariables(vars),
mSymbolTable(symbolTable),
mCodeInserted(false)
{ {
ASSERT(mSymbolTable.atGlobalLevel());
} }
protected: protected:
...@@ -39,6 +44,7 @@ class VariableInitializer : public TIntermTraverser ...@@ -39,6 +44,7 @@ class VariableInitializer : public TIntermTraverser
void insertInitCode(TIntermSequence *sequence); void insertInitCode(TIntermSequence *sequence);
const InitVariableList &mVariables; const InitVariableList &mVariables;
const TSymbolTable &mSymbolTable;
bool mCodeInserted; bool mCodeInserted;
}; };
...@@ -62,23 +68,23 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence) ...@@ -62,23 +68,23 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence)
for (const auto &var : mVariables) for (const auto &var : mVariables)
{ {
TString name = TString(var.name.c_str()); 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()) 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('['); size_t pos = name.find_last_of('[');
if (pos != TString::npos) if (pos != TString::npos)
{ {
name = name.substr(0, pos); name = name.substr(0, pos);
} }
TType elementType = type; TType elementType = sh::GetShaderVariableBasicType(var);
elementType.clearArrayness(); TType arrayType = elementType;
arrayType.setArraySize(var.elementCount());
for (unsigned int i = 0; i < var.arraySize; ++i) 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, TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
TIntermTyped::CreateIndexNode(i)); TIntermTyped::CreateIndexNode(i));
...@@ -88,8 +94,20 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence) ...@@ -88,8 +94,20 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence)
sequence->insert(sequence->begin(), assignment); 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 else
{ {
TType type = sh::GetShaderVariableBasicType(var);
TIntermSymbol *symbol = new TIntermSymbol(0, name, type); TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
TIntermTyped *zero = TIntermTyped::CreateZero(type); TIntermTyped *zero = TIntermTyped::CreateZero(type);
...@@ -101,9 +119,11 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence) ...@@ -101,9 +119,11 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence)
} // namespace anonymous } // 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); root->traverse(&initializer);
} }
......
...@@ -12,11 +12,20 @@ ...@@ -12,11 +12,20 @@
namespace sh namespace sh
{ {
class TIntermNode; class TIntermNode;
class TSymbolTable;
typedef std::vector<sh::ShaderVariable> InitVariableList; typedef std::vector<sh::ShaderVariable> InitVariableList;
// This function cannot currently initialize structures containing arrays for an ESSL 1.00 backend. // Currently this function is only capable of initializing variables of basic types,
void InitializeVariables(TIntermNode *root, const InitVariableList &vars); // 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 } // namespace sh
#endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ #endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
...@@ -126,6 +126,12 @@ TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, ...@@ -126,6 +126,12 @@ TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
return symbol; return symbol;
} }
TSymbol *TSymbolTable::findGlobal(const TString &name) const
{
ASSERT(table.size() > GLOBAL_LEVEL);
return table[GLOBAL_LEVEL]->find(name);
}
TSymbol *TSymbolTable::findBuiltIn( TSymbol *TSymbolTable::findBuiltIn(
const TString &name, int shaderVersion) const const TString &name, int shaderVersion) const
{ {
......
...@@ -459,8 +459,11 @@ class TSymbolTable : angle::NonCopyable ...@@ -459,8 +459,11 @@ class TSymbolTable : angle::NonCopyable
TSymbol *find(const TString &name, int shaderVersion, TSymbol *find(const TString &name, int shaderVersion,
bool *builtIn = NULL, bool *sameScope = NULL) const; bool *builtIn = NULL, bool *sameScope = NULL) const;
TSymbol *findGlobal(const TString &name) const;
TSymbol *findBuiltIn(const TString &name, int shaderVersion) const; TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
TSymbolTableLevel *getOuterLevel() TSymbolTableLevel *getOuterLevel()
{ {
assert(currentLevel() >= 1); assert(currentLevel() >= 1);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "compiler/translator/UseInterfaceBlockFields.h" #include "compiler/translator/UseInterfaceBlockFields.h"
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h" #include "compiler/translator/util.h"
namespace sh namespace sh
...@@ -22,9 +23,13 @@ namespace ...@@ -22,9 +23,13 @@ namespace
class UseUniformBlockMembers : public TIntermTraverser class UseUniformBlockMembers : public TIntermTraverser
{ {
public: public:
UseUniformBlockMembers(const InterfaceBlockList &blocks) UseUniformBlockMembers(const InterfaceBlockList &blocks, const TSymbolTable &symbolTable)
: TIntermTraverser(true, false, false), mBlocks(blocks), mCodeInserted(false) : TIntermTraverser(true, false, false),
mBlocks(blocks),
mSymbolTable(symbolTable),
mCodeInserted(false)
{ {
ASSERT(mSymbolTable.atGlobalLevel());
} }
protected: protected:
...@@ -36,6 +41,7 @@ class UseUniformBlockMembers : public TIntermTraverser ...@@ -36,6 +41,7 @@ class UseUniformBlockMembers : public TIntermTraverser
void AddFieldUseStatements(const ShaderVariable &var, TIntermSequence *sequence); void AddFieldUseStatements(const ShaderVariable &var, TIntermSequence *sequence);
const InterfaceBlockList &mBlocks; const InterfaceBlockList &mBlocks;
const TSymbolTable &mSymbolTable;
bool mCodeInserted; bool mCodeInserted;
}; };
...@@ -57,8 +63,6 @@ void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var, ...@@ -57,8 +63,6 @@ void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var,
TIntermSequence *sequence) TIntermSequence *sequence)
{ {
TString name = TString(var.name.c_str()); TString name = TString(var.name.c_str());
TType type = GetShaderVariableType(var);
if (var.isArray()) if (var.isArray())
{ {
size_t pos = name.find_last_of('['); size_t pos = name.find_last_of('[');
...@@ -66,33 +70,35 @@ void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var, ...@@ -66,33 +70,35 @@ void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var,
{ {
name = name.substr(0, pos); 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) for (unsigned int i = 0; i < var.arraySize; ++i)
{ {
TIntermBinary *element = TIntermBinary *element =
new TIntermBinary(EOpIndexDirect, arraySymbol, TIntermTyped::CreateIndexNode(i)); new TIntermBinary(EOpIndexDirect, symbol, 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));
sequence->insert(sequence->begin(), element); sequence->insert(sequence->begin(), element);
} }
} }
else else
{ {
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
sequence->insert(sequence->begin(), symbol); sequence->insert(sequence->begin(), symbol);
} }
} }
...@@ -110,9 +116,10 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence) ...@@ -110,9 +116,10 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
} }
else if (block.arraySize > 0) else if (block.arraySize > 0)
{ {
TType type = GetInterfaceBlockType(block); TString name = TString(block.instanceName.c_str());
TString name = TString(block.instanceName.c_str()); TVariable *ubInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type); ASSERT(ubInfo);
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, ubInfo->getType());
for (unsigned int i = 0; i < block.arraySize; ++i) for (unsigned int i = 0; i < block.arraySize; ++i)
{ {
TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol, TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol,
...@@ -128,9 +135,10 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence) ...@@ -128,9 +135,10 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
} }
else else
{ {
TType type = GetInterfaceBlockType(block); TString name = TString(block.instanceName.c_str());
TString name = TString(block.instanceName.c_str()); TVariable *ubInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, type); ASSERT(ubInfo);
TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
for (unsigned int i = 0; i < block.fields.size(); ++i) for (unsigned int i = 0; i < block.fields.size(); ++i)
{ {
TIntermBinary *element = new TIntermBinary( TIntermBinary *element = new TIntermBinary(
...@@ -144,9 +152,11 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence) ...@@ -144,9 +152,11 @@ void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
} // namespace anonymous } // 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); root->traverse(&useUniformBlock);
} }
......
...@@ -17,9 +17,14 @@ class TIntermNode; ...@@ -17,9 +17,14 @@ class TIntermNode;
namespace sh namespace sh
{ {
class TSymbolTable;
using InterfaceBlockList = std::vector<sh::InterfaceBlock>; 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 } // namespace sh
#endif // COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_ #endif // COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
...@@ -302,27 +302,6 @@ InterpolationType GetInterpolationType(TQualifier qualifier) ...@@ -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) TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
{ {
switch (var.type) switch (var.type)
...@@ -383,35 +362,6 @@ TType GetShaderVariableBasicType(const sh::ShaderVariable &var) ...@@ -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) TOperator TypeToConstructorOperator(const TType &type)
{ {
switch (type.getBasicType()) switch (type.getBasicType())
......
...@@ -37,9 +37,7 @@ bool IsVarying(TQualifier qualifier); ...@@ -37,9 +37,7 @@ bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier); InterpolationType GetInterpolationType(TQualifier qualifier);
TString ArrayString(const TType &type); TString ArrayString(const TType &type);
TType GetInterfaceBlockType(const sh::InterfaceBlock &block);
TType GetShaderVariableBasicType(const sh::ShaderVariable &var); TType GetShaderVariableBasicType(const sh::ShaderVariable &var);
TType GetShaderVariableType(const sh::ShaderVariable &var);
TOperator TypeToConstructorOperator(const TType &type); TOperator TypeToConstructorOperator(const TType &type);
......
...@@ -433,13 +433,6 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName) ...@@ -433,13 +433,6 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
return; 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 = const std::string &vertexShaderSource =
"#version 300 es\n" "#version 300 es\n"
"in vec2 position;\n" "in vec2 position;\n"
...@@ -448,13 +441,10 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName) ...@@ -448,13 +441,10 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
" highp ivec3 a;\n" " highp ivec3 a;\n"
" mediump ivec2 b[4];\n" " mediump ivec2 b[4];\n"
"};\n" "};\n"
"struct T {\n"
" S c[2];\n"
"};\n"
"layout(std140) uniform blockName0 {\n" "layout(std140) uniform blockName0 {\n"
" S s0;\n" " S s0;\n"
" lowp vec2 v0;\n" " lowp vec2 v0;\n"
" T t0[2];\n" " S s1[2];\n"
" highp uint u0;\n" " highp uint u0;\n"
"};\n" "};\n"
"layout(std140) uniform blockName1 {\n" "layout(std140) uniform blockName1 {\n"
...@@ -483,15 +473,14 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName) ...@@ -483,15 +473,14 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource); ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
// Note that the packed |blockName3| might (or might not) be optimized out.
GLint activeUniforms; GLint activeUniforms;
glGetProgramiv(program.get(), GL_ACTIVE_UNIFORMS, &activeUniforms); glGetProgramiv(program.get(), GL_ACTIVE_UNIFORMS, &activeUniforms);
EXPECT_GE(activeUniforms, 11);
ASSERT_EQ(15, activeUniforms);
GLint activeUniformBlocks; GLint activeUniformBlocks;
glGetProgramiv(program.get(), GL_ACTIVE_UNIFORM_BLOCKS, &activeUniformBlocks); glGetProgramiv(program.get(), GL_ACTIVE_UNIFORM_BLOCKS, &activeUniformBlocks);
EXPECT_GE(activeUniformBlocks, 3);
ASSERT_EQ(3, activeUniformBlocks);
GLint maxLength, size; GLint maxLength, size;
GLenum type; GLenum type;
...@@ -517,59 +506,39 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName) ...@@ -517,59 +506,39 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
glGetActiveUniform(program.get(), 3, maxLength, &length, &size, &type, &strBuffer[0]); glGetActiveUniform(program.get(), 3, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size); 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]); glGetActiveUniform(program.get(), 4, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size); 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]); glGetActiveUniform(program.get(), 5, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size); 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]); glGetActiveUniform(program.get(), 6, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size); 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]); glGetActiveUniform(program.get(), 7, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size); 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])); 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(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size); EXPECT_EQ(1, size);
EXPECT_EQ("blockName1.f1", std::string(&strBuffer[0])); 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(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size); EXPECT_EQ(1, size);
EXPECT_EQ("blockName1.b1", std::string(&strBuffer[0])); 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(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size); EXPECT_EQ(1, size);
EXPECT_EQ("f2", std::string(&strBuffer[0])); 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