• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 "include/private/SkSLIRNode.h"
9 #include "include/sksl/DSL.h"
10 #include "src/gpu/GrDirectContextPriv.h"
11 #include "src/gpu/GrGpu.h"
12 #include "src/sksl/SkSLIRGenerator.h"
13 #include "src/sksl/dsl/priv/DSLWriter.h"
14 
15 #include "tests/Test.h"
16 
17 #include <limits>
18 
19 using namespace SkSL::dsl;
20 
21 constexpr int kDefaultTestFlags = (kDefaultDSLFlags & ~kMangle_Flag) | kMarkVarsDeclared_Flag;
22 constexpr int kNoDeclareTestFlags = kDefaultDSLFlags & ~kMangle_Flag;
23 
24 /**
25  * In addition to issuing an automatic Start() and End(), disables mangling and optionally
26  * auto-declares variables during its lifetime. Variable auto-declaration simplifies testing so we
27  * don't have to sprinkle all the tests with a bunch of Declare(foo).release() calls just to avoid
28  * errors, especially given that some of the variables have options that make them an error to
29  * actually declare.
30  */
31 class AutoDSLContext {
32 public:
AutoDSLContext(GrGpu * gpu,int flags=kDefaultTestFlags,SkSL::ProgramKind kind=SkSL::ProgramKind::kFragment)33     AutoDSLContext(GrGpu* gpu, int flags = kDefaultTestFlags,
34                    SkSL::ProgramKind kind = SkSL::ProgramKind::kFragment) {
35         Start(gpu->shaderCompiler(), kind, flags);
36     }
37 
~AutoDSLContext()38     ~AutoDSLContext() {
39         End();
40     }
41 };
42 
43 class ExpectError : public ErrorHandler {
44 public:
ExpectError(skiatest::Reporter * reporter,const char * msg)45     ExpectError(skiatest::Reporter* reporter, const char* msg)
46         : fMsg(msg)
47         , fReporter(reporter) {
48         SetErrorHandler(this);
49     }
50 
~ExpectError()51     ~ExpectError() override {
52         REPORTER_ASSERT(fReporter, !fMsg,
53                         "Error mismatch: expected:\n%sbut no error occurred\n", fMsg);
54         SetErrorHandler(nullptr);
55     }
56 
handleError(const char * msg,PositionInfo * pos)57     void handleError(const char* msg, PositionInfo* pos) override {
58         REPORTER_ASSERT(fReporter, !strcmp(msg, fMsg),
59                         "Error mismatch: expected:\n%sbut received:\n%s", fMsg, msg);
60         fMsg = nullptr;
61     }
62 
63 private:
64     const char* fMsg;
65     skiatest::Reporter* fReporter;
66 };
67 
whitespace_insensitive_compare(const char * a,const char * b)68 static bool whitespace_insensitive_compare(const char* a, const char* b) {
69     for (;;) {
70         while (isspace(*a)) {
71             ++a;
72         }
73         while (isspace(*b)) {
74             ++b;
75         }
76         if (*a != *b) {
77             return false;
78         }
79         if (*a == 0) {
80             return true;
81         }
82         ++a;
83         ++b;
84     }
85 }
86 
87 // for use from SkSLDSLOnlyTest.cpp
StartDSL(const sk_gpu_test::ContextInfo ctxInfo)88 void StartDSL(const sk_gpu_test::ContextInfo ctxInfo) {
89     Start(ctxInfo.directContext()->priv().getGpu()->shaderCompiler());
90 }
91 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStartup,r,ctxInfo)92 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStartup, r, ctxInfo) {
93     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
94     Expression e1 = 1;
95     REPORTER_ASSERT(r, e1.release()->description() == "1");
96     Expression e2 = 1.0;
97     REPORTER_ASSERT(r, e2.release()->description() == "1.0");
98     Expression e3 = true;
99     REPORTER_ASSERT(r, e3.release()->description() == "true");
100     Var a(kInt_Type, "a");
101     Expression e4 = a;
102     REPORTER_ASSERT(r, e4.release()->description() == "a");
103 
104     REPORTER_ASSERT(r, whitespace_insensitive_compare("", ""));
105     REPORTER_ASSERT(r, !whitespace_insensitive_compare("", "a"));
106     REPORTER_ASSERT(r, !whitespace_insensitive_compare("a", ""));
107     REPORTER_ASSERT(r, whitespace_insensitive_compare("a", "a"));
108     REPORTER_ASSERT(r, whitespace_insensitive_compare("abc", "abc"));
109     REPORTER_ASSERT(r, whitespace_insensitive_compare("abc", " abc "));
110     REPORTER_ASSERT(r, whitespace_insensitive_compare("a b  c  ", "\n\n\nabc"));
111     REPORTER_ASSERT(r, !whitespace_insensitive_compare("a b c  d", "\n\n\nabc"));
112 }
113 
stringize(DSLStatement & stmt)114 static SkSL::String stringize(DSLStatement& stmt)          { return stmt.release()->description(); }
stringize(DSLPossibleStatement & stmt)115 static SkSL::String stringize(DSLPossibleStatement& stmt)  { return stmt.release()->description(); }
stringize(DSLExpression & expr)116 static SkSL::String stringize(DSLExpression& expr)         { return expr.release()->description(); }
stringize(DSLPossibleExpression & expr)117 static SkSL::String stringize(DSLPossibleExpression& expr) { return expr.release()->description(); }
stringize(DSLBlock & blck)118 static SkSL::String stringize(DSLBlock& blck)              { return blck.release()->description(); }
stringize(SkSL::IRNode & node)119 static SkSL::String stringize(SkSL::IRNode& node)  { return node.description(); }
120 
121 template <typename T>
expect_equal(skiatest::Reporter * r,int lineNumber,T & input,const char * expected)122 static void expect_equal(skiatest::Reporter* r, int lineNumber, T& input, const char* expected) {
123     SkSL::String actual = stringize(input);
124     if (!whitespace_insensitive_compare(expected, actual.c_str())) {
125         ERRORF(r, "(Failed on line %d)\nExpected: %s\n  Actual: %s\n",
126                   lineNumber, expected, actual.c_str());
127     }
128 }
129 
130 template <typename T>
expect_equal(skiatest::Reporter * r,int lineNumber,T && dsl,const char * expected)131 static void expect_equal(skiatest::Reporter* r, int lineNumber, T&& dsl, const char* expected) {
132     // This overload allows temporary values to be passed to expect_equal.
133     return expect_equal(r, lineNumber, dsl, expected);
134 }
135 
136 #define EXPECT_EQUAL(a, b)  expect_equal(r, __LINE__, (a), (b))
137 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFlags,r,ctxInfo)138 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFlags, r, ctxInfo) {
139     {
140         AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kOptimize_Flag);
141         EXPECT_EQUAL(All(GreaterThan(Float4(1), Float4(0))), "true");
142 
143         Var x(kInt_Type, "x");
144         EXPECT_EQUAL(Declare(x), "int x;");
145     }
146 
147     {
148         AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNo_Flag);
149         EXPECT_EQUAL(All(GreaterThan(Float4(1), Float4(0))),
150                      "all(greaterThan(float4(1.0), float4(0.0)))");
151     }
152 
153     {
154         AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kMangle_Flag);
155         Var x(kInt_Type, "x");
156         EXPECT_EQUAL(Declare(x), "int _0_x;");
157     }
158 }
159 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFloat,r,ctxInfo)160 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFloat, r, ctxInfo) {
161     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
162     Expression e1 = Float(std::numeric_limits<float>::max());
163     REPORTER_ASSERT(r, atof(e1.release()->description().c_str()) ==
164                        std::numeric_limits<float>::max());
165 
166     Expression e2 = Float(std::numeric_limits<float>::min());
167     REPORTER_ASSERT(r, atof(e2.release()->description().c_str()) ==
168                        std::numeric_limits<float>::min());
169 
170     EXPECT_EQUAL(Float2(0),
171                 "float2(0.0)");
172     EXPECT_EQUAL(Float2(-0.5, 1),
173                 "float2(-0.5, 1.0)");
174     EXPECT_EQUAL(Float3(0.75),
175                 "float3(0.75)");
176     EXPECT_EQUAL(Float3(Float2(0, 1), -2),
177                 "float3(0.0, 1.0, -2.0)");
178     EXPECT_EQUAL(Float3(0, 1, 2),
179                 "float3(0.0, 1.0, 2.0)");
180     EXPECT_EQUAL(Float4(0),
181                 "float4(0.0)");
182     EXPECT_EQUAL(Float4(Float2(0, 1), Float2(2, 3)),
183                 "float4(0.0, 1.0, 2.0, 3.0)");
184     EXPECT_EQUAL(Float4(0, 1, Float2(2, 3)),
185                 "float4(0.0, 1.0, 2.0, 3.0)");
186     EXPECT_EQUAL(Float4(0, 1, 2, 3),
187                 "float4(0.0, 1.0, 2.0, 3.0)");
188 
189     DSLVar x(kFloat_Type, "x");
190     EXPECT_EQUAL(x = 1.0, "(x = 1.0)");
191     EXPECT_EQUAL(x = 1.0f, "(x = 1.0)");
192 
193     DSLVar y(kFloat2_Type, "y");
194     EXPECT_EQUAL(y.x() = 1.0, "(y.x = 1.0)");
195     EXPECT_EQUAL(y.x() = 1.0f, "(y.x = 1.0)");
196 
197     {
198         ExpectError error(r, "error: floating point value is infinite\n");
199         Float(std::numeric_limits<float>::infinity()).release();
200     }
201 
202     {
203         ExpectError error(r, "error: floating point value is NaN\n");
204         Float(std::numeric_limits<float>::quiet_NaN()).release();
205     }
206 
207     {
208         ExpectError error(r, "error: invalid arguments to 'float2' constructor (expected 2 scalars,"
209                              " but found 4)\n");
210         Float2(Float4(1)).release();
211     }
212 
213     {
214         ExpectError error(r, "error: invalid arguments to 'float4' constructor (expected 4 scalars,"
215                              " but found 3)\n");
216         Float4(Float3(1)).release();
217     }
218 }
219 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLHalf,r,ctxInfo)220 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLHalf, r, ctxInfo) {
221     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
222     Expression e1 = Half(std::numeric_limits<float>::max());
223     REPORTER_ASSERT(r,
224                     atof(e1.release()->description().c_str()) == std::numeric_limits<float>::max());
225 
226     Expression e2 = Half(std::numeric_limits<float>::min());
227     REPORTER_ASSERT(r,
228                     atof(e2.release()->description().c_str()) == std::numeric_limits<float>::min());
229 
230     EXPECT_EQUAL(Half2(0),
231                 "half2(0.0)");
232     EXPECT_EQUAL(Half2(-0.5, 1),
233                 "half2(-0.5, 1.0)");
234     EXPECT_EQUAL(Half3(0.75),
235                 "half3(0.75)");
236     EXPECT_EQUAL(Half3(Half2(0, 1), -2),
237                 "half3(0.0, 1.0, -2.0)");
238     EXPECT_EQUAL(Half3(0, 1, 2),
239                 "half3(0.0, 1.0, 2.0)");
240     EXPECT_EQUAL(Half4(0),
241                 "half4(0.0)");
242     EXPECT_EQUAL(Half4(Half2(0, 1), Half2(2, 3)),
243                 "half4(0.0, 1.0, 2.0, 3.0)");
244     EXPECT_EQUAL(Half4(0, 1, Half2(2, 3)),
245                 "half4(0.0, 1.0, 2.0, 3.0)");
246     EXPECT_EQUAL(Half4(0, 1, 2, 3),
247                 "half4(0.0, 1.0, 2.0, 3.0)");
248 
249     {
250         ExpectError error(r, "error: floating point value is infinite\n");
251         Half(std::numeric_limits<float>::infinity()).release();
252     }
253 
254     {
255         ExpectError error(r, "error: floating point value is NaN\n");
256         Half(std::numeric_limits<float>::quiet_NaN()).release();
257     }
258 
259     {
260         ExpectError error(r, "error: invalid arguments to 'half2' constructor (expected 2 scalars,"
261                              " but found 4)\n");
262         Half2(Half4(1)).release();
263     }
264 
265     {
266         ExpectError error(r, "error: invalid arguments to 'half4' constructor (expected 4 scalars,"
267                              " but found 3)\n");
268         Half4(Half3(1)).release();
269     }
270 }
271 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInt,r,ctxInfo)272 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInt, r, ctxInfo) {
273     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
274 
275     EXPECT_EQUAL(Int(std::numeric_limits<int32_t>::max()),
276                 "2147483647");
277     EXPECT_EQUAL(Int2(std::numeric_limits<int32_t>::min()),
278                 "int2(-2147483648)");
279     EXPECT_EQUAL(Int2(0, 1),
280                 "int2(0, 1)");
281     EXPECT_EQUAL(Int3(0),
282                 "int3(0)");
283     EXPECT_EQUAL(Int3(Int2(0, 1), -2),
284                 "int3(0, 1, -2)");
285     EXPECT_EQUAL(Int3(0, 1, 2),
286                 "int3(0, 1, 2)");
287     EXPECT_EQUAL(Int4(0),
288                 "int4(0)");
289     EXPECT_EQUAL(Int4(Int2(0, 1), Int2(2, 3)),
290                 "int4(0, 1, 2, 3)");
291     EXPECT_EQUAL(Int4(0, 1, Int2(2, 3)),
292                 "int4(0, 1, 2, 3)");
293     EXPECT_EQUAL(Int4(0, 1, 2, 3),
294                 "int4(0, 1, 2, 3)");
295 
296     {
297         ExpectError error(r, "error: invalid arguments to 'int2' constructor (expected 2 scalars,"
298                              " but found 4)\n");
299         Int2(Int4(1)).release();
300     }
301 
302     {
303         ExpectError error(r, "error: invalid arguments to 'int4' constructor (expected 4 scalars,"
304                              " but found 3)\n");
305         Int4(Int3(1)).release();
306     }
307 }
308 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLUInt,r,ctxInfo)309 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLUInt, r, ctxInfo) {
310     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
311 
312     EXPECT_EQUAL(UInt(std::numeric_limits<uint32_t>::max()),
313                 "4294967295");
314     EXPECT_EQUAL(UInt2(std::numeric_limits<uint32_t>::min()),
315                 "uint2(0)");
316     EXPECT_EQUAL(UInt2(0, 1),
317                 "uint2(0, 1)");
318     EXPECT_EQUAL(UInt3(0),
319                 "uint3(0)");
320     EXPECT_EQUAL(UInt3(UInt2(0, 1), -2),
321                 "uint3(0, 1, -2)");
322     EXPECT_EQUAL(UInt3(0, 1, 2),
323                 "uint3(0, 1, 2)");
324     EXPECT_EQUAL(UInt4(0),
325                 "uint4(0)");
326     EXPECT_EQUAL(UInt4(UInt2(0, 1), UInt2(2, 3)),
327                 "uint4(0, 1, 2, 3)");
328     EXPECT_EQUAL(UInt4(0, 1, UInt2(2, 3)),
329                 "uint4(0, 1, 2, 3)");
330     EXPECT_EQUAL(UInt4(0, 1, 2, 3),
331                 "uint4(0, 1, 2, 3)");
332 
333     {
334         ExpectError error(r, "error: invalid arguments to 'uint2' constructor (expected 2 scalars,"
335                              " but found 4)\n");
336         UInt2(UInt4(1)).release();
337     }
338 
339     {
340         ExpectError error(r, "error: invalid arguments to 'uint4' constructor (expected 4 scalars,"
341                              " but found 3)\n");
342         UInt4(UInt3(1)).release();
343     }
344 }
345 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShort,r,ctxInfo)346 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShort, r, ctxInfo) {
347     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
348 
349     EXPECT_EQUAL(Short(std::numeric_limits<int16_t>::max()),
350                 "32767");
351     EXPECT_EQUAL(Short2(std::numeric_limits<int16_t>::min()),
352                 "short2(-32768)");
353     EXPECT_EQUAL(Short2(0, 1),
354                 "short2(0, 1)");
355     EXPECT_EQUAL(Short3(0),
356                 "short3(0)");
357     EXPECT_EQUAL(Short3(Short2(0, 1), -2),
358                 "short3(0, 1, -2)");
359     EXPECT_EQUAL(Short3(0, 1, 2),
360                 "short3(0, 1, 2)");
361     EXPECT_EQUAL(Short4(0),
362                 "short4(0)");
363     EXPECT_EQUAL(Short4(Short2(0, 1), Short2(2, 3)),
364                 "short4(0, 1, 2, 3)");
365     EXPECT_EQUAL(Short4(0, 1, Short2(2, 3)),
366                 "short4(0, 1, 2, 3)");
367     EXPECT_EQUAL(Short4(0, 1, 2, 3),
368                 "short4(0, 1, 2, 3)");
369 
370     {
371         ExpectError error(r, "error: invalid arguments to 'short2' constructor (expected 2 scalars,"
372                              " but found 4)\n");
373         Short2(Short4(1)).release();
374     }
375 
376     {
377         ExpectError error(r, "error: invalid arguments to 'short4' constructor (expected 4 scalars,"
378                              " but found 3)\n");
379         Short4(Short3(1)).release();
380     }
381 }
382 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLUShort,r,ctxInfo)383 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLUShort, r, ctxInfo) {
384     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
385 
386     EXPECT_EQUAL(UShort(std::numeric_limits<uint16_t>::max()),
387                 "65535");
388     EXPECT_EQUAL(UShort2(std::numeric_limits<uint16_t>::min()),
389                 "ushort2(0)");
390     EXPECT_EQUAL(UShort2(0, 1),
391                 "ushort2(0, 1)");
392     EXPECT_EQUAL(UShort3(0),
393                 "ushort3(0)");
394     EXPECT_EQUAL(UShort3(UShort2(0, 1), -2),
395                 "ushort3(0, 1, -2)");
396     EXPECT_EQUAL(UShort3(0, 1, 2),
397                 "ushort3(0, 1, 2)");
398     EXPECT_EQUAL(UShort4(0),
399                 "ushort4(0)");
400     EXPECT_EQUAL(UShort4(UShort2(0, 1), UShort2(2, 3)),
401                 "ushort4(0, 1, 2, 3)");
402     EXPECT_EQUAL(UShort4(0, 1, UShort2(2, 3)),
403                 "ushort4(0, 1, 2, 3)");
404     EXPECT_EQUAL(UShort4(0, 1, 2, 3),
405                 "ushort4(0, 1, 2, 3)");
406 
407     {
408         ExpectError error(r, "error: invalid arguments to 'ushort2' constructor (expected 2 "
409                              "scalars, but found 4)\n");
410         UShort2(UShort4(1)).release();
411     }
412 
413     {
414         ExpectError error(r, "error: invalid arguments to 'ushort4' constructor (expected 4 "
415                              "scalars, but found 3)\n");
416         UShort4(UShort3(1)).release();
417     }
418 }
419 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBool,r,ctxInfo)420 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBool, r, ctxInfo) {
421     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
422 
423     EXPECT_EQUAL(Bool2(false),
424                 "bool2(false)");
425     EXPECT_EQUAL(Bool2(false, true),
426                 "bool2(false, true)");
427     EXPECT_EQUAL(Bool3(false),
428                 "bool3(false)");
429     EXPECT_EQUAL(Bool3(Bool2(false, true), false),
430                 "bool3(false, true, false)");
431     EXPECT_EQUAL(Bool3(false, true, false),
432                 "bool3(false, true, false)");
433     EXPECT_EQUAL(Bool4(false),
434                 "bool4(false)");
435     EXPECT_EQUAL(Bool4(Bool2(false, true), Bool2(false, true)),
436                 "bool4(false, true, false, true)");
437     EXPECT_EQUAL(Bool4(false, true, Bool2(false, true)),
438                 "bool4(false, true, false, true)");
439     EXPECT_EQUAL(Bool4(false, true, false, true),
440                 "bool4(false, true, false, true)");
441 
442     {
443         ExpectError error(r, "error: invalid arguments to 'bool2' constructor (expected 2 scalars,"
444                              " but found 4)\n");
445         Bool2(Bool4(true)).release();
446     }
447 
448     {
449         ExpectError error(r, "error: invalid arguments to 'bool4' constructor (expected 4 scalars,"
450                              " but found 3)\n");
451         Bool4(Bool3(true)).release();
452     }
453 }
454 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLType,r,ctxInfo)455 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLType, r, ctxInfo) {
456     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
457     REPORTER_ASSERT(r,  DSLType(kBool_Type).isBoolean());
458     REPORTER_ASSERT(r, !DSLType(kBool_Type).isNumber());
459     REPORTER_ASSERT(r, !DSLType(kBool_Type).isFloat());
460     REPORTER_ASSERT(r, !DSLType(kBool_Type).isSigned());
461     REPORTER_ASSERT(r, !DSLType(kBool_Type).isUnsigned());
462     REPORTER_ASSERT(r, !DSLType(kBool_Type).isInteger());
463     REPORTER_ASSERT(r,  DSLType(kBool_Type).isScalar());
464     REPORTER_ASSERT(r, !DSLType(kBool_Type).isVector());
465     REPORTER_ASSERT(r, !DSLType(kBool_Type).isMatrix());
466     REPORTER_ASSERT(r, !DSLType(kBool_Type).isArray());
467     REPORTER_ASSERT(r, !DSLType(kBool_Type).isStruct());
468 
469     REPORTER_ASSERT(r, !DSLType(kInt_Type).isBoolean());
470     REPORTER_ASSERT(r,  DSLType(kInt_Type).isNumber());
471     REPORTER_ASSERT(r, !DSLType(kInt_Type).isFloat());
472     REPORTER_ASSERT(r,  DSLType(kInt_Type).isSigned());
473     REPORTER_ASSERT(r, !DSLType(kInt_Type).isUnsigned());
474     REPORTER_ASSERT(r,  DSLType(kInt_Type).isInteger());
475     REPORTER_ASSERT(r,  DSLType(kInt_Type).isScalar());
476     REPORTER_ASSERT(r, !DSLType(kInt_Type).isVector());
477     REPORTER_ASSERT(r, !DSLType(kInt_Type).isMatrix());
478     REPORTER_ASSERT(r, !DSLType(kInt_Type).isArray());
479     REPORTER_ASSERT(r, !DSLType(kInt_Type).isStruct());
480 
481     REPORTER_ASSERT(r, !DSLType(kUInt_Type).isBoolean());
482     REPORTER_ASSERT(r,  DSLType(kUInt_Type).isNumber());
483     REPORTER_ASSERT(r, !DSLType(kUInt_Type).isFloat());
484     REPORTER_ASSERT(r, !DSLType(kUInt_Type).isSigned());
485     REPORTER_ASSERT(r,  DSLType(kUInt_Type).isUnsigned());
486     REPORTER_ASSERT(r,  DSLType(kUInt_Type).isInteger());
487     REPORTER_ASSERT(r,  DSLType(kUInt_Type).isScalar());
488     REPORTER_ASSERT(r, !DSLType(kUInt_Type).isVector());
489     REPORTER_ASSERT(r, !DSLType(kUInt_Type).isMatrix());
490     REPORTER_ASSERT(r, !DSLType(kUInt_Type).isArray());
491     REPORTER_ASSERT(r, !DSLType(kUInt_Type).isStruct());
492 
493     REPORTER_ASSERT(r, !DSLType(kFloat_Type).isBoolean());
494     REPORTER_ASSERT(r,  DSLType(kFloat_Type).isNumber());
495     REPORTER_ASSERT(r,  DSLType(kFloat_Type).isFloat());
496     REPORTER_ASSERT(r, !DSLType(kFloat_Type).isSigned());
497     REPORTER_ASSERT(r, !DSLType(kFloat_Type).isUnsigned());
498     REPORTER_ASSERT(r, !DSLType(kFloat_Type).isInteger());
499     REPORTER_ASSERT(r,  DSLType(kFloat_Type).isScalar());
500     REPORTER_ASSERT(r, !DSLType(kFloat_Type).isVector());
501     REPORTER_ASSERT(r, !DSLType(kFloat_Type).isMatrix());
502     REPORTER_ASSERT(r, !DSLType(kFloat_Type).isArray());
503     REPORTER_ASSERT(r, !DSLType(kFloat_Type).isStruct());
504 
505     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isBoolean());
506     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isNumber());
507     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isFloat());
508     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isSigned());
509     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isUnsigned());
510     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isInteger());
511     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isScalar());
512     REPORTER_ASSERT(r,  DSLType(kFloat2_Type).isVector());
513     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isMatrix());
514     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isArray());
515     REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isStruct());
516 
517     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isBoolean());
518     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isNumber());
519     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isFloat());
520     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isSigned());
521     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isUnsigned());
522     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isInteger());
523     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isScalar());
524     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isVector());
525     REPORTER_ASSERT(r,  DSLType(kHalf2x2_Type).isMatrix());
526     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isArray());
527     REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isStruct());
528 
529     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isBoolean());
530     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isNumber());
531     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isFloat());
532     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isSigned());
533     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isUnsigned());
534     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isInteger());
535     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isScalar());
536     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isVector());
537     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isMatrix());
538     REPORTER_ASSERT(r,  DSLType(Array(kFloat_Type, 2)).isArray());
539     REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isStruct());
540 
541     Var x(kFloat_Type);
542     DSLExpression e = x + 1;
543     REPORTER_ASSERT(r, e.type().isFloat());
544     e.release();
545 }
546 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMatrices,r,ctxInfo)547 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMatrices, r, ctxInfo) {
548     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
549     Var f22(kFloat2x2_Type, "f22");
550     EXPECT_EQUAL(f22 = Float2x2(1), "(f22 = float2x2(1.0))");
551     Var f32(kFloat3x2_Type, "f32");
552     EXPECT_EQUAL(f32 = Float3x2(1, 2, 3, 4, 5, 6),
553                  "(f32 = float3x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))");
554     Var f42(kFloat4x2_Type, "f42");
555     EXPECT_EQUAL(f42 = Float4x2(Float4(1, 2, 3, 4), 5, 6, 7, 8),
556                  "(f42 = float4x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0))");
557     Var f23(kFloat2x3_Type, "f23");
558     EXPECT_EQUAL(f23 = Float2x3(1, Float2(2, 3), 4, Float2(5, 6)),
559                  "(f23 = float2x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))");
560     Var f33(kFloat3x3_Type, "f33");
561     EXPECT_EQUAL(f33 = Float3x3(Float3(1, 2, 3), 4, Float2(5, 6), 7, 8, 9),
562                  "(f33 = float3x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0))");
563     Var f43(kFloat4x3_Type, "f43");
564     EXPECT_EQUAL(f43 = Float4x3(Float4(1, 2, 3, 4), Float4(5, 6, 7, 8), Float4(9, 10, 11, 12)),
565                  "(f43 = float4x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0))");
566     Var f24(kFloat2x4_Type, "f24");
567     EXPECT_EQUAL(f24 = Float2x4(1, 2, 3, 4, 5, 6, 7, 8),
568                  "(f24 = float2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0))");
569     Var f34(kFloat3x4_Type, "f34");
570     EXPECT_EQUAL(f34 = Float3x4(1, 2, 3, 4, 5, 6, 7, 8, 9, Float3(10, 11, 12)),
571                  "(f34 = float3x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0))");
572     Var f44(kFloat4x4_Type, "f44");
573     EXPECT_EQUAL(f44 = Float4x4(1), "(f44 = float4x4(1.0))");
574 
575     Var h22(kHalf2x2_Type, "h22");
576     EXPECT_EQUAL(h22 = Half2x2(1), "(h22 = half2x2(1.0))");
577     Var h32(kHalf3x2_Type, "h32");
578     EXPECT_EQUAL(h32 = Half3x2(1, 2, 3, 4, 5, 6),
579                  "(h32 = half3x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))");
580     Var h42(kHalf4x2_Type, "h42");
581     EXPECT_EQUAL(h42 = Half4x2(Half4(1, 2, 3, 4), 5, 6, 7, 8),
582                  "(h42 = half4x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0))");
583     Var h23(kHalf2x3_Type, "h23");
584     EXPECT_EQUAL(h23 = Half2x3(1, Half2(2, 3), 4, Half2(5, 6)),
585                  "(h23 = half2x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))");
586     Var h33(kHalf3x3_Type, "h33");
587     EXPECT_EQUAL(h33 = Half3x3(Half3(1, 2, 3), 4, Half2(5, 6), 7, 8, 9),
588                  "(h33 = half3x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0))");
589     Var h43(kHalf4x3_Type, "h43");
590     EXPECT_EQUAL(h43 = Half4x3(Half4(1, 2, 3, 4), Half4(5, 6, 7, 8), Half4(9, 10, 11, 12)),
591                  "(h43 = half4x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0))");
592     Var h24(kHalf2x4_Type, "h24");
593     EXPECT_EQUAL(h24 = Half2x4(1, 2, 3, 4, 5, 6, 7, 8),
594                  "(h24 = half2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0))");
595     Var h34(kHalf3x4_Type, "h34");
596     EXPECT_EQUAL(h34 = Half3x4(1, 2, 3, 4, 5, 6, 7, 8, 9, Half3(10, 11, 12)),
597                  "(h34 = half3x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0))");
598     Var h44(kHalf4x4_Type, "h44");
599     EXPECT_EQUAL(h44 = Half4x4(1), "(h44 = half4x4(1.0))");
600 
601     EXPECT_EQUAL(f22 * 2, "(f22 * 2.0)");
602     EXPECT_EQUAL(f22 == Float2x2(1), "(f22 == float2x2(1.0))");
603     EXPECT_EQUAL(h42[0][1], "h42[0].y");
604     EXPECT_EQUAL(f43 * Float4(0), "(f43 * float4(0.0))");
605     EXPECT_EQUAL(h23 * 2, "(h23 * 2.0)");
606     EXPECT_EQUAL(Inverse(f44), "inverse(f44)");
607 
608     {
609         ExpectError error(r, "error: invalid arguments to 'float3x3' constructor (expected 9 "
610                              "scalars, but found 2)\n");
611         DSLExpression(Float3x3(Float2(1))).release();
612     }
613 
614     {
615         ExpectError error(r, "error: invalid arguments to 'half2x2' constructor (expected 4 "
616                              "scalars, but found 5)\n");
617         DSLExpression(Half2x2(1, 2, 3, 4, 5)).release();
618     }
619 
620     {
621         ExpectError error(r, "error: type mismatch: '*' cannot operate on 'float4x3', 'float3'\n");
622         DSLExpression(f43 * Float3(1)).release();
623     }
624 
625     {
626         ExpectError error(r, "error: type mismatch: '=' cannot operate on 'float4x3', "
627                              "'float3x3'\n");
628         DSLExpression(f43 = f33).release();
629     }
630 
631     {
632         ExpectError error(r, "error: type mismatch: '=' cannot operate on 'half2x2', "
633                              "'float2x2'\n");
634         DSLExpression(h22 = f22).release();
635     }
636 
637     {
638         ExpectError error(r,
639                           "error: no match for inverse(float4x3)\n");
640         DSLExpression(Inverse(f43)).release();
641     }
642 }
643 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLPlus,r,ctxInfo)644 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLPlus, r, ctxInfo) {
645     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
646     Var a(kFloat_Type, "a"), b(kFloat_Type, "b");
647 
648     EXPECT_EQUAL(a + b,
649                "(a + b)");
650     EXPECT_EQUAL(a + 1,
651                "(a + 1.0)");
652     EXPECT_EQUAL(0.5 + a + -99,
653               "((0.5 + a) + -99.0)");
654     EXPECT_EQUAL(a += b + 1,
655                "(a += (b + 1.0))");
656     EXPECT_EQUAL(+a,
657                  "a");
658     EXPECT_EQUAL(+(a + b),
659                  "(a + b)");
660 
661     {
662         ExpectError error(r, "error: type mismatch: '+' cannot operate on 'bool2', 'float'\n");
663         DSLExpression((Bool2(true) + a)).release();
664     }
665 
666     {
667         ExpectError error(r, "error: type mismatch: '+=' cannot operate on 'float', 'bool2'\n");
668         DSLExpression((a += Bool2(true))).release();
669     }
670 
671     {
672         ExpectError error(r, "error: cannot assign to this expression\n");
673         DSLExpression((1.0 += a)).release();
674     }
675 
676     {
677         ExpectError error(r, "error: '+' cannot operate on 'bool'\n");
678         Var c(kBool_Type);
679         DSLExpression(+c);
680     }
681 }
682 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMinus,r,ctxInfo)683 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMinus, r, ctxInfo) {
684     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
685     Var a(kInt_Type, "a"), b(kInt_Type, "b");
686 
687     EXPECT_EQUAL(a - b,
688                "(a - b)");
689     EXPECT_EQUAL(a - 1,
690                "(a - 1)");
691     EXPECT_EQUAL(2 - a - b,
692               "((2 - a) - b)");
693     EXPECT_EQUAL(a -= b + 1,
694                "(a -= (b + 1))");
695     EXPECT_EQUAL(-a,
696                 "-a");
697     EXPECT_EQUAL(-(a - b),
698                 "-(a - b)");
699 
700     {
701         ExpectError error(r, "error: type mismatch: '-' cannot operate on 'bool2', 'int'\n");
702         DSLExpression(Bool2(true) - a).release();
703     }
704 
705     {
706         ExpectError error(r, "error: type mismatch: '-=' cannot operate on 'int', 'bool2'\n");
707         DSLExpression(a -= Bool2(true)).release();
708     }
709 
710     {
711         ExpectError error(r, "error: cannot assign to this expression\n");
712         DSLExpression(1.0 -= a).release();
713     }
714 
715     {
716         ExpectError error(r, "error: '-' cannot operate on 'bool'\n");
717         Var c(kBool_Type);
718         DSLExpression(-c);
719     }
720 }
721 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMultiply,r,ctxInfo)722 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMultiply, r, ctxInfo) {
723     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
724     Var a(kFloat_Type, "a"), b(kFloat_Type, "b");
725 
726     EXPECT_EQUAL(a * b,
727                "(a * b)");
728     EXPECT_EQUAL(a * 2,
729                "(a * 2.0)");
730     EXPECT_EQUAL(0.5 * a * -99,
731               "((0.5 * a) * -99.0)");
732     EXPECT_EQUAL(a *= b + 1,
733                "(a *= (b + 1.0))");
734 
735     {
736         ExpectError error(r, "error: type mismatch: '*' cannot operate on 'bool2', 'float'\n");
737         DSLExpression(Bool2(true) * a).release();
738     }
739 
740     {
741         ExpectError error(r, "error: type mismatch: '*=' cannot operate on 'float', 'bool2'\n");
742         DSLExpression(a *= Bool2(true)).release();
743     }
744 
745     {
746         ExpectError error(r, "error: cannot assign to this expression\n");
747         DSLExpression(1.0 *= a).release();
748     }
749 }
750 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDivide,r,ctxInfo)751 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDivide, r, ctxInfo) {
752     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
753     Var a(kFloat_Type, "a"), b(kFloat_Type, "b");
754 
755     EXPECT_EQUAL(a / b,
756                "(a / b)");
757     EXPECT_EQUAL(a / 2,
758                "(a / 2.0)");
759     EXPECT_EQUAL(0.5 / a / -99,
760               "((0.5 / a) / -99.0)");
761     EXPECT_EQUAL(b / (a - 1),
762                "(b / (a - 1.0))");
763     EXPECT_EQUAL(a /= b + 1,
764                "(a /= (b + 1.0))");
765 
766     {
767         ExpectError error(r, "error: type mismatch: '/' cannot operate on 'bool2', 'float'\n");
768         DSLExpression(Bool2(true) / a).release();
769     }
770 
771     {
772         ExpectError error(r, "error: type mismatch: '/=' cannot operate on 'float', 'bool2'\n");
773         DSLExpression(a /= Bool2(true)).release();
774     }
775 
776     {
777         ExpectError error(r, "error: cannot assign to this expression\n");
778         DSLExpression(1.0 /= a).release();
779     }
780 
781     {
782         ExpectError error(r, "error: division by zero\n");
783         DSLExpression(a /= 0).release();
784     }
785 
786     {
787         Var c(kFloat2_Type, "c");
788         ExpectError error(r, "error: division by zero\n");
789         DSLExpression(c /= Float2(Float(0), 1)).release();
790     }
791 }
792 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMod,r,ctxInfo)793 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMod, r, ctxInfo) {
794     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
795     Var a(kInt_Type, "a"), b(kInt_Type, "b");
796     Expression e1 = a % b;
797     EXPECT_EQUAL(e1, "(a % b)");
798 
799     Expression e2 = a % 2;
800     EXPECT_EQUAL(e2, "(a % 2)");
801 
802     Expression e3 = 10 % a % -99;
803     EXPECT_EQUAL(e3, "((10 % a) % -99)");
804 
805     Expression e4 = a %= b + 1;
806     EXPECT_EQUAL(e4, "(a %= (b + 1))");
807 
808     {
809         ExpectError error(r, "error: type mismatch: '%' cannot operate on 'bool2', 'int'\n");
810         DSLExpression(Bool2(true) % a).release();
811     }
812 
813     {
814         ExpectError error(r, "error: type mismatch: '%=' cannot operate on 'int', 'bool2'\n");
815         DSLExpression(a %= Bool2(true)).release();
816     }
817 
818     {
819         ExpectError error(r, "error: cannot assign to this expression\n");
820         DSLExpression(1 %= a).release();
821     }
822 
823     {
824         ExpectError error(r, "error: division by zero\n");
825         DSLExpression(a %= 0).release();
826     }
827 
828     {
829         Var c(kInt2_Type, "c");
830         ExpectError error(r, "error: division by zero\n");
831         DSLExpression(c %= Int2(Int(0), 1)).release();
832     }
833 }
834 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShl,r,ctxInfo)835 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShl, r, ctxInfo) {
836     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
837     Var a(kInt_Type, "a"), b(kInt_Type, "b");
838     Expression e1 = a << b;
839     EXPECT_EQUAL(e1, "(a << b)");
840 
841     Expression e2 = a << 1;
842     EXPECT_EQUAL(e2, "(a << 1)");
843 
844     Expression e3 = 1 << a << 2;
845     EXPECT_EQUAL(e3, "((1 << a) << 2)");
846 
847     Expression e4 = a <<= b + 1;
848     EXPECT_EQUAL(e4, "(a <<= (b + 1))");
849 
850     {
851         ExpectError error(r, "error: type mismatch: '<<' cannot operate on 'bool2', 'int'\n");
852         DSLExpression(Bool2(true) << a).release();
853     }
854 
855     {
856         ExpectError error(r, "error: type mismatch: '<<=' cannot operate on 'int', 'bool2'\n");
857         DSLExpression(a <<= Bool2(true)).release();
858     }
859 
860     {
861         ExpectError error(r, "error: cannot assign to this expression\n");
862         DSLExpression(1 <<= a).release();
863     }
864 }
865 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShr,r,ctxInfo)866 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShr, r, ctxInfo) {
867     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
868     Var a(kInt_Type, "a"), b(kInt_Type, "b");
869     Expression e1 = a >> b;
870     EXPECT_EQUAL(e1, "(a >> b)");
871 
872     Expression e2 = a >> 1;
873     EXPECT_EQUAL(e2, "(a >> 1)");
874 
875     Expression e3 = 1 >> a >> 2;
876     EXPECT_EQUAL(e3, "((1 >> a) >> 2)");
877 
878     Expression e4 = a >>= b + 1;
879     EXPECT_EQUAL(e4, "(a >>= (b + 1))");
880 
881     {
882         ExpectError error(r, "error: type mismatch: '>>' cannot operate on 'bool2', 'int'\n");
883         DSLExpression(Bool2(true) >> a).release();
884     }
885 
886     {
887         ExpectError error(r, "error: type mismatch: '>>=' cannot operate on 'int', 'bool2'\n");
888         DSLExpression(a >>= Bool2(true)).release();
889     }
890 
891     {
892         ExpectError error(r, "error: cannot assign to this expression\n");
893         DSLExpression(1 >>= a).release();
894     }
895 }
896 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseAnd,r,ctxInfo)897 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseAnd, r, ctxInfo) {
898     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
899     Var a(kInt_Type, "a"), b(kInt_Type, "b");
900     Expression e1 = a & b;
901     EXPECT_EQUAL(e1, "(a & b)");
902 
903     Expression e2 = a & 1;
904     EXPECT_EQUAL(e2, "(a & 1)");
905 
906     Expression e3 = 1 & a & 2;
907     EXPECT_EQUAL(e3, "((1 & a) & 2)");
908 
909     Expression e4 = a &= b + 1;
910     EXPECT_EQUAL(e4, "(a &= (b + 1))");
911 
912     {
913         ExpectError error(r, "error: type mismatch: '&' cannot operate on 'bool2', 'int'\n");
914         DSLExpression(Bool2(true) & a).release();
915     }
916 
917     {
918         ExpectError error(r, "error: type mismatch: '&=' cannot operate on 'int', 'bool2'\n");
919         DSLExpression(a &= Bool2(true)).release();
920     }
921 
922     {
923         ExpectError error(r, "error: cannot assign to this expression\n");
924         DSLExpression(1 &= a).release();
925     }
926 }
927 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseOr,r,ctxInfo)928 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseOr, r, ctxInfo) {
929     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
930     Var a(kInt_Type, "a"), b(kInt_Type, "b");
931     Expression e1 = a | b;
932     EXPECT_EQUAL(e1, "(a | b)");
933 
934     Expression e2 = a | 1;
935     EXPECT_EQUAL(e2, "(a | 1)");
936 
937     Expression e3 = 1 | a | 2;
938     EXPECT_EQUAL(e3, "((1 | a) | 2)");
939 
940     Expression e4 = a |= b + 1;
941     EXPECT_EQUAL(e4, "(a |= (b + 1))");
942 
943     {
944         ExpectError error(r, "error: type mismatch: '|' cannot operate on 'bool2', 'int'\n");
945         DSLExpression(Bool2(true) | a).release();
946     }
947 
948     {
949         ExpectError error(r, "error: type mismatch: '|=' cannot operate on 'int', 'bool2'\n");
950         DSLExpression(a |= Bool2(true)).release();
951     }
952 
953     {
954         ExpectError error(r, "error: cannot assign to this expression\n");
955         DSLExpression(1 |= a).release();
956     }
957 }
958 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseXor,r,ctxInfo)959 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseXor, r, ctxInfo) {
960     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
961     Var a(kInt_Type, "a"), b(kInt_Type, "b");
962     Expression e1 = a ^ b;
963     EXPECT_EQUAL(e1, "(a ^ b)");
964 
965     Expression e2 = a ^ 1;
966     EXPECT_EQUAL(e2, "(a ^ 1)");
967 
968     Expression e3 = 1 ^ a ^ 2;
969     EXPECT_EQUAL(e3, "((1 ^ a) ^ 2)");
970 
971     Expression e4 = a ^= b + 1;
972     EXPECT_EQUAL(e4, "(a ^= (b + 1))");
973 
974     {
975         ExpectError error(r, "error: type mismatch: '^' cannot operate on 'bool2', 'int'\n");
976         DSLExpression(Bool2(true) ^ a).release();
977     }
978 
979     {
980         ExpectError error(r, "error: type mismatch: '^=' cannot operate on 'int', 'bool2'\n");
981         DSLExpression(a ^= Bool2(true)).release();
982     }
983 
984     {
985         ExpectError error(r, "error: cannot assign to this expression\n");
986         DSLExpression(1 ^= a).release();
987     }
988 }
989 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalAnd,r,ctxInfo)990 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalAnd, r, ctxInfo) {
991     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
992     Var a(kBool_Type, "a"), b(kBool_Type, "b");
993     Expression e1 = a && b;
994     EXPECT_EQUAL(e1, "(a && b)");
995 
996     Expression e2 = a && true && b;
997     EXPECT_EQUAL(e2, "(a && b)");
998 
999     Expression e3 = a && false && b;
1000     EXPECT_EQUAL(e3, "false");
1001 
1002     {
1003         ExpectError error(r, "error: type mismatch: '&&' cannot operate on 'bool', 'int'\n");
1004         DSLExpression(a && 5).release();
1005     }
1006 }
1007 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalOr,r,ctxInfo)1008 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalOr, r, ctxInfo) {
1009     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1010     Var a(kBool_Type, "a"), b(kBool_Type, "b");
1011     Expression e1 = a || b;
1012     EXPECT_EQUAL(e1, "(a || b)");
1013 
1014     Expression e2 = a || true || b;
1015     EXPECT_EQUAL(e2, "true");
1016 
1017     Expression e3 = a || false || b;
1018     EXPECT_EQUAL(e3, "(a || b)");
1019 
1020     {
1021         ExpectError error(r, "error: type mismatch: '||' cannot operate on 'bool', 'int'\n");
1022         DSLExpression(a || 5).release();
1023     }
1024 }
1025 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLComma,r,ctxInfo)1026 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLComma, r, ctxInfo) {
1027     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1028     Var a(kInt_Type, "a"), b(kInt_Type, "b");
1029     Expression e1 = (a += b, b);
1030     EXPECT_EQUAL(e1, "((a += b) , b)");
1031 
1032     Expression e2 = (a += b, b += b, Int2(a));
1033     EXPECT_EQUAL(e2, "(((a += b) , (b += b)) , int2(a))");
1034 }
1035 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLEqual,r,ctxInfo)1036 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLEqual, r, ctxInfo) {
1037     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1038     Var a(kInt_Type, "a"), b(kInt_Type, "b");
1039     Expression e1 = a == b;
1040     EXPECT_EQUAL(e1, "(a == b)");
1041 
1042     Expression e2 = a == 5;
1043     EXPECT_EQUAL(e2, "(a == 5)");
1044 
1045     {
1046         ExpectError error(r, "error: type mismatch: '==' cannot operate on 'int', 'bool2'\n");
1047         DSLExpression(a == Bool2(true)).release();
1048     }
1049 }
1050 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLNotEqual,r,ctxInfo)1051 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLNotEqual, r, ctxInfo) {
1052     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1053     Var a(kInt_Type, "a"), b(kInt_Type, "b");
1054     Expression e1 = a != b;
1055     EXPECT_EQUAL(e1, "(a != b)");
1056 
1057     Expression e2 = a != 5;
1058     EXPECT_EQUAL(e2, "(a != 5)");
1059 
1060     {
1061         ExpectError error(r, "error: type mismatch: '!=' cannot operate on 'int', 'bool2'\n");
1062         DSLExpression(a != Bool2(true)).release();
1063     }
1064 }
1065 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLGreaterThan,r,ctxInfo)1066 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLGreaterThan, r, ctxInfo) {
1067     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1068     Var a(kInt_Type, "a"), b(kInt_Type, "b");
1069     Expression e1 = a > b;
1070     EXPECT_EQUAL(e1, "(a > b)");
1071 
1072     Expression e2 = a > 5;
1073     EXPECT_EQUAL(e2, "(a > 5)");
1074 
1075     {
1076         ExpectError error(r, "error: type mismatch: '>' cannot operate on 'int', 'bool2'\n");
1077         DSLExpression(a > Bool2(true)).release();
1078     }
1079 }
1080 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLGreaterThanOrEqual,r,ctxInfo)1081 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLGreaterThanOrEqual, r, ctxInfo) {
1082     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1083     Var a(kInt_Type, "a"), b(kInt_Type, "b");
1084     Expression e1 = a >= b;
1085     EXPECT_EQUAL(e1, "(a >= b)");
1086 
1087     Expression e2 = a >= 5;
1088     EXPECT_EQUAL(e2, "(a >= 5)");
1089 
1090     {
1091         ExpectError error(r, "error: type mismatch: '>=' cannot operate on 'int', 'bool2'\n");
1092         DSLExpression(a >= Bool2(true)).release();
1093     }
1094 }
1095 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLessThan,r,ctxInfo)1096 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLessThan, r, ctxInfo) {
1097     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1098     Var a(kInt_Type, "a"), b(kInt_Type, "b");
1099     Expression e1 = a < b;
1100     EXPECT_EQUAL(e1, "(a < b)");
1101 
1102     Expression e2 = a < 5;
1103     EXPECT_EQUAL(e2, "(a < 5)");
1104 
1105     {
1106         ExpectError error(r, "error: type mismatch: '<' cannot operate on 'int', 'bool2'\n");
1107         DSLExpression(a < Bool2(true)).release();
1108     }
1109 }
1110 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLessThanOrEqual,r,ctxInfo)1111 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLessThanOrEqual, r, ctxInfo) {
1112     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1113     Var a(kInt_Type, "a"), b(kInt_Type, "b");
1114     Expression e1 = a <= b;
1115     EXPECT_EQUAL(e1, "(a <= b)");
1116 
1117     Expression e2 = a <= 5;
1118     EXPECT_EQUAL(e2, "(a <= 5)");
1119 
1120     {
1121         ExpectError error(r, "error: type mismatch: '<=' cannot operate on 'int', 'bool2'\n");
1122         DSLExpression(a <= Bool2(true)).release();
1123     }
1124 }
1125 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalNot,r,ctxInfo)1126 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalNot, r, ctxInfo) {
1127     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1128     Var a(kInt_Type, "a"), b(kInt_Type, "b");
1129     Expression e1 = !(a <= b);
1130     EXPECT_EQUAL(e1, "!(a <= b)");
1131 
1132     {
1133         ExpectError error(r, "error: '!' cannot operate on 'int'\n");
1134         DSLExpression(!a).release();
1135     }
1136 }
1137 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseNot,r,ctxInfo)1138 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBitwiseNot, r, ctxInfo) {
1139     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1140     Var a(kInt_Type, "a"), b(kBool_Type, "b");
1141     Expression e1 = ~a;
1142     EXPECT_EQUAL(e1, "~a");
1143 
1144     {
1145         ExpectError error(r, "error: '~' cannot operate on 'bool'\n");
1146         DSLExpression(~b).release();
1147     }
1148 }
1149 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIncrement,r,ctxInfo)1150 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIncrement, r, ctxInfo) {
1151     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1152     Var a(kInt_Type, "a"), b(kBool_Type, "b");
1153     Expression e1 = ++a;
1154     EXPECT_EQUAL(e1, "++a");
1155 
1156     Expression e2 = a++;
1157     EXPECT_EQUAL(e2, "a++");
1158 
1159     {
1160         ExpectError error(r, "error: '++' cannot operate on 'bool'\n");
1161         DSLExpression(++b).release();
1162     }
1163 
1164     {
1165         ExpectError error(r, "error: '++' cannot operate on 'bool'\n");
1166         DSLExpression(b++).release();
1167     }
1168 
1169     {
1170         ExpectError error(r, "error: cannot assign to this expression\n");
1171         DSLExpression(++(a + 1)).release();
1172     }
1173 
1174     {
1175         ExpectError error(r, "error: cannot assign to this expression\n");
1176         DSLExpression((a + 1)++).release();
1177     }
1178 }
1179 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDecrement,r,ctxInfo)1180 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDecrement, r, ctxInfo) {
1181     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1182     Var a(kInt_Type, "a"), b(kBool_Type, "b");
1183     Expression e1 = --a;
1184     EXPECT_EQUAL(e1, "--a");
1185 
1186     Expression e2 = a--;
1187     EXPECT_EQUAL(e2, "a--");
1188 
1189     {
1190         ExpectError error(r, "error: '--' cannot operate on 'bool'\n");
1191         DSLExpression(--b).release();
1192     }
1193 
1194     {
1195         ExpectError error(r, "error: '--' cannot operate on 'bool'\n");
1196         DSLExpression(b--).release();
1197     }
1198 
1199     {
1200         ExpectError error(r, "error: cannot assign to this expression\n");
1201         DSLExpression(--(a + 1)).release();
1202     }
1203 
1204     {
1205         ExpectError error(r, "error: cannot assign to this expression\n");
1206         DSLExpression((a + 1)--).release();
1207     }
1208 }
1209 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLCall,r,ctxInfo)1210 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLCall, r, ctxInfo) {
1211     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1212     {
1213         DSLExpression sqrt = DSLWriter::IRGenerator().convertIdentifier(/*offset=*/-1, "sqrt");
1214         SkTArray<DSLWrapper<DSLExpression>> args;
1215         args.emplace_back(1);
1216         EXPECT_EQUAL(sqrt(std::move(args)), "sqrt(1.0)");
1217     }
1218 
1219     {
1220         DSLExpression pow = DSLWriter::IRGenerator().convertIdentifier(/*offset=*/-1, "pow");
1221         DSLVar a(kFloat_Type, "a");
1222         DSLVar b(kFloat_Type, "b");
1223         SkTArray<DSLWrapper<DSLExpression>> args;
1224         args.emplace_back(a);
1225         args.emplace_back(b);
1226         EXPECT_EQUAL(pow(std::move(args)), "pow(a, b)");
1227     }
1228 }
1229 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBlock,r,ctxInfo)1230 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBlock, r, ctxInfo) {
1231     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1232     EXPECT_EQUAL(Block(), "{ }");
1233     Var a(kInt_Type, "a", 1), b(kInt_Type, "b", 2);
1234     EXPECT_EQUAL(Block(Declare(a), Declare(b), a = b), "{ int a = 1; int b = 2; (a = b); }");
1235 
1236     EXPECT_EQUAL((If(a > 0, --a), ++b), "if ((a > 0)) --a; ++b;");
1237 
1238     SkTArray<DSLStatement> statements;
1239     statements.push_back(a = 0);
1240     statements.push_back(++a);
1241     EXPECT_EQUAL(Block(std::move(statements)), "{ (a = 0); ++a; }");
1242 }
1243 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBreak,r,ctxInfo)1244 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBreak, r, ctxInfo) {
1245     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1246     Var i(kInt_Type, "i", 0);
1247     DSLFunction(kVoid_Type, "success").define(
1248         For(Declare(i), i < 10, ++i, Block(
1249             If(i > 5, Break())
1250         ))
1251     );
1252     REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
1253     EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
1254                  "void success() { for (int i = 0; (i < 10); ++i) { if ((i > 5)) break; } }");
1255 
1256     {
1257         ExpectError error(r, "error: break statement must be inside a loop or switch\n");
1258         DSLFunction(kVoid_Type, "fail").define(
1259             Break()
1260         );
1261     }
1262 }
1263 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLContinue,r,ctxInfo)1264 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLContinue, r, ctxInfo) {
1265     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1266     Var i(kInt_Type, "i", 0);
1267     DSLFunction(kVoid_Type, "success").define(
1268         For(Declare(i), i < 10, ++i, Block(
1269             If(i < 5, Continue())
1270         ))
1271     );
1272     REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
1273     EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
1274                  "void success() { for (int i = 0; (i < 10); ++i) { if ((i < 5)) continue; } }");
1275 
1276     {
1277         ExpectError error(r, "error: continue statement must be inside a loop\n");
1278         DSLFunction(kVoid_Type, "fail").define(
1279             Continue()
1280         );
1281     }
1282 }
1283 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclare,r,ctxInfo)1284 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclare, r, ctxInfo) {
1285     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1286     Var a(kHalf4_Type, "a"), b(kHalf4_Type, "b", Half4(1));
1287     Statement x = Declare(a);
1288     EXPECT_EQUAL(x, "half4 a;");
1289     Statement y = Declare(b);
1290     EXPECT_EQUAL(y, "half4 b = half4(1.0);");
1291 
1292     {
1293         Var c(kHalf4_Type, "c", 1);
1294         ExpectError error(r, "error: expected 'half4', but found 'int'\n");
1295         Declare(c).release();
1296     }
1297 
1298     {
1299         Var d(kInt_Type, "d");
1300         Declare(d).release();
1301         ExpectError error(r, "error: variable has already been declared\n");
1302         Declare(d).release();
1303     }
1304 
1305     {
1306         Var e(kUniform_Modifier, kInt_Type, "e");
1307         ExpectError error(r, "error: this variable must be declared with DeclareGlobal\n");
1308         Declare(e).release();
1309     }
1310 }
1311 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclareGlobal,r,ctxInfo)1312 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclareGlobal, r, ctxInfo) {
1313     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1314     Var x(kInt_Type, "x", 0);
1315     DeclareGlobal(x);
1316     Var y(kUniform_Modifier, kFloat2_Type, "y");
1317     DeclareGlobal(y);
1318     REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
1319     EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "int x = 0;");
1320     EXPECT_EQUAL(*DSLWriter::ProgramElements()[1], "uniform float2 y;");
1321 }
1322 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDiscard,r,ctxInfo)1323 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDiscard, r, ctxInfo) {
1324     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1325     Statement x = If(Sqrt(1) > 0, Discard());
1326     EXPECT_EQUAL(x, "if ((sqrt(1.0) > 0.0)) discard;");
1327 }
1328 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDo,r,ctxInfo)1329 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDo, r, ctxInfo) {
1330     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1331     Statement x = Do(Block(), true);
1332     EXPECT_EQUAL(x, "do {} while (true);");
1333 
1334     Var a(kFloat_Type, "a"), b(kFloat_Type, "b");
1335     Statement y = Do(Block(a++, --b), a != b);
1336     EXPECT_EQUAL(y, "do { a++; --b; } while ((a != b));");
1337 
1338     {
1339         ExpectError error(r, "error: expected 'bool', but found 'int'\n");
1340         Do(Block(), 7).release();
1341     }
1342 }
1343 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFor,r,ctxInfo)1344 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFor, r, ctxInfo) {
1345     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1346     EXPECT_EQUAL(For(Statement(), Expression(), Expression(), Block()),
1347                 "for (;;) {}");
1348 
1349     Var i(kInt_Type, "i", 0);
1350     EXPECT_EQUAL(For(Declare(i), i < 10, ++i, i += 5),
1351                 "for (int i = 0; (i < 10); ++i) (i += 5);");
1352 
1353     Var j(kInt_Type, "j", 0);
1354     Var k(kInt_Type, "k", 10);
1355     EXPECT_EQUAL(For((Declare(j), Declare(k)), j < k, ++j, Block()), R"(
1356                  {
1357                      int j = 0;
1358                      int k = 10;
1359                      for (; (j < k); ++j) {}
1360                  }
1361     )");
1362 
1363     {
1364         ExpectError error(r, "error: expected 'bool', but found 'int'\n");
1365         For(i = 0, i + 10, ++i, i += 5).release();
1366     }
1367 
1368     {
1369         ExpectError error(r, "error: invalid for loop initializer\n");
1370         For(If(i == 0, i = 1), i < 10, ++i, i += 5).release();
1371     }
1372 }
1373 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction,r,ctxInfo)1374 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
1375     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1376     Var coords(kFloat2_Type, "coords");
1377     DSLFunction(kVoid_Type, "main", coords).define(
1378         sk_FragColor() = Half4(coords, 0, 1)
1379     );
1380     REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
1381     EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
1382                  "void main(float2 coords) { (sk_FragColor = half4(half2(coords), 0.0, 1.0)); }");
1383 
1384     {
1385         DSLWriter::Reset();
1386         Var x(kFloat_Type, "x");
1387         DSLFunction sqr(kFloat_Type, "sqr", x);
1388         sqr.define(
1389             Return(x * x)
1390         );
1391         EXPECT_EQUAL(sqr(sk_FragCoord().x()), "sqr(sk_FragCoord.x)");
1392         REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
1393         EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "float sqr(float x) { return (x * x); }");
1394     }
1395 
1396     {
1397         DSLWriter::Reset();
1398         Var x(kFloat2_Type, "x");
1399         Var y(kFloat2_Type, "y");
1400         DSLFunction dot(kFloat2_Type, "dot", x, y);
1401         dot.define(
1402             Return(x * x + y * y)
1403         );
1404         EXPECT_EQUAL(dot(Float2(1.0f, 2.0f), Float2(3.0f, 4.0f)),
1405                      "dot(float2(1.0, 2.0), float2(3.0, 4.0))");
1406         REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
1407         EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
1408                 "float2 dot(float2 x, float2 y) { return ((x * x) + (y * y)); }");
1409     }
1410 
1411     {
1412         DSLWriter::Reset();
1413         Var x(kFloat_Type, "x");
1414         Var y(kFloat_Type, "y");
1415         DSLFunction pair(kFloat2_Type, "pair", x, y);
1416         pair.define(
1417             Return(Float2(x, y))
1418         );
1419         Var varArg1(kFloat_Type, "varArg1");
1420         Var varArg2(kFloat_Type, "varArg2");
1421         DSLWriter::MarkDeclared(varArg1);
1422         DSLWriter::MarkDeclared(varArg2);
1423         EXPECT_EQUAL(pair(varArg1, varArg2), "pair(varArg1, varArg2)");
1424     }
1425 
1426     {
1427         ExpectError error(r, "error: expected 'float', but found 'bool'\n");
1428         DSLWriter::Reset();
1429         DSLFunction(kFloat_Type, "broken").define(
1430             Return(true)
1431         );
1432     }
1433 
1434     {
1435         ExpectError error(r, "error: expected function to return 'float'\n");
1436         DSLWriter::Reset();
1437         DSLFunction(kFloat_Type, "broken").define(
1438             Return()
1439         );
1440     }
1441 
1442     {
1443         ExpectError error(r, "error: function 'broken' can exit without returning a value\n");
1444         DSLWriter::Reset();
1445         Var x(kFloat_Type, "x", 0);
1446         DSLFunction(kFloat_Type, "broken").define(
1447             Declare(x),
1448             If(x == 1, Return(x))
1449         );
1450     }
1451 
1452     {
1453         ExpectError error(r, "error: may not return a value from a void function\n");
1454         DSLWriter::Reset();
1455         DSLFunction(kVoid_Type, "broken").define(
1456             Return(0)
1457         );
1458     }
1459 
1460     {
1461         ExpectError error(r, "error: function 'broken' can exit without returning a value\n");
1462         DSLWriter::Reset();
1463         DSLFunction(kFloat_Type, "broken").define(
1464         );
1465     }
1466 
1467     {
1468         ExpectError error(r, "error: using an already-declared variable as a function parameter\n");
1469         DSLWriter::Reset();
1470         DSLVar p(kFloat_Type);
1471         Declare(p).release();
1472         DSLFunction(kVoid_Type, "broken", p).define(
1473         );
1474     }
1475 
1476     {
1477         ExpectError error(r, "error: variable has already been declared\n");
1478         DSLWriter::Reset();
1479         DSLVar p(kFloat_Type);
1480         DSLFunction(kVoid_Type, "broken", p).define(
1481         );
1482         Declare(p).release();
1483     }
1484 
1485     {
1486         ExpectError error(r, "error: variables used as function parameters cannot have initial "
1487                              "values\n");
1488         DSLWriter::Reset();
1489         DSLVar p(kFloat_Type, 1);
1490         DSLFunction(kVoid_Type, "broken", p).define(
1491         );
1492     }
1493 }
1494 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIf,r,ctxInfo)1495 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIf, r, ctxInfo) {
1496     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1497     Var a(kFloat_Type, "a"), b(kFloat_Type, "b");
1498     Statement x = If(a > b, a -= b);
1499     EXPECT_EQUAL(x, "if ((a > b)) (a -= b);");
1500 
1501     Statement y = If(a > b, a -= b, b -= a);
1502     EXPECT_EQUAL(y, "if ((a > b)) (a -= b); else (b -= a);");
1503 
1504     Statement z = StaticIf(a > b, a -= b, b -= a);
1505     EXPECT_EQUAL(z, "@if ((a > b)) (a -= b); else (b -= a);");
1506 
1507     {
1508         ExpectError error(r, "error: expected 'bool', but found 'float'\n");
1509         If(a + b, a -= b).release();
1510     }
1511 }
1512 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLReturn,r,ctxInfo)1513 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLReturn, r, ctxInfo) {
1514     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1515 
1516     Statement x = Return();
1517     EXPECT_EQUAL(x, "return;");
1518 
1519     Statement y = Return(true);
1520     EXPECT_EQUAL(y, "return true;");
1521 }
1522 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSelect,r,ctxInfo)1523 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSelect, r, ctxInfo) {
1524     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1525     Var a(kInt_Type, "a");
1526     Expression x = Select(a > 0, 1, -1);
1527     EXPECT_EQUAL(x, "((a > 0) ? 1 : -1)");
1528 
1529     {
1530         ExpectError error(r, "error: expected 'bool', but found 'int'\n");
1531         DSLExpression x = Select(a, 1, -1);
1532     }
1533 
1534     {
1535         ExpectError error(r, "error: ternary operator result mismatch: 'float2', 'float3'\n");
1536         DSLExpression x = Select(a > 0, Float2(1), Float3(1));
1537     }
1538 }
1539 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSwitch,r,ctxInfo)1540 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSwitch, r, ctxInfo) {
1541     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1542 
1543     Var a(kFloat_Type, "a"), b(kInt_Type, "b");
1544 
1545     SkTArray<DSLStatement> caseStatements;
1546     caseStatements.push_back(a = 1);
1547     caseStatements.push_back(Continue());
1548     Statement x = Switch(b,
1549         Case(0, a = 0, Break()),
1550         Case(1, std::move(caseStatements)),
1551         Case(2, a = 2  /*Fallthrough*/),
1552         Default(Discard())
1553     );
1554     EXPECT_EQUAL(x, R"(
1555         switch (b) {
1556             case 0: (a = 0.0); break;
1557             case 1: (a = 1.0); continue;
1558             case 2: (a = 2.0);
1559             default: discard;
1560         }
1561     )");
1562 
1563     Statement y = StaticSwitch(b,
1564         Case(0, a = 0, Break()),
1565         Case(1, a = 1, Continue()),
1566         Case(2, a = 2  /*Fallthrough*/),
1567         Default(Discard())
1568     );
1569     EXPECT_EQUAL(y, R"(
1570         @switch (b) {
1571             case 0: (a = 0.0); break;
1572             case 1: (a = 1.0); continue;
1573             case 2: (a = 2.0);
1574             default: discard;
1575         }
1576     )");
1577 
1578     EXPECT_EQUAL(Switch(b),
1579                 "switch (b) {}");
1580 
1581     EXPECT_EQUAL(Switch(b, Default(), Case(0), Case(1)),
1582                 "switch (b) { default: case 0: case 1: }");
1583 
1584     {
1585         ExpectError error(r, "error: duplicate case value '0'\n");
1586         DSLStatement(Switch(0, Case(0), Case(0))).release();
1587     }
1588 
1589     {
1590         ExpectError error(r, "error: duplicate default case\n");
1591         DSLStatement(Switch(0, Default(a = 0), Default(a = 1))).release();
1592     }
1593 
1594     {
1595         ExpectError error(r, "error: case value must be a constant integer\n");
1596         Var b(kInt_Type);
1597         DSLStatement(Switch(0, Case(b))).release();
1598     }
1599 }
1600 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSwizzle,r,ctxInfo)1601 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSwizzle, r, ctxInfo) {
1602     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kDefaultTestFlags);
1603     Var a(kFloat4_Type, "a");
1604 
1605     EXPECT_EQUAL(a.x(),
1606                 "a.x");
1607     EXPECT_EQUAL(a.y(),
1608                 "a.y");
1609     EXPECT_EQUAL(a.z(),
1610                 "a.z");
1611     EXPECT_EQUAL(a.w(),
1612                 "a.w");
1613     EXPECT_EQUAL(a.r(),
1614                 "a.x");
1615     EXPECT_EQUAL(a.g(),
1616                 "a.y");
1617     EXPECT_EQUAL(a.b(),
1618                 "a.z");
1619     EXPECT_EQUAL(a.a(),
1620                 "a.w");
1621     EXPECT_EQUAL(Swizzle(a, R),
1622                 "a.x");
1623     EXPECT_EQUAL(Swizzle(a, ZERO, G),
1624                 "float2(0.0, a.y)");
1625     EXPECT_EQUAL(Swizzle(a, B, G, G),
1626                 "a.zyy");
1627     EXPECT_EQUAL(Swizzle(a, R, G, B, ONE),
1628                 "float4(a.xyz, 1.0)");
1629     EXPECT_EQUAL(Swizzle(a, B, G, R, ONE).r(),
1630                 "a.z");
1631 }
1632 
1633 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLVarSwap,r,ctxInfo)1634 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLVarSwap, r, ctxInfo) {
1635     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1636 
1637     // We should be able to convert `a` into a proper var by swapping it, even from within a scope.
1638     Var a;
1639     if (true)
1640     {
1641         Var(kInt_Type, "a").swap(a);
1642     }
1643 
1644     EXPECT_EQUAL(Statement(Block(Declare(a), a = 123)),
1645                 "{ int a; (a = 123); }");
1646 }
1647 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWhile,r,ctxInfo)1648 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWhile, r, ctxInfo) {
1649     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1650     Statement x = While(true, Block());
1651     EXPECT_EQUAL(x, "for (; true;) {}");
1652 
1653     Var a(kFloat_Type, "a"), b(kFloat_Type, "b");
1654     Statement y = While(a != b, Block(a++, --b));
1655     EXPECT_EQUAL(y, "for (; (a != b);) { a++; --b; }");
1656 
1657     {
1658         ExpectError error(r, "error: expected 'bool', but found 'int'\n");
1659         DSLStatement x = While(7, Block());
1660     }
1661 }
1662 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIndex,r,ctxInfo)1663 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIndex, r, ctxInfo) {
1664     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1665     Var a(Array(kInt_Type, 5), "a"), b(kInt_Type, "b");
1666 
1667     EXPECT_EQUAL(a[0], "a[0]");
1668     EXPECT_EQUAL(a[b], "a[b]");
1669 
1670     {
1671         ExpectError error(r, "error: expected 'int', but found 'bool'\n");
1672         DSLExpression x = a[true];
1673     }
1674 
1675     {
1676         ExpectError error(r, "error: expected array, but found 'int'\n");
1677         DSLExpression x = b[0];
1678     }
1679 
1680     {
1681         ExpectError error(r, "error: index -1 out of range for 'int[5]'\n");
1682         DSLExpression x = a[-1];
1683     }
1684 }
1685 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBuiltins,r,ctxInfo)1686 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBuiltins, r, ctxInfo) {
1687     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1688     // There is a Fract type on Mac which can conflict with our Fract builtin
1689     using SkSL::dsl::Fract;
1690     Var a(kHalf4_Type, "a"), b(kHalf4_Type, "b"), c(kHalf4_Type, "c");
1691     Var h3(kHalf3_Type, "h3");
1692     Var b4(kBool4_Type, "b4");
1693     EXPECT_EQUAL(Abs(a),                 "abs(a)");
1694     EXPECT_EQUAL(All(b4),                "all(b4)");
1695     EXPECT_EQUAL(Any(b4),                "any(b4)");
1696     EXPECT_EQUAL(Atan(a),                "atan(a)");
1697     EXPECT_EQUAL(Atan(a, b),             "atan(a, b)");
1698     EXPECT_EQUAL(Ceil(a),                "ceil(a)");
1699     EXPECT_EQUAL(Clamp(a, 0, 1),         "clamp(a, 0.0, 1.0)");
1700     EXPECT_EQUAL(Cos(a),                 "cos(a)");
1701     EXPECT_EQUAL(Cross(h3, h3),          "cross(h3, h3)");
1702     EXPECT_EQUAL(Degrees(a),             "degrees(a)");
1703     EXPECT_EQUAL(Distance(a, b),         "distance(a, b)");
1704     EXPECT_EQUAL(Dot(a, b),              "dot(a, b)");
1705     EXPECT_EQUAL(Equal(a, b),            "equal(a, b)");
1706     EXPECT_EQUAL(Exp(a),                 "exp(a)");
1707     EXPECT_EQUAL(Exp2(a),                "exp2(a)");
1708     EXPECT_EQUAL(Faceforward(a, b, c),   "faceforward(a, b, c)");
1709     EXPECT_EQUAL(Floor(a),               "floor(a)");
1710     EXPECT_EQUAL(Fract(a),               "fract(a)");
1711     EXPECT_EQUAL(GreaterThan(a, b),      "greaterThan(a, b)");
1712     EXPECT_EQUAL(GreaterThanEqual(a, b), "greaterThanEqual(a, b)");
1713     EXPECT_EQUAL(Inversesqrt(a),         "inversesqrt(a)");
1714     EXPECT_EQUAL(LessThan(a, b),         "lessThan(a, b)");
1715     EXPECT_EQUAL(LessThanEqual(a, b),    "lessThanEqual(a, b)");
1716     EXPECT_EQUAL(Length(a),              "length(a)");
1717     EXPECT_EQUAL(Log(a),                 "log(a)");
1718     EXPECT_EQUAL(Log2(a),                "log2(a)");
1719     EXPECT_EQUAL(Max(a, b),              "max(a, b)");
1720     EXPECT_EQUAL(Min(a, b),              "min(a, b)");
1721     EXPECT_EQUAL(Mix(a, b, c),           "mix(a, b, c)");
1722     EXPECT_EQUAL(Mod(a, b),              "mod(a, b)");
1723     EXPECT_EQUAL(Normalize(a),           "normalize(a)");
1724     EXPECT_EQUAL(NotEqual(a, b),         "notEqual(a, b)");
1725     EXPECT_EQUAL(Pow(a, b),              "pow(a, b)");
1726     EXPECT_EQUAL(Radians(a),             "radians(a)");
1727     EXPECT_EQUAL(Reflect(a, b),          "reflect(a, b)");
1728     EXPECT_EQUAL(Refract(a, b, 1),       "refract(a, b, 1.0)");
1729     EXPECT_EQUAL(Saturate(a),            "saturate(a)");
1730     EXPECT_EQUAL(Sign(a),                "sign(a)");
1731     EXPECT_EQUAL(Sin(a),                 "sin(a)");
1732     EXPECT_EQUAL(Smoothstep(a, b, c),    "smoothstep(a, b, c)");
1733     EXPECT_EQUAL(Sqrt(a),                "sqrt(a)");
1734     EXPECT_EQUAL(Step(a, b),             "step(a, b)");
1735     EXPECT_EQUAL(Tan(a),                 "tan(a)");
1736     EXPECT_EQUAL(Unpremul(a),            "unpremul(a)");
1737 
1738     // these calls all go through the normal channels, so it ought to be sufficient to prove that
1739     // one of them reports errors correctly
1740     {
1741         ExpectError error(r, "error: no match for ceil(bool)\n");
1742         Ceil(a == b).release();
1743     }
1744 }
1745 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLModifiers,r,ctxInfo)1746 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLModifiers, r, ctxInfo) {
1747     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1748 
1749     Var v1(kConst_Modifier, kInt_Type, "v1", 0);
1750     Statement d1 = Declare(v1);
1751     EXPECT_EQUAL(d1, "const int v1 = 0;");
1752 
1753     // Most modifiers require an appropriate context to be legal. We can't yet give them that
1754     // context, so we can't as yet Declare() variables with these modifiers.
1755     // TODO: better tests when able
1756     Var v2(kIn_Modifier, kInt_Type, "v2");
1757     REPORTER_ASSERT(r, DSLWriter::Var(v2).modifiers().fFlags == SkSL::Modifiers::kIn_Flag);
1758     DSLWriter::MarkDeclared(v2);
1759 
1760     Var v3(kOut_Modifier, kInt_Type, "v3");
1761     REPORTER_ASSERT(r, DSLWriter::Var(v3).modifiers().fFlags == SkSL::Modifiers::kOut_Flag);
1762     DSLWriter::MarkDeclared(v3);
1763 
1764     Var v4(kFlat_Modifier, kInt_Type, "v4");
1765     REPORTER_ASSERT(r, DSLWriter::Var(v4).modifiers().fFlags == SkSL::Modifiers::kFlat_Flag);
1766     DSLWriter::MarkDeclared(v4);
1767 
1768     Var v5(kNoPerspective_Modifier, kInt_Type, "v5");
1769     REPORTER_ASSERT(r, DSLWriter::Var(v5).modifiers().fFlags ==
1770                        SkSL::Modifiers::kNoPerspective_Flag);
1771     DSLWriter::MarkDeclared(v5);
1772 
1773     Var v6(kIn_Modifier | kOut_Modifier, kInt_Type, "v6");
1774     REPORTER_ASSERT(r, DSLWriter::Var(v6).modifiers().fFlags ==
1775                        (SkSL::Modifiers::kIn_Flag | SkSL::Modifiers::kOut_Flag));
1776     DSLWriter::MarkDeclared(v6);
1777 
1778     Var v7(kInOut_Modifier, kInt_Type, "v7");
1779     REPORTER_ASSERT(r, DSLWriter::Var(v7).modifiers().fFlags ==
1780                        (SkSL::Modifiers::kIn_Flag | SkSL::Modifiers::kOut_Flag));
1781     DSLWriter::MarkDeclared(v7);
1782 
1783     Var v8(kUniform_Modifier, kInt_Type, "v8");
1784     REPORTER_ASSERT(r, DSLWriter::Var(v8).modifiers().fFlags == SkSL::Modifiers::kUniform_Flag);
1785     DSLWriter::MarkDeclared(v8);
1786     // Uniforms do not need to be explicitly declared
1787 }
1788 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLayout,r,ctxInfo)1789 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLayout, r, ctxInfo) {
1790     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1791     Var v1(DSLModifiers(DSLLayout().location(1).set(2).binding(3).offset(4).index(5).builtin(6)
1792                                    .inputAttachmentIndex(7),
1793                         kConst_Modifier), kInt_Type, "v1", 0);
1794     EXPECT_EQUAL(Declare(v1), "layout (location = 1, offset = 4, binding = 3, index = 5, set = 2, "
1795                               "builtin = 6, input_attachment_index = 7) const int v1 = 0;");
1796 
1797     Var v2(DSLLayout().originUpperLeft(), kFloat2_Type, "v2");
1798     EXPECT_EQUAL(Declare(v2), "layout (origin_upper_left) float2 v2;");
1799 
1800     Var v3(DSLLayout().overrideCoverage(), kHalf_Type, "v3");
1801     EXPECT_EQUAL(Declare(v3), "layout (override_coverage) half v3;");
1802 
1803     Var v4(DSLLayout().pushConstant(), kBool_Type, "v4");
1804     EXPECT_EQUAL(Declare(v4), "layout (push_constant) bool v4;");
1805 
1806     Var v5(DSLLayout().blendSupportAllEquations(), kHalf4_Type, "v5");
1807     EXPECT_EQUAL(Declare(v5), "layout (blend_support_all_equations) half4 v5;");
1808 
1809     Var v6(DSLModifiers(DSLLayout().srgbUnpremul(), kUniform_Modifier), kBool_Type, "v6");
1810     DeclareGlobal(v6);
1811     EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "layout (srgb_unpremul) uniform bool v6;");
1812 
1813     {
1814         ExpectError error(r, "error: layout qualifier 'location' appears more than once\n");
1815         DSLLayout().location(1).location(2);
1816     }
1817 
1818     {
1819         ExpectError error(r, "error: layout qualifier 'set' appears more than once\n");
1820         DSLLayout().set(1).set(2);
1821     }
1822 
1823     {
1824         ExpectError error(r, "error: layout qualifier 'binding' appears more than once\n");
1825         DSLLayout().binding(1).binding(2);
1826     }
1827 
1828     {
1829         ExpectError error(r, "error: layout qualifier 'offset' appears more than once\n");
1830         DSLLayout().offset(1).offset(2);
1831     }
1832 
1833     {
1834         ExpectError error(r, "error: layout qualifier 'index' appears more than once\n");
1835         DSLLayout().index(1).index(2);
1836     }
1837 
1838     {
1839         ExpectError error(r, "error: layout qualifier 'builtin' appears more than once\n");
1840         DSLLayout().builtin(1).builtin(2);
1841     }
1842 
1843     {
1844         ExpectError error(r, "error: layout qualifier 'input_attachment_index' appears more than "
1845                              "once\n");
1846         DSLLayout().inputAttachmentIndex(1).inputAttachmentIndex(2);
1847     }
1848 
1849     {
1850         ExpectError error(r, "error: layout qualifier 'origin_upper_left' appears more than "
1851                              "once\n");
1852         DSLLayout().originUpperLeft().originUpperLeft();
1853     }
1854 
1855     {
1856         ExpectError error(r, "error: layout qualifier 'override_coverage' appears more than "
1857                              "once\n");
1858         DSLLayout().overrideCoverage().overrideCoverage();
1859     }
1860 
1861     {
1862         ExpectError error(r, "error: layout qualifier 'push_constant' appears more than once\n");
1863         DSLLayout().pushConstant().pushConstant();
1864     }
1865 
1866     {
1867         ExpectError error(r, "error: layout qualifier 'blend_support_all_equations' appears more "
1868                              "than once\n");
1869         DSLLayout().blendSupportAllEquations().blendSupportAllEquations();
1870     }
1871 
1872     {
1873         ExpectError error(r, "error: layout qualifier 'srgb_unpremul' appears more than once\n");
1874         DSLLayout().srgbUnpremul().srgbUnpremul();
1875     }
1876 }
1877 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSampleFragmentProcessor,r,ctxInfo)1878 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSampleFragmentProcessor, r, ctxInfo) {
1879     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kDefaultTestFlags,
1880                            SkSL::ProgramKind::kFragmentProcessor);
1881     DSLVar child(kUniform_Modifier, kFragmentProcessor_Type, "child");
1882     EXPECT_EQUAL(Sample(child), "sample(child)");
1883     EXPECT_EQUAL(Sample(child, Float2(0, 0)), "sample(child, float2(0.0, 0.0))");
1884     EXPECT_EQUAL(Sample(child, Half4(1)), "sample(child, half4(1.0))");
1885     EXPECT_EQUAL(Sample(child, Float2(0), Half4(1)), "sample(child, float2(0.0), half4(1.0))");
1886 
1887     {
1888         ExpectError error(r, "error: no match for sample(fragmentProcessor, bool)\n");
1889         Sample(child, true).release();
1890     }
1891 }
1892 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSampleShader,r,ctxInfo)1893 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSampleShader, r, ctxInfo) {
1894     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kDefaultTestFlags,
1895                            SkSL::ProgramKind::kRuntimeShader);
1896     DSLVar shader(kUniform_Modifier, kShader_Type, "shader");
1897     EXPECT_EQUAL(Sample(shader, Float2(0, 0)), "sample(shader, float2(0.0, 0.0))");
1898 
1899     {
1900         ExpectError error(r, "error: no match for sample(shader, half4)\n");
1901         Sample(shader, Half4(1)).release();
1902     }
1903 }
1904 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStruct,r,ctxInfo)1905 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStruct, r, ctxInfo) {
1906     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), kNoDeclareTestFlags);
1907 
1908     DSLType simpleStruct = Struct("SimpleStruct",
1909         Field(kFloat_Type, "x"),
1910         Field(kBool_Type, "b"),
1911         Field(Array(kFloat_Type, 3), "a")
1912     );
1913     DSLVar result(simpleStruct, "result");
1914     DSLFunction(simpleStruct, "returnStruct").define(
1915         Declare(result),
1916         result.field("x") = 123,
1917         result.field("b") = result.field("x") > 0,
1918         result.field("a")[0] = result.field("x"),
1919         Return(result)
1920     );
1921     REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
1922     EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
1923                  "struct SimpleStruct { float x; bool b; float[3] a; };");
1924     EXPECT_EQUAL(*DSLWriter::ProgramElements()[1],
1925                  "SimpleStruct returnStruct() { SimpleStruct result; (result.x = 123.0);"
1926                  "(result.b = (result.x > 0.0)); (result.a[0] = result.x); return result; }");
1927 
1928     Struct("NestedStruct",
1929         Field(kInt_Type, "x"),
1930         Field(simpleStruct, "simple")
1931     );
1932     REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 3);
1933     EXPECT_EQUAL(*DSLWriter::ProgramElements()[2],
1934                  "struct NestedStruct { int x; SimpleStruct simple; };");
1935 }
1936 
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWrapper,r,ctxInfo)1937 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWrapper, r, ctxInfo) {
1938     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
1939     std::vector<Wrapper<DSLExpression>> exprs;
1940     exprs.push_back(DSLExpression(1));
1941     exprs.emplace_back(2.0);
1942     EXPECT_EQUAL(std::move(*exprs[0]), "1");
1943     EXPECT_EQUAL(std::move(*exprs[1]), "2.0");
1944 
1945     std::vector<Wrapper<DSLVar>> vars;
1946     vars.emplace_back(DSLVar(kInt_Type, "x"));
1947     REPORTER_ASSERT(r, DSLWriter::Var(*vars[0]).name() == "x");
1948 }
1949