blob: 0586b5ad36df1e2508f6f858afef67109c5c3ae9 [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 Nicholas762466e2017-06-29 10:03:38 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "tests/Test.h"
Ethan Nicholas762466e2017-06-29 10:03:38 -040011
Ethan Nicholas762466e2017-06-29 10:03:38 -040012static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& caps,
13 std::vector<const char*> expectedH, std::vector<const char*> expectedCPP) {
14 SkSL::Program::Settings settings;
15 settings.fCaps = &caps;
16 SkSL::Compiler compiler;
17 SkSL::StringStream output;
18 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
19 SkSL::Program::kFragmentProcessor_Kind,
Brian Osman93ba0a42017-08-14 14:48:10 -040020 SkSL::String(src),
Ethan Nicholas762466e2017-06-29 10:03:38 -040021 settings);
22 if (!program) {
23 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
24 return;
25 }
26 REPORTER_ASSERT(r, program);
27 bool success = compiler.toH(*program, "Test", output);
28 if (!success) {
29 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
30 }
31 REPORTER_ASSERT(r, success);
32 if (success) {
33 for (const char* expected : expectedH) {
34 bool found = strstr(output.str().c_str(), expected);
35 if (!found) {
36 SkDebugf("HEADER MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
37 expected, output.str().c_str());
38 }
39 REPORTER_ASSERT(r, found);
40 }
41 }
42 output.reset();
43 success = compiler.toCPP(*program, "Test", output);
44 if (!success) {
45 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
46 }
47 REPORTER_ASSERT(r, success);
48 if (success) {
49 for (const char* expected : expectedCPP) {
50 bool found = strstr(output.str().c_str(), expected);
51 if (!found) {
52 SkDebugf("CPP MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
53 expected, output.str().c_str());
54 }
55 REPORTER_ASSERT(r, found);
56 }
57 }
58}
59
60DEF_TEST(SkSLFPHelloWorld, r) {
61 test(r,
Ethan Nicholas130fb3f2018-02-01 12:14:34 -050062 "/* HEADER */"
Ethan Nicholas762466e2017-06-29 10:03:38 -040063 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -040064 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -040065 "}",
66 *SkSL::ShaderCapsFactory::Default(),
67 {
Ethan Nicholas130fb3f2018-02-01 12:14:34 -050068 "/* HEADER */\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040069 "\n"
Ethan Nicholas130fb3f2018-02-01 12:14:34 -050070 "/**************************************************************************************************\n"
71 " *** This file was autogenerated from GrTest.fp; do not modify.\n"
72 " **************************************************************************************************/\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040073 "#ifndef GrTest_DEFINED\n"
74 "#define GrTest_DEFINED\n"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050075 "#include \"include/core/SkTypes.h\"\n\n"
76 "#include \"src/gpu/GrCoordTransform.h\"\n"
77 "#include \"src/gpu/GrFragmentProcessor.h\"\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040078 "class GrTest : public GrFragmentProcessor {\n"
79 "public:\n"
Brian Salomonaff329b2017-08-11 09:40:37 -040080 " static std::unique_ptr<GrFragmentProcessor> Make() {\n"
81 " return std::unique_ptr<GrFragmentProcessor>(new GrTest());\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040082 " }\n"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -040083 " GrTest(const GrTest& src);\n"
Brian Salomonaff329b2017-08-11 09:40:37 -040084 " std::unique_ptr<GrFragmentProcessor> clone() const override;\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040085 " const char* name() const override { return \"Test\"; }\n"
86 "private:\n"
87 " GrTest()\n"
Ethan Nicholasabff9562017-10-09 10:54:08 -040088 " : INHERITED(kGrTest_ClassID, kNone_OptimizationFlags) {\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040089 " }\n"
90 " GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n"
Ethan Nicholasbcd51e82019-04-09 10:40:41 -040091 " void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) const "
92 "override;\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040093 " bool onIsEqual(const GrFragmentProcessor&) const override;\n"
Brian Salomon0c26a9d2017-07-06 10:09:38 -040094 " GR_DECLARE_FRAGMENT_PROCESSOR_TEST\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040095 " typedef GrFragmentProcessor INHERITED;\n"
96 "};\n"
97 "#endif\n"
98 },
99 {
Ethan Nicholas130fb3f2018-02-01 12:14:34 -0500100 "/**************************************************************************************************\n"
101 " *** This file was autogenerated from GrTest.fp; do not modify.\n"
102 " **************************************************************************************************/\n"
Mike Kleinc0bd9f92019-04-23 12:05:21 -0500103 "#include \"GrTest.h\"\n\n"
104 "#include \"include/gpu/GrTexture.h\"\n"
105 "#include \"src/gpu/glsl/GrGLSLFragmentProcessor.h\"\n"
106 "#include \"src/gpu/glsl/GrGLSLFragmentShaderBuilder.h\"\n"
107 "#include \"src/gpu/glsl/GrGLSLProgramBuilder.h\"\n"
108 "#include \"src/sksl/SkSLCPP.h\"\n"
109 "#include \"src/sksl/SkSLUtil.h\"\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400110 "class GrGLSLTest : public GrGLSLFragmentProcessor {\n"
111 "public:\n"
112 " GrGLSLTest() {}\n"
113 " void emitCode(EmitArgs& args) override {\n"
114 " GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n"
115 " const GrTest& _outer = args.fFp.cast<GrTest>();\n"
116 " (void) _outer;\n"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400117 " fragBuilder->codeAppendf(\"%s = half4(1.0);\\n\", args.fOutputColor);\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400118 " }\n"
119 "private:\n"
120 " void onSetData(const GrGLSLProgramDataManager& pdman, "
121 "const GrFragmentProcessor& _proc) override {\n"
122 " }\n"
123 "};\n"
124 "GrGLSLFragmentProcessor* GrTest::onCreateGLSLInstance() const {\n"
125 " return new GrGLSLTest();\n"
126 "}\n"
127 "void GrTest::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
128 "GrProcessorKeyBuilder* b) const {\n"
129 "}\n"
130 "bool GrTest::onIsEqual(const GrFragmentProcessor& other) const {\n"
131 " const GrTest& that = other.cast<GrTest>();\n"
132 " (void) that;\n"
133 " return true;\n"
134 "}\n"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400135 "GrTest::GrTest(const GrTest& src)\n"
Ethan Nicholasabff9562017-10-09 10:54:08 -0400136 ": INHERITED(kGrTest_ClassID, src.optimizationFlags()) {\n"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400137 "}\n"
Brian Salomonaff329b2017-08-11 09:40:37 -0400138 "std::unique_ptr<GrFragmentProcessor> GrTest::clone() const {\n"
139 " return std::unique_ptr<GrFragmentProcessor>(new GrTest(*this));\n"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400140 "}\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400141 });
142}
143
144DEF_TEST(SkSLFPInput, r) {
145 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400146 "in half2 point;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400147 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400148 "sk_OutColor = half4(point, point);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400149 "}",
150 *SkSL::ShaderCapsFactory::Default(),
151 {
Brian Salomonaff329b2017-08-11 09:40:37 -0400152 "static std::unique_ptr<GrFragmentProcessor> Make(SkPoint point) {",
153 "return std::unique_ptr<GrFragmentProcessor>(new GrTest(point));",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400154 "GrTest(SkPoint point)",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400155 ", point(point)"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400156 },
157 {
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400158 "fragBuilder->codeAppendf(\"%s = half4(half2(%f, %f), half2(%f, %f));\\n\", "
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400159 "args.fOutputColor, _outer.point.fX, _outer.point.fY, "
160 "_outer.point.fX, _outer.point.fY);",
161 "if (point != that.point) return false;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400162 });
163}
164
165DEF_TEST(SkSLFPUniform, r) {
166 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400167 "uniform half4 color;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400168 "void main() {"
169 "sk_OutColor = color;"
170 "}",
171 *SkSL::ShaderCapsFactory::Default(),
172 {
Brian Salomonaff329b2017-08-11 09:40:37 -0400173 "static std::unique_ptr<GrFragmentProcessor> Make()"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400174 },
175 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400176 "colorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, "
177 "\"color\");",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400178 });
179}
180
Michael Ludwiga4275592018-08-31 10:52:47 -0400181// SkSLFPInUniform tests the simplest plumbing case, default type, no tracking
182// with a setUniform template that supports inlining the value call with no
183// local variable.
Ethan Nicholas762466e2017-06-29 10:03:38 -0400184DEF_TEST(SkSLFPInUniform, r) {
185 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400186 "in uniform half4 color;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400187 "void main() {"
188 "sk_OutColor = color;"
189 "}",
190 *SkSL::ShaderCapsFactory::Default(),
191 {
Brian Salomonaff329b2017-08-11 09:40:37 -0400192 "static std::unique_ptr<GrFragmentProcessor> Make(SkRect color) {",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400193 },
194 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400195 "colorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, "
196 "\"color\");",
197 "pdman.set4fv(colorVar, 1, reinterpret_cast<const float*>(&(_outer.color)));"
Michael Ludwiga4275592018-08-31 10:52:47 -0400198 });
199}
200
201// As above, but tests in uniform's ability to override the default ctype.
202DEF_TEST(SkSLFPInUniformCType, r) {
203 test(r,
Brian Osman495993a2018-10-16 15:45:55 -0400204 "layout(ctype=SkPMColor4f) in uniform half4 color;"
Michael Ludwiga4275592018-08-31 10:52:47 -0400205 "void main() {"
206 "sk_OutColor = color;"
207 "}",
208 *SkSL::ShaderCapsFactory::Default(),
209 {
Brian Osman495993a2018-10-16 15:45:55 -0400210 "static std::unique_ptr<GrFragmentProcessor> Make(SkPMColor4f color) {",
Michael Ludwiga4275592018-08-31 10:52:47 -0400211 },
212 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400213 "colorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, "
214 "\"color\");",
215 "pdman.set4fv(colorVar, 1, (_outer.color).vec());"
Michael Ludwiga4275592018-08-31 10:52:47 -0400216 });
217}
218
219// Add state tracking to the default typed SkRect <-> half4 uniform. But since
220// it now has to track state, the value inlining previously done for the
221// setUniform call is removed in favor of a local variable.
222DEF_TEST(SkSLFPTrackedInUniform, r) {
223 test(r,
224 "layout(tracked) in uniform half4 color;"
225 "void main() {"
226 "sk_OutColor = color;"
227 "}",
228 *SkSL::ShaderCapsFactory::Default(),
229 {
230 "static std::unique_ptr<GrFragmentProcessor> Make(SkRect color) {",
231 },
232 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400233 "SkRect colorPrev = SkRect::MakeEmpty();",
234 "colorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, "
235 "\"color\");",
236 "const SkRect& colorValue = _outer.color;",
237 "if (colorPrev.isEmpty() || colorPrev != colorValue) {",
238 "colorPrev = colorValue;",
239 "pdman.set4fv(colorVar, 1, reinterpret_cast<const float*>(&colorValue));"
Michael Ludwiga4275592018-08-31 10:52:47 -0400240 });
241}
242
243// Test the case where the template does not support variable inlining in
244// setUniform (i.e. it references the value multiple times).
245DEF_TEST(SkSLFPNonInlinedInUniform, r) {
246 test(r,
247 "in uniform half2 point;"
248 "void main() {"
249 "sk_OutColor = half4(point, point);"
250 "}",
251 *SkSL::ShaderCapsFactory::Default(),
252 {
253 "static std::unique_ptr<GrFragmentProcessor> Make(SkPoint point) {",
254 },
255 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400256 "pointVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "
257 "\"point\");",
258 "const SkPoint& pointValue = _outer.point;",
259 "pdman.set2f(pointVar, pointValue.fX, pointValue.fY);"
Michael Ludwiga4275592018-08-31 10:52:47 -0400260 });
261}
262
263// Test handling conditional uniforms (that use when= in layout), combined with
264// state tracking and custom ctypes to really put the code generation through its paces.
265DEF_TEST(SkSLFPConditionalInUniform, r) {
266 test(r,
267 "in bool test;"
Brian Osman495993a2018-10-16 15:45:55 -0400268 "layout(ctype=SkPMColor4f, tracked, when=test) in uniform half4 color;"
Michael Ludwiga4275592018-08-31 10:52:47 -0400269 "void main() {"
270 " if (test) {"
271 " sk_OutColor = color;"
272 " } else {"
273 " sk_OutColor = half4(1);"
274 " }"
275 "}",
276 *SkSL::ShaderCapsFactory::Default(),
277 {
Brian Osman495993a2018-10-16 15:45:55 -0400278 "static std::unique_ptr<GrFragmentProcessor> Make(bool test, SkPMColor4f color) {",
Michael Ludwiga4275592018-08-31 10:52:47 -0400279 },
280 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400281 "SkPMColor4f colorPrev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN}",
282 "auto test = _outer.test;",
Michael Ludwiga4275592018-08-31 10:52:47 -0400283 "if (test) {",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400284 "colorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, "
285 "\"color\");",
286 "if (colorVar.isValid()) {",
287 "const SkPMColor4f& colorValue = _outer.color;",
288 "if (colorPrev != colorValue) {",
289 "colorPrev = colorValue;",
290 "pdman.set4fv(colorVar, 1, colorValue.vec());"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400291 });
292}
293
294DEF_TEST(SkSLFPSections, r) {
295 test(r,
296 "@header { header section }"
297 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400298 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400299 "}",
300 *SkSL::ShaderCapsFactory::Default(),
301 {
Greg Daniel3e8c3452018-04-06 10:37:55 -0400302 "header section"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400303 },
304 {});
305 test(r,
306 "@class { class section }"
307 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400308 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400309 "}",
310 *SkSL::ShaderCapsFactory::Default(),
311 {
312 "class GrTest : public GrFragmentProcessor {\n"
313 "public:\n"
314 " class section"
315 },
316 {});
317 test(r,
318 "@cpp { cpp 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 {},
324 {"cpp section"});
325 test(r,
326 "@constructorParams { int x, float y, std::vector<float> z }"
Ethan Nicholas8aa45692017-09-20 11:24:15 -0400327 "in float w;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400328 "void main() {"
Ethan Nicholase1f55022019-02-05 17:17:40 -0500329 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400330 "}",
331 *SkSL::ShaderCapsFactory::Default(),
332 {
333 "Make(float w, int x, float y, std::vector<float> z )",
Brian Salomonaff329b2017-08-11 09:40:37 -0400334 "return std::unique_ptr<GrFragmentProcessor>(new GrTest(w, x, y, z));",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400335 "GrTest(float w, int x, float y, std::vector<float> z )",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400336 ", w(w) {"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400337 },
338 {});
339 test(r,
340 "@constructor { constructor 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 "private:\n constructor section"
347 },
348 {});
349 test(r,
350 "@initializers { initializers section }"
351 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400352 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400353 "}",
354 *SkSL::ShaderCapsFactory::Default(),
355 {
Ethan Nicholasabff9562017-10-09 10:54:08 -0400356 ": INHERITED(kGrTest_ClassID, kNone_OptimizationFlags)\n , initializers section"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400357 },
358 {});
359 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400360 "half x = 10;"
361 "@emitCode { fragBuilder->codeAppendf(\"half y = %d\\n\", x * 2); }"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400362 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400363 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400364 "}",
365 *SkSL::ShaderCapsFactory::Default(),
366 {},
367 {
368 "x = 10.0;\n"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400369 " fragBuilder->codeAppendf(\"half y = %d\\n\", x * 2);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400370 });
371 test(r,
372 "@fields { fields section }"
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400373 "@clone { }"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400374 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400375 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400376 "}",
377 *SkSL::ShaderCapsFactory::Default(),
378 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400379 "const char* name() const override { return \"Test\"; }\n"
380 " fields section private:"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400381 },
382 {});
383 test(r,
384 "@make { make section }"
385 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400386 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400387 "}",
388 *SkSL::ShaderCapsFactory::Default(),
389 {
390 "public:\n"
391 " make section"
392 },
393 {});
394 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400395 "uniform half calculated;"
396 "in half provided;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400397 "@setData(varName) { varName.set1f(calculated, provided * 2); }"
398 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400399 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400400 "}",
401 *SkSL::ShaderCapsFactory::Default(),
402 {},
403 {
404 "void onSetData(const GrGLSLProgramDataManager& varName, "
405 "const GrFragmentProcessor& _proc) override {\n",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400406 "UniformHandle& calculated = calculatedVar;",
407 "auto provided = _outer.provided;",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400408 "varName.set1f(calculated, provided * 2);"
409 });
410 test(r,
411 "@test(testDataName) { testDataName section }"
412 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400413 "sk_OutColor = half4(1);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400414 "}",
415 *SkSL::ShaderCapsFactory::Default(),
416 {},
417 {
418 "#if GR_TEST_UTILS\n"
Brian Salomonaff329b2017-08-11 09:40:37 -0400419 "std::unique_ptr<GrFragmentProcessor> GrTest::TestCreate(GrProcessorTestData* testDataName) {\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400420 " testDataName section }\n"
421 "#endif"
422 });
423}
424
Ethan Nicholas762466e2017-06-29 10:03:38 -0400425DEF_TEST(SkSLFPTransformedCoords, r) {
426 test(r,
427 "void main() {"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400428 "sk_OutColor = half4(sk_TransformedCoords2D[0], sk_TransformedCoords2D[0]);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400429 "}",
430 *SkSL::ShaderCapsFactory::Default(),
431 {},
432 {
Brian Osman72a37be2017-08-15 09:19:53 -0400433 "SkString sk_TransformedCoords2D_0 = "
Ethan Nicholas762466e2017-06-29 10:03:38 -0400434 "fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);",
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400435 "fragBuilder->codeAppendf(\"%s = half4(%s, %s);\\n\", args.fOutputColor, "
Ethan Nicholas762466e2017-06-29 10:03:38 -0400436 "sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str());"
437 });
438
439}
440
441DEF_TEST(SkSLFPLayoutWhen, r) {
442 test(r,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400443 "layout(when=someExpression(someOtherExpression())) uniform half sometimes;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400444 "void main() {"
445 "}",
446 *SkSL::ShaderCapsFactory::Default(),
447 {},
448 {
449 "if (someExpression(someOtherExpression())) {\n"
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400450 " sometimesVar = args.fUniformHandler->addUniform"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400451 });
452
453}
454
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400455DEF_TEST(SkSLFPChildProcessors, r) {
456 test(r,
457 "in fragmentProcessor child1;"
458 "in fragmentProcessor child2;"
459 "void main() {"
460 " sk_OutColor = process(child1) * process(child2);"
461 "}",
462 *SkSL::ShaderCapsFactory::Default(),
463 {
464 "this->registerChildProcessor(std::move(child1));",
465 "this->registerChildProcessor(std::move(child2));"
466 },
467 {
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000468 "SkString _child0(\"_child0\");",
469 "this->emitChild(_outer.child1_index, &_child0, args);",
470 "SkString _child1(\"_child1\");",
471 "this->emitChild(_outer.child2_index, &_child1, args);",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400472 "this->registerChildProcessor(src.childProcessor(child1_index).clone());",
473 "this->registerChildProcessor(src.childProcessor(child2_index).clone());"
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400474 });
475}
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400476
477DEF_TEST(SkSLFPChildProcessorsWithInput, r) {
478 test(r,
479 "in fragmentProcessor child1;"
480 "in fragmentProcessor child2;"
481 "void main() {"
482 " half4 childIn = sk_InColor;"
483 " half4 childOut1 = process(child1, childIn);"
484 " half4 childOut2 = process(child2, childOut1);"
485 " sk_OutColor = childOut2;"
486 "}",
487 *SkSL::ShaderCapsFactory::Default(),
488 {
489 "this->registerChildProcessor(std::move(child1));",
490 "this->registerChildProcessor(std::move(child2));"
491 },
492 {
493 "SkString _input0(\"childIn\");",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000494 "SkString _child0(\"_child0\");",
495 "this->emitChild(_outer.child1_index, _input0.c_str(), &_child0, args);",
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400496 "SkString _input1(\"childOut1\");",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000497 "SkString _child1(\"_child1\");",
498 "this->emitChild(_outer.child2_index, _input1.c_str(), &_child1, args);",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400499 "this->registerChildProcessor(src.childProcessor(child1_index).clone());",
500 "this->registerChildProcessor(src.childProcessor(child2_index).clone());"
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400501 });
502}
503
504DEF_TEST(SkSLFPChildProcessorWithInputExpression, r) {
505 test(r,
506 "in fragmentProcessor child;"
507 "void main() {"
508 " sk_OutColor = process(child, sk_InColor * half4(0.5));"
509 "}",
510 *SkSL::ShaderCapsFactory::Default(),
511 {
512 "this->registerChildProcessor(std::move(child));",
513 },
514 {
515 "SkString _input0 = SkStringPrintf(\"%s * half4(0.5)\", args.fInputColor);",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000516 "SkString _child0(\"_child0\");",
517 "this->emitChild(_outer.child_index, _input0.c_str(), &_child0, args);",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400518 "this->registerChildProcessor(src.childProcessor(child_index).clone());",
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400519 });
520}
521
522DEF_TEST(SkSLFPNestedChildProcessors, r) {
523 test(r,
524 "in fragmentProcessor child1;"
525 "in fragmentProcessor child2;"
526 "void main() {"
527 " sk_OutColor = process(child2, sk_InColor * process(child1, sk_InColor * half4(0.5)));"
528 "}",
529 *SkSL::ShaderCapsFactory::Default(),
530 {
531 "this->registerChildProcessor(std::move(child1));",
532 "this->registerChildProcessor(std::move(child2));"
533 },
534 {
535 "SkString _input0 = SkStringPrintf(\"%s * half4(0.5)\", args.fInputColor);",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000536 "SkString _child0(\"_child0\");",
537 "this->emitChild(_outer.child1_index, _input0.c_str(), &_child0, args);",
538 "SkString _input1 = SkStringPrintf(\"%s * %s\", args.fInputColor, _child0.c_str());",
539 "SkString _child1(\"_child1\");",
540 "this->emitChild(_outer.child2_index, _input1.c_str(), &_child1, args);",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400541 "this->registerChildProcessor(src.childProcessor(child1_index).clone());",
542 "this->registerChildProcessor(src.childProcessor(child2_index).clone());"
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400543 });
544}
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400545
546DEF_TEST(SkSLFPChildFPAndGlobal, r) {
547 test(r,
548 "in fragmentProcessor child;"
549 "bool hasCap = sk_Caps.externalTextureSupport;"
550 "void main() {"
551 " if (hasCap) {"
552 " sk_OutColor = process(child, sk_InColor);"
553 " } else {"
554 " sk_OutColor = half4(1);"
555 " }"
556 "}",
557 *SkSL::ShaderCapsFactory::Default(),
558 {
559 "this->registerChildProcessor(std::move(child));"
560 },
561 {
562 "hasCap = sk_Caps.externalTextureSupport;",
563 "fragBuilder->codeAppendf(\"bool hasCap = %s;\\nif (hasCap) {\", "
564 "(hasCap ? \"true\" : \"false\"));",
565 "SkString _input0 = SkStringPrintf(\"%s\", args.fInputColor);",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000566 "SkString _child0(\"_child0\");",
567 "this->emitChild(_outer.child_index, _input0.c_str(), &_child0, args);",
568 "fragBuilder->codeAppendf(\"\\n %s = %s;\\n} else {\\n %s = half4(1.0);\\n}"
569 "\\n\", args.fOutputColor, _child0.c_str(), args.fOutputColor);",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400570 "this->registerChildProcessor(src.childProcessor(child_index).clone());"
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400571 });
572}
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400573
574DEF_TEST(SkSLFPChildProcessorInlineFieldAccess, r) {
575 test(r,
576 "in fragmentProcessor child;"
577 "void main() {"
578 " if (child.preservesOpaqueInput) {"
579 " sk_OutColor = process(child, sk_InColor);"
580 " } else {"
581 " sk_OutColor = half4(1);"
582 " }"
583 "}",
584 *SkSL::ShaderCapsFactory::Default(),
585 {
586 "this->registerChildProcessor(std::move(child));"
587 },
588 {
589 "fragBuilder->codeAppendf(\"if (%s) {\", "
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400590 "(_outer.childProcessor(_outer.child_index).preservesOpaqueInput() ? "
Ethan Nicholasee1c8a72019-02-22 10:50:47 -0500591 "\"true\" : \"false\"));",
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400592 "SkString _input0 = SkStringPrintf(\"%s\", args.fInputColor);",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000593 "SkString _child0(\"_child0\");",
594 "this->emitChild(_outer.child_index, _input0.c_str(), &_child0, args);",
595 "fragBuilder->codeAppendf(\"\\n %s = %s;\\n} else {\\n %s = half4(1.0);\\n}\\n\""
596 ", args.fOutputColor, _child0.c_str(), args.fOutputColor);",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400597 "this->registerChildProcessor(src.childProcessor(child_index).clone());"
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400598 });
599}
600
601DEF_TEST(SkSLFPChildProcessorFieldAccess, r) {
602 test(r,
603 "in fragmentProcessor child;"
604 "bool opaque = child.preservesOpaqueInput;"
605 "void main() {"
606 " if (opaque) {"
607 " sk_OutColor = process(child);"
608 " } else {"
609 " sk_OutColor = half4(0.5);"
610 " }"
611 "}",
612 *SkSL::ShaderCapsFactory::Default(),
613 {
614 "this->registerChildProcessor(std::move(child));"
615 },
616 {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400617 "opaque = _outer.childProcessor(_outer.child_index).preservesOpaqueInput();",
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400618 "fragBuilder->codeAppendf(\"bool opaque = %s;\\nif (opaque) {\", "
619 "(opaque ? \"true\" : \"false\"));",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000620 "SkString _child0(\"_child0\");",
621 "this->emitChild(_outer.child_index, &_child0, args);",
622 "fragBuilder->codeAppendf(\"\\n %s = %s;\\n} else {\\n %s = half4(0.5);\\n}\\n\""
623 ", args.fOutputColor, _child0.c_str(), args.fOutputColor);",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400624 "this->registerChildProcessor(src.childProcessor(child_index).clone());"
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400625 });
626}
Florin Malita390f9bd2019-03-04 12:25:57 -0500627
628DEF_TEST(SkSLFPNullableChildProcessor, r) {
629 test(r,
630 "in fragmentProcessor? child;"
631 "void main() {"
632 " if (child != null) {"
633 " sk_OutColor = process(child);"
634 " } else {"
635 " sk_OutColor = half4(0.5);"
636 " }"
637 "}",
638 *SkSL::ShaderCapsFactory::Default(),
639 {},
640 {
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000641 "SkString _child0(\"_child0\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400642 "if (_outer.child_index >= 0) {",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000643 "this->emitChild(_outer.child_index, &_child0, args);",
Florin Malita390f9bd2019-03-04 12:25:57 -0500644 "} else {",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000645 "fragBuilder->codeAppendf(\"half4 %s;\", _child0.c_str());",
Florin Malita390f9bd2019-03-04 12:25:57 -0500646 "}",
Ethan Nicholas6ad52892019-05-03 13:13:42 +0000647 "fragBuilder->codeAppendf(\"\\n %s = %s;\\n} else {\\n %s = half4(0.5);\\n}\\n\""
648 ", args.fOutputColor, _child0.c_str(), args.fOutputColor);",
Florin Malita390f9bd2019-03-04 12:25:57 -0500649 });
650}