1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci#include <string>
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
18fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
19fd4e5da5Sopenharmony_ci
20fd4e5da5Sopenharmony_cinamespace spvtools {
21fd4e5da5Sopenharmony_cinamespace opt {
22fd4e5da5Sopenharmony_cinamespace {
23fd4e5da5Sopenharmony_ci
24fd4e5da5Sopenharmony_ciusing DescriptorScalarReplacementTest = PassTest<::testing::Test>;
25fd4e5da5Sopenharmony_ci
26fd4e5da5Sopenharmony_cistd::string GetStructureArrayTestSpirv() {
27fd4e5da5Sopenharmony_ci  // The SPIR-V for the following high-level shader:
28fd4e5da5Sopenharmony_ci  // Flattening structures and arrays should result in the following binding
29fd4e5da5Sopenharmony_ci  // numbers. Only the ones that are actually used in the shader should be in
30fd4e5da5Sopenharmony_ci  // the final SPIR-V.
31fd4e5da5Sopenharmony_ci  //
32fd4e5da5Sopenharmony_ci  // globalS[0][0].t[0]  0 (used)
33fd4e5da5Sopenharmony_ci  // globalS[0][0].t[1]  1
34fd4e5da5Sopenharmony_ci  // globalS[0][0].s[0]  2 (used)
35fd4e5da5Sopenharmony_ci  // globalS[0][0].s[1]  3
36fd4e5da5Sopenharmony_ci  // globalS[0][1].t[0]  4
37fd4e5da5Sopenharmony_ci  // globalS[0][1].t[1]  5
38fd4e5da5Sopenharmony_ci  // globalS[0][1].s[0]  6
39fd4e5da5Sopenharmony_ci  // globalS[0][1].s[1]  7
40fd4e5da5Sopenharmony_ci  // globalS[1][0].t[0]  8
41fd4e5da5Sopenharmony_ci  // globalS[1][0].t[1]  9
42fd4e5da5Sopenharmony_ci  // globalS[1][0].s[0]  10
43fd4e5da5Sopenharmony_ci  // globalS[1][0].s[1]  11
44fd4e5da5Sopenharmony_ci  // globalS[1][1].t[0]  12
45fd4e5da5Sopenharmony_ci  // globalS[1][1].t[1]  13 (used)
46fd4e5da5Sopenharmony_ci  // globalS[1][1].s[0]  14
47fd4e5da5Sopenharmony_ci  // globalS[1][1].s[1]  15 (used)
48fd4e5da5Sopenharmony_ci
49fd4e5da5Sopenharmony_ci  /*
50fd4e5da5Sopenharmony_ci    struct S {
51fd4e5da5Sopenharmony_ci      Texture2D t[2];
52fd4e5da5Sopenharmony_ci      SamplerState s[2];
53fd4e5da5Sopenharmony_ci    };
54fd4e5da5Sopenharmony_ci
55fd4e5da5Sopenharmony_ci    S globalS[2][2];
56fd4e5da5Sopenharmony_ci
57fd4e5da5Sopenharmony_ci    float4 main() : SV_Target {
58fd4e5da5Sopenharmony_ci      return globalS[0][0].t[0].Sample(globalS[0][0].s[0], float2(0,0)) +
59fd4e5da5Sopenharmony_ci             globalS[1][1].t[1].Sample(globalS[1][1].s[1], float2(0,0));
60fd4e5da5Sopenharmony_ci    }
61fd4e5da5Sopenharmony_ci  */
62fd4e5da5Sopenharmony_ci
63fd4e5da5Sopenharmony_ci  return R"(
64fd4e5da5Sopenharmony_ci               OpCapability Shader
65fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
66fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %out_var_SV_Target
67fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
68fd4e5da5Sopenharmony_ci               OpName %S "S"
69fd4e5da5Sopenharmony_ci               OpMemberName %S 0 "t"
70fd4e5da5Sopenharmony_ci               OpMemberName %S 1 "s"
71fd4e5da5Sopenharmony_ci               OpName %type_2d_image "type.2d.image"
72fd4e5da5Sopenharmony_ci               OpName %type_sampler "type.sampler"
73fd4e5da5Sopenharmony_ci               OpName %globalS "globalS"
74fd4e5da5Sopenharmony_ci               OpName %out_var_SV_Target "out.var.SV_Target"
75fd4e5da5Sopenharmony_ci               OpName %main "main"
76fd4e5da5Sopenharmony_ci               OpName %src_main "src.main"
77fd4e5da5Sopenharmony_ci               OpName %bb_entry "bb.entry"
78fd4e5da5Sopenharmony_ci               OpName %type_sampled_image "type.sampled.image"
79fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target Location 0
80fd4e5da5Sopenharmony_ci               OpDecorate %globalS DescriptorSet 0
81fd4e5da5Sopenharmony_ci               OpDecorate %globalS Binding 0
82fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
83fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
84fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
85fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
86fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
87fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
88fd4e5da5Sopenharmony_ci         %10 = OpConstantComposite %v2float %float_0 %float_0
89fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
90fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
91fd4e5da5Sopenharmony_ci%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
92fd4e5da5Sopenharmony_ci%_arr_type_2d_image_uint_2 = OpTypeArray %type_2d_image %uint_2
93fd4e5da5Sopenharmony_ci%type_sampler = OpTypeSampler
94fd4e5da5Sopenharmony_ci%_arr_type_sampler_uint_2 = OpTypeArray %type_sampler %uint_2
95fd4e5da5Sopenharmony_ci          %S = OpTypeStruct %_arr_type_2d_image_uint_2 %_arr_type_sampler_uint_2
96fd4e5da5Sopenharmony_ci%_arr_S_uint_2 = OpTypeArray %S %uint_2
97fd4e5da5Sopenharmony_ci%_arr__arr_S_uint_2_uint_2 = OpTypeArray %_arr_S_uint_2 %uint_2
98fd4e5da5Sopenharmony_ci%_ptr_UniformConstant__arr__arr_S_uint_2_uint_2 = OpTypePointer UniformConstant %_arr__arr_S_uint_2_uint_2
99fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
100fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
101fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
102fd4e5da5Sopenharmony_ci         %24 = OpTypeFunction %void
103fd4e5da5Sopenharmony_ci         %28 = OpTypeFunction %v4float
104fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
105fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
106fd4e5da5Sopenharmony_ci%type_sampled_image = OpTypeSampledImage %type_2d_image
107fd4e5da5Sopenharmony_ci    %globalS = OpVariable %_ptr_UniformConstant__arr__arr_S_uint_2_uint_2 UniformConstant
108fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
109fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %24
110fd4e5da5Sopenharmony_ci         %25 = OpLabel
111fd4e5da5Sopenharmony_ci         %26 = OpFunctionCall %v4float %src_main
112fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_Target %26
113fd4e5da5Sopenharmony_ci               OpReturn
114fd4e5da5Sopenharmony_ci               OpFunctionEnd
115fd4e5da5Sopenharmony_ci   %src_main = OpFunction %v4float None %28
116fd4e5da5Sopenharmony_ci   %bb_entry = OpLabel
117fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %_ptr_UniformConstant_type_2d_image %globalS %int_0 %int_0 %int_0 %int_0
118fd4e5da5Sopenharmony_ci         %32 = OpLoad %type_2d_image %31
119fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %_ptr_UniformConstant_type_sampler %globalS %int_0 %int_0 %int_1 %int_0
120fd4e5da5Sopenharmony_ci         %35 = OpLoad %type_sampler %34
121fd4e5da5Sopenharmony_ci         %37 = OpSampledImage %type_sampled_image %32 %35
122fd4e5da5Sopenharmony_ci         %38 = OpImageSampleImplicitLod %v4float %37 %10 None
123fd4e5da5Sopenharmony_ci         %39 = OpAccessChain %_ptr_UniformConstant_type_2d_image %globalS %int_1 %int_1 %int_0 %int_1
124fd4e5da5Sopenharmony_ci         %40 = OpLoad %type_2d_image %39
125fd4e5da5Sopenharmony_ci         %41 = OpAccessChain %_ptr_UniformConstant_type_sampler %globalS %int_1 %int_1 %int_1 %int_1
126fd4e5da5Sopenharmony_ci         %42 = OpLoad %type_sampler %41
127fd4e5da5Sopenharmony_ci         %43 = OpSampledImage %type_sampled_image %40 %42
128fd4e5da5Sopenharmony_ci         %44 = OpImageSampleImplicitLod %v4float %43 %10 None
129fd4e5da5Sopenharmony_ci         %45 = OpFAdd %v4float %38 %44
130fd4e5da5Sopenharmony_ci               OpReturnValue %45
131fd4e5da5Sopenharmony_ci               OpFunctionEnd
132fd4e5da5Sopenharmony_ci  )";
133fd4e5da5Sopenharmony_ci}
134fd4e5da5Sopenharmony_ci
135fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, ExpandArrayOfTextures) {
136fd4e5da5Sopenharmony_ci  const std::string text = R"(
137fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var1:%\w+]] DescriptorSet 0
138fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var1]] Binding 0
139fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var2:%\w+]] DescriptorSet 0
140fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var2]] Binding 1
141fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var3:%\w+]] DescriptorSet 0
142fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var3]] Binding 2
143fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var4:%\w+]] DescriptorSet 0
144fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var4]] Binding 3
145fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var5:%\w+]] DescriptorSet 0
146fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var5]] Binding 4
147fd4e5da5Sopenharmony_ci; CHECK: [[image_type:%\w+]] = OpTypeImage
148fd4e5da5Sopenharmony_ci; CHECK: [[ptr_type:%\w+]] = OpTypePointer UniformConstant [[image_type]]
149fd4e5da5Sopenharmony_ci; CHECK: [[var1]] = OpVariable [[ptr_type]] UniformConstant
150fd4e5da5Sopenharmony_ci; CHECK: [[var2]] = OpVariable [[ptr_type]] UniformConstant
151fd4e5da5Sopenharmony_ci; CHECK: [[var3]] = OpVariable [[ptr_type]] UniformConstant
152fd4e5da5Sopenharmony_ci; CHECK: [[var4]] = OpVariable [[ptr_type]] UniformConstant
153fd4e5da5Sopenharmony_ci; CHECK: [[var5]] = OpVariable [[ptr_type]] UniformConstant
154fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[image_type]] [[var1]]
155fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[image_type]] [[var2]]
156fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[image_type]] [[var3]]
157fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[image_type]] [[var4]]
158fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[image_type]] [[var5]]
159fd4e5da5Sopenharmony_ci               OpCapability Shader
160fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
161fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
162fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
163fd4e5da5Sopenharmony_ci               OpSource HLSL 600
164fd4e5da5Sopenharmony_ci               OpDecorate %MyTextures DescriptorSet 0
165fd4e5da5Sopenharmony_ci               OpDecorate %MyTextures Binding 0
166fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
167fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
168fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
169fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
170fd4e5da5Sopenharmony_ci      %int_3 = OpConstant %int 3
171fd4e5da5Sopenharmony_ci      %int_4 = OpConstant %int 4
172fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
173fd4e5da5Sopenharmony_ci     %uint_5 = OpConstant %uint 5
174fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
175fd4e5da5Sopenharmony_ci%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
176fd4e5da5Sopenharmony_ci%_arr_type_2d_image_uint_5 = OpTypeArray %type_2d_image %uint_5
177fd4e5da5Sopenharmony_ci%_ptr_UniformConstant__arr_type_2d_image_uint_5 = OpTypePointer UniformConstant %_arr_type_2d_image_uint_5
178fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
179fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
180fd4e5da5Sopenharmony_ci         %26 = OpTypeFunction %void
181fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
182fd4e5da5Sopenharmony_ci %MyTextures = OpVariable %_ptr_UniformConstant__arr_type_2d_image_uint_5 UniformConstant
183fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %26
184fd4e5da5Sopenharmony_ci         %28 = OpLabel
185fd4e5da5Sopenharmony_ci         %29 = OpUndef %v2float
186fd4e5da5Sopenharmony_ci         %30 = OpAccessChain %_ptr_UniformConstant_type_2d_image %MyTextures %int_0
187fd4e5da5Sopenharmony_ci         %31 = OpLoad %type_2d_image %30
188fd4e5da5Sopenharmony_ci         %35 = OpAccessChain %_ptr_UniformConstant_type_2d_image %MyTextures %int_1
189fd4e5da5Sopenharmony_ci         %36 = OpLoad %type_2d_image %35
190fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %_ptr_UniformConstant_type_2d_image %MyTextures %int_2
191fd4e5da5Sopenharmony_ci         %41 = OpLoad %type_2d_image %40
192fd4e5da5Sopenharmony_ci         %45 = OpAccessChain %_ptr_UniformConstant_type_2d_image %MyTextures %int_3
193fd4e5da5Sopenharmony_ci         %46 = OpLoad %type_2d_image %45
194fd4e5da5Sopenharmony_ci         %50 = OpAccessChain %_ptr_UniformConstant_type_2d_image %MyTextures %int_4
195fd4e5da5Sopenharmony_ci         %51 = OpLoad %type_2d_image %50
196fd4e5da5Sopenharmony_ci               OpReturn
197fd4e5da5Sopenharmony_ci               OpFunctionEnd
198fd4e5da5Sopenharmony_ci
199fd4e5da5Sopenharmony_ci  )";
200fd4e5da5Sopenharmony_ci
201fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
202fd4e5da5Sopenharmony_ci}
203fd4e5da5Sopenharmony_ci
204fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, ExpandArrayOfSamplers) {
205fd4e5da5Sopenharmony_ci  const std::string text = R"(
206fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var1:%\w+]] DescriptorSet 0
207fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var1]] Binding 1
208fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var2:%\w+]] DescriptorSet 0
209fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var2]] Binding 2
210fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var3:%\w+]] DescriptorSet 0
211fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var3]] Binding 3
212fd4e5da5Sopenharmony_ci; CHECK: [[sampler_type:%\w+]] = OpTypeSampler
213fd4e5da5Sopenharmony_ci; CHECK: [[ptr_type:%\w+]] = OpTypePointer UniformConstant [[sampler_type]]
214fd4e5da5Sopenharmony_ci; CHECK: [[var1]] = OpVariable [[ptr_type]] UniformConstant
215fd4e5da5Sopenharmony_ci; CHECK: [[var2]] = OpVariable [[ptr_type]] UniformConstant
216fd4e5da5Sopenharmony_ci; CHECK: [[var3]] = OpVariable [[ptr_type]] UniformConstant
217fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[sampler_type]] [[var1]]
218fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[sampler_type]] [[var2]]
219fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[sampler_type]] [[var3]]
220fd4e5da5Sopenharmony_ci               OpCapability Shader
221fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
222fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
223fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
224fd4e5da5Sopenharmony_ci               OpSource HLSL 600
225fd4e5da5Sopenharmony_ci               OpDecorate %MySampler DescriptorSet 0
226fd4e5da5Sopenharmony_ci               OpDecorate %MySampler Binding 1
227fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
228fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
229fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
230fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
231fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
232fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
233fd4e5da5Sopenharmony_ci%type_sampler = OpTypeSampler
234fd4e5da5Sopenharmony_ci%_arr_type_sampler_uint_3 = OpTypeArray %type_sampler %uint_3
235fd4e5da5Sopenharmony_ci%_ptr_UniformConstant__arr_type_sampler_uint_3 = OpTypePointer UniformConstant %_arr_type_sampler_uint_3
236fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
237fd4e5da5Sopenharmony_ci         %26 = OpTypeFunction %void
238fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
239fd4e5da5Sopenharmony_ci  %MySampler = OpVariable %_ptr_UniformConstant__arr_type_sampler_uint_3 UniformConstant
240fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %26
241fd4e5da5Sopenharmony_ci         %28 = OpLabel
242fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %_ptr_UniformConstant_type_sampler %MySampler %int_0
243fd4e5da5Sopenharmony_ci         %32 = OpLoad %type_sampler %31
244fd4e5da5Sopenharmony_ci         %35 = OpAccessChain %_ptr_UniformConstant_type_sampler %MySampler %int_1
245fd4e5da5Sopenharmony_ci         %36 = OpLoad %type_sampler %35
246fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %_ptr_UniformConstant_type_sampler %MySampler %int_2
247fd4e5da5Sopenharmony_ci         %41 = OpLoad %type_sampler %40
248fd4e5da5Sopenharmony_ci               OpReturn
249fd4e5da5Sopenharmony_ci               OpFunctionEnd
250fd4e5da5Sopenharmony_ci  )";
251fd4e5da5Sopenharmony_ci
252fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
253fd4e5da5Sopenharmony_ci}
254fd4e5da5Sopenharmony_ci
255fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, ExpandArrayOfSSBOs) {
256fd4e5da5Sopenharmony_ci  // Tests the expansion of an SSBO.  Also check that an access chain with more
257fd4e5da5Sopenharmony_ci  // than 1 index is correctly handled.
258fd4e5da5Sopenharmony_ci  const std::string text = R"(
259fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var1:%\w+]] DescriptorSet 0
260fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var1]] Binding 0
261fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var2:%\w+]] DescriptorSet 0
262fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var2]] Binding 1
263fd4e5da5Sopenharmony_ci; CHECK: OpTypeStruct
264fd4e5da5Sopenharmony_ci; CHECK: [[struct_type:%\w+]] = OpTypeStruct
265fd4e5da5Sopenharmony_ci; CHECK: [[ptr_type:%\w+]] = OpTypePointer Uniform [[struct_type]]
266fd4e5da5Sopenharmony_ci; CHECK: [[var1]] = OpVariable [[ptr_type]] Uniform
267fd4e5da5Sopenharmony_ci; CHECK: [[var2]] = OpVariable [[ptr_type]] Uniform
268fd4e5da5Sopenharmony_ci; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[var1]] %uint_0 %uint_0 %uint_0
269fd4e5da5Sopenharmony_ci; CHECK: OpLoad %v4float [[ac1]]
270fd4e5da5Sopenharmony_ci; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[var2]] %uint_0 %uint_0 %uint_0
271fd4e5da5Sopenharmony_ci; CHECK: OpLoad %v4float [[ac2]]
272fd4e5da5Sopenharmony_ci               OpCapability Shader
273fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
274fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
275fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
276fd4e5da5Sopenharmony_ci               OpSource HLSL 600
277fd4e5da5Sopenharmony_ci               OpDecorate %buffers DescriptorSet 0
278fd4e5da5Sopenharmony_ci               OpDecorate %buffers Binding 0
279fd4e5da5Sopenharmony_ci               OpMemberDecorate %S 0 Offset 0
280fd4e5da5Sopenharmony_ci               OpDecorate %_runtimearr_S ArrayStride 16
281fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_StructuredBuffer_S 0 Offset 0
282fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_StructuredBuffer_S 0 NonWritable
283fd4e5da5Sopenharmony_ci               OpDecorate %type_StructuredBuffer_S BufferBlock
284fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
285fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
286fd4e5da5Sopenharmony_ci      %uint_1 = OpConstant %uint 1
287fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
288fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
289fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
290fd4e5da5Sopenharmony_ci          %S = OpTypeStruct %v4float
291fd4e5da5Sopenharmony_ci%_runtimearr_S = OpTypeRuntimeArray %S
292fd4e5da5Sopenharmony_ci%type_StructuredBuffer_S = OpTypeStruct %_runtimearr_S
293fd4e5da5Sopenharmony_ci%_arr_type_StructuredBuffer_S_uint_2 = OpTypeArray %type_StructuredBuffer_S %uint_2
294fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_type_StructuredBuffer_S_uint_2 = OpTypePointer Uniform %_arr_type_StructuredBuffer_S_uint_2
295fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_StructuredBuffer_S = OpTypePointer Uniform %type_StructuredBuffer_S
296fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
297fd4e5da5Sopenharmony_ci         %19 = OpTypeFunction %void
298fd4e5da5Sopenharmony_ci%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
299fd4e5da5Sopenharmony_ci    %buffers = OpVariable %_ptr_Uniform__arr_type_StructuredBuffer_S_uint_2 Uniform
300fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %19
301fd4e5da5Sopenharmony_ci         %21 = OpLabel
302fd4e5da5Sopenharmony_ci         %22 = OpAccessChain %_ptr_Uniform_v4float %buffers %uint_0 %uint_0 %uint_0 %uint_0
303fd4e5da5Sopenharmony_ci         %23 = OpLoad %v4float %22
304fd4e5da5Sopenharmony_ci         %24 = OpAccessChain %_ptr_Uniform_type_StructuredBuffer_S %buffers %uint_1
305fd4e5da5Sopenharmony_ci         %25 = OpAccessChain %_ptr_Uniform_v4float %24 %uint_0 %uint_0 %uint_0
306fd4e5da5Sopenharmony_ci         %26 = OpLoad %v4float %25
307fd4e5da5Sopenharmony_ci               OpReturn
308fd4e5da5Sopenharmony_ci               OpFunctionEnd
309fd4e5da5Sopenharmony_ci  )";
310fd4e5da5Sopenharmony_ci
311fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
312fd4e5da5Sopenharmony_ci}
313fd4e5da5Sopenharmony_ci
314fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, NameNewVariables) {
315fd4e5da5Sopenharmony_ci  // Checks that if the original variable has a name, then the new variables
316fd4e5da5Sopenharmony_ci  // will have a name derived from that name.
317fd4e5da5Sopenharmony_ci  const std::string text = R"(
318fd4e5da5Sopenharmony_ci; CHECK: OpName [[var1:%\w+]] "SSBO[0]"
319fd4e5da5Sopenharmony_ci; CHECK: OpName [[var2:%\w+]] "SSBO[1]"
320fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var1]] DescriptorSet 0
321fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var1]] Binding 0
322fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var2]] DescriptorSet 0
323fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[var2]] Binding 1
324fd4e5da5Sopenharmony_ci; CHECK: OpTypeStruct
325fd4e5da5Sopenharmony_ci; CHECK: [[struct_type:%\w+]] = OpTypeStruct
326fd4e5da5Sopenharmony_ci; CHECK: [[ptr_type:%\w+]] = OpTypePointer Uniform [[struct_type]]
327fd4e5da5Sopenharmony_ci; CHECK: [[var1]] = OpVariable [[ptr_type]] Uniform
328fd4e5da5Sopenharmony_ci; CHECK: [[var2]] = OpVariable [[ptr_type]] Uniform
329fd4e5da5Sopenharmony_ci; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[var1]] %uint_0 %uint_0 %uint_0
330fd4e5da5Sopenharmony_ci; CHECK: OpLoad %v4float [[ac1]]
331fd4e5da5Sopenharmony_ci; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[var2]] %uint_0 %uint_0 %uint_0
332fd4e5da5Sopenharmony_ci; CHECK: OpLoad %v4float [[ac2]]
333fd4e5da5Sopenharmony_ci               OpCapability Shader
334fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
335fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
336fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
337fd4e5da5Sopenharmony_ci               OpSource HLSL 600
338fd4e5da5Sopenharmony_ci               OpName %buffers "SSBO"
339fd4e5da5Sopenharmony_ci               OpDecorate %buffers DescriptorSet 0
340fd4e5da5Sopenharmony_ci               OpDecorate %buffers Binding 0
341fd4e5da5Sopenharmony_ci               OpMemberDecorate %S 0 Offset 0
342fd4e5da5Sopenharmony_ci               OpDecorate %_runtimearr_S ArrayStride 16
343fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_StructuredBuffer_S 0 Offset 0
344fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_StructuredBuffer_S 0 NonWritable
345fd4e5da5Sopenharmony_ci               OpDecorate %type_StructuredBuffer_S BufferBlock
346fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
347fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
348fd4e5da5Sopenharmony_ci      %uint_1 = OpConstant %uint 1
349fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
350fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
351fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
352fd4e5da5Sopenharmony_ci          %S = OpTypeStruct %v4float
353fd4e5da5Sopenharmony_ci%_runtimearr_S = OpTypeRuntimeArray %S
354fd4e5da5Sopenharmony_ci%type_StructuredBuffer_S = OpTypeStruct %_runtimearr_S
355fd4e5da5Sopenharmony_ci%_arr_type_StructuredBuffer_S_uint_2 = OpTypeArray %type_StructuredBuffer_S %uint_2
356fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_type_StructuredBuffer_S_uint_2 = OpTypePointer Uniform %_arr_type_StructuredBuffer_S_uint_2
357fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_StructuredBuffer_S = OpTypePointer Uniform %type_StructuredBuffer_S
358fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
359fd4e5da5Sopenharmony_ci         %19 = OpTypeFunction %void
360fd4e5da5Sopenharmony_ci%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
361fd4e5da5Sopenharmony_ci    %buffers = OpVariable %_ptr_Uniform__arr_type_StructuredBuffer_S_uint_2 Uniform
362fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %19
363fd4e5da5Sopenharmony_ci         %21 = OpLabel
364fd4e5da5Sopenharmony_ci         %22 = OpAccessChain %_ptr_Uniform_v4float %buffers %uint_0 %uint_0 %uint_0 %uint_0
365fd4e5da5Sopenharmony_ci         %23 = OpLoad %v4float %22
366fd4e5da5Sopenharmony_ci         %24 = OpAccessChain %_ptr_Uniform_type_StructuredBuffer_S %buffers %uint_1
367fd4e5da5Sopenharmony_ci         %25 = OpAccessChain %_ptr_Uniform_v4float %24 %uint_0 %uint_0 %uint_0
368fd4e5da5Sopenharmony_ci         %26 = OpLoad %v4float %25
369fd4e5da5Sopenharmony_ci               OpReturn
370fd4e5da5Sopenharmony_ci               OpFunctionEnd
371fd4e5da5Sopenharmony_ci  )";
372fd4e5da5Sopenharmony_ci
373fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
374fd4e5da5Sopenharmony_ci}
375fd4e5da5Sopenharmony_ci
376fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, DontExpandCBuffers) {
377fd4e5da5Sopenharmony_ci  // Checks that constant buffers are not expanded.
378fd4e5da5Sopenharmony_ci  // Constant buffers are represented as global structures, but they should not
379fd4e5da5Sopenharmony_ci  // be replaced with new variables for their elements.
380fd4e5da5Sopenharmony_ci  /*
381fd4e5da5Sopenharmony_ci    cbuffer MyCbuffer : register(b1) {
382fd4e5da5Sopenharmony_ci      float2    a;
383fd4e5da5Sopenharmony_ci      float2   b;
384fd4e5da5Sopenharmony_ci    };
385fd4e5da5Sopenharmony_ci    float main() : A {
386fd4e5da5Sopenharmony_ci      return a.x + b.y;
387fd4e5da5Sopenharmony_ci    }
388fd4e5da5Sopenharmony_ci  */
389fd4e5da5Sopenharmony_ci  const std::string text = R"(
390fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %MyCbuffer %int_0 %int_0
391fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %MyCbuffer %int_1 %int_1
392fd4e5da5Sopenharmony_ci               OpCapability Shader
393fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
394fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main" %out_var_A
395fd4e5da5Sopenharmony_ci               OpSource HLSL 600
396fd4e5da5Sopenharmony_ci               OpName %type_MyCbuffer "type.MyCbuffer"
397fd4e5da5Sopenharmony_ci               OpMemberName %type_MyCbuffer 0 "a"
398fd4e5da5Sopenharmony_ci               OpMemberName %type_MyCbuffer 1 "b"
399fd4e5da5Sopenharmony_ci               OpName %MyCbuffer "MyCbuffer"
400fd4e5da5Sopenharmony_ci               OpName %out_var_A "out.var.A"
401fd4e5da5Sopenharmony_ci               OpName %main "main"
402fd4e5da5Sopenharmony_ci               OpDecorate %out_var_A Location 0
403fd4e5da5Sopenharmony_ci               OpDecorate %MyCbuffer DescriptorSet 0
404fd4e5da5Sopenharmony_ci               OpDecorate %MyCbuffer Binding 1
405fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_MyCbuffer 0 Offset 0
406fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_MyCbuffer 1 Offset 8
407fd4e5da5Sopenharmony_ci               OpDecorate %type_MyCbuffer Block
408fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
409fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
410fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
411fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
412fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
413fd4e5da5Sopenharmony_ci%type_MyCbuffer = OpTypeStruct %v2float %v2float
414fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCbuffer = OpTypePointer Uniform %type_MyCbuffer
415fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float
416fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
417fd4e5da5Sopenharmony_ci         %13 = OpTypeFunction %void
418fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
419fd4e5da5Sopenharmony_ci  %MyCbuffer = OpVariable %_ptr_Uniform_type_MyCbuffer Uniform
420fd4e5da5Sopenharmony_ci  %out_var_A = OpVariable %_ptr_Output_float Output
421fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %13
422fd4e5da5Sopenharmony_ci         %15 = OpLabel
423fd4e5da5Sopenharmony_ci         %16 = OpAccessChain %_ptr_Uniform_float %MyCbuffer %int_0 %int_0
424fd4e5da5Sopenharmony_ci         %17 = OpLoad %float %16
425fd4e5da5Sopenharmony_ci         %18 = OpAccessChain %_ptr_Uniform_float %MyCbuffer %int_1 %int_1
426fd4e5da5Sopenharmony_ci         %19 = OpLoad %float %18
427fd4e5da5Sopenharmony_ci         %20 = OpFAdd %float %17 %19
428fd4e5da5Sopenharmony_ci               OpStore %out_var_A %20
429fd4e5da5Sopenharmony_ci               OpReturn
430fd4e5da5Sopenharmony_ci               OpFunctionEnd
431fd4e5da5Sopenharmony_ci)";
432fd4e5da5Sopenharmony_ci
433fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
434fd4e5da5Sopenharmony_ci}
435fd4e5da5Sopenharmony_ci
436fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, DontExpandStructuredBuffers) {
437fd4e5da5Sopenharmony_ci  // Checks that structured buffers are not expanded.
438fd4e5da5Sopenharmony_ci  // Structured buffers are represented as global structures, that have one
439fd4e5da5Sopenharmony_ci  // member which is a runtime array.
440fd4e5da5Sopenharmony_ci  /*
441fd4e5da5Sopenharmony_ci    struct S {
442fd4e5da5Sopenharmony_ci      float2   a;
443fd4e5da5Sopenharmony_ci      float2   b;
444fd4e5da5Sopenharmony_ci    };
445fd4e5da5Sopenharmony_ci    RWStructuredBuffer<S> sb;
446fd4e5da5Sopenharmony_ci    float main() : A {
447fd4e5da5Sopenharmony_ci      return sb[0].a.x + sb[0].b.x;
448fd4e5da5Sopenharmony_ci    }
449fd4e5da5Sopenharmony_ci  */
450fd4e5da5Sopenharmony_ci  const std::string text = R"(
451fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %sb %int_0 %uint_0 %int_0 %int_0
452fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %sb %int_0 %uint_0 %int_1 %int_0
453fd4e5da5Sopenharmony_ci               OpCapability Shader
454fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
455fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main" %out_var_A
456fd4e5da5Sopenharmony_ci               OpName %type_RWStructuredBuffer_S "type.RWStructuredBuffer.S"
457fd4e5da5Sopenharmony_ci               OpName %S "S"
458fd4e5da5Sopenharmony_ci               OpMemberName %S 0 "a"
459fd4e5da5Sopenharmony_ci               OpMemberName %S 1 "b"
460fd4e5da5Sopenharmony_ci               OpName %sb "sb"
461fd4e5da5Sopenharmony_ci               OpName %out_var_A "out.var.A"
462fd4e5da5Sopenharmony_ci               OpName %main "main"
463fd4e5da5Sopenharmony_ci               OpDecorate %out_var_A Location 0
464fd4e5da5Sopenharmony_ci               OpDecorate %sb DescriptorSet 0
465fd4e5da5Sopenharmony_ci               OpDecorate %sb Binding 0
466fd4e5da5Sopenharmony_ci               OpMemberDecorate %S 0 Offset 0
467fd4e5da5Sopenharmony_ci               OpMemberDecorate %S 1 Offset 8
468fd4e5da5Sopenharmony_ci               OpDecorate %_runtimearr_S ArrayStride 16
469fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_RWStructuredBuffer_S 0 Offset 0
470fd4e5da5Sopenharmony_ci               OpDecorate %type_RWStructuredBuffer_S BufferBlock
471fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
472fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
473fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
474fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
475fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
476fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
477fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
478fd4e5da5Sopenharmony_ci          %S = OpTypeStruct %v2float %v2float
479fd4e5da5Sopenharmony_ci%_runtimearr_S = OpTypeRuntimeArray %S
480fd4e5da5Sopenharmony_ci%type_RWStructuredBuffer_S = OpTypeStruct %_runtimearr_S
481fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_RWStructuredBuffer_S = OpTypePointer Uniform %type_RWStructuredBuffer_S
482fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float
483fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
484fd4e5da5Sopenharmony_ci         %17 = OpTypeFunction %void
485fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
486fd4e5da5Sopenharmony_ci         %sb = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_S Uniform
487fd4e5da5Sopenharmony_ci  %out_var_A = OpVariable %_ptr_Output_float Output
488fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %17
489fd4e5da5Sopenharmony_ci         %19 = OpLabel
490fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %_ptr_Uniform_float %sb %int_0 %uint_0 %int_0 %int_0
491fd4e5da5Sopenharmony_ci         %21 = OpLoad %float %20
492fd4e5da5Sopenharmony_ci         %22 = OpAccessChain %_ptr_Uniform_float %sb %int_0 %uint_0 %int_1 %int_0
493fd4e5da5Sopenharmony_ci         %23 = OpLoad %float %22
494fd4e5da5Sopenharmony_ci         %24 = OpFAdd %float %21 %23
495fd4e5da5Sopenharmony_ci               OpStore %out_var_A %24
496fd4e5da5Sopenharmony_ci               OpReturn
497fd4e5da5Sopenharmony_ci               OpFunctionEnd
498fd4e5da5Sopenharmony_ci)";
499fd4e5da5Sopenharmony_ci
500fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
501fd4e5da5Sopenharmony_ci}
502fd4e5da5Sopenharmony_ci
503fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, StructureArrayNames) {
504fd4e5da5Sopenharmony_ci  // Checks that names are properly generated for multi-dimension arrays and
505fd4e5da5Sopenharmony_ci  // structure members.
506fd4e5da5Sopenharmony_ci  const std::string checks = R"(
507fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_0__0__t_0_ "globalS[0][0].t[0]"
508fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_0__0__s_0_ "globalS[0][0].s[0]"
509fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_1__1__t_1_ "globalS[1][1].t[1]"
510fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_1__1__s_1_ "globalS[1][1].s[1]"
511fd4e5da5Sopenharmony_ci  )";
512fd4e5da5Sopenharmony_ci
513fd4e5da5Sopenharmony_ci  const std::string text = checks + GetStructureArrayTestSpirv();
514fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
515fd4e5da5Sopenharmony_ci}
516fd4e5da5Sopenharmony_ci
517fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, StructureArrayBindings) {
518fd4e5da5Sopenharmony_ci  // Checks that flattening structures and arrays results in correct binding
519fd4e5da5Sopenharmony_ci  // numbers.
520fd4e5da5Sopenharmony_ci  const std::string checks = R"(
521fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_0__0__t_0_ Binding 0
522fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_0__0__s_0_ Binding 2
523fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_1__1__t_1_ Binding 13
524fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_1__1__s_1_ Binding 15
525fd4e5da5Sopenharmony_ci  )";
526fd4e5da5Sopenharmony_ci
527fd4e5da5Sopenharmony_ci  const std::string text = checks + GetStructureArrayTestSpirv();
528fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
529fd4e5da5Sopenharmony_ci}
530fd4e5da5Sopenharmony_ci
531fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, StructureArrayReplacements) {
532fd4e5da5Sopenharmony_ci  // Checks that all access chains indexing into structures and/or arrays are
533fd4e5da5Sopenharmony_ci  // replaced with direct access to replacement variables.
534fd4e5da5Sopenharmony_ci  const std::string checks = R"(
535fd4e5da5Sopenharmony_ci; CHECK-NOT: OpAccessChain
536fd4e5da5Sopenharmony_ci; CHECK: OpLoad %type_2d_image %globalS_0__0__t_0_
537fd4e5da5Sopenharmony_ci; CHECK: OpLoad %type_sampler %globalS_0__0__s_0_
538fd4e5da5Sopenharmony_ci; CHECK: OpLoad %type_2d_image %globalS_1__1__t_1_
539fd4e5da5Sopenharmony_ci; CHECK: OpLoad %type_sampler %globalS_1__1__s_1_
540fd4e5da5Sopenharmony_ci  )";
541fd4e5da5Sopenharmony_ci
542fd4e5da5Sopenharmony_ci  const std::string text = checks + GetStructureArrayTestSpirv();
543fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(text, true);
544fd4e5da5Sopenharmony_ci}
545fd4e5da5Sopenharmony_ci
546fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, ResourceStructAsFunctionParam) {
547fd4e5da5Sopenharmony_ci  // Checks that a mix of OpAccessChain, OpLoad, and OpCompositeExtract patterns
548fd4e5da5Sopenharmony_ci  // can be properly replaced with replacement variables.
549fd4e5da5Sopenharmony_ci  // This pattern can be seen when a global structure of resources is passed to
550fd4e5da5Sopenharmony_ci  // a function.
551fd4e5da5Sopenharmony_ci
552fd4e5da5Sopenharmony_ci  /* High-level source:
553fd4e5da5Sopenharmony_ci  // globalS[0].t[0]        binding: 0  (used)
554fd4e5da5Sopenharmony_ci  // globalS[0].t[1]        binding: 1  (used)
555fd4e5da5Sopenharmony_ci  // globalS[0].tt[0].s[0]  binding: 2
556fd4e5da5Sopenharmony_ci  // globalS[0].tt[0].s[1]  binding: 3  (used)
557fd4e5da5Sopenharmony_ci  // globalS[0].tt[0].s[2]  binding: 4
558fd4e5da5Sopenharmony_ci  // globalS[0].tt[1].s[0]  binding: 5
559fd4e5da5Sopenharmony_ci  // globalS[0].tt[1].s[1]  binding: 6
560fd4e5da5Sopenharmony_ci  // globalS[0].tt[1].s[2]  binding: 7  (used)
561fd4e5da5Sopenharmony_ci  // globalS[1].t[0]        binding: 8  (used)
562fd4e5da5Sopenharmony_ci  // globalS[1].t[1]        binding: 9  (used)
563fd4e5da5Sopenharmony_ci  // globalS[1].tt[0].s[0]  binding: 10
564fd4e5da5Sopenharmony_ci  // globalS[1].tt[0].s[1]  binding: 11 (used)
565fd4e5da5Sopenharmony_ci  // globalS[1].tt[0].s[2]  binding: 12
566fd4e5da5Sopenharmony_ci  // globalS[1].tt[1].s[0]  binding: 13
567fd4e5da5Sopenharmony_ci  // globalS[1].tt[1].s[1]  binding: 14
568fd4e5da5Sopenharmony_ci  // globalS[1].tt[1].s[2]  binding: 15 (used)
569fd4e5da5Sopenharmony_ci
570fd4e5da5Sopenharmony_ci  struct T {
571fd4e5da5Sopenharmony_ci    SamplerState s[3];
572fd4e5da5Sopenharmony_ci  };
573fd4e5da5Sopenharmony_ci
574fd4e5da5Sopenharmony_ci  struct S {
575fd4e5da5Sopenharmony_ci    Texture2D t[2];
576fd4e5da5Sopenharmony_ci    T tt[2];
577fd4e5da5Sopenharmony_ci  };
578fd4e5da5Sopenharmony_ci
579fd4e5da5Sopenharmony_ci  float4 tex2D(S x, float2 v) {
580fd4e5da5Sopenharmony_ci    return x.t[0].Sample(x.tt[0].s[1], v) + x.t[1].Sample(x.tt[1].s[2], v);
581fd4e5da5Sopenharmony_ci  }
582fd4e5da5Sopenharmony_ci
583fd4e5da5Sopenharmony_ci  S globalS[2];
584fd4e5da5Sopenharmony_ci
585fd4e5da5Sopenharmony_ci  float4 main() : SV_Target {
586fd4e5da5Sopenharmony_ci    return tex2D(globalS[0], float2(0,0)) + tex2D(globalS[1], float2(0,0)) ;
587fd4e5da5Sopenharmony_ci  }
588fd4e5da5Sopenharmony_ci  */
589fd4e5da5Sopenharmony_ci  const std::string shader = R"(
590fd4e5da5Sopenharmony_ci               OpCapability Shader
591fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
592fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %out_var_SV_Target
593fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
594fd4e5da5Sopenharmony_ci               OpName %S "S"
595fd4e5da5Sopenharmony_ci               OpMemberName %S 0 "t"
596fd4e5da5Sopenharmony_ci               OpMemberName %S 1 "tt"
597fd4e5da5Sopenharmony_ci               OpName %type_2d_image "type.2d.image"
598fd4e5da5Sopenharmony_ci               OpName %T "T"
599fd4e5da5Sopenharmony_ci               OpMemberName %T 0 "s"
600fd4e5da5Sopenharmony_ci               OpName %type_sampler "type.sampler"
601fd4e5da5Sopenharmony_ci               OpName %globalS "globalS"
602fd4e5da5Sopenharmony_ci               OpName %out_var_SV_Target "out.var.SV_Target"
603fd4e5da5Sopenharmony_ci               OpName %main "main"
604fd4e5da5Sopenharmony_ci               OpName %type_sampled_image "type.sampled.image"
605fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target Location 0
606fd4e5da5Sopenharmony_ci               OpDecorate %globalS DescriptorSet 0
607fd4e5da5Sopenharmony_ci               OpDecorate %globalS Binding 0
608fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
609fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
610fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
611fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
612fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
613fd4e5da5Sopenharmony_ci         %14 = OpConstantComposite %v2float %float_0 %float_0
614fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
615fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
616fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
617fd4e5da5Sopenharmony_ci%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
618fd4e5da5Sopenharmony_ci%_arr_type_2d_image_uint_2 = OpTypeArray %type_2d_image %uint_2
619fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
620fd4e5da5Sopenharmony_ci%type_sampler = OpTypeSampler
621fd4e5da5Sopenharmony_ci%_arr_type_sampler_uint_3 = OpTypeArray %type_sampler %uint_3
622fd4e5da5Sopenharmony_ci          %T = OpTypeStruct %_arr_type_sampler_uint_3
623fd4e5da5Sopenharmony_ci%_arr_T_uint_2 = OpTypeArray %T %uint_2
624fd4e5da5Sopenharmony_ci          %S = OpTypeStruct %_arr_type_2d_image_uint_2 %_arr_T_uint_2
625fd4e5da5Sopenharmony_ci%_arr_S_uint_2 = OpTypeArray %S %uint_2
626fd4e5da5Sopenharmony_ci%_ptr_UniformConstant__arr_S_uint_2 = OpTypePointer UniformConstant %_arr_S_uint_2
627fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
628fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
629fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
630fd4e5da5Sopenharmony_ci         %27 = OpTypeFunction %void
631fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_S = OpTypePointer UniformConstant %S
632fd4e5da5Sopenharmony_ci%type_sampled_image = OpTypeSampledImage %type_2d_image
633fd4e5da5Sopenharmony_ci    %globalS = OpVariable %_ptr_UniformConstant__arr_S_uint_2 UniformConstant
634fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
635fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %27
636fd4e5da5Sopenharmony_ci         %29 = OpLabel
637fd4e5da5Sopenharmony_ci         %30 = OpAccessChain %_ptr_UniformConstant_S %globalS %int_0
638fd4e5da5Sopenharmony_ci         %31 = OpLoad %S %30
639fd4e5da5Sopenharmony_ci         %32 = OpCompositeExtract %_arr_type_2d_image_uint_2 %31 0
640fd4e5da5Sopenharmony_ci         %33 = OpCompositeExtract %type_2d_image %32 0
641fd4e5da5Sopenharmony_ci         %34 = OpCompositeExtract %type_2d_image %32 1
642fd4e5da5Sopenharmony_ci         %35 = OpCompositeExtract %_arr_T_uint_2 %31 1
643fd4e5da5Sopenharmony_ci         %36 = OpCompositeExtract %T %35 0
644fd4e5da5Sopenharmony_ci         %37 = OpCompositeExtract %_arr_type_sampler_uint_3 %36 0
645fd4e5da5Sopenharmony_ci         %38 = OpCompositeExtract %type_sampler %37 1
646fd4e5da5Sopenharmony_ci         %39 = OpCompositeExtract %T %35 1
647fd4e5da5Sopenharmony_ci         %40 = OpCompositeExtract %_arr_type_sampler_uint_3 %39 0
648fd4e5da5Sopenharmony_ci         %41 = OpCompositeExtract %type_sampler %40 2
649fd4e5da5Sopenharmony_ci         %42 = OpSampledImage %type_sampled_image %33 %38
650fd4e5da5Sopenharmony_ci         %43 = OpImageSampleImplicitLod %v4float %42 %14 None
651fd4e5da5Sopenharmony_ci         %44 = OpSampledImage %type_sampled_image %34 %41
652fd4e5da5Sopenharmony_ci         %45 = OpImageSampleImplicitLod %v4float %44 %14 None
653fd4e5da5Sopenharmony_ci         %46 = OpFAdd %v4float %43 %45
654fd4e5da5Sopenharmony_ci         %47 = OpAccessChain %_ptr_UniformConstant_S %globalS %int_1
655fd4e5da5Sopenharmony_ci         %48 = OpLoad %S %47
656fd4e5da5Sopenharmony_ci         %49 = OpCompositeExtract %_arr_type_2d_image_uint_2 %48 0
657fd4e5da5Sopenharmony_ci         %50 = OpCompositeExtract %type_2d_image %49 0
658fd4e5da5Sopenharmony_ci         %51 = OpCompositeExtract %type_2d_image %49 1
659fd4e5da5Sopenharmony_ci         %52 = OpCompositeExtract %_arr_T_uint_2 %48 1
660fd4e5da5Sopenharmony_ci         %53 = OpCompositeExtract %T %52 0
661fd4e5da5Sopenharmony_ci         %54 = OpCompositeExtract %_arr_type_sampler_uint_3 %53 0
662fd4e5da5Sopenharmony_ci         %55 = OpCompositeExtract %type_sampler %54 1
663fd4e5da5Sopenharmony_ci         %56 = OpCompositeExtract %T %52 1
664fd4e5da5Sopenharmony_ci         %57 = OpCompositeExtract %_arr_type_sampler_uint_3 %56 0
665fd4e5da5Sopenharmony_ci         %58 = OpCompositeExtract %type_sampler %57 2
666fd4e5da5Sopenharmony_ci         %59 = OpSampledImage %type_sampled_image %50 %55
667fd4e5da5Sopenharmony_ci         %60 = OpImageSampleImplicitLod %v4float %59 %14 None
668fd4e5da5Sopenharmony_ci         %61 = OpSampledImage %type_sampled_image %51 %58
669fd4e5da5Sopenharmony_ci         %62 = OpImageSampleImplicitLod %v4float %61 %14 None
670fd4e5da5Sopenharmony_ci         %63 = OpFAdd %v4float %60 %62
671fd4e5da5Sopenharmony_ci         %64 = OpFAdd %v4float %46 %63
672fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_Target %64
673fd4e5da5Sopenharmony_ci               OpReturn
674fd4e5da5Sopenharmony_ci               OpFunctionEnd
675fd4e5da5Sopenharmony_ci)";
676fd4e5da5Sopenharmony_ci
677fd4e5da5Sopenharmony_ci  const std::string checks = R"(
678fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_0__t_0_ "globalS[0].t[0]"
679fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_0__t_1_ "globalS[0].t[1]"
680fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_1__t_0_ "globalS[1].t[0]"
681fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_1__t_1_ "globalS[1].t[1]"
682fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_0__tt_0__s_1_ "globalS[0].tt[0].s[1]"
683fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_0__tt_1__s_2_ "globalS[0].tt[1].s[2]"
684fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_1__tt_0__s_1_ "globalS[1].tt[0].s[1]"
685fd4e5da5Sopenharmony_ci; CHECK: OpName %globalS_1__tt_1__s_2_ "globalS[1].tt[1].s[2]"
686fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_0__t_0_ Binding 0
687fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_0__t_1_ Binding 1
688fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_1__t_0_ Binding 8
689fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_1__t_1_ Binding 9
690fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_0__tt_0__s_1_ Binding 3
691fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_0__tt_1__s_2_ Binding 7
692fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_1__tt_0__s_1_ Binding 11
693fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %globalS_1__tt_1__s_2_ Binding 15
694fd4e5da5Sopenharmony_ci
695fd4e5da5Sopenharmony_ci; CHECK: %globalS_0__t_0_ = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
696fd4e5da5Sopenharmony_ci; CHECK: %globalS_0__t_1_ = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
697fd4e5da5Sopenharmony_ci; CHECK: %globalS_1__t_0_ = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
698fd4e5da5Sopenharmony_ci; CHECK: %globalS_1__t_1_ = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
699fd4e5da5Sopenharmony_ci; CHECK: %globalS_0__tt_0__s_1_ = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
700fd4e5da5Sopenharmony_ci; CHECK: %globalS_0__tt_1__s_2_ = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
701fd4e5da5Sopenharmony_ci; CHECK: %globalS_1__tt_0__s_1_ = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
702fd4e5da5Sopenharmony_ci; CHECK: %globalS_1__tt_1__s_2_ = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
703fd4e5da5Sopenharmony_ci
704fd4e5da5Sopenharmony_ci; CHECK:     [[img_1:%\w+]] = OpLoad %type_2d_image %globalS_0__t_0_
705fd4e5da5Sopenharmony_ci; CHECK:     [[img_2:%\w+]] = OpLoad %type_2d_image %globalS_0__t_1_
706fd4e5da5Sopenharmony_ci; CHECK: [[sampler_1:%\w+]] = OpLoad %type_sampler %globalS_0__tt_0__s_1_
707fd4e5da5Sopenharmony_ci; CHECK: [[sampler_2:%\w+]] = OpLoad %type_sampler %globalS_0__tt_1__s_2_
708fd4e5da5Sopenharmony_ci
709fd4e5da5Sopenharmony_ci; CHECK: [[sampled_img_1:%\w+]] = OpSampledImage %type_sampled_image [[img_1]] [[sampler_1]]
710fd4e5da5Sopenharmony_ci; CHECK:      [[sample_1:%\w+]] = OpImageSampleImplicitLod %v4float [[sampled_img_1]]
711fd4e5da5Sopenharmony_ci; CHECK: [[sampled_img_2:%\w+]] = OpSampledImage %type_sampled_image [[img_2]] [[sampler_2]]
712fd4e5da5Sopenharmony_ci; CHECK:      [[sample_2:%\w+]] = OpImageSampleImplicitLod %v4float [[sampled_img_2]]
713fd4e5da5Sopenharmony_ci; CHECK:                          OpFAdd %v4float [[sample_1]] [[sample_2]]
714fd4e5da5Sopenharmony_ci
715fd4e5da5Sopenharmony_ci; CHECK:     [[img_3:%\w+]] = OpLoad %type_2d_image %globalS_1__t_0_
716fd4e5da5Sopenharmony_ci; CHECK:     [[img_4:%\w+]] = OpLoad %type_2d_image %globalS_1__t_1_
717fd4e5da5Sopenharmony_ci; CHECK: [[sampler_3:%\w+]] = OpLoad %type_sampler %globalS_1__tt_0__s_1_
718fd4e5da5Sopenharmony_ci; CHECK: [[sampler_4:%\w+]] = OpLoad %type_sampler %globalS_1__tt_1__s_2_
719fd4e5da5Sopenharmony_ci
720fd4e5da5Sopenharmony_ci; CHECK: [[sampled_img_3:%\w+]] = OpSampledImage %type_sampled_image [[img_3]] [[sampler_3]]
721fd4e5da5Sopenharmony_ci; CHECK:      [[sample_3:%\w+]] = OpImageSampleImplicitLod %v4float [[sampled_img_3]]
722fd4e5da5Sopenharmony_ci; CHECK: [[sampled_img_4:%\w+]] = OpSampledImage %type_sampled_image [[img_4]] [[sampler_4]]
723fd4e5da5Sopenharmony_ci; CHECK:      [[sample_4:%\w+]] = OpImageSampleImplicitLod %v4float [[sampled_img_4]]
724fd4e5da5Sopenharmony_ci; CHECK:                          OpFAdd %v4float [[sample_3]] [[sample_4]]
725fd4e5da5Sopenharmony_ci)";
726fd4e5da5Sopenharmony_ci
727fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(checks + shader, true);
728fd4e5da5Sopenharmony_ci}
729fd4e5da5Sopenharmony_ci
730fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, BindingForResourceArrayOfStructs) {
731fd4e5da5Sopenharmony_ci  // Check that correct binding numbers are given to an array of descriptors
732fd4e5da5Sopenharmony_ci  // to structs.
733fd4e5da5Sopenharmony_ci
734fd4e5da5Sopenharmony_ci  const std::string shader = R"(
735fd4e5da5Sopenharmony_ci; CHECK: OpDecorate {{%\w+}} Binding 0
736fd4e5da5Sopenharmony_ci; CHECK: OpDecorate {{%\w+}} Binding 1
737fd4e5da5Sopenharmony_ci               OpCapability Shader
738fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
739fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
740fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "psmain"
741fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
742fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
743fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 0
744fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_4 0 Offset 0
745fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_4 1 Offset 4
746fd4e5da5Sopenharmony_ci               OpDecorate %_struct_4 Block
747fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
748fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
749fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
750fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
751fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
752fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
753fd4e5da5Sopenharmony_ci  %_struct_4 = OpTypeStruct %float %int
754fd4e5da5Sopenharmony_ci%_arr__struct_4_uint_2 = OpTypeArray %_struct_4 %uint_2
755fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr__struct_4_uint_2 = OpTypePointer Uniform %_arr__struct_4_uint_2
756fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
757fd4e5da5Sopenharmony_ci         %25 = OpTypeFunction %void
758fd4e5da5Sopenharmony_ci%_ptr_Uniform_int = OpTypePointer Uniform %int
759fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_Uniform__arr__struct_4_uint_2 Uniform
760fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %25
761fd4e5da5Sopenharmony_ci         %29 = OpLabel
762fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %_ptr_Uniform_int %5 %int_0 %int_1
763fd4e5da5Sopenharmony_ci         %41 = OpAccessChain %_ptr_Uniform_int %5 %int_1 %int_1
764fd4e5da5Sopenharmony_ci               OpReturn
765fd4e5da5Sopenharmony_ci               OpFunctionEnd
766fd4e5da5Sopenharmony_ci)";
767fd4e5da5Sopenharmony_ci
768fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(shader, true);
769fd4e5da5Sopenharmony_ci}
770fd4e5da5Sopenharmony_ci
771fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, MemberDecorationForResourceStruct) {
772fd4e5da5Sopenharmony_ci  // Check that an OpMemberDecorate instruction is correctly converted to a
773fd4e5da5Sopenharmony_ci  // OpDecorate instruction.
774fd4e5da5Sopenharmony_ci
775fd4e5da5Sopenharmony_ci  const std::string shader = R"(
776fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[t:%\w+]] DescriptorSet 0
777fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[t]] Binding 0
778fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[t]] RelaxedPrecision
779fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[s:%\w+]] DescriptorSet 0
780fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[s]] Binding 1
781fd4e5da5Sopenharmony_ci               OpCapability Shader
782fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
783fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %PSMain "PSMain" %in_var_TEXCOORD %out_var_SV_Target
784fd4e5da5Sopenharmony_ci               OpExecutionMode %PSMain OriginUpperLeft
785fd4e5da5Sopenharmony_ci               OpSource HLSL 600
786fd4e5da5Sopenharmony_ci               OpName %sampler2D_h "sampler2D_h"
787fd4e5da5Sopenharmony_ci               OpMemberName %sampler2D_h 0 "t"
788fd4e5da5Sopenharmony_ci               OpMemberName %sampler2D_h 1 "s"
789fd4e5da5Sopenharmony_ci               OpName %type_2d_image "type.2d.image"
790fd4e5da5Sopenharmony_ci               OpName %type_sampler "type.sampler"
791fd4e5da5Sopenharmony_ci               OpName %_MainTex "_MainTex"
792fd4e5da5Sopenharmony_ci               OpName %in_var_TEXCOORD "in.var.TEXCOORD"
793fd4e5da5Sopenharmony_ci               OpName %out_var_SV_Target "out.var.SV_Target"
794fd4e5da5Sopenharmony_ci               OpName %PSMain "PSMain"
795fd4e5da5Sopenharmony_ci               OpName %type_sampled_image "type.sampled.image"
796fd4e5da5Sopenharmony_ci               OpDecorate %in_var_TEXCOORD Location 0
797fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target Location 0
798fd4e5da5Sopenharmony_ci               OpDecorate %_MainTex DescriptorSet 0
799fd4e5da5Sopenharmony_ci               OpDecorate %_MainTex Binding 0
800fd4e5da5Sopenharmony_ci               OpMemberDecorate %sampler2D_h 0 RelaxedPrecision
801fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target RelaxedPrecision
802fd4e5da5Sopenharmony_ci               OpDecorate %69 RelaxedPrecision
803fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
804fd4e5da5Sopenharmony_ci%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
805fd4e5da5Sopenharmony_ci%type_sampler = OpTypeSampler
806fd4e5da5Sopenharmony_ci%sampler2D_h = OpTypeStruct %type_2d_image %type_sampler
807fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_sampler2D_h = OpTypePointer UniformConstant %sampler2D_h
808fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
809fd4e5da5Sopenharmony_ci%_ptr_Input_v2float = OpTypePointer Input %v2float
810fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
811fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
812fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
813fd4e5da5Sopenharmony_ci         %35 = OpTypeFunction %void
814fd4e5da5Sopenharmony_ci%type_sampled_image = OpTypeSampledImage %type_2d_image
815fd4e5da5Sopenharmony_ci   %_MainTex = OpVariable %_ptr_UniformConstant_sampler2D_h UniformConstant
816fd4e5da5Sopenharmony_ci%in_var_TEXCOORD = OpVariable %_ptr_Input_v2float Input
817fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
818fd4e5da5Sopenharmony_ci     %PSMain = OpFunction %void None %35
819fd4e5da5Sopenharmony_ci         %43 = OpLabel
820fd4e5da5Sopenharmony_ci         %44 = OpLoad %v2float %in_var_TEXCOORD
821fd4e5da5Sopenharmony_ci         %57 = OpLoad %sampler2D_h %_MainTex
822fd4e5da5Sopenharmony_ci         %72 = OpCompositeExtract %type_2d_image %57 0
823fd4e5da5Sopenharmony_ci         %73 = OpCompositeExtract %type_sampler %57 1
824fd4e5da5Sopenharmony_ci         %68 = OpSampledImage %type_sampled_image %72 %73
825fd4e5da5Sopenharmony_ci         %69 = OpImageSampleImplicitLod %v4float %68 %44 None
826fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_Target %69
827fd4e5da5Sopenharmony_ci               OpReturn
828fd4e5da5Sopenharmony_ci               OpFunctionEnd
829fd4e5da5Sopenharmony_ci)";
830fd4e5da5Sopenharmony_ci
831fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(shader, true);
832fd4e5da5Sopenharmony_ci}
833fd4e5da5Sopenharmony_ci
834fd4e5da5Sopenharmony_ciTEST_F(DescriptorScalarReplacementTest, DecorateStringForReflect) {
835fd4e5da5Sopenharmony_ci  // Check that an OpDecorateString instruction is correctly cloned to new
836fd4e5da5Sopenharmony_ci  // variable.
837fd4e5da5Sopenharmony_ci
838fd4e5da5Sopenharmony_ci  const std::string shader = R"(
839fd4e5da5Sopenharmony_ci; CHECK: OpName %g_testTextures_0_ "g_testTextures[0]"
840fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %g_testTextures_0_ DescriptorSet 0
841fd4e5da5Sopenharmony_ci; CHECK: OpDecorate %g_testTextures_0_ Binding 0
842fd4e5da5Sopenharmony_ci; CHECK: OpDecorateString %g_testTextures_0_ UserTypeGOOGLE "texture2d"
843fd4e5da5Sopenharmony_ci               OpCapability Shader
844fd4e5da5Sopenharmony_ci               OpExtension "SPV_GOOGLE_hlsl_functionality1"
845fd4e5da5Sopenharmony_ci               OpExtension "SPV_GOOGLE_user_type"
846fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
847fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %gl_FragCoord %out_var_SV_Target
848fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
849fd4e5da5Sopenharmony_ci               OpSource HLSL 600
850fd4e5da5Sopenharmony_ci               OpName %type_2d_image "type.2d.image"
851fd4e5da5Sopenharmony_ci               OpName %g_testTextures "g_testTextures"
852fd4e5da5Sopenharmony_ci               OpName %out_var_SV_Target "out.var.SV_Target"
853fd4e5da5Sopenharmony_ci               OpName %main "main"
854fd4e5da5Sopenharmony_ci               OpName %param_var_vPixelPos "param.var.vPixelPos"
855fd4e5da5Sopenharmony_ci               OpName %src_main "src.main"
856fd4e5da5Sopenharmony_ci               OpName %vPixelPos "vPixelPos"
857fd4e5da5Sopenharmony_ci               OpName %bb_entry "bb.entry"
858fd4e5da5Sopenharmony_ci               OpDecorate %gl_FragCoord BuiltIn FragCoord
859fd4e5da5Sopenharmony_ci               OpDecorateString %gl_FragCoord UserSemantic "SV_Position"
860fd4e5da5Sopenharmony_ci               OpDecorateString %out_var_SV_Target UserSemantic "SV_Target"
861fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target Location 0
862fd4e5da5Sopenharmony_ci               OpDecorate %g_testTextures DescriptorSet 0
863fd4e5da5Sopenharmony_ci               OpDecorate %g_testTextures Binding 0
864fd4e5da5Sopenharmony_ci               OpDecorateString %g_testTextures UserTypeGOOGLE "texture2d"
865fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
866fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
867fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
868fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
869fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
870fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
871fd4e5da5Sopenharmony_ci%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
872fd4e5da5Sopenharmony_ci%_arr_type_2d_image_uint_2 = OpTypeArray %type_2d_image %uint_2
873fd4e5da5Sopenharmony_ci%_ptr_UniformConstant__arr_type_2d_image_uint_2 = OpTypePointer UniformConstant %_arr_type_2d_image_uint_2
874fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
875fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
876fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
877fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
878fd4e5da5Sopenharmony_ci         %18 = OpTypeFunction %void
879fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
880fd4e5da5Sopenharmony_ci         %25 = OpTypeFunction %v4float %_ptr_Function_v4float
881fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
882fd4e5da5Sopenharmony_ci     %v3uint = OpTypeVector %uint 3
883fd4e5da5Sopenharmony_ci      %v3int = OpTypeVector %int 3
884fd4e5da5Sopenharmony_ci      %v2int = OpTypeVector %int 2
885fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
886fd4e5da5Sopenharmony_ci%g_testTextures = OpVariable %_ptr_UniformConstant__arr_type_2d_image_uint_2 UniformConstant
887fd4e5da5Sopenharmony_ci%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
888fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
889fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %18
890fd4e5da5Sopenharmony_ci         %19 = OpLabel
891fd4e5da5Sopenharmony_ci%param_var_vPixelPos = OpVariable %_ptr_Function_v4float Function
892fd4e5da5Sopenharmony_ci         %22 = OpLoad %v4float %gl_FragCoord
893fd4e5da5Sopenharmony_ci               OpStore %param_var_vPixelPos %22
894fd4e5da5Sopenharmony_ci         %23 = OpFunctionCall %v4float %src_main %param_var_vPixelPos
895fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_Target %23
896fd4e5da5Sopenharmony_ci               OpReturn
897fd4e5da5Sopenharmony_ci               OpFunctionEnd
898fd4e5da5Sopenharmony_ci   %src_main = OpFunction %v4float None %25
899fd4e5da5Sopenharmony_ci  %vPixelPos = OpFunctionParameter %_ptr_Function_v4float
900fd4e5da5Sopenharmony_ci   %bb_entry = OpLabel
901fd4e5da5Sopenharmony_ci         %28 = OpLoad %v4float %vPixelPos
902fd4e5da5Sopenharmony_ci         %30 = OpVectorShuffle %v2float %28 %28 0 1
903fd4e5da5Sopenharmony_ci         %31 = OpCompositeExtract %float %30 0
904fd4e5da5Sopenharmony_ci         %32 = OpCompositeExtract %float %30 1
905fd4e5da5Sopenharmony_ci         %33 = OpConvertFToU %uint %31
906fd4e5da5Sopenharmony_ci         %34 = OpConvertFToU %uint %32
907fd4e5da5Sopenharmony_ci         %36 = OpCompositeConstruct %v3uint %33 %34 %uint_0
908fd4e5da5Sopenharmony_ci         %38 = OpBitcast %v3int %36
909fd4e5da5Sopenharmony_ci         %40 = OpVectorShuffle %v2int %38 %38 0 1
910fd4e5da5Sopenharmony_ci         %41 = OpCompositeExtract %int %38 2
911fd4e5da5Sopenharmony_ci         %43 = OpAccessChain %_ptr_UniformConstant_type_2d_image %g_testTextures %int_0
912fd4e5da5Sopenharmony_ci         %44 = OpLoad %type_2d_image %43
913fd4e5da5Sopenharmony_ci         %45 = OpImageFetch %v4float %44 %40 Lod %41
914fd4e5da5Sopenharmony_ci               OpReturnValue %45
915fd4e5da5Sopenharmony_ci               OpFunctionEnd
916fd4e5da5Sopenharmony_ci)";
917fd4e5da5Sopenharmony_ci
918fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DescriptorScalarReplacement>(shader, true);
919fd4e5da5Sopenharmony_ci}
920fd4e5da5Sopenharmony_ci
921fd4e5da5Sopenharmony_ci}  // namespace
922fd4e5da5Sopenharmony_ci}  // namespace opt
923fd4e5da5Sopenharmony_ci}  // namespace spvtools
924