blob: 05cea394ea0a8ba2bdace6a55c17624d6d238070 [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
Ethan Nicholas24c17722021-03-09 13:10:59 -05008#include "include/private/SkSLIRNode.h"
Ethan Nicholasdaed2592021-03-04 14:30:25 -05009#include "include/sksl/DSL.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050010#include "src/gpu/GrDirectContextPriv.h"
11#include "src/gpu/GrGpu.h"
12#include "src/sksl/SkSLIRGenerator.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050013#include "src/sksl/dsl/priv/DSLWriter.h"
14
15#include "tests/Test.h"
16
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050017#include <limits>
18
Ethan Nicholas95046142021-01-07 10:57:27 -050019using namespace SkSL::dsl;
20
21class AutoDSLContext {
22public:
23 AutoDSLContext(GrGpu* gpu) {
24 Start(gpu->shaderCompiler());
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050025 DSLWriter::Instance().fMangle = false;
Ethan Nicholas95046142021-01-07 10:57:27 -050026 }
27
28 ~AutoDSLContext() {
29 End();
30 }
31};
32
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050033class ExpectError : public ErrorHandler {
34public:
35 ExpectError(skiatest::Reporter* reporter, const char* msg)
36 : fMsg(msg)
37 , fReporter(reporter) {
38 SetErrorHandler(this);
39 }
40
41 ~ExpectError() override {
John Stiles642cde22021-02-23 14:57:01 -050042 REPORTER_ASSERT(fReporter, !fMsg,
43 "Error mismatch: expected:\n%sbut no error occurred\n", fMsg);
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050044 SetErrorHandler(nullptr);
45 }
46
Ethan Nicholasb9563042021-02-25 09:45:49 -050047 void handleError(const char* msg, PositionInfo* pos) override {
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050048 REPORTER_ASSERT(fReporter, !strcmp(msg, fMsg),
49 "Error mismatch: expected:\n%sbut received:\n%s", fMsg, msg);
50 fMsg = nullptr;
51 }
52
53private:
54 const char* fMsg;
55 skiatest::Reporter* fReporter;
56};
57
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -050058static bool whitespace_insensitive_compare(const char* a, const char* b) {
59 for (;;) {
60 while (isspace(*a)) {
61 ++a;
62 }
63 while (isspace(*b)) {
64 ++b;
65 }
66 if (*a != *b) {
67 return false;
68 }
69 if (*a == 0) {
70 return true;
71 }
72 ++a;
73 ++b;
74 }
75}
76
Ethan Nicholas24c17722021-03-09 13:10:59 -050077// for use from SkSLDSLOnlyTest.cpp
78void StartDSL(const sk_gpu_test::ContextInfo ctxInfo) {
79 Start(ctxInfo.directContext()->priv().getGpu()->shaderCompiler());
80}
81
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050082DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStartup, r, ctxInfo) {
Ethan Nicholas95046142021-01-07 10:57:27 -050083 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
84 Expression e1 = 1;
85 REPORTER_ASSERT(r, e1.release()->description() == "1");
86 Expression e2 = 1.0;
87 REPORTER_ASSERT(r, e2.release()->description() == "1.0");
88 Expression e3 = true;
89 REPORTER_ASSERT(r, e3.release()->description() == "true");
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050090 Var a(kInt, "a");
91 Expression e4 = a;
92 REPORTER_ASSERT(r, e4.release()->description() == "a");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -050093
94 REPORTER_ASSERT(r, whitespace_insensitive_compare("", ""));
95 REPORTER_ASSERT(r, !whitespace_insensitive_compare("", "a"));
96 REPORTER_ASSERT(r, !whitespace_insensitive_compare("a", ""));
97 REPORTER_ASSERT(r, whitespace_insensitive_compare("a", "a"));
98 REPORTER_ASSERT(r, whitespace_insensitive_compare("abc", "abc"));
99 REPORTER_ASSERT(r, whitespace_insensitive_compare("abc", " abc "));
100 REPORTER_ASSERT(r, whitespace_insensitive_compare("a b c ", "\n\n\nabc"));
101 REPORTER_ASSERT(r, !whitespace_insensitive_compare("a b c d", "\n\n\nabc"));
Ethan Nicholas95046142021-01-07 10:57:27 -0500102}
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500103
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500104static SkSL::String stringize(DSLStatement& stmt) { return stmt.release()->description(); }
105static SkSL::String stringize(DSLPossibleStatement& stmt) { return stmt.release()->description(); }
106static SkSL::String stringize(DSLExpression& expr) { return expr.release()->description(); }
107static SkSL::String stringize(DSLPossibleExpression& expr) { return expr.release()->description(); }
John Stilesb4d7b582021-02-19 09:56:31 -0500108static SkSL::String stringize(SkSL::IRNode& node) { return node.description(); }
109
110template <typename T>
111static void expect_equal(skiatest::Reporter* r, int lineNumber, T& input, const char* expected) {
112 SkSL::String actual = stringize(input);
113 if (!whitespace_insensitive_compare(expected, actual.c_str())) {
114 ERRORF(r, "(Failed on line %d)\nExpected: %s\n Actual: %s\n",
115 lineNumber, expected, actual.c_str());
116 }
117}
118
119template <typename T>
120static void expect_equal(skiatest::Reporter* r, int lineNumber, T&& dsl, const char* expected) {
121 // This overload allows temporary values to be passed to expect_equal.
122 return expect_equal(r, lineNumber, dsl, expected);
123}
124
125#define EXPECT_EQUAL(a, b) expect_equal(r, __LINE__, (a), (b))
126
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500127DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFloat, r, ctxInfo) {
128 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
129 Expression e1 = Float(std::numeric_limits<float>::max());
130 REPORTER_ASSERT(r, atof(e1.release()->description().c_str()) ==
131 std::numeric_limits<float>::max());
132
133 Expression e2 = Float(std::numeric_limits<float>::min());
134 REPORTER_ASSERT(r, atof(e2.release()->description().c_str()) ==
135 std::numeric_limits<float>::min());
136
John Stilesb4d7b582021-02-19 09:56:31 -0500137 EXPECT_EQUAL(Float2(0),
138 "float2(0.0)");
139 EXPECT_EQUAL(Float2(-0.5, 1),
140 "float2(-0.5, 1.0)");
141 EXPECT_EQUAL(Float3(0.75),
142 "float3(0.75)");
143 EXPECT_EQUAL(Float3(Float2(0, 1), -2),
John Stilesb9e4f642021-03-05 09:11:38 -0500144 "float3(0.0, 1.0, -2.0)");
John Stilesb4d7b582021-02-19 09:56:31 -0500145 EXPECT_EQUAL(Float3(0, 1, 2),
146 "float3(0.0, 1.0, 2.0)");
147 EXPECT_EQUAL(Float4(0),
148 "float4(0.0)");
149 EXPECT_EQUAL(Float4(Float2(0, 1), Float2(2, 3)),
John Stilesb9e4f642021-03-05 09:11:38 -0500150 "float4(0.0, 1.0, 2.0, 3.0)");
John Stilesb4d7b582021-02-19 09:56:31 -0500151 EXPECT_EQUAL(Float4(0, 1, Float2(2, 3)),
John Stilesb9e4f642021-03-05 09:11:38 -0500152 "float4(0.0, 1.0, 2.0, 3.0)");
John Stilesb4d7b582021-02-19 09:56:31 -0500153 EXPECT_EQUAL(Float4(0, 1, 2, 3),
154 "float4(0.0, 1.0, 2.0, 3.0)");
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500155
156 {
157 ExpectError error(r, "error: floating point value is infinite\n");
158 Float(std::numeric_limits<float>::infinity()).release();
159 }
160
161 {
162 ExpectError error(r, "error: floating point value is NaN\n");
163 Float(std::numeric_limits<float>::quiet_NaN()).release();
164 }
165
166 {
167 ExpectError error(r, "error: invalid arguments to 'float2' constructor (expected 2 scalars,"
168 " but found 4)\n");
169 Float2(Float4(1)).release();
170 }
171
172 {
173 ExpectError error(r, "error: invalid arguments to 'float4' constructor (expected 4 scalars,"
174 " but found 3)\n");
175 Float4(Float3(1)).release();
176 }
177}
178
179DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLHalf, r, ctxInfo) {
180 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
181 Expression e1 = Half(std::numeric_limits<float>::max());
John Stilesb4d7b582021-02-19 09:56:31 -0500182 REPORTER_ASSERT(r,
183 atof(e1.release()->description().c_str()) == std::numeric_limits<float>::max());
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500184
185 Expression e2 = Half(std::numeric_limits<float>::min());
John Stilesb4d7b582021-02-19 09:56:31 -0500186 REPORTER_ASSERT(r,
187 atof(e2.release()->description().c_str()) == std::numeric_limits<float>::min());
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500188
John Stilesb9e4f642021-03-05 09:11:38 -0500189 EXPECT_EQUAL(Half2(0),
190 "half2(0.0)");
191 EXPECT_EQUAL(Half2(-0.5, 1),
192 "half2(-0.5, 1.0)");
193 EXPECT_EQUAL(Half3(0.75),
194 "half3(0.75)");
195 EXPECT_EQUAL(Half3(Half2(0, 1), -2),
196 "half3(0.0, 1.0, -2.0)");
197 EXPECT_EQUAL(Half3(0, 1, 2),
198 "half3(0.0, 1.0, 2.0)");
199 EXPECT_EQUAL(Half4(0),
200 "half4(0.0)");
201 EXPECT_EQUAL(Half4(Half2(0, 1), Half2(2, 3)),
202 "half4(0.0, 1.0, 2.0, 3.0)");
203 EXPECT_EQUAL(Half4(0, 1, Half2(2, 3)),
204 "half4(0.0, 1.0, 2.0, 3.0)");
205 EXPECT_EQUAL(Half4(0, 1, 2, 3),
206 "half4(0.0, 1.0, 2.0, 3.0)");
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500207
208 {
209 ExpectError error(r, "error: floating point value is infinite\n");
210 Half(std::numeric_limits<float>::infinity()).release();
211 }
212
213 {
214 ExpectError error(r, "error: floating point value is NaN\n");
215 Half(std::numeric_limits<float>::quiet_NaN()).release();
216 }
217
218 {
219 ExpectError error(r, "error: invalid arguments to 'half2' constructor (expected 2 scalars,"
220 " but found 4)\n");
221 Half2(Half4(1)).release();
222 }
223
224 {
225 ExpectError error(r, "error: invalid arguments to 'half4' constructor (expected 4 scalars,"
226 " but found 3)\n");
227 Half4(Half3(1)).release();
228 }
229}
230
231DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInt, r, ctxInfo) {
232 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500233
John Stilesb9e4f642021-03-05 09:11:38 -0500234 EXPECT_EQUAL(Int(std::numeric_limits<int32_t>::max()),
235 "2147483647");
236 EXPECT_EQUAL(Int2(std::numeric_limits<int32_t>::min()),
237 "int2(-2147483648)");
238 EXPECT_EQUAL(Int2(0, 1),
239 "int2(0, 1)");
240 EXPECT_EQUAL(Int3(0),
241 "int3(0)");
242 EXPECT_EQUAL(Int3(Int2(0, 1), -2),
243 "int3(0, 1, -2)");
244 EXPECT_EQUAL(Int3(0, 1, 2),
245 "int3(0, 1, 2)");
246 EXPECT_EQUAL(Int4(0),
247 "int4(0)");
248 EXPECT_EQUAL(Int4(Int2(0, 1), Int2(2, 3)),
249 "int4(0, 1, 2, 3)");
250 EXPECT_EQUAL(Int4(0, 1, Int2(2, 3)),
251 "int4(0, 1, 2, 3)");
252 EXPECT_EQUAL(Int4(0, 1, 2, 3),
253 "int4(0, 1, 2, 3)");
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500254
255 {
256 ExpectError error(r, "error: invalid arguments to 'int2' constructor (expected 2 scalars,"
257 " but found 4)\n");
258 Int2(Int4(1)).release();
259 }
260
261 {
262 ExpectError error(r, "error: invalid arguments to 'int4' constructor (expected 4 scalars,"
263 " but found 3)\n");
264 Int4(Int3(1)).release();
265 }
266}
267
268DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShort, r, ctxInfo) {
269 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500270
John Stilesb9e4f642021-03-05 09:11:38 -0500271 EXPECT_EQUAL(Short(std::numeric_limits<int16_t>::max()),
272 "32767");
273 EXPECT_EQUAL(Short2(std::numeric_limits<int16_t>::min()),
274 "short2(-32768)");
275 EXPECT_EQUAL(Short2(0, 1),
276 "short2(0, 1)");
277 EXPECT_EQUAL(Short3(0),
278 "short3(0)");
279 EXPECT_EQUAL(Short3(Short2(0, 1), -2),
280 "short3(0, 1, -2)");
281 EXPECT_EQUAL(Short3(0, 1, 2),
282 "short3(0, 1, 2)");
283 EXPECT_EQUAL(Short4(0),
284 "short4(0)");
285 EXPECT_EQUAL(Short4(Short2(0, 1), Short2(2, 3)),
286 "short4(0, 1, 2, 3)");
287 EXPECT_EQUAL(Short4(0, 1, Short2(2, 3)),
288 "short4(0, 1, 2, 3)");
289 EXPECT_EQUAL(Short4(0, 1, 2, 3),
290 "short4(0, 1, 2, 3)");
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500291
292 {
293 ExpectError error(r, "error: invalid arguments to 'short2' constructor (expected 2 scalars,"
294 " but found 4)\n");
295 Short2(Short4(1)).release();
296 }
297
298 {
299 ExpectError error(r, "error: invalid arguments to 'short4' constructor (expected 4 scalars,"
300 " but found 3)\n");
301 Short4(Short3(1)).release();
302 }
303}
304
305DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBool, r, ctxInfo) {
306 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500307
John Stilesb9e4f642021-03-05 09:11:38 -0500308 EXPECT_EQUAL(Bool2(false),
309 "bool2(false)");
310 EXPECT_EQUAL(Bool2(false, true),
311 "bool2(false, true)");
312 EXPECT_EQUAL(Bool3(false),
313 "bool3(false)");
314 EXPECT_EQUAL(Bool3(Bool2(false, true), false),
315 "bool3(false, true, false)");
316 EXPECT_EQUAL(Bool3(false, true, false),
317 "bool3(false, true, false)");
318 EXPECT_EQUAL(Bool4(false),
319 "bool4(false)");
320 EXPECT_EQUAL(Bool4(Bool2(false, true), Bool2(false, true)),
321 "bool4(false, true, false, true)");
322 EXPECT_EQUAL(Bool4(false, true, Bool2(false, true)),
323 "bool4(false, true, false, true)");
324 EXPECT_EQUAL(Bool4(false, true, false, true),
325 "bool4(false, true, false, true)");
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500326
327 {
328 ExpectError error(r, "error: invalid arguments to 'bool2' constructor (expected 2 scalars,"
329 " but found 4)\n");
330 Bool2(Bool4(true)).release();
331 }
332
333 {
334 ExpectError error(r, "error: invalid arguments to 'bool4' constructor (expected 4 scalars,"
335 " but found 3)\n");
336 Bool4(Bool3(true)).release();
337 }
338}
Ethan Nicholas92969f22021-01-13 10:38:59 -0500339
340DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLPlus, r, ctxInfo) {
341 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
342 Var a(kFloat, "a"), b(kFloat, "b");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500343
John Stiles8f440b42021-03-05 16:48:56 -0500344 EXPECT_EQUAL(a + b,
345 "(a + b)");
346 EXPECT_EQUAL(a + 1,
347 "(a + 1.0)");
348 EXPECT_EQUAL(0.5 + a + -99,
349 "((0.5 + a) + -99.0)");
350 EXPECT_EQUAL(a += b + 1,
351 "(a += (b + 1.0))");
Ethan Nicholasb14b6362021-03-08 17:07:58 -0500352 EXPECT_EQUAL(+a,
353 "a");
354 EXPECT_EQUAL(+(a + b),
355 "(a + b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500356
357 {
358 ExpectError error(r, "error: type mismatch: '+' cannot operate on 'bool2', 'float'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500359 DSLExpression((Bool2(true) + a)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500360 }
361
362 {
363 ExpectError error(r, "error: type mismatch: '+=' cannot operate on 'float', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500364 DSLExpression((a += Bool2(true))).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500365 }
366
367 {
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500368 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500369 DSLExpression((1.0 += a)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500370 }
Ethan Nicholasb14b6362021-03-08 17:07:58 -0500371
372 {
373 ExpectError error(r, "error: '+' cannot operate on 'bool'\n");
374 Var c(kBool);
375 DSLExpression(+c);
376 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500377}
378
379DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMinus, r, ctxInfo) {
380 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
381 Var a(kInt, "a"), b(kInt, "b");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500382
John Stiles8f440b42021-03-05 16:48:56 -0500383 EXPECT_EQUAL(a - b,
384 "(a - b)");
385 EXPECT_EQUAL(a - 1,
386 "(a - 1)");
387 EXPECT_EQUAL(2 - a - b,
388 "((2 - a) - b)");
389 EXPECT_EQUAL(a -= b + 1,
390 "(a -= (b + 1))");
Ethan Nicholasb14b6362021-03-08 17:07:58 -0500391 EXPECT_EQUAL(-a,
392 "-a");
393 EXPECT_EQUAL(-(a - b),
394 "-(a - b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500395
396 {
397 ExpectError error(r, "error: type mismatch: '-' cannot operate on 'bool2', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500398 DSLExpression(Bool2(true) - a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500399 }
400
401 {
402 ExpectError error(r, "error: type mismatch: '-=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500403 DSLExpression(a -= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500404 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500405
406 {
407 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500408 DSLExpression(1.0 -= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500409 }
Ethan Nicholasb14b6362021-03-08 17:07:58 -0500410
411 {
412 ExpectError error(r, "error: '-' cannot operate on 'bool'\n");
413 Var c(kBool);
414 DSLExpression(-c);
415 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500416}
417
418DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMultiply, r, ctxInfo) {
419 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
420 Var a(kFloat, "a"), b(kFloat, "b");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500421
John Stiles8f440b42021-03-05 16:48:56 -0500422 EXPECT_EQUAL(a * b,
423 "(a * b)");
424 EXPECT_EQUAL(a * 2,
425 "(a * 2.0)");
426 EXPECT_EQUAL(0.5 * a * -99,
427 "((0.5 * a) * -99.0)");
428 EXPECT_EQUAL(a *= b + 1,
429 "(a *= (b + 1.0))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500430
431 {
432 ExpectError error(r, "error: type mismatch: '*' cannot operate on 'bool2', 'float'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500433 DSLExpression(Bool2(true) * a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500434 }
435
436 {
437 ExpectError error(r, "error: type mismatch: '*=' cannot operate on 'float', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500438 DSLExpression(a *= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500439 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500440
441 {
442 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500443 DSLExpression(1.0 *= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500444 }
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");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500450
John Stiles8f440b42021-03-05 16:48:56 -0500451 EXPECT_EQUAL(a / b,
452 "(a / b)");
453 EXPECT_EQUAL(a / 2,
454 "(a / 2.0)");
455 EXPECT_EQUAL(0.5 / a / -99,
456 "((0.5 / a) / -99.0)");
457 EXPECT_EQUAL(b / (a - 1),
458 "(b / (a - 1.0))");
459 EXPECT_EQUAL(a /= b + 1,
460 "(a /= (b + 1.0))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500461
462 {
463 ExpectError error(r, "error: type mismatch: '/' cannot operate on 'bool2', 'float'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500464 DSLExpression(Bool2(true) / a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500465 }
466
467 {
468 ExpectError error(r, "error: type mismatch: '/=' cannot operate on 'float', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500469 DSLExpression(a /= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500470 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500471
472 {
473 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500474 DSLExpression(1.0 /= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500475 }
Ethan Nicholasc0f98152021-02-05 16:21:10 -0500476
477 {
478 ExpectError error(r, "error: division by zero\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500479 DSLExpression(a /= 0).release();
Ethan Nicholasc0f98152021-02-05 16:21:10 -0500480 }
481
482 {
483 Var c(kFloat2, "c");
484 ExpectError error(r, "error: division by zero\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500485 DSLExpression(c /= Float2(Float(0), 1)).release();
Ethan Nicholasc0f98152021-02-05 16:21:10 -0500486 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500487}
488
489DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMod, r, ctxInfo) {
490 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
491 Var a(kInt, "a"), b(kInt, "b");
492 Expression e1 = a % b;
John Stilesb4d7b582021-02-19 09:56:31 -0500493 EXPECT_EQUAL(e1, "(a % b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500494
495 Expression e2 = a % 2;
John Stilesb4d7b582021-02-19 09:56:31 -0500496 EXPECT_EQUAL(e2, "(a % 2)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500497
498 Expression e3 = 10 % a % -99;
John Stilesb4d7b582021-02-19 09:56:31 -0500499 EXPECT_EQUAL(e3, "((10 % a) % -99)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500500
501 Expression e4 = a %= b + 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500502 EXPECT_EQUAL(e4, "(a %= (b + 1))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500503
504 {
505 ExpectError error(r, "error: type mismatch: '%' cannot operate on 'bool2', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500506 DSLExpression(Bool2(true) % a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500507 }
508
509 {
510 ExpectError error(r, "error: type mismatch: '%=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500511 DSLExpression(a %= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500512 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500513
514 {
515 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500516 DSLExpression(1 %= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500517 }
Ethan Nicholasc0f98152021-02-05 16:21:10 -0500518
519 {
520 ExpectError error(r, "error: division by zero\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500521 DSLExpression(a %= 0).release();
Ethan Nicholasc0f98152021-02-05 16:21:10 -0500522 }
523
524 {
525 Var c(kInt2, "c");
526 ExpectError error(r, "error: division by zero\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500527 DSLExpression(c %= Int2(Int(0), 1)).release();
Ethan Nicholasc0f98152021-02-05 16:21:10 -0500528 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500529}
530
531DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShl, r, ctxInfo) {
532 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
533 Var a(kInt, "a"), b(kInt, "b");
534 Expression e1 = a << b;
John Stilesb4d7b582021-02-19 09:56:31 -0500535 EXPECT_EQUAL(e1, "(a << b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500536
537 Expression e2 = a << 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500538 EXPECT_EQUAL(e2, "(a << 1)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500539
540 Expression e3 = 1 << a << 2;
John Stilesb4d7b582021-02-19 09:56:31 -0500541 EXPECT_EQUAL(e3, "((1 << a) << 2)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500542
543 Expression e4 = a <<= b + 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500544 EXPECT_EQUAL(e4, "(a <<= (b + 1))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500545
546 {
547 ExpectError error(r, "error: type mismatch: '<<' cannot operate on 'bool2', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500548 DSLExpression(Bool2(true) << a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500549 }
550
551 {
552 ExpectError error(r, "error: type mismatch: '<<=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500553 DSLExpression(a <<= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500554 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500555
556 {
557 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500558 DSLExpression(1 <<= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500559 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500560}
561
562DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShr, r, ctxInfo) {
563 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
564 Var a(kInt, "a"), b(kInt, "b");
565 Expression e1 = a >> b;
John Stilesb4d7b582021-02-19 09:56:31 -0500566 EXPECT_EQUAL(e1, "(a >> b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500567
568 Expression e2 = a >> 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500569 EXPECT_EQUAL(e2, "(a >> 1)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500570
571 Expression e3 = 1 >> a >> 2;
John Stilesb4d7b582021-02-19 09:56:31 -0500572 EXPECT_EQUAL(e3, "((1 >> a) >> 2)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500573
574 Expression e4 = a >>= b + 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500575 EXPECT_EQUAL(e4, "(a >>= (b + 1))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500576
577 {
578 ExpectError error(r, "error: type mismatch: '>>' cannot operate on 'bool2', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500579 DSLExpression(Bool2(true) >> a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500580 }
581
582 {
583 ExpectError error(r, "error: type mismatch: '>>=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500584 DSLExpression(a >>= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500585 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500586
587 {
588 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500589 DSLExpression(1 >>= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500590 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500591}
592
593DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseAnd, r, ctxInfo) {
594 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
595 Var a(kInt, "a"), b(kInt, "b");
596 Expression e1 = a & b;
John Stilesb4d7b582021-02-19 09:56:31 -0500597 EXPECT_EQUAL(e1, "(a & b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500598
599 Expression e2 = a & 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500600 EXPECT_EQUAL(e2, "(a & 1)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500601
602 Expression e3 = 1 & a & 2;
John Stilesb4d7b582021-02-19 09:56:31 -0500603 EXPECT_EQUAL(e3, "((1 & a) & 2)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500604
605 Expression e4 = a &= b + 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500606 EXPECT_EQUAL(e4, "(a &= (b + 1))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500607
608 {
609 ExpectError error(r, "error: type mismatch: '&' cannot operate on 'bool2', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500610 DSLExpression(Bool2(true) & a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500611 }
612
613 {
614 ExpectError error(r, "error: type mismatch: '&=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500615 DSLExpression(a &= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500616 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500617
618 {
619 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500620 DSLExpression(1 &= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500621 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500622}
623
624DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseOr, r, ctxInfo) {
625 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
626 Var a(kInt, "a"), b(kInt, "b");
627 Expression e1 = a | b;
John Stilesb4d7b582021-02-19 09:56:31 -0500628 EXPECT_EQUAL(e1, "(a | b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500629
630 Expression e2 = a | 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500631 EXPECT_EQUAL(e2, "(a | 1)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500632
633 Expression e3 = 1 | a | 2;
John Stilesb4d7b582021-02-19 09:56:31 -0500634 EXPECT_EQUAL(e3, "((1 | a) | 2)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500635
636 Expression e4 = a |= b + 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500637 EXPECT_EQUAL(e4, "(a |= (b + 1))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500638
639 {
640 ExpectError error(r, "error: type mismatch: '|' cannot operate on 'bool2', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500641 DSLExpression(Bool2(true) | a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500642 }
643
644 {
645 ExpectError error(r, "error: type mismatch: '|=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500646 DSLExpression(a |= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500647 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500648
649 {
650 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500651 DSLExpression(1 |= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500652 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500653}
654
655DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseXor, r, ctxInfo) {
656 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
657 Var a(kInt, "a"), b(kInt, "b");
658 Expression e1 = a ^ b;
John Stilesb4d7b582021-02-19 09:56:31 -0500659 EXPECT_EQUAL(e1, "(a ^ b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500660
661 Expression e2 = a ^ 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500662 EXPECT_EQUAL(e2, "(a ^ 1)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500663
664 Expression e3 = 1 ^ a ^ 2;
John Stilesb4d7b582021-02-19 09:56:31 -0500665 EXPECT_EQUAL(e3, "((1 ^ a) ^ 2)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500666
667 Expression e4 = a ^= b + 1;
John Stilesb4d7b582021-02-19 09:56:31 -0500668 EXPECT_EQUAL(e4, "(a ^= (b + 1))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500669
670 {
671 ExpectError error(r, "error: type mismatch: '^' cannot operate on 'bool2', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500672 DSLExpression(Bool2(true) ^ a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500673 }
674
675 {
676 ExpectError error(r, "error: type mismatch: '^=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500677 DSLExpression(a ^= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500678 }
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500679
680 {
681 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500682 DSLExpression(1 ^= a).release();
Ethan Nicholas67a0a8a2021-01-13 12:36:02 -0500683 }
Ethan Nicholas92969f22021-01-13 10:38:59 -0500684}
685
686DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalAnd, r, ctxInfo) {
687 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
688 Var a(kBool, "a"), b(kBool, "b");
689 Expression e1 = a && b;
John Stilesb4d7b582021-02-19 09:56:31 -0500690 EXPECT_EQUAL(e1, "(a && b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500691
692 Expression e2 = a && true && b;
John Stilesb4d7b582021-02-19 09:56:31 -0500693 EXPECT_EQUAL(e2, "(a && b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500694
695 Expression e3 = a && false && b;
John Stilesb4d7b582021-02-19 09:56:31 -0500696 EXPECT_EQUAL(e3, "false");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500697
698 {
699 ExpectError error(r, "error: type mismatch: '&&' cannot operate on 'bool', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500700 DSLExpression(a && 5).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500701 }
702}
703
704DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalOr, r, ctxInfo) {
705 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
706 Var a(kBool, "a"), b(kBool, "b");
707 Expression e1 = a || b;
John Stilesb4d7b582021-02-19 09:56:31 -0500708 EXPECT_EQUAL(e1, "(a || b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500709
710 Expression e2 = a || true || b;
John Stilesb4d7b582021-02-19 09:56:31 -0500711 EXPECT_EQUAL(e2, "true");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500712
713 Expression e3 = a || false || b;
John Stilesb4d7b582021-02-19 09:56:31 -0500714 EXPECT_EQUAL(e3, "(a || b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500715
716 {
717 ExpectError error(r, "error: type mismatch: '||' cannot operate on 'bool', 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500718 DSLExpression(a || 5).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500719 }
720}
721
722DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLComma, r, ctxInfo) {
723 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
724 Var a(kInt, "a"), b(kInt, "b");
725 Expression e1 = (a += b, b);
John Stilesb4d7b582021-02-19 09:56:31 -0500726 EXPECT_EQUAL(e1, "((a += b) , b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500727
728 Expression e2 = (a += b, b += b, Int2(a));
John Stilesb4d7b582021-02-19 09:56:31 -0500729 EXPECT_EQUAL(e2, "(((a += b) , (b += b)) , int2(a))");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500730}
731
732DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLEqual, r, ctxInfo) {
733 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
734 Var a(kInt, "a"), b(kInt, "b");
735 Expression e1 = a == b;
John Stilesb4d7b582021-02-19 09:56:31 -0500736 EXPECT_EQUAL(e1, "(a == b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500737
738 Expression e2 = a == 5;
John Stilesb4d7b582021-02-19 09:56:31 -0500739 EXPECT_EQUAL(e2, "(a == 5)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500740
741 {
742 ExpectError error(r, "error: type mismatch: '==' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500743 DSLExpression(a == Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500744 }
745}
746
747DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLNotEqual, r, ctxInfo) {
748 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
749 Var a(kInt, "a"), b(kInt, "b");
750 Expression e1 = a != b;
John Stilesb4d7b582021-02-19 09:56:31 -0500751 EXPECT_EQUAL(e1, "(a != b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500752
753 Expression e2 = a != 5;
John Stilesb4d7b582021-02-19 09:56:31 -0500754 EXPECT_EQUAL(e2, "(a != 5)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500755
756 {
757 ExpectError error(r, "error: type mismatch: '!=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500758 DSLExpression(a != Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500759 }
760}
761
762DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLGreaterThan, r, ctxInfo) {
763 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
764 Var a(kInt, "a"), b(kInt, "b");
765 Expression e1 = a > b;
John Stilesb4d7b582021-02-19 09:56:31 -0500766 EXPECT_EQUAL(e1, "(a > b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500767
768 Expression e2 = a > 5;
John Stilesb4d7b582021-02-19 09:56:31 -0500769 EXPECT_EQUAL(e2, "(a > 5)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500770
771 {
772 ExpectError error(r, "error: type mismatch: '>' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500773 DSLExpression(a > Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500774 }
775}
776
777DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLGreaterThanOrEqual, r, ctxInfo) {
778 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
779 Var a(kInt, "a"), b(kInt, "b");
780 Expression e1 = a >= b;
John Stilesb4d7b582021-02-19 09:56:31 -0500781 EXPECT_EQUAL(e1, "(a >= b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500782
783 Expression e2 = a >= 5;
John Stilesb4d7b582021-02-19 09:56:31 -0500784 EXPECT_EQUAL(e2, "(a >= 5)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500785
786 {
787 ExpectError error(r, "error: type mismatch: '>=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500788 DSLExpression(a >= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500789 }
790}
791
792DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLessThan, r, ctxInfo) {
793 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
794 Var a(kInt, "a"), b(kInt, "b");
795 Expression e1 = a < b;
John Stilesb4d7b582021-02-19 09:56:31 -0500796 EXPECT_EQUAL(e1, "(a < b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500797
798 Expression e2 = a < 5;
John Stilesb4d7b582021-02-19 09:56:31 -0500799 EXPECT_EQUAL(e2, "(a < 5)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500800
801 {
802 ExpectError error(r, "error: type mismatch: '<' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500803 DSLExpression(a < Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500804 }
805}
806
807DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLessThanOrEqual, r, ctxInfo) {
808 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
809 Var a(kInt, "a"), b(kInt, "b");
810 Expression e1 = a <= b;
John Stilesb4d7b582021-02-19 09:56:31 -0500811 EXPECT_EQUAL(e1, "(a <= b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500812
813 Expression e2 = a <= 5;
John Stilesb4d7b582021-02-19 09:56:31 -0500814 EXPECT_EQUAL(e2, "(a <= 5)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500815
816 {
817 ExpectError error(r, "error: type mismatch: '<=' cannot operate on 'int', 'bool2'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500818 DSLExpression(a <= Bool2(true)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500819 }
820}
821
822DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalNot, r, ctxInfo) {
823 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
824 Var a(kInt, "a"), b(kInt, "b");
825 Expression e1 = !(a <= b);
John Stilesb4d7b582021-02-19 09:56:31 -0500826 EXPECT_EQUAL(e1, "!(a <= b)");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500827
828 {
829 ExpectError error(r, "error: '!' cannot operate on 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500830 DSLExpression(!a).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500831 }
832}
833
834DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseNot, r, ctxInfo) {
835 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
836 Var a(kInt, "a"), b(kBool, "b");
837 Expression e1 = ~a;
John Stilesb4d7b582021-02-19 09:56:31 -0500838 EXPECT_EQUAL(e1, "~a");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500839
840 {
841 ExpectError error(r, "error: '~' cannot operate on 'bool'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500842 DSLExpression(~b).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500843 }
844}
845
846DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIncrement, r, ctxInfo) {
847 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
848 Var a(kInt, "a"), b(kBool, "b");
849 Expression e1 = ++a;
John Stilesb4d7b582021-02-19 09:56:31 -0500850 EXPECT_EQUAL(e1, "++a");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500851
852 Expression e2 = a++;
John Stilesb4d7b582021-02-19 09:56:31 -0500853 EXPECT_EQUAL(e2, "a++");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500854
855 {
856 ExpectError error(r, "error: '++' cannot operate on 'bool'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500857 DSLExpression(++b).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500858 }
859
860 {
861 ExpectError error(r, "error: '++' cannot operate on 'bool'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500862 DSLExpression(b++).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500863 }
864
865 {
866 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500867 DSLExpression(++(a + 1)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500868 }
869
870 {
871 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500872 DSLExpression((a + 1)++).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500873 }
874}
875
876DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDecrement, r, ctxInfo) {
877 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
878 Var a(kInt, "a"), b(kBool, "b");
879 Expression e1 = --a;
John Stilesb4d7b582021-02-19 09:56:31 -0500880 EXPECT_EQUAL(e1, "--a");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500881
882 Expression e2 = a--;
John Stilesb4d7b582021-02-19 09:56:31 -0500883 EXPECT_EQUAL(e2, "a--");
Ethan Nicholas92969f22021-01-13 10:38:59 -0500884
885 {
886 ExpectError error(r, "error: '--' cannot operate on 'bool'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500887 DSLExpression(--b).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500888 }
889
890 {
891 ExpectError error(r, "error: '--' cannot operate on 'bool'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500892 DSLExpression(b--).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500893 }
894
895 {
896 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500897 DSLExpression(--(a + 1)).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500898 }
899
900 {
901 ExpectError error(r, "error: cannot assign to this expression\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500902 DSLExpression((a + 1)--).release();
Ethan Nicholas92969f22021-01-13 10:38:59 -0500903 }
904}
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500905
906DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBlock, r, ctxInfo) {
907 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
908 Statement x = Block();
John Stilesb4d7b582021-02-19 09:56:31 -0500909 EXPECT_EQUAL(x, "{ }");
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500910 Var a(kInt, "a", 1), b(kInt, "b", 2);
911 Statement y = Block(Declare(a), Declare(b), a = b);
John Stilesb4d7b582021-02-19 09:56:31 -0500912 EXPECT_EQUAL(y, "{ int a = 1; int b = 2; (a = b); }");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500913}
914
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500915DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBreak, r, ctxInfo) {
916 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500917 Var i(kInt, "i", 0);
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500918 DSLFunction(kVoid, "success").define(
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500919 For(Declare(i), i < 10, ++i, Block(
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500920 If(i > 5, Break())
921 ))
922 );
923 REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
John Stilesb4d7b582021-02-19 09:56:31 -0500924 EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
925 "void success() { for (int i = 0; (i < 10); ++i) { if ((i > 5)) break; } }");
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500926
927 {
928 ExpectError error(r, "error: break statement must be inside a loop or switch\n");
929 DSLFunction(kVoid, "fail").define(
930 Break()
931 );
932 }
933}
934
935DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLContinue, r, ctxInfo) {
936 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500937 Var i(kInt, "i", 0);
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500938 DSLFunction(kVoid, "success").define(
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500939 For(Declare(i), i < 10, ++i, Block(
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500940 If(i < 5, Continue())
941 ))
942 );
943 REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
John Stilesb4d7b582021-02-19 09:56:31 -0500944 EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
945 "void success() { for (int i = 0; (i < 10); ++i) { if ((i < 5)) continue; } }");
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500946
947 {
948 ExpectError error(r, "error: continue statement must be inside a loop\n");
949 DSLFunction(kVoid, "fail").define(
950 Continue()
951 );
952 }
953}
954
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500955DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclare, r, ctxInfo) {
956 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500957 Var a(kHalf4, "a"), b(kHalf4, "b", Half4(1));
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500958 Statement x = Declare(a);
John Stilesb4d7b582021-02-19 09:56:31 -0500959 EXPECT_EQUAL(x, "half4 a;");
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500960 Statement y = Declare(b);
John Stilesb4d7b582021-02-19 09:56:31 -0500961 EXPECT_EQUAL(y, "half4 b = half4(1.0);");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500962
963 {
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500964 Var c(kHalf4, "c", 1);
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500965 ExpectError error(r, "error: expected 'half4', but found 'int'\n");
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500966 Declare(c).release();
967 }
968
969 {
970 Var d(kInt, "d");
971 Declare(d).release();
972 ExpectError error(r, "error: variable has already been declared\n");
973 Declare(d).release();
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500974 }
975}
976
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500977DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDiscard, r, ctxInfo) {
978 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
979 Statement x = If(Sqrt(1) > 0, Discard());
John Stilesb4d7b582021-02-19 09:56:31 -0500980 EXPECT_EQUAL(x, "if ((sqrt(1.0) > 0.0)) discard;");
Ethan Nicholasdaceb792021-02-05 14:22:32 -0500981}
982
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500983DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDo, r, ctxInfo) {
984 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
985 Statement x = Do(Block(), true);
John Stilesb4d7b582021-02-19 09:56:31 -0500986 EXPECT_EQUAL(x, "do {} while (true);");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500987
988 Var a(kFloat, "a"), b(kFloat, "b");
989 Statement y = Do(Block(a++, --b), a != b);
John Stilesb4d7b582021-02-19 09:56:31 -0500990 EXPECT_EQUAL(y, "do { a++; --b; } while ((a != b));");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500991
992 {
993 ExpectError error(r, "error: expected 'bool', but found 'int'\n");
994 Do(Block(), 7).release();
995 }
996}
997
998DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFor, r, ctxInfo) {
999 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1000 Statement x = For(Statement(), Expression(), Expression(), Block());
John Stilesb4d7b582021-02-19 09:56:31 -05001001 EXPECT_EQUAL(x, "for (;;) {}");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001002
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001003 Var i(kInt, "i", 0);
1004 Statement y = For(Declare(i), i < 10, ++i, i += 5);
John Stilesb4d7b582021-02-19 09:56:31 -05001005 EXPECT_EQUAL(y, "for (int i = 0; (i < 10); ++i) (i += 5);");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001006
1007 {
1008 ExpectError error(r, "error: expected 'bool', but found 'int'\n");
1009 For(i = 0, i + 10, ++i, i += 5).release();
1010 }
1011}
1012
Ethan Nicholase2c05042021-02-03 10:27:22 -05001013DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001014 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001015 Var coords(kHalf2, "coords");
1016 DSLFunction(kVoid, "main", coords).define(
1017 sk_FragColor() = Half4(coords, 0, 1)
1018 );
1019 REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
John Stilesb4d7b582021-02-19 09:56:31 -05001020 EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
1021 "void main(half2 coords) { (sk_FragColor = half4(coords, 0.0, 1.0)); }");
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001022
Ethan Nicholas63f75fc2021-02-23 12:05:49 -05001023 {
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001024 DSLWriter::Reset();
Ethan Nicholas63f75fc2021-02-23 12:05:49 -05001025 Var x(kFloat, "x");
1026 DSLFunction sqr(kFloat, "sqr", x);
1027 sqr.define(
1028 Return(x * x)
1029 );
1030 EXPECT_EQUAL(sqr(sk_FragCoord().x()), "sqr(sk_FragCoord.x)");
1031 REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
1032 EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "float sqr(float x) { return (x * x); }");
1033 }
1034
1035 {
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001036 DSLWriter::Reset();
Ethan Nicholas63f75fc2021-02-23 12:05:49 -05001037 Var x(kFloat2, "x");
1038 Var y(kFloat2, "y");
1039 DSLFunction dot(kFloat2, "dot", x, y);
1040 dot.define(
1041 Return(x * x + y * y)
1042 );
1043 EXPECT_EQUAL(dot(Float2(1.0f, 2.0f), Float2(3.0f, 4.0f)),
1044 "dot(float2(1.0, 2.0), float2(3.0, 4.0))");
1045 REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
1046 EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
1047 "float2 dot(float2 x, float2 y) { return ((x * x) + (y * y)); }");
1048 }
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001049
1050 {
1051 ExpectError error(r, "error: expected 'float', but found 'bool'\n");
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001052 DSLWriter::Reset();
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001053 DSLFunction(kFloat, "broken").define(
1054 Return(true)
1055 );
1056 }
1057
1058 {
John Stilesb3dcbb12021-03-04 16:00:20 -05001059 ExpectError error(r, "error: expected function to return 'float'\n");
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001060 DSLWriter::Reset();
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001061 DSLFunction(kFloat, "broken").define(
1062 Return()
1063 );
1064 }
1065
1066 {
John Stilesb3dcbb12021-03-04 16:00:20 -05001067 ExpectError error(r, "error: function 'broken' can exit without returning a value\n");
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001068 DSLWriter::Reset();
1069 Var x(kFloat, "x", 0);
John Stilesb3dcbb12021-03-04 16:00:20 -05001070 DSLFunction(kFloat, "broken").define(
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001071 Declare(x),
John Stilesb3dcbb12021-03-04 16:00:20 -05001072 If(x == 1, Return(x))
1073 );
1074 }
1075
1076 {
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001077 ExpectError error(r, "error: may not return a value from a void function\n");
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001078 DSLWriter::Reset();
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001079 DSLFunction(kVoid, "broken").define(
1080 Return(0)
1081 );
1082 }
1083
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001084 {
John Stilesb3dcbb12021-03-04 16:00:20 -05001085 ExpectError error(r, "error: function 'broken' can exit without returning a value\n");
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001086 DSLWriter::Reset();
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001087 DSLFunction(kFloat, "broken").define(
1088 );
1089 }
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001090}
1091
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001092DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIf, r, ctxInfo) {
1093 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1094 Var a(kFloat, "a"), b(kFloat, "b");
1095 Statement x = If(a > b, a -= b);
John Stilesb4d7b582021-02-19 09:56:31 -05001096 EXPECT_EQUAL(x, "if ((a > b)) (a -= b);");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001097
1098 Statement y = If(a > b, a -= b, b -= a);
John Stilesb4d7b582021-02-19 09:56:31 -05001099 EXPECT_EQUAL(y, "if ((a > b)) (a -= b); else (b -= a);");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001100
1101 {
1102 ExpectError error(r, "error: expected 'bool', but found 'float'\n");
1103 If(a + b, a -= b).release();
1104 }
1105}
1106
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001107DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLReturn, r, ctxInfo) {
1108 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1109
1110 Statement x = Return();
John Stilesb4d7b582021-02-19 09:56:31 -05001111 EXPECT_EQUAL(x, "return;");
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001112
1113 Statement y = Return(true);
John Stilesb4d7b582021-02-19 09:56:31 -05001114 EXPECT_EQUAL(y, "return true;");
Ethan Nicholas1ff76092021-01-28 10:02:43 -05001115}
1116
Ethan Nicholasfa648a12021-02-17 12:13:20 -05001117DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSelect, r, ctxInfo) {
1118 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1119 Var a(kInt, "a");
1120 Expression x = Select(a > 0, 1, -1);
John Stilesb4d7b582021-02-19 09:56:31 -05001121 EXPECT_EQUAL(x, "((a > 0) ? 1 : -1)");
Ethan Nicholasfa648a12021-02-17 12:13:20 -05001122
1123 {
1124 ExpectError error(r, "error: expected 'bool', but found 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001125 DSLExpression x = Select(a, 1, -1);
Ethan Nicholasfa648a12021-02-17 12:13:20 -05001126 }
1127
1128 {
1129 ExpectError error(r, "error: ternary operator result mismatch: 'float2', 'float3'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001130 DSLExpression x = Select(a > 0, Float2(1), Float3(1));
Ethan Nicholasfa648a12021-02-17 12:13:20 -05001131 }
1132}
1133
Ethan Nicholascfefec02021-02-09 15:22:57 -05001134DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSwitch, r, ctxInfo) {
1135 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1136
1137 Var a(kFloat, "a"), b(kInt, "b");
1138
John Stilesf3a28db2021-03-10 23:00:47 -05001139 Statement x = Switch(b,
Ethan Nicholascfefec02021-02-09 15:22:57 -05001140 Case(0, a = 0, Break()),
1141 Case(1, a = 1, Continue()),
John Stilese1d1b082021-02-23 13:44:36 -05001142 Case(2, a = 2 /*Fallthrough*/),
Ethan Nicholascfefec02021-02-09 15:22:57 -05001143 Default(Discard())
1144 );
John Stilese1d1b082021-02-23 13:44:36 -05001145 EXPECT_EQUAL(x, R"(
John Stilesf3a28db2021-03-10 23:00:47 -05001146 switch (b) {
John Stilese1d1b082021-02-23 13:44:36 -05001147 case 0: (a = 0.0); break;
1148 case 1: (a = 1.0); continue;
1149 case 2: (a = 2.0);
1150 default: discard;
1151 }
1152 )");
Ethan Nicholascfefec02021-02-09 15:22:57 -05001153
John Stiles642cde22021-02-23 14:57:01 -05001154 EXPECT_EQUAL(Switch(b),
1155 "switch (b) {}");
1156
1157 EXPECT_EQUAL(Switch(b, Default(), Case(0), Case(1)),
1158 "switch (b) { default: case 0: case 1: }");
Ethan Nicholascfefec02021-02-09 15:22:57 -05001159
1160 {
John Stilese1d1b082021-02-23 13:44:36 -05001161 ExpectError error(r, "error: duplicate case value '0'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001162 DSLStatement(Switch(0, Case(0), Case(0))).release();
Ethan Nicholascfefec02021-02-09 15:22:57 -05001163 }
1164
1165 {
John Stilese1d1b082021-02-23 13:44:36 -05001166 ExpectError error(r, "error: duplicate default case\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001167 DSLStatement(Switch(0, Default(a = 0), Default(a = 1))).release();
John Stilese1d1b082021-02-23 13:44:36 -05001168 }
1169
1170 {
Ethan Nicholascfefec02021-02-09 15:22:57 -05001171 ExpectError error(r, "error: case value must be a constant integer\n");
1172 Var b(kInt);
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001173 DSLStatement(Switch(0, Case(b))).release();
Ethan Nicholascfefec02021-02-09 15:22:57 -05001174 }
Ethan Nicholascfefec02021-02-09 15:22:57 -05001175}
1176
Ethan Nicholas68c77d42021-01-26 14:31:29 -05001177DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSwizzle, r, ctxInfo) {
1178 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1179 Var a(kFloat4, "a");
1180
John Stilesf04e09c2021-03-05 13:13:14 -05001181 EXPECT_EQUAL(a.x(),
1182 "a.x");
1183 EXPECT_EQUAL(a.y(),
1184 "a.y");
1185 EXPECT_EQUAL(a.z(),
1186 "a.z");
1187 EXPECT_EQUAL(a.w(),
1188 "a.w");
1189 EXPECT_EQUAL(a.r(),
1190 "a.x");
1191 EXPECT_EQUAL(a.g(),
1192 "a.y");
1193 EXPECT_EQUAL(a.b(),
1194 "a.z");
1195 EXPECT_EQUAL(a.a(),
1196 "a.w");
1197 EXPECT_EQUAL(Swizzle(a, R),
1198 "a.x");
1199 EXPECT_EQUAL(Swizzle(a, ZERO, G),
1200 "float2(0.0, a.y)");
1201 EXPECT_EQUAL(Swizzle(a, B, G, G),
1202 "a.zyy");
1203 EXPECT_EQUAL(Swizzle(a, R, G, B, ONE),
1204 "float4(a.xyz, 1.0)");
1205 EXPECT_EQUAL(Swizzle(a, B, G, R, ONE).r(),
1206 "a.z");
Ethan Nicholas68c77d42021-01-26 14:31:29 -05001207}
1208
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001209DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWhile, r, ctxInfo) {
1210 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1211 Statement x = While(true, Block());
John Stilesb4d7b582021-02-19 09:56:31 -05001212 EXPECT_EQUAL(x, "for (; true;) {}");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001213
1214 Var a(kFloat, "a"), b(kFloat, "b");
1215 Statement y = While(a != b, Block(a++, --b));
John Stilesb4d7b582021-02-19 09:56:31 -05001216 EXPECT_EQUAL(y, "for (; (a != b);) { a++; --b; }");
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001217
1218 {
1219 ExpectError error(r, "error: expected 'bool', but found 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001220 DSLStatement x = While(7, Block());
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -05001221 }
1222}
Ethan Nicholas04be3392021-01-26 10:07:01 -05001223
1224DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIndex, r, ctxInfo) {
1225 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1226 Var a(Array(kInt, 5), "a"), b(kInt, "b");
John Stilesb4d7b582021-02-19 09:56:31 -05001227
1228 EXPECT_EQUAL(a[0], "a[0]");
1229 EXPECT_EQUAL(a[b], "a[b]");
Ethan Nicholas04be3392021-01-26 10:07:01 -05001230
1231 {
1232 ExpectError error(r, "error: expected 'int', but found 'bool'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001233 DSLExpression x = a[true];
Ethan Nicholas04be3392021-01-26 10:07:01 -05001234 }
1235
1236 {
1237 ExpectError error(r, "error: expected array, but found 'int'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001238 DSLExpression x = b[0];
Ethan Nicholas04be3392021-01-26 10:07:01 -05001239 }
1240
1241 {
1242 ExpectError error(r, "error: index -1 out of range for 'int[5]'\n");
Ethan Nicholas34c7e112021-02-25 20:50:32 -05001243 DSLExpression x = a[-1];
Ethan Nicholas04be3392021-01-26 10:07:01 -05001244 }
1245}
Ethan Nicholas30e93d52021-01-26 12:00:25 -05001246
1247DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBuiltins, r, ctxInfo) {
1248 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1249 // There is a Fract type on Mac which can conflict with our Fract builtin
1250 using SkSL::dsl::Fract;
1251 Var a(kHalf4, "a"), b(kHalf4, "b"), c(kHalf4, "c");
1252 Var h3(kHalf3, "h3");
1253 Var b4(kBool4, "b4");
John Stilesb4d7b582021-02-19 09:56:31 -05001254 EXPECT_EQUAL(Abs(a), "abs(a)");
1255 EXPECT_EQUAL(All(b4), "all(b4)");
1256 EXPECT_EQUAL(Any(b4), "any(b4)");
1257 EXPECT_EQUAL(Ceil(a), "ceil(a)");
1258 EXPECT_EQUAL(Clamp(a, 0, 1), "clamp(a, 0.0, 1.0)");
1259 EXPECT_EQUAL(Cos(a), "cos(a)");
1260 EXPECT_EQUAL(Cross(h3, h3), "cross(h3, h3)");
1261 EXPECT_EQUAL(Degrees(a), "degrees(a)");
1262 EXPECT_EQUAL(Distance(a, b), "distance(a, b)");
1263 EXPECT_EQUAL(Dot(a, b), "dot(a, b)");
1264 EXPECT_EQUAL(Equal(a, b), "equal(a, b)");
1265 EXPECT_EQUAL(Exp(a), "exp(a)");
1266 EXPECT_EQUAL(Exp2(a), "exp2(a)");
1267 EXPECT_EQUAL(Faceforward(a, b, c), "faceforward(a, b, c)");
1268 EXPECT_EQUAL(Floor(a), "floor(a)");
1269 EXPECT_EQUAL(Fract(a), "fract(a)");
1270 EXPECT_EQUAL(GreaterThan(a, b), "greaterThan(a, b)");
1271 EXPECT_EQUAL(GreaterThanEqual(a, b), "greaterThanEqual(a, b)");
1272 EXPECT_EQUAL(Inversesqrt(a), "inversesqrt(a)");
1273 EXPECT_EQUAL(LessThan(a, b), "lessThan(a, b)");
1274 EXPECT_EQUAL(LessThanEqual(a, b), "lessThanEqual(a, b)");
1275 EXPECT_EQUAL(Length(a), "length(a)");
1276 EXPECT_EQUAL(Log(a), "log(a)");
1277 EXPECT_EQUAL(Log2(a), "log2(a)");
1278 EXPECT_EQUAL(Max(a, b), "max(a, b)");
1279 EXPECT_EQUAL(Min(a, b), "min(a, b)");
1280 EXPECT_EQUAL(Mix(a, b, c), "mix(a, b, c)");
1281 EXPECT_EQUAL(Mod(a, b), "mod(a, b)");
1282 EXPECT_EQUAL(Normalize(a), "normalize(a)");
1283 EXPECT_EQUAL(NotEqual(a, b), "notEqual(a, b)");
1284 EXPECT_EQUAL(Pow(a, b), "pow(a, b)");
1285 EXPECT_EQUAL(Radians(a), "radians(a)");
1286 EXPECT_EQUAL(Reflect(a, b), "reflect(a, b)");
1287 EXPECT_EQUAL(Refract(a, b, 1), "refract(a, b, 1.0)");
1288 EXPECT_EQUAL(Saturate(a), "saturate(a)");
1289 EXPECT_EQUAL(Sign(a), "sign(a)");
1290 EXPECT_EQUAL(Sin(a), "sin(a)");
1291 EXPECT_EQUAL(Smoothstep(a, b, c), "smoothstep(a, b, c)");
1292 EXPECT_EQUAL(Sqrt(a), "sqrt(a)");
1293 EXPECT_EQUAL(Step(a, b), "step(a, b)");
1294 EXPECT_EQUAL(Tan(a), "tan(a)");
1295 EXPECT_EQUAL(Unpremul(a), "unpremul(a)");
Ethan Nicholas30e93d52021-01-26 12:00:25 -05001296
1297 // these calls all go through the normal channels, so it ought to be sufficient to prove that
1298 // one of them reports errors correctly
1299 {
1300 ExpectError error(r, "error: no match for ceil(bool)\n");
1301 Ceil(a == b).release();
1302 }
1303}
Ethan Nicholasd6b26e52021-01-27 07:53:46 -05001304
1305DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLModifiers, r, ctxInfo) {
1306 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1307
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001308 Var v1(kConst_Modifier, kInt, "v1", 0);
1309 Statement d1 = Declare(v1);
Ethan Nicholasbd974002021-02-22 16:20:06 -05001310 EXPECT_EQUAL(d1, "const int v1 = 0;");
Ethan Nicholasd6b26e52021-01-27 07:53:46 -05001311
1312 // Most modifiers require an appropriate context to be legal. We can't yet give them that
1313 // context, so we can't as yet Declare() variables with these modifiers.
1314 // TODO: better tests when able
1315 Var v2(kIn_Modifier, kInt, "v2");
1316 REPORTER_ASSERT(r, DSLWriter::Var(v2).modifiers().fFlags == SkSL::Modifiers::kIn_Flag);
1317
1318 Var v3(kOut_Modifier, kInt, "v3");
1319 REPORTER_ASSERT(r, DSLWriter::Var(v3).modifiers().fFlags == SkSL::Modifiers::kOut_Flag);
1320
Ethan Nicholas11a15b12021-02-11 15:56:27 -05001321 Var v4(kFlat_Modifier, kInt, "v4");
1322 REPORTER_ASSERT(r, DSLWriter::Var(v4).modifiers().fFlags == SkSL::Modifiers::kFlat_Flag);
Ethan Nicholasd6b26e52021-01-27 07:53:46 -05001323
Ethan Nicholas11a15b12021-02-11 15:56:27 -05001324 Var v5(kNoPerspective_Modifier, kInt, "v5");
1325 REPORTER_ASSERT(r, DSLWriter::Var(v5).modifiers().fFlags ==
Ethan Nicholasd6b26e52021-01-27 07:53:46 -05001326 SkSL::Modifiers::kNoPerspective_Flag);
1327
Ethan Nicholas11a15b12021-02-11 15:56:27 -05001328 Var v6(kIn_Modifier | kOut_Modifier, kInt, "v6");
1329 REPORTER_ASSERT(r, DSLWriter::Var(v6).modifiers().fFlags ==
1330 (SkSL::Modifiers::kIn_Flag | SkSL::Modifiers::kOut_Flag));
1331
1332 Var v7(kInOut_Modifier, kInt, "v7");
Ethan Nicholasd6b26e52021-01-27 07:53:46 -05001333 REPORTER_ASSERT(r, DSLWriter::Var(v7).modifiers().fFlags ==
1334 (SkSL::Modifiers::kIn_Flag | SkSL::Modifiers::kOut_Flag));
1335
Ethan Nicholas11a15b12021-02-11 15:56:27 -05001336 Var v8(kUniform_Modifier, kInt, "v8");
1337 REPORTER_ASSERT(r, DSLWriter::Var(v8).modifiers().fFlags == SkSL::Modifiers::kUniform_Flag);
Ethan Nicholasd6b26e52021-01-27 07:53:46 -05001338}
Ethan Nicholasbf79dff2021-02-11 15:18:31 -05001339
1340DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStruct, r, ctxInfo) {
1341 AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1342
1343 DSLType simpleStruct = Struct("SimpleStruct",
1344 Field(kFloat, "x"),
1345 Field(kBool, "b"),
1346 Field(Array(kFloat, 3), "a")
1347 );
1348 DSLVar result(simpleStruct, "result");
1349 DSLFunction(simpleStruct, "returnStruct").define(
1350 Declare(result),
1351 result.field("x") = 123,
1352 result.field("b") = result.field("x") > 0,
1353 result.field("a")[0] = result.field("x"),
1354 Return(result)
1355 );
1356 REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
John Stilesb4d7b582021-02-19 09:56:31 -05001357 EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
1358 "struct SimpleStruct { float x; bool b; float[3] a; };");
1359 EXPECT_EQUAL(*DSLWriter::ProgramElements()[1],
1360 "SimpleStruct returnStruct() { SimpleStruct result; (result.x = 123.0);"
1361 "(result.b = (result.x > 0.0)); (result.a[0] = result.x); return result; }");
Ethan Nicholasbf79dff2021-02-11 15:18:31 -05001362
Ethan Nicholasbf79dff2021-02-11 15:18:31 -05001363 Struct("NestedStruct",
1364 Field(kInt, "x"),
1365 Field(simpleStruct, "simple")
1366 );
Ethan Nicholasfe5d6922021-03-05 14:23:48 -05001367 REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 3);
1368 EXPECT_EQUAL(*DSLWriter::ProgramElements()[2],
John Stilesb4d7b582021-02-19 09:56:31 -05001369 "struct NestedStruct { int x; SimpleStruct simple; };");
Ethan Nicholasbf79dff2021-02-11 15:18:31 -05001370}