diff --git a/Test/baseResults/hlsl.float4.frag.out b/Test/baseResults/hlsl.float4.frag.out index ba757c98..2ea803f1 100755 --- a/Test/baseResults/hlsl.float4.frag.out +++ b/Test/baseResults/hlsl.float4.frag.out @@ -9,16 +9,20 @@ gl_FragCoord origin is upper left 0:? 0.500000 0:? 0.000000 0:? 1.000000 -0:7 Function Definition: ShaderFunction(vf4; (temp 4-component vector of float) -0:4 Function Parameters: -0:4 'input' (temp 4-component vector of float) +0:12 Function Definition: ShaderFunction(vf4; (temp 4-component vector of float) +0:9 Function Parameters: +0:9 'input' (temp 4-component vector of float) 0:? Sequence -0:5 Branch: Return with expression -0:5 component-wise multiply (temp 4-component vector of float) -0:5 'input' (temp 4-component vector of float) -0:5 'AmbientColor' (temp 4-component vector of float) +0:10 Branch: Return with expression +0:10 component-wise multiply (temp 4-component vector of float) +0:10 'input' (temp 4-component vector of float) +0:10 'AmbientColor' (temp 4-component vector of float) 0:? Linker Objects 0:? 'AmbientColor' (temp 4-component vector of float) +0:? 'ff1' (temp bool Face) +0:? 'ff2' (temp 4-component vector of float) +0:? 'ff3' (temp 4-component vector of float) +0:? 'ff4' (temp 4-component vector of float FragCoord) Linked fragment stage: @@ -34,20 +38,24 @@ gl_FragCoord origin is upper left 0:? 0.500000 0:? 0.000000 0:? 1.000000 -0:7 Function Definition: ShaderFunction(vf4; (temp 4-component vector of float) -0:4 Function Parameters: -0:4 'input' (temp 4-component vector of float) +0:12 Function Definition: ShaderFunction(vf4; (temp 4-component vector of float) +0:9 Function Parameters: +0:9 'input' (temp 4-component vector of float) 0:? Sequence -0:5 Branch: Return with expression -0:5 component-wise multiply (temp 4-component vector of float) -0:5 'input' (temp 4-component vector of float) -0:5 'AmbientColor' (temp 4-component vector of float) +0:10 Branch: Return with expression +0:10 component-wise multiply (temp 4-component vector of float) +0:10 'input' (temp 4-component vector of float) +0:10 'AmbientColor' (temp 4-component vector of float) 0:? Linker Objects 0:? 'AmbientColor' (temp 4-component vector of float) +0:? 'ff1' (temp bool Face) +0:? 'ff2' (temp 4-component vector of float) +0:? 'ff3' (temp 4-component vector of float) +0:? 'ff4' (temp 4-component vector of float FragCoord) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 19 +// Id's are bound by 25 Capability Shader 1: ExtInstImport "GLSL.std.450" @@ -59,12 +67,20 @@ gl_FragCoord origin is upper left Name 11 "ShaderFunction(vf4;" Name 10 "input" Name 14 "AmbientColor" + Name 21 "ff1" + Name 22 "ff2" + Name 23 "ff3" + Name 24 "ff4" + Decorate 21(ff1) BuiltIn FrontFacing + Decorate 24(ff4) BuiltIn FragCoord 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 7: TypeVector 6(float) 4 8: TypePointer Function 7(fvec4) 9: TypeFunction 7(fvec4) 8(ptr) + 19: TypeBool + 20: TypePointer Function 19(bool) 4(PixelShaderFunction): 2 Function None 3 5: Label FunctionEnd @@ -72,6 +88,10 @@ gl_FragCoord origin is upper left 10(input): 8(ptr) FunctionParameter 12: Label 14(AmbientColor): 8(ptr) Variable Function + 21(ff1): 20(ptr) Variable Function + 22(ff2): 8(ptr) Variable Function + 23(ff3): 8(ptr) Variable Function + 24(ff4): 8(ptr) Variable Function 13: 7(fvec4) Load 10(input) 15: 7(fvec4) Load 14(AmbientColor) 16: 7(fvec4) FMul 13 15 diff --git a/Test/baseResults/hlsl.struct.frag.out b/Test/baseResults/hlsl.struct.frag.out index 6e344891..de2c74be 100755 --- a/Test/baseResults/hlsl.struct.frag.out +++ b/Test/baseResults/hlsl.struct.frag.out @@ -2,16 +2,19 @@ hlsl.struct.frag Shader version: 450 gl_FragCoord origin is upper left 0:? Sequence -0:26 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) -0:20 Function Parameters: -0:20 'input' (temp 4-component vector of float) +0:39 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) +0:31 Function Parameters: +0:31 'input' (temp 4-component vector of float) 0:? Sequence -0:25 Compare Equal (temp bool) -0:25 's3' (temp structure{temp 3-component vector of bool b3}) -0:25 's3' (temp structure{temp 3-component vector of bool b3}) +0:36 Compare Equal (temp bool) +0:36 's3' (temp structure{temp 3-component vector of bool b3}) +0:36 's3' (temp structure{temp 3-component vector of bool b3}) +0:38 Branch: Return with expression +0:38 'input' (temp 4-component vector of float) 0:? Linker Objects 0:? 's1' (temp structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d}) 0:? 's2' (temp structure{temp 4-component vector of float i}) +0:? 's4' (temp structure{smooth in 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, temp bool Face ff1, temp bool ff2, temp bool ff3, temp 4-component vector of float FragCoord ff4}) Linked fragment stage: @@ -20,20 +23,23 @@ Linked fragment stage: Shader version: 450 gl_FragCoord origin is upper left 0:? Sequence -0:26 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) -0:20 Function Parameters: -0:20 'input' (temp 4-component vector of float) +0:39 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) +0:31 Function Parameters: +0:31 'input' (temp 4-component vector of float) 0:? Sequence -0:25 Compare Equal (temp bool) -0:25 's3' (temp structure{temp 3-component vector of bool b3}) -0:25 's3' (temp structure{temp 3-component vector of bool b3}) +0:36 Compare Equal (temp bool) +0:36 's3' (temp structure{temp 3-component vector of bool b3}) +0:36 's3' (temp structure{temp 3-component vector of bool b3}) +0:38 Branch: Return with expression +0:38 'input' (temp 4-component vector of float) 0:? Linker Objects 0:? 's1' (temp structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d}) 0:? 's2' (temp structure{temp 4-component vector of float i}) +0:? 's4' (temp structure{smooth in 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, temp bool Face ff1, temp bool ff2, temp bool ff3, temp 4-component vector of float FragCoord ff4}) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 25 +// Id's are bound by 33 Capability Shader 1: ExtInstImport "GLSL.std.450" @@ -45,15 +51,28 @@ gl_FragCoord origin is upper left Name 8 "FS" MemberName 8(FS) 0 "b3" Name 10 "s3" - Name 19 "myS" - MemberName 19(myS) 0 "b" - MemberName 19(myS) 1 "c" - MemberName 19(myS) 2 "a" - MemberName 19(myS) 3 "d" - Name 21 "s1" - Name 22 "" - MemberName 22 0 "i" - Name 24 "s2" + Name 20 "input" + Name 23 "myS" + MemberName 23(myS) 0 "b" + MemberName 23(myS) 1 "c" + MemberName 23(myS) 2 "a" + MemberName 23(myS) 3 "d" + Name 25 "s1" + Name 26 "" + MemberName 26 0 "i" + Name 28 "s2" + Name 30 "" + MemberName 30 0 "a" + MemberName 30 1 "b" + MemberName 30 2 "c" + MemberName 30 3 "d" + MemberName 30 4 "ff1" + MemberName 30 5 "ff2" + MemberName 30 6 "ff3" + MemberName 30 7 "ff4" + Name 32 "s4" + MemberDecorate 30 4 BuiltIn FrontFacing + MemberDecorate 30 7 BuiltIn FragCoord 2: TypeVoid 3: TypeFunction 2 6: TypeBool @@ -62,20 +81,27 @@ gl_FragCoord origin is upper left 9: TypePointer Function 8(FS) 17: TypeFloat 32 18: TypeVector 17(float) 4 - 19(myS): TypeStruct 6(bool) 6(bool) 18(fvec4) 18(fvec4) - 20: TypePointer Function 19(myS) - 22: TypeStruct 18(fvec4) - 23: TypePointer Function 22(struct) + 19: TypePointer Function 18(fvec4) + 23(myS): TypeStruct 6(bool) 6(bool) 18(fvec4) 18(fvec4) + 24: TypePointer Function 23(myS) + 26: TypeStruct 18(fvec4) + 27: TypePointer Function 26(struct) + 29: TypeVector 17(float) 2 + 30: TypeStruct 18(fvec4) 6(bool) 17(float) 29(fvec2) 6(bool) 6(bool) 6(bool) 18(fvec4) + 31: TypePointer Function 30(struct) 4(PixelShaderFunction): 2 Function None 3 5: Label 10(s3): 9(ptr) Variable Function - 21(s1): 20(ptr) Variable Function - 24(s2): 23(ptr) Variable Function + 20(input): 19(ptr) Variable Function + 25(s1): 24(ptr) Variable Function + 28(s2): 27(ptr) Variable Function + 32(s4): 31(ptr) Variable Function 11: 8(FS) Load 10(s3) 12: 8(FS) Load 10(s3) 13: 7(bvec3) CompositeExtract 11 0 14: 7(bvec3) CompositeExtract 12 0 15: 7(bvec3) LogicalEqual 13 14 16: 6(bool) All 15 - Return + 21: 18(fvec4) Load 20(input) + ReturnValue 21 FunctionEnd diff --git a/Test/hlsl.float4.frag b/Test/hlsl.float4.frag index 8ed4eab1..df871225 100644 --- a/Test/hlsl.float4.frag +++ b/Test/hlsl.float4.frag @@ -1,5 +1,10 @@ float4 AmbientColor = float4(1, 0.5, 0, 1); +bool ff1 : SV_IsFrontFace; +float4 ff2 : packoffset(c0.y); +float4 ff3 : packoffset(c0.y) : register(ps_5_0, s[0]) ; +float4 ff4 : VPOS : packoffset(c0.y) : register(ps_5_0, s[0]) ; + float4 ShaderFunction(float4 input) : COLOR0 { return input * AmbientColor; diff --git a/Test/hlsl.struct.frag b/Test/hlsl.struct.frag index 4b5b2419..aded037c 100644 --- a/Test/hlsl.struct.frag +++ b/Test/hlsl.struct.frag @@ -16,6 +16,17 @@ struct { float4 i; } s2; +struct { + linear float4 a; + nointerpolation bool b; + noperspective centroid float1 c; + sample centroid float2 d; + bool ff1 : SV_IsFrontFace; + bool ff2 : packoffset(c0.y); + bool ff3 : packoffset(c0.y) : register(ps_5_0, s[0]) ; + float4 ff4 : VPOS : packoffset(c0.y) : register(ps_5_0, s[0]) ; +} s4; + float4 PixelShaderFunction(float4 input) : COLOR0 { struct FS { @@ -23,4 +34,6 @@ float4 PixelShaderFunction(float4 input) : COLOR0 } s3; s3 == s3; + + return input; } \ No newline at end of file diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 1bd44165..c0d4f285 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -107,10 +107,10 @@ bool HlslGrammar::acceptCompilationUnit() // declaration // : SEMICOLON // : fully_specified_type SEMICOLON -// | fully_specified_type identifier SEMICOLON -// | fully_specified_type identifier = expression SEMICOLON -// | fully_specified_type identifier function_parameters SEMICOLON // function prototype -// | fully_specified_type identifier function_parameters COLON semantic compound_statement // function definition +// | fully_specified_type identifier post_decls SEMICOLON +// | fully_specified_type identifier post_decls = expression SEMICOLON +// | fully_specified_type identifier function_parameters post_decls SEMICOLON // function prototype +// | fully_specified_type identifier function_parameters post_decls compound_statement // function definition // // 'node' could get created if the declaration creates code, like an initializer // or a function body. @@ -127,6 +127,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) // identifier HlslToken idToken; if (acceptIdentifier(idToken)) { + acceptPostDecls(type); // = expression TIntermTyped* expressionNode = nullptr; if (acceptTokenClass(EHTokAssign)) { @@ -145,8 +146,8 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) // function_parameters TFunction* function = new TFunction(idToken.string, type); if (acceptFunctionParameters(*function)) { - // COLON semantic - acceptSemantic(); + // post_decls + acceptPostDecls(type); // compound_statement if (peekTokenClass(EHTokLeftBrace)) @@ -186,22 +187,66 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type) return true; } -// If token is a qualifier, return its token class and advance to the next -// qualifier. Otherwise, return false, and don't advance. +// type_qualifier +// : qualifier qualifier ... +// +// Zero or more of these, so this can't return false. +// void HlslGrammar::acceptQualifier(TQualifier& qualifier) { - switch (peek()) { - case EHTokUniform: - qualifier.storage = EvqUniform; - break; - case EHTokConst: - qualifier.storage = EvqConst; - break; - default: - return; - } - - advanceToken(); + do { + switch (peek()) { + case EHTokStatic: + // normal glslang default + break; + case EHTokExtern: + // TODO: no meaning in glslang? + break; + case EHTokShared: + // TODO: hint + break; + case EHTokGroupShared: + qualifier.storage = EvqShared; + break; + case EHTokUniform: + qualifier.storage = EvqUniform; + break; + case EHTokConst: + qualifier.storage = EvqConst; + break; + case EHTokVolatile: + qualifier.volatil = true; + break; + case EHTokLinear: + qualifier.storage = EvqVaryingIn; + qualifier.smooth = true; + break; + case EHTokCentroid: + qualifier.centroid = true; + break; + case EHTokNointerpolation: + qualifier.flat = true; + break; + case EHTokNoperspective: + qualifier.nopersp = true; + break; + case EHTokSample: + qualifier.sample = true; + break; + case EHTokRowMajor: + qualifier.layoutMatrix = ElmRowMajor; + break; + case EHTokColumnMajor: + qualifier.layoutMatrix = ElmColumnMajor; + break; + case EHTokPrecise: + qualifier.noContraction = true; + break; + default: + return; + } + advanceToken(); + } while (true); } // If token is for a type, update 'type' with the type information, @@ -627,8 +672,8 @@ bool HlslGrammar::acceptStruct(TType& type) // : fully_specified_type struct_declarator COMMA struct_declarator ... // // struct_declarator -// : IDENTIFIER -// | IDENTIFIER array_specifier +// : IDENTIFIER post_decls +// | IDENTIFIER array_specifier post_decls // bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList) { @@ -668,6 +713,8 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList) // array_specifier // TODO + acceptPostDecls(*member.type); + // success on seeing the SEMICOLON coming up if (peekTokenClass(EHTokSemicolon)) break; @@ -1570,20 +1617,68 @@ bool HlslGrammar::acceptCaseLabel(TIntermNode*& statement) return false; } -// COLON semantic -bool HlslGrammar::acceptSemantic() +// post_decls +// : COLON semantic // optional +// COLON PACKOFFSET LEFT_PAREN ... RIGHT_PAREN // optional +// COLON REGISTER // optional +// annotations // optional +// +void HlslGrammar::acceptPostDecls(TType& type) { - // COLON - if (acceptTokenClass(EHTokColon)) { - // semantic - HlslToken idToken; - if (! acceptIdentifier(idToken)) { - expected("semantic"); - return false; - } - } + do { + // COLON + if (acceptTokenClass(EHTokColon)) { + HlslToken idToken; + if (acceptTokenClass(EHTokPackOffset)) { + if (! acceptTokenClass(EHTokLeftParen)) { + expected("("); + return; + } + acceptTokenClass(EHTokIdentifier); + acceptTokenClass(EHTokDot); + acceptTokenClass(EHTokIdentifier); + if (! acceptTokenClass(EHTokRightParen)) { + expected(")"); + break; + } + // TODO: process the packoffset information + } else if (! acceptIdentifier(idToken)) { + expected("semantic or packoffset or register"); + return; + } else if (*idToken.string == "register") { + if (! acceptTokenClass(EHTokLeftParen)) { + expected("("); + return; + } + acceptTokenClass(EHTokIdentifier); + acceptTokenClass(EHTokComma); + acceptTokenClass(EHTokIdentifier); + acceptTokenClass(EHTokLeftBracket); + if (peekTokenClass(EHTokIntConstant)) + advanceToken(); + acceptTokenClass(EHTokRightBracket); + if (! acceptTokenClass(EHTokRightParen)) { + expected(")"); + break; + } + // TODO: process the register information + } else { + // semantic, in idToken.string + parseContext.handleSemantic(type, *idToken.string); + } + } else if (acceptTokenClass(EHTokLeftAngle)) { + // TODO: process annotations, just accepting them for now + do { + if (peekTokenClass(EHTokNone)) + return; + if (acceptTokenClass(EHTokRightAngle)) + break; + advanceToken(); + } while (true); + } else + break; - return true; + } while (true); } } // end namespace glslang diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 6cbcf2f0..97cea84a 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -87,8 +87,7 @@ namespace glslang { bool acceptIterationStatement(TIntermNode*&); bool acceptJumpStatement(TIntermNode*&); bool acceptCaseLabel(TIntermNode*&); - - bool acceptSemantic(); + void acceptPostDecls(TType&); HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate TIntermediate& intermediate; // the final product, the intermediate representation, includes the AST diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 1d6ffd85..13eb6389 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1212,6 +1212,38 @@ TFunction* HlslParseContext::handleConstructorCall(const TSourceLoc& loc, const return new TFunction(&empty, type, op); } +// +// Handle seeing a "COLON semantic" at the end of a type declaration, +// by updating the type according to the semantic. +// +void HlslParseContext::handleSemantic(TType& type, const TString& semantic) +{ + // TODO: need to know if it's an input or an output + // The following sketches what needs to be done, but can't be right + // without taking into account stage and input/output. + + if (semantic == "PSIZE") + type.getQualifier().builtIn = EbvPointSize; + else if (semantic == "POSITION") + type.getQualifier().builtIn = EbvPosition; + else if (semantic == "FOG") + type.getQualifier().builtIn = EbvFogFragCoord; + else if (semantic == "DEPTH" || semantic == "SV_Depth") + type.getQualifier().builtIn = EbvFragDepth; + else if (semantic == "VFACE" || semantic == "SV_IsFrontFace") + type.getQualifier().builtIn = EbvFace; + else if (semantic == "VPOS" || semantic == "SV_Position") + type.getQualifier().builtIn = EbvFragCoord; + else if (semantic == "SV_ClipDistance") + type.getQualifier().builtIn = EbvClipDistance; + else if (semantic == "SV_CullDistance") + type.getQualifier().builtIn = EbvCullDistance; + else if (semantic == "SV_VertexID") + type.getQualifier().builtIn = EbvVertexId; + else if (semantic == "SV_ViewportArrayIndex") + type.getQualifier().builtIn = EbvViewportIndex; +} + // // Given a type, find what operation would fully construct it. // diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 7f1e1acb..7def6b9a 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -90,6 +90,7 @@ public: TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); TFunction* handleConstructorCall(const TSourceLoc&, const TType&); + void handleSemantic(TType& type, const TString& semantic); bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&); void assignError(const TSourceLoc&, const char* op, TString left, TString right); diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp index dc470ffe..69e582f6 100755 --- a/hlsl/hlslScanContext.cpp +++ b/hlsl/hlslScanContext.cpp @@ -102,6 +102,7 @@ void HlslScanContext::fillInKeywordMap() (*KeywordMap)["extern"] = EHTokExtern; (*KeywordMap)["uniform"] = EHTokUniform; (*KeywordMap)["volatile"] = EHTokVolatile; + (*KeywordMap)["precise"] = EHTokPrecise; (*KeywordMap)["shared"] = EHTokShared; (*KeywordMap)["groupshared"] = EHTokGroupShared; (*KeywordMap)["linear"] = EHTokLinear; diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h index 9e6795b9..b3c1227d 100755 --- a/hlsl/hlslTokens.h +++ b/hlsl/hlslTokens.h @@ -49,6 +49,7 @@ enum EHlslTokenClass { EHTokExtern, EHTokUniform, EHTokVolatile, + EHTokPrecise, EHTokShared, EHTokGroupShared, EHTokLinear,