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 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 176
#define ANGLE_SH_VERSION 177
enum ShShaderSpec
{
......@@ -401,6 +401,9 @@ struct ShBuiltInResources
// maximum number of uniform block bindings
int MaxUniformBufferBindings;
// maximum number of shader storage buffer bindings
int MaxShaderStorageBufferBindings;
};
//
......
......@@ -502,6 +502,7 @@ enum TQualifier
EvqVaryingIn, // readonly, fragment shaders only
EvqVaryingOut, // vertex shaders only read/write
EvqUniform, // Readonly, vertex and fragment
EvqBuffer, // read/write, vertex, fragment and compute shader
EvqVertexIn, // Vertex shader input
EvqFragmentOut, // Fragment shader output
......@@ -753,6 +754,7 @@ inline const char *getQualifierString(TQualifier q)
case EvqVaryingIn: return "varying";
case EvqVaryingOut: return "varying";
case EvqUniform: return "uniform";
case EvqBuffer: return "buffer";
case EvqVertexIn: return "in";
case EvqFragmentOut: return "out";
case EvqVertexOut: return "out";
......
......@@ -155,7 +155,7 @@ class TParseContext : angle::NonCopyable
int versionRequired);
bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
const TLayoutQualifier &layoutQualifier);
void functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
void checkInvariantVariableQualifier(bool invariant,
const TQualifier qualifier,
const TSourceLoc &invariantLocation);
......@@ -464,7 +464,10 @@ class TParseContext : angle::NonCopyable
void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
void checkImageBindingIsValid(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 checkUniformLocationInRange(const TSourceLoc &location,
......@@ -527,8 +530,10 @@ class TParseContext : angle::NonCopyable
// without precision, explicit or implicit.
bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
// ESSL1.
TLayoutMatrixPacking mDefaultMatrixPacking;
TLayoutBlockStorage mDefaultBlockStorage;
TLayoutMatrixPacking mDefaultUniformMatrixPacking;
TLayoutBlockStorage mDefaultUniformBlockStorage;
TLayoutMatrixPacking mDefaultBufferMatrixPacking;
TLayoutBlockStorage mDefaultBufferBlockStorage;
TString mHashErrMsg;
TDiagnostics *mDiagnostics;
TDirectiveHandler mDirectiveHandler;
......@@ -554,6 +559,7 @@ class TParseContext : angle::NonCopyable
int mMaxUniformLocations;
int mMaxUniformBufferBindings;
int mMaxAtomicCounterBindings;
int mMaxShaderStorageBufferBindings;
// keeps track whether we are declaring / defining a function
bool mDeclaringFunction;
......
......@@ -581,7 +581,13 @@ bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node
const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
if (typedNode.getBasicType() == EbtInterfaceBlock)
{
mInterfaceBlocks->push_back(recordInterfaceBlock(variable));
// 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));
}
}
else
{
......@@ -622,12 +628,15 @@ bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
ASSERT(namedBlock);
namedBlock->staticUse = true;
unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
ASSERT(fieldIndex < namedBlock->fields.size());
namedBlock->fields[fieldIndex].staticUse = true;
// TODO(jiajia.qin@intel.com): Currently, only uniform blocks are added into
// mInterfaceBlocks.
if (namedBlock)
{
namedBlock->staticUse = true;
unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
ASSERT(fieldIndex < namedBlock->fields.size());
namedBlock->fields[fieldIndex].staticUse = true;
}
return false;
}
......
......@@ -114,6 +114,7 @@ O [0-7]
"attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); }
"const" { return CONST_QUAL; }
"uniform" { return UNIFORM; }
"buffer" { return ES2_and_ES3_ident_ES3_1_keyword(context, BUFFER); }
"varying" { return ES2_keyword_ES3_reserved(context, VARYING); }
"break" { return BREAK; }
......
......@@ -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> 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> 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> CENTROID FLAT SMOOTH
%token <lex> READONLY WRITEONLY COHERENT RESTRICT VOLATILE SHARED
......@@ -857,6 +857,10 @@ storage_qualifier
| UNIFORM {
$$ = context->parseGlobalStorageQualifier(EvqUniform, @1);
}
| BUFFER {
ES3_1_ONLY("buffer", @1, "storage qualifier");
$$ = context->parseGlobalStorageQualifier(EvqBuffer, @1);
}
| READONLY {
$$ = 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
OUT_QUAL = 296,
INOUT_QUAL = 297,
UNIFORM = 298,
VARYING = 299,
MATRIX2x3 = 300,
MATRIX3x2 = 301,
MATRIX2x4 = 302,
MATRIX4x2 = 303,
MATRIX3x4 = 304,
MATRIX4x3 = 305,
CENTROID = 306,
FLAT = 307,
SMOOTH = 308,
READONLY = 309,
WRITEONLY = 310,
COHERENT = 311,
RESTRICT = 312,
VOLATILE = 313,
SHARED = 314,
STRUCT = 315,
VOID_TYPE = 316,
WHILE = 317,
SAMPLER2D = 318,
SAMPLERCUBE = 319,
SAMPLER_EXTERNAL_OES = 320,
SAMPLER2DRECT = 321,
SAMPLER2DARRAY = 322,
ISAMPLER2D = 323,
ISAMPLER3D = 324,
ISAMPLERCUBE = 325,
ISAMPLER2DARRAY = 326,
USAMPLER2D = 327,
USAMPLER3D = 328,
USAMPLERCUBE = 329,
USAMPLER2DARRAY = 330,
SAMPLER2DMS = 331,
ISAMPLER2DMS = 332,
USAMPLER2DMS = 333,
SAMPLER3D = 334,
SAMPLER3DRECT = 335,
SAMPLER2DSHADOW = 336,
SAMPLERCUBESHADOW = 337,
SAMPLER2DARRAYSHADOW = 338,
SAMPLEREXTERNAL2DY2YEXT = 339,
IMAGE2D = 340,
IIMAGE2D = 341,
UIMAGE2D = 342,
IMAGE3D = 343,
IIMAGE3D = 344,
UIMAGE3D = 345,
IMAGE2DARRAY = 346,
IIMAGE2DARRAY = 347,
UIMAGE2DARRAY = 348,
IMAGECUBE = 349,
IIMAGECUBE = 350,
UIMAGECUBE = 351,
ATOMICUINT = 352,
LAYOUT = 353,
YUVCSCSTANDARDEXT = 354,
YUVCSCSTANDARDEXTCONSTANT = 355,
IDENTIFIER = 356,
TYPE_NAME = 357,
FLOATCONSTANT = 358,
INTCONSTANT = 359,
UINTCONSTANT = 360,
BOOLCONSTANT = 361,
FIELD_SELECTION = 362,
LEFT_OP = 363,
RIGHT_OP = 364,
INC_OP = 365,
DEC_OP = 366,
LE_OP = 367,
GE_OP = 368,
EQ_OP = 369,
NE_OP = 370,
AND_OP = 371,
OR_OP = 372,
XOR_OP = 373,
MUL_ASSIGN = 374,
DIV_ASSIGN = 375,
ADD_ASSIGN = 376,
MOD_ASSIGN = 377,
LEFT_ASSIGN = 378,
RIGHT_ASSIGN = 379,
AND_ASSIGN = 380,
XOR_ASSIGN = 381,
OR_ASSIGN = 382,
SUB_ASSIGN = 383,
LEFT_PAREN = 384,
RIGHT_PAREN = 385,
LEFT_BRACKET = 386,
RIGHT_BRACKET = 387,
LEFT_BRACE = 388,
RIGHT_BRACE = 389,
DOT = 390,
COMMA = 391,
COLON = 392,
EQUAL = 393,
SEMICOLON = 394,
BANG = 395,
DASH = 396,
TILDE = 397,
PLUS = 398,
STAR = 399,
SLASH = 400,
PERCENT = 401,
LEFT_ANGLE = 402,
RIGHT_ANGLE = 403,
VERTICAL_BAR = 404,
CARET = 405,
AMPERSAND = 406,
QUESTION = 407
BUFFER = 299,
VARYING = 300,
MATRIX2x3 = 301,
MATRIX3x2 = 302,
MATRIX2x4 = 303,
MATRIX4x2 = 304,
MATRIX3x4 = 305,
MATRIX4x3 = 306,
CENTROID = 307,
FLAT = 308,
SMOOTH = 309,
READONLY = 310,
WRITEONLY = 311,
COHERENT = 312,
RESTRICT = 313,
VOLATILE = 314,
SHARED = 315,
STRUCT = 316,
VOID_TYPE = 317,
WHILE = 318,
SAMPLER2D = 319,
SAMPLERCUBE = 320,
SAMPLER_EXTERNAL_OES = 321,
SAMPLER2DRECT = 322,
SAMPLER2DARRAY = 323,
ISAMPLER2D = 324,
ISAMPLER3D = 325,
ISAMPLERCUBE = 326,
ISAMPLER2DARRAY = 327,
USAMPLER2D = 328,
USAMPLER3D = 329,
USAMPLERCUBE = 330,
USAMPLER2DARRAY = 331,
SAMPLER2DMS = 332,
ISAMPLER2DMS = 333,
USAMPLER2DMS = 334,
SAMPLER3D = 335,
SAMPLER3DRECT = 336,
SAMPLER2DSHADOW = 337,
SAMPLERCUBESHADOW = 338,
SAMPLER2DARRAYSHADOW = 339,
SAMPLEREXTERNAL2DY2YEXT = 340,
IMAGE2D = 341,
IIMAGE2D = 342,
UIMAGE2D = 343,
IMAGE3D = 344,
IIMAGE3D = 345,
UIMAGE3D = 346,
IMAGE2DARRAY = 347,
IIMAGE2DARRAY = 348,
UIMAGE2DARRAY = 349,
IMAGECUBE = 350,
IIMAGECUBE = 351,
UIMAGECUBE = 352,
ATOMICUINT = 353,
LAYOUT = 354,
YUVCSCSTANDARDEXT = 355,
YUVCSCSTANDARDEXTCONSTANT = 356,
IDENTIFIER = 357,
TYPE_NAME = 358,
FLOATCONSTANT = 359,
INTCONSTANT = 360,
UINTCONSTANT = 361,
BOOLCONSTANT = 362,
FIELD_SELECTION = 363,
LEFT_OP = 364,
RIGHT_OP = 365,
INC_OP = 366,
DEC_OP = 367,
LE_OP = 368,
GE_OP = 369,
EQ_OP = 370,
NE_OP = 371,
AND_OP = 372,
OR_OP = 373,
XOR_OP = 374,
MUL_ASSIGN = 375,
DIV_ASSIGN = 376,
ADD_ASSIGN = 377,
MOD_ASSIGN = 378,
LEFT_ASSIGN = 379,
RIGHT_ASSIGN = 380,
AND_ASSIGN = 381,
XOR_ASSIGN = 382,
OR_ASSIGN = 383,
SUB_ASSIGN = 384,
LEFT_PAREN = 385,
RIGHT_PAREN = 386,
LEFT_BRACKET = 387,
RIGHT_BRACKET = 388,
LEFT_BRACE = 389,
RIGHT_BRACE = 390,
DOT = 391,
COMMA = 392,
COLON = 393,
EQUAL = 394,
SEMICOLON = 395,
BANG = 396,
DASH = 397,
TILDE = 398,
PLUS = 399,
STAR = 400,
SLASH = 401,
PERCENT = 402,
LEFT_ANGLE = 403,
RIGHT_ANGLE = 404,
VERTICAL_BAR = 405,
CARET = 406,
AMPERSAND = 407,
QUESTION = 408
};
#endif
......
......@@ -50,6 +50,7 @@
'<(angle_path)/src/tests/compiler_tests/API_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/BufferVariables_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/ConstantFoldingNaN_test.cpp',
......
......@@ -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_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