• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2017 Valve Corporation
2 // Copyright (c) 2017 LunarG Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #include <string>
17 
18 #include "test/opt/pass_fixture.h"
19 #include "test/opt/pass_utils.h"
20 
21 namespace spvtools {
22 namespace opt {
23 namespace {
24 
25 using InlineOpaqueTest = PassTest<::testing::Test>;
26 
TEST_F(InlineOpaqueTest,InlineCallWithStructArgContainingSampledImage)27 TEST_F(InlineOpaqueTest, InlineCallWithStructArgContainingSampledImage) {
28   // Function with opaque argument is inlined.
29   // TODO(greg-lunarg): Add HLSL code
30 
31   const std::string predefs_1 =
32       R"(OpCapability Shader
33 %1 = OpExtInstImport "GLSL.std.450"
34 OpMemoryModel Logical GLSL450
35 OpEntryPoint Fragment %main "main" %outColor %texCoords
36 OpExecutionMode %main OriginUpperLeft
37 OpSource GLSL 140
38 OpName %main "main"
39 OpName %S_t "S_t"
40 OpMemberName %S_t 0 "v0"
41 OpMemberName %S_t 1 "v1"
42 OpMemberName %S_t 2 "smp"
43 OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
44 OpName %s "s"
45 OpName %outColor "outColor"
46 OpName %sampler15 "sampler15"
47 OpName %s0 "s0"
48 OpName %texCoords "texCoords"
49 OpName %param "param"
50 )";
51 
52   const std::string name = R"(OpName %return_value "return_value"
53 )";
54 
55   const std::string predefs_2 = R"(OpDecorate %sampler15 DescriptorSet 0
56 %void = OpTypeVoid
57 %13 = OpTypeFunction %void
58 %float = OpTypeFloat 32
59 %v2float = OpTypeVector %float 2
60 %v4float = OpTypeVector %float 4
61 %_ptr_Output_v4float = OpTypePointer Output %v4float
62 %outColor = OpVariable %_ptr_Output_v4float Output
63 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
64 %19 = OpTypeSampledImage %18
65 %S_t = OpTypeStruct %v2float %v2float %19
66 %_ptr_Function_S_t = OpTypePointer Function %S_t
67 %21 = OpTypeFunction %void %_ptr_Function_S_t
68 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
69 %_ptr_Function_19 = OpTypePointer Function %19
70 %sampler15 = OpVariable %_ptr_UniformConstant_19 UniformConstant
71 %int = OpTypeInt 32 1
72 %int_0 = OpConstant %int 0
73 %int_2 = OpConstant %int 2
74 %_ptr_Function_v2float = OpTypePointer Function %v2float
75 %_ptr_Input_v2float = OpTypePointer Input %v2float
76 %texCoords = OpVariable %_ptr_Input_v2float Input
77 )";
78 
79   const std::string before =
80       R"(%main = OpFunction %void None %13
81 %29 = OpLabel
82 %s0 = OpVariable %_ptr_Function_S_t Function
83 %param = OpVariable %_ptr_Function_S_t Function
84 %30 = OpLoad %v2float %texCoords
85 %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
86 OpStore %31 %30
87 %32 = OpLoad %19 %sampler15
88 %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
89 OpStore %33 %32
90 %34 = OpLoad %S_t %s0
91 OpStore %param %34
92 %return_value = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
93 OpReturn
94 OpFunctionEnd
95 )";
96 
97   const std::string after =
98       R"(%main = OpFunction %void None %13
99 %29 = OpLabel
100 %s0 = OpVariable %_ptr_Function_S_t Function
101 %param = OpVariable %_ptr_Function_S_t Function
102 %30 = OpLoad %v2float %texCoords
103 %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
104 OpStore %31 %30
105 %32 = OpLoad %19 %sampler15
106 %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
107 OpStore %33 %32
108 %34 = OpLoad %S_t %s0
109 OpStore %param %34
110 %42 = OpAccessChain %_ptr_Function_19 %param %int_2
111 %43 = OpLoad %19 %42
112 %44 = OpAccessChain %_ptr_Function_v2float %param %int_0
113 %45 = OpLoad %v2float %44
114 %46 = OpImageSampleImplicitLod %v4float %43 %45
115 OpStore %outColor %46
116 OpReturn
117 OpFunctionEnd
118 )";
119 
120   const std::string post_defs =
121       R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
122 %s = OpFunctionParameter %_ptr_Function_S_t
123 %35 = OpLabel
124 %36 = OpAccessChain %_ptr_Function_19 %s %int_2
125 %37 = OpLoad %19 %36
126 %38 = OpAccessChain %_ptr_Function_v2float %s %int_0
127 %39 = OpLoad %v2float %38
128 %40 = OpImageSampleImplicitLod %v4float %37 %39
129 OpStore %outColor %40
130 OpReturn
131 OpFunctionEnd
132 )";
133 
134   SinglePassRunAndCheck<InlineOpaquePass>(
135       predefs_1 + name + predefs_2 + before + post_defs,
136       predefs_1 + predefs_2 + after + post_defs, true, true);
137 }
138 
TEST_F(InlineOpaqueTest,InlineOpaqueReturn)139 TEST_F(InlineOpaqueTest, InlineOpaqueReturn) {
140   // Function with opaque return value is inlined.
141   // TODO(greg-lunarg): Add HLSL code
142 
143   const std::string predefs =
144       R"(OpCapability Shader
145 %1 = OpExtInstImport "GLSL.std.450"
146 OpMemoryModel Logical GLSL450
147 OpEntryPoint Fragment %main "main" %texCoords %outColor
148 OpExecutionMode %main OriginUpperLeft
149 OpSource GLSL 140
150 OpName %main "main"
151 OpName %foo_ "foo("
152 OpName %texCoords "texCoords"
153 OpName %outColor "outColor"
154 OpName %sampler15 "sampler15"
155 OpName %sampler16 "sampler16"
156 OpDecorate %sampler15 DescriptorSet 0
157 OpDecorate %sampler16 DescriptorSet 0
158 %void = OpTypeVoid
159 %9 = OpTypeFunction %void
160 %float = OpTypeFloat 32
161 %v2float = OpTypeVector %float 2
162 %bool = OpTypeBool
163 %false = OpConstantFalse %bool
164 %_ptr_Input_v2float = OpTypePointer Input %v2float
165 %texCoords = OpVariable %_ptr_Input_v2float Input
166 %float_0 = OpConstant %float 0
167 %16 = OpConstantComposite %v2float %float_0 %float_0
168 %v4float = OpTypeVector %float 4
169 %_ptr_Output_v4float = OpTypePointer Output %v4float
170 %outColor = OpVariable %_ptr_Output_v4float Output
171 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
172 %20 = OpTypeSampledImage %19
173 %21 = OpTypeFunction %20
174 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
175 %_ptr_Function_20 = OpTypePointer Function %20
176 %sampler15 = OpVariable %_ptr_UniformConstant_20 UniformConstant
177 %sampler16 = OpVariable %_ptr_UniformConstant_20 UniformConstant
178 )";
179 
180   const std::string before =
181       R"(%main = OpFunction %void None %9
182 %24 = OpLabel
183 %25 = OpVariable %_ptr_Function_20 Function
184 %26 = OpFunctionCall %20 %foo_
185 OpStore %25 %26
186 %27 = OpLoad %20 %25
187 %28 = OpLoad %v2float %texCoords
188 %29 = OpImageSampleImplicitLod %v4float %27 %28
189 OpStore %outColor %29
190 OpReturn
191 OpFunctionEnd
192 )";
193 
194   const std::string after =
195       R"(%main = OpFunction %void None %9
196 %24 = OpLabel
197 %34 = OpVariable %_ptr_Function_20 Function
198 %35 = OpVariable %_ptr_Function_20 Function
199 %25 = OpVariable %_ptr_Function_20 Function
200 %37 = OpLoad %20 %sampler16
201 OpStore %34 %37
202 %38 = OpLoad %20 %34
203 OpStore %35 %38
204 %26 = OpLoad %20 %35
205 OpStore %25 %26
206 %27 = OpLoad %20 %25
207 %28 = OpLoad %v2float %texCoords
208 %29 = OpImageSampleImplicitLod %v4float %27 %28
209 OpStore %outColor %29
210 OpReturn
211 OpFunctionEnd
212 )";
213 
214   const std::string post_defs =
215       R"(%foo_ = OpFunction %20 None %21
216 %30 = OpLabel
217 %31 = OpVariable %_ptr_Function_20 Function
218 %32 = OpLoad %20 %sampler16
219 OpStore %31 %32
220 %33 = OpLoad %20 %31
221 OpReturnValue %33
222 OpFunctionEnd
223 )";
224 
225   SinglePassRunAndCheck<InlineOpaquePass>(
226       predefs + before + post_defs, predefs + after + post_defs, true, true);
227 }
228 
TEST_F(InlineOpaqueTest,InlineOpaqueForLinkage)229 TEST_F(InlineOpaqueTest, InlineOpaqueForLinkage) {
230   const std::string predefs_1 =
231       R"(OpCapability Shader
232 OpCapability Linkage
233 %1 = OpExtInstImport "GLSL.std.450"
234 OpMemoryModel Logical GLSL450
235 OpSource HLSL 630
236 OpName %main "main"
237 OpName %S_t "S_t"
238 OpMemberName %S_t 0 "v0"
239 OpMemberName %S_t 1 "v1"
240 OpMemberName %S_t 2 "smp"
241 OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
242 OpName %s "s"
243 OpName %outColor "outColor"
244 OpName %sampler15 "sampler15"
245 OpName %s0 "s0"
246 OpName %texCoords "texCoords"
247 OpName %param "param"
248 OpDecorate %main LinkageAttributes "main" Export
249 )";
250 
251   const std::string name = R"(OpName %return_value "return_value"
252 )";
253 
254   const std::string predefs_2 = R"(OpDecorate %sampler15 DescriptorSet 0
255 %void = OpTypeVoid
256 %13 = OpTypeFunction %void
257 %float = OpTypeFloat 32
258 %v2float = OpTypeVector %float 2
259 %v4float = OpTypeVector %float 4
260 %_ptr_Output_v4float = OpTypePointer Output %v4float
261 %outColor = OpVariable %_ptr_Output_v4float Output
262 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
263 %19 = OpTypeSampledImage %18
264 %S_t = OpTypeStruct %v2float %v2float %19
265 %_ptr_Function_S_t = OpTypePointer Function %S_t
266 %21 = OpTypeFunction %void %_ptr_Function_S_t
267 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
268 %_ptr_Function_19 = OpTypePointer Function %19
269 %sampler15 = OpVariable %_ptr_UniformConstant_19 UniformConstant
270 %int = OpTypeInt 32 1
271 %int_0 = OpConstant %int 0
272 %int_2 = OpConstant %int 2
273 %_ptr_Function_v2float = OpTypePointer Function %v2float
274 %_ptr_Input_v2float = OpTypePointer Input %v2float
275 %texCoords = OpVariable %_ptr_Input_v2float Input
276 )";
277 
278   const std::string before =
279       R"(%main = OpFunction %void None %13
280 %29 = OpLabel
281 %s0 = OpVariable %_ptr_Function_S_t Function
282 %param = OpVariable %_ptr_Function_S_t Function
283 %30 = OpLoad %v2float %texCoords
284 %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
285 OpStore %31 %30
286 %32 = OpLoad %19 %sampler15
287 %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
288 OpStore %33 %32
289 %34 = OpLoad %S_t %s0
290 OpStore %param %34
291 %return_value = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
292 OpReturn
293 OpFunctionEnd
294 )";
295 
296   const std::string after =
297       R"(%main = OpFunction %void None %13
298 %29 = OpLabel
299 %s0 = OpVariable %_ptr_Function_S_t Function
300 %param = OpVariable %_ptr_Function_S_t Function
301 %30 = OpLoad %v2float %texCoords
302 %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
303 OpStore %31 %30
304 %32 = OpLoad %19 %sampler15
305 %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
306 OpStore %33 %32
307 %34 = OpLoad %S_t %s0
308 OpStore %param %34
309 %42 = OpAccessChain %_ptr_Function_19 %param %int_2
310 %43 = OpLoad %19 %42
311 %44 = OpAccessChain %_ptr_Function_v2float %param %int_0
312 %45 = OpLoad %v2float %44
313 %46 = OpImageSampleImplicitLod %v4float %43 %45
314 OpStore %outColor %46
315 OpReturn
316 OpFunctionEnd
317 )";
318 
319   const std::string post_defs =
320       R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
321 %s = OpFunctionParameter %_ptr_Function_S_t
322 %35 = OpLabel
323 %36 = OpAccessChain %_ptr_Function_19 %s %int_2
324 %37 = OpLoad %19 %36
325 %38 = OpAccessChain %_ptr_Function_v2float %s %int_0
326 %39 = OpLoad %v2float %38
327 %40 = OpImageSampleImplicitLod %v4float %37 %39
328 OpStore %outColor %40
329 OpReturn
330 OpFunctionEnd
331 )";
332 
333   SinglePassRunAndCheck<InlineOpaquePass>(
334       predefs_1 + name + predefs_2 + before + post_defs,
335       predefs_1 + predefs_2 + after + post_defs, true, true);
336 }
337 
TEST_F(InlineOpaqueTest,InlineInNonEntryPointFunction)338 TEST_F(InlineOpaqueTest, InlineInNonEntryPointFunction) {
339   // This demonstrates opaque inlining in a function that is not
340   // an entry point function (main2) but is in the call tree of an
341   // entry point function (main).
342   // TODO(greg-lunarg): Add HLSL code
343 
344   const std::string predefs =
345       R"(OpCapability Shader
346 %1 = OpExtInstImport "GLSL.std.450"
347 OpMemoryModel Logical GLSL450
348 OpEntryPoint Fragment %main "main" %outColor %texCoords
349 OpExecutionMode %main OriginUpperLeft
350 OpSource GLSL 140
351 OpName %main "main"
352 OpName %main2 "main2"
353 OpName %S_t "S_t"
354 OpMemberName %S_t 0 "v0"
355 OpMemberName %S_t 1 "v1"
356 OpMemberName %S_t 2 "smp"
357 OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
358 OpName %s "s"
359 OpName %outColor "outColor"
360 OpName %sampler15 "sampler15"
361 OpName %s0 "s0"
362 OpName %texCoords "texCoords"
363 OpName %param "param"
364 OpDecorate %sampler15 DescriptorSet 0
365 %void = OpTypeVoid
366 %13 = OpTypeFunction %void
367 %float = OpTypeFloat 32
368 %v2float = OpTypeVector %float 2
369 %v4float = OpTypeVector %float 4
370 %_ptr_Output_v4float = OpTypePointer Output %v4float
371 %outColor = OpVariable %_ptr_Output_v4float Output
372 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
373 %19 = OpTypeSampledImage %18
374 %S_t = OpTypeStruct %v2float %v2float %19
375 %_ptr_Function_S_t = OpTypePointer Function %S_t
376 %21 = OpTypeFunction %void %_ptr_Function_S_t
377 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
378 %_ptr_Function_19 = OpTypePointer Function %19
379 %sampler15 = OpVariable %_ptr_UniformConstant_19 UniformConstant
380 %int = OpTypeInt 32 1
381 %int_0 = OpConstant %int 0
382 %int_2 = OpConstant %int 2
383 %_ptr_Function_v2float = OpTypePointer Function %v2float
384 %_ptr_Input_v2float = OpTypePointer Input %v2float
385 %texCoords = OpVariable %_ptr_Input_v2float Input
386 )";
387 
388   const std::string before =
389       R"(%main2 = OpFunction %void None %13
390 %29 = OpLabel
391 %s0 = OpVariable %_ptr_Function_S_t Function
392 %param = OpVariable %_ptr_Function_S_t Function
393 %30 = OpLoad %v2float %texCoords
394 %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
395 OpStore %31 %30
396 %32 = OpLoad %19 %sampler15
397 %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
398 OpStore %33 %32
399 %34 = OpLoad %S_t %s0
400 OpStore %param %34
401 %35 = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
402 OpReturn
403 OpFunctionEnd
404 )";
405 
406   const std::string after =
407       R"(%main2 = OpFunction %void None %13
408 %29 = OpLabel
409 %s0 = OpVariable %_ptr_Function_S_t Function
410 %param = OpVariable %_ptr_Function_S_t Function
411 %30 = OpLoad %v2float %texCoords
412 %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
413 OpStore %31 %30
414 %32 = OpLoad %19 %sampler15
415 %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
416 OpStore %33 %32
417 %34 = OpLoad %S_t %s0
418 OpStore %param %34
419 %45 = OpAccessChain %_ptr_Function_19 %param %int_2
420 %46 = OpLoad %19 %45
421 %47 = OpAccessChain %_ptr_Function_v2float %param %int_0
422 %48 = OpLoad %v2float %47
423 %49 = OpImageSampleImplicitLod %v4float %46 %48
424 OpStore %outColor %49
425 OpReturn
426 OpFunctionEnd
427 )";
428 
429   const std::string post_defs =
430       R"(%main = OpFunction %void None %13
431 %36 = OpLabel
432 %37 = OpFunctionCall %void %main2
433 OpReturn
434 OpFunctionEnd
435 %foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
436 %s = OpFunctionParameter %_ptr_Function_S_t
437 %38 = OpLabel
438 %39 = OpAccessChain %_ptr_Function_19 %s %int_2
439 %40 = OpLoad %19 %39
440 %41 = OpAccessChain %_ptr_Function_v2float %s %int_0
441 %42 = OpLoad %v2float %41
442 %43 = OpImageSampleImplicitLod %v4float %40 %42
443 OpStore %outColor %43
444 OpReturn
445 OpFunctionEnd
446 )";
447 
448   SinglePassRunAndCheck<InlineOpaquePass>(
449       predefs + before + post_defs, predefs + after + post_defs, true, true);
450 }
451 
TEST_F(InlineOpaqueTest,NoInlineNoOpaque)452 TEST_F(InlineOpaqueTest, NoInlineNoOpaque) {
453   // Function without opaque interface is not inlined.
454   // #version 140
455   //
456   // in vec4 BaseColor;
457   //
458   // float foo(vec4 bar)
459   // {
460   //     return bar.x + bar.y;
461   // }
462   //
463   // void main()
464   // {
465   //     vec4 color = vec4(foo(BaseColor));
466   //     gl_FragColor = color;
467   // }
468 
469   const std::string assembly =
470       R"(OpCapability Shader
471 %1 = OpExtInstImport "GLSL.std.450"
472 OpMemoryModel Logical GLSL450
473 OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
474 OpExecutionMode %main OriginUpperLeft
475 OpSource GLSL 140
476 OpName %main "main"
477 OpName %foo_vf4_ "foo(vf4;"
478 OpName %bar "bar"
479 OpName %color "color"
480 OpName %BaseColor "BaseColor"
481 OpName %param "param"
482 OpName %gl_FragColor "gl_FragColor"
483 %void = OpTypeVoid
484 %10 = OpTypeFunction %void
485 %float = OpTypeFloat 32
486 %v4float = OpTypeVector %float 4
487 %_ptr_Function_v4float = OpTypePointer Function %v4float
488 %14 = OpTypeFunction %float %_ptr_Function_v4float
489 %uint = OpTypeInt 32 0
490 %uint_0 = OpConstant %uint 0
491 %_ptr_Function_float = OpTypePointer Function %float
492 %uint_1 = OpConstant %uint 1
493 %_ptr_Input_v4float = OpTypePointer Input %v4float
494 %BaseColor = OpVariable %_ptr_Input_v4float Input
495 %_ptr_Output_v4float = OpTypePointer Output %v4float
496 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
497 %main = OpFunction %void None %10
498 %21 = OpLabel
499 %color = OpVariable %_ptr_Function_v4float Function
500 %param = OpVariable %_ptr_Function_v4float Function
501 %22 = OpLoad %v4float %BaseColor
502 OpStore %param %22
503 %23 = OpFunctionCall %float %foo_vf4_ %param
504 %24 = OpCompositeConstruct %v4float %23 %23 %23 %23
505 OpStore %color %24
506 %25 = OpLoad %v4float %color
507 OpStore %gl_FragColor %25
508 OpReturn
509 OpFunctionEnd
510 %foo_vf4_ = OpFunction %float None %14
511 %bar = OpFunctionParameter %_ptr_Function_v4float
512 %26 = OpLabel
513 %27 = OpAccessChain %_ptr_Function_float %bar %uint_0
514 %28 = OpLoad %float %27
515 %29 = OpAccessChain %_ptr_Function_float %bar %uint_1
516 %30 = OpLoad %float %29
517 %31 = OpFAdd %float %28 %30
518 OpReturnValue %31
519 OpFunctionEnd
520 )";
521 
522   SinglePassRunAndCheck<InlineOpaquePass>(assembly, assembly, true, true);
523 }
524 
525 }  // namespace
526 }  // namespace opt
527 }  // namespace spvtools
528