Commit 977ee7eb by Olli Etuaho Committed by Commit Bot

Add gl_ViewportIndex to the symbol table

gl_ViewportIndex is a GLSL built-in that's needed to implement instanced multiview. It is a bit of a special case: it only exists in desktop GLSL and not ESSL, and it shouldn't be exposed to the parser. We add a new level to the symbol table that's hidden from the parser to make adding this kind of builtins in AST transforms consistent with the way ESSL builtins are supported. BUG=angleproject:1490 TEST=angle_unittests Change-Id: I51b2d983950b38c8e85e4b6ed00c6b39f9b3cb03 Reviewed-on: https://chromium-review.googlesource.com/580953 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 4e619f58
......@@ -628,11 +628,12 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
compileResources = resources;
setResourceString();
assert(symbolTable.isEmpty());
ASSERT(symbolTable.isEmpty());
symbolTable.push(); // COMMON_BUILTINS
symbolTable.push(); // ESSL1_BUILTINS
symbolTable.push(); // ESSL3_BUILTINS
symbolTable.push(); // ESSL3_1_BUILTINS
symbolTable.push(); // GLSL_BUILTINS
switch (shaderType)
{
......
......@@ -113,7 +113,8 @@ void DeclareGlobalVariable(TIntermBlock *root, TIntermTyped *typedNode)
// added to the end of the initializers' sequence.
void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
TIntermTyped *multiviewBaseViewLayerIndexSymbol,
TIntermSequence *initializers)
TIntermSequence *initializers,
const TSymbolTable &symbolTable)
{
// Create an int(ViewID_OVR) node.
TIntermSequence *viewIDSymbolCastArguments = new TIntermSequence();
......@@ -123,7 +124,7 @@ void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
// Create a gl_ViewportIndex node.
TIntermSymbol *viewportIndexSymbol =
new TIntermSymbol(0, "gl_ViewportIndex", TType(EbtInt, EbpHigh, EvqViewportIndex));
ReferenceBuiltInVariable("gl_ViewportIndex", symbolTable, 0);
// Create a { gl_ViewportIndex = int(ViewID_OVR) } node.
TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock();
......@@ -206,7 +207,7 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// initialization.
SelectViewIndexInVertexShader(viewIDSymbol->deepCopy(),
multiviewBaseViewLayerIndexSymbol->deepCopy(),
initializers);
initializers, *symbolTable);
}
// Insert initializers at the beginning of main().
......
......@@ -871,11 +871,11 @@ void IdentifyBuiltIns(sh::GLenum type,
"gl_LastFragColorARM",
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4));
}
}
break;
break;
}
case GL_VERTEX_SHADER:
{
symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position",
TType(EbtFloat, EbpHigh, EvqPosition, 4));
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize",
......@@ -884,7 +884,12 @@ void IdentifyBuiltIns(sh::GLenum type,
TType(EbtInt, EbpHigh, EvqInstanceID, 1));
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID",
TType(EbtInt, EbpHigh, EvqVertexID, 1));
// For internal use by ANGLE - not exposed to the parser.
symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex",
TType(EbtInt, EbpHigh, EvqViewportIndex));
break;
}
case GL_COMPUTE_SHADER:
{
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups",
......@@ -899,15 +904,15 @@ void IdentifyBuiltIns(sh::GLenum type,
TType(EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3));
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationIndex",
TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1));
break;
}
break;
case GL_GEOMETRY_SHADER_OES:
// TODO(jiawei.shao@intel.com): add Geometry Shader built-in variables.
break;
default:
assert(false && "Language not supported");
UNREACHABLE();
}
}
......
......@@ -193,7 +193,7 @@ TIntermSymbol *ReferenceBuiltInVariable(const TString &name,
int shaderVersion)
{
const TVariable *var =
reinterpret_cast<const TVariable *>(symbolTable.findBuiltIn(name, shaderVersion));
reinterpret_cast<const TVariable *>(symbolTable.findBuiltIn(name, shaderVersion, true));
ASSERT(var);
return new TIntermSymbol(var->getUniqueId(), name, var->getType());
}
......
......@@ -35,7 +35,10 @@ TIntermConstantUnion *CreateBoolNode(bool value);
// If the input node is not a block node, put it inside a block node and return that.
TIntermBlock *EnsureBlock(TIntermNode *node);
// Should be called from inside Compiler::compileTreeImpl() where the global level is in scope.
TIntermSymbol *ReferenceGlobalVariable(const TString &name, const TSymbolTable &symbolTable);
// Note: this can access desktop GLSL built-ins that are hidden from the parser.
TIntermSymbol *ReferenceBuiltInVariable(const TString &name,
const TSymbolTable &symbolTable,
int shaderVersion);
......
......@@ -141,6 +141,8 @@ TSymbol *TSymbolTable::find(const TString &name,
do
{
if (level == GLSL_BUILTINS)
level--;
if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
level--;
if (level == ESSL3_BUILTINS && shaderVersion < 300)
......@@ -167,8 +169,17 @@ TSymbol *TSymbolTable::findGlobal(const TString &name) const
TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
{
return findBuiltIn(name, shaderVersion, false);
}
TSymbol *TSymbolTable::findBuiltIn(const TString &name,
int shaderVersion,
bool includeGLSLBuiltins) const
{
for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
{
if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
level--;
if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
level--;
if (level == ESSL3_BUILTINS && shaderVersion < 300)
......@@ -182,7 +193,7 @@ TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
return symbol;
}
return 0;
return nullptr;
}
TSymbolTable::~TSymbolTable()
......
......@@ -292,8 +292,11 @@ const int COMMON_BUILTINS = 0;
const int ESSL1_BUILTINS = 1;
const int ESSL3_BUILTINS = 2;
const int ESSL3_1_BUILTINS = 3;
const int LAST_BUILTIN_LEVEL = ESSL3_1_BUILTINS;
const int GLOBAL_LEVEL = 4;
// GLSL_BUILTINS are desktop GLSL builtins that don't exist in ESSL but are used to implement
// features in ANGLE's GLSL backend. They're not visible to the parser.
const int GLSL_BUILTINS = 4;
const int LAST_BUILTIN_LEVEL = GLSL_BUILTINS;
const int GLOBAL_LEVEL = 5;
class TSymbolTable : angle::NonCopyable
{
......@@ -454,6 +457,8 @@ class TSymbolTable : angle::NonCopyable
TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
TSymbol *findBuiltIn(const TString &name, int shaderVersion, bool includeGLSLBuiltins) const;
TSymbolTableLevel *getOuterLevel()
{
assert(currentLevel() >= 1);
......
......@@ -4401,3 +4401,20 @@ TEST_F(FragmentShaderValidationTest, RedefinedParamInFunctionHeader)
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test that using gl_ViewportIndex is not allowed in an ESSL 3.10 shader.
TEST_F(VertexShaderValidationTest, ViewportIndexInESSL310)
{
const std::string &shaderString =
"#version 310 es\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(gl_ViewportIndex);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
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