blob: c1de765e0930642451b2fb5dc2c9f2c5833d9a16 [file] [log] [blame]
Ethan Nicholas762466e2017-06-29 10:03:38 -04001/*
2 * Copyright 2017 Google Inc.
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/sksl/SkSLCompiler.h"
Ethan Nicholasfc994162019-06-06 10:04:27 -04009#include "src/sksl/SkSLStringStream.h"
Ethan Nicholas762466e2017-06-29 10:03:38 -040010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "tests/Test.h"
Ethan Nicholas762466e2017-06-29 10:03:38 -040012
Ethan Nicholas762466e2017-06-29 10:03:38 -040013static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& caps,
14 std::vector<const char*> expectedH, std::vector<const char*> expectedCPP) {
15 SkSL::Program::Settings settings;
16 settings.fCaps = &caps;
17 SkSL::Compiler compiler;
18 SkSL::StringStream output;
19 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
20 SkSL::Program::kFragmentProcessor_Kind,
Brian Osman93ba0a42017-08-14 14:48:10 -040021 SkSL::String(src),
Ethan Nicholas762466e2017-06-29 10:03:38 -040022 settings);
23 if (!program) {
24 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
25 return;
26 }
27 REPORTER_ASSERT(r, program);
28 bool success = compiler.toH(*program, "Test", output);
29 if (!success) {
30 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
31 }
32 REPORTER_ASSERT(r, success);
33 if (success) {
34 for (const char* expected : expectedH) {
35 bool found = strstr(output.str().c_str(), expected);
36 if (!found) {
37 SkDebugf("HEADER MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
38 expected, output.str().c_str());
39 }
40 REPORTER_ASSERT(r, found);
41 }
42 }
43 output.reset();
44 success = compiler.toCPP(*program, "Test", output);
45 if (!success) {
46 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
47 }
48 REPORTER_ASSERT(r, success);
49 if (success) {
50 for (const char* expected : expectedCPP) {
51 bool found = strstr(output.str().c_str(), expected);
52 if (!found) {
53 SkDebugf("CPP MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
54 expected, output.str().c_str());
55 }
56 REPORTER_ASSERT(r, found);
57 }
58 }
59}
60
Ethan Nicholas33c59ed2019-08-13 10:21:38 -040061static void test_failure(skiatest::Reporter* r, const char* src, const char* error) {
62 SkSL::Compiler compiler;
63 SkSL::Program::Settings settings;
64 sk_sp<GrShaderCaps> caps = SkSL::ShaderCapsFactory::Default();
65 settings.fCaps = caps.get();
66 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
67 SkSL::Program::kFragmentProcessor_Kind,
68 SkSL::String(src),
69 settings);
70 if (!compiler.errorCount()) {
71 compiler.optimize(*program);
72 }
73 SkSL::String skError(error);
74 if (compiler.errorText() != skError) {
75 SkDebugf("SKSL ERROR:\n source: %s\n expected: %s received: %s", src, error,
76 compiler.errorText().c_str());
77 }
78 REPORTER_ASSERT(r, compiler.errorText() == skError);
79}
80
Ethan Nicholas762466e2017-06-29 10:03:38 -040081DEF_TEST(SkSLFPHelloWorld, r) {
82 test(r,
Ethan Nicholas130fb3f2018-02-01 12:14:34 -050083 "/* HEADER */"
Ethan Nicholas762466e2017-06-29 10:03:38 -040084 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -040085 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -040086 "}",
87 *SkSL::ShaderCapsFactory::Default(),
88 {
Ethan Nicholas130fb3f2018-02-01 12:14:34 -050089 "/* HEADER */\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040090 "\n"
Ethan Nicholas130fb3f2018-02-01 12:14:34 -050091 "/**************************************************************************************************\n"
92 " *** This file was autogenerated from GrTest.fp; do not modify.\n"
93 " **************************************************************************************************/\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040094 "#ifndef GrTest_DEFINED\n"
95 "#define GrTest_DEFINED\n"
Mike Reed55f6fc32020-01-21 12:23:51 -050096 "#include \"include/core/SkTypes.h\"\n"
Mike Reed46f5c5f2020-02-20 15:42:29 -050097 "#include \"include/core/SkM44.h\"\n\n"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050098 "#include \"src/gpu/GrCoordTransform.h\"\n"
99 "#include \"src/gpu/GrFragmentProcessor.h\"\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400100 "class GrTest : public GrFragmentProcessor {\n"
101 "public:\n"
Brian Salomonaff329b2017-08-11 09:40:37 -0400102 " static std::unique_ptr<GrFragmentProcessor> Make() {\n"
103 " return std::unique_ptr<GrFragmentProcessor>(new GrTest());\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400104 " }\n"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400105 " GrTest(const GrTest& src);\n"
Brian Salomonaff329b2017-08-11 09:40:37 -0400106 " std::unique_ptr<GrFragmentProcessor> clone() const override;\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400107 " const char* name() const override { return \"Test\"; }\n"
108 "private:\n"
109 " GrTest()\n"
Ethan Nicholasabff9562017-10-09 10:54:08 -0400110 " : INHERITED(kGrTest_ClassID, kNone_OptimizationFlags) {\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400111 " }\n"
112 " GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n"
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400113 " void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) const "
114 "override;\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400115 " bool onIsEqual(const GrFragmentProcessor&) const override;\n"
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400116 " GR_DECLARE_FRAGMENT_PROCESSOR_TEST\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400117 " typedef GrFragmentProcessor INHERITED;\n"
118 "};\n"
119 "#endif\n"
120 },
121 {
Ethan Nicholas130fb3f2018-02-01 12:14:34 -0500122 "/**************************************************************************************************\n"
123 " *** This file was autogenerated from GrTest.fp; do not modify.\n"
124 " **************************************************************************************************/\n"
Mike Kleinc0bd9f92019-04-23 12:05:21 -0500125 "#include \"GrTest.h\"\n\n"
Greg Daniel456f9b52020-03-05 19:14:18 +0000126 "#include \"src/gpu/GrTexture.h\"\n"
Mike Kleinc0bd9f92019-04-23 12:05:21 -0500127 "#include \"src/gpu/glsl/GrGLSLFragmentProcessor.h\"\n"
128 "#include \"src/gpu/glsl/GrGLSLFragmentShaderBuilder.h\"\n"
129 "#include \"src/gpu/glsl/GrGLSLProgramBuilder.h\"\n"
130 "#include \"src/sksl/SkSLCPP.h\"\n"
131 "#include \"src/sksl/SkSLUtil.h\"\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400132 "class GrGLSLTest : public GrGLSLFragmentProcessor {\n"
133 "public:\n"
134 " GrGLSLTest() {}\n"
135 " void emitCode(EmitArgs& args) override {\n"
136 " GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n"
137 " const GrTest& _outer = args.fFp.cast<GrTest>();\n"
138 " (void) _outer;\n"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400139 " fragBuilder->codeAppendf(\"%s = half4(1.0);\\n\", args.fOutputColor);\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400140 " }\n"
141 "private:\n"
142 " void onSetData(const GrGLSLProgramDataManager& pdman, "
143 "const GrFragmentProcessor& _proc) override {\n"
144 " }\n"
145 "};\n"
146 "GrGLSLFragmentProcessor* GrTest::onCreateGLSLInstance() const {\n"
147 " return new GrGLSLTest();\n"
148 "}\n"
149 "void GrTest::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
150 "GrProcessorKeyBuilder* b) const {\n"
151 "}\n"
152 "bool GrTest::onIsEqual(const GrFragmentProcessor& other) const {\n"
153 " const GrTest& that = other.cast<GrTest>();\n"
154 " (void) that;\n"
155 " return true;\n"
156 "}\n"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400157 "GrTest::GrTest(const GrTest& src)\n"
Ethan Nicholasabff9562017-10-09 10:54:08 -0400158 ": INHERITED(kGrTest_ClassID, src.optimizationFlags()) {\n"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400159 "}\n"
Brian Salomonaff329b2017-08-11 09:40:37 -0400160 "std::unique_ptr<GrFragmentProcessor> GrTest::clone() const {\n"
161 " return std::unique_ptr<GrFragmentProcessor>(new GrTest(*this));\n"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400162 "}\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400163 });
164}
165
166DEF_TEST(SkSLFPInput, r) {
167 test(r,
Ethan Nicholas33c59ed2019-08-13 10:21:38 -0400168 "layout(key) in half2 point;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400169 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400170 "sk_OutColor = half4(point, point);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400171 "}",
172 *SkSL::ShaderCapsFactory::Default(),
173 {
Brian Salomonaff329b2017-08-11 09:40:37 -0400174 "static std::unique_ptr<GrFragmentProcessor> Make(SkPoint point) {",
175 "return std::unique_ptr<GrFragmentProcessor>(new GrTest(point));",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400176 "GrTest(SkPoint point)",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400177 ", point(point)"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400178 },
179 {
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400180 "fragBuilder->codeAppendf(\"%s = half4(half2(%f, %f), half2(%f, %f));\\n\", "
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400181 "args.fOutputColor, _outer.point.fX, _outer.point.fY, "
182 "_outer.point.fX, _outer.point.fY);",
183 "if (point != that.point) return false;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400184 });
185}
186
187DEF_TEST(SkSLFPUniform, r) {
188 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400189 "uniform half4 color;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400190 "void main() {"
191 "sk_OutColor = color;"
192 "}",
193 *SkSL::ShaderCapsFactory::Default(),
194 {
Brian Salomonaff329b2017-08-11 09:40:37 -0400195 "static std::unique_ptr<GrFragmentProcessor> Make()"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400196 },
197 {
Ethan Nicholas16464c32020-04-06 13:53:05 -0400198 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
199 "kHalf4_GrSLType, \"color\");",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400200 });
201}
202
Michael Ludwiga4275592018-08-31 10:52:47 -0400203// SkSLFPInUniform tests the simplest plumbing case, default type, no tracking
204// with a setUniform template that supports inlining the value call with no
205// local variable.
Ethan Nicholas762466e2017-06-29 10:03:38 -0400206DEF_TEST(SkSLFPInUniform, r) {
207 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400208 "in uniform half4 color;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400209 "void main() {"
210 "sk_OutColor = color;"
211 "}",
212 *SkSL::ShaderCapsFactory::Default(),
213 {
Brian Salomonaff329b2017-08-11 09:40:37 -0400214 "static std::unique_ptr<GrFragmentProcessor> Make(SkRect color) {",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400215 },
216 {
Ethan Nicholas16464c32020-04-06 13:53:05 -0400217 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
218 "kHalf4_GrSLType, \"color\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400219 "pdman.set4fv(colorVar, 1, reinterpret_cast<const float*>(&(_outer.color)));"
Michael Ludwiga4275592018-08-31 10:52:47 -0400220 });
221}
222
223// As above, but tests in uniform's ability to override the default ctype.
224DEF_TEST(SkSLFPInUniformCType, r) {
225 test(r,
Brian Osman495993a2018-10-16 15:45:55 -0400226 "layout(ctype=SkPMColor4f) in uniform half4 color;"
Michael Ludwiga4275592018-08-31 10:52:47 -0400227 "void main() {"
228 "sk_OutColor = color;"
229 "}",
230 *SkSL::ShaderCapsFactory::Default(),
231 {
Brian Osman495993a2018-10-16 15:45:55 -0400232 "static std::unique_ptr<GrFragmentProcessor> Make(SkPMColor4f color) {",
Michael Ludwiga4275592018-08-31 10:52:47 -0400233 },
234 {
Ethan Nicholas16464c32020-04-06 13:53:05 -0400235 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
236 "kHalf4_GrSLType, \"color\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400237 "pdman.set4fv(colorVar, 1, (_outer.color).vec());"
Michael Ludwiga4275592018-08-31 10:52:47 -0400238 });
239}
240
241// Add state tracking to the default typed SkRect <-> half4 uniform. But since
242// it now has to track state, the value inlining previously done for the
243// setUniform call is removed in favor of a local variable.
244DEF_TEST(SkSLFPTrackedInUniform, r) {
245 test(r,
246 "layout(tracked) in uniform half4 color;"
247 "void main() {"
248 "sk_OutColor = color;"
249 "}",
250 *SkSL::ShaderCapsFactory::Default(),
251 {
252 "static std::unique_ptr<GrFragmentProcessor> Make(SkRect color) {",
253 },
254 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400255 "SkRect colorPrev = SkRect::MakeEmpty();",
Ethan Nicholas16464c32020-04-06 13:53:05 -0400256 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
257 "kHalf4_GrSLType, \"color\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400258 "const SkRect& colorValue = _outer.color;",
259 "if (colorPrev.isEmpty() || colorPrev != colorValue) {",
260 "colorPrev = colorValue;",
261 "pdman.set4fv(colorVar, 1, reinterpret_cast<const float*>(&colorValue));"
Michael Ludwiga4275592018-08-31 10:52:47 -0400262 });
263}
264
265// Test the case where the template does not support variable inlining in
266// setUniform (i.e. it references the value multiple times).
267DEF_TEST(SkSLFPNonInlinedInUniform, r) {
268 test(r,
269 "in uniform half2 point;"
270 "void main() {"
271 "sk_OutColor = half4(point, point);"
272 "}",
273 *SkSL::ShaderCapsFactory::Default(),
274 {
275 "static std::unique_ptr<GrFragmentProcessor> Make(SkPoint point) {",
276 },
277 {
Ethan Nicholas16464c32020-04-06 13:53:05 -0400278 "pointVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
279 "kHalf2_GrSLType, \"point\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400280 "const SkPoint& pointValue = _outer.point;",
281 "pdman.set2f(pointVar, pointValue.fX, pointValue.fY);"
Michael Ludwiga4275592018-08-31 10:52:47 -0400282 });
283}
284
285// Test handling conditional uniforms (that use when= in layout), combined with
286// state tracking and custom ctypes to really put the code generation through its paces.
287DEF_TEST(SkSLFPConditionalInUniform, r) {
288 test(r,
Ethan Nicholas33c59ed2019-08-13 10:21:38 -0400289 "layout(key) in bool test;"
Brian Osman495993a2018-10-16 15:45:55 -0400290 "layout(ctype=SkPMColor4f, tracked, when=test) in uniform half4 color;"
Michael Ludwiga4275592018-08-31 10:52:47 -0400291 "void main() {"
292 " if (test) {"
293 " sk_OutColor = color;"
294 " } else {"
295 " sk_OutColor = half4(1);"
296 " }"
297 "}",
298 *SkSL::ShaderCapsFactory::Default(),
299 {
Brian Osman495993a2018-10-16 15:45:55 -0400300 "static std::unique_ptr<GrFragmentProcessor> Make(bool test, SkPMColor4f color) {",
Michael Ludwiga4275592018-08-31 10:52:47 -0400301 },
302 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400303 "SkPMColor4f colorPrev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN}",
304 "auto test = _outer.test;",
Michael Ludwiga4275592018-08-31 10:52:47 -0400305 "if (test) {",
Ethan Nicholas16464c32020-04-06 13:53:05 -0400306 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
307 "kHalf4_GrSLType, \"color\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400308 "if (colorVar.isValid()) {",
309 "const SkPMColor4f& colorValue = _outer.color;",
310 "if (colorPrev != colorValue) {",
311 "colorPrev = colorValue;",
312 "pdman.set4fv(colorVar, 1, colorValue.vec());"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400313 });
314}
315
316DEF_TEST(SkSLFPSections, r) {
317 test(r,
318 "@header { header section }"
319 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400320 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400321 "}",
322 *SkSL::ShaderCapsFactory::Default(),
323 {
Greg Daniel3e8c3452018-04-06 10:37:55 -0400324 "header section"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400325 },
326 {});
327 test(r,
328 "@class { class section }"
329 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400330 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400331 "}",
332 *SkSL::ShaderCapsFactory::Default(),
333 {
334 "class GrTest : public GrFragmentProcessor {\n"
335 "public:\n"
336 " class section"
337 },
338 {});
339 test(r,
340 "@cpp { cpp section }"
341 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400342 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400343 "}",
344 *SkSL::ShaderCapsFactory::Default(),
345 {},
346 {"cpp section"});
347 test(r,
348 "@constructorParams { int x, float y, std::vector<float> z }"
Ethan Nicholas8aa45692017-09-20 11:24:15 -0400349 "in float w;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400350 "void main() {"
Ethan Nicholase1f55022019-02-05 17:17:40 -0500351 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400352 "}",
353 *SkSL::ShaderCapsFactory::Default(),
354 {
355 "Make(float w, int x, float y, std::vector<float> z )",
Brian Salomonaff329b2017-08-11 09:40:37 -0400356 "return std::unique_ptr<GrFragmentProcessor>(new GrTest(w, x, y, z));",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400357 "GrTest(float w, int x, float y, std::vector<float> z )",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400358 ", w(w) {"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400359 },
360 {});
361 test(r,
362 "@constructor { constructor section }"
363 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400364 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400365 "}",
366 *SkSL::ShaderCapsFactory::Default(),
367 {
368 "private:\n constructor section"
369 },
370 {});
371 test(r,
372 "@initializers { initializers section }"
373 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400374 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400375 "}",
376 *SkSL::ShaderCapsFactory::Default(),
377 {
Ethan Nicholasabff9562017-10-09 10:54:08 -0400378 ": INHERITED(kGrTest_ClassID, kNone_OptimizationFlags)\n , initializers section"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400379 },
380 {});
381 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400382 "half x = 10;"
383 "@emitCode { fragBuilder->codeAppendf(\"half y = %d\\n\", x * 2); }"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400384 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400385 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400386 "}",
387 *SkSL::ShaderCapsFactory::Default(),
388 {},
389 {
390 "x = 10.0;\n"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400391 " fragBuilder->codeAppendf(\"half y = %d\\n\", x * 2);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400392 });
393 test(r,
394 "@fields { fields section }"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400395 "@clone { }"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400396 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400397 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400398 "}",
399 *SkSL::ShaderCapsFactory::Default(),
400 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400401 "const char* name() const override { return \"Test\"; }\n"
402 " fields section private:"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400403 },
404 {});
405 test(r,
406 "@make { make section }"
407 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400408 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400409 "}",
410 *SkSL::ShaderCapsFactory::Default(),
411 {
412 "public:\n"
413 " make section"
414 },
415 {});
416 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400417 "uniform half calculated;"
Ethan Nicholas33c59ed2019-08-13 10:21:38 -0400418 "layout(key) in half provided;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400419 "@setData(varName) { varName.set1f(calculated, provided * 2); }"
420 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400421 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400422 "}",
423 *SkSL::ShaderCapsFactory::Default(),
424 {},
425 {
426 "void onSetData(const GrGLSLProgramDataManager& varName, "
427 "const GrFragmentProcessor& _proc) override {\n",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400428 "UniformHandle& calculated = calculatedVar;",
429 "auto provided = _outer.provided;",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400430 "varName.set1f(calculated, provided * 2);"
431 });
432 test(r,
433 "@test(testDataName) { testDataName section }"
434 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400435 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400436 "}",
437 *SkSL::ShaderCapsFactory::Default(),
438 {},
439 {
440 "#if GR_TEST_UTILS\n"
Brian Salomonaff329b2017-08-11 09:40:37 -0400441 "std::unique_ptr<GrFragmentProcessor> GrTest::TestCreate(GrProcessorTestData* testDataName) {\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400442 " testDataName section }\n"
443 "#endif"
444 });
445}
446
Ethan Nicholas762466e2017-06-29 10:03:38 -0400447DEF_TEST(SkSLFPTransformedCoords, r) {
448 test(r,
449 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400450 "sk_OutColor = half4(sk_TransformedCoords2D[0], sk_TransformedCoords2D[0]);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400451 "}",
452 *SkSL::ShaderCapsFactory::Default(),
453 {},
454 {
Brian Osman72a37be2017-08-15 09:19:53 -0400455 "SkString sk_TransformedCoords2D_0 = "
Ethan Nicholas58430122020-04-14 09:54:02 -0400456 "fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint, "
457 "_outer.sampleMatrix());",
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400458 "fragBuilder->codeAppendf(\"%s = half4(%s, %s);\\n\", args.fOutputColor, "
Brian Salomonbf5c0c02019-11-11 14:55:28 -0500459 "sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str());"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400460 });
Ethan Nicholas762466e2017-06-29 10:03:38 -0400461}
462
463DEF_TEST(SkSLFPLayoutWhen, r) {
464 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400465 "layout(when=someExpression(someOtherExpression())) uniform half sometimes;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400466 "void main() {"
467 "}",
468 *SkSL::ShaderCapsFactory::Default(),
469 {},
470 {
471 "if (someExpression(someOtherExpression())) {\n"
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400472 " sometimesVar = args.fUniformHandler->addUniform"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400473 });
474
475}
476
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400477DEF_TEST(SkSLFPChildProcessors, r) {
478 test(r,
479 "in fragmentProcessor child1;"
480 "in fragmentProcessor child2;"
481 "void main() {"
Ethan Nicholas13863662019-07-29 13:05:15 -0400482 " sk_OutColor = sample(child1) * sample(child2);"
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400483 "}",
484 *SkSL::ShaderCapsFactory::Default(),
485 {
486 "this->registerChildProcessor(std::move(child1));",
487 "this->registerChildProcessor(std::move(child2));"
488 },
489 {
Brian Osman978693c2020-01-24 14:52:10 -0500490 "SkString _sample93;\n",
491 "_sample93 = this->invokeChild(_outer.child1_index, args);\n",
492 "SkString _sample110;\n",
493 "_sample110 = this->invokeChild(_outer.child2_index, args);\n",
Ethan Nicholas13863662019-07-29 13:05:15 -0400494 "fragBuilder->codeAppendf(\"%s = %s * %s;\\n\", args.fOutputColor, _sample93.c_str(), "
495 "_sample110.c_str());\n",
Brian Salomonb243b432020-02-20 14:41:47 -0500496 "{",
497 " auto clone = src.childProcessor(child1_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400498 " if (src.childProcessor(child1_index).isSampledWithExplicitCoords()) {",
499 " clone->setSampledWithExplicitCoords();",
500 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500501 " this->registerChildProcessor(std::move(clone));",
502 "}",
503 "{",
504 " auto clone = src.childProcessor(child2_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400505 " if (src.childProcessor(child2_index).isSampledWithExplicitCoords()) {",
506 " clone->setSampledWithExplicitCoords();",
507 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500508 " this->registerChildProcessor(std::move(clone));",
509 "}",
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400510 });
511}
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400512
513DEF_TEST(SkSLFPChildProcessorsWithInput, r) {
514 test(r,
515 "in fragmentProcessor child1;"
516 "in fragmentProcessor child2;"
517 "void main() {"
518 " half4 childIn = sk_InColor;"
Ethan Nicholas13863662019-07-29 13:05:15 -0400519 " half4 childOut1 = sample(child1, childIn);"
520 " half4 childOut2 = sample(child2, childOut1);"
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400521 " sk_OutColor = childOut2;"
522 "}",
523 *SkSL::ShaderCapsFactory::Default(),
524 {
525 "this->registerChildProcessor(std::move(child1));",
526 "this->registerChildProcessor(std::move(child2));"
527 },
528 {
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400529 "SkString _input128(\"childIn\");",
Brian Osman978693c2020-01-24 14:52:10 -0500530 "SkString _sample128;",
531 "_sample128 = this->invokeChild(_outer.child1_index, _input128.c_str(), args);",
Ethan Nicholas13863662019-07-29 13:05:15 -0400532 "fragBuilder->codeAppendf(\"\\nhalf4 childOut1 = %s;\", _sample128.c_str());",
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400533 "SkString _input174(\"childOut1\");",
Brian Osman978693c2020-01-24 14:52:10 -0500534 "SkString _sample174;",
535 "_sample174 = this->invokeChild(_outer.child2_index, _input174.c_str(), args);",
Brian Salomonb243b432020-02-20 14:41:47 -0500536 "{",
537 " auto clone = src.childProcessor(child1_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400538 " if (src.childProcessor(child1_index).isSampledWithExplicitCoords()) {",
539 " clone->setSampledWithExplicitCoords();",
540 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500541 " this->registerChildProcessor(std::move(clone));",
542 "}",
543 "{",
544 " auto clone = src.childProcessor(child2_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400545 " if (src.childProcessor(child2_index).isSampledWithExplicitCoords()) {",
546 " clone->setSampledWithExplicitCoords();",
547 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500548 " this->registerChildProcessor(std::move(clone));",
549 "}"
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400550 });
551}
552
553DEF_TEST(SkSLFPChildProcessorWithInputExpression, r) {
554 test(r,
555 "in fragmentProcessor child;"
556 "void main() {"
Ethan Nicholas13863662019-07-29 13:05:15 -0400557 " sk_OutColor = sample(child, sk_InColor * half4(0.5));"
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400558 "}",
559 *SkSL::ShaderCapsFactory::Default(),
560 {
561 "this->registerChildProcessor(std::move(child));",
562 },
563 {
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400564 "SkString _input64 = SkStringPrintf(\"%s * half4(0.5)\", args.fInputColor);",
Brian Osman978693c2020-01-24 14:52:10 -0500565 "SkString _sample64;",
566 "_sample64 = this->invokeChild(_outer.child_index, _input64.c_str(), args);",
Ethan Nicholas13863662019-07-29 13:05:15 -0400567 "fragBuilder->codeAppendf(\"%s = %s;\\n\", args.fOutputColor, _sample64.c_str());",
Brian Salomonb243b432020-02-20 14:41:47 -0500568 "{",
569 " auto clone = src.childProcessor(child_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400570 " if (src.childProcessor(child_index).isSampledWithExplicitCoords()) {",
571 " clone->setSampledWithExplicitCoords();",
572 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500573 " this->registerChildProcessor(std::move(clone));",
574 "}",
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400575 });
576}
577
578DEF_TEST(SkSLFPNestedChildProcessors, r) {
579 test(r,
580 "in fragmentProcessor child1;"
581 "in fragmentProcessor child2;"
582 "void main() {"
Ethan Nicholas13863662019-07-29 13:05:15 -0400583 " sk_OutColor = sample(child2, sk_InColor * sample(child1, sk_InColor * half4(0.5)));"
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400584 "}",
585 *SkSL::ShaderCapsFactory::Default(),
586 {
587 "this->registerChildProcessor(std::move(child1));",
588 "this->registerChildProcessor(std::move(child2));"
589 },
590 {
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400591 "SkString _input121 = SkStringPrintf(\"%s * half4(0.5)\", args.fInputColor);",
Brian Osman978693c2020-01-24 14:52:10 -0500592 "SkString _sample121;",
593 "_sample121 = this->invokeChild(_outer.child1_index, _input121.c_str(), args);",
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400594 "SkString _input93 = SkStringPrintf(\"%s * %s\", args.fInputColor, _sample121.c_str());",
Brian Osman978693c2020-01-24 14:52:10 -0500595 "SkString _sample93;",
596 "_sample93 = this->invokeChild(_outer.child2_index, _input93.c_str(), args);",
Ethan Nicholas13863662019-07-29 13:05:15 -0400597 "fragBuilder->codeAppendf(\"%s = %s;\\n\", args.fOutputColor, _sample93.c_str());",
Brian Salomonb243b432020-02-20 14:41:47 -0500598 "{",
599 " auto clone = src.childProcessor(child1_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400600 " if (src.childProcessor(child1_index).isSampledWithExplicitCoords()) {",
601 " clone->setSampledWithExplicitCoords();",
602 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500603 " this->registerChildProcessor(std::move(clone));",
604 "}",
605 "{",
606 " auto clone = src.childProcessor(child2_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400607 " if (src.childProcessor(child2_index).isSampledWithExplicitCoords()) {",
608 " clone->setSampledWithExplicitCoords();",
609 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500610 " this->registerChildProcessor(std::move(clone));",
611 "}",
612 });
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400613}
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400614
615DEF_TEST(SkSLFPChildFPAndGlobal, r) {
616 test(r,
617 "in fragmentProcessor child;"
618 "bool hasCap = sk_Caps.externalTextureSupport;"
619 "void main() {"
620 " if (hasCap) {"
Ethan Nicholas13863662019-07-29 13:05:15 -0400621 " sk_OutColor = sample(child, sk_InColor);"
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400622 " } else {"
623 " sk_OutColor = half4(1);"
624 " }"
625 "}",
626 *SkSL::ShaderCapsFactory::Default(),
627 {
628 "this->registerChildProcessor(std::move(child));"
629 },
630 {
631 "hasCap = sk_Caps.externalTextureSupport;",
Ethan Nicholas13863662019-07-29 13:05:15 -0400632 "fragBuilder->codeAppendf(\"bool hasCap = %s;\\nif (hasCap) {\", (hasCap ? \"true\" : "
633 "\"false\"));",
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400634 "SkString _input130 = SkStringPrintf(\"%s\", args.fInputColor);",
Brian Osman978693c2020-01-24 14:52:10 -0500635 "SkString _sample130;",
636 "_sample130 = this->invokeChild(_outer.child_index, _input130.c_str(), args);",
Ethan Nicholas13863662019-07-29 13:05:15 -0400637 "fragBuilder->codeAppendf(\"\\n %s = %s;\\n} else {\\n %s = half4(1.0);\\n}\\n\","
638 " args.fOutputColor, _sample130.c_str(), args.fOutputColor);",
Brian Salomonb243b432020-02-20 14:41:47 -0500639 "{",
640 " auto clone = src.childProcessor(child_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400641 " if (src.childProcessor(child_index).isSampledWithExplicitCoords()) {",
642 " clone->setSampledWithExplicitCoords();",
643 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500644 " this->registerChildProcessor(std::move(clone));",
645 "}",
646 });
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400647}
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400648
649DEF_TEST(SkSLFPChildProcessorInlineFieldAccess, r) {
650 test(r,
651 "in fragmentProcessor child;"
652 "void main() {"
653 " if (child.preservesOpaqueInput) {"
Ethan Nicholas13863662019-07-29 13:05:15 -0400654 " sk_OutColor = sample(child, sk_InColor);"
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400655 " } else {"
656 " sk_OutColor = half4(1);"
657 " }"
658 "}",
659 *SkSL::ShaderCapsFactory::Default(),
660 {
661 "this->registerChildProcessor(std::move(child));"
662 },
663 {
664 "fragBuilder->codeAppendf(\"if (%s) {\", "
Ethan Nicholas13863662019-07-29 13:05:15 -0400665 "(_outer.childProcessor(_outer.child_index).preservesOpaqueInput() ? ",
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400666 "SkString _input105 = SkStringPrintf(\"%s\", args.fInputColor);",
Brian Osman978693c2020-01-24 14:52:10 -0500667 "SkString _sample105;",
668 "_sample105 = this->invokeChild(_outer.child_index, _input105.c_str(), args);",
Ethan Nicholas13863662019-07-29 13:05:15 -0400669 "fragBuilder->codeAppendf(\"\\n %s = %s;\\n} else {\\n %s = half4(1.0);\\n}\\n\","
670 " args.fOutputColor, _sample105.c_str(), args.fOutputColor);",
Brian Salomonb243b432020-02-20 14:41:47 -0500671 "{",
672 " auto clone = src.childProcessor(child_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400673 " if (src.childProcessor(child_index).isSampledWithExplicitCoords()) {",
674 " clone->setSampledWithExplicitCoords();",
675 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500676 " this->registerChildProcessor(std::move(clone));",
677 "}",
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400678 });
679}
680
681DEF_TEST(SkSLFPChildProcessorFieldAccess, r) {
682 test(r,
683 "in fragmentProcessor child;"
684 "bool opaque = child.preservesOpaqueInput;"
685 "void main() {"
686 " if (opaque) {"
Ethan Nicholas13863662019-07-29 13:05:15 -0400687 " sk_OutColor = sample(child);"
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400688 " } else {"
689 " sk_OutColor = half4(0.5);"
690 " }"
691 "}",
692 *SkSL::ShaderCapsFactory::Default(),
693 {
694 "this->registerChildProcessor(std::move(child));"
695 },
696 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400697 "opaque = _outer.childProcessor(_outer.child_index).preservesOpaqueInput();",
Ethan Nicholas13863662019-07-29 13:05:15 -0400698 "fragBuilder->codeAppendf(\"bool opaque = %s;\\nif (opaque) {\", (opaque ? \"true\" : "
699 "\"false\"));",
Brian Osman978693c2020-01-24 14:52:10 -0500700 "SkString _sample126;",
701 "_sample126 = this->invokeChild(_outer.child_index, args);",
Ethan Nicholas13863662019-07-29 13:05:15 -0400702 "fragBuilder->codeAppendf(\"\\n %s = %s;\\n} else {\\n %s = half4(0.5);\\n}\\n\","
703 " args.fOutputColor, _sample126.c_str(), args.fOutputColor);",
Brian Salomonb243b432020-02-20 14:41:47 -0500704 "{",
705 " auto clone = src.childProcessor(child_index).clone();",
Ethan Nicholas58430122020-04-14 09:54:02 -0400706 " if (src.childProcessor(child_index).isSampledWithExplicitCoords()) {",
707 " clone->setSampledWithExplicitCoords();",
708 " }",
Brian Salomonb243b432020-02-20 14:41:47 -0500709 " this->registerChildProcessor(std::move(clone));",
710 "}",
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400711 });
712}
Florin Malita390f9bd2019-03-04 12:25:57 -0500713
714DEF_TEST(SkSLFPNullableChildProcessor, r) {
715 test(r,
716 "in fragmentProcessor? child;"
717 "void main() {"
718 " if (child != null) {"
Ethan Nicholas13863662019-07-29 13:05:15 -0400719 " sk_OutColor = sample(child);"
Florin Malita390f9bd2019-03-04 12:25:57 -0500720 " } else {"
721 " sk_OutColor = half4(0.5);"
722 " }"
723 "}",
724 *SkSL::ShaderCapsFactory::Default(),
725 {},
726 {
Ethan Nicholas13863662019-07-29 13:05:15 -0400727 "fragBuilder->codeAppendf(\"if (%s) {\", _outer.child_index >= 0 ? \"true\" : "
728 "\"false\");",
Brian Osman978693c2020-01-24 14:52:10 -0500729 "SkString _sample93;",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400730 "if (_outer.child_index >= 0) {",
Brian Osman978693c2020-01-24 14:52:10 -0500731 "_sample93 = this->invokeChild(_outer.child_index, args);",
Florin Malita390f9bd2019-03-04 12:25:57 -0500732 "}",
Ethan Nicholas13863662019-07-29 13:05:15 -0400733 "fragBuilder->codeAppendf(\"\\n %s = %s;\\n} else {\\n %s = half4(0.5);\\n}\\n\","
734 " args.fOutputColor, _sample93.c_str(), args.fOutputColor);"
735
Florin Malita390f9bd2019-03-04 12:25:57 -0500736 });
737}
Ethan Nicholas33c59ed2019-08-13 10:21:38 -0400738
739DEF_TEST(SkSLFPBadIn, r) {
740 test_failure(r,
741 "in half4 c;"
742 "void main() {"
743 " sk_OutColor = c;"
744 "}",
745 "error: 1: 'in' variable must be either 'uniform' or 'layout(key)', or there must be a "
746 "custom @setData function\n1 error\n");
747}
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400748
749DEF_TEST(SkSLFPSampleCoords, r) {
750 test(r,
751 "in fragmentProcessor child;"
752 "@coordTransform { SkMatrix() }"
753 "void main() {"
754 " sk_OutColor = sample(child) + sample(child, sk_TransformedCoords2D[0] / 2);"
755 "}",
756 *SkSL::ShaderCapsFactory::Default(),
757 {},
758 {
Brian Osman978693c2020-01-24 14:52:10 -0500759 "SkString _sample94;\n",
760 "_sample94 = this->invokeChild(_outer.child_index, args);\n",
761 "SkString _sample110;\n",
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400762 "SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D("
Ethan Nicholas58430122020-04-14 09:54:02 -0400763 "args.fTransformedCoords[0].fVaryingPoint, "
764 "_outer.sampleMatrix());\n",
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400765 "SkString _coords110 = SkStringPrintf(\"%s / 2.0\", "
Brian Salomonbf5c0c02019-11-11 14:55:28 -0500766 "sk_TransformedCoords2D_0.c_str());\n",
Brian Osman978693c2020-01-24 14:52:10 -0500767 "_sample110 = this->invokeChild(_outer.child_index, args, _coords110.c_str());\n",
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400768 "fragBuilder->codeAppendf(\"%s = %s + %s;\\n\", args.fOutputColor, _sample94.c_str(), "
769 "_sample110.c_str());\n"
770 });
771}
Ethan Nicholas095f5b42019-08-30 11:51:41 -0400772
773DEF_TEST(SkSLFPFunction, r) {
774 test(r,
775 "in fragmentProcessor? child;"
776 "half4 flip(half4 c) { return c.abgr; }"
777 "void main() {"
778 " sk_OutColor = flip(sk_InColor);"
779 "}",
780 *SkSL::ShaderCapsFactory::Default(),
781 {},
782 {
783 "SkString flip_name;",
784 "const GrShaderVar flip_args[] = { GrShaderVar(\"c\", kHalf4_GrSLType)};",
785 "fragBuilder->emitFunction(kHalf4_GrSLType, \"flip\", 1, flip_args, "
786 "\"return c.wzyx;\\n\", &flip_name);",
Robert Phillips1b63b4a2020-05-19 15:38:05 +0000787 "fragBuilder->codeAppendf(\"%s = %s(%s);\\n\", args.fOutputColor, flip_name.c_str(), "
788 "args.fInputColor);"
Ethan Nicholas095f5b42019-08-30 11:51:41 -0400789 });
790}
Ethan Nicholas58430122020-04-14 09:54:02 -0400791
792DEF_TEST(SkSLFPMatrixSample, r) {
793 test(r,
794 "in fragmentProcessor? child;"
795 "void main() {"
796 " sk_OutColor = sample(child, float3x3(2));"
797 "}",
798 *SkSL::ShaderCapsFactory::Default(),
799 {},
800 {
801 });
802}