From 19b92fff7ec0f5973d45434764f79e8f13c186f9 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sun, 19 Jun 2016 11:50:34 -0600 Subject: [PATCH] HLSL: Basic array grammar. --- Test/baseResults/hlsl.array.frag.out | 181 +++++++++++++++++++++++++++ Test/hlsl.array.frag | 11 ++ gtests/Hlsl.FromFile.cpp | 1 + hlsl/hlslGrammar.cpp | 67 ++++++++-- hlsl/hlslGrammar.h | 1 + hlsl/hlslOpMap.cpp | 2 +- 6 files changed, 254 insertions(+), 9 deletions(-) create mode 100755 Test/baseResults/hlsl.array.frag.out create mode 100644 Test/hlsl.array.frag diff --git a/Test/baseResults/hlsl.array.frag.out b/Test/baseResults/hlsl.array.frag.out new file mode 100755 index 00000000..113f1521 --- /dev/null +++ b/Test/baseResults/hlsl.array.frag.out @@ -0,0 +1,181 @@ +hlsl.array.frag +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:11 Function Definition: PixelShaderFunction(i1;vf4[3]; (temp 4-component vector of float) +0:8 Function Parameters: +0:8 'i' (in int) +0:8 'input' (in 3-element array of 4-component vector of float) +0:? Sequence +0:10 Branch: Return with expression +0:10 add (temp 4-component vector of float) +0:10 add (temp 4-component vector of float) +0:10 add (temp 4-component vector of float) +0:10 direct index (temp 4-component vector of float) +0:10 'a' (temp 4-element array of 4-component vector of float) +0:10 Constant: +0:10 1 (const int) +0:10 indirect index (temp 4-component vector of float) +0:10 'a' (temp 4-element array of 4-component vector of float) +0:10 'i' (in int) +0:10 add (temp 4-component vector of float) +0:10 direct index (temp 4-component vector of float) +0:10 'input' (in 3-element array of 4-component vector of float) +0:10 Constant: +0:10 2 (const int) +0:10 indirect index (temp 4-component vector of float) +0:10 'input' (in 3-element array of 4-component vector of float) +0:10 'i' (in int) +0:10 add (temp 4-component vector of float) +0:10 add (temp 4-component vector of float) +0:10 direct index (temp 4-component vector of float) +0:10 'b' (temp 10-element array of 4-component vector of float) +0:10 Constant: +0:10 5 (const int) +0:10 indirect index (temp 4-component vector of float) +0:10 'b' (temp 10-element array of 4-component vector of float) +0:10 'i' (in int) +0:10 indirect index (temp 4-component vector of float) +0:10 m: direct index for structure (temp 7-element array of 4-component vector of float) +0:10 indirect index (temp structure{temp 7-element array of 4-component vector of float m}) +0:10 's' (temp 11-element array of structure{temp 7-element array of 4-component vector of float m}) +0:10 'i' (in int) +0:10 Constant: +0:10 0 (const int) +0:10 'i' (in int) +0:? Linker Objects +0:? 'a' (temp 4-element array of 4-component vector of float) +0:? 's' (temp 11-element array of structure{temp 7-element array of 4-component vector of float m}) + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:11 Function Definition: PixelShaderFunction(i1;vf4[3]; (temp 4-component vector of float) +0:8 Function Parameters: +0:8 'i' (in int) +0:8 'input' (in 3-element array of 4-component vector of float) +0:? Sequence +0:10 Branch: Return with expression +0:10 add (temp 4-component vector of float) +0:10 add (temp 4-component vector of float) +0:10 add (temp 4-component vector of float) +0:10 direct index (temp 4-component vector of float) +0:10 'a' (temp 4-element array of 4-component vector of float) +0:10 Constant: +0:10 1 (const int) +0:10 indirect index (temp 4-component vector of float) +0:10 'a' (temp 4-element array of 4-component vector of float) +0:10 'i' (in int) +0:10 add (temp 4-component vector of float) +0:10 direct index (temp 4-component vector of float) +0:10 'input' (in 3-element array of 4-component vector of float) +0:10 Constant: +0:10 2 (const int) +0:10 indirect index (temp 4-component vector of float) +0:10 'input' (in 3-element array of 4-component vector of float) +0:10 'i' (in int) +0:10 add (temp 4-component vector of float) +0:10 add (temp 4-component vector of float) +0:10 direct index (temp 4-component vector of float) +0:10 'b' (temp 10-element array of 4-component vector of float) +0:10 Constant: +0:10 5 (const int) +0:10 indirect index (temp 4-component vector of float) +0:10 'b' (temp 10-element array of 4-component vector of float) +0:10 'i' (in int) +0:10 indirect index (temp 4-component vector of float) +0:10 m: direct index for structure (temp 7-element array of 4-component vector of float) +0:10 indirect index (temp structure{temp 7-element array of 4-component vector of float m}) +0:10 's' (temp 11-element array of structure{temp 7-element array of 4-component vector of float m}) +0:10 'i' (in int) +0:10 Constant: +0:10 0 (const int) +0:10 'i' (in int) +0:? Linker Objects +0:? 'a' (temp 4-element array of 4-component vector of float) +0:? 's' (temp 11-element array of structure{temp 7-element array of 4-component vector of float m}) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 63 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "PixelShaderFunction" 19 27 + ExecutionMode 4 OriginUpperLeft + Source HLSL 450 + Name 4 "PixelShaderFunction" + Name 12 "a" + Name 19 "i" + Name 27 "input" + Name 40 "b" + Name 50 "" + MemberName 50 0 "m" + Name 54 "s" + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeInt 32 0 + 9: 8(int) Constant 4 + 10: TypeArray 7(fvec4) 9 + 11: TypePointer Function 10 + 13: TypeInt 32 1 + 14: 13(int) Constant 1 + 15: TypePointer Function 7(fvec4) + 18: TypePointer Input 13(int) + 19(i): 18(ptr) Variable Input + 24: 8(int) Constant 3 + 25: TypeArray 7(fvec4) 24 + 26: TypePointer Input 25 + 27(input): 26(ptr) Variable Input + 28: 13(int) Constant 2 + 29: TypePointer Input 7(fvec4) + 37: 8(int) Constant 10 + 38: TypeArray 7(fvec4) 37 + 39: TypePointer Function 38 + 41: 13(int) Constant 5 + 48: 8(int) Constant 7 + 49: TypeArray 7(fvec4) 48 + 50: TypeStruct 49 + 51: 8(int) Constant 11 + 52: TypeArray 50(struct) 51 + 53: TypePointer Function 52 + 56: 13(int) Constant 0 +4(PixelShaderFunction): 2 Function None 3 + 5: Label + 12(a): 11(ptr) Variable Function + 40(b): 39(ptr) Variable Function + 54(s): 53(ptr) Variable Function + 16: 15(ptr) AccessChain 12(a) 14 + 17: 7(fvec4) Load 16 + 20: 13(int) Load 19(i) + 21: 15(ptr) AccessChain 12(a) 20 + 22: 7(fvec4) Load 21 + 23: 7(fvec4) FAdd 17 22 + 30: 29(ptr) AccessChain 27(input) 28 + 31: 7(fvec4) Load 30 + 32: 13(int) Load 19(i) + 33: 29(ptr) AccessChain 27(input) 32 + 34: 7(fvec4) Load 33 + 35: 7(fvec4) FAdd 31 34 + 36: 7(fvec4) FAdd 23 35 + 42: 15(ptr) AccessChain 40(b) 41 + 43: 7(fvec4) Load 42 + 44: 13(int) Load 19(i) + 45: 15(ptr) AccessChain 40(b) 44 + 46: 7(fvec4) Load 45 + 47: 7(fvec4) FAdd 43 46 + 55: 13(int) Load 19(i) + 57: 13(int) Load 19(i) + 58: 15(ptr) AccessChain 54(s) 55 56 57 + 59: 7(fvec4) Load 58 + 60: 7(fvec4) FAdd 47 59 + 61: 7(fvec4) FAdd 36 60 + ReturnValue 61 + FunctionEnd diff --git a/Test/hlsl.array.frag b/Test/hlsl.array.frag new file mode 100644 index 00000000..1abba89f --- /dev/null +++ b/Test/hlsl.array.frag @@ -0,0 +1,11 @@ +float4 a[4]; + +struct { + float4 m[7]; +} s[11]; + +float4 PixelShaderFunction(int i, float4 input[3]) : COLOR0 +{ + float4 b[10]; + return a[1] + a[i] + input[2] + input[i] + b[5] + b[i] + s[i].m[i]; +} \ No newline at end of file diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 46389624..22f48d76 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -72,6 +72,7 @@ TEST_P(HlslCompileTest, FromFile) INSTANTIATE_TEST_CASE_P( ToSpirv, HlslCompileTest, ::testing::ValuesIn(std::vector{ + {"hlsl.array.frag", "PixelShaderFunction"}, {"hlsl.assoc.frag", "PixelShaderFunction"}, {"hlsl.attribute.frag", "PixelShaderFunction"}, {"hlsl.cast.frag", "PixelShaderFunction"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index eb5a9aca..17ec8208 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -107,8 +107,7 @@ bool HlslGrammar::acceptCompilationUnit() // declaration // : SEMICOLON // : fully_specified_type SEMICOLON -// | fully_specified_type identifier post_decls SEMICOLON -// | fully_specified_type identifier post_decls = expression SEMICOLON +// | fully_specified_type identifier array_specifier post_decls (EQUAL expression)opt SEMICOLON // | fully_specified_type identifier function_parameters post_decls SEMICOLON // function prototype // | fully_specified_type identifier function_parameters post_decls compound_statement // function definition // @@ -127,8 +126,14 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) // identifier HlslToken idToken; if (acceptIdentifier(idToken)) { + // array_specifier + TArraySizes* arraySizes = nullptr; + acceptArraySpecifier(arraySizes); + + // post_decls acceptPostDecls(type); - // = expression + + // EQUAL expression TIntermTyped* expressionNode = nullptr; if (acceptTokenClass(EHTokAssign)) { if (! acceptExpression(expressionNode)) { @@ -139,7 +144,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) // SEMICOLON if (acceptTokenClass(EHTokSemicolon)) { - node = parseContext.declareVariable(idToken.loc, *idToken.string, type, 0, expressionNode); + node = parseContext.declareVariable(idToken.loc, *idToken.string, type, arraySizes, expressionNode); return true; } @@ -711,7 +716,10 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList) advanceToken(); // array_specifier - // TODO + TArraySizes* arraySizes = nullptr; + acceptArraySpecifier(arraySizes); + if (arraySizes) + typeList->back().type->newArraySizes(*arraySizes); acceptPostDecls(*member.type); @@ -770,7 +778,7 @@ bool HlslGrammar::acceptFunctionParameters(TFunction& function) // parameter_declaration // : fully_specified_type post_decls -// | fully_specified_type identifier post_decls +// | fully_specified_type identifier array_specifier post_decls // bool HlslGrammar::acceptParameterDeclaration(TFunction& function) { @@ -783,6 +791,13 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function) HlslToken idToken; acceptIdentifier(idToken); + // array_specifier + TArraySizes* arraySizes = nullptr; + acceptArraySpecifier(arraySizes); + if (arraySizes) + type->newArraySizes(*arraySizes); + + // post_decls acceptPostDecls(*type); parseContext.paramFix(*type); @@ -1098,7 +1113,9 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) switch (postOp) { case EOpIndexDirectStruct: { - // includes swizzles + // DOT IDENTIFIER + // includes swizzles and struct members + // TODO: possibly includes "method" syntax HlslToken field; if (! acceptIdentifier(field)) { expected("swizzle or member"); @@ -1109,16 +1126,22 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) } case EOpIndexIndirect: { + // LEFT_BRACKET integer_expression RIGHT_BRACKET TIntermTyped* indexNode = nullptr; if (! acceptExpression(indexNode) || ! peekTokenClass(EHTokRightBracket)) { expected("expression followed by ']'"); return false; } - // todo: node = intermediate.addBinaryMath( + advanceToken(); + node = parseContext.handleBracketDereference(indexNode->getLoc(), node, indexNode); + break; } case EOpPostIncrement: + // INC_OP + // fall through case EOpPostDecrement: + // DEC_OP node = intermediate.addUnaryMath(postOp, node, loc); break; default: @@ -1629,6 +1652,34 @@ bool HlslGrammar::acceptCaseLabel(TIntermNode*& statement) return false; } +// array_specifier +// : LEFT_BRACKET integer_expression RGHT_BRACKET post_decls // optional +// +void HlslGrammar::acceptArraySpecifier(TArraySizes*& arraySizes) +{ + arraySizes = nullptr; + + if (! acceptTokenClass(EHTokLeftBracket)) + return; + + TSourceLoc loc = token.loc; + TIntermTyped* sizeExpr; + if (! acceptAssignmentExpression(sizeExpr)) { + expected("array-sizing expression"); + return; + } + + if (! acceptTokenClass(EHTokRightBracket)) { + expected("]"); + return; + } + + TArraySize arraySize; + parseContext.arraySizeCheck(loc, sizeExpr, arraySize); + arraySizes = new TArraySizes; + arraySizes->addInnerSize(arraySize); +} + // post_decls // : COLON semantic // optional // COLON PACKOFFSET LEFT_PAREN ... RIGHT_PAREN // optional diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 97cea84a..b4a948f2 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -87,6 +87,7 @@ namespace glslang { bool acceptIterationStatement(TIntermNode*&); bool acceptJumpStatement(TIntermNode*&); bool acceptCaseLabel(TIntermNode*&); + void acceptArraySpecifier(TArraySizes*&); void acceptPostDecls(TType&); HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate diff --git a/hlsl/hlslOpMap.cpp b/hlsl/hlslOpMap.cpp index c31dd7cf..524e66a2 100755 --- a/hlsl/hlslOpMap.cpp +++ b/hlsl/hlslOpMap.cpp @@ -113,7 +113,7 @@ TOperator HlslOpMap::postUnary(EHlslTokenClass op) { switch (op) { case EHTokDot: return EOpIndexDirectStruct; - case EHTokLeftBracket: return EOpIndexIndirect; // may need to change later to EOpIndexDirect + case EHTokLeftBracket: return EOpIndexIndirect; case EHTokIncOp: return EOpPostIncrement; case EHTokDecOp: return EOpPostDecrement;