Home | History | Annotate | Download | only in opt
      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 
     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 =
     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 OpDecorate %sampler15 DescriptorSet 0
     51 %void = OpTypeVoid
     52 %12 = OpTypeFunction %void
     53 %float = OpTypeFloat 32
     54 %v2float = OpTypeVector %float 2
     55 %v4float = OpTypeVector %float 4
     56 %_ptr_Output_v4float = OpTypePointer Output %v4float
     57 %outColor = OpVariable %_ptr_Output_v4float Output
     58 %17 = OpTypeImage %float 2D 0 0 0 1 Unknown
     59 %18 = OpTypeSampledImage %17
     60 %S_t = OpTypeStruct %v2float %v2float %18
     61 %_ptr_Function_S_t = OpTypePointer Function %S_t
     62 %20 = OpTypeFunction %void %_ptr_Function_S_t
     63 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
     64 %_ptr_Function_18 = OpTypePointer Function %18
     65 %sampler15 = OpVariable %_ptr_UniformConstant_18 UniformConstant
     66 %int = OpTypeInt 32 1
     67 %int_0 = OpConstant %int 0
     68 %int_2 = OpConstant %int 2
     69 %_ptr_Function_v2float = OpTypePointer Function %v2float
     70 %_ptr_Input_v2float = OpTypePointer Input %v2float
     71 %texCoords = OpVariable %_ptr_Input_v2float Input
     72 )";
     73 
     74   const std::string before =
     75       R"(%main = OpFunction %void None %12
     76 %28 = OpLabel
     77 %s0 = OpVariable %_ptr_Function_S_t Function
     78 %param = OpVariable %_ptr_Function_S_t Function
     79 %29 = OpLoad %v2float %texCoords
     80 %30 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
     81 OpStore %30 %29
     82 %31 = OpLoad %18 %sampler15
     83 %32 = OpAccessChain %_ptr_Function_18 %s0 %int_2
     84 OpStore %32 %31
     85 %33 = OpLoad %S_t %s0
     86 OpStore %param %33
     87 %34 = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
     88 OpReturn
     89 OpFunctionEnd
     90 )";
     91 
     92   const std::string after =
     93       R"(%main = OpFunction %void None %12
     94 %28 = OpLabel
     95 %s0 = OpVariable %_ptr_Function_S_t Function
     96 %param = OpVariable %_ptr_Function_S_t Function
     97 %29 = OpLoad %v2float %texCoords
     98 %30 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
     99 OpStore %30 %29
    100 %31 = OpLoad %18 %sampler15
    101 %32 = OpAccessChain %_ptr_Function_18 %s0 %int_2
    102 OpStore %32 %31
    103 %33 = OpLoad %S_t %s0
    104 OpStore %param %33
    105 %41 = OpAccessChain %_ptr_Function_18 %param %int_2
    106 %42 = OpLoad %18 %41
    107 %43 = OpAccessChain %_ptr_Function_v2float %param %int_0
    108 %44 = OpLoad %v2float %43
    109 %45 = OpImageSampleImplicitLod %v4float %42 %44
    110 OpStore %outColor %45
    111 OpReturn
    112 OpFunctionEnd
    113 )";
    114 
    115   const std::string post_defs =
    116       R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %20
    117 %s = OpFunctionParameter %_ptr_Function_S_t
    118 %35 = OpLabel
    119 %36 = OpAccessChain %_ptr_Function_18 %s %int_2
    120 %37 = OpLoad %18 %36
    121 %38 = OpAccessChain %_ptr_Function_v2float %s %int_0
    122 %39 = OpLoad %v2float %38
    123 %40 = OpImageSampleImplicitLod %v4float %37 %39
    124 OpStore %outColor %40
    125 OpReturn
    126 OpFunctionEnd
    127 )";
    128 
    129   SinglePassRunAndCheck<InlineOpaquePass>(
    130       predefs + before + post_defs, predefs + after + post_defs, true, true);
    131 }
    132 
    133 TEST_F(InlineOpaqueTest, InlineOpaqueReturn) {
    134   // Function with opaque return value is inlined.
    135   // TODO(greg-lunarg): Add HLSL code
    136 
    137   const std::string predefs =
    138       R"(OpCapability Shader
    139 %1 = OpExtInstImport "GLSL.std.450"
    140 OpMemoryModel Logical GLSL450
    141 OpEntryPoint Fragment %main "main" %texCoords %outColor
    142 OpExecutionMode %main OriginUpperLeft
    143 OpSource GLSL 140
    144 OpName %main "main"
    145 OpName %foo_ "foo("
    146 OpName %texCoords "texCoords"
    147 OpName %outColor "outColor"
    148 OpName %sampler15 "sampler15"
    149 OpName %sampler16 "sampler16"
    150 OpDecorate %sampler15 DescriptorSet 0
    151 OpDecorate %sampler16 DescriptorSet 0
    152 %void = OpTypeVoid
    153 %9 = OpTypeFunction %void
    154 %float = OpTypeFloat 32
    155 %v2float = OpTypeVector %float 2
    156 %bool = OpTypeBool
    157 %false = OpConstantFalse %bool
    158 %_ptr_Input_v2float = OpTypePointer Input %v2float
    159 %texCoords = OpVariable %_ptr_Input_v2float Input
    160 %float_0 = OpConstant %float 0
    161 %16 = OpConstantComposite %v2float %float_0 %float_0
    162 %v4float = OpTypeVector %float 4
    163 %_ptr_Output_v4float = OpTypePointer Output %v4float
    164 %outColor = OpVariable %_ptr_Output_v4float Output
    165 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
    166 %20 = OpTypeSampledImage %19
    167 %21 = OpTypeFunction %20
    168 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
    169 %_ptr_Function_20 = OpTypePointer Function %20
    170 %sampler15 = OpVariable %_ptr_UniformConstant_20 UniformConstant
    171 %sampler16 = OpVariable %_ptr_UniformConstant_20 UniformConstant
    172 )";
    173 
    174   const std::string before =
    175       R"(%main = OpFunction %void None %9
    176 %24 = OpLabel
    177 %25 = OpVariable %_ptr_Function_20 Function
    178 %26 = OpFunctionCall %20 %foo_
    179 OpStore %25 %26
    180 %27 = OpLoad %20 %25
    181 %28 = OpLoad %v2float %texCoords
    182 %29 = OpImageSampleImplicitLod %v4float %27 %28
    183 OpStore %outColor %29
    184 OpReturn
    185 OpFunctionEnd
    186 )";
    187 
    188   const std::string after =
    189       R"(%main = OpFunction %void None %9
    190 %24 = OpLabel
    191 %34 = OpVariable %_ptr_Function_20 Function
    192 %35 = OpVariable %_ptr_Function_20 Function
    193 %25 = OpVariable %_ptr_Function_20 Function
    194 %36 = OpLoad %20 %sampler16
    195 OpStore %34 %36
    196 %37 = OpLoad %20 %34
    197 OpStore %35 %37
    198 %26 = OpLoad %20 %35
    199 OpStore %25 %26
    200 %27 = OpLoad %20 %25
    201 %28 = OpLoad %v2float %texCoords
    202 %29 = OpImageSampleImplicitLod %v4float %27 %28
    203 OpStore %outColor %29
    204 OpReturn
    205 OpFunctionEnd
    206 )";
    207 
    208   const std::string post_defs =
    209       R"(%foo_ = OpFunction %20 None %21
    210 %30 = OpLabel
    211 %31 = OpVariable %_ptr_Function_20 Function
    212 %32 = OpLoad %20 %sampler16
    213 OpStore %31 %32
    214 %33 = OpLoad %20 %31
    215 OpReturnValue %33
    216 OpFunctionEnd
    217 )";
    218 
    219   SinglePassRunAndCheck<InlineOpaquePass>(
    220       predefs + before + post_defs, predefs + after + post_defs, true, true);
    221 }
    222 
    223 TEST_F(InlineOpaqueTest, InlineInNonEntryPointFunction) {
    224   // This demonstrates opaque inlining in a function that is not
    225   // an entry point function (main2) but is in the call tree of an
    226   // entry point function (main).
    227   // TODO(greg-lunarg): Add HLSL code
    228 
    229   const std::string predefs =
    230       R"(OpCapability Shader
    231 %1 = OpExtInstImport "GLSL.std.450"
    232 OpMemoryModel Logical GLSL450
    233 OpEntryPoint Fragment %main "main" %outColor %texCoords
    234 OpExecutionMode %main OriginUpperLeft
    235 OpSource GLSL 140
    236 OpName %main "main"
    237 OpName %main2 "main2"
    238 OpName %S_t "S_t"
    239 OpMemberName %S_t 0 "v0"
    240 OpMemberName %S_t 1 "v1"
    241 OpMemberName %S_t 2 "smp"
    242 OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
    243 OpName %s "s"
    244 OpName %outColor "outColor"
    245 OpName %sampler15 "sampler15"
    246 OpName %s0 "s0"
    247 OpName %texCoords "texCoords"
    248 OpName %param "param"
    249 OpDecorate %sampler15 DescriptorSet 0
    250 %void = OpTypeVoid
    251 %13 = OpTypeFunction %void
    252 %float = OpTypeFloat 32
    253 %v2float = OpTypeVector %float 2
    254 %v4float = OpTypeVector %float 4
    255 %_ptr_Output_v4float = OpTypePointer Output %v4float
    256 %outColor = OpVariable %_ptr_Output_v4float Output
    257 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
    258 %19 = OpTypeSampledImage %18
    259 %S_t = OpTypeStruct %v2float %v2float %19
    260 %_ptr_Function_S_t = OpTypePointer Function %S_t
    261 %21 = OpTypeFunction %void %_ptr_Function_S_t
    262 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
    263 %_ptr_Function_19 = OpTypePointer Function %19
    264 %sampler15 = OpVariable %_ptr_UniformConstant_19 UniformConstant
    265 %int = OpTypeInt 32 1
    266 %int_0 = OpConstant %int 0
    267 %int_2 = OpConstant %int 2
    268 %_ptr_Function_v2float = OpTypePointer Function %v2float
    269 %_ptr_Input_v2float = OpTypePointer Input %v2float
    270 %texCoords = OpVariable %_ptr_Input_v2float Input
    271 )";
    272 
    273   const std::string before =
    274       R"(%main2 = OpFunction %void None %13
    275 %29 = OpLabel
    276 %s0 = OpVariable %_ptr_Function_S_t Function
    277 %param = OpVariable %_ptr_Function_S_t Function
    278 %30 = OpLoad %v2float %texCoords
    279 %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
    280 OpStore %31 %30
    281 %32 = OpLoad %19 %sampler15
    282 %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
    283 OpStore %33 %32
    284 %34 = OpLoad %S_t %s0
    285 OpStore %param %34
    286 %35 = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
    287 OpReturn
    288 OpFunctionEnd
    289 )";
    290 
    291   const std::string after =
    292       R"(%main2 = OpFunction %void None %13
    293 %29 = OpLabel
    294 %s0 = OpVariable %_ptr_Function_S_t Function
    295 %param = OpVariable %_ptr_Function_S_t Function
    296 %30 = OpLoad %v2float %texCoords
    297 %31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
    298 OpStore %31 %30
    299 %32 = OpLoad %19 %sampler15
    300 %33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
    301 OpStore %33 %32
    302 %34 = OpLoad %S_t %s0
    303 OpStore %param %34
    304 %44 = OpAccessChain %_ptr_Function_19 %param %int_2
    305 %45 = OpLoad %19 %44
    306 %46 = OpAccessChain %_ptr_Function_v2float %param %int_0
    307 %47 = OpLoad %v2float %46
    308 %48 = OpImageSampleImplicitLod %v4float %45 %47
    309 OpStore %outColor %48
    310 OpReturn
    311 OpFunctionEnd
    312 )";
    313 
    314   const std::string post_defs =
    315       R"(%main = OpFunction %void None %13
    316 %36 = OpLabel
    317 %37 = OpFunctionCall %void %main2
    318 OpReturn
    319 OpFunctionEnd
    320 %foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
    321 %s = OpFunctionParameter %_ptr_Function_S_t
    322 %38 = OpLabel
    323 %39 = OpAccessChain %_ptr_Function_19 %s %int_2
    324 %40 = OpLoad %19 %39
    325 %41 = OpAccessChain %_ptr_Function_v2float %s %int_0
    326 %42 = OpLoad %v2float %41
    327 %43 = OpImageSampleImplicitLod %v4float %40 %42
    328 OpStore %outColor %43
    329 OpReturn
    330 OpFunctionEnd
    331 )";
    332 
    333   SinglePassRunAndCheck<InlineOpaquePass>(
    334       predefs + before + post_defs, predefs + after + post_defs, true, true);
    335 }
    336 
    337 TEST_F(InlineOpaqueTest, NoInlineNoOpaque) {
    338   // Function without opaque interface is not inlined.
    339   // #version 140
    340   //
    341   // in vec4 BaseColor;
    342   //
    343   // float foo(vec4 bar)
    344   // {
    345   //     return bar.x + bar.y;
    346   // }
    347   //
    348   // void main()
    349   // {
    350   //     vec4 color = vec4(foo(BaseColor));
    351   //     gl_FragColor = color;
    352   // }
    353 
    354   const std::string assembly =
    355       R"(OpCapability Shader
    356 %1 = OpExtInstImport "GLSL.std.450"
    357 OpMemoryModel Logical GLSL450
    358 OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
    359 OpExecutionMode %main OriginUpperLeft
    360 OpSource GLSL 140
    361 OpName %main "main"
    362 OpName %foo_vf4_ "foo(vf4;"
    363 OpName %bar "bar"
    364 OpName %color "color"
    365 OpName %BaseColor "BaseColor"
    366 OpName %param "param"
    367 OpName %gl_FragColor "gl_FragColor"
    368 %void = OpTypeVoid
    369 %10 = OpTypeFunction %void
    370 %float = OpTypeFloat 32
    371 %v4float = OpTypeVector %float 4
    372 %_ptr_Function_v4float = OpTypePointer Function %v4float
    373 %14 = OpTypeFunction %float %_ptr_Function_v4float
    374 %uint = OpTypeInt 32 0
    375 %uint_0 = OpConstant %uint 0
    376 %_ptr_Function_float = OpTypePointer Function %float
    377 %uint_1 = OpConstant %uint 1
    378 %_ptr_Input_v4float = OpTypePointer Input %v4float
    379 %BaseColor = OpVariable %_ptr_Input_v4float Input
    380 %_ptr_Output_v4float = OpTypePointer Output %v4float
    381 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
    382 %main = OpFunction %void None %10
    383 %21 = OpLabel
    384 %color = OpVariable %_ptr_Function_v4float Function
    385 %param = OpVariable %_ptr_Function_v4float Function
    386 %22 = OpLoad %v4float %BaseColor
    387 OpStore %param %22
    388 %23 = OpFunctionCall %float %foo_vf4_ %param
    389 %24 = OpCompositeConstruct %v4float %23 %23 %23 %23
    390 OpStore %color %24
    391 %25 = OpLoad %v4float %color
    392 OpStore %gl_FragColor %25
    393 OpReturn
    394 OpFunctionEnd
    395 %foo_vf4_ = OpFunction %float None %14
    396 %bar = OpFunctionParameter %_ptr_Function_v4float
    397 %26 = OpLabel
    398 %27 = OpAccessChain %_ptr_Function_float %bar %uint_0
    399 %28 = OpLoad %float %27
    400 %29 = OpAccessChain %_ptr_Function_float %bar %uint_1
    401 %30 = OpLoad %float %29
    402 %31 = OpFAdd %float %28 %30
    403 OpReturnValue %31
    404 OpFunctionEnd
    405 )";
    406 
    407   SinglePassRunAndCheck<InlineOpaquePass>(assembly, assembly, true, true);
    408 }
    409 
    410 }  // namespace
    411 }  // namespace opt
    412 }  // namespace spvtools
    413