blob: e8516dc19784ce93a1b20bb9d7961322eca7076e [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
John Stiles88183902020-06-10 16:40:38 -040013static void test(skiatest::Reporter* r, const GrShaderCaps& caps, const char* src,
Ethan Nicholas762466e2017-06-29 10:03:38 -040014 std::vector<const char*> expectedH, std::vector<const char*> expectedCPP) {
15 SkSL::Program::Settings settings;
16 settings.fCaps = &caps;
Ethan Nicholase8ad02c2020-06-03 16:58:20 -040017 settings.fRemoveDeadFunctions = false;
Ethan Nicholas762466e2017-06-29 10:03:38 -040018 SkSL::Compiler compiler;
19 SkSL::StringStream output;
20 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
21 SkSL::Program::kFragmentProcessor_Kind,
Brian Osman93ba0a42017-08-14 14:48:10 -040022 SkSL::String(src),
Ethan Nicholas762466e2017-06-29 10:03:38 -040023 settings);
24 if (!program) {
25 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
26 return;
27 }
28 REPORTER_ASSERT(r, program);
29 bool success = compiler.toH(*program, "Test", output);
30 if (!success) {
31 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
32 }
33 REPORTER_ASSERT(r, success);
34 if (success) {
35 for (const char* expected : expectedH) {
36 bool found = strstr(output.str().c_str(), expected);
37 if (!found) {
John Stiles50819422020-06-18 13:00:38 -040038 SkDebugf("HEADER MISMATCH:\nsource:\n%s\n\n"
39 "header expected:\n'%s'\n\n"
40 "header received:\n'%s'",
John Stiles88183902020-06-10 16:40:38 -040041 src, expected, output.str().c_str());
Ethan Nicholas762466e2017-06-29 10:03:38 -040042 }
43 REPORTER_ASSERT(r, found);
44 }
45 }
46 output.reset();
47 success = compiler.toCPP(*program, "Test", output);
48 if (!success) {
49 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
50 }
51 REPORTER_ASSERT(r, success);
52 if (success) {
53 for (const char* expected : expectedCPP) {
54 bool found = strstr(output.str().c_str(), expected);
55 if (!found) {
John Stiles50819422020-06-18 13:00:38 -040056 SkDebugf("CPP MISMATCH:\nsource:\n%s\n\n"
57 "cpp expected:\n'%s'\n\n"
58 "cpp received:\n'%s'",
John Stiles88183902020-06-10 16:40:38 -040059 src, expected, output.str().c_str());
Ethan Nicholas762466e2017-06-29 10:03:38 -040060 }
61 REPORTER_ASSERT(r, found);
62 }
63 }
64}
65
Ethan Nicholas33c59ed2019-08-13 10:21:38 -040066static void test_failure(skiatest::Reporter* r, const char* src, const char* error) {
67 SkSL::Compiler compiler;
68 SkSL::Program::Settings settings;
69 sk_sp<GrShaderCaps> caps = SkSL::ShaderCapsFactory::Default();
70 settings.fCaps = caps.get();
71 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
72 SkSL::Program::kFragmentProcessor_Kind,
73 SkSL::String(src),
74 settings);
75 if (!compiler.errorCount()) {
76 compiler.optimize(*program);
77 }
78 SkSL::String skError(error);
79 if (compiler.errorText() != skError) {
John Stiles88183902020-06-10 16:40:38 -040080 SkDebugf("SKSL ERROR:\n source: %s\n expected: %s received: %s",
81 src, error, compiler.errorText().c_str());
Ethan Nicholas33c59ed2019-08-13 10:21:38 -040082 }
83 REPORTER_ASSERT(r, compiler.errorText() == skError);
84}
85
Ethan Nicholas762466e2017-06-29 10:03:38 -040086DEF_TEST(SkSLFPHelloWorld, r) {
87 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -040088 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -040089 R"__SkSL__(
John Stiles50819422020-06-18 13:00:38 -040090 /* HELLO WORLD */
John Stiles88183902020-06-10 16:40:38 -040091 void main() {
92 sk_OutColor = half4(1);
93 }
94 )__SkSL__",
95 /*expectedH=*/{
John Stiles50819422020-06-18 13:00:38 -040096R"__Header__(/* HELLO WORLD */
John Stiles88183902020-06-10 16:40:38 -040097
98/**************************************************************************************************
99 *** This file was autogenerated from GrTest.fp; do not modify.
100 **************************************************************************************************/
101#ifndef GrTest_DEFINED
102#define GrTest_DEFINED
103
104#include "include/core/SkM44.h"
105#include "include/core/SkTypes.h"
106
107
John Stiles88183902020-06-10 16:40:38 -0400108#include "src/gpu/GrFragmentProcessor.h"
109
110class GrTest : public GrFragmentProcessor {
111public:
112 static std::unique_ptr<GrFragmentProcessor> Make() {
113 return std::unique_ptr<GrFragmentProcessor>(new GrTest());
114 }
115 GrTest(const GrTest& src);
116 std::unique_ptr<GrFragmentProcessor> clone() const override;
117 const char* name() const override { return "Test"; }
118private:
119 GrTest()
120 : INHERITED(kGrTest_ClassID, kNone_OptimizationFlags) {
121 }
122 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
123 void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) const override;
124 bool onIsEqual(const GrFragmentProcessor&) const override;
125 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
126 typedef GrFragmentProcessor INHERITED;
127};
128#endif
129)__Header__"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400130 },
John Stiles88183902020-06-10 16:40:38 -0400131 /*expectedCPP=*/{
John Stiles50819422020-06-18 13:00:38 -0400132R"__Cpp__(/* HELLO WORLD */
133
134/**************************************************************************************************
John Stiles88183902020-06-10 16:40:38 -0400135 *** This file was autogenerated from GrTest.fp; do not modify.
136 **************************************************************************************************/
137#include "GrTest.h"
138
139#include "src/gpu/GrTexture.h"
140#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
141#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
142#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
143#include "src/sksl/SkSLCPP.h"
144#include "src/sksl/SkSLUtil.h"
145class GrGLSLTest : public GrGLSLFragmentProcessor {
146public:
147 GrGLSLTest() {}
148 void emitCode(EmitArgs& args) override {
149 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
150 const GrTest& _outer = args.fFp.cast<GrTest>();
151 (void) _outer;
John Stiles50819422020-06-18 13:00:38 -0400152 fragBuilder->codeAppendf(
153R"SkSL(%s = half4(1.0);
154)SkSL"
155, args.fOutputColor);
John Stiles88183902020-06-10 16:40:38 -0400156 }
157private:
158 void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
159 }
160};
161GrGLSLFragmentProcessor* GrTest::onCreateGLSLInstance() const {
162 return new GrGLSLTest();
163}
164void GrTest::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
165}
166bool GrTest::onIsEqual(const GrFragmentProcessor& other) const {
167 const GrTest& that = other.cast<GrTest>();
168 (void) that;
169 return true;
170}
171GrTest::GrTest(const GrTest& src)
172: INHERITED(kGrTest_ClassID, src.optimizationFlags()) {
Brian Osman12c5d292020-07-13 16:11:35 -0400173 this->cloneAndRegisterAllChildProcessors(src);
John Stiles88183902020-06-10 16:40:38 -0400174}
175std::unique_ptr<GrFragmentProcessor> GrTest::clone() const {
176 return std::unique_ptr<GrFragmentProcessor>(new GrTest(*this));
177}
178)__Cpp__"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400179 });
180}
181
182DEF_TEST(SkSLFPInput, r) {
183 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400184 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400185 R"__SkSL__(
186 layout(key) in half2 point;
187 void main() {
188 sk_OutColor = half4(point, point);
189 }
190 )__SkSL__",
191 /*expectedH=*/{
Brian Salomonaff329b2017-08-11 09:40:37 -0400192 "static std::unique_ptr<GrFragmentProcessor> Make(SkPoint point) {",
193 "return std::unique_ptr<GrFragmentProcessor>(new GrTest(point));",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400194 "GrTest(SkPoint point)",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400195 ", point(point)"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400196 },
John Stiles88183902020-06-10 16:40:38 -0400197 /*expectedCPP=*/{
John Stiles50819422020-06-18 13:00:38 -0400198 "fragBuilder->codeAppendf(\n"
199 "R\"SkSL(%s = half4(half2(%f, %f), half2(%f, %f));\n"
200 ")SkSL\"\n"
201 ", args.fOutputColor, _outer.point.fX, _outer.point.fY, _outer.point.fX, _outer.point.fY);",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400202 "if (point != that.point) return false;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400203 });
204}
205
206DEF_TEST(SkSLFPUniform, r) {
207 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400208 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400209 R"__SkSL__(
210 uniform half4 color;
211 void main() {
212 sk_OutColor = color;
213 }
214 )__SkSL__",
215 /*expectedH=*/{
Brian Salomonaff329b2017-08-11 09:40:37 -0400216 "static std::unique_ptr<GrFragmentProcessor> Make()"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400217 },
John Stiles88183902020-06-10 16:40:38 -0400218 /*expectedCPP=*/{
219 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
Ethan Nicholas16464c32020-04-06 13:53:05 -0400220 "kHalf4_GrSLType, \"color\");",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400221 });
222}
223
Michael Ludwiga4275592018-08-31 10:52:47 -0400224// SkSLFPInUniform tests the simplest plumbing case, default type, no tracking
225// with a setUniform template that supports inlining the value call with no
226// local variable.
Ethan Nicholas762466e2017-06-29 10:03:38 -0400227DEF_TEST(SkSLFPInUniform, r) {
228 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400229 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400230 R"__SkSL__(
231 in uniform half4 color;
232 void main() {
233 sk_OutColor = color;
234 }
235 )__SkSL__",
236 /*expectedH=*/{
Brian Salomonaff329b2017-08-11 09:40:37 -0400237 "static std::unique_ptr<GrFragmentProcessor> Make(SkRect color) {",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400238 },
John Stiles88183902020-06-10 16:40:38 -0400239 /*expectedCPP=*/{
Ethan Nicholas16464c32020-04-06 13:53:05 -0400240 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
241 "kHalf4_GrSLType, \"color\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400242 "pdman.set4fv(colorVar, 1, reinterpret_cast<const float*>(&(_outer.color)));"
Michael Ludwiga4275592018-08-31 10:52:47 -0400243 });
244}
245
246// As above, but tests in uniform's ability to override the default ctype.
247DEF_TEST(SkSLFPInUniformCType, r) {
248 test(r,
Michael Ludwiga4275592018-08-31 10:52:47 -0400249 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400250 R"__SkSL__(
251 layout(ctype=SkPMColor4f) in uniform half4 color;
252 void main() {
253 sk_OutColor = color;
254 }
255 )__SkSL__",
256 /*expectedH=*/{
Brian Osman495993a2018-10-16 15:45:55 -0400257 "static std::unique_ptr<GrFragmentProcessor> Make(SkPMColor4f color) {",
Michael Ludwiga4275592018-08-31 10:52:47 -0400258 },
John Stiles88183902020-06-10 16:40:38 -0400259 /*expectedCPP=*/{
Ethan Nicholas16464c32020-04-06 13:53:05 -0400260 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
261 "kHalf4_GrSLType, \"color\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400262 "pdman.set4fv(colorVar, 1, (_outer.color).vec());"
Michael Ludwiga4275592018-08-31 10:52:47 -0400263 });
264}
265
266// Add state tracking to the default typed SkRect <-> half4 uniform. But since
267// it now has to track state, the value inlining previously done for the
268// setUniform call is removed in favor of a local variable.
269DEF_TEST(SkSLFPTrackedInUniform, r) {
270 test(r,
Michael Ludwiga4275592018-08-31 10:52:47 -0400271 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400272 R"__SkSL__(
273 layout(tracked) in uniform half4 color;
274 void main() {
275 sk_OutColor = color;
276 }
277 )__SkSL__",
278 /*expectedH=*/{
Michael Ludwiga4275592018-08-31 10:52:47 -0400279 "static std::unique_ptr<GrFragmentProcessor> Make(SkRect color) {",
280 },
John Stiles88183902020-06-10 16:40:38 -0400281 /*expectedCPP=*/{
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400282 "SkRect colorPrev = SkRect::MakeEmpty();",
Ethan Nicholas16464c32020-04-06 13:53:05 -0400283 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
284 "kHalf4_GrSLType, \"color\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400285 "const SkRect& colorValue = _outer.color;",
286 "if (colorPrev.isEmpty() || colorPrev != colorValue) {",
287 "colorPrev = colorValue;",
288 "pdman.set4fv(colorVar, 1, reinterpret_cast<const float*>(&colorValue));"
Michael Ludwiga4275592018-08-31 10:52:47 -0400289 });
290}
291
292// Test the case where the template does not support variable inlining in
293// setUniform (i.e. it references the value multiple times).
294DEF_TEST(SkSLFPNonInlinedInUniform, r) {
295 test(r,
Michael Ludwiga4275592018-08-31 10:52:47 -0400296 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400297 R"__SkSL__(
298 in uniform half2 point;
299 void main() {
300 sk_OutColor = half4(point, point);
301 }
302 )__SkSL__",
303 /*expectedH=*/{
Michael Ludwiga4275592018-08-31 10:52:47 -0400304 "static std::unique_ptr<GrFragmentProcessor> Make(SkPoint point) {",
305 },
John Stiles88183902020-06-10 16:40:38 -0400306 /*expectedCPP=*/{
Ethan Nicholas16464c32020-04-06 13:53:05 -0400307 "pointVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
308 "kHalf2_GrSLType, \"point\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400309 "const SkPoint& pointValue = _outer.point;",
310 "pdman.set2f(pointVar, pointValue.fX, pointValue.fY);"
Michael Ludwiga4275592018-08-31 10:52:47 -0400311 });
312}
313
314// Test handling conditional uniforms (that use when= in layout), combined with
315// state tracking and custom ctypes to really put the code generation through its paces.
316DEF_TEST(SkSLFPConditionalInUniform, r) {
317 test(r,
Michael Ludwiga4275592018-08-31 10:52:47 -0400318 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400319 R"__SkSL__(
320 layout(key) in bool test;
321 layout(ctype=SkPMColor4f, tracked, when=test) in uniform half4 color;
322 void main() {
323 if (test) {
324 sk_OutColor = color;
325 } else {
326 sk_OutColor = half4(1);
327 }
328 }
329 )__SkSL__",
330 /*expectedH=*/{
Brian Osman495993a2018-10-16 15:45:55 -0400331 "static std::unique_ptr<GrFragmentProcessor> Make(bool test, SkPMColor4f color) {",
Michael Ludwiga4275592018-08-31 10:52:47 -0400332 },
John Stiles88183902020-06-10 16:40:38 -0400333 /*expectedCPP=*/{
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400334 "SkPMColor4f colorPrev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN}",
335 "auto test = _outer.test;",
Michael Ludwiga4275592018-08-31 10:52:47 -0400336 "if (test) {",
Ethan Nicholas16464c32020-04-06 13:53:05 -0400337 "colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, "
338 "kHalf4_GrSLType, \"color\");",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400339 "if (colorVar.isValid()) {",
340 "const SkPMColor4f& colorValue = _outer.color;",
341 "if (colorPrev != colorValue) {",
342 "colorPrev = colorValue;",
343 "pdman.set4fv(colorVar, 1, colorValue.vec());"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400344 });
345}
346
347DEF_TEST(SkSLFPSections, r) {
348 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400349 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400350 R"__SkSL__(
351 @header { header section }
352 void main() {
353 sk_OutColor = half4(1);
354 }
355 )__SkSL__",
356 /*expectedH=*/{
Greg Daniel3e8c3452018-04-06 10:37:55 -0400357 "header section"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400358 },
John Stiles88183902020-06-10 16:40:38 -0400359 /*expectedCPP=*/{});
Ethan Nicholas762466e2017-06-29 10:03:38 -0400360 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400361 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400362 R"__SkSL__(
363 @class { class section }
364 void main() {
365 sk_OutColor = half4(1);
366 }
367 )__SkSL__",
368 /*expectedH=*/{
Ethan Nicholas762466e2017-06-29 10:03:38 -0400369 "class GrTest : public GrFragmentProcessor {\n"
370 "public:\n"
371 " class section"
372 },
John Stiles88183902020-06-10 16:40:38 -0400373 /*expectedCPP=*/{});
Ethan Nicholas762466e2017-06-29 10:03:38 -0400374 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400375 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400376 R"__SkSL__(
377 @cpp { cpp section }
378 void main() {
379 sk_OutColor = half4(1);
380 }
381 )__SkSL__",
382 /*expectedH=*/{},
383 /*expectedCPP=*/{
384 "cpp section"
385 });
Ethan Nicholas762466e2017-06-29 10:03:38 -0400386 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400387 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400388 R"__SkSL__(
389 @constructorParams { int x, float y, std::vector<float> z }
390 in float w;
391 void main() {
392 sk_OutColor = half4(1);
393 }
394 )__SkSL__",
395 /*expectedH=*/{
Ethan Nicholas762466e2017-06-29 10:03:38 -0400396 "Make(float w, int x, float y, std::vector<float> z )",
Brian Salomonaff329b2017-08-11 09:40:37 -0400397 "return std::unique_ptr<GrFragmentProcessor>(new GrTest(w, x, y, z));",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400398 "GrTest(float w, int x, float y, std::vector<float> z )",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400399 ", w(w) {"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400400 },
John Stiles88183902020-06-10 16:40:38 -0400401 /*expectedCPP=*/{});
Ethan Nicholas762466e2017-06-29 10:03:38 -0400402 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400403 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400404 R"__SkSL__(
405 @constructor { constructor section }
406 void main() {
407 sk_OutColor = half4(1);
408 }
409 )__SkSL__",
410 /*expectedH=*/{
Ethan Nicholas762466e2017-06-29 10:03:38 -0400411 "private:\n constructor section"
412 },
John Stiles88183902020-06-10 16:40:38 -0400413 /*expectedCPP=*/{});
Ethan Nicholas762466e2017-06-29 10:03:38 -0400414 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400415 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400416 R"__SkSL__(
417 @initializers { initializers section }
418 void main() {
419 sk_OutColor = half4(1);
420 }
421 )__SkSL__",
422 /*expectedH=*/{
Ethan Nicholasabff9562017-10-09 10:54:08 -0400423 ": INHERITED(kGrTest_ClassID, kNone_OptimizationFlags)\n , initializers section"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400424 },
John Stiles88183902020-06-10 16:40:38 -0400425 /*expectedCPP=*/{});
Ethan Nicholas762466e2017-06-29 10:03:38 -0400426 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400427 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400428 R"__SkSL__(
429 half x = 10;
430 @emitCode { fragBuilder->codeAppendf("half y = %d\n", x * 2); }
431 void main() {
432 sk_OutColor = half4(1);
433 }
434 )__SkSL__",
435 /*expectedH=*/{},
436 /*expectedCPP=*/{
Ethan Nicholas762466e2017-06-29 10:03:38 -0400437 "x = 10.0;\n"
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400438 " fragBuilder->codeAppendf(\"half y = %d\\n\", x * 2);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400439 });
440 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400441 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400442 R"__SkSL__(
443 @fields { fields section }
444 @clone { }
445 void main() {
446 sk_OutColor = half4(1);
447 }
448 )__SkSL__",
449 /*expectedH=*/{
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400450 "const char* name() const override { return \"Test\"; }\n"
451 " fields section private:"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400452 },
John Stiles88183902020-06-10 16:40:38 -0400453 /*expectedCPP=*/{});
Ethan Nicholas762466e2017-06-29 10:03:38 -0400454 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400455 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400456 R"__SkSL__(
457 @make { make section }
458 void main() {
459 sk_OutColor = half4(1);
460 }
461 )__SkSL__",
462 /*expectedH=*/{
Ethan Nicholas762466e2017-06-29 10:03:38 -0400463 "public:\n"
464 " make section"
465 },
John Stiles88183902020-06-10 16:40:38 -0400466 /*expectedCPP=*/{});
Ethan Nicholas762466e2017-06-29 10:03:38 -0400467 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400468 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400469 R"__SkSL__(
470 uniform half calculated;
471 layout(key) in half provided;
472 @setData(varName) { varName.set1f(calculated, provided * 2); }
473 void main() {
474 sk_OutColor = half4(1);
475 }
476 )__SkSL__",
477 /*expectedH=*/{},
478 /*expectedCPP=*/{
Ethan Nicholas762466e2017-06-29 10:03:38 -0400479 "void onSetData(const GrGLSLProgramDataManager& varName, "
480 "const GrFragmentProcessor& _proc) override {\n",
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400481 "UniformHandle& calculated = calculatedVar;",
482 "auto provided = _outer.provided;",
Ethan Nicholas762466e2017-06-29 10:03:38 -0400483 "varName.set1f(calculated, provided * 2);"
484 });
485 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400486 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400487 R"__SkSL__(
488 @test(testDataName) { testDataName section }
489 void main() {
490 sk_OutColor = half4(1);
491 }
492 )__SkSL__",
493 /*expectedH=*/{},
494 /*expectedCPP=*/{
Ethan Nicholas762466e2017-06-29 10:03:38 -0400495 "#if GR_TEST_UTILS\n"
Brian Salomonaff329b2017-08-11 09:40:37 -0400496 "std::unique_ptr<GrFragmentProcessor> GrTest::TestCreate(GrProcessorTestData* testDataName) {\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400497 " testDataName section }\n"
498 "#endif"
499 });
500}
501
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400502DEF_TEST(SkSLFPMainCoords, r) {
Ethan Nicholas762466e2017-06-29 10:03:38 -0400503 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400504 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400505 R"__SkSL__(
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400506 void main(float2 coord) {
507 sk_OutColor = half4(coord, coord);
John Stiles88183902020-06-10 16:40:38 -0400508 }
509 )__SkSL__",
Michael Ludwige88320b2020-06-24 09:04:56 -0400510 /*expectedH=*/{
511 "this->setUsesSampleCoordsDirectly();"
512 },
John Stiles88183902020-06-10 16:40:38 -0400513 /*expectedCPP=*/{
John Stiles50819422020-06-18 13:00:38 -0400514 "fragBuilder->codeAppendf(\n"
515 "R\"SkSL(%s = half4(%s, %s);\n"
516 ")SkSL\"\n"
Michael Ludwige88320b2020-06-24 09:04:56 -0400517 ", args.fOutputColor, args.fSampleCoord, args.fSampleCoord);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400518 });
Ethan Nicholas762466e2017-06-29 10:03:38 -0400519}
520
521DEF_TEST(SkSLFPLayoutWhen, r) {
522 test(r,
Ethan Nicholas762466e2017-06-29 10:03:38 -0400523 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400524 R"__SkSL__(
525 layout(when=someExpression(someOtherExpression())) uniform half sometimes;
526 void main() {
527 }
528 )__SkSL__",
529 /*expectedH=*/{},
530 /*expectedCPP=*/{
Ethan Nicholas762466e2017-06-29 10:03:38 -0400531 "if (someExpression(someOtherExpression())) {\n"
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400532 " sometimesVar = args.fUniformHandler->addUniform"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400533 });
Ethan Nicholas762466e2017-06-29 10:03:38 -0400534}
535
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400536DEF_TEST(SkSLFPChildProcessors, r) {
537 test(r,
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400538 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400539 R"__SkSL__(
540 in fragmentProcessor child1;
541 in fragmentProcessor child2;
542 void main() {
543 sk_OutColor = sample(child1) * sample(child2);
544 }
545 )__SkSL__",
546 /*expectedH=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400547 "this->registerChild(std::move(child1), SkSL::SampleUsage::PassThrough());",
548 "this->registerChild(std::move(child2), SkSL::SampleUsage::PassThrough());"
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400549 },
John Stiles88183902020-06-10 16:40:38 -0400550 /*expectedCPP=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400551 "SkString _sample149 = this->invokeChild(0, args);\n",
552 "SkString _sample166 = this->invokeChild(1, args);\n",
John Stiles50819422020-06-18 13:00:38 -0400553 "fragBuilder->codeAppendf(\n"
554 "R\"SkSL(%s = %s * %s;\n"
555 ")SkSL\"\n"
556 ", args.fOutputColor, _sample149.c_str(), _sample166.c_str());",
Brian Osman12c5d292020-07-13 16:11:35 -0400557 "this->cloneAndRegisterAllChildProcessors(src);",
Ethan Nicholasc9472af2017-10-10 16:30:21 -0400558 });
559}
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400560
561DEF_TEST(SkSLFPChildProcessorsWithInput, r) {
562 test(r,
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400563 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400564 R"__SkSL__(
565 in fragmentProcessor child1;
566 in fragmentProcessor child2;
567 void main() {
568 half4 childIn = sk_InColor;
569 half4 childOut1 = sample(child1, childIn);
570 half4 childOut2 = sample(child2, childOut1);
571 sk_OutColor = childOut2;
572 }
573 )__SkSL__",
574 /*expectedH=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400575 "this->registerChild(std::move(child1), SkSL::SampleUsage::PassThrough());",
576 "this->registerChild(std::move(child2), SkSL::SampleUsage::PassThrough());"
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400577 },
John Stiles88183902020-06-10 16:40:38 -0400578 /*expectedCPP=*/{
579 "SkString _input198(\"childIn\");",
Brian Osman12c5d292020-07-13 16:11:35 -0400580 "SkString _sample198 = this->invokeChild(0, _input198.c_str(), args);",
John Stiles50819422020-06-18 13:00:38 -0400581 "fragBuilder->codeAppendf(\n"
582 "R\"SkSL(\n"
583 "half4 childOut1 = %s;)SkSL\"\n"
584 ", _sample198.c_str());",
John Stiles88183902020-06-10 16:40:38 -0400585 "SkString _input258(\"childOut1\");",
Brian Osman12c5d292020-07-13 16:11:35 -0400586 "SkString _sample258 = this->invokeChild(1, _input258.c_str(), args);",
587 "this->cloneAndRegisterAllChildProcessors(src);",
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400588 });
589}
590
591DEF_TEST(SkSLFPChildProcessorWithInputExpression, r) {
592 test(r,
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400593 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400594 R"__SkSL__(
595 in fragmentProcessor child;
596 void main() {
597 sk_OutColor = sample(child, sk_InColor * half4(0.5));
598 }
599 )__SkSL__",
600 /*expectedH=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400601 "this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());",
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400602 },
John Stiles88183902020-06-10 16:40:38 -0400603 /*expectedCPP=*/{
604 "SkString _input106 = SkStringPrintf(\"%s * half4(0.5)\", args.fInputColor);",
Brian Osman12c5d292020-07-13 16:11:35 -0400605 "SkString _sample106 = this->invokeChild(0, _input106.c_str(), args);",
John Stiles50819422020-06-18 13:00:38 -0400606 "fragBuilder->codeAppendf(\n"
607 "R\"SkSL(%s = %s;\n"
608 ")SkSL\"\n"
609 ", args.fOutputColor, _sample106.c_str());",
Brian Osman12c5d292020-07-13 16:11:35 -0400610 "this->cloneAndRegisterAllChildProcessors(src);",
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400611 });
612}
613
614DEF_TEST(SkSLFPNestedChildProcessors, r) {
615 test(r,
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400616 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400617 R"__SkSL__(
618 in fragmentProcessor child1;
619 in fragmentProcessor child2;
620 void main() {
621 sk_OutColor = sample(child2, sk_InColor * sample(child1, sk_InColor * half4(0.5)));
622 }
623 )__SkSL__",
624 /*expectedH=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400625 "this->registerChild(std::move(child1), SkSL::SampleUsage::PassThrough());",
626 "this->registerChild(std::move(child2), SkSL::SampleUsage::PassThrough());"
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400627 },
John Stiles88183902020-06-10 16:40:38 -0400628 /*expectedCPP=*/{
629 "SkString _input177 = SkStringPrintf(\"%s * half4(0.5)\", args.fInputColor);",
Brian Osman12c5d292020-07-13 16:11:35 -0400630 "SkString _sample177 = this->invokeChild(0, _input177.c_str(), args);",
John Stiles88183902020-06-10 16:40:38 -0400631 "SkString _input149 = SkStringPrintf(\"%s * %s\", args.fInputColor, _sample177.c_str());",
Brian Osman12c5d292020-07-13 16:11:35 -0400632 "SkString _sample149 = this->invokeChild(1, _input149.c_str(), args);",
John Stiles50819422020-06-18 13:00:38 -0400633 "fragBuilder->codeAppendf(\n"
634 "R\"SkSL(%s = %s;\n"
635 ")SkSL\"\n"
636 ", args.fOutputColor, _sample149.c_str());",
Brian Osman12c5d292020-07-13 16:11:35 -0400637 "this->cloneAndRegisterAllChildProcessors(src);",
Brian Salomonb243b432020-02-20 14:41:47 -0500638 });
Michael Ludwig92e4c7f2018-08-30 16:08:18 -0400639}
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400640
641DEF_TEST(SkSLFPChildFPAndGlobal, r) {
642 test(r,
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400643 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400644 R"__SkSL__(
645 in fragmentProcessor child;
646 bool hasCap = sk_Caps.externalTextureSupport;
647 void main() {
648 if (hasCap) {
649 sk_OutColor = sample(child, sk_InColor);
650 } else {
651 sk_OutColor = half4(1);
652 }
653 }
654 )__SkSL__",
655 /*expectedH=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400656 "this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());"
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400657 },
John Stiles88183902020-06-10 16:40:38 -0400658 /*expectedCPP=*/{
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400659 "hasCap = sk_Caps.externalTextureSupport;",
John Stiles50819422020-06-18 13:00:38 -0400660
661 "fragBuilder->codeAppendf(\n"
662 "R\"SkSL(bool hasCap = %s;\n"
663 "if (hasCap) {)SkSL\"\n"
664 ", (hasCap ? \"true\" : \"false\"));",
665 "SkString _input200(args.fInputColor);",
Brian Osman12c5d292020-07-13 16:11:35 -0400666 "SkString _sample200 = this->invokeChild(0, _input200.c_str(), args);",
John Stiles50819422020-06-18 13:00:38 -0400667 "fragBuilder->codeAppendf(\n"
668 "R\"SkSL(\n"
669 " %s = %s;\n"
670 "} else {\n"
671 " %s = half4(1.0);\n"
672 "}\n"
673 ")SkSL\"\n"
674 ", args.fOutputColor, _sample200.c_str(), args.fOutputColor);",
Brian Osman12c5d292020-07-13 16:11:35 -0400675 "this->cloneAndRegisterAllChildProcessors(src);",
John Stiles88183902020-06-10 16:40:38 -0400676 });
Michael Ludwig1fc5fbd2018-09-07 13:13:06 -0400677}
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400678
679DEF_TEST(SkSLFPChildProcessorInlineFieldAccess, r) {
680 test(r,
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400681 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400682 R"__SkSL__(
683 in fragmentProcessor child;
684 void main() {
685 if (child.preservesOpaqueInput) {
686 sk_OutColor = sample(child, sk_InColor);
687 } else {
688 sk_OutColor = half4(1);
689 }
690 }
691 )__SkSL__",
692 /*expectedH=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400693 "this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());"
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400694 },
John Stiles88183902020-06-10 16:40:38 -0400695 /*expectedCPP=*/{
John Stiles50819422020-06-18 13:00:38 -0400696 "fragBuilder->codeAppendf(\n"
697 "R\"SkSL(if (%s) {)SkSL\"\n"
Brian Osman12c5d292020-07-13 16:11:35 -0400698 ", (_outer.childProcessor(0)->preservesOpaqueInput() ? \"true\" : \"false\"));",
John Stiles50819422020-06-18 13:00:38 -0400699 "SkString _input161(args.fInputColor);",
Brian Osman12c5d292020-07-13 16:11:35 -0400700 "SkString _sample161 = this->invokeChild(0, _input161.c_str(), args);",
John Stiles50819422020-06-18 13:00:38 -0400701 "fragBuilder->codeAppendf(\n"
702 "R\"SkSL(\n"
703 " %s = %s;\n"
704 "} else {\n"
705 " %s = half4(1.0);\n"
706 "}\n"
707 ")SkSL\"\n"
708 ", args.fOutputColor, _sample161.c_str(), args.fOutputColor);",
Brian Osman12c5d292020-07-13 16:11:35 -0400709 "this->cloneAndRegisterAllChildProcessors(src);",
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400710 });
711}
712
713DEF_TEST(SkSLFPChildProcessorFieldAccess, r) {
714 test(r,
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400715 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400716 R"__SkSL__(
717 in fragmentProcessor child;
718 bool opaque = child.preservesOpaqueInput;
719 void main() {
720 if (opaque) {
721 sk_OutColor = sample(child);
722 } else {
723 sk_OutColor = half4(0.5);
724 }
725 }
726 )__SkSL__",
727 /*expectedH=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400728 "this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());"
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400729 },
John Stiles88183902020-06-10 16:40:38 -0400730 /*expectedCPP=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400731 "opaque = _outer.childProcessor(0)->preservesOpaqueInput();",
John Stiles50819422020-06-18 13:00:38 -0400732 "fragBuilder->codeAppendf(\n"
733 "R\"SkSL(bool opaque = %s;\n"
734 "if (opaque) {)SkSL\"\n"
735 ", (opaque ? \"true\" : \"false\"));",
Brian Osman12c5d292020-07-13 16:11:35 -0400736 "SkString _sample196 = this->invokeChild(0, args);",
John Stiles50819422020-06-18 13:00:38 -0400737 "fragBuilder->codeAppendf(\n"
738 "R\"SkSL(\n"
739 " %s = %s;\n"
740 "} else {\n"
741 " %s = half4(0.5);\n"
742 "}\n"
743 ")SkSL\"\n"
744 ", args.fOutputColor, _sample196.c_str(), args.fOutputColor);",
Brian Osman12c5d292020-07-13 16:11:35 -0400745 "this->cloneAndRegisterAllChildProcessors(src);",
Michael Ludwig9094f2c2018-09-07 13:44:21 -0400746 });
747}
Florin Malita390f9bd2019-03-04 12:25:57 -0500748
749DEF_TEST(SkSLFPNullableChildProcessor, r) {
750 test(r,
Florin Malita390f9bd2019-03-04 12:25:57 -0500751 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400752 R"__SkSL__(
753 in fragmentProcessor? child;
754 void main() {
755 if (child != null) {
756 sk_OutColor = sample(child);
757 } else {
758 sk_OutColor = half4(0.5);
759 }
760 }
761 )__SkSL__",
762 /*expectedH=*/{},
763 /*expectedCPP=*/{
John Stiles50819422020-06-18 13:00:38 -0400764 "fragBuilder->codeAppendf(\n"
765 "R\"SkSL(if (%s) {)SkSL\"\n"
Brian Osman12c5d292020-07-13 16:11:35 -0400766 ", _outer.childProcessor(0) ? \"true\" : \"false\");",
767 "SkString _sample149 = this->invokeChild(0, args);",
John Stiles50819422020-06-18 13:00:38 -0400768 "fragBuilder->codeAppendf(\n"
769 "R\"SkSL(\n"
770 " %s = %s;\n"
771 "} else {\n"
772 " %s = half4(0.5);\n"
773 "}\n"
774 ")SkSL\"\n"
775 ", args.fOutputColor, _sample149.c_str(), args.fOutputColor);",
Florin Malita390f9bd2019-03-04 12:25:57 -0500776 });
777}
Ethan Nicholas33c59ed2019-08-13 10:21:38 -0400778
779DEF_TEST(SkSLFPBadIn, r) {
780 test_failure(r,
John Stiles88183902020-06-10 16:40:38 -0400781 R"__SkSL__(
782 in half4 c;
783 void main() {
784 sk_OutColor = c;
785 }
786 )__SkSL__",
787 "error: 4: 'in' variable must be either 'uniform' or 'layout(key)', or there must be a "
Ethan Nicholas33c59ed2019-08-13 10:21:38 -0400788 "custom @setData function\n1 error\n");
789}
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400790
791DEF_TEST(SkSLFPSampleCoords, r) {
792 test(r,
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400793 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400794 R"__SkSL__(
795 in fragmentProcessor child;
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400796 void main(float2 coord) {
797 sk_OutColor = sample(child) + sample(child, coord / 2);
John Stiles88183902020-06-10 16:40:38 -0400798 }
799 )__SkSL__",
Michael Ludwig9aba6252020-06-22 14:46:36 -0400800 /*expectedH=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400801 "this->registerChild(std::move(child), SkSL::SampleUsage(SkSL::SampleUsage::Kind::kNone, \"\", false, true, true));",
Michael Ludwige88320b2020-06-24 09:04:56 -0400802 "this->setUsesSampleCoordsDirectly();"
Michael Ludwig9aba6252020-06-22 14:46:36 -0400803 },
John Stiles88183902020-06-10 16:40:38 -0400804 /*expectedCPP=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400805 "SkString _sample118 = this->invokeChild(0, args);\n",
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400806 "SkString _coords134 = SkStringPrintf(\"%s / 2.0\", args.fSampleCoord);\n",
Brian Osman12c5d292020-07-13 16:11:35 -0400807 "SkString _sample134 = this->invokeChild(0, args, _coords134.c_str());\n",
John Stiles50819422020-06-18 13:00:38 -0400808 "fragBuilder->codeAppendf(\n"
809 "R\"SkSL(%s = %s + %s;\n"
810 ")SkSL\"\n"
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400811 ", args.fOutputColor, _sample118.c_str(), _sample134.c_str());"
John Stiles50819422020-06-18 13:00:38 -0400812 });
Ethan Nicholasd4efe682019-08-29 16:10:13 -0400813}
Ethan Nicholas095f5b42019-08-30 11:51:41 -0400814
815DEF_TEST(SkSLFPFunction, r) {
816 test(r,
Ethan Nicholas095f5b42019-08-30 11:51:41 -0400817 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400818 R"__SkSL__(
819 in fragmentProcessor? child;
820 half4 flip(half4 c) { return c.abgr; }
821 void main() {
822 sk_OutColor = flip(sk_InColor);
823 }
824 )__SkSL__",
825 /*expectedH=*/{},
826 /*expectedCPP=*/{
Ethan Nicholas095f5b42019-08-30 11:51:41 -0400827 "SkString flip_name;",
828 "const GrShaderVar flip_args[] = { GrShaderVar(\"c\", kHalf4_GrSLType)};",
John Stiles50819422020-06-18 13:00:38 -0400829 "fragBuilder->emitFunction(kHalf4_GrSLType, \"flip\", 1, flip_args,\n"
830 "R\"SkSL(return c.wzyx;\n"
831 ")SkSL\", &flip_name);",
832 "fragBuilder->codeAppendf(\n"
Michael Ludwig9861b7c2020-06-23 18:37:17 -0400833 "R\"SkSL(half4 inlineResult0;\n"
834 "half4 inlineArg1_0 = %s;\n"
John Stiles50819422020-06-18 13:00:38 -0400835 "{\n"
Michael Ludwig9861b7c2020-06-23 18:37:17 -0400836 " inlineResult0 = inlineArg1_0.wzyx;\n"
John Stiles50819422020-06-18 13:00:38 -0400837 "}\n"
Michael Ludwig9861b7c2020-06-23 18:37:17 -0400838 "%s = inlineResult0;\n"
John Stiles50819422020-06-18 13:00:38 -0400839 "\n"
840 ")SkSL\"\n"
841 ", args.fInputColor, args.fOutputColor);"
Ethan Nicholas095f5b42019-08-30 11:51:41 -0400842 });
843}
Ethan Nicholas58430122020-04-14 09:54:02 -0400844
Michael Ludwige88320b2020-06-24 09:04:56 -0400845DEF_TEST(SkSLFPMatrixSampleConstant, r) {
Ethan Nicholas58430122020-04-14 09:54:02 -0400846 test(r,
Ethan Nicholas58430122020-04-14 09:54:02 -0400847 *SkSL::ShaderCapsFactory::Default(),
John Stiles88183902020-06-10 16:40:38 -0400848 R"__SkSL__(
849 in fragmentProcessor? child;
850 void main() {
851 sk_OutColor = sample(child, float3x3(2));
852 }
853 )__SkSL__",
Michael Ludwige88320b2020-06-24 09:04:56 -0400854 /*expectedH=*/{
855 "this->registerChild(std::move(child), "
Brian Osman1298bc42020-06-30 13:39:35 -0400856 "SkSL::SampleUsage::UniformMatrix(\"float3x3(2.0)\", true));"
Michael Ludwige88320b2020-06-24 09:04:56 -0400857 },
858 /*expectedCPP=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400859 "this->invokeChildWithMatrix(0, args)"
Michael Ludwige88320b2020-06-24 09:04:56 -0400860 });
861}
862
863DEF_TEST(SkSLFPMatrixSampleUniform, r) {
864 test(r,
865 *SkSL::ShaderCapsFactory::Default(),
866 R"__SkSL__(
867 in fragmentProcessor? child;
868 uniform float3x3 matrix;
869 void main() {
870 sk_OutColor = sample(child, matrix);
871 }
872 )__SkSL__",
873 /*expectedH=*/{
874 // Since 'matrix' is just a uniform, the generated code can't determine perspective.
875 "this->registerChild(std::move(child), "
Brian Osman1298bc42020-06-30 13:39:35 -0400876 "SkSL::SampleUsage::UniformMatrix(\"matrix\", true));"
Michael Ludwige88320b2020-06-24 09:04:56 -0400877 },
878 /*expectedCPP=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400879 "this->invokeChildWithMatrix(0, args)"
Michael Ludwige88320b2020-06-24 09:04:56 -0400880 });
881}
882
883DEF_TEST(SkSLFPMatrixSampleInUniform, r) {
884 test(r,
885 *SkSL::ShaderCapsFactory::Default(),
886 R"__SkSL__(
887 in fragmentProcessor? child;
888 in uniform float3x3 matrix;
889 void main() {
890 sk_OutColor = sample(child, matrix);
891 }
892 )__SkSL__",
893 /*expectedH=*/{
894 // Since 'matrix' is marked 'in', we can detect perspective at runtime
895 "this->registerChild(std::move(child), "
Brian Osman1298bc42020-06-30 13:39:35 -0400896 "SkSL::SampleUsage::UniformMatrix(\"matrix\", matrix.hasPerspective()));"
Michael Ludwige88320b2020-06-24 09:04:56 -0400897 },
898 /*expectedCPP=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400899 "this->invokeChildWithMatrix(0, args)"
Michael Ludwige88320b2020-06-24 09:04:56 -0400900 });
901}
902
903DEF_TEST(SkSLFPMatrixSampleMultipleInUniforms, r) {
904 test(r,
905 *SkSL::ShaderCapsFactory::Default(),
906 R"__SkSL__(
907 in fragmentProcessor? child;
908 in uniform float3x3 matrixA;
909 in uniform float3x3 matrixB;
910 void main() {
911 sk_OutColor = sample(child, matrixA);
912 sk_OutColor += sample(child, matrixB);
913 }
914 )__SkSL__",
915 /*expectedH=*/{
916 // FIXME it would be nice if codegen can produce
917 // (matrixA.hasPerspective() || matrixB.hasPerspective()) even though it's variable.
918 "this->registerChild(std::move(child), "
Brian Osman1298bc42020-06-30 13:39:35 -0400919 "SkSL::SampleUsage::VariableMatrix(true));"
Michael Ludwige88320b2020-06-24 09:04:56 -0400920 },
921 /*expectedCPP=*/{
922 "SkString _matrix191(args.fUniformHandler->getUniformCStr(matrixAVar));",
Brian Osman12c5d292020-07-13 16:11:35 -0400923 "this->invokeChildWithMatrix(0, args, _matrix191.c_str());",
Michael Ludwige88320b2020-06-24 09:04:56 -0400924 "SkString _matrix247(args.fUniformHandler->getUniformCStr(matrixBVar));",
Brian Osman12c5d292020-07-13 16:11:35 -0400925 "this->invokeChildWithMatrix(0, args, _matrix247.c_str());"
Michael Ludwige88320b2020-06-24 09:04:56 -0400926 });
927}
928
929DEF_TEST(SkSLFPMatrixSampleConstUniformExpression, r) {
930 test(r,
931 *SkSL::ShaderCapsFactory::Default(),
932 R"__SkSL__(
933 in fragmentProcessor? child;
934 uniform float3x3 matrix;
935 void main() {
936 sk_OutColor = sample(child, 0.5 * matrix);
937 }
938 )__SkSL__",
939 /*expectedH=*/{
Brian Osman1298bc42020-06-30 13:39:35 -0400940 // FIXME: "0.5 * matrix" is a uniform expression and could be lifted to the vertex
941 // shader, once downstream code is able to properly map 'matrix' within the expression.
Michael Ludwige88320b2020-06-24 09:04:56 -0400942 "this->registerChild(std::move(child), "
Brian Osman1298bc42020-06-30 13:39:35 -0400943 "SkSL::SampleUsage::VariableMatrix(true));"
Michael Ludwige88320b2020-06-24 09:04:56 -0400944 },
945 /*expectedCPP=*/{
946 "SkString _matrix145 = SkStringPrintf(\"0.5 * %s\", "
947 "args.fUniformHandler->getUniformCStr(matrixVar));",
Brian Osman12c5d292020-07-13 16:11:35 -0400948 "this->invokeChildWithMatrix(0, args, _matrix145.c_str());"
Michael Ludwige88320b2020-06-24 09:04:56 -0400949 });
950}
951
952DEF_TEST(SkSLFPMatrixSampleConstantAndExplicitly, r) {
953 test(r,
954 *SkSL::ShaderCapsFactory::Default(),
955 R"__SkSL__(
956 in fragmentProcessor? child;
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400957 void main(float2 coord) {
Michael Ludwige88320b2020-06-24 09:04:56 -0400958 sk_OutColor = sample(child, float3x3(0.5));
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400959 sk_OutColor = sample(child, coord / 2);
Michael Ludwige88320b2020-06-24 09:04:56 -0400960 }
961 )__SkSL__",
962 /*expectedH=*/{
963 "this->registerChild(std::move(child), "
Brian Osman1298bc42020-06-30 13:39:35 -0400964 "SkSL::SampleUsage(SkSL::SampleUsage::Kind::kUniform, \"float3x3(0.5)\", true, true, false));"
Michael Ludwige88320b2020-06-24 09:04:56 -0400965 },
966 /*expectedCPP=*/{
Brian Osman12c5d292020-07-13 16:11:35 -0400967 "this->invokeChildWithMatrix(0, args)",
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400968 "SkString _coords180 = SkStringPrintf(\"%s / 2.0\", args.fSampleCoord);",
Brian Osman12c5d292020-07-13 16:11:35 -0400969 "this->invokeChild(0, args, _coords180.c_str())",
Michael Ludwige88320b2020-06-24 09:04:56 -0400970 });
971}
972
973DEF_TEST(SkSLFPMatrixSampleVariableAndExplicitly, r) {
974 test(r,
975 *SkSL::ShaderCapsFactory::Default(),
976 R"__SkSL__(
977 in fragmentProcessor? child;
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400978 void main(float2 coord) {
Michael Ludwige88320b2020-06-24 09:04:56 -0400979 float3x3 matrix = float3x3(sk_InColor.a);
980 sk_OutColor = sample(child, matrix);
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400981 sk_OutColor = sample(child, coord / 2);
Michael Ludwige88320b2020-06-24 09:04:56 -0400982 }
983 )__SkSL__",
984 /*expectedH=*/{
985 "this->registerChild(std::move(child), "
Brian Osman1298bc42020-06-30 13:39:35 -0400986 "SkSL::SampleUsage(SkSL::SampleUsage::Kind::kVariable, \"\", true, true, false));"
Michael Ludwige88320b2020-06-24 09:04:56 -0400987 },
988 /*expectedCPP=*/{
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400989 "SkString _matrix178(\"matrix\");",
Brian Osman12c5d292020-07-13 16:11:35 -0400990 "this->invokeChildWithMatrix(0, args, _matrix178.c_str())",
Michael Ludwigfc2fdf02020-06-29 17:20:13 -0400991 "SkString _coords232 = SkStringPrintf(\"%s / 2.0\", args.fSampleCoord);",
Brian Osman12c5d292020-07-13 16:11:35 -0400992 "this->invokeChild(0, args, _coords232.c_str()",
Michael Ludwige88320b2020-06-24 09:04:56 -0400993 });
Ethan Nicholas58430122020-04-14 09:54:02 -0400994}