Merge pull request #994 from KhronosGroup/opaque-init
HLSL: Fix #980: flatten opaque initializers to use aliases.
This commit is contained in:
		
						commit
						198652a6d4
					
				
							
								
								
									
										132
									
								
								Test/baseResults/hlsl.flattenOpaqueInit.vert.out
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										132
									
								
								Test/baseResults/hlsl.flattenOpaqueInit.vert.out
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,132 @@
 | 
			
		||||
hlsl.flattenOpaqueInit.vert
 | 
			
		||||
Shader version: 500
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:5  Function Definition: lookUp(struct-FxaaTex-p1-t211; ( temp 4-component vector of float)
 | 
			
		||||
0:5    Function Parameters: 
 | 
			
		||||
0:?       'smpl' ( in sampler)
 | 
			
		||||
0:?       'tex' ( in texture2D)
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:6      Branch: Return with expression
 | 
			
		||||
0:6        texture ( temp 4-component vector of float)
 | 
			
		||||
0:6          Construct combined texture-sampler ( temp sampler2D)
 | 
			
		||||
0:?             'tex' ( in texture2D)
 | 
			
		||||
0:?             'smpl' ( in sampler)
 | 
			
		||||
0:?           Constant:
 | 
			
		||||
0:?             0.300000
 | 
			
		||||
0:?             0.400000
 | 
			
		||||
0:10  Function Definition: @main( ( temp 4-component vector of float)
 | 
			
		||||
0:10    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:12      Branch: Return with expression
 | 
			
		||||
0:12        Function Call: lookUp(struct-FxaaTex-p1-t211; ( temp 4-component vector of float)
 | 
			
		||||
0:?           'g_tInputTexture_sampler' ( uniform sampler)
 | 
			
		||||
0:?           'g_tInputTexture' ( uniform texture2D)
 | 
			
		||||
0:10  Function Definition: main( ( temp void)
 | 
			
		||||
0:10    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:10      move second child to first child ( temp 4-component vector of float)
 | 
			
		||||
0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
 | 
			
		||||
0:10        Function Call: @main( ( temp 4-component vector of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'g_tInputTexture_sampler' ( uniform sampler)
 | 
			
		||||
0:?     'g_tInputTexture' ( uniform texture2D)
 | 
			
		||||
0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Linked vertex stage:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Shader version: 500
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:5  Function Definition: lookUp(struct-FxaaTex-p1-t211; ( temp 4-component vector of float)
 | 
			
		||||
0:5    Function Parameters: 
 | 
			
		||||
0:?       'smpl' ( in sampler)
 | 
			
		||||
0:?       'tex' ( in texture2D)
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:6      Branch: Return with expression
 | 
			
		||||
0:6        texture ( temp 4-component vector of float)
 | 
			
		||||
0:6          Construct combined texture-sampler ( temp sampler2D)
 | 
			
		||||
0:?             'tex' ( in texture2D)
 | 
			
		||||
0:?             'smpl' ( in sampler)
 | 
			
		||||
0:?           Constant:
 | 
			
		||||
0:?             0.300000
 | 
			
		||||
0:?             0.400000
 | 
			
		||||
0:10  Function Definition: @main( ( temp 4-component vector of float)
 | 
			
		||||
0:10    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:12      Branch: Return with expression
 | 
			
		||||
0:12        Function Call: lookUp(struct-FxaaTex-p1-t211; ( temp 4-component vector of float)
 | 
			
		||||
0:?           'g_tInputTexture_sampler' ( uniform sampler)
 | 
			
		||||
0:?           'g_tInputTexture' ( uniform texture2D)
 | 
			
		||||
0:10  Function Definition: main( ( temp void)
 | 
			
		||||
0:10    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:10      move second child to first child ( temp 4-component vector of float)
 | 
			
		||||
0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
 | 
			
		||||
0:10        Function Call: @main( ( temp 4-component vector of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'g_tInputTexture_sampler' ( uniform sampler)
 | 
			
		||||
0:?     'g_tInputTexture' ( uniform texture2D)
 | 
			
		||||
0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 80001
 | 
			
		||||
// Id's are bound by 40
 | 
			
		||||
 | 
			
		||||
                              Capability Shader
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint Vertex 4  "main" 38
 | 
			
		||||
                              Source HLSL 500
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 15  "lookUp(struct-FxaaTex-p1-t211;"
 | 
			
		||||
                              Name 13  "smpl"
 | 
			
		||||
                              Name 14  "tex"
 | 
			
		||||
                              Name 18  "@main("
 | 
			
		||||
                              Name 32  "g_tInputTexture_sampler"
 | 
			
		||||
                              Name 33  "g_tInputTexture"
 | 
			
		||||
                              Name 38  "@entryPointOutput"
 | 
			
		||||
                              Decorate 32(g_tInputTexture_sampler) DescriptorSet 0
 | 
			
		||||
                              Decorate 33(g_tInputTexture) DescriptorSet 0
 | 
			
		||||
                              Decorate 38(@entryPointOutput) Location 0
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               6:             TypeSampler
 | 
			
		||||
               7:             TypePointer UniformConstant 6
 | 
			
		||||
               8:             TypeFloat 32
 | 
			
		||||
               9:             TypeImage 8(float) 2D sampled format:Unknown
 | 
			
		||||
              10:             TypePointer UniformConstant 9
 | 
			
		||||
              11:             TypeVector 8(float) 4
 | 
			
		||||
              12:             TypeFunction 11(fvec4) 7(ptr) 10(ptr)
 | 
			
		||||
              17:             TypeFunction 11(fvec4)
 | 
			
		||||
              22:             TypeSampledImage 9
 | 
			
		||||
              24:             TypeVector 8(float) 2
 | 
			
		||||
              25:    8(float) Constant 1050253722
 | 
			
		||||
              26:    8(float) Constant 1053609165
 | 
			
		||||
              27:   24(fvec2) ConstantComposite 25 26
 | 
			
		||||
              28:    8(float) Constant 0
 | 
			
		||||
32(g_tInputTexture_sampler):      7(ptr) Variable UniformConstant
 | 
			
		||||
33(g_tInputTexture):     10(ptr) Variable UniformConstant
 | 
			
		||||
              37:             TypePointer Output 11(fvec4)
 | 
			
		||||
38(@entryPointOutput):     37(ptr) Variable Output
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
              39:   11(fvec4) FunctionCall 18(@main()
 | 
			
		||||
                              Store 38(@entryPointOutput) 39
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
15(lookUp(struct-FxaaTex-p1-t211;):   11(fvec4) Function None 12
 | 
			
		||||
        13(smpl):      7(ptr) FunctionParameter
 | 
			
		||||
         14(tex):     10(ptr) FunctionParameter
 | 
			
		||||
              16:             Label
 | 
			
		||||
              20:           9 Load 14(tex)
 | 
			
		||||
              21:           6 Load 13(smpl)
 | 
			
		||||
              23:          22 SampledImage 20 21
 | 
			
		||||
              29:   11(fvec4) ImageSampleExplicitLod 23 27 Lod 28
 | 
			
		||||
                              ReturnValue 29
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
      18(@main():   11(fvec4) Function None 17
 | 
			
		||||
              19:             Label
 | 
			
		||||
              34:   11(fvec4) FunctionCall 15(lookUp(struct-FxaaTex-p1-t211;) 32(g_tInputTexture_sampler) 33(g_tInputTexture)
 | 
			
		||||
                              ReturnValue 34
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										159
									
								
								Test/baseResults/hlsl.flattenOpaqueInitMix.vert.out
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										159
									
								
								Test/baseResults/hlsl.flattenOpaqueInitMix.vert.out
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,159 @@
 | 
			
		||||
hlsl.flattenOpaqueInitMix.vert
 | 
			
		||||
Shader version: 500
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:5  Function Definition: lookUp(struct-FxaaTex-p1-t21-f11; ( temp 4-component vector of float)
 | 
			
		||||
0:5    Function Parameters: 
 | 
			
		||||
0:?       'smpl' ( in sampler)
 | 
			
		||||
0:?       'tex' ( in texture2D)
 | 
			
		||||
0:?       'f' ( in float)
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:6      Branch: Return with expression
 | 
			
		||||
0:6        texture ( temp 4-component vector of float)
 | 
			
		||||
0:6          Construct combined texture-sampler ( temp sampler2D)
 | 
			
		||||
0:?             'tex' ( in texture2D)
 | 
			
		||||
0:?             'smpl' ( in sampler)
 | 
			
		||||
0:?           Construct vec2 ( temp 2-component vector of float)
 | 
			
		||||
0:?             'f' ( in float)
 | 
			
		||||
0:?             'f' ( in float)
 | 
			
		||||
0:10  Function Definition: @main( ( temp 4-component vector of float)
 | 
			
		||||
0:10    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:11      Sequence
 | 
			
		||||
0:?         Sequence
 | 
			
		||||
0:11          move second child to first child ( temp float)
 | 
			
		||||
0:?             'f' ( temp float)
 | 
			
		||||
0:11            Constant:
 | 
			
		||||
0:11              0.500000
 | 
			
		||||
0:12      Branch: Return with expression
 | 
			
		||||
0:12        Function Call: lookUp(struct-FxaaTex-p1-t21-f11; ( temp 4-component vector of float)
 | 
			
		||||
0:?           'g_tInputTexture_sampler' ( uniform sampler)
 | 
			
		||||
0:?           'g_tInputTexture' ( uniform texture2D)
 | 
			
		||||
0:?           'f' ( temp float)
 | 
			
		||||
0:10  Function Definition: main( ( temp void)
 | 
			
		||||
0:10    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:10      move second child to first child ( temp 4-component vector of float)
 | 
			
		||||
0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
 | 
			
		||||
0:10        Function Call: @main( ( temp 4-component vector of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'g_tInputTexture_sampler' ( uniform sampler)
 | 
			
		||||
0:?     'g_tInputTexture' ( uniform texture2D)
 | 
			
		||||
0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Linked vertex stage:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Shader version: 500
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:5  Function Definition: lookUp(struct-FxaaTex-p1-t21-f11; ( temp 4-component vector of float)
 | 
			
		||||
0:5    Function Parameters: 
 | 
			
		||||
0:?       'smpl' ( in sampler)
 | 
			
		||||
0:?       'tex' ( in texture2D)
 | 
			
		||||
0:?       'f' ( in float)
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:6      Branch: Return with expression
 | 
			
		||||
0:6        texture ( temp 4-component vector of float)
 | 
			
		||||
0:6          Construct combined texture-sampler ( temp sampler2D)
 | 
			
		||||
0:?             'tex' ( in texture2D)
 | 
			
		||||
0:?             'smpl' ( in sampler)
 | 
			
		||||
0:?           Construct vec2 ( temp 2-component vector of float)
 | 
			
		||||
0:?             'f' ( in float)
 | 
			
		||||
0:?             'f' ( in float)
 | 
			
		||||
0:10  Function Definition: @main( ( temp 4-component vector of float)
 | 
			
		||||
0:10    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:11      Sequence
 | 
			
		||||
0:?         Sequence
 | 
			
		||||
0:11          move second child to first child ( temp float)
 | 
			
		||||
0:?             'f' ( temp float)
 | 
			
		||||
0:11            Constant:
 | 
			
		||||
0:11              0.500000
 | 
			
		||||
0:12      Branch: Return with expression
 | 
			
		||||
0:12        Function Call: lookUp(struct-FxaaTex-p1-t21-f11; ( temp 4-component vector of float)
 | 
			
		||||
0:?           'g_tInputTexture_sampler' ( uniform sampler)
 | 
			
		||||
0:?           'g_tInputTexture' ( uniform texture2D)
 | 
			
		||||
0:?           'f' ( temp float)
 | 
			
		||||
0:10  Function Definition: main( ( temp void)
 | 
			
		||||
0:10    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:10      move second child to first child ( temp 4-component vector of float)
 | 
			
		||||
0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
 | 
			
		||||
0:10        Function Call: @main( ( temp 4-component vector of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'g_tInputTexture_sampler' ( uniform sampler)
 | 
			
		||||
0:?     'g_tInputTexture' ( uniform texture2D)
 | 
			
		||||
0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 80001
 | 
			
		||||
// Id's are bound by 46
 | 
			
		||||
 | 
			
		||||
                              Capability Shader
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint Vertex 4  "main" 44
 | 
			
		||||
                              Source HLSL 500
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 17  "lookUp(struct-FxaaTex-p1-t21-f11;"
 | 
			
		||||
                              Name 14  "smpl"
 | 
			
		||||
                              Name 15  "tex"
 | 
			
		||||
                              Name 16  "f"
 | 
			
		||||
                              Name 20  "@main("
 | 
			
		||||
                              Name 34  "f"
 | 
			
		||||
                              Name 36  "g_tInputTexture_sampler"
 | 
			
		||||
                              Name 37  "g_tInputTexture"
 | 
			
		||||
                              Name 38  "param"
 | 
			
		||||
                              Name 44  "@entryPointOutput"
 | 
			
		||||
                              Decorate 36(g_tInputTexture_sampler) DescriptorSet 0
 | 
			
		||||
                              Decorate 37(g_tInputTexture) DescriptorSet 0
 | 
			
		||||
                              Decorate 44(@entryPointOutput) Location 0
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               6:             TypeSampler
 | 
			
		||||
               7:             TypePointer UniformConstant 6
 | 
			
		||||
               8:             TypeFloat 32
 | 
			
		||||
               9:             TypeImage 8(float) 2D sampled format:Unknown
 | 
			
		||||
              10:             TypePointer UniformConstant 9
 | 
			
		||||
              11:             TypePointer Function 8(float)
 | 
			
		||||
              12:             TypeVector 8(float) 4
 | 
			
		||||
              13:             TypeFunction 12(fvec4) 7(ptr) 10(ptr) 11(ptr)
 | 
			
		||||
              19:             TypeFunction 12(fvec4)
 | 
			
		||||
              24:             TypeSampledImage 9
 | 
			
		||||
              28:             TypeVector 8(float) 2
 | 
			
		||||
              30:    8(float) Constant 0
 | 
			
		||||
              35:    8(float) Constant 1056964608
 | 
			
		||||
36(g_tInputTexture_sampler):      7(ptr) Variable UniformConstant
 | 
			
		||||
37(g_tInputTexture):     10(ptr) Variable UniformConstant
 | 
			
		||||
              43:             TypePointer Output 12(fvec4)
 | 
			
		||||
44(@entryPointOutput):     43(ptr) Variable Output
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
              45:   12(fvec4) FunctionCall 20(@main()
 | 
			
		||||
                              Store 44(@entryPointOutput) 45
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
17(lookUp(struct-FxaaTex-p1-t21-f11;):   12(fvec4) Function None 13
 | 
			
		||||
        14(smpl):      7(ptr) FunctionParameter
 | 
			
		||||
         15(tex):     10(ptr) FunctionParameter
 | 
			
		||||
           16(f):     11(ptr) FunctionParameter
 | 
			
		||||
              18:             Label
 | 
			
		||||
              22:           9 Load 15(tex)
 | 
			
		||||
              23:           6 Load 14(smpl)
 | 
			
		||||
              25:          24 SampledImage 22 23
 | 
			
		||||
              26:    8(float) Load 16(f)
 | 
			
		||||
              27:    8(float) Load 16(f)
 | 
			
		||||
              29:   28(fvec2) CompositeConstruct 26 27
 | 
			
		||||
              31:   12(fvec4) ImageSampleExplicitLod 25 29 Lod 30
 | 
			
		||||
                              ReturnValue 31
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
      20(@main():   12(fvec4) Function None 19
 | 
			
		||||
              21:             Label
 | 
			
		||||
           34(f):     11(ptr) Variable Function
 | 
			
		||||
       38(param):     11(ptr) Variable Function
 | 
			
		||||
                              Store 34(f) 35
 | 
			
		||||
              39:    8(float) Load 34(f)
 | 
			
		||||
                              Store 38(param) 39
 | 
			
		||||
              40:   12(fvec4) FunctionCall 17(lookUp(struct-FxaaTex-p1-t21-f11;) 36(g_tInputTexture_sampler) 37(g_tInputTexture) 38(param)
 | 
			
		||||
                              ReturnValue 40
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										13
									
								
								Test/hlsl.flattenOpaqueInit.vert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Test/hlsl.flattenOpaqueInit.vert
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
struct FxaaTex { SamplerState smpl; Texture2D tex; };
 | 
			
		||||
SamplerState g_tInputTexture_sampler; Texture2D g_tInputTexture;
 | 
			
		||||
 | 
			
		||||
float4 lookUp(FxaaTex tex)
 | 
			
		||||
{
 | 
			
		||||
    return tex.tex.Sample(tex.smpl, float2(0.3, 0.4));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float4 main() : SV_TARGET0
 | 
			
		||||
{
 | 
			
		||||
    FxaaTex tex = { g_tInputTexture_sampler, g_tInputTexture };
 | 
			
		||||
    return lookUp(tex);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								Test/hlsl.flattenOpaqueInitMix.vert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Test/hlsl.flattenOpaqueInitMix.vert
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
struct FxaaTex { SamplerState smpl; Texture2D tex; float f; };
 | 
			
		||||
SamplerState g_tInputTexture_sampler; Texture2D g_tInputTexture;
 | 
			
		||||
 | 
			
		||||
float4 lookUp(FxaaTex tex)
 | 
			
		||||
{
 | 
			
		||||
    return tex.tex.Sample(tex.smpl, float2(tex.f, tex.f));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float4 main() : SV_TARGET0
 | 
			
		||||
{
 | 
			
		||||
    FxaaTex tex = { g_tInputTexture_sampler, g_tInputTexture, 0.5 };
 | 
			
		||||
    return lookUp(tex);
 | 
			
		||||
}
 | 
			
		||||
@ -122,6 +122,8 @@ INSTANTIATE_TEST_CASE_P(
 | 
			
		||||
        {"hlsl.float4.frag", "PixelShaderFunction"},
 | 
			
		||||
        {"hlsl.flatten.return.frag", "main"},
 | 
			
		||||
        {"hlsl.flattenOpaque.frag", "main"},
 | 
			
		||||
        {"hlsl.flattenOpaqueInit.vert", "main"},
 | 
			
		||||
        {"hlsl.flattenOpaqueInitMix.vert", "main"},
 | 
			
		||||
        {"hlsl.forLoop.frag", "PixelShaderFunction"},
 | 
			
		||||
        {"hlsl.gather.array.dx10.frag", "main"},
 | 
			
		||||
        {"hlsl.gather.basic.dx10.frag", "main"},
 | 
			
		||||
 | 
			
		||||
@ -506,12 +506,14 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deal with sampler aliasing: turning assignments into aliases
 | 
			
		||||
// Return a placeholder node for higher-level code that think assignments must
 | 
			
		||||
// generate code.
 | 
			
		||||
TIntermTyped* HlslParseContext::handleSamplerLvalue(const TSourceLoc& loc, const char* op, TIntermTyped*& node)
 | 
			
		||||
{
 | 
			
		||||
    // Can only alias an assignment:  "s1 = s2"
 | 
			
		||||
    TIntermBinary* binary = node->getAsBinaryNode();
 | 
			
		||||
    if (binary == nullptr || node->getAsOperator()->getOp() != EOpAssign ||
 | 
			
		||||
        binary->getLeft() ->getAsSymbolNode() == nullptr ||
 | 
			
		||||
        binary->getLeft()->getAsSymbolNode() == nullptr ||
 | 
			
		||||
        binary->getRight()->getAsSymbolNode() == nullptr) {
 | 
			
		||||
        error(loc, "can't modify sampler", op, "");
 | 
			
		||||
        return node;
 | 
			
		||||
@ -520,11 +522,25 @@ TIntermTyped* HlslParseContext::handleSamplerLvalue(const TSourceLoc& loc, const
 | 
			
		||||
    if (controlFlowNestingLevel > 0)
 | 
			
		||||
        warn(loc, "sampler or image aliased under control flow; consumption must be in same path", op, "");
 | 
			
		||||
 | 
			
		||||
    TIntermTyped* set = setOpaqueLvalue(binary->getLeft(), binary->getRight());
 | 
			
		||||
    if (set == nullptr)
 | 
			
		||||
        warn(loc, "could not create alias for sampler", op, "");
 | 
			
		||||
    else
 | 
			
		||||
        node = set;
 | 
			
		||||
 | 
			
		||||
    return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Do an opaque assignment that needs to turn into an alias.
 | 
			
		||||
// Return nullptr if it can't be done, otherwise return a placeholder
 | 
			
		||||
// node for higher-level code that think assignments must generate code.
 | 
			
		||||
TIntermTyped* HlslParseContext::setOpaqueLvalue(TIntermTyped* leftTyped, TIntermTyped* rightTyped)
 | 
			
		||||
{
 | 
			
		||||
    // Best is if we are aliasing a flattened struct member "S.s1 = s2",
 | 
			
		||||
    // in which case we want to update the flattening information with the alias,
 | 
			
		||||
    // making everything else work seamlessly.
 | 
			
		||||
    TIntermSymbol* left = binary->getLeft()->getAsSymbolNode();
 | 
			
		||||
    TIntermSymbol* right = binary->getRight()->getAsSymbolNode();
 | 
			
		||||
    TIntermSymbol* left = leftTyped->getAsSymbolNode();
 | 
			
		||||
    TIntermSymbol* right = rightTyped->getAsSymbolNode();
 | 
			
		||||
    for (auto fit = flattenMap.begin(); fit != flattenMap.end(); ++fit) {
 | 
			
		||||
        for (auto mit = fit->second.members.begin(); mit != fit->second.members.end(); ++mit) {
 | 
			
		||||
            if ((*mit)->getUniqueId() == left->getId()) {
 | 
			
		||||
@ -533,15 +549,12 @@ TIntermTyped* HlslParseContext::handleSamplerLvalue(const TSourceLoc& loc, const
 | 
			
		||||
                (*mit)->setUniqueId(right->getId());
 | 
			
		||||
                // replace node (rest of compiler expects either an error or code to generate)
 | 
			
		||||
                // with pointless access
 | 
			
		||||
                node = binary->getRight();
 | 
			
		||||
                return node;
 | 
			
		||||
                return right;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    warn(loc, "could not create alias for sampler", op, "");
 | 
			
		||||
 | 
			
		||||
    return node;
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HlslParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
 | 
			
		||||
@ -2412,6 +2425,34 @@ TIntermAggregate* HlslParseContext::assignClipCullDistance(const TSourceLoc& loc
 | 
			
		||||
    return assignList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// For a declaration with an initializer, where the initialized symbol is flattened,
 | 
			
		||||
// and possibly contains opaque values, such that the initializer should never exist
 | 
			
		||||
// as emitted code, because even creating the initializer would write opaques.
 | 
			
		||||
//
 | 
			
		||||
// Decompose this into individual member-wise assignments, which themselves are
 | 
			
		||||
// expected to then not exist for opaque types, because they will turn into aliases.
 | 
			
		||||
//
 | 
			
		||||
// Return a node that contains the non-aliased assignments that must continue to exist.
 | 
			
		||||
TIntermAggregate* HlslParseContext::flattenedInit(const TSourceLoc& loc, TIntermSymbol* symbol, const TIntermAggregate& initializer)
 | 
			
		||||
{
 | 
			
		||||
    TIntermAggregate* initList = nullptr;
 | 
			
		||||
    // synthesize an access to each member, and then an assignment to it
 | 
			
		||||
    const TTypeList& typeList = *symbol->getType().getStruct();
 | 
			
		||||
    for (int member = 0; member < (int)typeList.size(); ++member) {
 | 
			
		||||
        TIntermTyped* memberInitializer = initializer.getSequence()[member]->getAsTyped();
 | 
			
		||||
        TIntermTyped* flattenedMember = flattenAccess(symbol, member);
 | 
			
		||||
        if (flattenedMember->getType().containsOpaque())
 | 
			
		||||
            setOpaqueLvalue(flattenedMember, memberInitializer);
 | 
			
		||||
        else
 | 
			
		||||
            initList = intermediate.growAggregate(initList, handleAssign(loc, EOpAssign, flattenedMember,
 | 
			
		||||
                                                  memberInitializer));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (initList)
 | 
			
		||||
        initList->setOperator(EOpSequence);
 | 
			
		||||
    return initList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Some simple source assignments need to be flattened to a sequence
 | 
			
		||||
// of AST assignments. Catch these and flatten, otherwise, pass through
 | 
			
		||||
// to intermediate.addAssign().
 | 
			
		||||
@ -2449,7 +2490,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
 | 
			
		||||
 | 
			
		||||
    // A temporary to store the right node's value, so we don't keep indirecting into it
 | 
			
		||||
    // if it's not a simple symbol.
 | 
			
		||||
    TVariable*     rhsTempVar   = nullptr;
 | 
			
		||||
    TVariable* rhsTempVar = nullptr;
 | 
			
		||||
 | 
			
		||||
    // If the RHS is a simple symbol node, we'll copy it for each member.
 | 
			
		||||
    TIntermSymbol* cloneSymNode = nullptr;
 | 
			
		||||
@ -7222,27 +7263,22 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, const TStr
 | 
			
		||||
            error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (flattenVar)
 | 
			
		||||
        flatten(loc, *symbol->getAsVariable());
 | 
			
		||||
 | 
			
		||||
    if (symbol == nullptr)
 | 
			
		||||
        return nullptr;
 | 
			
		||||
 | 
			
		||||
    if (flattenVar)
 | 
			
		||||
        flatten(loc, *symbol->getAsVariable());
 | 
			
		||||
 | 
			
		||||
    if (initializer == nullptr)
 | 
			
		||||
        return nullptr;
 | 
			
		||||
 | 
			
		||||
    // Deal with initializer
 | 
			
		||||
    TIntermNode* initNode = nullptr;
 | 
			
		||||
    if (symbol && initializer) {
 | 
			
		||||
        if (flattenVar)
 | 
			
		||||
            error(loc, "flattened array with initializer list unsupported", identifier.c_str(), "");
 | 
			
		||||
 | 
			
		||||
        TVariable* variable = symbol->getAsVariable();
 | 
			
		||||
        if (variable == nullptr) {
 | 
			
		||||
            error(loc, "initializer requires a variable, not a member", identifier.c_str(), "");
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
        initNode = executeInitializer(loc, initializer, variable);
 | 
			
		||||
    TVariable* variable = symbol->getAsVariable();
 | 
			
		||||
    if (variable == nullptr) {
 | 
			
		||||
        error(loc, "initializer requires a variable, not a member", identifier.c_str(), "");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return initNode;
 | 
			
		||||
    return executeInitializer(loc, initializer, variable, flattenVar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pick up global defaults from the provide global defaults into dst.
 | 
			
		||||
@ -7308,7 +7344,7 @@ TVariable* HlslParseContext::declareNonArray(const TSourceLoc& loc, const TStrin
 | 
			
		||||
// Returning nullptr just means there is no code to execute to handle the
 | 
			
		||||
// initializer, which will, for example, be the case for constant initializers.
 | 
			
		||||
//
 | 
			
		||||
TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
 | 
			
		||||
TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable, bool flattened)
 | 
			
		||||
{
 | 
			
		||||
    //
 | 
			
		||||
    // Identifier must be of type constant, a global, or a temporary, and
 | 
			
		||||
@ -7329,6 +7365,7 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
 | 
			
		||||
    TType skeletalType;
 | 
			
		||||
    skeletalType.shallowCopy(variable->getType());
 | 
			
		||||
    skeletalType.getQualifier().makeTemporary();
 | 
			
		||||
    TIntermAggregate* initializerList = nullptr;
 | 
			
		||||
    if (initializer->getAsAggregate() && initializer->getAsAggregate()->getOp() == EOpNull)
 | 
			
		||||
        initializer = convertInitializerList(loc, skeletalType, initializer, nullptr);
 | 
			
		||||
    if (initializer == nullptr) {
 | 
			
		||||
@ -7388,11 +7425,20 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
 | 
			
		||||
        // normal assigning of a value to a variable...
 | 
			
		||||
        specializationCheck(loc, initializer->getType(), "initializer");
 | 
			
		||||
        TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
 | 
			
		||||
        TIntermNode* initNode = handleAssign(loc, EOpAssign, intermSymbol, initializer);
 | 
			
		||||
        if (initNode == nullptr)
 | 
			
		||||
            assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
 | 
			
		||||
 | 
			
		||||
        return initNode;
 | 
			
		||||
        // If we are flattening, it could be due to setting opaques, which must be handled
 | 
			
		||||
        // as aliases, and the 'initializer' node cannot actually be emitted, because it
 | 
			
		||||
        // itself stores the result of the constructor, and we can't store to opaques.
 | 
			
		||||
        // handleAssign() will emit the initializer.
 | 
			
		||||
        TIntermNode* initNode = nullptr;
 | 
			
		||||
        if (flattened && intermSymbol->getType().containsOpaque())
 | 
			
		||||
            return flattenedInit(loc, intermSymbol, *initializer->getAsAggregate());
 | 
			
		||||
        else {
 | 
			
		||||
            initNode = handleAssign(loc, EOpAssign, intermSymbol, initializer);
 | 
			
		||||
            if (initNode == nullptr)
 | 
			
		||||
                assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
 | 
			
		||||
            return initNode;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return nullptr;
 | 
			
		||||
 | 
			
		||||
@ -87,6 +87,7 @@ public:
 | 
			
		||||
    void remapNonEntryPointIO(TFunction& function);
 | 
			
		||||
    TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
 | 
			
		||||
    void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg);
 | 
			
		||||
    TIntermAggregate* flattenedInit(const TSourceLoc&, TIntermSymbol*, const TIntermAggregate&);
 | 
			
		||||
    TIntermTyped* handleAssign(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
 | 
			
		||||
    TIntermTyped* handleAssignToMatrixSwizzle(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
 | 
			
		||||
    TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermTyped*);
 | 
			
		||||
@ -191,6 +192,7 @@ public:
 | 
			
		||||
    // 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* handleSamplerLvalue(const TSourceLoc&, const char* op, TIntermTyped*& node);
 | 
			
		||||
    TIntermTyped* setOpaqueLvalue(TIntermTyped* left, TIntermTyped* right);
 | 
			
		||||
    bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
 | 
			
		||||
 | 
			
		||||
    TLayoutFormat getLayoutFromTxType(const TSourceLoc&, const TType&);
 | 
			
		||||
@ -231,7 +233,7 @@ protected:
 | 
			
		||||
    TIntermSymbol* makeInternalVariableNode(const TSourceLoc&, const char* name, const TType&) const;
 | 
			
		||||
    TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&, bool track);
 | 
			
		||||
    void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&, bool track);
 | 
			
		||||
    TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
 | 
			
		||||
    TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable, bool flattened);
 | 
			
		||||
    TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer, TIntermTyped* scalarInit);
 | 
			
		||||
    bool isScalarConstructor(const TIntermNode*);
 | 
			
		||||
    TOperator mapAtomicOp(const TSourceLoc& loc, TOperator op, bool isImage);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user