// 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 <string>

#include "test/opt/pass_fixture.h"
#include "test/opt/pass_utils.h"

namespace spvtools {
namespace opt {
namespace {

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_1 =
      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"
)";

  const std::string name = R"(OpName %return_value "return_value"
)";

  const std::string predefs_2 = R"(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"(%main = 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
%return_value = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
OpReturn
OpFunctionEnd
)";

  const std::string after =
      R"(%main = 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
%42 = OpAccessChain %_ptr_Function_19 %param %int_2
%43 = OpLoad %19 %42
%44 = OpAccessChain %_ptr_Function_v2float %param %int_0
%45 = OpLoad %v2float %44
%46 = OpImageSampleImplicitLod %v4float %43 %45
OpStore %outColor %46
OpReturn
OpFunctionEnd
)";

  const std::string post_defs =
      R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
%s = OpFunctionParameter %_ptr_Function_S_t
%35 = OpLabel
%36 = OpAccessChain %_ptr_Function_19 %s %int_2
%37 = OpLoad %19 %36
%38 = OpAccessChain %_ptr_Function_v2float %s %int_0
%39 = OpLoad %v2float %38
%40 = OpImageSampleImplicitLod %v4float %37 %39
OpStore %outColor %40
OpReturn
OpFunctionEnd
)";

  SinglePassRunAndCheck<InlineOpaquePass>(
      predefs_1 + name + predefs_2 + before + post_defs,
      predefs_1 + predefs_2 + 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
%37 = OpLoad %20 %sampler16
OpStore %34 %37
%38 = OpLoad %20 %34
OpStore %35 %38
%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<InlineOpaquePass>(
      predefs + before + post_defs, predefs + after + post_defs, true, true);
}

TEST_F(InlineOpaqueTest, InlineOpaqueForLinkage) {
  const std::string predefs_1 =
      R"(OpCapability Shader
OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpSource HLSL 630
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 %main LinkageAttributes "main" Export
)";

  const std::string name = R"(OpName %return_value "return_value"
)";

  const std::string predefs_2 = R"(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"(%main = 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
%return_value = OpFunctionCall %void %foo_struct_S_t_vf2_vf21_ %param
OpReturn
OpFunctionEnd
)";

  const std::string after =
      R"(%main = 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
%42 = OpAccessChain %_ptr_Function_19 %param %int_2
%43 = OpLoad %19 %42
%44 = OpAccessChain %_ptr_Function_v2float %param %int_0
%45 = OpLoad %v2float %44
%46 = OpImageSampleImplicitLod %v4float %43 %45
OpStore %outColor %46
OpReturn
OpFunctionEnd
)";

  const std::string post_defs =
      R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %21
%s = OpFunctionParameter %_ptr_Function_S_t
%35 = OpLabel
%36 = OpAccessChain %_ptr_Function_19 %s %int_2
%37 = OpLoad %19 %36
%38 = OpAccessChain %_ptr_Function_v2float %s %int_0
%39 = OpLoad %v2float %38
%40 = OpImageSampleImplicitLod %v4float %37 %39
OpStore %outColor %40
OpReturn
OpFunctionEnd
)";

  SinglePassRunAndCheck<InlineOpaquePass>(
      predefs_1 + name + predefs_2 + before + post_defs,
      predefs_1 + predefs_2 + 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
%45 = OpAccessChain %_ptr_Function_19 %param %int_2
%46 = OpLoad %19 %45
%47 = OpAccessChain %_ptr_Function_v2float %param %int_0
%48 = OpLoad %v2float %47
%49 = OpImageSampleImplicitLod %v4float %46 %48
OpStore %outColor %49
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<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<InlineOpaquePass>(assembly, assembly, true, true);
}

}  // namespace
}  // namespace opt
}  // namespace spvtools
