diff --git a/Test/baseResults/hlsl.attributeGlobalBuffer.frag.out b/Test/baseResults/hlsl.attributeGlobalBuffer.frag.out new file mode 100755 index 000000000..e00ae5282 --- /dev/null +++ b/Test/baseResults/hlsl.attributeGlobalBuffer.frag.out @@ -0,0 +1,109 @@ +hlsl.attributeGlobalBuffer.frag +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:6 Function Definition: @main( ( temp 4-component vector of float) +0:6 Function Parameters: +0:? Sequence +0:7 Branch: Return with expression +0:7 add ( temp 4-component vector of float) +0:7 u1: direct index for structure ( uniform 4-component vector of float) +0:7 'anon@0' (layout( set=2 binding=5 row_major std140) uniform block{ uniform 4-component vector of float u1, uniform 4-component vector of float u2}) +0:7 Constant: +0:7 0 (const uint) +0:7 u2: direct index for structure ( uniform 4-component vector of float) +0:7 'anon@0' (layout( set=2 binding=5 row_major std140) uniform block{ uniform 4-component vector of float u1, uniform 4-component vector of float u2}) +0:7 Constant: +0:7 1 (const uint) +0:6 Function Definition: main( ( temp void) +0:6 Function Parameters: +0:? Sequence +0:6 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:6 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( set=2 binding=5 row_major std140) uniform block{ uniform 4-component vector of float u1, uniform 4-component vector of float u2}) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + + +Linked fragment stage: + + +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:6 Function Definition: @main( ( temp 4-component vector of float) +0:6 Function Parameters: +0:? Sequence +0:7 Branch: Return with expression +0:7 add ( temp 4-component vector of float) +0:7 u1: direct index for structure ( uniform 4-component vector of float) +0:7 'anon@0' (layout( set=2 binding=5 row_major std140) uniform block{ uniform 4-component vector of float u1, uniform 4-component vector of float u2}) +0:7 Constant: +0:7 0 (const uint) +0:7 u2: direct index for structure ( uniform 4-component vector of float) +0:7 'anon@0' (layout( set=2 binding=5 row_major std140) uniform block{ uniform 4-component vector of float u1, uniform 4-component vector of float u2}) +0:7 Constant: +0:7 1 (const uint) +0:6 Function Definition: main( ( temp void) +0:6 Function Parameters: +0:? Sequence +0:6 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:6 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( set=2 binding=5 row_major std140) uniform block{ uniform 4-component vector of float u1, uniform 4-component vector of float u2}) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + +// Module Version 10000 +// Generated by (magic number): 80002 +// Id's are bound by 28 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 26 + ExecutionMode 4 OriginUpperLeft + Source HLSL 500 + Name 4 "main" + Name 9 "@main(" + Name 11 "$Global" + MemberName 11($Global) 0 "u1" + MemberName 11($Global) 1 "u2" + Name 13 "" + Name 26 "@entryPointOutput" + MemberDecorate 11($Global) 0 Offset 0 + MemberDecorate 11($Global) 1 Offset 16 + Decorate 11($Global) Block + Decorate 13 DescriptorSet 2 + Decorate 13 Binding 5 + Decorate 26(@entryPointOutput) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeFunction 7(fvec4) + 11($Global): TypeStruct 7(fvec4) 7(fvec4) + 12: TypePointer Uniform 11($Global) + 13: 12(ptr) Variable Uniform + 14: TypeInt 32 1 + 15: 14(int) Constant 0 + 16: TypePointer Uniform 7(fvec4) + 19: 14(int) Constant 1 + 25: TypePointer Output 7(fvec4) +26(@entryPointOutput): 25(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 27: 7(fvec4) FunctionCall 9(@main() + Store 26(@entryPointOutput) 27 + Return + FunctionEnd + 9(@main(): 7(fvec4) Function None 8 + 10: Label + 17: 16(ptr) AccessChain 13 15 + 18: 7(fvec4) Load 17 + 20: 16(ptr) AccessChain 13 19 + 21: 7(fvec4) Load 20 + 22: 7(fvec4) FAdd 18 21 + ReturnValue 22 + FunctionEnd diff --git a/Test/hlsl.attributeGlobalBuffer.frag b/Test/hlsl.attributeGlobalBuffer.frag new file mode 100644 index 000000000..a1177dab2 --- /dev/null +++ b/Test/hlsl.attributeGlobalBuffer.frag @@ -0,0 +1,8 @@ +[[vk::global_cbuffer_binding(5, 2)]] +float4 u1; +float4 u2; + +float4 main() : SV_Target0 +{ + return u1 + u2; +} \ No newline at end of file diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index 447c038f3..bbc3cac08 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -569,6 +569,10 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem firstNewMember = 0; } + // Update with binding and set + globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding; + globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet; + // Add the requested member as a member to the global block. TType* type = new TType; type->shallowCopy(memberType); diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 2a054c1c1..62b1e8e08 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -84,7 +84,9 @@ public: contextPragma(true, false), parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr), limits(resources.limits), - globalUniformBlock(nullptr) + globalUniformBlock(nullptr), + globalUniformBinding(TQualifier::layoutBindingEnd), + globalUniformSet(TQualifier::layoutSetEnd) { if (entryPoint != nullptr) sourceEntryPointName = *entryPoint; @@ -209,6 +211,8 @@ protected: // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) TVariable* globalUniformBlock; // the actual block, inserted into the symbol table + unsigned int globalUniformBinding; + unsigned int globalUniformSet; int firstNewMember; // the index of the first member not yet inserted into the symbol table // override this to set the language-specific name virtual const char* getGlobalUniformBlockName() const { return ""; } diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index ca5fb3b0f..9d97fdf09 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -100,6 +100,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.attribute.frag", "PixelShaderFunction"}, {"hlsl.attribute.expression.comp", "main"}, {"hlsl.attributeC11.frag", "main"}, + {"hlsl.attributeGlobalBuffer.frag", "main"}, {"hlsl.basic.comp", "main"}, {"hlsl.basic.geom", "main"}, {"hlsl.boolConv.vert", "main"}, diff --git a/hlsl/hlslAttributes.cpp b/hlsl/hlslAttributes.cpp index 2a8e37028..fccf6c187 100644 --- a/hlsl/hlslAttributes.cpp +++ b/hlsl/hlslAttributes.cpp @@ -58,6 +58,8 @@ namespace glslang { return EatLocation; else if (lowername == "binding") return EatBinding; + else if (lowername == "global_cbuffer_binding") + return EatGlobalBinding; } else if (lowernameSpace.size() > 0) return EatNone; diff --git a/hlsl/hlslAttributes.h b/hlsl/hlslAttributes.h index 2d7b6c7a5..1fdb4ba04 100644 --- a/hlsl/hlslAttributes.h +++ b/hlsl/hlslAttributes.h @@ -64,6 +64,7 @@ namespace glslang { EatUnroll, EatLoop, EatBinding, + EatGlobalBinding, EatLocation, EatInputAttachment }; diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 3352276a3..b3fc1165a 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1869,6 +1869,14 @@ void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, T if (attributes.getInt(EatBinding, value, 1)) type.getQualifier().layoutSet = value; + // global cbuffer binding + if (attributes.getInt(EatGlobalBinding, value)) + globalUniformBinding = value; + + // global cbuffer binding + if (attributes.getInt(EatGlobalBinding, value, 1)) + globalUniformSet = value; + // input attachment if (attributes.getInt(EatInputAttachment, value)) type.getQualifier().layoutAttachment = value; diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 669c1ec0d..c1752f129 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -187,7 +187,8 @@ public: void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); } void popSwitchSequence() { switchSequenceStack.pop_back(); } - virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override; + virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, + TTypeList* typeList = nullptr) override; // Apply L-value conversions. E.g, turning a write to a RWTexture into an ImageStore. TIntermTyped* handleLvalue(const TSourceLoc&, const char* op, TIntermTyped*& node);