1fd4e5da5Sopenharmony_ci// Copyright (c) 2021 The Khronos Group Inc.
2fd4e5da5Sopenharmony_ci// Copyright (c) 2021 Valve Corporation
3fd4e5da5Sopenharmony_ci// Copyright (c) 2021 LunarG Inc.
4fd4e5da5Sopenharmony_ci//
5fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
6fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
7fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
10fd4e5da5Sopenharmony_ci//
11fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
12fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
13fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
15fd4e5da5Sopenharmony_ci// limitations under the License.
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include <vector>
18fd4e5da5Sopenharmony_ci
19fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
20fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
21fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
22fd4e5da5Sopenharmony_ci
23fd4e5da5Sopenharmony_cinamespace spvtools {
24fd4e5da5Sopenharmony_cinamespace opt {
25fd4e5da5Sopenharmony_cinamespace {
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciusing InterpFixupTest = PassTest<::testing::Test>;
28fd4e5da5Sopenharmony_ci
29fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr;
30fd4e5da5Sopenharmony_ci
31fd4e5da5Sopenharmony_ciTEST_F(InterpFixupTest, FixInterpAtSample) {
32fd4e5da5Sopenharmony_ci  const std::string text = R"(
33fd4e5da5Sopenharmony_ci               OpCapability Shader
34fd4e5da5Sopenharmony_ci               OpCapability InterpolationFunction
35fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
36fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
37fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %MainPs "MainPs" %i_vPositionOs %_entryPointOutput
38fd4e5da5Sopenharmony_ci               OpExecutionMode %MainPs OriginUpperLeft
39fd4e5da5Sopenharmony_ci               OpSource HLSL 500
40fd4e5da5Sopenharmony_ci               OpName %MainPs "MainPs"
41fd4e5da5Sopenharmony_ci               OpName %i_vPositionOs "i.vPositionOs"
42fd4e5da5Sopenharmony_ci               OpName %_entryPointOutput "@entryPointOutput"
43fd4e5da5Sopenharmony_ci               OpDecorate %i_vPositionOs Location 0
44fd4e5da5Sopenharmony_ci               OpDecorate %_entryPointOutput Location 0
45fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
46fd4e5da5Sopenharmony_ci          %6 = OpTypeFunction %void
47fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
48fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
49fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
50fd4e5da5Sopenharmony_ci         %10 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
51fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
52fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
53fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
54fd4e5da5Sopenharmony_ci       %bool = OpTypeBool
55fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
56fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
57fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
58fd4e5da5Sopenharmony_ci%i_vPositionOs = OpVariable %_ptr_Input_v4float Input
59fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
60fd4e5da5Sopenharmony_ci%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
61fd4e5da5Sopenharmony_ci     %MainPs = OpFunction %void None %6
62fd4e5da5Sopenharmony_ci         %19 = OpLabel
63fd4e5da5Sopenharmony_ci         %20 = OpLoad %v4float %i_vPositionOs
64fd4e5da5Sopenharmony_ci               OpBranch %21
65fd4e5da5Sopenharmony_ci         %21 = OpLabel
66fd4e5da5Sopenharmony_ci         %22 = OpPhi %v4float %10 %19 %23 %24
67fd4e5da5Sopenharmony_ci         %25 = OpPhi %uint %uint_0 %19 %26 %24
68fd4e5da5Sopenharmony_ci         %27 = OpULessThan %bool %25 %uint_4
69fd4e5da5Sopenharmony_ci               OpLoopMerge %28 %24 None
70fd4e5da5Sopenharmony_ci               OpBranchConditional %27 %24 %28
71fd4e5da5Sopenharmony_ci         %24 = OpLabel
72fd4e5da5Sopenharmony_ci         %29 = OpExtInst %v4float %1 InterpolateAtSample %20 %25
73fd4e5da5Sopenharmony_ci;CHECK:  %29 = OpExtInst %v4float %1 InterpolateAtSample %i_vPositionOs %25
74fd4e5da5Sopenharmony_ci         %30 = OpCompositeExtract %float %29 0
75fd4e5da5Sopenharmony_ci         %31 = OpCompositeExtract %float %22 0
76fd4e5da5Sopenharmony_ci         %32 = OpFAdd %float %31 %30
77fd4e5da5Sopenharmony_ci         %23 = OpCompositeInsert %v4float %32 %22 0
78fd4e5da5Sopenharmony_ci         %26 = OpIAdd %uint %25 %int_1
79fd4e5da5Sopenharmony_ci               OpBranch %21
80fd4e5da5Sopenharmony_ci         %28 = OpLabel
81fd4e5da5Sopenharmony_ci               OpStore %_entryPointOutput %22
82fd4e5da5Sopenharmony_ci               OpReturn
83fd4e5da5Sopenharmony_ci               OpFunctionEnd
84fd4e5da5Sopenharmony_ci)";
85fd4e5da5Sopenharmony_ci
86fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InterpFixupPass>(text, false);
87fd4e5da5Sopenharmony_ci}
88fd4e5da5Sopenharmony_ci
89fd4e5da5Sopenharmony_ciTEST_F(InterpFixupTest, FixInterpAtCentroid) {
90fd4e5da5Sopenharmony_ci  const std::string text = R"(
91fd4e5da5Sopenharmony_ci               OpCapability Shader
92fd4e5da5Sopenharmony_ci               OpCapability InterpolationFunction
93fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
94fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
95fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %MainPs "MainPs" %i_vPositionOs %_entryPointOutput
96fd4e5da5Sopenharmony_ci               OpExecutionMode %MainPs OriginUpperLeft
97fd4e5da5Sopenharmony_ci               OpSource HLSL 500
98fd4e5da5Sopenharmony_ci               OpName %MainPs "MainPs"
99fd4e5da5Sopenharmony_ci               OpName %i_vPositionOs "i.vPositionOs"
100fd4e5da5Sopenharmony_ci               OpName %_entryPointOutput "@entryPointOutput"
101fd4e5da5Sopenharmony_ci               OpDecorate %i_vPositionOs Location 0
102fd4e5da5Sopenharmony_ci               OpDecorate %_entryPointOutput Location 0
103fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
104fd4e5da5Sopenharmony_ci          %6 = OpTypeFunction %void
105fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
106fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
107fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
108fd4e5da5Sopenharmony_ci         %10 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
109fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
110fd4e5da5Sopenharmony_ci%i_vPositionOs = OpVariable %_ptr_Input_v4float Input
111fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
112fd4e5da5Sopenharmony_ci%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
113fd4e5da5Sopenharmony_ci     %MainPs = OpFunction %void None %6
114fd4e5da5Sopenharmony_ci         %13 = OpLabel
115fd4e5da5Sopenharmony_ci         %14 = OpLoad %v4float %i_vPositionOs
116fd4e5da5Sopenharmony_ci         %15 = OpExtInst %v4float %1 InterpolateAtCentroid %14
117fd4e5da5Sopenharmony_ci;CHECK:  %15 = OpExtInst %v4float %1 InterpolateAtCentroid %i_vPositionOs
118fd4e5da5Sopenharmony_ci         %16 = OpCompositeExtract %float %15 0
119fd4e5da5Sopenharmony_ci         %17 = OpCompositeInsert %v4float %16 %10 0
120fd4e5da5Sopenharmony_ci               OpStore %_entryPointOutput %17
121fd4e5da5Sopenharmony_ci               OpReturn
122fd4e5da5Sopenharmony_ci               OpFunctionEnd
123fd4e5da5Sopenharmony_ci)";
124fd4e5da5Sopenharmony_ci
125fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InterpFixupPass>(text, false);
126fd4e5da5Sopenharmony_ci}
127fd4e5da5Sopenharmony_ci
128fd4e5da5Sopenharmony_ciTEST_F(InterpFixupTest, FixInterpAtOffset) {
129fd4e5da5Sopenharmony_ci  const std::string text = R"(
130fd4e5da5Sopenharmony_ci               OpCapability Shader
131fd4e5da5Sopenharmony_ci               OpCapability InterpolationFunction
132fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
133fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
134fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %MainPs "MainPs" %i_vPositionOs %_entryPointOutput
135fd4e5da5Sopenharmony_ci               OpExecutionMode %MainPs OriginUpperLeft
136fd4e5da5Sopenharmony_ci               OpSource HLSL 500
137fd4e5da5Sopenharmony_ci               OpName %MainPs "MainPs"
138fd4e5da5Sopenharmony_ci               OpName %i_vPositionOs "i.vPositionOs"
139fd4e5da5Sopenharmony_ci               OpName %_entryPointOutput "@entryPointOutput"
140fd4e5da5Sopenharmony_ci               OpDecorate %i_vPositionOs Location 0
141fd4e5da5Sopenharmony_ci               OpDecorate %_entryPointOutput Location 0
142fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
143fd4e5da5Sopenharmony_ci          %6 = OpTypeFunction %void
144fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
145fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
146fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
147fd4e5da5Sopenharmony_ci         %10 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
148fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
149fd4e5da5Sopenharmony_ci%float_0_0625 = OpConstant %float 0.0625
150fd4e5da5Sopenharmony_ci         %13 = OpConstantComposite %v2float %float_0_0625 %float_0_0625
151fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
152fd4e5da5Sopenharmony_ci%i_vPositionOs = OpVariable %_ptr_Input_v4float Input
153fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
154fd4e5da5Sopenharmony_ci%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
155fd4e5da5Sopenharmony_ci     %MainPs = OpFunction %void None %6
156fd4e5da5Sopenharmony_ci         %16 = OpLabel
157fd4e5da5Sopenharmony_ci         %17 = OpLoad %v4float %i_vPositionOs
158fd4e5da5Sopenharmony_ci         %18 = OpExtInst %v4float %1 InterpolateAtOffset %17 %13
159fd4e5da5Sopenharmony_ci;CHECK:  %18 = OpExtInst %v4float %1 InterpolateAtOffset %i_vPositionOs %13
160fd4e5da5Sopenharmony_ci         %19 = OpCompositeExtract %float %18 0
161fd4e5da5Sopenharmony_ci         %20 = OpCompositeInsert %v4float %19 %10 0
162fd4e5da5Sopenharmony_ci               OpStore %_entryPointOutput %20
163fd4e5da5Sopenharmony_ci               OpReturn
164fd4e5da5Sopenharmony_ci               OpFunctionEnd
165fd4e5da5Sopenharmony_ci)";
166fd4e5da5Sopenharmony_ci
167fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InterpFixupPass>(text, false);
168fd4e5da5Sopenharmony_ci}
169fd4e5da5Sopenharmony_ci
170fd4e5da5Sopenharmony_ci}  // namespace
171fd4e5da5Sopenharmony_ci}  // namespace opt
172fd4e5da5Sopenharmony_ci}  // namespace spvtools
173