blob: 5deab726552e6c881a41501becbea219da37ead8 [file] [log] [blame]
dan sinclair256f1112022-07-22 16:05:06 +00001// Copyright 2022 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 "src/tint/transform/substitute_override.h"
16
17#include "src/tint/transform/test_helper.h"
18
19namespace tint::transform {
20namespace {
21
22using SubstituteOverrideTest = TransformTest;
23
24TEST_F(SubstituteOverrideTest, Error_NoData) {
25 auto* src = R"(
26override width: i32;
27@vertex
28fn main() -> @builtin(position) vec4<f32> {
29 return vec4<f32>();
30}
31)";
32
33 auto* expect = "error: Missing override substitution data";
34
35 DataMap data;
36 auto got = Run<SubstituteOverride>(src, data);
37
38 EXPECT_EQ(expect, str(got));
39}
40
41TEST_F(SubstituteOverrideTest, Error_NoOverrideValue) {
42 auto* src = R"(
43override width: i32;
44@vertex
45fn main() -> @builtin(position) vec4<f32> {
46 return vec4<f32>();
47}
48)";
49
50 auto* expect = "error: Initializer not provided for override, and override not overridden.";
51
52 SubstituteOverride::Config cfg;
53 DataMap data;
54 data.Add<SubstituteOverride::Config>(cfg);
55
56 auto got = Run<SubstituteOverride>(src, data);
57
58 EXPECT_EQ(expect, str(got));
59}
60
61TEST_F(SubstituteOverrideTest, Module_NoOverrides) {
62 auto* src = R"(
63@vertex
64fn main() -> @builtin(position) vec4<f32> {
65 return vec4<f32>();
66}
67)";
68
69 auto* expect = R"(
70@vertex
71fn main() -> @builtin(position) vec4<f32> {
72 return vec4<f32>();
73}
74)";
75
76 SubstituteOverride::Config cfg;
77
78 DataMap data;
79 data.Add<SubstituteOverride::Config>(cfg);
80 auto got = Run<SubstituteOverride>(src, data);
81
82 EXPECT_EQ(expect, str(got));
83}
84
Ben Clayton634a2432022-07-28 10:22:17 +000085TEST_F(SubstituteOverrideTest, ImplicitId) {
dan sinclair256f1112022-07-22 16:05:06 +000086 auto* src = R"(
Zhaoming Jiang6af073c2023-03-20 10:32:45 +000087enable f16;
88
dan sinclair256f1112022-07-22 16:05:06 +000089override i_width: i32;
90override i_height = 1i;
91
92override f_width: f32;
93override f_height = 1.f;
94
Zhaoming Jiang6af073c2023-03-20 10:32:45 +000095override h_width: f16;
96override h_height = 1.h;
dan sinclair256f1112022-07-22 16:05:06 +000097
98override b_width: bool;
99override b_height = true;
100
101override o_width = 2i;
102
103@vertex
104fn main() -> @builtin(position) vec4<f32> {
105 return vec4<f32>();
106}
107)";
108
109 auto* expect = R"(
Zhaoming Jiang6af073c2023-03-20 10:32:45 +0000110enable f16;
111
dan sinclair256f1112022-07-22 16:05:06 +0000112const i_width : i32 = 42i;
113
114const i_height = 11i;
115
dan sinclair6cc183c2023-03-02 21:28:45 +0000116const f_width : f32 = 22.299999237060546875f;
dan sinclair256f1112022-07-22 16:05:06 +0000117
dan sinclair6cc183c2023-03-02 21:28:45 +0000118const f_height = 12.3999996185302734375f;
dan sinclair256f1112022-07-22 16:05:06 +0000119
Zhaoming Jiang6af073c2023-03-20 10:32:45 +0000120const h_width : f16 = 9.3984375h;
121
122const h_height = 3.3984375h;
123
dan sinclair256f1112022-07-22 16:05:06 +0000124const b_width : bool = true;
125
126const b_height = false;
127
128const o_width = 2i;
129
130@vertex
131fn main() -> @builtin(position) vec4<f32> {
132 return vec4<f32>();
133}
134)";
135
136 SubstituteOverride::Config cfg;
Ben Clayton634a2432022-07-28 10:22:17 +0000137 cfg.map.insert({OverrideId{0}, 42.0});
138 cfg.map.insert({OverrideId{1}, 11.0});
139 cfg.map.insert({OverrideId{2}, 22.3});
140 cfg.map.insert({OverrideId{3}, 12.4});
Zhaoming Jiang6af073c2023-03-20 10:32:45 +0000141 cfg.map.insert({OverrideId{4}, 9.4});
142 cfg.map.insert({OverrideId{5}, 3.4});
143 cfg.map.insert({OverrideId{6}, 1.0});
144 cfg.map.insert({OverrideId{7}, 0.0});
dan sinclair256f1112022-07-22 16:05:06 +0000145
146 DataMap data;
147 data.Add<SubstituteOverride::Config>(cfg);
148 auto got = Run<SubstituteOverride>(src, data);
149
150 EXPECT_EQ(expect, str(got));
151}
152
Ben Clayton634a2432022-07-28 10:22:17 +0000153TEST_F(SubstituteOverrideTest, ExplicitId) {
dan sinclair256f1112022-07-22 16:05:06 +0000154 auto* src = R"(
155enable f16;
156
157@id(0) override i_width: i32;
158@id(10) override i_height = 1i;
159
160@id(1) override f_width: f32;
161@id(9) override f_height = 1.f;
162
Zhaoming Jiang6af073c2023-03-20 10:32:45 +0000163@id(2) override h_width: f16;
164@id(8) override h_height = 1.h;
dan sinclair256f1112022-07-22 16:05:06 +0000165
166@id(3) override b_width: bool;
167@id(7) override b_height = true;
168
169@id(5) override o_width = 2i;
170
171@vertex
172fn main() -> @builtin(position) vec4<f32> {
173 return vec4<f32>();
174}
175)";
176
177 auto* expect = R"(
178enable f16;
179
180const i_width : i32 = 42i;
181
182const i_height = 11i;
183
dan sinclair6cc183c2023-03-02 21:28:45 +0000184const f_width : f32 = 22.299999237060546875f;
dan sinclair256f1112022-07-22 16:05:06 +0000185
dan sinclair6cc183c2023-03-02 21:28:45 +0000186const f_height = 12.3999996185302734375f;
dan sinclair256f1112022-07-22 16:05:06 +0000187
Zhaoming Jiang6af073c2023-03-20 10:32:45 +0000188const h_width : f16 = 9.3984375h;
189
190const h_height = 3.3984375h;
191
dan sinclair256f1112022-07-22 16:05:06 +0000192const b_width : bool = true;
193
194const b_height = false;
195
Ben Clayton634a2432022-07-28 10:22:17 +0000196const o_width = 13i;
dan sinclair256f1112022-07-22 16:05:06 +0000197
198@vertex
199fn main() -> @builtin(position) vec4<f32> {
200 return vec4<f32>();
201}
202)";
203
204 SubstituteOverride::Config cfg;
Ben Clayton634a2432022-07-28 10:22:17 +0000205 cfg.map.insert({OverrideId{0}, 42.0});
206 cfg.map.insert({OverrideId{10}, 11.0});
207 cfg.map.insert({OverrideId{1}, 22.3});
208 cfg.map.insert({OverrideId{9}, 12.4});
209 cfg.map.insert({OverrideId{2}, 9.4});
210 cfg.map.insert({OverrideId{8}, 3.4});
211 cfg.map.insert({OverrideId{3}, 1.0});
212 cfg.map.insert({OverrideId{7}, 0.0});
213 cfg.map.insert({OverrideId{5}, 13});
dan sinclair256f1112022-07-22 16:05:06 +0000214
215 DataMap data;
216 data.Add<SubstituteOverride::Config>(cfg);
217 auto got = Run<SubstituteOverride>(src, data);
218
219 EXPECT_EQ(expect, str(got));
220}
221
222TEST_F(SubstituteOverrideTest, Identifier_Expression) {
223 auto* src = R"(
224override i_height = ~2i;
225
226@vertex
227fn main() -> @builtin(position) vec4<f32> {
228 return vec4<f32>();
229}
230)";
231
232 auto* expect = R"(
233const i_height = 11i;
234
235@vertex
236fn main() -> @builtin(position) vec4<f32> {
237 return vec4<f32>();
238}
239)";
240
241 SubstituteOverride::Config cfg;
Ben Clayton634a2432022-07-28 10:22:17 +0000242 cfg.map.insert({OverrideId{0}, 11.0});
dan sinclair256f1112022-07-22 16:05:06 +0000243
244 DataMap data;
245 data.Add<SubstituteOverride::Config>(cfg);
246 auto got = Run<SubstituteOverride>(src, data);
247
248 EXPECT_EQ(expect, str(got));
249}
250
Ben Claytonba384f02022-10-12 19:18:25 +0000251TEST_F(SubstituteOverrideTest, IndexMaterialization) {
252 auto* src = R"(
253override O = 0; // Try switching to 'const'
254
255fn f() {
256 const smaller_than_any_f32 = 1e-50;
257 const large_float = 1e27;
258 // When O is an override, the outer index value is not constant, so the
259 // value is not calculated at shader-creation time, and does not error.
260 //
261 // When O is a const, and 'smaller_than_any_f32' *is not* materialized, the
262 // outer index value will evaluate to 10000, resulting in an out-of-bounds
263 // error.
264 //
265 // When O is a const, and 'smaller_than_any_f32' *is* materialized, the
266 // materialization of 'smaller_than_any_f32' to f32 will evaluate to zero,
267 // and so the outer index value will be zero, and we get no error.
268 _ = vec2(0)[i32(vec2(smaller_than_any_f32)[O]*large_float*large_float)];
269}
270)";
271
272 auto* expect = R"(
273const O = 0i;
274
275fn f() {
276 const smaller_than_any_f32 = 1e-50;
277 const large_float = 1000000000000000013287555072.0;
278 _ = _tint_materialize(vec2(0))[i32(((_tint_materialize(vec2(smaller_than_any_f32))[O] * large_float) * large_float))];
279}
280)";
281
282 SubstituteOverride::Config cfg;
283 cfg.map.insert({OverrideId{0}, 0.0});
284
285 DataMap data;
286 data.Add<SubstituteOverride::Config>(cfg);
287 auto got = Run<SubstituteOverride>(src, data);
288
289 EXPECT_EQ(expect, str(got));
290}
291
dan sinclair256f1112022-07-22 16:05:06 +0000292} // namespace
293} // namespace tint::transform