diff --git a/Test/baseResults/hlsl.constantbuffer.frag.out b/Test/baseResults/hlsl.constantbuffer.frag.out new file mode 100644 index 00000000..2c7dafe8 --- /dev/null +++ b/Test/baseResults/hlsl.constantbuffer.frag.out @@ -0,0 +1,241 @@ +hlsl.constantbuffer.frag +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:20 Function Definition: @main( ( temp 4-component vector of float) +0:20 Function Parameters: +0:? Sequence +0:21 Test condition and select ( temp void) +0:21 Condition +0:21 x: direct index for structure (layout( row_major std140) uniform bool) +0:21 direct index (layout( row_major std140) temp block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:21 direct index (layout( row_major std140) temp 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:21 'cb3' (layout( row_major std140) uniform 2-element array of 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:21 Constant: +0:21 1 (const int) +0:21 Constant: +0:21 2 (const int) +0:21 Constant: +0:21 0 (const int) +0:21 true case +0:22 Branch: Return with expression +0:22 add ( temp 4-component vector of float) +0:22 add ( temp 4-component vector of float) +0:22 x: direct index for structure (layout( row_major std140) uniform 4-component vector of float) +0:22 'cb1' (layout( binding=12 row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float x}) +0:22 Constant: +0:22 0 (const int) +0:22 y: direct index for structure (layout( row_major std140) uniform float) +0:22 direct index (layout( row_major std140) temp block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:22 'cb2' (layout( row_major std140) uniform 3-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:22 Constant: +0:22 1 (const int) +0:22 Constant: +0:22 1 (const int) +0:22 Convert int to float ( temp float) +0:22 c1: direct index for structure (layout( row_major std140) uniform int) +0:22 'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform int c1}) +0:22 Constant: +0:22 0 (const uint) +0:21 false case +0:24 Branch: Return with expression +0:24 Construct vec4 ( temp 4-component vector of float) +0:24 y: direct index for structure (layout( row_major std140) uniform float) +0:24 direct index (layout( row_major std140) temp block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:24 direct index (layout( row_major std140) temp 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:24 'cb3' (layout( row_major std140) uniform 2-element array of 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:24 Constant: +0:24 2 (const int) +0:24 Constant: +0:24 3 (const int) +0:24 Constant: +0:24 1 (const int) +0:20 Function Definition: main( ( temp void) +0:20 Function Parameters: +0:? Sequence +0:20 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:20 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? 'cb1' (layout( binding=12 row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float x}) +0:? 'cb2' (layout( row_major std140) uniform 3-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:? 'cb3' (layout( row_major std140) uniform 2-element array of 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:? 'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform int c1}) +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:20 Function Definition: @main( ( temp 4-component vector of float) +0:20 Function Parameters: +0:? Sequence +0:21 Test condition and select ( temp void) +0:21 Condition +0:21 x: direct index for structure (layout( row_major std140) uniform bool) +0:21 direct index (layout( row_major std140) temp block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:21 direct index (layout( row_major std140) temp 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:21 'cb3' (layout( row_major std140) uniform 2-element array of 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:21 Constant: +0:21 1 (const int) +0:21 Constant: +0:21 2 (const int) +0:21 Constant: +0:21 0 (const int) +0:21 true case +0:22 Branch: Return with expression +0:22 add ( temp 4-component vector of float) +0:22 add ( temp 4-component vector of float) +0:22 x: direct index for structure (layout( row_major std140) uniform 4-component vector of float) +0:22 'cb1' (layout( binding=12 row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float x}) +0:22 Constant: +0:22 0 (const int) +0:22 y: direct index for structure (layout( row_major std140) uniform float) +0:22 direct index (layout( row_major std140) temp block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:22 'cb2' (layout( row_major std140) uniform 3-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:22 Constant: +0:22 1 (const int) +0:22 Constant: +0:22 1 (const int) +0:22 Convert int to float ( temp float) +0:22 c1: direct index for structure (layout( row_major std140) uniform int) +0:22 'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform int c1}) +0:22 Constant: +0:22 0 (const uint) +0:21 false case +0:24 Branch: Return with expression +0:24 Construct vec4 ( temp 4-component vector of float) +0:24 y: direct index for structure (layout( row_major std140) uniform float) +0:24 direct index (layout( row_major std140) temp block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:24 direct index (layout( row_major std140) temp 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:24 'cb3' (layout( row_major std140) uniform 2-element array of 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:24 Constant: +0:24 2 (const int) +0:24 Constant: +0:24 3 (const int) +0:24 Constant: +0:24 1 (const int) +0:20 Function Definition: main( ( temp void) +0:20 Function Parameters: +0:? Sequence +0:20 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:20 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? 'cb1' (layout( binding=12 row_major std140) uniform block{layout( row_major std140) uniform 4-component vector of float x}) +0:? 'cb2' (layout( row_major std140) uniform 3-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:? 'cb3' (layout( row_major std140) uniform 2-element array of 4-element array of block{layout( row_major std140) uniform bool x, layout( row_major std140) uniform float y}) +0:? 'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform int c1}) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 66 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 64 + ExecutionMode 4 OriginUpperLeft + Source HLSL 500 + Name 4 "main" + Name 9 "@main(" + Name 12 "cb3" + MemberName 12(cb3) 0 "x" + MemberName 12(cb3) 1 "y" + Name 18 "cb3" + Name 31 "cb1" + MemberName 31(cb1) 0 "x" + Name 33 "cb1" + Name 40 "cb2" + Name 46 "cbuff" + MemberName 46(cbuff) 0 "c1" + Name 48 "" + Name 64 "@entryPointOutput" + MemberDecorate 12(cb3) 0 Offset 0 + MemberDecorate 12(cb3) 1 Offset 4 + Decorate 12(cb3) Block + Decorate 18(cb3) DescriptorSet 0 + MemberDecorate 31(cb1) 0 Offset 0 + Decorate 31(cb1) Block + Decorate 33(cb1) DescriptorSet 0 + Decorate 33(cb1) Binding 12 + Decorate 40(cb2) DescriptorSet 0 + MemberDecorate 46(cbuff) 0 Offset 0 + Decorate 46(cbuff) Block + Decorate 48 DescriptorSet 0 + Decorate 64(@entryPointOutput) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeFunction 7(fvec4) + 11: TypeInt 32 0 + 12(cb3): TypeStruct 11(int) 6(float) + 13: 11(int) Constant 4 + 14: TypeArray 12(cb3) 13 + 15: 11(int) Constant 2 + 16: TypeArray 14 15 + 17: TypePointer Uniform 16 + 18(cb3): 17(ptr) Variable Uniform + 19: TypeInt 32 1 + 20: 19(int) Constant 1 + 21: 19(int) Constant 2 + 22: 19(int) Constant 0 + 23: TypePointer Uniform 11(int) + 26: TypeBool + 27: 11(int) Constant 0 + 31(cb1): TypeStruct 7(fvec4) + 32: TypePointer Uniform 31(cb1) + 33(cb1): 32(ptr) Variable Uniform + 34: TypePointer Uniform 7(fvec4) + 37: 11(int) Constant 3 + 38: TypeArray 12(cb3) 37 + 39: TypePointer Uniform 38 + 40(cb2): 39(ptr) Variable Uniform + 41: TypePointer Uniform 6(float) + 46(cbuff): TypeStruct 19(int) + 47: TypePointer Uniform 46(cbuff) + 48: 47(ptr) Variable Uniform + 49: TypePointer Uniform 19(int) + 57: 19(int) Constant 3 + 63: TypePointer Output 7(fvec4) +64(@entryPointOutput): 63(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 65: 7(fvec4) FunctionCall 9(@main() + Store 64(@entryPointOutput) 65 + Return + FunctionEnd + 9(@main(): 7(fvec4) Function None 8 + 10: Label + 24: 23(ptr) AccessChain 18(cb3) 20 21 22 + 25: 11(int) Load 24 + 28: 26(bool) INotEqual 25 27 + SelectionMerge 30 None + BranchConditional 28 29 56 + 29: Label + 35: 34(ptr) AccessChain 33(cb1) 22 + 36: 7(fvec4) Load 35 + 42: 41(ptr) AccessChain 40(cb2) 20 20 + 43: 6(float) Load 42 + 44: 7(fvec4) CompositeConstruct 43 43 43 43 + 45: 7(fvec4) FAdd 36 44 + 50: 49(ptr) AccessChain 48 22 + 51: 19(int) Load 50 + 52: 6(float) ConvertSToF 51 + 53: 7(fvec4) CompositeConstruct 52 52 52 52 + 54: 7(fvec4) FAdd 45 53 + ReturnValue 54 + 56: Label + 58: 41(ptr) AccessChain 18(cb3) 21 57 20 + 59: 6(float) Load 58 + 60: 7(fvec4) CompositeConstruct 59 59 59 59 + ReturnValue 60 + 30: Label + 62: 7(fvec4) Undef + ReturnValue 62 + FunctionEnd diff --git a/Test/hlsl.constantbuffer.frag b/Test/hlsl.constantbuffer.frag new file mode 100644 index 00000000..d7a6ef52 --- /dev/null +++ b/Test/hlsl.constantbuffer.frag @@ -0,0 +1,26 @@ + +struct c1_t { + float4 x; +}; + +struct c2_t { + bool x; + float y; +}; + +ConstantBuffer cb1 : register(b12); +ConstantBuffer cb2[3]; +ConstantBuffer cb3[2][4]; + +cbuffer cbuff { + int c1; +}; + +float4 main() : SV_Target0 +{ + if (cb3[1][2].x) + return cb1.x + cb2[1].y + c1; + else + return cb3[2][3].y; +} + diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index 920ed0cb..8b80cbed 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -532,6 +532,7 @@ u – for unordered access views (UAV) b – for constant buffer views (CBV) CBUFFER + CONSTANTBUFFER ********************************************************************************/ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase { diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index b23674ea..5dcc095b 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -98,6 +98,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.clip.frag", "main"}, {"hlsl.comparison.vec.frag", "main"}, {"hlsl.conditional.frag", "PixelShaderFunction"}, + {"hlsl.constantbuffer.frag", "main"}, {"hlsl.constructexpr.frag", "main"}, {"hlsl.depthGreater.frag", "PixelShaderFunction"}, {"hlsl.depthLess.frag", "PixelShaderFunction"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 63b78bf3..a9743c21 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -476,7 +476,8 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList) if (typedefDecl) parseContext.declareTypedef(idToken.loc, *fullName, variableType); else if (variableType.getBasicType() == EbtBlock) { - parseContext.declareBlock(idToken.loc, variableType, fullName); + parseContext.declareBlock(idToken.loc, variableType, fullName, + variableType.isArray() ? &variableType.getArraySizes() : nullptr); parseContext.declareStructBufferCounter(idToken.loc, variableType, *fullName); } else { if (variableType.getQualifier().storage == EvqUniform && ! variableType.containsOpaque()) { @@ -1364,6 +1365,9 @@ bool HlslGrammar::acceptType(TType& type, TIntermNode*& nodeList) return acceptStructBufferType(type); break; + case EHTokConstantBuffer: + return acceptConstantBufferType(type); + case EHTokClass: case EHTokStruct: case EHTokCBuffer: @@ -1944,6 +1948,47 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList) return deferredSuccess; } +// constantbuffer +// : CONSTANTBUFFER LEFT_ANGLE type RIGHT_ANGLE +bool HlslGrammar::acceptConstantBufferType(TType& type) +{ + if (! acceptTokenClass(EHTokConstantBuffer)) + return false; + + if (! acceptTokenClass(EHTokLeftAngle)) { + expected("left angle bracket"); + return false; + } + + TType templateType; + if (! acceptType(templateType)) { + expected("type"); + return false; + } + + if (! acceptTokenClass(EHTokRightAngle)) { + expected("right angle bracket"); + return false; + } + + TQualifier postDeclQualifier; + postDeclQualifier.clear(); + postDeclQualifier.storage = EvqUniform; + + if (templateType.isStruct()) { + // Make a block from the type parsed as the template argument + TTypeList* typeList = templateType.getWritableStruct(); + new(&type) TType(typeList, "", postDeclQualifier); // sets EbtBlock + + type.getQualifier().storage = EvqUniform; + + return true; + } else { + parseContext.error(token.loc, "non-structure type in ConstantBuffer", "", ""); + return false; + } +} + // struct_buffer // : APPENDSTRUCTUREDBUFFER // | BYTEADDRESSBUFFER diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 6d8ed8fd..f1ff1c68 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -87,6 +87,7 @@ namespace glslang { bool acceptSamplerType(TType&); bool acceptTextureType(TType&); bool acceptStructBufferType(TType&); + bool acceptConstantBufferType(TType&); bool acceptStruct(TType&, TIntermNode*& nodeList); bool acceptStructDeclarationList(TTypeList*&, TIntermNode*& nodeList, TVector&); bool acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType&, const TString& memberName, diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp index 55304a09..0eb5bf57 100755 --- a/hlsl/hlslScanContext.cpp +++ b/hlsl/hlslScanContext.cpp @@ -331,6 +331,7 @@ void HlslScanContext::fillInKeywordMap() (*KeywordMap)["class"] = EHTokClass; (*KeywordMap)["struct"] = EHTokStruct; (*KeywordMap)["cbuffer"] = EHTokCBuffer; + (*KeywordMap)["ConstantBuffer"] = EHTokConstantBuffer; (*KeywordMap)["tbuffer"] = EHTokTBuffer; (*KeywordMap)["typedef"] = EHTokTypedef; (*KeywordMap)["this"] = EHTokThis; @@ -827,6 +828,7 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier() case EHTokStruct: case EHTokTypedef: case EHTokCBuffer: + case EHTokConstantBuffer: case EHTokTBuffer: case EHTokThis: case EHTokNamespace: diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h index cba0b965..f6a2c969 100755 --- a/hlsl/hlslTokens.h +++ b/hlsl/hlslTokens.h @@ -275,6 +275,7 @@ enum EHlslTokenClass { EHTokTypedef, EHTokThis, EHTokNamespace, + EHTokConstantBuffer, // constant EHTokFloatConstant,