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) ...@@ -628,11 +628,12 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
compileResources = resources; compileResources = resources;
setResourceString(); setResourceString();
assert(symbolTable.isEmpty()); ASSERT(symbolTable.isEmpty());
symbolTable.push(); // COMMON_BUILTINS symbolTable.push(); // COMMON_BUILTINS
symbolTable.push(); // ESSL1_BUILTINS symbolTable.push(); // ESSL1_BUILTINS
symbolTable.push(); // ESSL3_BUILTINS symbolTable.push(); // ESSL3_BUILTINS
symbolTable.push(); // ESSL3_1_BUILTINS symbolTable.push(); // ESSL3_1_BUILTINS
symbolTable.push(); // GLSL_BUILTINS
switch (shaderType) switch (shaderType)
{ {
......
...@@ -113,7 +113,8 @@ void DeclareGlobalVariable(TIntermBlock *root, TIntermTyped *typedNode) ...@@ -113,7 +113,8 @@ void DeclareGlobalVariable(TIntermBlock *root, TIntermTyped *typedNode)
// added to the end of the initializers' sequence. // added to the end of the initializers' sequence.
void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol, void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
TIntermTyped *multiviewBaseViewLayerIndexSymbol, TIntermTyped *multiviewBaseViewLayerIndexSymbol,
TIntermSequence *initializers) TIntermSequence *initializers,
const TSymbolTable &symbolTable)
{ {
// Create an int(ViewID_OVR) node. // Create an int(ViewID_OVR) node.
TIntermSequence *viewIDSymbolCastArguments = new TIntermSequence(); TIntermSequence *viewIDSymbolCastArguments = new TIntermSequence();
...@@ -123,7 +124,7 @@ void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol, ...@@ -123,7 +124,7 @@ void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
// Create a gl_ViewportIndex node. // Create a gl_ViewportIndex node.
TIntermSymbol *viewportIndexSymbol = TIntermSymbol *viewportIndexSymbol =
new TIntermSymbol(0, "gl_ViewportIndex", TType(EbtInt, EbpHigh, EvqViewportIndex)); ReferenceBuiltInVariable("gl_ViewportIndex", symbolTable, 0);
// Create a { gl_ViewportIndex = int(ViewID_OVR) } node. // Create a { gl_ViewportIndex = int(ViewID_OVR) } node.
TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock(); TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock();
...@@ -206,7 +207,7 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root, ...@@ -206,7 +207,7 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// initialization. // initialization.
SelectViewIndexInVertexShader(viewIDSymbol->deepCopy(), SelectViewIndexInVertexShader(viewIDSymbol->deepCopy(),
multiviewBaseViewLayerIndexSymbol->deepCopy(), multiviewBaseViewLayerIndexSymbol->deepCopy(),
initializers); initializers, *symbolTable);
} }
// Insert initializers at the beginning of main(). // Insert initializers at the beginning of main().
......
...@@ -871,11 +871,11 @@ void IdentifyBuiltIns(sh::GLenum type, ...@@ -871,11 +871,11 @@ void IdentifyBuiltIns(sh::GLenum type,
"gl_LastFragColorARM", "gl_LastFragColorARM",
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)); TType(EbtFloat, EbpMedium, EvqLastFragColor, 4));
} }
}
break;
break;
}
case GL_VERTEX_SHADER: case GL_VERTEX_SHADER:
{
symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position", symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position",
TType(EbtFloat, EbpHigh, EvqPosition, 4)); TType(EbtFloat, EbpHigh, EvqPosition, 4));
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize", symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize",
...@@ -884,7 +884,12 @@ void IdentifyBuiltIns(sh::GLenum type, ...@@ -884,7 +884,12 @@ void IdentifyBuiltIns(sh::GLenum type,
TType(EbtInt, EbpHigh, EvqInstanceID, 1)); TType(EbtInt, EbpHigh, EvqInstanceID, 1));
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID", symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID",
TType(EbtInt, EbpHigh, EvqVertexID, 1)); 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; break;
}
case GL_COMPUTE_SHADER: case GL_COMPUTE_SHADER:
{ {
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups", symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups",
...@@ -899,15 +904,15 @@ void IdentifyBuiltIns(sh::GLenum type, ...@@ -899,15 +904,15 @@ void IdentifyBuiltIns(sh::GLenum type,
TType(EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3)); TType(EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3));
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationIndex", symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationIndex",
TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1)); TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1));
break;
} }
break;
case GL_GEOMETRY_SHADER_OES: case GL_GEOMETRY_SHADER_OES:
// TODO(jiawei.shao@intel.com): add Geometry Shader built-in variables. // TODO(jiawei.shao@intel.com): add Geometry Shader built-in variables.
break; break;
default: default:
assert(false && "Language not supported"); UNREACHABLE();
} }
} }
......
...@@ -193,7 +193,7 @@ TIntermSymbol *ReferenceBuiltInVariable(const TString &name, ...@@ -193,7 +193,7 @@ TIntermSymbol *ReferenceBuiltInVariable(const TString &name,
int shaderVersion) int shaderVersion)
{ {
const TVariable *var = const TVariable *var =
reinterpret_cast<const TVariable *>(symbolTable.findBuiltIn(name, shaderVersion)); reinterpret_cast<const TVariable *>(symbolTable.findBuiltIn(name, shaderVersion, true));
ASSERT(var); ASSERT(var);
return new TIntermSymbol(var->getUniqueId(), name, var->getType()); return new TIntermSymbol(var->getUniqueId(), name, var->getType());
} }
......
...@@ -35,7 +35,10 @@ TIntermConstantUnion *CreateBoolNode(bool value); ...@@ -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. // If the input node is not a block node, put it inside a block node and return that.
TIntermBlock *EnsureBlock(TIntermNode *node); 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); 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, TIntermSymbol *ReferenceBuiltInVariable(const TString &name,
const TSymbolTable &symbolTable, const TSymbolTable &symbolTable,
int shaderVersion); int shaderVersion);
......
...@@ -141,6 +141,8 @@ TSymbol *TSymbolTable::find(const TString &name, ...@@ -141,6 +141,8 @@ TSymbol *TSymbolTable::find(const TString &name,
do do
{ {
if (level == GLSL_BUILTINS)
level--;
if (level == ESSL3_1_BUILTINS && shaderVersion != 310) if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
level--; level--;
if (level == ESSL3_BUILTINS && shaderVersion < 300) if (level == ESSL3_BUILTINS && shaderVersion < 300)
...@@ -167,8 +169,17 @@ TSymbol *TSymbolTable::findGlobal(const TString &name) const ...@@ -167,8 +169,17 @@ TSymbol *TSymbolTable::findGlobal(const TString &name) const
TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) 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--) for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
{ {
if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
level--;
if (level == ESSL3_1_BUILTINS && shaderVersion != 310) if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
level--; level--;
if (level == ESSL3_BUILTINS && shaderVersion < 300) if (level == ESSL3_BUILTINS && shaderVersion < 300)
...@@ -182,7 +193,7 @@ TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const ...@@ -182,7 +193,7 @@ TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
return symbol; return symbol;
} }
return 0; return nullptr;
} }
TSymbolTable::~TSymbolTable() TSymbolTable::~TSymbolTable()
......
...@@ -292,8 +292,11 @@ const int COMMON_BUILTINS = 0; ...@@ -292,8 +292,11 @@ const int COMMON_BUILTINS = 0;
const int ESSL1_BUILTINS = 1; const int ESSL1_BUILTINS = 1;
const int ESSL3_BUILTINS = 2; const int ESSL3_BUILTINS = 2;
const int ESSL3_1_BUILTINS = 3; const int ESSL3_1_BUILTINS = 3;
const int LAST_BUILTIN_LEVEL = ESSL3_1_BUILTINS; // GLSL_BUILTINS are desktop GLSL builtins that don't exist in ESSL but are used to implement
const int GLOBAL_LEVEL = 4; // 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 class TSymbolTable : angle::NonCopyable
{ {
...@@ -454,6 +457,8 @@ 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) const;
TSymbol *findBuiltIn(const TString &name, int shaderVersion, bool includeGLSLBuiltins) const;
TSymbolTableLevel *getOuterLevel() TSymbolTableLevel *getOuterLevel()
{ {
assert(currentLevel() >= 1); assert(currentLevel() >= 1);
......
...@@ -4401,3 +4401,20 @@ TEST_F(FragmentShaderValidationTest, RedefinedParamInFunctionHeader) ...@@ -4401,3 +4401,20 @@ TEST_F(FragmentShaderValidationTest, RedefinedParamInFunctionHeader)
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog; 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