1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "gmock/gmock.h"
16 #include "src/ast/call_statement.h"
17 #include "src/ast/intrinsic_texture_helper_test.h"
18 #include "src/ast/stage_decoration.h"
19 #include "src/writer/glsl/test_helper.h"
20
21 namespace tint {
22 namespace writer {
23 namespace glsl {
24 namespace {
25
26 using ::testing::HasSubstr;
27
28 struct ExpectedResult {
ExpectedResulttint::writer::glsl::__anon0ac560370111::ExpectedResult29 ExpectedResult(const char* o) : out(o) {} // NOLINT
30
31 std::string pre;
32 std::string out;
33 };
34
expected_texture_overload(ast::intrinsic::test::ValidTextureOverload overload)35 ExpectedResult expected_texture_overload(
36 ast::intrinsic::test::ValidTextureOverload overload) {
37 using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
38 switch (overload) {
39 case ValidTextureOverload::kDimensions1d:
40 case ValidTextureOverload::kDimensions2d:
41 case ValidTextureOverload::kDimensionsDepth2d:
42 case ValidTextureOverload::kDimensionsDepthMultisampled2d:
43 case ValidTextureOverload::kDimensionsMultisampled2d:
44 case ValidTextureOverload::kDimensions2dArray:
45 case ValidTextureOverload::kDimensionsDepth2dArray:
46 case ValidTextureOverload::kDimensions3d:
47 case ValidTextureOverload::kDimensionsCube:
48 case ValidTextureOverload::kDimensionsDepthCube:
49 case ValidTextureOverload::kDimensionsCubeArray:
50 case ValidTextureOverload::kDimensionsDepthCubeArray:
51 case ValidTextureOverload::kDimensions2dLevel:
52 case ValidTextureOverload::kDimensionsDepth2dLevel:
53 case ValidTextureOverload::kDimensions2dArrayLevel:
54 case ValidTextureOverload::kDimensionsDepth2dArrayLevel:
55 case ValidTextureOverload::kDimensions3dLevel:
56 case ValidTextureOverload::kDimensionsCubeLevel:
57 case ValidTextureOverload::kDimensionsDepthCubeLevel:
58 case ValidTextureOverload::kDimensionsCubeArrayLevel:
59 case ValidTextureOverload::kDimensionsDepthCubeArrayLevel:
60 return {"textureSize"};
61 case ValidTextureOverload::kDimensionsStorageWO1d:
62 case ValidTextureOverload::kDimensionsStorageWO2d:
63 case ValidTextureOverload::kDimensionsStorageWO2dArray:
64 case ValidTextureOverload::kDimensionsStorageWO3d:
65 return {"imageSize"};
66 case ValidTextureOverload::kGather2dF32:
67 return R"(textureGather(tint_symbol, vec2(1.0f, 2.0f), 0))";
68 case ValidTextureOverload::kGather2dOffsetF32:
69 return R"(textureGatherOffset(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4), 0))";
70 case ValidTextureOverload::kGather2dArrayF32:
71 return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, float(3)), 0))";
72 case ValidTextureOverload::kGather2dArrayOffsetF32:
73 return R"(textureGatherOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5), 0))";
74 case ValidTextureOverload::kGatherCubeF32:
75 return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 0))";
76 case ValidTextureOverload::kGatherCubeArrayF32:
77 return R"(textureGather(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 0))";
78 case ValidTextureOverload::kGatherDepth2dF32:
79 return R"(textureGather(tint_symbol, vec2(1.0f, 2.0f)))";
80 case ValidTextureOverload::kGatherDepth2dOffsetF32:
81 return R"(textureGatherOffset(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4)))";
82 case ValidTextureOverload::kGatherDepth2dArrayF32:
83 return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, float(3))))";
84 case ValidTextureOverload::kGatherDepth2dArrayOffsetF32:
85 return R"(textureGatherOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)))";
86 case ValidTextureOverload::kGatherDepthCubeF32:
87 return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, 3.0f)))";
88 case ValidTextureOverload::kGatherDepthCubeArrayF32:
89 return R"(textureGather(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4))))";
90 case ValidTextureOverload::kGatherCompareDepth2dF32:
91 return R"(textureGather(tint_symbol, vec2(1.0f, 2.0f), 3.0f))";
92 case ValidTextureOverload::kGatherCompareDepth2dOffsetF32:
93 return R"(textureGatherOffset(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5)))";
94 case ValidTextureOverload::kGatherCompareDepth2dArrayF32:
95 return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f))";
96 case ValidTextureOverload::kGatherCompareDepth2dArrayOffsetF32:
97 return R"(textureGatherOffset(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6)))";
98 case ValidTextureOverload::kGatherCompareDepthCubeF32:
99 return R"(textureGather(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f))";
100 case ValidTextureOverload::kGatherCompareDepthCubeArrayF32:
101 return R"(textureGather(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f))";
102 case ValidTextureOverload::kNumLayers2dArray:
103 case ValidTextureOverload::kNumLayersDepth2dArray:
104 case ValidTextureOverload::kNumLayersCubeArray:
105 case ValidTextureOverload::kNumLayersDepthCubeArray:
106 case ValidTextureOverload::kNumLayersStorageWO2dArray:
107 case ValidTextureOverload::kNumLevels2d:
108 case ValidTextureOverload::kNumLevelsCube:
109 case ValidTextureOverload::kNumLevelsDepth2d:
110 case ValidTextureOverload::kNumLevelsDepthCube:
111 case ValidTextureOverload::kNumLevels2dArray:
112 case ValidTextureOverload::kNumLevels3d:
113 case ValidTextureOverload::kNumLevelsCubeArray:
114 case ValidTextureOverload::kNumLevelsDepth2dArray:
115 case ValidTextureOverload::kNumLevelsDepthCubeArray:
116 return {"textureQueryLevels"};
117 case ValidTextureOverload::kNumSamplesDepthMultisampled2d:
118 case ValidTextureOverload::kNumSamplesMultisampled2d:
119 return {"textureSamples"};
120 case ValidTextureOverload::kSample1dF32:
121 return R"(texture(tint_symbol, 1.0f);)";
122 case ValidTextureOverload::kSample2dF32:
123 return R"(texture(tint_symbol, vec2(1.0f, 2.0f));)";
124 case ValidTextureOverload::kSample2dOffsetF32:
125 return R"(texture(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4));)";
126 case ValidTextureOverload::kSample2dArrayF32:
127 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)));)";
128 case ValidTextureOverload::kSample2dArrayOffsetF32:
129 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5));)";
130 case ValidTextureOverload::kSample3dF32:
131 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f));)";
132 case ValidTextureOverload::kSample3dOffsetF32:
133 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), ivec3(4, 5, 6));)";
134 case ValidTextureOverload::kSampleCubeF32:
135 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f));)";
136 case ValidTextureOverload::kSampleCubeArrayF32:
137 return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)));)";
138 case ValidTextureOverload::kSampleDepth2dF32:
139 return R"(texture(tint_symbol, vec2(1.0f, 2.0f)).x;)";
140 case ValidTextureOverload::kSampleDepth2dOffsetF32:
141 return R"(texture(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4)).x;)";
142 case ValidTextureOverload::kSampleDepth2dArrayF32:
143 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3))).x;)";
144 case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
145 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)).x;)";
146 case ValidTextureOverload::kSampleDepthCubeF32:
147 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f)).x;)";
148 case ValidTextureOverload::kSampleDepthCubeArrayF32:
149 return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4))).x;)";
150 case ValidTextureOverload::kSampleBias2dF32:
151 return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
152 case ValidTextureOverload::kSampleBias2dOffsetF32:
153 return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
154 case ValidTextureOverload::kSampleBias2dArrayF32:
155 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
156 case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
157 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6));)";
158 case ValidTextureOverload::kSampleBias3dF32:
159 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
160 case ValidTextureOverload::kSampleBias3dOffsetF32:
161 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f, ivec3(5, 6, 7));)";
162 case ValidTextureOverload::kSampleBiasCubeF32:
163 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
164 case ValidTextureOverload::kSampleBiasCubeArrayF32:
165 return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(3)), 4.0f);)";
166 case ValidTextureOverload::kSampleLevel2dF32:
167 return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
168 case ValidTextureOverload::kSampleLevel2dOffsetF32:
169 return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
170 case ValidTextureOverload::kSampleLevel2dArrayF32:
171 return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f);)";
172 case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
173 return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6));)";
174 case ValidTextureOverload::kSampleLevel3dF32:
175 return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
176 case ValidTextureOverload::kSampleLevel3dOffsetF32:
177 return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f, ivec3(5, 6, 7));)";
178 case ValidTextureOverload::kSampleLevelCubeF32:
179 return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
180 case ValidTextureOverload::kSampleLevelCubeArrayF32:
181 return R"(textureLod(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
182 case ValidTextureOverload::kSampleLevelDepth2dF32:
183 return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3).x;)";
184 case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
185 return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3, ivec2(4, 5)).x;)";
186 case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
187 return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4).x;)";
188 case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
189 return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4, ivec2(5, 6)).x;)";
190 case ValidTextureOverload::kSampleLevelDepthCubeF32:
191 return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4).x;)";
192 case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
193 return R"(textureLod(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5).x;)";
194 case ValidTextureOverload::kSampleGrad2dF32:
195 return R"(textureGrad(tint_symbol, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f));)";
196 case ValidTextureOverload::kSampleGrad2dOffsetF32:
197 return R"(textureGrad(tint_symbol, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f), ivec2(7, 7));)";
198 case ValidTextureOverload::kSampleGrad2dArrayF32:
199 return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));)";
200 case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
201 return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f), ivec2(6, 7));)";
202 case ValidTextureOverload::kSampleGrad3dF32:
203 return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
204 case ValidTextureOverload::kSampleGrad3dOffsetF32:
205 return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f), ivec3(0, 1, 2));)";
206 case ValidTextureOverload::kSampleGradCubeF32:
207 return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
208 case ValidTextureOverload::kSampleGradCubeArrayF32:
209 return R"(textureGrad(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), vec3(5.0f, 6.0f, 7.0f), vec3(8.0f, 9.0f, 10.0f));)";
210 case ValidTextureOverload::kSampleCompareDepth2dF32:
211 return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
212 case ValidTextureOverload::kSampleCompareDepth2dOffsetF32:
213 return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
214 case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
215 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
216 case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
217 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
218 case ValidTextureOverload::kSampleCompareDepthCubeF32:
219 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
220 case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
221 return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
222 case ValidTextureOverload::kSampleCompareLevelDepth2dF32:
223 return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
224 case ValidTextureOverload::kSampleCompareLevelDepth2dOffsetF32:
225 return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
226 case ValidTextureOverload::kSampleCompareLevelDepth2dArrayF32:
227 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
228 case ValidTextureOverload::kSampleCompareLevelDepth2dArrayOffsetF32:
229 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
230 case ValidTextureOverload::kSampleCompareLevelDepthCubeF32:
231 return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
232 case ValidTextureOverload::kSampleCompareLevelDepthCubeArrayF32:
233 return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
234 case ValidTextureOverload::kLoad1dLevelF32:
235 case ValidTextureOverload::kLoad1dLevelU32:
236 case ValidTextureOverload::kLoad1dLevelI32:
237 return R"(texelFetch(tint_symbol, 1, 3);)";
238 case ValidTextureOverload::kLoad2dLevelF32:
239 case ValidTextureOverload::kLoad2dLevelU32:
240 case ValidTextureOverload::kLoad2dLevelI32:
241 return R"(texelFetch(tint_symbol, ivec2(1, 2), 3);)";
242 case ValidTextureOverload::kLoad2dArrayLevelF32:
243 case ValidTextureOverload::kLoad2dArrayLevelU32:
244 case ValidTextureOverload::kLoad2dArrayLevelI32:
245 case ValidTextureOverload::kLoad3dLevelF32:
246 case ValidTextureOverload::kLoad3dLevelU32:
247 case ValidTextureOverload::kLoad3dLevelI32:
248 return R"(texelFetch(tint_symbol, ivec3(1, 2, 3), 4);)";
249 case ValidTextureOverload::kLoadDepthMultisampled2dF32:
250 case ValidTextureOverload::kLoadMultisampled2dF32:
251 case ValidTextureOverload::kLoadMultisampled2dU32:
252 case ValidTextureOverload::kLoadMultisampled2dI32:
253 return R"(texelFetch(tint_symbol, ivec2(1, 2), 3);)";
254 case ValidTextureOverload::kLoadDepth2dLevelF32:
255 return R"(texelFetch(tint_symbol, ivec2(1, 2), 3).x;)";
256 case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
257 return R"(texelFetch(tint_symbol, ivec3(1, 2, 3), 4).x;)";
258 case ValidTextureOverload::kStoreWO1dRgba32float:
259 return R"(imageStore(tint_symbol, 1, vec4(2.0f, 3.0f, 4.0f, 5.0f));)";
260 case ValidTextureOverload::kStoreWO2dRgba32float:
261 return R"(imageStore(tint_symbol, ivec2(1, 2), vec4(3.0f, 4.0f, 5.0f, 6.0f));)";
262 case ValidTextureOverload::kStoreWO2dArrayRgba32float:
263 return R"(imageStore(tint_symbol, ivec3(1, 2, 3), vec4(4.0f, 5.0f, 6.0f, 7.0f));)";
264 case ValidTextureOverload::kStoreWO3dRgba32float:
265 return R"(imageStore(tint_symbol, ivec3(1, 2, 3), vec4(4.0f, 5.0f, 6.0f, 7.0f));)";
266 }
267 return "<unmatched texture overload>";
268 } // NOLINT - Ignore the length of this function
269
270 class GlslGeneratorIntrinsicTextureTest
271 : public TestParamHelper<ast::intrinsic::test::TextureOverloadCase> {};
272
TEST_P(GlslGeneratorIntrinsicTextureTest,Call)273 TEST_P(GlslGeneratorIntrinsicTextureTest, Call) {
274 auto param = GetParam();
275
276 param.BuildTextureVariable(this);
277 param.BuildSamplerVariable(this);
278
279 auto* call = Call(param.function, param.args(this));
280 auto* stmt = CallStmt(call);
281
282 Func("main", {}, ty.void_(), {stmt}, {Stage(ast::PipelineStage::kFragment)});
283
284 GeneratorImpl& gen = SanitizeAndBuild();
285
286 ASSERT_TRUE(gen.Generate()) << gen.error();
287
288 auto expected = expected_texture_overload(param.overload);
289
290 EXPECT_THAT(gen.result(), HasSubstr(expected.pre));
291 EXPECT_THAT(gen.result(), HasSubstr(expected.out));
292 }
293
294 INSTANTIATE_TEST_SUITE_P(
295 GlslGeneratorIntrinsicTextureTest,
296 GlslGeneratorIntrinsicTextureTest,
297 testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
298
299 } // namespace
300 } // namespace glsl
301 } // namespace writer
302 } // namespace tint
303