HLSL: Add tests and refine what decorations are passed through per stage/in/out.

This commit is contained in:
John Kessenich 2017-02-06 18:44:52 -07:00
parent bf47286fe7
commit 65ee230f1c
12 changed files with 386 additions and 30 deletions

View File

@ -2248,8 +2248,10 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix)); addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix));
addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember)); addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember));
// Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes // 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.getQualifier().storage == glslang::EvqVaryingIn ||
if (type.getBasicType() == glslang::EbtBlock) { type.getQualifier().storage == glslang::EvqVaryingOut) {
if (type.getBasicType() == glslang::EbtBlock ||
glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier)); addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier)); addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
} }

View File

@ -284,6 +284,10 @@ gl_FragCoord origin is upper left
MemberName 94($Global) 2 "ff6" MemberName 94($Global) 2 "ff6"
Name 96 "" Name 96 ""
Decorate 43(input) Location 0 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 48(s) Location 1
Decorate 71(s_ff1) BuiltIn FrontFacing Decorate 71(s_ff1) BuiltIn FrontFacing
Decorate 86(@entryPointOutput) Location 0 Decorate 86(@entryPointOutput) Location 0

View File

@ -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

View File

@ -92,7 +92,7 @@ Shader version: 450
0:? 'e' (temp 4-component vector of float) 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 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 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 Constant:
0:8 0 (const int) 0:8 0 (const int)
0:8 m: direct index for structure (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)
@ -101,7 +101,7 @@ Shader version: 450
0:8 0 (const int) 0:8 0 (const int)
0:8 move second child to first child (temp 2-component vector of uint) 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 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 Constant:
0:8 1 (const int) 0:8 1 (const int)
0:8 coord: direct index for structure (temp 2-component vector of uint) 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 Constant:
0:8 1 (const int) 0:8 1 (const int)
0:8 move second child to first child (temp 4-component vector of float) 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 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, 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 Constant:
0:8 2 (const int) 0:8 2 (const int)
0:8 b: direct index for structure (temp 4-component vector of float) 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 Constant:
0:8 2 (const int) 0:8 2 (const int)
0:? Linker Objects 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:? 'd' (layout(location=0 ) in 4-component vector of float)
0:? 'm[0]' (layout(location=1 ) 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) 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:? '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 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 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 Constant:
0:8 0 (const int) 0:8 0 (const int)
0:8 m: direct index for structure (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)
@ -234,7 +234,7 @@ Shader version: 450
0:8 0 (const int) 0:8 0 (const int)
0:8 move second child to first child (temp 2-component vector of uint) 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 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 Constant:
0:8 1 (const int) 0:8 1 (const int)
0:8 coord: direct index for structure (temp 2-component vector of uint) 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 Constant:
0:8 1 (const int) 0:8 1 (const int)
0:8 move second child to first child (temp 4-component vector of float) 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 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, 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 Constant:
0:8 2 (const int) 0:8 2 (const int)
0:8 b: direct index for structure (temp 4-component vector of float) 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 Constant:
0:8 2 (const int) 0:8 2 (const int)
0:? Linker Objects 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:? 'd' (layout(location=0 ) in 4-component vector of float)
0:? 'm[0]' (layout(location=1 ) 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) 0:? 'm[1]' (layout(location=2 ) in 4-component vector of float)

18
Test/hlsl.structIoFourWay.frag Executable file
View File

@ -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;
}

View File

@ -410,6 +410,13 @@ public:
} }
void clearInterstage() void clearInterstage()
{
clearInterpolation();
patch = false;
sample = false;
}
void clearInterpolation()
{ {
centroid = false; centroid = false;
smooth = false; smooth = false;
@ -418,8 +425,6 @@ public:
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
explicitInterp = false; explicitInterp = false;
#endif #endif
patch = false;
sample = false;
} }
void clearMemory() void clearMemory()

View File

@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // 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). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1791" #define GLSLANG_REVISION "Overload400-PrecQual.1792"
#define GLSLANG_DATE "05-Feb-2017" #define GLSLANG_DATE "06-Feb-2017"

View File

@ -530,7 +530,7 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin
// Make the passed-in variable information become a member of the // Make the passed-in variable information become a member of the
// global uniform block. If this doesn't exist yet, make it. // 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 // make the global block, if not yet made
if (globalUniformBlock == nullptr) { if (globalUniformBlock == nullptr) {
@ -548,6 +548,8 @@ void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberTyp
TType* type = new TType; TType* type = new TType;
type->shallowCopy(memberType); type->shallowCopy(memberType);
type->setFieldName(memberName); type->setFieldName(memberName);
if (typeList)
type->setStruct(typeList);
TTypeLoc typeLoc = {type, loc}; TTypeLoc typeLoc = {type, loc};
globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc); globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);
} }

View File

@ -139,7 +139,7 @@ public:
// TODO: This could perhaps get its own object, but the current design doesn't work // 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 // yet when new uniform variables are declared between function definitions, so
// this is pending getting a fully functional design. // 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 insertGlobalUniformBlock();
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*); virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);

View File

