Commit 173f1c94 by Jamie Madill Committed by Commit Bot

Translator: Collect gl_in as a varying.

This unifies the variable handling for IO blocks. Previously the gl_in block we treated as an "in block" similar to an interface block. Bug: angleproject:5423 Change-Id: Idf2db4c209055fa9ffca567dab39c89464eba156 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2571966Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 51a0e95d
......@@ -51,10 +51,6 @@ enum class BlockType
{
BLOCK_UNIFORM,
BLOCK_BUFFER,
// TODO: Remove gl_in from interface blocks and place it in varyings with the rest of shader I/O
// blocks, then remove GetInBlocks and getInBlocks everywhere. http://anglebug.com/5423
BLOCK_IN
};
// Base class for all variables defined in shaders, including Varyings, Uniforms, etc
......
......@@ -1097,6 +1097,8 @@ inline bool IsShaderIoBlock(TQualifier qualifier)
{
switch (qualifier)
{
case EvqPerVertexIn:
case EvqPerVertexOut:
case EvqVertexOut:
case EvqTessControlIn:
case EvqTessControlOut:
......
......@@ -46,8 +46,6 @@ BlockType GetBlockType(TQualifier qualifier)
return BlockType::BLOCK_UNIFORM;
case EvqBuffer:
return BlockType::BLOCK_BUFFER;
case EvqPerVertexIn:
return BlockType::BLOCK_IN;
default:
UNREACHABLE();
return BlockType::BLOCK_UNIFORM;
......@@ -123,7 +121,6 @@ class CollectVariablesTraverser : public TIntermTraverser
std::vector<ShaderVariable> *sharedVariables,
std::vector<InterfaceBlock> *uniformBlocks,
std::vector<InterfaceBlock> *shaderStorageBlocks,
std::vector<InterfaceBlock> *inBlocks,
ShHashFunction64 hashFunction,
TSymbolTable *symbolTable,
GLenum shaderType,
......@@ -166,7 +163,6 @@ class CollectVariablesTraverser : public TIntermTraverser
std::vector<ShaderVariable> *varyings);
void recordBuiltInFragmentOutputUsed(const TVariable &variable, bool *addedFlag);
void recordBuiltInAttributeUsed(const TVariable &variable, bool *addedFlag);
InterfaceBlock *recordGLInUsed(const TType &glInType);
InterfaceBlock *findNamedInterfaceBlock(const ImmutableString &name) const;
std::vector<ShaderVariable> *mAttribs;
......@@ -177,7 +173,6 @@ class CollectVariablesTraverser : public TIntermTraverser
std::vector<ShaderVariable> *mSharedVariables;
std::vector<InterfaceBlock> *mUniformBlocks;
std::vector<InterfaceBlock> *mShaderStorageBlocks;
std::vector<InterfaceBlock> *mInBlocks;
std::map<std::string, ShaderVariable *> mInterfaceBlockFields;
......@@ -248,7 +243,6 @@ CollectVariablesTraverser::CollectVariablesTraverser(
std::vector<sh::ShaderVariable> *sharedVariables,
std::vector<sh::InterfaceBlock> *uniformBlocks,
std::vector<sh::InterfaceBlock> *shaderStorageBlocks,
std::vector<sh::InterfaceBlock> *inBlocks,
ShHashFunction64 hashFunction,
TSymbolTable *symbolTable,
GLenum shaderType,
......@@ -262,7 +256,6 @@ CollectVariablesTraverser::CollectVariablesTraverser(
mSharedVariables(sharedVariables),
mUniformBlocks(uniformBlocks),
mShaderStorageBlocks(shaderStorageBlocks),
mInBlocks(inBlocks),
mDepthRangeAdded(false),
mNumSamplesAdded(false),
mNumWorkGroupsAdded(false),
......@@ -317,7 +310,10 @@ void CollectVariablesTraverser::setBuiltInInfoFromSymbol(const TVariable &variab
info->name = variable.name().data();
info->mappedName = variable.name().data();
setFieldOrVariableProperties(type, true, false, info);
bool isShaderIOBlock =
IsShaderIoBlock(type.getQualifier()) && type.getInterfaceBlock() != nullptr;
setFieldOrVariableProperties(type, true, isShaderIOBlock, info);
}
void CollectVariablesTraverser::recordBuiltInVaryingUsed(const TVariable &variable,
......@@ -364,24 +360,6 @@ void CollectVariablesTraverser::recordBuiltInAttributeUsed(const TVariable &vari
}
}
InterfaceBlock *CollectVariablesTraverser::recordGLInUsed(const TType &glInType)
{
if (!mPerVertexInAdded)
{
ASSERT(glInType.getQualifier() == EvqPerVertexIn);
InterfaceBlock info;
recordInterfaceBlock("gl_in", glInType, &info);
mPerVertexInAdded = true;
mInBlocks->push_back(info);
return &mInBlocks->back();
}
else
{
return FindVariable(ImmutableString("gl_PerVertex"), mInBlocks);
}
}
bool CollectVariablesTraverser::visitGlobalQualifierDeclaration(
Visit visit,
TIntermGlobalQualifierDeclaration *node)
......@@ -724,10 +702,8 @@ void CollectVariablesTraverser::setFieldOrVariableProperties(const TType &type,
variableOut->fields.push_back(fieldVariable);
}
}
else if (interfaceBlock && interfaceBlock->symbolType() != SymbolType::BuiltIn)
else if (interfaceBlock && isShaderIOBlock)
{
ASSERT(isShaderIOBlock);
variableOut->type = GL_NONE;
if (interfaceBlock->symbolType() != SymbolType::Empty)
{
......@@ -1119,31 +1095,28 @@ bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
bool traverseIndexExpression = false;
TIntermBinary *interfaceIndexingNode = blockNode->getAsBinaryNode();
TIntermTyped *interfaceNode = blockNode;
if (interfaceIndexingNode)
{
interfaceNode = interfaceIndexingNode->getLeft()->getAsTyped();
ASSERT(interfaceNode);
const TType &interfaceType = interfaceNode->getType();
if (interfaceType.getQualifier() == EvqPerVertexIn)
{
namedBlock = recordGLInUsed(interfaceType);
ASSERT(namedBlock);
}
// We need to continue traversing to collect useful variables in the index expression
// of the interface block array or gl_in in the case of the if above.
ASSERT(interfaceIndexingNode->getOp() == EOpIndexDirect ||
interfaceIndexingNode->getOp() == EOpIndexIndirect);
traverseIndexExpression = true;
blockNode = interfaceIndexingNode->getLeft();
}
const TType &interfaceNodeType = interfaceNode->getType();
const TType &interfaceNodeType = blockNode->getType();
const TInterfaceBlock *interfaceBlock = interfaceNodeType.getInterfaceBlock();
const TQualifier qualifier = interfaceNodeType.getQualifier();
// If it's a shader I/O block, look in varyings
ShaderVariable *ioBlockVar = nullptr;
if (IsVaryingIn(qualifier))
if (qualifier == EvqPerVertexIn)
{
TIntermSymbol *symbolNode = blockNode->getAsSymbolNode();
ASSERT(symbolNode);
recordBuiltInVaryingUsed(symbolNode->variable(), &mPerVertexInAdded, mInputVaryings);
ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
}
else if (IsVaryingIn(qualifier))
{
ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
}
......@@ -1196,7 +1169,6 @@ void CollectVariables(TIntermBlock *root,
std::vector<ShaderVariable> *sharedVariables,
std::vector<InterfaceBlock> *uniformBlocks,
std::vector<InterfaceBlock> *shaderStorageBlocks,
std::vector<InterfaceBlock> *inBlocks,
ShHashFunction64 hashFunction,
TSymbolTable *symbolTable,
GLenum shaderType,
......@@ -1204,8 +1176,8 @@ void CollectVariables(TIntermBlock *root,
{
CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings,
outputVaryings, sharedVariables, uniformBlocks,
shaderStorageBlocks, inBlocks, hashFunction, symbolTable,
shaderType, extensionBehavior);
shaderStorageBlocks, hashFunction, symbolTable, shaderType,
extensionBehavior);
root->traverse(&collect);
}
......
......@@ -27,7 +27,6 @@ void CollectVariables(TIntermBlock *root,
std::vector<ShaderVariable> *sharedVariables,
std::vector<InterfaceBlock> *uniformBlocks,
std::vector<InterfaceBlock> *shaderStorageBlocks,
std::vector<InterfaceBlock> *inBlocks,
ShHashFunction64 hashFunction,
TSymbolTable *symbolTable,
GLenum shaderType,
......
......@@ -806,8 +806,8 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
ASSERT(!mVariablesCollected);
CollectVariables(root, &mAttributes, &mOutputVariables, &mUniforms, &mInputVaryings,
&mOutputVaryings, &mSharedVariables, &mUniformBlocks,
&mShaderStorageBlocks, &mInBlocks, mResources.HashFunction, &mSymbolTable,
mShaderType, mExtensionBehavior);
&mShaderStorageBlocks, mResources.HashFunction, &mSymbolTable, mShaderType,
mExtensionBehavior);
collectInterfaceBlocks();
mVariablesCollected = true;
if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
......@@ -1156,12 +1156,10 @@ void TCompiler::setResourceString()
void TCompiler::collectInterfaceBlocks()
{
ASSERT(mInterfaceBlocks.empty());
mInterfaceBlocks.reserve(mUniformBlocks.size() + mShaderStorageBlocks.size() +
mInBlocks.size());
mInterfaceBlocks.reserve(mUniformBlocks.size() + mShaderStorageBlocks.size());
mInterfaceBlocks.insert(mInterfaceBlocks.end(), mUniformBlocks.begin(), mUniformBlocks.end());
mInterfaceBlocks.insert(mInterfaceBlocks.end(), mShaderStorageBlocks.begin(),
mShaderStorageBlocks.end());
mInterfaceBlocks.insert(mInterfaceBlocks.end(), mInBlocks.begin(), mInBlocks.end());
}
bool TCompiler::emulatePrecisionIfNeeded(TIntermBlock *root,
......@@ -1201,7 +1199,6 @@ void TCompiler::clearResults()
mInterfaceBlocks.clear();
mUniformBlocks.clear();
mShaderStorageBlocks.clear();
mInBlocks.clear();
mVariablesCollected = false;
mGLPositionInitialized = false;
......@@ -1249,7 +1246,7 @@ bool TCompiler::checkCallDepth()
int depth = 0;
const CallDAG::Record &record = mCallDag.getRecordFromIndex(i);
for (const int &calleeIndex : record.callees)
for (int calleeIndex : record.callees)
{
depth = std::max(depth, depths[calleeIndex] + 1);
}
......
......@@ -123,7 +123,6 @@ class TCompiler : public TShHandleBase
{
return mShaderStorageBlocks;
}
const std::vector<sh::InterfaceBlock> &getInBlocks() const { return mInBlocks; }
ShHashFunction64 getHashFunction() const { return mResources.HashFunction; }
NameMap &getNameMap() { return mNameMap; }
......@@ -195,7 +194,6 @@ class TCompiler : public TShHandleBase
std::vector<sh::InterfaceBlock> mInterfaceBlocks;
std::vector<sh::InterfaceBlock> mUniformBlocks;
std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
std::vector<sh::InterfaceBlock> mInBlocks;
// Specialization constant usage bits
SpecConstUsageBits mSpecConstUsageBits;
......
......@@ -1038,26 +1038,26 @@ TEST_F(CollectGeometryVariablesTest, CollectGLInFields)
compile(shaderString);
EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
EXPECT_TRUE(mTranslator->getInputVaryings().empty());
const auto &inBlocks = mTranslator->getInBlocks();
ASSERT_EQ(1u, inBlocks.size());
const std::vector<ShaderVariable> &inVaryings = mTranslator->getInputVaryings();
ASSERT_EQ(1u, inVaryings.size());
const InterfaceBlock *inBlock = &inBlocks[0];
EXPECT_EQ("gl_PerVertex", inBlock->name);
EXPECT_EQ("gl_in", inBlock->instanceName);
EXPECT_TRUE(inBlock->staticUse);
EXPECT_TRUE(inBlock->active);
EXPECT_TRUE(inBlock->isBuiltIn());
const ShaderVariable &glIn = inVaryings[0];
EXPECT_EQ("gl_in", glIn.name);
EXPECT_EQ("gl_PerVertex", glIn.structName);
EXPECT_TRUE(glIn.staticUse);
EXPECT_TRUE(glIn.active);
EXPECT_TRUE(glIn.isBuiltIn());
ASSERT_EQ(1u, inBlock->fields.size());
ASSERT_EQ(1u, glIn.fields.size());
const ShaderVariable &glPositionField = inBlock->fields[0];
const ShaderVariable &glPositionField = glIn.fields[0];
EXPECT_EQ("gl_Position", glPositionField.name);
EXPECT_FALSE(glPositionField.isArray());
EXPECT_FALSE(glPositionField.isStruct());
EXPECT_TRUE(glPositionField.staticUse);
EXPECT_TRUE(glPositionField.active);
// Tracking for "active" not set up currently.
// EXPECT_TRUE(glPositionField.active);
EXPECT_TRUE(glPositionField.isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, glPositionField.precision);
EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, glPositionField.type);
......@@ -1081,12 +1081,12 @@ TEST_F(CollectGeometryVariablesTest, GLInArraySize)
{
compileGeometryShaderWithInputPrimitive(kInputPrimitives[i], "", functionBody);
const auto &inBlocks = mTranslator->getInBlocks();
ASSERT_EQ(1u, inBlocks.size());
const std::vector<ShaderVariable> &inVaryings = mTranslator->getInputVaryings();
ASSERT_EQ(1u, inVaryings.size());
const InterfaceBlock *inBlock = &inBlocks[0];
ASSERT_EQ("gl_in", inBlock->instanceName);
EXPECT_EQ(kArraySizeForInputPrimitives[i], inBlock->arraySize);
const ShaderVariable &glIn = inVaryings[0];
ASSERT_EQ("gl_in", glIn.name);
EXPECT_EQ(kArraySizeForInputPrimitives[i], glIn.arraySizes[0]);
}
}
......@@ -1107,20 +1107,19 @@ TEST_F(CollectGeometryVariablesTest, CollectPrimitiveIDIn)
compile(shaderString);
EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
ASSERT_TRUE(mTranslator->getInBlocks().empty());
const auto &inputVaryings = mTranslator->getInputVaryings();
const std::vector<ShaderVariable> &inputVaryings = mTranslator->getInputVaryings();
ASSERT_EQ(1u, inputVaryings.size());
const ShaderVariable *varying = &inputVaryings[0];
EXPECT_EQ("gl_PrimitiveIDIn", varying->name);
EXPECT_FALSE(varying->isArray());
EXPECT_FALSE(varying->isStruct());
EXPECT_TRUE(varying->staticUse);
EXPECT_TRUE(varying->active);
EXPECT_TRUE(varying->isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
EXPECT_GLENUM_EQ(GL_INT, varying->type);
const ShaderVariable &varying = inputVaryings[0];
EXPECT_EQ("gl_PrimitiveIDIn", varying.name);
EXPECT_FALSE(varying.isArray());
EXPECT_FALSE(varying.isStruct());
EXPECT_TRUE(varying.staticUse);
EXPECT_TRUE(varying.active);
EXPECT_TRUE(varying.isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_INT, varying.precision);
EXPECT_GLENUM_EQ(GL_INT, varying.type);
}
// Test collecting gl_InvocationID in a geometry shader.
......@@ -1140,20 +1139,19 @@ TEST_F(CollectGeometryVariablesTest, CollectInvocationID)
compile(shaderString);
EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
ASSERT_TRUE(mTranslator->getInBlocks().empty());
const auto &inputVaryings = mTranslator->getInputVaryings();
const std::vector<ShaderVariable> &inputVaryings = mTranslator->getInputVaryings();
ASSERT_EQ(1u, inputVaryings.size());
const ShaderVariable *varying = &inputVaryings[0];
EXPECT_EQ("gl_InvocationID", varying->name);
EXPECT_FALSE(varying->isArray());
EXPECT_FALSE(varying->isStruct());
EXPECT_TRUE(varying->staticUse);
EXPECT_TRUE(varying->active);
EXPECT_TRUE(varying->isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
EXPECT_GLENUM_EQ(GL_INT, varying->type);
const ShaderVariable &varying = inputVaryings[0];
EXPECT_EQ("gl_InvocationID", varying.name);
EXPECT_FALSE(varying.isArray());
EXPECT_FALSE(varying.isStruct());
EXPECT_TRUE(varying.staticUse);
EXPECT_TRUE(varying.active);
EXPECT_TRUE(varying.isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_INT, varying.precision);
EXPECT_GLENUM_EQ(GL_INT, varying.type);
}
// Test collecting gl_in in a geometry shader when gl_in is indexed by an expression.
......@@ -1174,16 +1172,28 @@ TEST_F(CollectGeometryVariablesTest, CollectGLInIndexedByExpression)
EXPECT_EQ(1u, mTranslator->getOutputVaryings().size());
const auto &inBlocks = mTranslator->getInBlocks();
ASSERT_EQ(1u, inBlocks.size());
const InterfaceBlock *inBlock = &inBlocks[0];
EXPECT_EQ("gl_PerVertex", inBlock->name);
EXPECT_EQ("gl_in", inBlock->instanceName);
const std::vector<ShaderVariable> &inVaryings = mTranslator->getInputVaryings();
ASSERT_EQ(2u, inVaryings.size());
const auto &inputVaryings = mTranslator->getInputVaryings();
ASSERT_EQ(1u, inputVaryings.size());
const ShaderVariable *glInvocationID = &inputVaryings[0];
EXPECT_EQ("gl_InvocationID", glInvocationID->name);
bool foundGLIn = false;
bool foundInvocationID = false;
for (const ShaderVariable &varying : inVaryings)
{
if (varying.name == "gl_in")
{
foundGLIn = true;
EXPECT_TRUE(varying.isShaderIOBlock);
EXPECT_EQ("gl_PerVertex", varying.structName);
}
else if (varying.name == "gl_InvocationID")
{
foundInvocationID = true;
}
}
EXPECT_TRUE(foundGLIn);
EXPECT_TRUE(foundInvocationID);
}
// Test collecting gl_Position in a geometry shader.
......@@ -1202,20 +1212,19 @@ TEST_F(CollectGeometryVariablesTest, CollectPosition)
compile(shaderString);
ASSERT_TRUE(mTranslator->getInputVaryings().empty());
ASSERT_TRUE(mTranslator->getInBlocks().empty());
const auto &outputVaryings = mTranslator->getOutputVaryings();
const std::vector<ShaderVariable> &outputVaryings = mTranslator->getOutputVaryings();
ASSERT_EQ(1u, outputVaryings.size());
const ShaderVariable *varying = &outputVaryings[0];
EXPECT_EQ("gl_Position", varying->name);
EXPECT_FALSE(varying->isArray());
EXPECT_FALSE(varying->isStruct());
EXPECT_TRUE(varying->staticUse);
EXPECT_TRUE(varying->active);
EXPECT_TRUE(varying->isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, varying->precision);
EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, varying->type);
const ShaderVariable &varying = outputVaryings[0];
EXPECT_EQ("gl_Position", varying.name);
EXPECT_FALSE(varying.isArray());
EXPECT_FALSE(varying.isStruct());
EXPECT_TRUE(varying.staticUse);
EXPECT_TRUE(varying.active);
EXPECT_TRUE(varying.isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, varying.precision);
EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, varying.type);
}
// Test collecting gl_PrimitiveID in a geometry shader.
......@@ -1234,20 +1243,19 @@ TEST_F(CollectGeometryVariablesTest, CollectPrimitiveID)
compile(shaderString);
ASSERT_TRUE(mTranslator->getInputVaryings().empty());
ASSERT_TRUE(mTranslator->getInBlocks().empty());
const auto &OutputVaryings = mTranslator->getOutputVaryings();
ASSERT_EQ(1u, OutputVaryings.size());
const std::vector<ShaderVariable> &outputVaryings = mTranslator->getOutputVaryings();
ASSERT_EQ(1u, outputVaryings.size());
const ShaderVariable *varying = &OutputVaryings[0];
EXPECT_EQ("gl_PrimitiveID", varying->name);
EXPECT_FALSE(varying->isArray());
EXPECT_FALSE(varying->isStruct());
EXPECT_TRUE(varying->staticUse);
EXPECT_TRUE(varying->active);
EXPECT_TRUE(varying->isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
EXPECT_GLENUM_EQ(GL_INT, varying->type);
const ShaderVariable &varying = outputVaryings[0];
EXPECT_EQ("gl_PrimitiveID", varying.name);
EXPECT_FALSE(varying.isArray());
EXPECT_FALSE(varying.isStruct());
EXPECT_TRUE(varying.staticUse);
EXPECT_TRUE(varying.active);
EXPECT_TRUE(varying.isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_INT, varying.precision);
EXPECT_GLENUM_EQ(GL_INT, varying.type);
}
// Test collecting gl_Layer in a geometry shader.
......@@ -1266,20 +1274,19 @@ TEST_F(CollectGeometryVariablesTest, CollectLayer)
compile(shaderString);
ASSERT_TRUE(mTranslator->getInputVaryings().empty());
ASSERT_TRUE(mTranslator->getInBlocks().empty());
const auto &OutputVaryings = mTranslator->getOutputVaryings();
ASSERT_EQ(1u, OutputVaryings.size());
const auto &outputVaryings = mTranslator->getOutputVaryings();
ASSERT_EQ(1u, outputVaryings.size());
const ShaderVariable *varying = &OutputVaryings[0];
EXPECT_EQ("gl_Layer", varying->name);
EXPECT_FALSE(varying->isArray());
EXPECT_FALSE(varying->isStruct());
EXPECT_TRUE(varying->staticUse);
EXPECT_TRUE(varying->active);
EXPECT_TRUE(varying->isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_INT, varying->precision);
EXPECT_GLENUM_EQ(GL_INT, varying->type);
const ShaderVariable &varying = outputVaryings[0];
EXPECT_EQ("gl_Layer", varying.name);
EXPECT_FALSE(varying.isArray());
EXPECT_FALSE(varying.isStruct());
EXPECT_TRUE(varying.staticUse);
EXPECT_TRUE(varying.active);
EXPECT_TRUE(varying.isBuiltIn());
EXPECT_GLENUM_EQ(GL_HIGH_INT, varying.precision);
EXPECT_GLENUM_EQ(GL_INT, varying.type);
}
// Test collecting gl_PrimitiveID in a fragment shader.
......
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