diff --git a/Test/baseResults/hlsl.layout.frag.out b/Test/baseResults/hlsl.layout.frag.out new file mode 100755 index 00000000..58b4100d --- /dev/null +++ b/Test/baseResults/hlsl.layout.frag.out @@ -0,0 +1,112 @@ +hlsl.layout.frag +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:15 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) +0:12 Function Parameters: +0:12 'input' (in 4-component vector of float) +0:? Sequence +0:13 Branch: Return with expression +0:13 add (temp 4-component vector of float) +0:13 add (temp 4-component vector of float) +0:13 'input' (in 4-component vector of float) +0:13 v1: direct index for structure (layout(column_major std430 offset=16 ) buffer 4-component vector of float) +0:13 'anon@0' (layout(set=3 binding=5 column_major std430 ) buffer block{layout(column_major std430 offset=16 ) buffer 4-component vector of float v1}) +0:13 Constant: +0:13 0 (const uint) +0:13 v5: direct index for structure (layout(column_major std430 offset=0 ) buffer 4-component vector of float) +0:13 'anon@1' (layout(column_major std430 push_constant ) buffer block{layout(column_major std430 offset=0 ) buffer 4-component vector of float v5}) +0:13 Constant: +0:13 0 (const uint) +0:? Linker Objects +0:? 'anon@0' (layout(set=3 binding=5 column_major std430 ) buffer block{layout(column_major std430 offset=16 ) buffer 4-component vector of float v1}) +0:? 'anon@1' (layout(column_major std430 push_constant ) buffer block{layout(column_major std430 offset=0 ) buffer 4-component vector of float v5}) +0:? 'specConst' (specialization-constant const int) +0:? 10 (const int) + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:15 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) +0:12 Function Parameters: +0:12 'input' (in 4-component vector of float) +0:? Sequence +0:13 Branch: Return with expression +0:13 add (temp 4-component vector of float) +0:13 add (temp 4-component vector of float) +0:13 'input' (in 4-component vector of float) +0:13 v1: direct index for structure (layout(column_major std430 offset=16 ) buffer 4-component vector of float) +0:13 'anon@0' (layout(set=3 binding=5 column_major std430 ) buffer block{layout(column_major std430 offset=16 ) buffer 4-component vector of float v1}) +0:13 Constant: +0:13 0 (const uint) +0:13 v5: direct index for structure (layout(column_major std430 offset=0 ) buffer 4-component vector of float) +0:13 'anon@1' (layout(column_major std430 push_constant ) buffer block{layout(column_major std430 offset=0 ) buffer 4-component vector of float v5}) +0:13 Constant: +0:13 0 (const uint) +0:? Linker Objects +0:? 'anon@0' (layout(set=3 binding=5 column_major std430 ) buffer block{layout(column_major std430 offset=16 ) buffer 4-component vector of float v1}) +0:? 'anon@1' (layout(column_major std430 push_constant ) buffer block{layout(column_major std430 offset=0 ) buffer 4-component vector of float v5}) +0:? 'specConst' (specialization-constant const int) +0:? 10 (const int) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 33 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" + ExecutionMode 4 OriginUpperLeft + Name 4 "main" + Name 11 "PixelShaderFunction(vf4;" + Name 10 "input" + Name 14 "" + MemberName 14 0 "v1" + Name 16 "" + Name 23 "" + MemberName 23 0 "v5" + Name 25 "" + MemberDecorate 14 0 Offset 16 + Decorate 14 BufferBlock + Decorate 16 DescriptorSet 3 + Decorate 16 Binding 5 + MemberDecorate 23 0 Offset 0 + Decorate 23 BufferBlock + Decorate 32 SpecId 17 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Function 7(fvec4) + 9: TypeFunction 7(fvec4) 8(ptr) + 14: TypeStruct 7(fvec4) + 15: TypePointer Uniform 14(struct) + 16: 15(ptr) Variable Uniform + 17: TypeInt 32 1 + 18: 17(int) Constant 0 + 19: TypePointer Uniform 7(fvec4) + 23: TypeStruct 7(fvec4) + 24: TypePointer PushConstant 23(struct) + 25: 24(ptr) Variable PushConstant + 26: TypePointer PushConstant 7(fvec4) + 32: 17(int) SpecConstant 10 + 4(main): 2 Function None 3 + 5: Label + FunctionEnd +11(PixelShaderFunction(vf4;): 7(fvec4) Function None 9 + 10(input): 8(ptr) FunctionParameter + 12: Label + 13: 7(fvec4) Load 10(input) + 20: 19(ptr) AccessChain 16 18 + 21: 7(fvec4) Load 20 + 22: 7(fvec4) FAdd 13 21 + 27: 26(ptr) AccessChain 25 18 + 28: 7(fvec4) Load 27 + 29: 7(fvec4) FAdd 22 28 + ReturnValue 29 + FunctionEnd diff --git a/Test/hlsl.layout.frag b/Test/hlsl.layout.frag new file mode 100644 index 00000000..9080beb3 --- /dev/null +++ b/Test/hlsl.layout.frag @@ -0,0 +1,14 @@ +layout(set=3,binding=5) tbuffer tbufName { + layout(offset = 16) float4 v1; +}; + +layout(push_constant) tbuffer tbufName2 { + float4 v5; +}; + +layout(constant_id=17) const int specConst = 10; + +float4 PixelShaderFunction(float4 input) : COLOR0 +{ + return input + v1 + v5; +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 3e3b6b4a..3ea6fc1f 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -112,6 +112,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"}, {"hlsl.intrinsics.negative.frag", "PixelShaderFunction"}, {"hlsl.intrinsics.negative.vert", "VertexShaderFunction"}, + {"hlsl.layout.frag", "main"}, {"hlsl.load.2dms.dx10.frag", "main"}, {"hlsl.load.array.dx10.frag", "main"}, {"hlsl.load.basic.dx10.frag", "main"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 582b1d06..9de3a277 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -426,7 +426,8 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type) // type_qualifier TQualifier qualifier; qualifier.clear(); - acceptQualifier(qualifier); + if (! acceptQualifier(qualifier)) + return false; TSourceLoc loc = token.loc; // type_specifier @@ -449,7 +450,7 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type) // // Zero or more of these, so this can't return false. // -void HlslGrammar::acceptQualifier(TQualifier& qualifier) +bool HlslGrammar::acceptQualifier(TQualifier& qualifier) { do { switch (peek()) { @@ -508,13 +509,66 @@ void HlslGrammar::acceptQualifier(TQualifier& qualifier) case EHTokInOut: qualifier.storage = EvqInOut; break; + case EHTokLayout: + if (! acceptLayoutQualifierList(qualifier)) + return false; + continue; default: - return; + return true; } advanceToken(); } while (true); } +// layout_qualifier_list +// : LEFT_PAREN layout_qualifier COMMA layout_qualifier ... RIGHT_PAREN +// +// layout_qualifier +// : identifier +// | identifier EQUAL expresion +// +// Zero or more of these, so this can't return false. +// +bool HlslGrammar::acceptLayoutQualifierList(TQualifier& qualifier) +{ + if (! acceptTokenClass(EHTokLayout)) + return false; + + // LEFT_PAREN + if (! acceptTokenClass(EHTokLeftParen)) + return false; + + do { + // identifier + HlslToken idToken; + if (! acceptIdentifier(idToken)) + break; + + // EQUAL expression + if (acceptTokenClass(EHTokAssign)) { + TIntermTyped* expr; + if (! acceptConditionalExpression(expr)) { + expected("expression"); + return false; + } + parseContext.setLayoutQualifier(idToken.loc, qualifier, *idToken.string, expr); + } else + parseContext.setLayoutQualifier(idToken.loc, qualifier, *idToken.string); + + // COMMA + if (! acceptTokenClass(EHTokComma)) + break; + } while (true); + + // RIGHT_PAREN + if (! acceptTokenClass(EHTokRightParen)) { + expected(")"); + return false; + } + + return true; +} + // template_type // : FLOAT // | DOUBLE diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index c522df4c..361e26c5 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -67,7 +67,8 @@ namespace glslang { bool acceptSamplerDeclarationDX9(TType&); bool acceptSamplerState(); bool acceptFullySpecifiedType(TType&); - void acceptQualifier(TQualifier&); + bool acceptQualifier(TQualifier&); + bool acceptLayoutQualifierList(TQualifier&); bool acceptType(TType&); bool acceptTemplateType(TBasicType&); bool acceptVectorTemplateType(TType&); diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 8ee8f9c7..e2de7013 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -3112,51 +3112,58 @@ void HlslParseContext::specializationCheck(const TSourceLoc& loc, const TType& t // Put the id's layout qualification into the public type, for qualifiers not having a number set. // This is before we know any type information for error checking. -void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id) +void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qualifier, TString& id) { std::transform(id.begin(), id.end(), id.begin(), ::tolower); if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) { - publicType.qualifier.layoutMatrix = ElmColumnMajor; + qualifier.layoutMatrix = ElmColumnMajor; return; } if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) { - publicType.qualifier.layoutMatrix = ElmRowMajor; + qualifier.layoutMatrix = ElmRowMajor; return; } if (id == "push_constant") { requireVulkan(loc, "push_constant"); - publicType.qualifier.layoutPushConstant = true; + qualifier.layoutPushConstant = true; return; } if (language == EShLangGeometry || language == EShLangTessEvaluation) { if (id == TQualifier::getGeometryString(ElgTriangles)) { - publicType.shaderQualifiers.geometry = ElgTriangles; + //publicType.shaderQualifiers.geometry = ElgTriangles; + warn(loc, "ignored", id.c_str(), ""); return; } if (language == EShLangGeometry) { if (id == TQualifier::getGeometryString(ElgPoints)) { - publicType.shaderQualifiers.geometry = ElgPoints; + //publicType.shaderQualifiers.geometry = ElgPoints; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getGeometryString(ElgLineStrip)) { - publicType.shaderQualifiers.geometry = ElgLineStrip; + //publicType.shaderQualifiers.geometry = ElgLineStrip; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getGeometryString(ElgLines)) { - publicType.shaderQualifiers.geometry = ElgLines; + //publicType.shaderQualifiers.geometry = ElgLines; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) { - publicType.shaderQualifiers.geometry = ElgLinesAdjacency; + //publicType.shaderQualifiers.geometry = ElgLinesAdjacency; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) { - publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency; + //publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getGeometryString(ElgTriangleStrip)) { - publicType.shaderQualifiers.geometry = ElgTriangleStrip; + //publicType.shaderQualifiers.geometry = ElgTriangleStrip; + warn(loc, "ignored", id.c_str(), ""); return; } } else { @@ -3164,65 +3171,78 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu // input primitive if (id == TQualifier::getGeometryString(ElgTriangles)) { - publicType.shaderQualifiers.geometry = ElgTriangles; + //publicType.shaderQualifiers.geometry = ElgTriangles; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getGeometryString(ElgQuads)) { - publicType.shaderQualifiers.geometry = ElgQuads; + //publicType.shaderQualifiers.geometry = ElgQuads; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getGeometryString(ElgIsolines)) { - publicType.shaderQualifiers.geometry = ElgIsolines; + //publicType.shaderQualifiers.geometry = ElgIsolines; + warn(loc, "ignored", id.c_str(), ""); return; } // vertex spacing if (id == TQualifier::getVertexSpacingString(EvsEqual)) { - publicType.shaderQualifiers.spacing = EvsEqual; + //publicType.shaderQualifiers.spacing = EvsEqual; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) { - publicType.shaderQualifiers.spacing = EvsFractionalEven; + //publicType.shaderQualifiers.spacing = EvsFractionalEven; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) { - publicType.shaderQualifiers.spacing = EvsFractionalOdd; + //publicType.shaderQualifiers.spacing = EvsFractionalOdd; + warn(loc, "ignored", id.c_str(), ""); return; } // triangle order if (id == TQualifier::getVertexOrderString(EvoCw)) { - publicType.shaderQualifiers.order = EvoCw; + //publicType.shaderQualifiers.order = EvoCw; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == TQualifier::getVertexOrderString(EvoCcw)) { - publicType.shaderQualifiers.order = EvoCcw; + //publicType.shaderQualifiers.order = EvoCcw; + warn(loc, "ignored", id.c_str(), ""); return; } // point mode if (id == "point_mode") { - publicType.shaderQualifiers.pointMode = true; + //publicType.shaderQualifiers.pointMode = true; + warn(loc, "ignored", id.c_str(), ""); return; } } } if (language == EShLangFragment) { if (id == "origin_upper_left") { - publicType.shaderQualifiers.originUpperLeft = true; + //publicType.shaderQualifiers.originUpperLeft = true; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == "pixel_center_integer") { - publicType.shaderQualifiers.pixelCenterInteger = true; + //publicType.shaderQualifiers.pixelCenterInteger = true; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == "early_fragment_tests") { - publicType.shaderQualifiers.earlyFragmentTests = true; + //publicType.shaderQualifiers.earlyFragmentTests = true; + warn(loc, "ignored", id.c_str(), ""); return; } for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth + 1)) { if (id == TQualifier::getLayoutDepthString(depth)) { - publicType.shaderQualifiers.layoutDepth = depth; + //publicType.shaderQualifiers.layoutDepth = depth; + warn(loc, "ignored", id.c_str(), ""); return; } } @@ -3232,7 +3252,8 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu if (id == TQualifier::getBlendEquationString(be)) { requireExtensions(loc, 1, &E_GL_KHR_blend_equation_advanced, "blend equation"); intermediate.addBlendEquation(be); - publicType.shaderQualifiers.blendEquation = true; + //publicType.shaderQualifiers.blendEquation = true; + warn(loc, "ignored", id.c_str(), ""); found = true; break; } @@ -3247,7 +3268,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu // Put the id's layout qualifier value into the public type, for qualifiers having a number set. // This is before we know any type information for error checking. -void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id, const TIntermTyped* node) +void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qualifier, TString& id, const TIntermTyped* node) { const char* feature = "layout-id value"; //const char* nonLiteralFeature = "non-literal layout-id value"; @@ -3262,38 +3283,38 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu std::transform(id.begin(), id.end(), id.begin(), ::tolower); if (id == "offset") { - publicType.qualifier.layoutOffset = value; + qualifier.layoutOffset = value; return; } else if (id == "align") { // "The specified alignment must be a power of 2, or a compile-time error results." if (! IsPow2(value)) error(loc, "must be a power of 2", "align", ""); else - publicType.qualifier.layoutAlign = value; + qualifier.layoutAlign = value; return; } else if (id == "location") { if ((unsigned int)value >= TQualifier::layoutLocationEnd) error(loc, "location is too large", id.c_str(), ""); else - publicType.qualifier.layoutLocation = value; + qualifier.layoutLocation = value; return; } else if (id == "set") { if ((unsigned int)value >= TQualifier::layoutSetEnd) error(loc, "set is too large", id.c_str(), ""); else - publicType.qualifier.layoutSet = value; + qualifier.layoutSet = value; return; } else if (id == "binding") { if ((unsigned int)value >= TQualifier::layoutBindingEnd) error(loc, "binding is too large", id.c_str(), ""); else - publicType.qualifier.layoutBinding = value; + qualifier.layoutBinding = value; return; } else if (id == "component") { if ((unsigned)value >= TQualifier::layoutComponentEnd) error(loc, "component is too large", id.c_str(), ""); else - publicType.qualifier.layoutComponent = value; + qualifier.layoutComponent = value; return; } else if (id.compare(0, 4, "xfb_") == 0) { // "Any shader making any static use (after preprocessing) of any of these @@ -3309,13 +3330,13 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu if (value >= (int)TQualifier::layoutXfbBufferEnd) error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd - 1); else - publicType.qualifier.layoutXfbBuffer = value; + qualifier.layoutXfbBuffer = value; return; } else if (id == "xfb_offset") { if (value >= (int)TQualifier::layoutXfbOffsetEnd) error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd - 1); else - publicType.qualifier.layoutXfbOffset = value; + qualifier.layoutXfbOffset = value; return; } else if (id == "xfb_stride") { // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the @@ -3325,7 +3346,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu else if (value >= (int)TQualifier::layoutXfbStrideEnd) error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd - 1); if (value < (int)TQualifier::layoutXfbStrideEnd) - publicType.qualifier.layoutXfbStride = value; + qualifier.layoutXfbStride = value; return; } } @@ -3335,7 +3356,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu if (value >= (int)TQualifier::layoutAttachmentEnd) error(loc, "attachment index is too large", id.c_str(), ""); else - publicType.qualifier.layoutAttachment = value; + qualifier.layoutAttachment = value; return; } if (id == "constant_id") { @@ -3343,8 +3364,8 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu if (value >= (int)TQualifier::layoutSpecConstantIdEnd) { error(loc, "specialization-constant id is too large", id.c_str(), ""); } else { - publicType.qualifier.layoutSpecConstantId = value; - publicType.qualifier.specConstant = true; + qualifier.layoutSpecConstantId = value; + qualifier.specConstant = true; if (! intermediate.addUsedConstantId(value)) error(loc, "specialization-constant id already used", id.c_str(), ""); } @@ -3360,7 +3381,8 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu if (value == 0) error(loc, "must be greater than 0", "vertices", ""); else - publicType.shaderQualifiers.vertices = value; + //publicType.shaderQualifiers.vertices = value; + warn(loc, "ignored", id.c_str(), ""); return; } break; @@ -3373,24 +3395,26 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu if (value == 0) error(loc, "must be at least 1", "invocations", ""); else - publicType.shaderQualifiers.invocations = value; + //publicType.shaderQualifiers.invocations = value; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == "max_vertices") { - publicType.shaderQualifiers.vertices = value; + //publicType.shaderQualifiers.vertices = value; + warn(loc, "ignored", id.c_str(), ""); if (value > resources.maxGeometryOutputVertices) error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", ""); return; } if (id == "stream") { - publicType.qualifier.layoutStream = value; + qualifier.layoutStream = value; return; } break; case EShLangFragment: if (id == "index") { - publicType.qualifier.layoutIndex = value; + qualifier.layoutIndex = value; return; } break; @@ -3398,28 +3422,34 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu case EShLangCompute: if (id.compare(0, 11, "local_size_") == 0) { if (id == "local_size_x") { - publicType.shaderQualifiers.localSize[0] = value; + //publicType.shaderQualifiers.localSize[0] = value; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == "local_size_y") { - publicType.shaderQualifiers.localSize[1] = value; + //publicType.shaderQualifiers.localSize[1] = value; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == "local_size_z") { - publicType.shaderQualifiers.localSize[2] = value; + //publicType.shaderQualifiers.localSize[2] = value; + warn(loc, "ignored", id.c_str(), ""); return; } if (spvVersion.spv != 0) { if (id == "local_size_x_id") { - publicType.shaderQualifiers.localSizeSpecId[0] = value; + //publicType.shaderQualifiers.localSizeSpecId[0] = value; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == "local_size_y_id") { - publicType.shaderQualifiers.localSizeSpecId[1] = value; + //publicType.shaderQualifiers.localSizeSpecId[1] = value; + warn(loc, "ignored", id.c_str(), ""); return; } if (id == "local_size_z_id") { - publicType.shaderQualifiers.localSizeSpecId[2] = value; + //publicType.shaderQualifiers.localSizeSpecId[2] = value; + warn(loc, "ignored", id.c_str(), ""); return; } } diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index f45a874f..659ec4a7 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -128,8 +128,8 @@ public: void paramFix(TType& type); void specializationCheck(const TSourceLoc&, const TType&, const char* op); - void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&); - void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*); + void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&); + void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&, const TIntermTyped*); void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly); void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&); diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp index 36dea5cb..a3be6fad 100755 --- a/hlsl/hlslScanContext.cpp +++ b/hlsl/hlslScanContext.cpp @@ -117,6 +117,7 @@ void HlslScanContext::fillInKeywordMap() (*KeywordMap)["in"] = EHTokIn; (*KeywordMap)["out"] = EHTokOut; (*KeywordMap)["inout"] = EHTokInOut; + (*KeywordMap)["layout"] = EHTokLayout; (*KeywordMap)["Buffer"] = EHTokBuffer; (*KeywordMap)["vector"] = EHTokVector; @@ -457,6 +458,7 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier() case EHTokIn: case EHTokOut: case EHTokInOut: + case EHTokLayout: return keyword; // template types diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h index d72b2cd9..b54a757d 100755 --- a/hlsl/hlslTokens.h +++ b/hlsl/hlslTokens.h @@ -64,6 +64,7 @@ enum EHlslTokenClass { EHTokIn, EHTokOut, EHTokInOut, + EHTokLayout, // template types EHTokBuffer,