@ -219,6 +219,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.structarray.flatten.frag", "main"}, {"hlsl.structarray.flatten.frag", "main"},
{"hlsl.structarray.flatten.geom", "main"}, {"hlsl.structarray.flatten.geom", "main"},
{"hlsl.structin.vert", "main"}, {"hlsl.structin.vert", "main"},
{"hlsl.structIoFourWay.frag", "main"},
{"hlsl.intrinsics.vert", "VertexShaderFunction"}, {"hlsl.intrinsics.vert", "VertexShaderFunction"},
{"hlsl.matType.frag", "PixelShaderFunction"}, {"hlsl.matType.frag", "PixelShaderFunction"},
{"hlsl.matType.bool.frag", "main"}, {"hlsl.matType.bool.frag", "main"},

View File

@ -159,10 +159,16 @@ bool HlslParseContext::shouldConvertLValue(const TIntermNode* node) const
return false; 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()); 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 && if (newLists.uniform == nullptr &&
newLists.input == 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; return;
}
// We have IO involved. // We have IO involved.
@ -5471,6 +5481,11 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& i
case EvqUniform: case EvqUniform:
case EvqBuffer: case EvqBuffer:
correctUniform(type.getQualifier()); correctUniform(type.getQualifier());
if (type.isStruct()) {
auto it = ioTypeMap.find(type.getStruct());
if (it != ioTypeMap.end())
type.setStruct(it->second.uniform);
}
break; break;
default: default:
break; break;
@ -6011,6 +6026,22 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TS
{ {
assert(type.getWritableStruct() != nullptr); 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(); TTypeList& typeList = *type.getWritableStruct();
// fix and check for member storage qualifiers and types that don't belong within a block // 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) { 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; const TSourceLoc& memberLoc = typeList[member].loc;
globalQualifierFix(memberLoc, memberQualifier); globalQualifierFix(memberLoc, memberQualifier);
memberQualifier.storage = type.getQualifier().storage; 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 // 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, // Return true if there are decorations to preserve for input-like storage.
// except for builtIn.
bool HlslParseContext::hasInput(const TQualifier& qualifier) const bool HlslParseContext::hasInput(const TQualifier& qualifier) const
{ {
if (qualifier.hasAnyLocation()) if (qualifier.hasAnyLocation())
return true; return true;
if (language != EShLangVertex && language != EShLangCompute && if (language == EShLangFragment && (qualifier.isInterpolation() || qualifier.centroid || qualifier.sample))
(qualifier.isInterpolation() || qualifier.isAuxiliary())) return true;
if (language == EShLangTessEvaluation && qualifier.patch)
return true; return true;
if (isInputBuiltIn(qualifier)) if (isInputBuiltIn(qualifier))
@ -6630,6 +6687,8 @@ bool HlslParseContext::isOutputBuiltIn(const TQualifier& qualifier) const
case EbvCullDistance: case EbvCullDistance:
return language != EShLangFragment && language != EShLangCompute; return language != EShLangFragment && language != EShLangCompute;
case EbvFragDepth: case EbvFragDepth:
case EbvFragDepthGreater:
case EbvFragDepthLesser:
case EbvSampleMask: case EbvSampleMask:
return language == EShLangFragment; return language == EShLangFragment;
case EbvLayer: 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, // Return true if there are decorations to preserve for output-like storage.
// except for builtIn.
bool HlslParseContext::hasOutput(const TQualifier& qualifier) const bool HlslParseContext::hasOutput(const TQualifier& qualifier) const
{ {
if (qualifier.hasAnyLocation()) if (qualifier.hasAnyLocation())
return true; return true;
if (language != EShLangFragment && language != EShLangCompute && if (language != EShLangFragment && language != EShLangCompute && qualifier.hasXfb())
(qualifier.hasXfb() || qualifier.isInterpolation() || qualifier.isAuxiliary())) return true;
if (language == EShLangTessControl && qualifier.patch)
return true; return true;
if (language == EShLangGeometry && qualifier.hasStream()) if (language == EShLangGeometry && qualifier.hasStream())
@ -6671,6 +6731,13 @@ void HlslParseContext::correctInput(TQualifier& qualifier)
clearUniform(qualifier); clearUniform(qualifier);
if (language == EShLangVertex) if (language == EShLangVertex)
qualifier.clearInterstage(); qualifier.clearInterstage();
if (language != EShLangTessEvaluation)
qualifier.patch = false;
if (language != EShLangFragment) {
qualifier.clearInterpolation();
qualifier.sample = false;
}
qualifier.clearStreamLayout(); qualifier.clearStreamLayout();
qualifier.clearXfbLayout(); qualifier.clearXfbLayout();
@ -6688,6 +6755,8 @@ void HlslParseContext::correctOutput(TQualifier& qualifier)
qualifier.clearStreamLayout(); qualifier.clearStreamLayout();
if (language == EShLangFragment) if (language == EShLangFragment)
qualifier.clearXfbLayout(); qualifier.clearXfbLayout();
if (language != EShLangTessControl)
qualifier.patch = false;
switch (qualifier.builtIn) { switch (qualifier.builtIn) {
case EbvFragDepthGreater: case EbvFragDepthGreater:

View File

@ -161,7 +161,7 @@ public:
void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); } void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); }
void popSwitchSequence() { switchSequenceStack.pop_back(); } 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. // Apply L-value conversions. E.g, turning a write to a RWTexture into an ImageStore.
TIntermTyped* handleLvalue(const TSourceLoc&, const char* op, TIntermTyped* node); TIntermTyped* handleLvalue(const TSourceLoc&, const char* op, TIntermTyped* node);