HLSL: Fix #942: Map SV_TargetN to SPV Location N.
authorJohn Kessenich <cepheus@frii.com>
Tue, 27 Jun 2017 21:17:38 +0000 (15:17 -0600)
committerJohn Kessenich <cepheus@frii.com>
Tue, 27 Jun 2017 21:17:38 +0000 (15:17 -0600)
Test/baseResults/hlsl.target.frag.out [new file with mode: 0755]
Test/baseResults/hlsl.targetStruct1.frag.out [new file with mode: 0755]
Test/baseResults/hlsl.targetStruct2.frag.out [new file with mode: 0755]
Test/hlsl.target.frag [new file with mode: 0644]
Test/hlsl.targetStruct1.frag [new file with mode: 0644]
Test/hlsl.targetStruct2.frag [new file with mode: 0644]
gtests/Hlsl.FromFile.cpp
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h

diff --git a/Test/baseResults/hlsl.target.frag.out b/Test/baseResults/hlsl.target.frag.out
new file mode 100755 (executable)
index 0000000..a44931f
--- /dev/null
@@ -0,0 +1,188 @@
+hlsl.target.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:7  Function Definition: @main(struct-PSInput-f1-u11;vf4;vf4; ( temp void)
+0:7    Function Parameters: 
+0:7      'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:7      'out1' ( out 4-component vector of float)
+0:7      'out2' ( out 4-component vector of float)
+0:?     Sequence
+0:8      move second child to first child ( temp 4-component vector of float)
+0:8        'out1' ( out 4-component vector of float)
+0:8        Constant:
+0:8          1.000000
+0:8          1.000000
+0:8          1.000000
+0:8          1.000000
+0:9      move second child to first child ( temp 4-component vector of float)
+0:9        'out2' ( out 4-component vector of float)
+0:9        Constant:
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:7  Function Definition: main( ( temp void)
+0:7    Function Parameters: 
+0:?     Sequence
+0:7      move second child to first child ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:7      Function Call: @main(struct-PSInput-f1-u11;vf4;vf4; ( temp void)
+0:?         'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'out1' ( temp 4-component vector of float)
+0:?         'out2' ( temp 4-component vector of float)
+0:7      move second child to first child ( temp 4-component vector of float)
+0:?         'out1' (layout( location=1) out 4-component vector of float)
+0:?         'out1' ( temp 4-component vector of float)
+0:7      move second child to first child ( temp 4-component vector of float)
+0:?         'out2' (layout( location=3) out 4-component vector of float)
+0:?         'out2' ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:?     'out1' (layout( location=1) out 4-component vector of float)
+0:?     'out2' (layout( location=3) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:7  Function Definition: @main(struct-PSInput-f1-u11;vf4;vf4; ( temp void)
+0:7    Function Parameters: 
+0:7      'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:7      'out1' ( out 4-component vector of float)
+0:7      'out2' ( out 4-component vector of float)
+0:?     Sequence
+0:8      move second child to first child ( temp 4-component vector of float)
+0:8        'out1' ( out 4-component vector of float)
+0:8        Constant:
+0:8          1.000000
+0:8          1.000000
+0:8          1.000000
+0:8          1.000000
+0:9      move second child to first child ( temp 4-component vector of float)
+0:9        'out2' ( out 4-component vector of float)
+0:9        Constant:
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:7  Function Definition: main( ( temp void)
+0:7    Function Parameters: 
+0:?     Sequence
+0:7      move second child to first child ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:7      Function Call: @main(struct-PSInput-f1-u11;vf4;vf4; ( temp void)
+0:?         'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'out1' ( temp 4-component vector of float)
+0:?         'out2' ( temp 4-component vector of float)
+0:7      move second child to first child ( temp 4-component vector of float)
+0:?         'out1' (layout( location=1) out 4-component vector of float)
+0:?         'out1' ( temp 4-component vector of float)
+0:7      move second child to first child ( temp 4-component vector of float)
+0:?         'out2' (layout( location=3) out 4-component vector of float)
+0:?         'out2' ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:?     'out1' (layout( location=1) out 4-component vector of float)
+0:?     'out2' (layout( location=3) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 50
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 25 46 48
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 8  "PSInput"
+                              MemberName 8(PSInput) 0  "interp"
+                              MemberName 8(PSInput) 1  "no_interp"
+                              Name 16  "@main(struct-PSInput-f1-u11;vf4;vf4;"
+                              Name 13  "input"
+                              Name 14  "out1"
+                              Name 15  "out2"
+                              Name 22  "input"
+                              Name 23  "PSInput"
+                              MemberName 23(PSInput) 0  "interp"
+                              MemberName 23(PSInput) 1  "no_interp"
+                              Name 25  "input"
+                              Name 36  "out1"
+                              Name 37  "out2"
+                              Name 38  "param"
+                              Name 40  "param"
+                              Name 41  "param"
+                              Name 46  "out1"
+                              Name 48  "out2"
+                              MemberDecorate 23(PSInput) 1 Flat
+                              Decorate 25(input) Location 0
+                              Decorate 46(out1) Location 1
+                              Decorate 48(out2) Location 3
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeInt 32 0
+      8(PSInput):             TypeStruct 6(float) 7(int)
+               9:             TypePointer Function 8(PSInput)
+              10:             TypeVector 6(float) 4
+              11:             TypePointer Function 10(fvec4)
+              12:             TypeFunction 2 9(ptr) 11(ptr) 11(ptr)
+              18:    6(float) Constant 1065353216
+              19:   10(fvec4) ConstantComposite 18 18 18 18
+              20:    6(float) Constant 0
+              21:   10(fvec4) ConstantComposite 20 20 20 20
+     23(PSInput):             TypeStruct 6(float) 7(int)
+              24:             TypePointer Input 23(PSInput)
+       25(input):     24(ptr) Variable Input
+              28:             TypeInt 32 1
+              29:     28(int) Constant 0
+              30:             TypePointer Function 6(float)
+              33:     28(int) Constant 1
+              34:             TypePointer Function 7(int)
+              45:             TypePointer Output 10(fvec4)
+        46(out1):     45(ptr) Variable Output
+        48(out2):     45(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+       22(input):      9(ptr) Variable Function
+        36(out1):     11(ptr) Variable Function
+        37(out2):     11(ptr) Variable Function
+       38(param):      9(ptr) Variable Function
+       40(param):     11(ptr) Variable Function
+       41(param):     11(ptr) Variable Function
+              26: 23(PSInput) Load 25(input)
+              27:    6(float) CompositeExtract 26 0
+              31:     30(ptr) AccessChain 22(input) 29
+                              Store 31 27
+              32:      7(int) CompositeExtract 26 1
+              35:     34(ptr) AccessChain 22(input) 33
+                              Store 35 32
+              39:  8(PSInput) Load 22(input)
+                              Store 38(param) 39
+              42:           2 FunctionCall 16(@main(struct-PSInput-f1-u11;vf4;vf4;) 38(param) 40(param) 41(param)
+              43:   10(fvec4) Load 40(param)
+                              Store 36(out1) 43
+              44:   10(fvec4) Load 41(param)
+                              Store 37(out2) 44
+              47:   10(fvec4) Load 36(out1)
+                              Store 46(out1) 47
+              49:   10(fvec4) Load 37(out2)
+                              Store 48(out2) 49
+                              Return
+                              FunctionEnd
+16(@main(struct-PSInput-f1-u11;vf4;vf4;):           2 Function None 12
+       13(input):      9(ptr) FunctionParameter
+        14(out1):     11(ptr) FunctionParameter
+        15(out2):     11(ptr) FunctionParameter
+              17:             Label
+                              Store 14(out1) 19
+                              Store 15(out2) 21
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.targetStruct1.frag.out b/Test/baseResults/hlsl.targetStruct1.frag.out
new file mode 100755 (executable)
index 0000000..48fee12
--- /dev/null
@@ -0,0 +1,277 @@
+hlsl.targetStruct1.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: @main(struct-PSInput-f1-u11;vf4; ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12    Function Parameters: 
+0:12      'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:12      'po' ( out 4-component vector of float)
+0:?     Sequence
+0:14      move second child to first child ( temp 4-component vector of float)
+0:14        o1: direct index for structure ( temp 4-component vector of float)
+0:14          'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:14          Constant:
+0:14            0 (const int)
+0:?         Construct vec4 ( temp 4-component vector of float)
+0:14          Convert uint to float ( temp float)
+0:14            no_interp: direct index for structure ( temp uint)
+0:14              'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:14              Constant:
+0:14                1 (const int)
+0:14          interp: direct index for structure ( temp float)
+0:14            'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:14            Constant:
+0:14              0 (const int)
+0:14          Constant:
+0:14            0.000000
+0:14          Constant:
+0:14            1.000000
+0:15      move second child to first child ( temp 4-component vector of float)
+0:15        o2: direct index for structure ( temp 4-component vector of float)
+0:15          'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:15          Constant:
+0:15            1 (const int)
+0:15        Constant:
+0:15          1.000000
+0:15          1.000000
+0:15          1.000000
+0:15          1.000000
+0:16      move second child to first child ( temp 4-component vector of float)
+0:16        'po' ( out 4-component vector of float)
+0:16        Constant:
+0:16          0.000000
+0:16          0.000000
+0:16          0.000000
+0:16          0.000000
+0:18      Branch: Return with expression
+0:18        'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12  Function Definition: main( ( temp void)
+0:12    Function Parameters: 
+0:?     Sequence
+0:12      move second child to first child ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:12      Sequence
+0:12        move second child to first child ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12          'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12          Function Call: @main(struct-PSInput-f1-u11;vf4; ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:?             'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?             'po' ( temp 4-component vector of float)
+0:12        move second child to first child ( temp 4-component vector of float)
+0:?           'o1' (layout( location=2) out 4-component vector of float)
+0:12          o1: direct index for structure ( temp 4-component vector of float)
+0:12            'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12            Constant:
+0:12              0 (const int)
+0:12        move second child to first child ( temp 4-component vector of float)
+0:?           'o2' (layout( location=1) out 4-component vector of float)
+0:12          o2: direct index for structure ( temp 4-component vector of float)
+0:12            'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12            Constant:
+0:12              1 (const int)
+0:12      move second child to first child ( temp 4-component vector of float)
+0:?         'po' (layout( location=0) out 4-component vector of float)
+0:?         'po' ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'o1' (layout( location=2) out 4-component vector of float)
+0:?     'o2' (layout( location=1) out 4-component vector of float)
+0:?     'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:?     'po' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: @main(struct-PSInput-f1-u11;vf4; ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12    Function Parameters: 
+0:12      'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:12      'po' ( out 4-component vector of float)
+0:?     Sequence
+0:14      move second child to first child ( temp 4-component vector of float)
+0:14        o1: direct index for structure ( temp 4-component vector of float)
+0:14          'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:14          Constant:
+0:14            0 (const int)
+0:?         Construct vec4 ( temp 4-component vector of float)
+0:14          Convert uint to float ( temp float)
+0:14            no_interp: direct index for structure ( temp uint)
+0:14              'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:14              Constant:
+0:14                1 (const int)
+0:14          interp: direct index for structure ( temp float)
+0:14            'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:14            Constant:
+0:14              0 (const int)
+0:14          Constant:
+0:14            0.000000
+0:14          Constant:
+0:14            1.000000
+0:15      move second child to first child ( temp 4-component vector of float)
+0:15        o2: direct index for structure ( temp 4-component vector of float)
+0:15          'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:15          Constant:
+0:15            1 (const int)
+0:15        Constant:
+0:15          1.000000
+0:15          1.000000
+0:15          1.000000
+0:15          1.000000
+0:16      move second child to first child ( temp 4-component vector of float)
+0:16        'po' ( out 4-component vector of float)
+0:16        Constant:
+0:16          0.000000
+0:16          0.000000
+0:16          0.000000
+0:16          0.000000
+0:18      Branch: Return with expression
+0:18        'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12  Function Definition: main( ( temp void)
+0:12    Function Parameters: 
+0:?     Sequence
+0:12      move second child to first child ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:12      Sequence
+0:12        move second child to first child ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12          'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12          Function Call: @main(struct-PSInput-f1-u11;vf4; ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:?             'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?             'po' ( temp 4-component vector of float)
+0:12        move second child to first child ( temp 4-component vector of float)
+0:?           'o1' (layout( location=2) out 4-component vector of float)
+0:12          o1: direct index for structure ( temp 4-component vector of float)
+0:12            'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12            Constant:
+0:12              0 (const int)
+0:12        move second child to first child ( temp 4-component vector of float)
+0:?           'o2' (layout( location=1) out 4-component vector of float)
+0:12          o2: direct index for structure ( temp 4-component vector of float)
+0:12            'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12            Constant:
+0:12              1 (const int)
+0:12      move second child to first child ( temp 4-component vector of float)
+0:?         'po' (layout( location=0) out 4-component vector of float)
+0:?         'po' ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'o1' (layout( location=2) out 4-component vector of float)
+0:?     'o2' (layout( location=1) out 4-component vector of float)
+0:?     'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:?     'po' (layout( location=0) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 65
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 43 57 60 63
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 8  "PSInput"
+                              MemberName 8(PSInput) 0  "interp"
+                              MemberName 8(PSInput) 1  "no_interp"
+                              Name 12  "PSOutput"
+                              MemberName 12(PSOutput) 0  "o1"
+                              MemberName 12(PSOutput) 1  "o2"
+                              Name 16  "@main(struct-PSInput-f1-u11;vf4;"
+                              Name 14  "input"
+                              Name 15  "po"
+                              Name 19  "pso"
+                              Name 40  "input"
+                              Name 41  "PSInput"
+                              MemberName 41(PSInput) 0  "interp"
+                              MemberName 41(PSInput) 1  "no_interp"
+                              Name 43  "input"
+                              Name 49  "flattenTemp"
+                              Name 50  "po"
+                              Name 51  "param"
+                              Name 53  "param"
+                              Name 57  "o1"
+                              Name 60  "o2"
+                              Name 63  "po"
+                              MemberDecorate 41(PSInput) 1 Flat
+                              Decorate 43(input) Location 0
+                              Decorate 57(o1) Location 2
+                              Decorate 60(o2) Location 1
+                              Decorate 63(po) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeInt 32 0
+      8(PSInput):             TypeStruct 6(float) 7(int)
+               9:             TypePointer Function 8(PSInput)
+              10:             TypeVector 6(float) 4
+              11:             TypePointer Function 10(fvec4)
+    12(PSOutput):             TypeStruct 10(fvec4) 10(fvec4)
+              13:             TypeFunction 12(PSOutput) 9(ptr) 11(ptr)
+              18:             TypePointer Function 12(PSOutput)
+              20:             TypeInt 32 1
+              21:     20(int) Constant 0
+              22:     20(int) Constant 1
+              23:             TypePointer Function 7(int)
+              27:             TypePointer Function 6(float)
+              30:    6(float) Constant 0
+              31:    6(float) Constant 1065353216
+              34:   10(fvec4) ConstantComposite 31 31 31 31
+              36:   10(fvec4) ConstantComposite 30 30 30 30
+     41(PSInput):             TypeStruct 6(float) 7(int)
+              42:             TypePointer Input 41(PSInput)
+       43(input):     42(ptr) Variable Input
+              56:             TypePointer Output 10(fvec4)
+          57(o1):     56(ptr) Variable Output
+          60(o2):     56(ptr) Variable Output
+          63(po):     56(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+       40(input):      9(ptr) Variable Function
+ 49(flattenTemp):     18(ptr) Variable Function
+          50(po):     11(ptr) Variable Function
+       51(param):      9(ptr) Variable Function
+       53(param):     11(ptr) Variable Function
+              44: 41(PSInput) Load 43(input)
+              45:    6(float) CompositeExtract 44 0
+              46:     27(ptr) AccessChain 40(input) 21
+                              Store 46 45
+              47:      7(int) CompositeExtract 44 1
+              48:     23(ptr) AccessChain 40(input) 22
+                              Store 48 47
+              52:  8(PSInput) Load 40(input)
+                              Store 51(param) 52
+              54:12(PSOutput) FunctionCall 16(@main(struct-PSInput-f1-u11;vf4;) 51(param) 53(param)
+              55:   10(fvec4) Load 53(param)
+                              Store 50(po) 55
+                              Store 49(flattenTemp) 54
+              58:     11(ptr) AccessChain 49(flattenTemp) 21
+              59:   10(fvec4) Load 58
+                              Store 57(o1) 59
+              61:     11(ptr) AccessChain 49(flattenTemp) 22
+              62:   10(fvec4) Load 61
+                              Store 60(o2) 62
+              64:   10(fvec4) Load 50(po)
+                              Store 63(po) 64
+                              Return
+                              FunctionEnd
+16(@main(struct-PSInput-f1-u11;vf4;):12(PSOutput) Function None 13
+       14(input):      9(ptr) FunctionParameter
+          15(po):     11(ptr) FunctionParameter
+              17:             Label
+         19(pso):     18(ptr) Variable Function
+              24:     23(ptr) AccessChain 14(input) 22
+              25:      7(int) Load 24
+              26:    6(float) ConvertUToF 25
+              28:     27(ptr) AccessChain 14(input) 21
+              29:    6(float) Load 28
+              32:   10(fvec4) CompositeConstruct 26 29 30 31
+              33:     11(ptr) AccessChain 19(pso) 21
+                              Store 33 32
+              35:     11(ptr) AccessChain 19(pso) 22
+                              Store 35 34
+                              Store 15(po) 36
+              37:12(PSOutput) Load 19(pso)
+                              ReturnValue 37
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.targetStruct2.frag.out b/Test/baseResults/hlsl.targetStruct2.frag.out
new file mode 100755 (executable)
index 0000000..0c2ac50
--- /dev/null
@@ -0,0 +1,277 @@
+hlsl.targetStruct2.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: @main(struct-PSInput-f1-u11;vf4; ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12    Function Parameters: 
+0:12      'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:12      'po' ( out 4-component vector of float)
+0:?     Sequence
+0:14      move second child to first child ( temp 4-component vector of float)
+0:14        o1: direct index for structure ( temp 4-component vector of float)
+0:14          'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:14          Constant:
+0:14            0 (const int)
+0:?         Construct vec4 ( temp 4-component vector of float)
+0:14          Convert uint to float ( temp float)
+0:14            no_interp: direct index for structure ( temp uint)
+0:14              'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:14              Constant:
+0:14                1 (const int)
+0:14          interp: direct index for structure ( temp float)
+0:14            'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:14            Constant:
+0:14              0 (const int)
+0:14          Constant:
+0:14            0.000000
+0:14          Constant:
+0:14            1.000000
+0:15      move second child to first child ( temp 4-component vector of float)
+0:15        o2: direct index for structure ( temp 4-component vector of float)
+0:15          'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:15          Constant:
+0:15            1 (const int)
+0:15        Constant:
+0:15          1.000000
+0:15          1.000000
+0:15          1.000000
+0:15          1.000000
+0:16      move second child to first child ( temp 4-component vector of float)
+0:16        'po' ( out 4-component vector of float)
+0:16        Constant:
+0:16          0.000000
+0:16          0.000000
+0:16          0.000000
+0:16          0.000000
+0:18      Branch: Return with expression
+0:18        'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12  Function Definition: main( ( temp void)
+0:12    Function Parameters: 
+0:?     Sequence
+0:12      move second child to first child ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:12      Sequence
+0:12        move second child to first child ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12          'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12          Function Call: @main(struct-PSInput-f1-u11;vf4; ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:?             'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?             'po' ( temp 4-component vector of float)
+0:12        move second child to first child ( temp 4-component vector of float)
+0:?           'o1' (layout( location=2) out 4-component vector of float)
+0:12          o1: direct index for structure ( temp 4-component vector of float)
+0:12            'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12            Constant:
+0:12              0 (const int)
+0:12        move second child to first child ( temp 4-component vector of float)
+0:?           'o2' (layout( location=3) out 4-component vector of float)
+0:12          o2: direct index for structure ( temp 4-component vector of float)
+0:12            'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12            Constant:
+0:12              1 (const int)
+0:12      move second child to first child ( temp 4-component vector of float)
+0:?         'po' (layout( location=0) out 4-component vector of float)
+0:?         'po' ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'o1' (layout( location=2) out 4-component vector of float)
+0:?     'o2' (layout( location=3) out 4-component vector of float)
+0:?     'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:?     'po' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: @main(struct-PSInput-f1-u11;vf4; ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12    Function Parameters: 
+0:12      'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:12      'po' ( out 4-component vector of float)
+0:?     Sequence
+0:14      move second child to first child ( temp 4-component vector of float)
+0:14        o1: direct index for structure ( temp 4-component vector of float)
+0:14          'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:14          Constant:
+0:14            0 (const int)
+0:?         Construct vec4 ( temp 4-component vector of float)
+0:14          Convert uint to float ( temp float)
+0:14            no_interp: direct index for structure ( temp uint)
+0:14              'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:14              Constant:
+0:14                1 (const int)
+0:14          interp: direct index for structure ( temp float)
+0:14            'input' ( in structure{ temp float interp,  temp uint no_interp})
+0:14            Constant:
+0:14              0 (const int)
+0:14          Constant:
+0:14            0.000000
+0:14          Constant:
+0:14            1.000000
+0:15      move second child to first child ( temp 4-component vector of float)
+0:15        o2: direct index for structure ( temp 4-component vector of float)
+0:15          'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:15          Constant:
+0:15            1 (const int)
+0:15        Constant:
+0:15          1.000000
+0:15          1.000000
+0:15          1.000000
+0:15          1.000000
+0:16      move second child to first child ( temp 4-component vector of float)
+0:16        'po' ( out 4-component vector of float)
+0:16        Constant:
+0:16          0.000000
+0:16          0.000000
+0:16          0.000000
+0:16          0.000000
+0:18      Branch: Return with expression
+0:18        'pso' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12  Function Definition: main( ( temp void)
+0:12    Function Parameters: 
+0:?     Sequence
+0:12      move second child to first child ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?         'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:12      Sequence
+0:12        move second child to first child ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12          'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12          Function Call: @main(struct-PSInput-f1-u11;vf4; ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:?             'input' ( temp structure{ temp float interp,  temp uint no_interp})
+0:?             'po' ( temp 4-component vector of float)
+0:12        move second child to first child ( temp 4-component vector of float)
+0:?           'o1' (layout( location=2) out 4-component vector of float)
+0:12          o1: direct index for structure ( temp 4-component vector of float)
+0:12            'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12            Constant:
+0:12              0 (const int)
+0:12        move second child to first child ( temp 4-component vector of float)
+0:?           'o2' (layout( location=3) out 4-component vector of float)
+0:12          o2: direct index for structure ( temp 4-component vector of float)
+0:12            'flattenTemp' ( temp structure{ temp 4-component vector of float o1,  temp 4-component vector of float o2})
+0:12            Constant:
+0:12              1 (const int)
+0:12      move second child to first child ( temp 4-component vector of float)
+0:?         'po' (layout( location=0) out 4-component vector of float)
+0:?         'po' ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'o1' (layout( location=2) out 4-component vector of float)
+0:?     'o2' (layout( location=3) out 4-component vector of float)
+0:?     'input' (layout( location=0) in structure{ temp float interp,  flat temp uint no_interp})
+0:?     'po' (layout( location=0) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 65
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 43 57 60 63
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 8  "PSInput"
+                              MemberName 8(PSInput) 0  "interp"
+                              MemberName 8(PSInput) 1  "no_interp"
+                              Name 12  "PSOutput"
+                              MemberName 12(PSOutput) 0  "o1"
+                              MemberName 12(PSOutput) 1  "o2"
+                              Name 16  "@main(struct-PSInput-f1-u11;vf4;"
+                              Name 14  "input"
+                              Name 15  "po"
+                              Name 19  "pso"
+                              Name 40  "input"
+                              Name 41  "PSInput"
+                              MemberName 41(PSInput) 0  "interp"
+                              MemberName 41(PSInput) 1  "no_interp"
+                              Name 43  "input"
+                              Name 49  "flattenTemp"
+                              Name 50  "po"
+                              Name 51  "param"
+                              Name 53  "param"
+                              Name 57  "o1"
+                              Name 60  "o2"
+                              Name 63  "po"
+                              MemberDecorate 41(PSInput) 1 Flat
+                              Decorate 43(input) Location 0
+                              Decorate 57(o1) Location 2
+                              Decorate 60(o2) Location 3
+                              Decorate 63(po) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeInt 32 0
+      8(PSInput):             TypeStruct 6(float) 7(int)
+               9:             TypePointer Function 8(PSInput)
+              10:             TypeVector 6(float) 4
+              11:             TypePointer Function 10(fvec4)
+    12(PSOutput):             TypeStruct 10(fvec4) 10(fvec4)
+              13:             TypeFunction 12(PSOutput) 9(ptr) 11(ptr)
+              18:             TypePointer Function 12(PSOutput)
+              20:             TypeInt 32 1
+              21:     20(int) Constant 0
+              22:     20(int) Constant 1
+              23:             TypePointer Function 7(int)
+              27:             TypePointer Function 6(float)
+              30:    6(float) Constant 0
+              31:    6(float) Constant 1065353216
+              34:   10(fvec4) ConstantComposite 31 31 31 31
+              36:   10(fvec4) ConstantComposite 30 30 30 30
+     41(PSInput):             TypeStruct 6(float) 7(int)
+              42:             TypePointer Input 41(PSInput)
+       43(input):     42(ptr) Variable Input
+              56:             TypePointer Output 10(fvec4)
+          57(o1):     56(ptr) Variable Output
+          60(o2):     56(ptr) Variable Output
+          63(po):     56(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+       40(input):      9(ptr) Variable Function
+ 49(flattenTemp):     18(ptr) Variable Function
+          50(po):     11(ptr) Variable Function
+       51(param):      9(ptr) Variable Function
+       53(param):     11(ptr) Variable Function
+              44: 41(PSInput) Load 43(input)
+              45:    6(float) CompositeExtract 44 0
+              46:     27(ptr) AccessChain 40(input) 21
+                              Store 46 45
+              47:      7(int) CompositeExtract 44 1
+              48:     23(ptr) AccessChain 40(input) 22
+                              Store 48 47
+              52:  8(PSInput) Load 40(input)
+                              Store 51(param) 52
+              54:12(PSOutput) FunctionCall 16(@main(struct-PSInput-f1-u11;vf4;) 51(param) 53(param)
+              55:   10(fvec4) Load 53(param)
+                              Store 50(po) 55
+                              Store 49(flattenTemp) 54
+              58:     11(ptr) AccessChain 49(flattenTemp) 21
+              59:   10(fvec4) Load 58
+                              Store 57(o1) 59
+              61:     11(ptr) AccessChain 49(flattenTemp) 22
+              62:   10(fvec4) Load 61
+                              Store 60(o2) 62
+              64:   10(fvec4) Load 50(po)
+                              Store 63(po) 64
+                              Return
+                              FunctionEnd
+16(@main(struct-PSInput-f1-u11;vf4;):12(PSOutput) Function None 13
+       14(input):      9(ptr) FunctionParameter
+          15(po):     11(ptr) FunctionParameter
+              17:             Label
+         19(pso):     18(ptr) Variable Function
+              24:     23(ptr) AccessChain 14(input) 22
+              25:      7(int) Load 24
+              26:    6(float) ConvertUToF 25
+              28:     27(ptr) AccessChain 14(input) 21
+              29:    6(float) Load 28
+              32:   10(fvec4) CompositeConstruct 26 29 30 31
+              33:     11(ptr) AccessChain 19(pso) 21
+                              Store 33 32
+              35:     11(ptr) AccessChain 19(pso) 22
+                              Store 35 34
+                              Store 15(po) 36
+              37:12(PSOutput) Load 19(pso)
+                              ReturnValue 37
+                              FunctionEnd
diff --git a/Test/hlsl.target.frag b/Test/hlsl.target.frag
new file mode 100644 (file)
index 0000000..5317236
--- /dev/null
@@ -0,0 +1,10 @@
+struct PSInput {\r
+  float interp;\r
+  uint no_interp;\r
+};\r
+\r
+void main(PSInput input : INPUT, out float4 out1 : SV_TARGET1, out float4 out2 : SV_TARGET3)\r
+{\r
+    out1 = 1;\r
+    out2 = 0;\r
+}
\ No newline at end of file
diff --git a/Test/hlsl.targetStruct1.frag b/Test/hlsl.targetStruct1.frag
new file mode 100644 (file)
index 0000000..7fcc082
--- /dev/null
@@ -0,0 +1,19 @@
+struct PSInput {\r
+  float interp;\r
+  uint no_interp;\r
+};\r
+\r
+struct PSOutput {\r
+    float4 o1 : SV_TARGET2;\r
+    float4 o2 : SV_TARGET1;\r
+};\r
+\r
+PSOutput main(PSInput input : INPUT, out float4 po : SV_TARGET0)\r
+{\r
+    PSOutput pso;\r
+    pso.o1 = float4(float(input.no_interp), input.interp, 0, 1);\r
+    pso.o2 = 1;\r
+    po = 0;\r
+\r
+    return pso;\r
+}
\ No newline at end of file
diff --git a/Test/hlsl.targetStruct2.frag b/Test/hlsl.targetStruct2.frag
new file mode 100644 (file)
index 0000000..e62ba0f
--- /dev/null
@@ -0,0 +1,19 @@
+struct PSInput {\r
+  float interp;\r
+  uint no_interp;\r
+};\r
+\r
+struct PSOutput {\r
+    float4 o1 : SV_TARGET1;\r
+    float4 o2 : SV_TARGET0;\r
+};\r
+\r
+PSOutput main(PSInput input : INPUT, out float4 po : SV_TARGET0) : SV_TARGET2\r
+{\r
+    PSOutput pso;\r
+    pso.o1 = float4(float(input.no_interp), input.interp, 0, 1);\r
+    pso.o2 = 1;\r
+    po = 0;\r
+\r
+    return pso;\r
+}
\ No newline at end of file
index 6981592..d6fe367 100644 (file)
@@ -300,6 +300,9 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.struct.frag", "PixelShaderFunction"},
         {"hlsl.switch.frag", "PixelShaderFunction"},
         {"hlsl.swizzle.frag", "PixelShaderFunction"},
+        {"hlsl.target.frag", "main"},
+        {"hlsl.targetStruct1.frag", "main"},
+        {"hlsl.targetStruct2.frag", "main"},
         {"hlsl.templatetypes.frag", "PixelShaderFunction"},
         {"hlsl.tx.bracket.frag", "main"},
         {"hlsl.tx.overload.frag", "main"},
index 9d2a3f2..0454b5e 100755 (executable)
@@ -1174,7 +1174,8 @@ void HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable)
     const TType& type = variable.getType();
 
     auto entry = flattenMap.insert(std::make_pair(variable.getUniqueId(),
-                                                  TFlattenData(type.getQualifier().layoutBinding)));
+                                                  TFlattenData(type.getQualifier().layoutBinding,
+                                                               type.getQualifier().layoutLocation)));
 
     // the item is a map pair, so first->second is the TFlattenData itself.
     flatten(loc, variable, type, entry.first->second, "");
@@ -1236,6 +1237,19 @@ int HlslParseContext::addFlattenedMember(const TSourceLoc& loc,
         if (flattenData.nextBinding != TQualifier::layoutBindingEnd)
             memberVariable->getWritableType().getQualifier().layoutBinding = flattenData.nextBinding++;
 
+        if (memberVariable->getType().getQualifier().builtIn == EbvNone) {
+            // inherited locations must be auto bumped, not replicated
+            if (flattenData.nextLocation != TQualifier::layoutLocationEnd &&
+                memberVariable->getType().getQualifier().builtIn == EbvNone) {
+                memberVariable->getWritableType().getQualifier().layoutLocation = flattenData.nextLocation;
+                flattenData.nextLocation += intermediate.computeTypeLocationSize(memberVariable->getType());
+                nextOutLocation = std::max(nextOutLocation, flattenData.nextLocation);
+            }
+        } else {
+            // inherited locations are nonsensical for built-ins
+            memberVariable->getWritableType().getQualifier().layoutLocation = TQualifier::layoutLocationEnd;
+        }
+
         flattenData.offsets.push_back(static_cast<int>(flattenData.members.size()));
         flattenData.members.push_back(memberVariable);
 
@@ -1551,7 +1565,7 @@ void HlslParseContext::assignToInterface(TVariable& variable)
         TType& type = variable.getWritableType();
         TQualifier& qualifier = type.getQualifier();
         if (qualifier.storage == EvqVaryingIn || qualifier.storage == EvqVaryingOut) {
-            if (qualifier.builtIn == EbvNone) {
+            if (qualifier.builtIn == EbvNone && !qualifier.hasLocation()) {
                 // Strip off the outer array dimension for those having an extra one.
                 int size;
                 if (type.isArray() && qualifier.isArrayedIo(language)) {
@@ -1991,7 +2005,7 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
 
         assignToInterface(variable);
     };
-    if (entryPointOutput)
+    if (entryPointOutput != nullptr)
         makeVariableInOut(*entryPointOutput);
     for (auto it = inputs.begin(); it != inputs.end(); ++it)
         if (!isDsPcfInput((*it)->getType()))  // skip domain shader PCF input (see comment below)
@@ -5211,12 +5225,27 @@ TFunction* HlslParseContext::makeConstructorCall(const TSourceLoc& loc, const TT
 // Handle seeing a "COLON semantic" at the end of a type declaration,
 // by updating the type according to the semantic.
 //
-void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, TBuiltInVariable builtIn, const TString& upperCase)
+void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, TBuiltInVariable builtIn,
+                                      const TString& upperCase)
 {
-    // adjust for stage in/out
+    const auto getSemanticNumber = [](const TString& semantic) -> unsigned int {
+        size_t pos = semantic.find_last_not_of("0123456789");
+        if (pos == std::string::npos)
+            return 0u;
+        return (unsigned int)atoi(semantic.c_str() + pos + 1);
+    };
 
     switch(builtIn) {
+    case EbvNone:
+        // Get location numbers from fragment outputs, instead of
+        // auto-assigning them.
+        if (language == EShLangFragment && upperCase.compare(0, 9, "SV_TARGET") == 0) {
+            qualifier.layoutLocation = getSemanticNumber(upperCase);
+            nextOutLocation = std::max(nextOutLocation, qualifier.layoutLocation + 1u);
+        }
+        break;
     case EbvPosition:
+        // adjust for stage in/out
         if (language == EShLangFragment)
             builtIn = EbvFragCoord;
         break;
index 0668f2b..6994365 100755 (executable)
@@ -213,12 +213,14 @@ public:
 
 protected:
     struct TFlattenData {
-        TFlattenData() : nextBinding(TQualifier::layoutBindingEnd) { }
-        TFlattenData(int nb) : nextBinding(nb) { }
+        TFlattenData() : nextBinding(TQualifier::layoutBindingEnd),
+                         nextLocation(TQualifier::layoutLocationEnd) { }
+        TFlattenData(int nb, int nl) : nextBinding(nb), nextLocation(nl) { }
 
         TVector<TVariable*> members;     // individual flattened variables
-        TVector<int>        offsets;     // offset to next tree level
-        int                 nextBinding; // next binding to use.
+        TVector<int> offsets;            // offset to next tree level
+        unsigned int nextBinding;        // next binding to use.
+        unsigned int nextLocation;       // next location to use
     };
 
     void fixConstInit(const TSourceLoc&, const TString& identifier, TType& type, TIntermTyped*& initializer);