aboutsummaryrefslogtreecommitdiff
path: root/test/opt/inline_opaque_test.cpp
diff options
context:
space:
mode:
authorGregF <greg@LunarG.com>2017-08-15 17:58:28 -0600
committerDavid Neto <dneto@google.com>2017-08-18 18:04:30 -0400
commit429ca05b3f8cbec89845ed2e8e2f9026ad95f3d8 (patch)
tree23f34b0e8aca4cfcee67fa03941dc645e189b5be /test/opt/inline_opaque_test.cpp
parentc8c86a0d368bebaf924870d8fb49ea29798c96a6 (diff)
downloadspirv-tools-429ca05b3f8cbec89845ed2e8e2f9026ad95f3d8.tar.gz
Opt: Create InlineOpaquePass
Only inline calls to functions with opaque params or return TODO: Handle parameter type or return type where the opqaue type is buried within an array.
Diffstat (limited to 'test/opt/inline_opaque_test.cpp')
-rw-r--r--test/opt/inline_opaque_test.cpp412
1 files changed, 412 insertions, 0 deletions
diff --git a/test/opt/inline_opaque_test.cpp b/test/opt/inline_opaque_test.cpp
new file mode 100644
index 00000000..76788945
--- /dev/null
+++ b/test/opt/inline_opaque_test.cpp
@@ -0,0 +1,412 @@
+// Copyright (c) 2017 Valve Corporation
+// Copyright (c) 2017 LunarG Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "pass_fixture.h"
+#include "pass_utils.h"
+
+namespace {
+
+using namespace spvtools;
+
+using InlineOpaqueTest = PassTest<::testing::Test>;
+
+TEST_F(InlineOpaqueTest, InlineCallWithStructArgContainingSampledImage) {
+ // Function with opaque argument is inlined.
+ // TODO(greg-lunarg): Add HLSL code
+
+ const std::string predefs =
+ R"(OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %outColor %texCoords
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 140
+OpName %main "main"
+OpName %S_t "S_t"
+OpMemberName %S_t 0 "v0"
+OpMemberName %S_t 1 "v1"
+OpMemberName %S_t 2 "smp"
+OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
+OpName %s "s"
+OpName %outColor "outColor"
+OpName %sampler15 "sampler15"
+OpName %s0 "s0"
+OpName %texCoords "texCoords"
+OpName %param "param"
+OpDecorate %sampler15 DescriptorSet 0
+%void = OpTypeVoid
+%12 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%outColor = OpVariable %_ptr_Output_v4float Output
+%17 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%18 = OpTypeSampledImage %17
+%S_t = OpTypeStruct %v2float %v2float %18
+%_ptr_Function_S_t = OpTypePointer Function %S_t
+%20 = OpTypeFunction %void %_ptr_Function_S_t
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+%_ptr_Function_18 = OpTypePointer Function %18
+%sampler15 = OpVariable %_ptr_UniformConstant_18 UniformConstant
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%int_2 = OpConstant %int 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+%texCoords = OpVariable %_ptr_Input_v2float Input
+)";
+
+ const std::string before =
+ R"(%main = OpFunction %void None %12
+%28 = OpLabel
+%s0 = OpVariable %_ptr_Function_S_t Function
+%param = OpVariable %_ptr_Function_S_t Function
+%29 = OpLoad %v2float %texCoords
+%30 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
+OpStore %30 %29
+%31 = OpLoad %18 %sampler15
+%32 = OpAccessChain %_ptr_Function_18 %s0 %int_2
+OpStore %32 %31
+%33 = OpLoad %S_t %s0
+OpStore %param %33
+%34 = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
+OpReturn
+OpFunctionEnd
+)";
+
+ const std::string after =
+ R"(%main = OpFunction %void None %12
+%28 = OpLabel
+%s0 = OpVariable %_ptr_Function_S_t Function
+%param = OpVariable %_ptr_Function_S_t Function
+%29 = OpLoad %v2float %texCoords
+%30 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
+OpStore %30 %29
+%31 = OpLoad %18 %sampler15
+%32 = OpAccessChain %_ptr_Function_18 %s0 %int_2
+OpStore %32 %31
+%33 = OpLoad %S_t %s0
+OpStore %param %33
+%41 = OpAccessChain %_ptr_Function_18 %param %int_2
+%42 = OpLoad %18 %41
+%43 = OpAccessChain %_ptr_Function_v2float %param %int_0
+%44 = OpLoad %v2float %43
+%45 = OpImageSampleImplicitLod %v4float %42 %44
+OpStore %outColor %45
+OpReturn
+OpFunctionEnd
+)";
+
+ const std::string post_defs =
+ R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %20
+%s = OpFunctionParameter %_ptr_Function_S_t
+%35 = OpLabel
+%36 = OpAccessChain %_ptr_Function_18 %s %int_2
+%37 = OpLoad %18 %36
+%38 = OpAccessChain %_ptr_Function_v2float %s %int_0
+%39 = OpLoad %v2float %38
+%40 = OpImageSampleImplicitLod %v4float %37 %39
+OpStore %outColor %40
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndCheck<opt::InlineOpaquePass>(
+ predefs + before + post_defs,
+ predefs + after + post_defs, true, true);
+}
+
+TEST_F(InlineOpaqueTest, InlineOpaqueReturn) {
+ // Function with opaque return value is inlined.
+ // TODO(greg-lunarg): Add HLSL code
+
+ const std::string predefs =
+ R"(OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %texCoords %outColor
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 140
+OpName %main "main"
+OpName %foo_ "foo("
+OpName %texCoords "texCoords"
+OpName %outColor "outColor"
+OpName %sampler15 "sampler15"
+OpName %sampler16 "sampler16"
+OpDecorate %sampler15 DescriptorSet 0
+OpDecorate %sampler16 DescriptorSet 0
+%void = OpTypeVoid
+%9 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%bool = OpTypeBool
+%false = OpConstantFalse %bool
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+%texCoords = OpVariable %_ptr_Input_v2float Input
+%float_0 = OpConstant %float 0
+%16 = OpConstantComposite %v2float %float_0 %float_0
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%outColor = OpVariable %_ptr_Output_v4float Output
+%19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%20 = OpTypeSampledImage %19
+%21 = OpTypeFunction %20
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+%_ptr_Function_20 = OpTypePointer Function %20
+%sampler15 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+%sampler16 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+)";
+
+ const std::string before =
+ R"(%main = OpFunction %void None %9
+%24 = OpLabel
+%25 = OpVariable %_ptr_Function_20 Function
+%26 = OpFunctionCall %20 %foo_
+OpStore %25 %26
+%27 = OpLoad %20 %25
+%28 = OpLoad %v2float %texCoords
+%29 = OpImageSampleImplicitLod %v4float %27 %28
+OpStore %outColor %29
+OpReturn
+OpFunctionEnd
+)";
+
+ const std::string after =
+ R"(%main = OpFunction %void None %9
+%24 = OpLabel
+%34 = OpVariable %_ptr_Function_20 Function
+%35 = OpVariable %_ptr_Function_20 Function
+%25 = OpVariable %_ptr_Function_20 Function
+%36 = OpLoad %20 %sampler16
+OpStore %34 %36
+%37 = OpLoad %20 %34
+OpStore %35 %37
+%26 = OpLoad %20 %35
+OpStore %25 %26
+%27 = OpLoad %20 %25
+%28 = OpLoad %v2float %texCoords
+%29 = OpImageSampleImplicitLod %v4float %27 %28
+OpStore %outColor %29
+OpReturn
+OpFunctionEnd
+)";
+
+ const std::string post_defs =
+ R"(%foo_ = OpFunction %20 None %21
+%30 = OpLabel
+%31 = OpVariable %_ptr_Function_20 Function
+%32 = OpLoad %20 %sampler16
+OpStore %31 %32
+%33 = OpLoad %20 %31
+OpReturnValue %33
+OpFunctionEnd
+)";
+
+ SinglePassRunAndCheck<opt::InlineOpaquePass>(
+ predefs + before + post_defs,
+ predefs + after + post_defs, true, true);
+}
+
+TEST_F(InlineOpaqueTest, InlineInNonEntryPointFunction) {
+ // This demonstrates opaque inlining in a function that is not
+ // an entry point function (main2) but is in the call tree of an
+ // entry point function (main).
+ // TODO(greg-lunarg): Add HLSL code
+
+ const std::string predefs =
+ R"(OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %outColor %texCoords
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 140
+OpName %main "main"
+OpName %main2 "main2"
+OpName %S_t "S_t"
+OpMemberName %S_t 0 "v0"
+OpMemberName %S_t 1 "v1"
+OpMemberName %S_t 2 "smp"
+OpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;"
+OpName %s "s"
+OpName %outColor "outColor"
+OpName %sampler15 "sampler15"
+OpName %s0 "s0"
+OpName %texCoords "texCoords"
+OpName %param "param"
+OpDecorate %sampler15 DescriptorSet 0
+%void = OpTypeVoid
+%13 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%outColor = OpVariable %_ptr_Output_v4float Output
+%18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%19 = OpTypeSampledImage %18
+%S_t = OpTypeStruct %v2float %v2float %19
+%_ptr_Function_S_t = OpTypePointer Function %S_t
+%21 = OpTypeFunction %void %_ptr_Function_S_t
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+%_ptr_Function_19 = OpTypePointer Function %19
+%sampler15 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%int_2 = OpConstant %int 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+%texCoords = OpVariable %_ptr_Input_v2float Input
+)";
+
+ const std::string before =
+ R"(%main2 = OpFunction %void None %13
+%29 = OpLabel
+%s0 = OpVariable %_ptr_Function_S_t Function
+%param = OpVariable %_ptr_Function_S_t Function
+%30 = OpLoad %v2float %texCoords
+%31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
+OpStore %31 %30
+%32 = OpLoad %19 %sampler15
+%33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
+OpStore %33 %32
+%34 = OpLoad %S_t %s0
+OpStore %param %34
+%35 = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
+OpReturn
+OpFunctionEnd
+)";
+
+ const std::string after =
+ R"(%main2 = OpFunction %void None %13
+%29 = OpLabel
+%s0 = OpVariable %_ptr_Function_S_t Function
+%param = OpVariable %_ptr_Function_S_t Function
+%30 = OpLoad %v2float %texCoords
+%31 = OpAccessChain %_ptr_Function_v2float %s0 %int_0
+OpStore %31 %30
+%32 = OpLoad %19 %sampler15
+%33 = OpAccessChain %_ptr_Function_19 %s0 %int_2
+OpStore %33 %32
+%34 = OpLoad %S_t %s0
+OpStore %param %34
+%44 = OpAccessChain %_ptr_Function_19 %param %int_2
+%45 = OpLoad %19 %44
+%46 = OpAccessChain %_ptr_Function_v2float %param %int_0
+%47 = OpLoad %v2float %46
+%48 = OpImageSampleImplicitLod %v4float %45 %47
+OpStore %outColor %48
+OpReturn
+OpFunctionEnd
+)";
+
+ const std::string post_defs =
+ R"(%main = OpFunction %void None %13
+%36 = OpLabel
+%37 = OpFunctionCall %void %main2
+OpReturn
+OpFunctionEnd
+%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
+%s = OpFunctionParameter %_ptr_Function_S_t
+%38 = OpLabel
+%39 = OpAccessChain %_ptr_Function_19 %s %int_2
+%40 = OpLoad %19 %39
+%41 = OpAccessChain %_ptr_Function_v2float %s %int_0
+%42 = OpLoad %v2float %41
+%43 = OpImageSampleImplicitLod %v4float %40 %42
+OpStore %outColor %43
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndCheck<opt::InlineOpaquePass>(
+ predefs + before + post_defs,
+ predefs + after + post_defs, true, true);
+}
+
+TEST_F(InlineOpaqueTest, NoInlineNoOpaque) {
+ // Function without opaque interface is not inlined.
+ // #version 140
+ //
+ // in vec4 BaseColor;
+ //
+ // float foo(vec4 bar)
+ // {
+ // return bar.x + bar.y;
+ // }
+ //
+ // void main()
+ // {
+ // vec4 color = vec4(foo(BaseColor));
+ // gl_FragColor = color;
+ // }
+
+ const std::string assembly =
+ R"(OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 140
+OpName %main "main"
+OpName %foo_vf4_ "foo(vf4;"
+OpName %bar "bar"
+OpName %color "color"
+OpName %BaseColor "BaseColor"
+OpName %param "param"
+OpName %gl_FragColor "gl_FragColor"
+%void = OpTypeVoid
+%10 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%14 = OpTypeFunction %float %_ptr_Function_v4float
+%uint = OpTypeInt 32 0
+%uint_0 = OpConstant %uint 0
+%_ptr_Function_float = OpTypePointer Function %float
+%uint_1 = OpConstant %uint 1
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%BaseColor = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%gl_FragColor = OpVariable %_ptr_Output_v4float Output
+%main = OpFunction %void None %10
+%21 = OpLabel
+%color = OpVariable %_ptr_Function_v4float Function
+%param = OpVariable %_ptr_Function_v4float Function
+%22 = OpLoad %v4float %BaseColor
+OpStore %param %22
+%23 = OpFunctionCall %float %foo_vf4_ %param
+%24 = OpCompositeConstruct %v4float %23 %23 %23 %23
+OpStore %color %24
+%25 = OpLoad %v4float %color
+OpStore %gl_FragColor %25
+OpReturn
+OpFunctionEnd
+%foo_vf4_ = OpFunction %float None %14
+%bar = OpFunctionParameter %_ptr_Function_v4float
+%26 = OpLabel
+%27 = OpAccessChain %_ptr_Function_float %bar %uint_0
+%28 = OpLoad %float %27
+%29 = OpAccessChain %_ptr_Function_float %bar %uint_1
+%30 = OpLoad %float %29
+%31 = OpFAdd %float %28 %30
+OpReturnValue %31
+OpFunctionEnd
+)";
+
+ SinglePassRunAndCheck<opt::InlineOpaquePass>(
+ assembly, assembly, true, true);
+}
+
+} // anonymous namespace