blob: d2057933bdd0a324219827335ad2d9c40dc4f3ab [file] [log] [blame]
Ethan Nicholas95046142021-01-07 10:57:27 -05001/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/GrDirectContextPriv.h"
9#include "src/gpu/GrGpu.h"
10#include "src/sksl/SkSLIRGenerator.h"
11#include "src/sksl/dsl/DSL.h"
12#include "src/sksl/dsl/priv/DSLWriter.h"
13
14#include "tests/Test.h"
15
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050016#include <limits>
17
Ethan Nicholas95046142021-01-07 10:57:27 -050018using namespace SkSL::dsl;
19
20class AutoDSLContext {
21public:
22 AutoDSLContext(GrGpu* gpu) {
23 Start(gpu->shaderCompiler());
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050024 DSLWriter::Instance().fMangle = false;
Ethan Nicholas95046142021-01-07 10:57:27 -050025 }
26
27 ~AutoDSLContext() {
28 End();
29 }
30};
31
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050032class ExpectError : public ErrorHandler {
33public:
34 ExpectError(skiatest::Reporter* reporter, const char* msg)
35 : fMsg(msg)
36 , fReporter(reporter) {
37 SetErrorHandler(this);
38 }
39
40 ~ExpectError() override {
41 REPORTER_ASSERT(fReporter, !fMsg);
42 SetErrorHandler(nullptr);
43 }
44
45 void handleError(const char* msg) override {
46 REPORTER_ASSERT(fReporter, !strcmp(msg, fMsg),
47 "Error mismatch: expected:\n%sbut received:\n%s", fMsg, msg);
48 fMsg = nullptr;
49 }
50
51private:
52 const char* fMsg;
53 skiatest::Reporter* fReporter;
54};
55
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -050056static bool whitespace_insensitive_compare(const char* a, const char* b) {
57 for (;;) {
58 while (isspace(*a)) {
59 ++a;
60 }
61 while (isspace(*b)) {
62 ++b;
63 }
64 if (*a != *b) {
65 return false;
66 }
67 if (*a == 0) {
68 return true;
69 }
70 ++a;
71 ++b;
72 }
73}
74
75static bool whitespace_insensitive_compare(DSLStatement& stmt, const char* description) {
76 return whitespace_insensitive_compare(stmt.release()->description().c_str(), description);
77}
78
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050079DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStartup, r, ctxInfo) {
Ethan Nicholas95046142021-01-07 10:57:27 -050080 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
81 Expression e1 = 1;
82 REPORTER_ASSERT(r, e1.release()->description() == "1");
83 Expression e2 = 1.0;
84 REPORTER_ASSERT(r, e2.release()->description() == "1.0");
85 Expression e3 = true;
86 REPORTER_ASSERT(r, e3.release()->description() == "true");
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050087 Var a(kInt, "a");
88 Expression e4 = a;
89 REPORTER_ASSERT(r, e4.release()->description() == "a");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -050090
91 REPORTER_ASSERT(r, whitespace_insensitive_compare("", ""));
92 REPORTER_ASSERT(r, !whitespace_insensitive_compare("", "a"));
93 REPORTER_ASSERT(r, !whitespace_insensitive_compare("a", ""));
94 REPORTER_ASSERT(r, whitespace_insensitive_compare("a", "a"));
95 REPORTER_ASSERT(r, whitespace_insensitive_compare("abc", "abc"));
96 REPORTER_ASSERT(r, whitespace_insensitive_compare("abc", " abc "));
97 REPORTER_ASSERT(r, whitespace_insensitive_compare("a b c ", "\n\n\nabc"));
98 REPORTER_ASSERT(r, !whitespace_insensitive_compare("a b c d", "\n\n\nabc"));
Ethan Nicholas95046142021-01-07 10:57:27 -050099}
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500100
101DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFloat, r, ctxInfo) {
102 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
103 Expression e1 = Float(std::numeric_limits<float>::max());
104 REPORTER_ASSERT(r, atof(e1.release()->description().c_str()) ==
105 std::numeric_limits<float>::max());
106
107 Expression e2 = Float(std::numeric_limits<float>::min());
108 REPORTER_ASSERT(r, atof(e2.release()->description().c_str()) ==
109 std::numeric_limits<float>::min());
110
111 Expression e3 = Float2(0);
112 REPORTER_ASSERT(r, e3.release()->description() == "float2(0.0)");
113
114 Expression e4 = Float2(-0.5, 1);
115 REPORTER_ASSERT(r, e4.release()->description() == "float2(-0.5, 1.0)");
116
117 Expression e5 = Float3(0.75);
118 REPORTER_ASSERT(r, e5.release()->description() == "float3(0.75)");
119
120 Expression e6 = Float3(Float2(0, 1), -2);
121 REPORTER_ASSERT(r, e6.release()->description() == "float3(float2(0.0, 1.0), -2.0)");
122
123 Expression e7 = Float3(0, 1, 2);
124 REPORTER_ASSERT(r, e7.release()->description() == "float3(0.0, 1.0, 2.0)");
125
126 Expression e8 = Float4(0);
127 REPORTER_ASSERT(r, e8.release()->description() == "float4(0.0)");
128
129 Expression e9 = Float4(Float2(0, 1), Float2(2, 3));
130 REPORTER_ASSERT(r, e9.release()->description() == "float4(float2(0.0, 1.0), float2(2.0, 3.0))");
131
132 Expression e10 = Float4(0, 1, Float2(2, 3));
133 REPORTER_ASSERT(r, e10.release()->description() == "float4(0.0, 1.0, float2(2.0, 3.0))");
134
135 Expression e11 = Float4(0, 1, 2, 3);
136 REPORTER_ASSERT(r, e11.release()->description() == "float4(0.0, 1.0, 2.0, 3.0)");
137
138 {
139 ExpectError error(r, "error: floating point value is infinite\n");
140 Float(std::numeric_limits<float>::infinity()).release();
141 }
142
143 {
144 ExpectError error(r, "error: floating point value is NaN\n");
145 Float(std::numeric_limits<float>::quiet_NaN()).release();
146 }
147
148 {
149 ExpectError error(r, "error: invalid arguments to 'float2' constructor (expected 2 scalars,"
150 " but found 4)\n");
151 Float2(Float4(1)).release();
152 }
153
154 {
155 ExpectError error(r, "error: invalid arguments to 'float4' constructor (expected 4 scalars,"
156 " but found 3)\n");
157 Float4(Float3(1)).release();
158 }
159}
160
161DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLHalf, r, ctxInfo) {
162 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
163 Expression e1 = Half(std::numeric_limits<float>::max());
164 REPORTER_ASSERT(r, atof(e1.release()->description().c_str()) ==
165 std::numeric_limits<float>::max());
166
167 Expression e2 = Half(std::numeric_limits<float>::min());
168 REPORTER_ASSERT(r, atof(e2.release()->description().c_str()) ==
169 std::numeric_limits<float>::min());
170
171 Expression e3 = Half2(0);
172 REPORTER_ASSERT(r, e3.release()->description() == "half2(0.0)");
173
174 Expression e4 = Half2(-0.5, 1);
175 REPORTER_ASSERT(r, e4.release()->description() == "half2(-0.5, 1.0)");
176
177 Expression e5 = Half3(0.75);
178 REPORTER_ASSERT(r, e5.release()->description() == "half3(0.75)");
179
180 Expression e6 = Half3(Half2(0, 1), -2);
181 REPORTER_ASSERT(r, e6.release()->description() == "half3(half2(0.0, 1.0), -2.0)");
182
183 Expression e7 = Half3(0, 1, 2);
184 REPORTER_ASSERT(r, e7.release()->description() == "half3(0.0, 1.0, 2.0)");
185
186 Expression e8 = Half4(0);
187 REPORTER_ASSERT(r, e8.release()->description() == "half4(0.0)");
188
189 Expression e9 = Half4(Half2(0, 1), Half2(2, 3));
190 REPORTER_ASSERT(r, e9.release()->description() == "half4(half2(0.0, 1.0), half2(2.0, 3.0))");
191
192 Expression e10 = Half4(0, 1, Half2(2, 3));
193 REPORTER_ASSERT(r, e10.release()->description() == "half4(0.0, 1.0, half2(2.0, 3.0))");
194
195 Expression e11 = Half4(0, 1, 2, 3);
196 REPORTER_ASSERT(r, e11.release()->description() == "half4(0.0, 1.0, 2.0, 3.0)");
197
198 {
199 ExpectError error(r, "error: floating point value is infinite\n");
200 Half(std::numeric_limits<float>::infinity()).release();
201 }
202
203 {
204 ExpectError error(r, "error: floating point value is NaN\n");
205 Half(std::numeric_limits<float>::quiet_NaN()).release();
206 }
207
208 {
209 ExpectError error(r, "error: invalid arguments to 'half2' constructor (expected 2 scalars,"
210 " but found 4)\n");
211 Half2(Half4(1)).release();
212 }
213
214 {
215 ExpectError error(r, "error: invalid arguments to 'half4' constructor (expected 4 scalars,"
216 " but found 3)\n");
217 Half4(Half3(1)).release();
218 }
219}
220
221DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInt, r, ctxInfo) {
222 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
223 Expression e1 = Int(std::numeric_limits<int32_t>::max());
224 REPORTER_ASSERT(r, e1.release()->description() == "2147483647");
225
226 Expression e2 = Int2(std::numeric_limits<int32_t>::min());
227 REPORTER_ASSERT(r, e2.release()->description() == "int2(-2147483648)");
228
229 Expression e3 = Int2(0, 1);
230 REPORTER_ASSERT(r, e3.release()->description() == "int2(0, 1)");
231
232 Expression e4 = Int3(0);
233 REPORTER_ASSERT(r, e4.release()->description() == "int3(0)");
234
235 Expression e5 = Int3(Int2(0, 1), -2);
236 REPORTER_ASSERT(r, e5.release()->description() == "int3(int2(0, 1), -2)");
237
238 Expression e6 = Int3(0, 1, 2);
239 REPORTER_ASSERT(r, e6.release()->description() == "int3(0, 1, 2)");
240
241 Expression e7 = Int4(0);
242 REPORTER_ASSERT(r, e7.release()->description() == "int4(0)");
243
244 Expression e8 = Int4(Int2(0, 1), Int2(2, 3));
245 REPORTER_ASSERT(r, e8.release()->description() == "int4(int2(0, 1), int2(2, 3))");
246
247 Expression e9 = Int4(0, 1, Int2(2, 3));
248 REPORTER_ASSERT(r, e9.release()->description() == "int4(0, 1, int2(2, 3))");
249
250 Expression e10 = Int4(0, 1, 2, 3);
251 REPORTER_ASSERT(r, e10.release()->description() == "int4(0, 1, 2, 3)");
252
253 {
254 ExpectError error(r, "error: invalid arguments to 'int2' constructor (expected 2 scalars,"
255 " but found 4)\n");
256 Int2(Int4(1)).release();
257 }
258
259 {
260 ExpectError error(r, "error: invalid arguments to 'int4' constructor (expected 4 scalars,"
261 " but found 3)\n");
262 Int4(Int3(1)).release();
263 }
264}
265
266DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShort, r, ctxInfo) {
267 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
268 Expression e1 = Short(std::numeric_limits<int16_t>::max());
269 REPORTER_ASSERT(r, e1.release()->description() == "32767");
270
271 Expression e2 = Short2(std::numeric_limits<int16_t>::min());
272 REPORTER_ASSERT(r, e2.release()->description() == "short2(-32768)");
273
274 Expression e3 = Short2(0, 1);
275 REPORTER_ASSERT(r, e3.release()->description() == "short2(0, 1)");
276
277 Expression e4 = Short3(0);
278 REPORTER_ASSERT(r, e4.release()->description() == "short3(0)");
279
280 Expression e5 = Short3(Short2(0, 1), -2);
281 REPORTER_ASSERT(r, e5.release()->description() == "short3(short2(0, 1), -2)");
282
283 Expression e6 = Short3(0, 1, 2);
284 REPORTER_ASSERT(r, e6.release()->description() == "short3(0, 1, 2)");
285
286 Expression e7 = Short4(0);
287 REPORTER_ASSERT(r, e7.release()->description() == "short4(0)");
288
289 Expression e8 = Short4(Short2(0, 1), Short2(2, 3));
290 REPORTER_ASSERT(r, e8.release()->description() == "short4(short2(0, 1), short2(2, 3))");
291
292 Expression e9 = Short4(0, 1, Short2(2, 3));
293 REPORTER_ASSERT(r, e9.release()->description() == "short4(0, 1, short2(2, 3))");
294
295 Expression e10 = Short4(0, 1, 2, 3);
296 REPORTER_ASSERT(r, e10.release()->description() == "short4(0, 1, 2, 3)");
297
298 {
299 ExpectError error(r, "error: invalid arguments to 'short2' constructor (expected 2 scalars,"
300 " but found 4)\n");
301 Short2(Short4(1)).release();
302 }
303
304 {
305 ExpectError error(r, "error: invalid arguments to 'short4' constructor (expected 4 scalars,"
306 " but found 3)\n");
307 Short4(Short3(1)).release();
308 }
309}
310
311DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBool, r, ctxInfo) {
312 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
313 Expression e1 = Bool2(false);
314 REPORTER_ASSERT(r, e1.release()->description() == "bool2(false)");
315
316 Expression e2 = Bool2(false, true);
317 REPORTER_ASSERT(r, e2.release()->description() == "bool2(false, true)");
318
319 Expression e3 = Bool3(false);
320 REPORTER_ASSERT(r, e3.release()->description() == "bool3(false)");
321
322 Expression e4 = Bool3(Bool2(false, true), false);
323 REPORTER_ASSERT(r, e4.release()->description() == "bool3(bool2(false, true), false)");
324
325 Expression e5 = Bool3(false, true, false);
326 REPORTER_ASSERT(r, e5.release()->description() == "bool3(false, true, false)");
327
328 Expression e6 = Bool4(false);
329 REPORTER_ASSERT(r, e6.release()->description() == "bool4(false)");
330
331 Expression e7 = Bool4(Bool2(false, true), Bool2(false, true));
332 REPORTER_ASSERT(r, e7.release()->description() == "bool4(bool2(false, true), "
333 "bool2(false, true))");
334
335 Expression e8 = Bool4(false, true, Bool2(false, true));
336 REPORTER_ASSERT(r, e8.release()->description() == "bool4(false, true, bool2(false, true))");
337
338 Expression e9 = Bool4(false, true, false, true);
339 REPORTER_ASSERT(r, e9.release()->description() == "bool4(false, true, false, true)");
340
341 {
342 ExpectError error(r, "error: invalid arguments to 'bool2' constructor (expected 2 scalars,"
343 " but found 4)\n");
344 Bool2(Bool4(true)).release();
345 }
346
347 {
348 ExpectError error(r, "error: invalid arguments to 'bool4' constructor (expected 4 scalars,"
349 " but found 3)\n");
350 Bool4(Bool3(true)).release();
351 }
352}
Ethan Nicholas92969f22021-01-13 10:38:59 -0500353
354DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLPlus, r, ctxInfo) {
355 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
356 Var a(kFloat, "a"), b(kFloat, "b");
357 Expression e1 = a + b;
358 REPORTER_ASSERT(r, e1.release()->description() == "(a + b)");
359
360 Expression e2 = a + 1;
361 REPORTER_ASSERT(r, e2.release()->description() == "(a + 1.0)");
362
363 Expression e3 = 0.5 + a + -99;
364 REPORTER_ASSERT(r, e3.release()->description() == "((0.5 + a) + -99.0)");
365
366 Expression e4 = a += b + 1;
367 REPORTER_ASSERT(r, e4.release()->description() == "(a += (b + 1.0))");
368
369 {
370 ExpectError error(r, "error: type mismatch: '+' cannot operate on 'bool2', 'float'\n");
371 (Bool2(true) + a).release();
372 }
373
374 {
375 ExpectError error(r, "error: type mismatch: '+=' cannot operate on 'float', 'bool2'\n");
376 (a += Bool2(true)).release();
377 }
378
379 {
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500380 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500381 (1.0 += a).release();
382 }
383}
384
385DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMinus, r, ctxInfo) {
386 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
387 Var a(kInt, "a"), b(kInt, "b");
388 Expression e1 = a - b;
389 REPORTER_ASSERT(r, e1.release()->description() == "(a - b)");
390
391 Expression e2 = a - 1;
392 REPORTER_ASSERT(r, e2.release()->description() == "(a - 1)");
393
394 Expression e3 = 2 - a - b;
395 REPORTER_ASSERT(r, e3.release()->description() == "((2 - a) - b)");
396
397 Expression e4 = a -= b + 1;
398 REPORTER_ASSERT(r, e4.release()->description() == "(a -= (b + 1))");
399
400 {
401 ExpectError error(r, "error: type mismatch: '-' cannot operate on 'bool2', 'int'\n");
402 (Bool2(true) - a).release();
403 }
404
405 {
406 ExpectError error(r, "error: type mismatch: '-=' cannot operate on 'int', 'bool2'\n");
407 (a -= Bool2(true)).release();
408 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500409
410 {
411 ExpectError error(r, "error: cannot assign to this expression\n");
412 (1.0 -= a).release();
413 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500414}
415
416DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMultiply, r, ctxInfo) {
417 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
418 Var a(kFloat, "a"), b(kFloat, "b");
419 Expression e1 = a * b;
420 REPORTER_ASSERT(r, e1.release()->description() == "(a * b)");
421
422 Expression e2 = a * 1;
423 REPORTER_ASSERT(r, e2.release()->description() == "(a * 1.0)");
424
425 Expression e3 = 0.5 * a * -99;
426 REPORTER_ASSERT(r, e3.release()->description() == "((0.5 * a) * -99.0)");
427
428 Expression e4 = a *= b + 1;
429 REPORTER_ASSERT(r, e4.release()->description() == "(a *= (b + 1.0))");
430
431 {
432 ExpectError error(r, "error: type mismatch: '*' cannot operate on 'bool2', 'float'\n");
433 (Bool2(true) * a).release();
434 }
435
436 {
437 ExpectError error(r, "error: type mismatch: '*=' cannot operate on 'float', 'bool2'\n");
438 (a *= Bool2(true)).release();
439 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500440
441 {
442 ExpectError error(r, "error: cannot assign to this expression\n");
443 (1.0 *= a).release();
444 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500445}
446
447DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDivide, r, ctxInfo) {
448 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
449 Var a(kFloat, "a"), b(kFloat, "b");
450 Expression e1 = a / b;
451 REPORTER_ASSERT(r, e1.release()->description() == "(a / b)");
452
453 Expression e2 = a / 1;
454 REPORTER_ASSERT(r, e2.release()->description() == "(a / 1.0)");
455
456 Expression e3 = 0.5 / a / -99;
457 REPORTER_ASSERT(r, e3.release()->description() == "((0.5 / a) / -99.0)");
458
459 Expression e4 = b / (a - 1);
460 REPORTER_ASSERT(r, e4.release()->description() == "(b / (a - 1.0))");
461
462 Expression e5 = a /= b + 1;
463 REPORTER_ASSERT(r, e5.release()->description() == "(a /= (b + 1.0))");
464
465 {
466 ExpectError error(r, "error: type mismatch: '/' cannot operate on 'bool2', 'float'\n");
467 (Bool2(true) / a).release();
468 }
469
470 {
471 ExpectError error(r, "error: type mismatch: '/=' cannot operate on 'float', 'bool2'\n");
472 (a /= Bool2(true)).release();
473 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500474
475 {
476 ExpectError error(r, "error: cannot assign to this expression\n");
477 (1.0 /= a).release();
478 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500479}
480
481DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMod, r, ctxInfo) {
482 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
483 Var a(kInt, "a"), b(kInt, "b");
484 Expression e1 = a % b;
485 REPORTER_ASSERT(r, e1.release()->description() == "(a % b)");
486
487 Expression e2 = a % 2;
488 REPORTER_ASSERT(r, e2.release()->description() == "(a % 2)");
489
490 Expression e3 = 10 % a % -99;
491 REPORTER_ASSERT(r, e3.release()->description() == "((10 % a) % -99)");
492
493 Expression e4 = a %= b + 1;
494 REPORTER_ASSERT(r, e4.release()->description() == "(a %= (b + 1))");
495
496 {
497 ExpectError error(r, "error: type mismatch: '%' cannot operate on 'bool2', 'int'\n");
498 (Bool2(true) % a).release();
499 }
500
501 {
502 ExpectError error(r, "error: type mismatch: '%=' cannot operate on 'int', 'bool2'\n");
503 (a %= Bool2(true)).release();
504 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500505
506 {
507 ExpectError error(r, "error: cannot assign to this expression\n");
508 (1 %= a).release();
509 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500510}
511
512DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShl, r, ctxInfo) {
513 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
514 Var a(kInt, "a"), b(kInt, "b");
515 Expression e1 = a << b;
516 REPORTER_ASSERT(r, e1.release()->description() == "(a << b)");
517
518 Expression e2 = a << 1;
519 REPORTER_ASSERT(r, e2.release()->description() == "(a << 1)");
520
521 Expression e3 = 1 << a << 2;
522 REPORTER_ASSERT(r, e3.release()->description() == "((1 << a) << 2)");
523
524 Expression e4 = a <<= b + 1;
525 REPORTER_ASSERT(r, e4.release()->description() == "(a <<= (b + 1))");
526
527 {
528 ExpectError error(r, "error: type mismatch: '<<' cannot operate on 'bool2', 'int'\n");
529 (Bool2(true) << a).release();
530 }
531
532 {
533 ExpectError error(r, "error: type mismatch: '<<=' cannot operate on 'int', 'bool2'\n");
534 (a <<= Bool2(true)).release();
535 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500536
537 {
538 ExpectError error(r, "error: cannot assign to this expression\n");
539 (1 <<= a).release();
540 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500541}
542
543DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShr, r, ctxInfo) {
544 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
545 Var a(kInt, "a"), b(kInt, "b");
546 Expression e1 = a >> b;
547 REPORTER_ASSERT(r, e1.release()->description() == "(a >> b)");
548
549 Expression e2 = a >> 1;
550 REPORTER_ASSERT(r, e2.release()->description() == "(a >> 1)");
551
552 Expression e3 = 1 >> a >> 2;
553 REPORTER_ASSERT(r, e3.release()->description() == "((1 >> a) >> 2)");
554
555 Expression e4 = a >>= b + 1;
556 REPORTER_ASSERT(r, e4.release()->description() == "(a >>= (b + 1))");
557
558 {
559 ExpectError error(r, "error: type mismatch: '>>' cannot operate on 'bool2', 'int'\n");
560 (Bool2(true) >> a).release();
561 }
562
563 {
564 ExpectError error(r, "error: type mismatch: '>>=' cannot operate on 'int', 'bool2'\n");
565 (a >>= Bool2(true)).release();
566 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500567
568 {
569 ExpectError error(r, "error: cannot assign to this expression\n");
570 (1 >>= a).release();
571 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500572}
573
574DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseAnd, r, ctxInfo) {
575 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
576 Var a(kInt, "a"), b(kInt, "b");
577 Expression e1 = a & b;
578 REPORTER_ASSERT(r, e1.release()->description() == "(a & b)");
579
580 Expression e2 = a & 1;
581 REPORTER_ASSERT(r, e2.release()->description() == "(a & 1)");
582
583 Expression e3 = 1 & a & 2;
584 REPORTER_ASSERT(r, e3.release()->description() == "((1 & a) & 2)");
585
586 Expression e4 = a &= b + 1;
587 REPORTER_ASSERT(r, e4.release()->description() == "(a &= (b + 1))");
588
589 {
590 ExpectError error(r, "error: type mismatch: '&' cannot operate on 'bool2', 'int'\n");
591 (Bool2(true) & a).release();
592 }
593
594 {
595 ExpectError error(r, "error: type mismatch: '&=' cannot operate on 'int', 'bool2'\n");
596 (a &= Bool2(true)).release();
597 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500598
599 {
600 ExpectError error(r, "error: cannot assign to this expression\n");
601 (1 &= a).release();
602 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500603}
604
605DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseOr, r, ctxInfo) {
606 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
607 Var a(kInt, "a"), b(kInt, "b");
608 Expression e1 = a | b;
609 REPORTER_ASSERT(r, e1.release()->description() == "(a | b)");
610
611 Expression e2 = a | 1;
612 REPORTER_ASSERT(r, e2.release()->description() == "(a | 1)");
613
614 Expression e3 = 1 | a | 2;
615 REPORTER_ASSERT(r, e3.release()->description() == "((1 | a) | 2)");
616
617 Expression e4 = a |= b + 1;
618 REPORTER_ASSERT(r, e4.release()->description() == "(a |= (b + 1))");
619
620 {
621 ExpectError error(r, "error: type mismatch: '|' cannot operate on 'bool2', 'int'\n");
622 (Bool2(true) | a).release();
623 }
624
625 {
626 ExpectError error(r, "error: type mismatch: '|=' cannot operate on 'int', 'bool2'\n");
627 (a |= Bool2(true)).release();
628 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500629
630 {
631 ExpectError error(r, "error: cannot assign to this expression\n");
632 (1 |= a).release();
633 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500634}
635
636DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseXor, r, ctxInfo) {
637 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
638 Var a(kInt, "a"), b(kInt, "b");
639 Expression e1 = a ^ b;
640 REPORTER_ASSERT(r, e1.release()->description() == "(a ^ b)");
641
642 Expression e2 = a ^ 1;
643 REPORTER_ASSERT(r, e2.release()->description() == "(a ^ 1)");
644
645 Expression e3 = 1 ^ a ^ 2;
646 REPORTER_ASSERT(r, e3.release()->description() == "((1 ^ a) ^ 2)");
647
648 Expression e4 = a ^= b + 1;
649 REPORTER_ASSERT(r, e4.release()->description() == "(a ^= (b + 1))");
650
651 {
652 ExpectError error(r, "error: type mismatch: '^' cannot operate on 'bool2', 'int'\n");
653 (Bool2(true) ^ a).release();
654 }
655
656 {
657 ExpectError error(r, "error: type mismatch: '^=' cannot operate on 'int', 'bool2'\n");
658 (a ^= Bool2(true)).release();
659 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500660
661 {
662 ExpectError error(r, "error: cannot assign to this expression\n");
663 (1 ^= a).release();
664 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500665}
666
667DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalAnd, r, ctxInfo) {
668 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
669 Var a(kBool, "a"), b(kBool, "b");
670 Expression e1 = a && b;
671 REPORTER_ASSERT(r, e1.release()->description() == "(a && b)");
672
673 Expression e2 = a && true && b;
674 REPORTER_ASSERT(r, e2.release()->description() == "(a && b)");
675
676 Expression e3 = a && false && b;
677 REPORTER_ASSERT(r, e3.release()->description() == "false");
678
679 {
680 ExpectError error(r, "error: type mismatch: '&&' cannot operate on 'bool', 'int'\n");
681 (a && 5).release();
682 }
683}
684
685DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalOr, r, ctxInfo) {
686 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
687 Var a(kBool, "a"), b(kBool, "b");
688 Expression e1 = a || b;
689 REPORTER_ASSERT(r, e1.release()->description() == "(a || b)");
690
691 Expression e2 = a || true || b;
692 REPORTER_ASSERT(r, e2.release()->description() == "true");
693
694 Expression e3 = a || false || b;
695 REPORTER_ASSERT(r, e3.release()->description() == "(a || b)");
696
697 {
698 ExpectError error(r, "error: type mismatch: '||' cannot operate on 'bool', 'int'\n");
699 (a || 5).release();
700 }
701}
702
703DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLComma, r, ctxInfo) {
704 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
705 Var a(kInt, "a"), b(kInt, "b");
706 Expression e1 = (a += b, b);
707 REPORTER_ASSERT(r, e1.release()->description() == "((a += b) , b)");
708
709 Expression e2 = (a += b, b += b, Int2(a));
710 REPORTER_ASSERT(r, e2.release()->description() == "(((a += b) , (b += b)) , int2(a))");
711}
712
713DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLEqual, r, ctxInfo) {
714 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
715 Var a(kInt, "a"), b(kInt, "b");
716 Expression e1 = a == b;
717 REPORTER_ASSERT(r, e1.release()->description() == "(a == b)");
718
719 Expression e2 = a == 5;
720 REPORTER_ASSERT(r, e2.release()->description() == "(a == 5)");
721
722 {
723 ExpectError error(r, "error: type mismatch: '==' cannot operate on 'int', 'bool2'\n");
724 (a == Bool2(true)).release();
725 }
726}
727
728DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLNotEqual, r, ctxInfo) {
729 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
730 Var a(kInt, "a"), b(kInt, "b");
731 Expression e1 = a != b;
732 REPORTER_ASSERT(r, e1.release()->description() == "(a != b)");
733
734 Expression e2 = a != 5;
735 REPORTER_ASSERT(r, e2.release()->description() == "(a != 5)");
736
737 {
738 ExpectError error(r, "error: type mismatch: '!=' cannot operate on 'int', 'bool2'\n");
739 (a != Bool2(true)).release();
740 }
741}
742
743DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLGreaterThan, r, ctxInfo) {
744 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
745 Var a(kInt, "a"), b(kInt, "b");
746 Expression e1 = a > b;
747 REPORTER_ASSERT(r, e1.release()->description() == "(a > b)");
748
749 Expression e2 = a > 5;
750 REPORTER_ASSERT(r, e2.release()->description() == "(a > 5)");
751
752 {
753 ExpectError error(r, "error: type mismatch: '>' cannot operate on 'int', 'bool2'\n");
754 (a > Bool2(true)).release();
755 }
756}
757
758DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLGreaterThanOrEqual, r, ctxInfo) {
759 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
760 Var a(kInt, "a"), b(kInt, "b");
761 Expression e1 = a >= b;
762 REPORTER_ASSERT(r, e1.release()->description() == "(a >= b)");
763
764 Expression e2 = a >= 5;
765 REPORTER_ASSERT(r, e2.release()->description() == "(a >= 5)");
766
767 {
768 ExpectError error(r, "error: type mismatch: '>=' cannot operate on 'int', 'bool2'\n");
769 (a >= Bool2(true)).release();
770 }
771}
772
773DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLessThan, r, ctxInfo) {
774 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
775 Var a(kInt, "a"), b(kInt, "b");
776 Expression e1 = a < b;
777 REPORTER_ASSERT(r, e1.release()->description() == "(a < b)");
778
779 Expression e2 = a < 5;
780 REPORTER_ASSERT(r, e2.release()->description() == "(a < 5)");
781
782 {
783 ExpectError error(r, "error: type mismatch: '<' cannot operate on 'int', 'bool2'\n");
784 (a < Bool2(true)).release();
785 }
786}
787
788DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLessThanOrEqual, r, ctxInfo) {
789 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
790 Var a(kInt, "a"), b(kInt, "b");
791 Expression e1 = a <= b;
792 REPORTER_ASSERT(r, e1.release()->description() == "(a <= b)");
793
794 Expression e2 = a <= 5;
795 REPORTER_ASSERT(r, e2.release()->description() == "(a <= 5)");
796
797 {
798 ExpectError error(r, "error: type mismatch: '<=' cannot operate on 'int', 'bool2'\n");
799 (a <= Bool2(true)).release();
800 }
801}
802
803DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalNot, r, ctxInfo) {
804 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
805 Var a(kInt, "a"), b(kInt, "b");
806 Expression e1 = !(a <= b);
807 REPORTER_ASSERT(r, e1.release()->description() == "!(a <= b)");
808
809 {
810 ExpectError error(r, "error: '!' cannot operate on 'int'\n");
811 (!a).release();
812 }
813}
814
815DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseNot, r, ctxInfo) {
816 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
817 Var a(kInt, "a"), b(kBool, "b");
818 Expression e1 = ~a;
819 REPORTER_ASSERT(r, e1.release()->description() == "~a");
820
821 {
822 ExpectError error(r, "error: '~' cannot operate on 'bool'\n");
823 (~b).release();
824 }
825}
826
827DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIncrement, r, ctxInfo) {
828 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
829 Var a(kInt, "a"), b(kBool, "b");
830 Expression e1 = ++a;
831 REPORTER_ASSERT(r, e1.release()->description() == "++a");
832
833 Expression e2 = a++;
834 REPORTER_ASSERT(r, e2.release()->description() == "a++");
835
836 {
837 ExpectError error(r, "error: '++' cannot operate on 'bool'\n");
838 (++b).release();
839 }
840
841 {
842 ExpectError error(r, "error: '++' cannot operate on 'bool'\n");
843 (b++).release();
844 }
845
846 {
847 ExpectError error(r, "error: cannot assign to this expression\n");
848 (++(a + 1)).release();
849 }
850
851 {
852 ExpectError error(r, "error: cannot assign to this expression\n");
853 ((a + 1)++).release();
854 }
855}
856
857DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDecrement, r, ctxInfo) {
858 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
859 Var a(kInt, "a"), b(kBool, "b");
860 Expression e1 = --a;
861 REPORTER_ASSERT(r, e1.release()->description() == "--a");
862
863 Expression e2 = a--;
864 REPORTER_ASSERT(r, e2.release()->description() == "a--");
865
866 {
867 ExpectError error(r, "error: '--' cannot operate on 'bool'\n");
868 (--b).release();
869 }
870
871 {
872 ExpectError error(r, "error: '--' cannot operate on 'bool'\n");
873 (b--).release();
874 }
875
876 {
877 ExpectError error(r, "error: cannot assign to this expression\n");
878 (--(a + 1)).release();
879 }
880
881 {
882 ExpectError error(r, "error: cannot assign to this expression\n");
883 ((a + 1)--).release();
884 }
885}
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500886
887DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBlock, r, ctxInfo) {
888 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
889 Statement x = Block();
890 REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "{ }"));
891 Var a(kInt, "a"), b(kInt, "b");
892 Statement y = Block(Declare(a, 1), Declare(b, 2), a = b);
893 REPORTER_ASSERT(r, whitespace_insensitive_compare(y, "{ int a = 1; int b = 2; (a = b); }"));
894}
895
896DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclare, r, ctxInfo) {
897 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
898 Var a(kHalf4, "a"), b(kHalf4, "b");
899 Statement x = Declare(a);
900 REPORTER_ASSERT(r, x.release()->description() == "half4 a;");
901 Statement y = Declare(b, Half4(1));
902 REPORTER_ASSERT(r, y.release()->description() == "half4 b = half4(1.0);");
903
904 {
905 Var c(kHalf4, "c");
906 ExpectError error(r, "error: expected 'half4', but found 'int'\n");
907 Declare(c, 1).release();
908 }
909}
910
911DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDo, r, ctxInfo) {
912 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
913 Statement x = Do(Block(), true);
914 REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "do {} while (true);"));
915
916 Var a(kFloat, "a"), b(kFloat, "b");
917 Statement y = Do(Block(a++, --b), a != b);
918 REPORTER_ASSERT(r, whitespace_insensitive_compare(y, "do { a++; --b; } while ((a != b));"));
919
920 {
921 ExpectError error(r, "error: expected 'bool', but found 'int'\n");
922 Do(Block(), 7).release();
923 }
924}
925
926DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFor, r, ctxInfo) {
927 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
928 Statement x = For(Statement(), Expression(), Expression(), Block());
929 REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "for (;;) {}"));
930
931 Var i(kInt, "i");
932 Statement y = For(Declare(i, 0), i < 10, ++i, i += 5);
933 REPORTER_ASSERT(r, whitespace_insensitive_compare(y,
934 "for (int i = 0; (i < 10); ++i) (i += 5);"));
935
936 {
937 ExpectError error(r, "error: expected 'bool', but found 'int'\n");
938 For(i = 0, i + 10, ++i, i += 5).release();
939 }
940}
941
942DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIf, r, ctxInfo) {
943 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
944 Var a(kFloat, "a"), b(kFloat, "b");
945 Statement x = If(a > b, a -= b);
946 REPORTER_ASSERT(r, x.release()->description() == "if ((a > b)) (a -= b);");
947
948 Statement y = If(a > b, a -= b, b -= a);
949 REPORTER_ASSERT(r, y.release()->description() == "if ((a > b)) (a -= b); else (b -= a);");
950
951 {
952 ExpectError error(r, "error: expected 'bool', but found 'float'\n");
953 If(a + b, a -= b).release();
954 }
955}
956
957DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLTernary, r, ctxInfo) {
958 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
959 Var a(kInt, "a");
960 Expression x = Ternary(a > 0, 1, -1);
961 REPORTER_ASSERT(r, x.release()->description() == "((a > 0) ? 1 : -1)");
962
963 {
964 ExpectError error(r, "error: expected 'bool', but found 'int'\n");
965 Ternary(a, 1, -1).release();
966 }
967
968 {
969 ExpectError error(r, "error: ternary operator result mismatch: 'float2', 'float3'\n");
970 Ternary(a > 0, Float2(1), Float3(1)).release();
971 }
972}
973
974DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWhile, r, ctxInfo) {
975 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
976 Statement x = While(true, Block());
977 REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "for (; true;) {}"));
978
979 Var a(kFloat, "a"), b(kFloat, "b");
980 Statement y = While(a != b, Block(a++, --b));
981 REPORTER_ASSERT(r, whitespace_insensitive_compare(y, "for (; (a != b);) { a++; --b; }"));
982
983 {
984 ExpectError error(r, "error: expected 'bool', but found 'int'\n");
985 While(7, Block()).release();
986 }
987}
Ethan Nicholas04be3392021-01-26 10:07:01 -0500988
989DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIndex, r, ctxInfo) {
990 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
991 Var a(Array(kInt, 5), "a"), b(kInt, "b");
992 Expression e1 = a[0];
993 REPORTER_ASSERT(r, e1.release()->description() == "a[0]");
994 Expression e2 = a[b];
995 REPORTER_ASSERT(r, e2.release()->description() == "a[b]");
996
997 {
998 ExpectError error(r, "error: expected 'int', but found 'bool'\n");
999 a[true].release();
1000 }
1001
1002 {
1003 ExpectError error(r, "error: expected array, but found 'int'\n");
1004 b[0].release();
1005 }
1006
1007 {
1008 ExpectError error(r, "error: index -1 out of range for 'int[5]'\n");
1009 a[-1].release();
1010 }
1011}
Ethan Nicholas30e93d52021-01-26 12:00:25 -05001012
1013DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBuiltins, r, ctxInfo) {
1014 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1015 // There is a Fract type on Mac which can conflict with our Fract builtin
1016 using SkSL::dsl::Fract;
1017 Var a(kHalf4, "a"), b(kHalf4, "b"), c(kHalf4, "c");
1018 Var h3(kHalf3, "h3");
1019 Var b4(kBool4, "b4");
1020 REPORTER_ASSERT(r, Abs(a).release()->description() == "abs(a)");
1021 REPORTER_ASSERT(r, All(b4).release()->description() == "all(b4)");
1022 REPORTER_ASSERT(r, Any(b4).release()->description() == "any(b4)");
1023 REPORTER_ASSERT(r, Ceil(a).release()->description() == "ceil(a)");
1024 REPORTER_ASSERT(r, Clamp(a, 0, 1).release()->description() == "clamp(a, 0.0, 1.0)");
1025 REPORTER_ASSERT(r, Cos(a).release()->description() == "cos(a)");
1026 REPORTER_ASSERT(r, Cross(h3, h3).release()->description() == "cross(h3, h3)");
1027 REPORTER_ASSERT(r, Degrees(a).release()->description() == "degrees(a)");
1028 REPORTER_ASSERT(r, Distance(a, b).release()->description() == "distance(a, b)");
1029 REPORTER_ASSERT(r, Dot(a, b).release()->description() == "dot(a, b)");
1030 REPORTER_ASSERT(r, Equal(a, b).release()->description() == "equal(a, b)");
1031 REPORTER_ASSERT(r, Exp(a).release()->description() == "exp(a)");
1032 REPORTER_ASSERT(r, Exp2(a).release()->description() == "exp2(a)");
1033 REPORTER_ASSERT(r, Faceforward(a, b, c).release()->description() == "faceforward(a, b, c)");
1034 REPORTER_ASSERT(r, Floor(a).release()->description() == "floor(a)");
1035 REPORTER_ASSERT(r, Fract(a).release()->description() == "fract(a)");
1036 REPORTER_ASSERT(r, GreaterThan(a, b).release()->description() == "greaterThan(a, b)");
1037 REPORTER_ASSERT(r, GreaterThanEqual(a, b).release()->description() == "greaterThanEqual(a, b)");
1038 REPORTER_ASSERT(r, Inversesqrt(a).release()->description() == "inversesqrt(a)");
1039 REPORTER_ASSERT(r, LessThan(a, b).release()->description() == "lessThan(a, b)");
1040 REPORTER_ASSERT(r, LessThanEqual(a, b).release()->description() == "lessThanEqual(a, b)");
1041 REPORTER_ASSERT(r, Length(a).release()->description() == "length(a)");
1042 REPORTER_ASSERT(r, Log(a).release()->description() == "log(a)");
1043 REPORTER_ASSERT(r, Log2(a).release()->description() == "log2(a)");
1044 REPORTER_ASSERT(r, Max(a, b).release()->description() == "max(a, b)");
1045 REPORTER_ASSERT(r, Min(a, b).release()->description() == "min(a, b)");
1046 REPORTER_ASSERT(r, Mix(a, b, c).release()->description() == "mix(a, b, c)");
1047 REPORTER_ASSERT(r, Mod(a, b).release()->description() == "mod(a, b)");
1048 REPORTER_ASSERT(r, Normalize(a).release()->description() == "normalize(a)");
1049 REPORTER_ASSERT(r, NotEqual(a, b).release()->description() == "notEqual(a, b)");
1050 REPORTER_ASSERT(r, Pow(a, b).release()->description() == "pow(a, b)");
1051 REPORTER_ASSERT(r, Radians(a).release()->description() == "radians(a)");
1052 REPORTER_ASSERT(r, Reflect(a, b).release()->description() == "reflect(a, b)");
1053 REPORTER_ASSERT(r, Refract(a, b, 1).release()->description() == "refract(a, b, 1.0)");
1054 REPORTER_ASSERT(r, Saturate(a).release()->description() == "saturate(a)");
1055 REPORTER_ASSERT(r, Sign(a).release()->description() == "sign(a)");
1056 REPORTER_ASSERT(r, Sin(a).release()->description() == "sin(a)");
1057 REPORTER_ASSERT(r, Smoothstep(a, b, c).release()->description() == "smoothstep(a, b, c)");
1058 REPORTER_ASSERT(r, Sqrt(a).release()->description() == "sqrt(a)");
1059 REPORTER_ASSERT(r, Step(a, b).release()->description() == "step(a, b)");
1060 REPORTER_ASSERT(r, Tan(a).release()->description() == "tan(a)");
1061 REPORTER_ASSERT(r, Unpremul(a).release()->description() == "unpremul(a)");
1062
1063 // these calls all go through the normal channels, so it ought to be sufficient to prove that
1064 // one of them reports errors correctly
1065 {
1066 ExpectError error(r, "error: no match for ceil(bool)\n");
1067 Ceil(a == b).release();
1068 }
1069}