• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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