From 046bae0babd17ecc19fc7cbe40c35aa13ac2ee65 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sat, 23 Dec 2017 17:29:45 -0700 Subject: [PATCH] HLSL: Attributes: Add [[vk::constant_id()]] and [[vk::push_constant]] --- Test/baseResults/hlsl.attributeC11.frag.out | 123 +++++++++++--------- Test/hlsl.attributeC11.frag | 6 +- hlsl/hlslAttributes.cpp | 4 + hlsl/hlslAttributes.h | 4 +- hlsl/hlslGrammar.cpp | 31 ++--- hlsl/hlslGrammar.h | 4 +- hlsl/hlslParseHelper.cpp | 34 ++++-- hlsl/hlslParseHelper.h | 1 + 8 files changed, 127 insertions(+), 80 deletions(-) diff --git a/Test/baseResults/hlsl.attributeC11.frag.out b/Test/baseResults/hlsl.attributeC11.frag.out index 905f049c2..b507abac0 100755 --- a/Test/baseResults/hlsl.attributeC11.frag.out +++ b/Test/baseResults/hlsl.attributeC11.frag.out @@ -2,42 +2,45 @@ hlsl.attributeC11.frag Shader version: 500 gl_FragCoord origin is upper left 0:? Sequence -0:16 Function Definition: @main(vf4; ( temp 4-component vector of float) -0:16 Function Parameters: -0:16 'input' ( in 4-component vector of float) +0:20 Function Definition: @main(vf4; ( temp 4-component vector of float) +0:20 Function Parameters: +0:20 'input' ( in 4-component vector of float) 0:? Sequence -0:17 Branch: Return with expression -0:17 add ( temp 4-component vector of float) -0:17 'input' ( in 4-component vector of float) -0:17 textureFetch ( temp 4-component vector of float) -0:17 'attach' ( uniform texture2D) -0:17 vector swizzle ( temp int) -0:17 Constant: -0:17 0 (const int) -0:17 0 (const int) -0:17 Sequence -0:17 Constant: -0:17 0 (const int) -0:17 direct index ( temp int) -0:17 Constant: -0:17 0 (const int) -0:17 0 (const int) -0:17 Constant: -0:17 1 (const int) -0:16 Function Definition: main( ( temp void) -0:16 Function Parameters: +0:21 Branch: Return with expression +0:21 add ( temp 4-component vector of float) +0:21 'input' ( in 4-component vector of float) +0:21 textureFetch ( temp 4-component vector of float) +0:21 'attach' ( uniform texture2D) +0:21 vector swizzle ( temp int) +0:21 Constant: +0:21 0 (const int) +0:21 0 (const int) +0:21 Sequence +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp int) +0:21 Constant: +0:21 0 (const int) +0:21 0 (const int) +0:21 Constant: +0:21 1 (const int) +0:20 Function Definition: main( ( temp void) +0:20 Function Parameters: 0:? Sequence -0:16 move second child to first child ( temp 4-component vector of float) +0:20 move second child to first child ( temp 4-component vector of float) 0:? 'input' ( temp 4-component vector of float) 0:? 'input' (layout( location=8) in 4-component vector of float) -0:16 move second child to first child ( temp 4-component vector of float) +0:20 move second child to first child ( temp 4-component vector of float) 0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float) -0:16 Function Call: @main(vf4; ( temp 4-component vector of float) +0:20 Function Call: @main(vf4; ( temp 4-component vector of float) 0:? 'input' ( temp 4-component vector of float) 0:? Linker Objects 0:? 'buffer1' (layout( set=0 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data}) 0:? 'buffer3' (layout( set=2 binding=3 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data}) 0:? 'attach' ( uniform texture2D) +0:? 'ci' ( specialization-constant const int) +0:? 11 (const int) +0:? 'anon@0' (layout( row_major std430 push_constant) uniform block{layout( row_major std430 offset=0) uniform int a}) 0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float) 0:? 'input' (layout( location=8) in 4-component vector of float) @@ -48,48 +51,51 @@ Linked fragment stage: Shader version: 500 gl_FragCoord origin is upper left 0:? Sequence -0:16 Function Definition: @main(vf4; ( temp 4-component vector of float) -0:16 Function Parameters: -0:16 'input' ( in 4-component vector of float) +0:20 Function Definition: @main(vf4; ( temp 4-component vector of float) +0:20 Function Parameters: +0:20 'input' ( in 4-component vector of float) 0:? Sequence -0:17 Branch: Return with expression -0:17 add ( temp 4-component vector of float) -0:17 'input' ( in 4-component vector of float) -0:17 textureFetch ( temp 4-component vector of float) -0:17 'attach' ( uniform texture2D) -0:17 vector swizzle ( temp int) -0:17 Constant: -0:17 0 (const int) -0:17 0 (const int) -0:17 Sequence -0:17 Constant: -0:17 0 (const int) -0:17 direct index ( temp int) -0:17 Constant: -0:17 0 (const int) -0:17 0 (const int) -0:17 Constant: -0:17 1 (const int) -0:16 Function Definition: main( ( temp void) -0:16 Function Parameters: +0:21 Branch: Return with expression +0:21 add ( temp 4-component vector of float) +0:21 'input' ( in 4-component vector of float) +0:21 textureFetch ( temp 4-component vector of float) +0:21 'attach' ( uniform texture2D) +0:21 vector swizzle ( temp int) +0:21 Constant: +0:21 0 (const int) +0:21 0 (const int) +0:21 Sequence +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp int) +0:21 Constant: +0:21 0 (const int) +0:21 0 (const int) +0:21 Constant: +0:21 1 (const int) +0:20 Function Definition: main( ( temp void) +0:20 Function Parameters: 0:? Sequence -0:16 move second child to first child ( temp 4-component vector of float) +0:20 move second child to first child ( temp 4-component vector of float) 0:? 'input' ( temp 4-component vector of float) 0:? 'input' (layout( location=8) in 4-component vector of float) -0:16 move second child to first child ( temp 4-component vector of float) +0:20 move second child to first child ( temp 4-component vector of float) 0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float) -0:16 Function Call: @main(vf4; ( temp 4-component vector of float) +0:20 Function Call: @main(vf4; ( temp 4-component vector of float) 0:? 'input' ( temp 4-component vector of float) 0:? Linker Objects 0:? 'buffer1' (layout( set=0 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data}) 0:? 'buffer3' (layout( set=2 binding=3 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data}) 0:? 'attach' ( uniform texture2D) +0:? 'ci' ( specialization-constant const int) +0:? 11 (const int) +0:? 'anon@0' (layout( row_major std430 push_constant) uniform block{layout( row_major std430 offset=0) uniform int a}) 0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float) 0:? 'input' (layout( location=8) in 4-component vector of float) // Module Version 10000 // Generated by (magic number): 80003 -// Id's are bound by 47 +// Id's are bound by 51 Capability Shader 1: ExtInstImport "GLSL.std.450" @@ -111,6 +117,10 @@ gl_FragCoord origin is upper left MemberName 43(buffer1) 0 "@data" Name 45 "buffer1" Name 46 "buffer3" + Name 47 "ci" + Name 48 "pcBuf" + MemberName 48(pcBuf) 0 "a" + Name 50 "" Decorate 16(attach) DescriptorSet 0 Decorate 16(attach) InputAttachmentIndex 4 Decorate 33(input) Location 8 @@ -124,6 +134,9 @@ gl_FragCoord origin is upper left Decorate 45(buffer1) Binding 1 Decorate 46(buffer3) DescriptorSet 2 Decorate 46(buffer3) Binding 3 + Decorate 47(ci) SpecId 13 + MemberDecorate 48(pcBuf) 0 Offset 0 + Decorate 48(pcBuf) Block 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -151,6 +164,10 @@ gl_FragCoord origin is upper left 44: TypePointer Uniform 43(buffer1) 45(buffer1): 44(ptr) Variable Uniform 46(buffer3): 44(ptr) Variable Uniform + 47(ci): 18(int) SpecConstant 11 + 48(pcBuf): TypeStruct 18(int) + 49: TypePointer PushConstant 48(pcBuf) + 50: 49(ptr) Variable PushConstant 4(main): 2 Function None 3 5: Label 31(input): 8(ptr) Variable Function diff --git a/Test/hlsl.attributeC11.frag b/Test/hlsl.attributeC11.frag index 4fe663a2a..336511f92 100644 --- a/Test/hlsl.attributeC11.frag +++ b/Test/hlsl.attributeC11.frag @@ -11,8 +11,12 @@ StructuredBuffer buffer3; [[vk::input_attachment_index(4)]] Texture2D attach; +[[vk::constant_id(13)]] const int ci = 11; + +[[vk::push_constant]] cbuffer pcBuf { int a; }; + [[vk::location(7)]] float4 main([[vk::location(8)]] float4 input: A) : B { - return input + attach.Load(float2(0.5)); + return input + attach.Load(float2(0.5));// * a; } diff --git a/hlsl/hlslAttributes.cpp b/hlsl/hlslAttributes.cpp index a7840da14..2d204d315 100644 --- a/hlsl/hlslAttributes.cpp +++ b/hlsl/hlslAttributes.cpp @@ -62,6 +62,10 @@ namespace glslang { return EatGlobalBinding; else if (lowername == "builtin") return EatBuiltIn; + else if (lowername == "constant_id") + return EatConstantId; + else if (lowername == "push_constant") + return EatPushConstant; } else if (lowernameSpace.size() > 0) return EatNone; diff --git a/hlsl/hlslAttributes.h b/hlsl/hlslAttributes.h index 5210ca3b8..2c3cf76e6 100644 --- a/hlsl/hlslAttributes.h +++ b/hlsl/hlslAttributes.h @@ -67,7 +67,9 @@ namespace glslang { EatGlobalBinding, EatLocation, EatInputAttachment, - EatBuiltIn + EatBuiltIn, + EatPushConstant, + EatConstantId }; } diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index db7397cfd..c71ba165f 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -376,11 +376,9 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList) bool forbidDeclarators = (peekTokenClass(EHTokCBuffer) || peekTokenClass(EHTokTBuffer)); // fully_specified_type - if (! acceptFullySpecifiedType(declaredType, nodeList)) + if (! acceptFullySpecifiedType(declaredType, nodeList, declarator.attributes)) return false; - parseContext.transferTypeAttributes(declarator.attributes, declaredType); - // cbuffer and tbuffer end with the closing '}'. // No semicolon is included. if (forbidDeclarators) @@ -538,10 +536,11 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList) bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node) { node = nullptr; + TAttributeMap attributes; // fully_specified_type TType type; - if (! acceptFullySpecifiedType(type)) + if (! acceptFullySpecifiedType(type, attributes)) return false; // filter out type casts @@ -579,12 +578,12 @@ bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node) // : type_specifier // | type_qualifier type_specifier // -bool HlslGrammar::acceptFullySpecifiedType(TType& type) +bool HlslGrammar::acceptFullySpecifiedType(TType& type, const TAttributeMap& attributes) { TIntermNode* nodeList = nullptr; - return acceptFullySpecifiedType(type, nodeList); + return acceptFullySpecifiedType(type, nodeList, attributes); } -bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList) +bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList, const TAttributeMap& attributes) { // type_qualifier TQualifier qualifier; @@ -603,9 +602,14 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList) return false; } + if (type.getBasicType() == EbtBlock) { // the type was a block, which set some parts of the qualifier parseContext.mergeQualifiers(type.getQualifier(), qualifier); + + // merge in the attributes + parseContext.transferTypeAttributes(attributes, type); + // further, it can create an anonymous instance of the block if (peek() != EHTokIdentifier) parseContext.declareBlock(loc, type); @@ -626,7 +630,10 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList) if (type.isBuiltIn()) qualifier.builtIn = type.getQualifier().builtIn; - type.getQualifier() = qualifier; + type.getQualifier() = qualifier; + + // merge in the attributes + parseContext.transferTypeAttributes(attributes, type); } return true; @@ -2333,13 +2340,11 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode* // fully_specified_type TType memberType; - if (! acceptFullySpecifiedType(memberType, nodeList)) { + if (! acceptFullySpecifiedType(memberType, nodeList, attributes)) { expected("member type"); return false; } - parseContext.transferTypeAttributes(attributes, memberType); - // struct_declarator COMMA struct_declarator ... bool functionDefinitionAccepted = false; do { @@ -2540,11 +2545,9 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function) // fully_specified_type TType* type = new TType; - if (! acceptFullySpecifiedType(*type)) + if (! acceptFullySpecifiedType(*type, attributes)) return false; - parseContext.transferTypeAttributes(attributes, *type); - // identifier HlslToken idToken; acceptIdentifier(idToken); diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 9d5380c10..f5613d907 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -71,8 +71,8 @@ namespace glslang { bool acceptControlDeclaration(TIntermNode*& node); bool acceptSamplerDeclarationDX9(TType&); bool acceptSamplerState(); - bool acceptFullySpecifiedType(TType&); - bool acceptFullySpecifiedType(TType&, TIntermNode*& nodeList); + bool acceptFullySpecifiedType(TType&, const TAttributeMap&); + bool acceptFullySpecifiedType(TType&, TIntermNode*& nodeList, const TAttributeMap&); bool acceptQualifier(TQualifier&); bool acceptLayoutQualifierList(TQualifier&); bool acceptType(TType&); diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 7e401fd6f..ac72e2700 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1890,6 +1890,17 @@ void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, T if (builtInString == "PointSize") type.getQualifier().builtIn = EbvPointSize; } + + // push_constant + if (attributes.contains(EatPushConstant)) + type.getQualifier().layoutPushConstant = true; + + // specialization constant + if (attributes.getInt(EatConstantId, value)) { + TSourceLoc loc; + loc.init(); + setSpecConstantId(loc, type.getQualifier(), value); + } } // @@ -7041,15 +7052,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qua return; } if (id == "constant_id") { - requireSpv(loc, "constant_id"); - if (value >= (int)TQualifier::layoutSpecConstantIdEnd) { - error(loc, "specialization-constant id is too large", id.c_str(), ""); - } else { - qualifier.layoutSpecConstantId = value; - qualifier.specConstant = true; - if (! intermediate.addUsedConstantId(value)) - error(loc, "specialization-constant id already used", id.c_str(), ""); - } + setSpecConstantId(loc, qualifier, value); return; } @@ -7144,6 +7147,19 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qua error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), ""); } +void HlslParseContext::setSpecConstantId(const TSourceLoc& loc, TQualifier& qualifier, int value) +{ + if (value >= (int)TQualifier::layoutSpecConstantIdEnd) { + error(loc, "specialization-constant id is too large", "constant_id", ""); + } else { + qualifier.layoutSpecConstantId = value; + qualifier.specConstant = true; + if (! intermediate.addUsedConstantId(value)) + error(loc, "specialization-constant id already used", "constant_id", ""); + } + return; +} + // Merge any layout qualifier information from src into dst, leaving everything else in dst alone // // "More than one layout qualifier may appear in a single declaration. diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index a56fc2e41..833eb8e5b 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -138,6 +138,7 @@ public: void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&); void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&, const TIntermTyped*); + void setSpecConstantId(const TSourceLoc&, TQualifier&, int value); void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly); void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);