diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 0b48dfcd..b15a19f0 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2248,8 +2248,10 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix)); addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember)); // Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes - if (type.getQualifier().storage == glslang::EvqVaryingIn || type.getQualifier().storage == glslang::EvqVaryingOut) { - if (type.getBasicType() == glslang::EbtBlock) { + if (type.getQualifier().storage == glslang::EvqVaryingIn || + type.getQualifier().storage == glslang::EvqVaryingOut) { + if (type.getBasicType() == glslang::EbtBlock || + glslangIntermediate->getSource() == glslang::EShSourceHlsl) { addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier)); addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier)); } diff --git a/Test/baseResults/hlsl.struct.frag.out b/Test/baseResults/hlsl.struct.frag.out index c9161d04..8b19c025 100755 --- a/Test/baseResults/hlsl.struct.frag.out +++ b/Test/baseResults/hlsl.struct.frag.out @@ -284,6 +284,10 @@ gl_FragCoord origin is upper left MemberName 94($Global) 2 "ff6" Name 96 "" Decorate 43(input) Location 0 + MemberDecorate 46(IN_S) 1 Flat + MemberDecorate 46(IN_S) 2 NoPerspective + MemberDecorate 46(IN_S) 2 Centroid + MemberDecorate 46(IN_S) 3 Centroid Decorate 48(s) Location 1 Decorate 71(s_ff1) BuiltIn FrontFacing Decorate 86(@entryPointOutput) Location 0 diff --git a/Test/baseResults/hlsl.structIoFourWay.frag.out b/Test/baseResults/hlsl.structIoFourWay.frag.out new file mode 100755 index 00000000..8b6d75af --- /dev/null +++ b/Test/baseResults/hlsl.structIoFourWay.frag.out @@ -0,0 +1,255 @@ +hlsl.structIoFourWay.frag +Shader version: 450 +gl_FragCoord origin is upper left +using depth_greater +0:? Sequence +0:15 Function Definition: @main(struct-T-f1-f1-f1-vf41; (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Function Parameters: +0:15 't' (in structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:? Sequence +0:17 Branch: Return with expression +0:17 'local' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Function Definition: main( (temp void) +0:15 Function Parameters: +0:? Sequence +0:15 move second child to first child (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:? 't' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:? 't' (layout(location=0 ) in structure{temp float f, centroid temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Sequence +0:15 move second child to first child (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Function Call: @main(struct-T-f1-f1-f1-vf41; (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:? 't' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 move second child to first child (temp float) +0:? 'f' (layout(location=0 ) out float) +0:15 f: direct index for structure (temp float) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Constant: +0:15 0 (const int) +0:15 move second child to first child (temp float) +0:? 'g' (layout(location=1 ) out float) +0:15 g: direct index for structure (temp float) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Constant: +0:15 1 (const int) +0:15 move second child to first child (temp float) +0:? 'd' (out float FragDepth) +0:15 d: direct index for structure (temp float) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Constant: +0:15 2 (const int) +0:15 move second child to first child (temp 4-component vector of float) +0:? 'normal' (layout(location=2 ) out 4-component vector of float) +0:15 normal: direct index for structure (temp 4-component vector of float) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Constant: +0:15 3 (const int) +0:? Linker Objects +0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=88 ) uniform structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal} t}) +0:? 'f' (layout(location=0 ) out float) +0:? 'g' (layout(location=1 ) out float) +0:? 'd' (out float FragDepth) +0:? 'normal' (layout(location=2 ) out 4-component vector of float) +0:? 't' (layout(location=0 ) in structure{temp float f, centroid temp float g, temp float d, temp 4-component vector of float normal}) +0:? 'anon@1' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform structure{layout(offset=68 ) temp float f, temp float g, temp float d, temp 4-component vector of float normal} s}) + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +using depth_greater +0:? Sequence +0:15 Function Definition: @main(struct-T-f1-f1-f1-vf41; (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Function Parameters: +0:15 't' (in structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:? Sequence +0:17 Branch: Return with expression +0:17 'local' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Function Definition: main( (temp void) +0:15 Function Parameters: +0:? Sequence +0:15 move second child to first child (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:? 't' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:? 't' (layout(location=0 ) in structure{temp float f, centroid temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Sequence +0:15 move second child to first child (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Function Call: @main(struct-T-f1-f1-f1-vf41; (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:? 't' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 move second child to first child (temp float) +0:? 'f' (layout(location=0 ) out float) +0:15 f: direct index for structure (temp float) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Constant: +0:15 0 (const int) +0:15 move second child to first child (temp float) +0:? 'g' (layout(location=1 ) out float) +0:15 g: direct index for structure (temp float) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Constant: +0:15 1 (const int) +0:15 move second child to first child (temp float) +0:? 'd' (out float FragDepth) +0:15 d: direct index for structure (temp float) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Constant: +0:15 2 (const int) +0:15 move second child to first child (temp 4-component vector of float) +0:? 'normal' (layout(location=2 ) out 4-component vector of float) +0:15 normal: direct index for structure (temp 4-component vector of float) +0:15 'flattenTemp' (temp structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal}) +0:15 Constant: +0:15 3 (const int) +0:? Linker Objects +0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=88 ) uniform structure{temp float f, temp float g, temp float d, temp 4-component vector of float normal} t}) +0:? 'f' (layout(location=0 ) out float) +0:? 'g' (layout(location=1 ) out float) +0:? 'd' (out float FragDepth) +0:? 'normal' (layout(location=2 ) out 4-component vector of float) +0:? 't' (layout(location=0 ) in structure{temp float f, centroid temp float g, temp float d, temp 4-component vector of float normal}) +0:? 'anon@1' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform structure{layout(offset=68 ) temp float f, temp float g, temp float d, temp 4-component vector of float normal} s}) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 64 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 21 43 46 49 53 + ExecutionMode 4 OriginUpperLeft + ExecutionMode 4 DepthGreater + Name 4 "main" + Name 8 "T" + MemberName 8(T) 0 "f" + MemberName 8(T) 1 "g" + MemberName 8(T) 2 "d" + MemberName 8(T) 3 "normal" + Name 12 "@main(struct-T-f1-f1-f1-vf41;" + Name 11 "t" + Name 14 "local" + Name 18 "t" + Name 19 "T" + MemberName 19(T) 0 "f" + MemberName 19(T) 1 "g" + MemberName 19(T) 2 "d" + MemberName 19(T) 3 "normal" + Name 21 "t" + Name 38 "flattenTemp" + Name 39 "param" + Name 43 "f" + Name 46 "g" + Name 49 "d" + Name 53 "normal" + Name 56 "T" + MemberName 56(T) 0 "f" + MemberName 56(T) 1 "g" + MemberName 56(T) 2 "d" + MemberName 56(T) 3 "normal" + Name 57 "buff" + MemberName 57(buff) 0 "t" + Name 59 "" + Name 60 "T" + MemberName 60(T) 0 "f" + MemberName 60(T) 1 "g" + MemberName 60(T) 2 "d" + MemberName 60(T) 3 "normal" + Name 61 "$Global" + MemberName 61($Global) 0 "s" + Name 63 "" + MemberDecorate 19(T) 1 Centroid + Decorate 21(t) Location 0 + Decorate 43(f) Location 0 + Decorate 46(g) Location 1 + Decorate 49(d) BuiltIn FragDepth + Decorate 53(normal) Location 2 + MemberDecorate 56(T) 0 Offset 0 + MemberDecorate 56(T) 1 Offset 4 + MemberDecorate 56(T) 2 Offset 8 + MemberDecorate 56(T) 3 Offset 16 + MemberDecorate 57(buff) 0 Offset 96 + Decorate 57(buff) Block + Decorate 59 DescriptorSet 0 + MemberDecorate 60(T) 0 Offset 68 + MemberDecorate 60(T) 1 Offset 72 + MemberDecorate 60(T) 2 Offset 76 + MemberDecorate 60(T) 3 Offset 80 + MemberDecorate 61($Global) 0 Offset 0 + Decorate 61($Global) Block + Decorate 63 DescriptorSet 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8(T): TypeStruct 6(float) 6(float) 6(float) 7(fvec4) + 9: TypePointer Function 8(T) + 10: TypeFunction 8(T) 9(ptr) + 19(T): TypeStruct 6(float) 6(float) 6(float) 7(fvec4) + 20: TypePointer Input 19(T) + 21(t): 20(ptr) Variable Input + 24: TypeInt 32 1 + 25: 24(int) Constant 0 + 26: TypePointer Function 6(float) + 29: 24(int) Constant 1 + 32: 24(int) Constant 2 + 35: 24(int) Constant 3 + 36: TypePointer Function 7(fvec4) + 42: TypePointer Output 6(float) + 43(f): 42(ptr) Variable Output + 46(g): 42(ptr) Variable Output + 49(d): 42(ptr) Variable Output + 52: TypePointer Output 7(fvec4) + 53(normal): 52(ptr) Variable Output + 56(T): TypeStruct 6(float) 6(float) 6(float) 7(fvec4) + 57(buff): TypeStruct 56(T) + 58: TypePointer Uniform 57(buff) + 59: 58(ptr) Variable Uniform + 60(T): TypeStruct 6(float) 6(float) 6(float) 7(fvec4) + 61($Global): TypeStruct 60(T) + 62: TypePointer Uniform 61($Global) + 63: 62(ptr) Variable Uniform + 4(main): 2 Function None 3 + 5: Label + 18(t): 9(ptr) Variable Function + 38(flattenTemp): 9(ptr) Variable Function + 39(param): 9(ptr) Variable Function + 22: 19(T) Load 21(t) + 23: 6(float) CompositeExtract 22 0 + 27: 26(ptr) AccessChain 18(t) 25 + Store 27 23 + 28: 6(float) CompositeExtract 22 1 + 30: 26(ptr) AccessChain 18(t) 29 + Store 30 28 + 31: 6(float) CompositeExtract 22 2 + 33: 26(ptr) AccessChain 18(t) 32 + Store 33 31 + 34: 7(fvec4) CompositeExtract 22 3 + 37: 36(ptr) AccessChain 18(t) 35 + Store 37 34 + 40: 8(T) Load 18(t) + Store 39(param) 40 + 41: 8(T) FunctionCall 12(@main(struct-T-f1-f1-f1-vf41;) 39(param) + Store 38(flattenTemp) 41 + 44: 26(ptr) AccessChain 38(flattenTemp) 25 + 45: 6(float) Load 44 + Store 43(f) 45 + 47: 26(ptr) AccessChain 38(flattenTemp) 29 + 48: 6(float) Load 47 + Store 46(g) 48 + 50: 26(ptr) AccessChain 38(flattenTemp) 32 + 51: 6(float) Load 50 + Store 49(d) 51 + 54: 36(ptr) AccessChain 38(flattenTemp) 35 + 55: 7(fvec4) Load 54 + Store 53(normal) 55 + Return + FunctionEnd +12(@main(struct-T-f1-f1-f1-vf41;): 8(T) Function None 10 + 11(t): 9(ptr) FunctionParameter + 13: Label + 14(local): 9(ptr) Variable Function + 15: 8(T) Load 14(local) + ReturnValue 15 + FunctionEnd diff --git a/Test/baseResults/hlsl.structin.vert.out b/Test/baseResults/hlsl.structin.vert.out index 50e4b9c6..e64202fb 100755 --- a/Test/baseResults/hlsl.structin.vert.out +++ b/Test/baseResults/hlsl.structin.vert.out @@ -92,7 +92,7 @@ Shader version: 450 0:? 'e' (temp 4-component vector of float) 0:8 move second child to first child (temp 2-element array of 4-component vector of float) 0:8 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) +0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:8 Constant: 0:8 0 (const int) 0:8 m: direct index for structure (temp 2-element array of 4-component vector of float) @@ -101,7 +101,7 @@ Shader version: 450 0:8 0 (const int) 0:8 move second child to first child (temp 2-component vector of uint) 0:8 coord: direct index for structure (temp 2-component vector of uint) -0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) +0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:8 Constant: 0:8 1 (const int) 0:8 coord: direct index for structure (temp 2-component vector of uint) @@ -109,8 +109,8 @@ Shader version: 450 0:8 Constant: 0:8 1 (const int) 0:8 move second child to first child (temp 4-component vector of float) -0:8 b: direct index for structure (smooth temp 4-component vector of float) -0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) +0:8 b: direct index for structure (temp 4-component vector of float) +0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:8 Constant: 0:8 2 (const int) 0:8 b: direct index for structure (temp 4-component vector of float) @@ -118,7 +118,7 @@ Shader version: 450 0:8 Constant: 0:8 2 (const int) 0:? Linker Objects -0:? '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) +0:? '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:? 'd' (layout(location=0 ) in 4-component vector of float) 0:? 'm[0]' (layout(location=1 ) in 4-component vector of float) 0:? 'm[1]' (layout(location=2 ) in 4-component vector of float) @@ -225,7 +225,7 @@ Shader version: 450 0:? 'e' (temp 4-component vector of float) 0:8 move second child to first child (temp 2-element array of 4-component vector of float) 0:8 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) +0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:8 Constant: 0:8 0 (const int) 0:8 m: direct index for structure (temp 2-element array of 4-component vector of float) @@ -234,7 +234,7 @@ Shader version: 450 0:8 0 (const int) 0:8 move second child to first child (temp 2-component vector of uint) 0:8 coord: direct index for structure (temp 2-component vector of uint) -0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) +0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:8 Constant: 0:8 1 (const int) 0:8 coord: direct index for structure (temp 2-component vector of uint) @@ -242,8 +242,8 @@ Shader version: 450 0:8 Constant: 0:8 1 (const int) 0:8 move second child to first child (temp 4-component vector of float) -0:8 b: direct index for structure (smooth temp 4-component vector of float) -0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) +0:8 b: direct index for structure (temp 4-component vector of float) +0:8 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:8 Constant: 0:8 2 (const int) 0:8 b: direct index for structure (temp 4-component vector of float) @@ -251,7 +251,7 @@ Shader version: 450 0:8 Constant: 0:8 2 (const int) 0:? Linker Objects -0:? '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) +0:? '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:? 'd' (layout(location=0 ) in 4-component vector of float) 0:? 'm[0]' (layout(location=1 ) in 4-component vector of float) 0:? 'm[1]' (layout(location=2 ) in 4-component vector of float) diff --git a/Test/hlsl.structIoFourWay.frag b/Test/hlsl.structIoFourWay.frag new file mode 100755 index 00000000..bca135e7 --- /dev/null +++ b/Test/hlsl.structIoFourWay.frag @@ -0,0 +1,18 @@ +struct T { + float f : packoffset(c4.y); // artificial, but validates all different treatments: uniform offset + centroid float g; // interpolant input + float d: SV_DepthGreaterEqual; // fragment output + float4 normal; // non-IO +}; + +T s; // loose uniform + +cbuffer buff { + T t : packoffset(c5.z); +}; + +T main(T t : myInput) : SV_Target0 +{ + T local; + return local; +} diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index a1ba5423..605f5f16 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -410,6 +410,13 @@ public: } void clearInterstage() + { + clearInterpolation(); + patch = false; + sample = false; + } + + void clearInterpolation() { centroid = false; smooth = false; @@ -418,8 +425,6 @@ public: #ifdef AMD_EXTENSIONS explicitInterp = false; #endif - patch = false; - sample = false; } void clearMemory() diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index a46f0451..e67629f8 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "Overload400-PrecQual.1791" -#define GLSLANG_DATE "05-Feb-2017" +#define GLSLANG_REVISION "Overload400-PrecQual.1792" +#define GLSLANG_DATE "06-Feb-2017" diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index 2f5401c1..946eb715 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -530,7 +530,7 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin // Make the passed-in variable information become a member of the // global uniform block. If this doesn't exist yet, make it. // -void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberType, TString& memberName) +void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberType, TString& memberName, TTypeList* typeList) { // make the global block, if not yet made if (globalUniformBlock == nullptr) { @@ -548,6 +548,8 @@ void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberTyp TType* type = new TType; type->shallowCopy(memberType); type->setFieldName(memberName); + if (typeList) + type->setStruct(typeList); TTypeLoc typeLoc = {type, loc}; globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc); } diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index e77089aa..ff4a3945 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -139,7 +139,7 @@ public: // TODO: This could perhaps get its own object, but the current design doesn't work // yet when new uniform variables are declared between function definitions, so // this is pending getting a fully functional design. - virtual void growGlobalUniformBlock(TSourceLoc&, TType&, TString& memberName); + virtual void growGlobalUniformBlock(TSourceLoc&, TType&, TString& memberName, TTypeList* typeList = nullptr); virtual bool insertGlobalUniformBlock(); virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*); diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 74a4f5d2..701863ac 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -219,6 +219,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.structarray.flatten.frag", "main"}, {"hlsl.structarray.flatten.geom", "main"}, {"hlsl.structin.vert", "main"}, + {"hlsl.structIoFourWay.frag", "main"}, {"hlsl.intrinsics.vert", "VertexShaderFunction"}, {"hlsl.matType.frag", "PixelShaderFunction"}, {"hlsl.matType.bool.frag", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 1f7bd6ab..280ab93c 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -159,10 +159,16 @@ bool HlslParseContext::shouldConvertLValue(const TIntermNode* node) const return false; } -void HlslParseContext::growGlobalUniformBlock(TSourceLoc& loc, TType& memberType, TString& memberName) +void HlslParseContext::growGlobalUniformBlock(TSourceLoc& loc, TType& memberType, TString& memberName, TTypeList* newTypeList) { + newTypeList = nullptr; correctUniform(memberType.getQualifier()); - TParseContextBase::growGlobalUniformBlock(loc, memberType, memberName); + if (memberType.isStruct()) { + auto it = ioTypeMap.find(memberType.getStruct()); + if (it != ioTypeMap.end() && it->second.uniform) + newTypeList = it->second.uniform; + } + TParseContextBase::growGlobalUniformBlock(loc, memberType, memberName, newTypeList); } // @@ -5381,8 +5387,12 @@ void HlslParseContext::declareStruct(const TSourceLoc& loc, TString& structName, } if (newLists.uniform == nullptr && newLists.input == nullptr && - newLists.output == nullptr) + newLists.output == nullptr) { + // Won't do any IO caching, clear up the type and get out now. + for (auto member = type.getStruct()->begin(); member != type.getStruct()->end(); ++member) + clearUniformInputOutput(member->type->getQualifier()); return; + } // We have IO involved. @@ -5471,6 +5481,11 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& i case EvqUniform: case EvqBuffer: correctUniform(type.getQualifier()); + if (type.isStruct()) { + auto it = ioTypeMap.find(type.getStruct()); + if (it != ioTypeMap.end()) + type.setStruct(it->second.uniform); + } break; default: break; @@ -6011,6 +6026,22 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TS { assert(type.getWritableStruct() != nullptr); + // Clean up top-level decorations that don't belong. + switch (type.getQualifier().storage) { + case EvqUniform: + case EvqBuffer: + correctUniform(type.getQualifier()); + break; + case EvqVaryingIn: + correctInput(type.getQualifier()); + break; + case EvqVaryingOut: + correctOutput(type.getQualifier()); + break; + default: + break; + } + TTypeList& typeList = *type.getWritableStruct(); // fix and check for member storage qualifiers and types that don't belong within a block for (unsigned int member = 0; member < typeList.size(); ++member) { @@ -6019,6 +6050,31 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TS const TSourceLoc& memberLoc = typeList[member].loc; globalQualifierFix(memberLoc, memberQualifier); memberQualifier.storage = type.getQualifier().storage; + + if (memberType.isStruct()) { + // clean up and pick up the right set of decorations + auto it = ioTypeMap.find(memberType.getStruct()); + switch (type.getQualifier().storage) { + case EvqUniform: + case EvqBuffer: + correctUniform(type.getQualifier()); + if (it != ioTypeMap.end() && it->second.uniform) + type.setStruct(it->second.uniform); + break; + case EvqVaryingIn: + correctInput(type.getQualifier()); + if (it != ioTypeMap.end() && it->second.input) + type.setStruct(it->second.input); + break; + case EvqVaryingOut: + correctOutput(type.getQualifier()); + if (it != ioTypeMap.end() && it->second.output) + type.setStruct(it->second.output); + break; + default: + break; + } + } } // This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will @@ -6602,15 +6658,16 @@ bool HlslParseContext::isInputBuiltIn(const TQualifier& qualifier) const } } -// Return true if there are decorations to preserve for input-like storage, -// except for builtIn. +// Return true if there are decorations to preserve for input-like storage. bool HlslParseContext::hasInput(const TQualifier& qualifier) const { if (qualifier.hasAnyLocation()) return true; - if (language != EShLangVertex && language != EShLangCompute && - (qualifier.isInterpolation() || qualifier.isAuxiliary())) + if (language == EShLangFragment && (qualifier.isInterpolation() || qualifier.centroid || qualifier.sample)) + return true; + + if (language == EShLangTessEvaluation && qualifier.patch) return true; if (isInputBuiltIn(qualifier)) @@ -6630,6 +6687,8 @@ bool HlslParseContext::isOutputBuiltIn(const TQualifier& qualifier) const case EbvCullDistance: return language != EShLangFragment && language != EShLangCompute; case EbvFragDepth: + case EbvFragDepthGreater: + case EbvFragDepthLesser: case EbvSampleMask: return language == EShLangFragment; case EbvLayer: @@ -6645,15 +6704,16 @@ bool HlslParseContext::isOutputBuiltIn(const TQualifier& qualifier) const } } -// Return true if there are decorations to preserve for output-like storage, -// except for builtIn. +// Return true if there are decorations to preserve for output-like storage. bool HlslParseContext::hasOutput(const TQualifier& qualifier) const { if (qualifier.hasAnyLocation()) return true; - if (language != EShLangFragment && language != EShLangCompute && - (qualifier.hasXfb() || qualifier.isInterpolation() || qualifier.isAuxiliary())) + if (language != EShLangFragment && language != EShLangCompute && qualifier.hasXfb()) + return true; + + if (language == EShLangTessControl && qualifier.patch) return true; if (language == EShLangGeometry && qualifier.hasStream()) @@ -6671,6 +6731,13 @@ void HlslParseContext::correctInput(TQualifier& qualifier) clearUniform(qualifier); if (language == EShLangVertex) qualifier.clearInterstage(); + if (language != EShLangTessEvaluation) + qualifier.patch = false; + if (language != EShLangFragment) { + qualifier.clearInterpolation(); + qualifier.sample = false; + } + qualifier.clearStreamLayout(); qualifier.clearXfbLayout(); @@ -6688,6 +6755,8 @@ void HlslParseContext::correctOutput(TQualifier& qualifier) qualifier.clearStreamLayout(); if (language == EShLangFragment) qualifier.clearXfbLayout(); + if (language != EShLangTessControl) + qualifier.patch = false; switch (qualifier.builtIn) { case EbvFragDepthGreater: diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index d0bfcdf3..4caa73c5 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -161,7 +161,7 @@ public: void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); } void popSwitchSequence() { switchSequenceStack.pop_back(); } - virtual void growGlobalUniformBlock(TSourceLoc&, TType&, TString& memberName) override; + virtual void growGlobalUniformBlock(TSourceLoc&, TType&, 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);