Commit bc58515e by Jiajia Qin Committed by Geoff Lang

ES31: Add 'buffer' qualifier support in shader

This change added 'buffer' qualifier support in shader which corresponds to ESSL 3.1 spec, session 4.3.7 'Buffer Variables'. BUG=angleproject:1951 TEST=angle_unittests:BufferVariablesTest Change-Id: I2ecb5317d5ea9d378a60b03f86bdae04dbd89e9f Reviewed-on: https://chromium-review.googlesource.com/534960Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent c5af8ba6
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 176 #define ANGLE_SH_VERSION 177
enum ShShaderSpec enum ShShaderSpec
{ {
...@@ -401,6 +401,9 @@ struct ShBuiltInResources ...@@ -401,6 +401,9 @@ struct ShBuiltInResources
// maximum number of uniform block bindings // maximum number of uniform block bindings
int MaxUniformBufferBindings; int MaxUniformBufferBindings;
// maximum number of shader storage buffer bindings
int MaxShaderStorageBufferBindings;
}; };
// //
......
...@@ -502,6 +502,7 @@ enum TQualifier ...@@ -502,6 +502,7 @@ enum TQualifier
EvqVaryingIn, // readonly, fragment shaders only EvqVaryingIn, // readonly, fragment shaders only
EvqVaryingOut, // vertex shaders only read/write EvqVaryingOut, // vertex shaders only read/write
EvqUniform, // Readonly, vertex and fragment EvqUniform, // Readonly, vertex and fragment
EvqBuffer, // read/write, vertex, fragment and compute shader
EvqVertexIn, // Vertex shader input EvqVertexIn, // Vertex shader input
EvqFragmentOut, // Fragment shader output EvqFragmentOut, // Fragment shader output
...@@ -753,6 +754,7 @@ inline const char *getQualifierString(TQualifier q) ...@@ -753,6 +754,7 @@ inline const char *getQualifierString(TQualifier q)
case EvqVaryingIn: return "varying"; case EvqVaryingIn: return "varying";
case EvqVaryingOut: return "varying"; case EvqVaryingOut: return "varying";
case EvqUniform: return "uniform"; case EvqUniform: return "uniform";
case EvqBuffer: return "buffer";
case EvqVertexIn: return "in"; case EvqVertexIn: return "in";
case EvqFragmentOut: return "out"; case EvqFragmentOut: return "out";
case EvqVertexOut: return "out"; case EvqVertexOut: return "out";
......
...@@ -155,7 +155,7 @@ class TParseContext : angle::NonCopyable ...@@ -155,7 +155,7 @@ class TParseContext : angle::NonCopyable
int versionRequired); int versionRequired);
bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
const TLayoutQualifier &layoutQualifier); const TLayoutQualifier &layoutQualifier);
void functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall); void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
void checkInvariantVariableQualifier(bool invariant, void checkInvariantVariableQualifier(bool invariant,
const TQualifier qualifier, const TQualifier qualifier,
const TSourceLoc &invariantLocation); const TSourceLoc &invariantLocation);
...@@ -464,7 +464,10 @@ class TParseContext : angle::NonCopyable ...@@ -464,7 +464,10 @@ class TParseContext : angle::NonCopyable
void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset); void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
void checkImageBindingIsValid(const TSourceLoc &location, int binding, int arraySize); void checkImageBindingIsValid(const TSourceLoc &location, int binding, int arraySize);
void checkSamplerBindingIsValid(const TSourceLoc &location, int binding, int arraySize); void checkSamplerBindingIsValid(const TSourceLoc &location, int binding, int arraySize);
void checkBlockBindingIsValid(const TSourceLoc &location, int binding, int arraySize); void checkBlockBindingIsValid(const TSourceLoc &location,
const TQualifier &qualifier,
int binding,
int arraySize);
void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding); void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
void checkUniformLocationInRange(const TSourceLoc &location, void checkUniformLocationInRange(const TSourceLoc &location,
...@@ -527,8 +530,10 @@ class TParseContext : angle::NonCopyable ...@@ -527,8 +530,10 @@ class TParseContext : angle::NonCopyable
// without precision, explicit or implicit. // without precision, explicit or implicit.
bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
// ESSL1. // ESSL1.
TLayoutMatrixPacking mDefaultMatrixPacking; TLayoutMatrixPacking mDefaultUniformMatrixPacking;
TLayoutBlockStorage mDefaultBlockStorage; TLayoutBlockStorage mDefaultUniformBlockStorage;
TLayoutMatrixPacking mDefaultBufferMatrixPacking;
TLayoutBlockStorage mDefaultBufferBlockStorage;
TString mHashErrMsg; TString mHashErrMsg;
TDiagnostics *mDiagnostics; TDiagnostics *mDiagnostics;
TDirectiveHandler mDirectiveHandler; TDirectiveHandler mDirectiveHandler;
...@@ -554,6 +559,7 @@ class TParseContext : angle::NonCopyable ...@@ -554,6 +559,7 @@ class TParseContext : angle::NonCopyable
int mMaxUniformLocations; int mMaxUniformLocations;
int mMaxUniformBufferBindings; int mMaxUniformBufferBindings;
int mMaxAtomicCounterBindings; int mMaxAtomicCounterBindings;
int mMaxShaderStorageBufferBindings;
// keeps track whether we are declaring / defining a function // keeps track whether we are declaring / defining a function
bool mDeclaringFunction; bool mDeclaringFunction;
......
...@@ -581,8 +581,14 @@ bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node ...@@ -581,8 +581,14 @@ bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node
const TIntermSymbol &variable = *variableNode->getAsSymbolNode(); const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
if (typedNode.getBasicType() == EbtInterfaceBlock) if (typedNode.getBasicType() == EbtInterfaceBlock)
{ {
// TODO(jiajia.qin@intel.com): In order not to affect the old set of mInterfaceBlocks,
// only uniform blocks are added into mInterfaceBlocks. Refactor it to gather
// uniformBlocks and shaderStorageBlocks separately.
if (qualifier == EvqUniform)
{
mInterfaceBlocks->push_back(recordInterfaceBlock(variable)); mInterfaceBlocks->push_back(recordInterfaceBlock(variable));
} }
}
else else
{ {
switch (qualifier) switch (qualifier)
...@@ -622,12 +628,15 @@ bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode) ...@@ -622,12 +628,15 @@ bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock(); const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks); InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
ASSERT(namedBlock); // TODO(jiajia.qin@intel.com): Currently, only uniform blocks are added into
// mInterfaceBlocks.
if (namedBlock)
{
namedBlock->staticUse = true; namedBlock->staticUse = true;
unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0)); unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
ASSERT(fieldIndex < namedBlock->fields.size()); ASSERT(fieldIndex < namedBlock->fields.size());
namedBlock->fields[fieldIndex].staticUse = true; namedBlock->fields[fieldIndex].staticUse = true;
}
return false; return false;
} }
......
...@@ -114,6 +114,7 @@ O [0-7] ...@@ -114,6 +114,7 @@ O [0-7]
"attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); } "attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); }
"const" { return CONST_QUAL; } "const" { return CONST_QUAL; }
"uniform" { return UNIFORM; } "uniform" { return UNIFORM; }
"buffer" { return ES2_and_ES3_ident_ES3_1_keyword(context, BUFFER); }
"varying" { return ES2_keyword_ES3_reserved(context, VARYING); } "varying" { return ES2_keyword_ES3_reserved(context, VARYING); }
"break" { return BREAK; } "break" { return BREAK; }
......
...@@ -162,7 +162,7 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons ...@@ -162,7 +162,7 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4
%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM BUFFER VARYING
%token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3 %token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3
%token <lex> CENTROID FLAT SMOOTH %token <lex> CENTROID FLAT SMOOTH
%token <lex> READONLY WRITEONLY COHERENT RESTRICT VOLATILE SHARED %token <lex> READONLY WRITEONLY COHERENT RESTRICT VOLATILE SHARED
...@@ -857,6 +857,10 @@ storage_qualifier ...@@ -857,6 +857,10 @@ storage_qualifier
| UNIFORM { | UNIFORM {
$$ = context->parseGlobalStorageQualifier(EvqUniform, @1); $$ = context->parseGlobalStorageQualifier(EvqUniform, @1);
} }
| BUFFER {
ES3_1_ONLY("buffer", @1, "storage qualifier");
$$ = context->parseGlobalStorageQualifier(EvqBuffer, @1);
}
| READONLY { | READONLY {
$$ = new TMemoryQualifierWrapper(EvqReadOnly, @1); $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1);
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -93,115 +93,116 @@ enum yytokentype ...@@ -93,115 +93,116 @@ enum yytokentype
OUT_QUAL = 296, OUT_QUAL = 296,
INOUT_QUAL = 297, INOUT_QUAL = 297,
UNIFORM = 298, UNIFORM = 298,
VARYING = 299, BUFFER = 299,
MATRIX2x3 = 300, VARYING = 300,
MATRIX3x2 = 301, MATRIX2x3 = 301,
MATRIX2x4 = 302, MATRIX3x2 = 302,
MATRIX4x2 = 303, MATRIX2x4 = 303,
MATRIX3x4 = 304, MATRIX4x2 = 304,
MATRIX4x3 = 305, MATRIX3x4 = 305,
CENTROID = 306, MATRIX4x3 = 306,
FLAT = 307, CENTROID = 307,
SMOOTH = 308, FLAT = 308,
READONLY = 309, SMOOTH = 309,
WRITEONLY = 310, READONLY = 310,
COHERENT = 311, WRITEONLY = 311,
RESTRICT = 312, COHERENT = 312,
VOLATILE = 313, RESTRICT = 313,
SHARED = 314, VOLATILE = 314,
STRUCT = 315, SHARED = 315,
VOID_TYPE = 316, STRUCT = 316,
WHILE = 317, VOID_TYPE = 317,
SAMPLER2D = 318, WHILE = 318,
SAMPLERCUBE = 319, SAMPLER2D = 319,
SAMPLER_EXTERNAL_OES = 320, SAMPLERCUBE = 320,
SAMPLER2DRECT = 321, SAMPLER_EXTERNAL_OES = 321,
SAMPLER2DARRAY = 322, SAMPLER2DRECT = 322,
ISAMPLER2D = 323, SAMPLER2DARRAY = 323,
ISAMPLER3D = 324, ISAMPLER2D = 324,
ISAMPLERCUBE = 325, ISAMPLER3D = 325,
ISAMPLER2DARRAY = 326, ISAMPLERCUBE = 326,
USAMPLER2D = 327, ISAMPLER2DARRAY = 327,
USAMPLER3D = 328, USAMPLER2D = 328,
USAMPLERCUBE = 329, USAMPLER3D = 329,
USAMPLER2DARRAY = 330, USAMPLERCUBE = 330,
SAMPLER2DMS = 331, USAMPLER2DARRAY = 331,
ISAMPLER2DMS = 332, SAMPLER2DMS = 332,
USAMPLER2DMS = 333, ISAMPLER2DMS = 333,
SAMPLER3D = 334, USAMPLER2DMS = 334,
SAMPLER3DRECT = 335, SAMPLER3D = 335,
SAMPLER2DSHADOW = 336, SAMPLER3DRECT = 336,
SAMPLERCUBESHADOW = 337, SAMPLER2DSHADOW = 337,
SAMPLER2DARRAYSHADOW = 338, SAMPLERCUBESHADOW = 338,
SAMPLEREXTERNAL2DY2YEXT = 339, SAMPLER2DARRAYSHADOW = 339,
IMAGE2D = 340, SAMPLEREXTERNAL2DY2YEXT = 340,
IIMAGE2D = 341, IMAGE2D = 341,
UIMAGE2D = 342, IIMAGE2D = 342,
IMAGE3D = 343, UIMAGE2D = 343,
IIMAGE3D = 344, IMAGE3D = 344,
UIMAGE3D = 345, IIMAGE3D = 345,
IMAGE2DARRAY = 346, UIMAGE3D = 346,
IIMAGE2DARRAY = 347, IMAGE2DARRAY = 347,
UIMAGE2DARRAY = 348, IIMAGE2DARRAY = 348,
IMAGECUBE = 349, UIMAGE2DARRAY = 349,
IIMAGECUBE = 350, IMAGECUBE = 350,
UIMAGECUBE = 351, IIMAGECUBE = 351,
ATOMICUINT = 352, UIMAGECUBE = 352,
LAYOUT = 353, ATOMICUINT = 353,
YUVCSCSTANDARDEXT = 354, LAYOUT = 354,
YUVCSCSTANDARDEXTCONSTANT = 355, YUVCSCSTANDARDEXT = 355,
IDENTIFIER = 356, YUVCSCSTANDARDEXTCONSTANT = 356,
TYPE_NAME = 357, IDENTIFIER = 357,
FLOATCONSTANT = 358, TYPE_NAME = 358,
INTCONSTANT = 359, FLOATCONSTANT = 359,
UINTCONSTANT = 360, INTCONSTANT = 360,
BOOLCONSTANT = 361, UINTCONSTANT = 361,
FIELD_SELECTION = 362, BOOLCONSTANT = 362,
LEFT_OP = 363, FIELD_SELECTION = 363,
RIGHT_OP = 364, LEFT_OP = 364,
INC_OP = 365, RIGHT_OP = 365,
DEC_OP = 366, INC_OP = 366,
LE_OP = 367, DEC_OP = 367,
GE_OP = 368, LE_OP = 368,
EQ_OP = 369, GE_OP = 369,
NE_OP = 370, EQ_OP = 370,
AND_OP = 371, NE_OP = 371,
OR_OP = 372, AND_OP = 372,
XOR_OP = 373, OR_OP = 373,
MUL_ASSIGN = 374, XOR_OP = 374,
DIV_ASSIGN = 375, MUL_ASSIGN = 375,
ADD_ASSIGN = 376, DIV_ASSIGN = 376,
MOD_ASSIGN = 377, ADD_ASSIGN = 377,
LEFT_ASSIGN = 378, MOD_ASSIGN = 378,
RIGHT_ASSIGN = 379, LEFT_ASSIGN = 379,
AND_ASSIGN = 380, RIGHT_ASSIGN = 380,
XOR_ASSIGN = 381, AND_ASSIGN = 381,
OR_ASSIGN = 382, XOR_ASSIGN = 382,
SUB_ASSIGN = 383, OR_ASSIGN = 383,
LEFT_PAREN = 384, SUB_ASSIGN = 384,
RIGHT_PAREN = 385, LEFT_PAREN = 385,
LEFT_BRACKET = 386, RIGHT_PAREN = 386,
RIGHT_BRACKET = 387, LEFT_BRACKET = 387,
LEFT_BRACE = 388, RIGHT_BRACKET = 388,
RIGHT_BRACE = 389, LEFT_BRACE = 389,
DOT = 390, RIGHT_BRACE = 390,
COMMA = 391, DOT = 391,
COLON = 392, COMMA = 392,
EQUAL = 393, COLON = 393,
SEMICOLON = 394, EQUAL = 394,
BANG = 395, SEMICOLON = 395,
DASH = 396, BANG = 396,
TILDE = 397, DASH = 397,
PLUS = 398, TILDE = 398,
STAR = 399, PLUS = 399,
SLASH = 400, STAR = 400,
PERCENT = 401, SLASH = 401,
LEFT_ANGLE = 402, PERCENT = 402,
RIGHT_ANGLE = 403, LEFT_ANGLE = 403,
VERTICAL_BAR = 404, RIGHT_ANGLE = 404,
CARET = 405, VERTICAL_BAR = 405,
AMPERSAND = 406, CARET = 406,
QUESTION = 407 AMPERSAND = 407,
QUESTION = 408
}; };
#endif #endif
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
'<(angle_path)/src/tests/compiler_tests/API_test.cpp', '<(angle_path)/src/tests/compiler_tests/API_test.cpp',
'<(angle_path)/src/tests/compiler_tests/AppendixALimitations_test.cpp', '<(angle_path)/src/tests/compiler_tests/AppendixALimitations_test.cpp',
'<(angle_path)/src/tests/compiler_tests/AtomicCounter_test.cpp', '<(angle_path)/src/tests/compiler_tests/AtomicCounter_test.cpp',
'<(angle_path)/src/tests/compiler_tests/BufferVariables_test.cpp',
'<(angle_path)/src/tests/compiler_tests/CollectVariables_test.cpp', '<(angle_path)/src/tests/compiler_tests/CollectVariables_test.cpp',
'<(angle_path)/src/tests/compiler_tests/ConstantFolding_test.cpp', '<(angle_path)/src/tests/compiler_tests/ConstantFolding_test.cpp',
'<(angle_path)/src/tests/compiler_tests/ConstantFoldingNaN_test.cpp', '<(angle_path)/src/tests/compiler_tests/ConstantFoldingNaN_test.cpp',
......
...@@ -3885,6 +3885,23 @@ TEST_F(FragmentShaderValidationTest, InvalidInterfaceBlockTernaryExpression) ...@@ -3885,6 +3885,23 @@ TEST_F(FragmentShaderValidationTest, InvalidInterfaceBlockTernaryExpression)
} }
} }
// Test that "buffer" and "shared" are valid identifiers in version lower than GLSL ES 3.10.
TEST_F(FragmentShaderValidationTest, BufferAndSharedAsIdentifierOnES3)
{
const std::string &shaderString =
"#version 300 es\n"
"void main()\n"
"{\n"
" int buffer;\n"
" int shared;\n"
"}\n";
if (!compile(shaderString))
{
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
}
}
// Test that a struct can not be used as a constructor argument for a scalar. // Test that a struct can not be used as a constructor argument for a scalar.
TEST_F(FragmentShaderValidationTest, StructAsBoolConstructorArgument) TEST_F(FragmentShaderValidationTest, StructAsBoolConstructorArgument)
{ {
......
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