blob: bf8e835bba3e915ae1f7b5848b52a75b8bed1987 [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
8#include "SkSLCompiler.h"
9
10#include "Test.h"
11
12#if SK_SUPPORT_GPU
13
14static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& caps,
15 std::vector<const char*> expectedH, std::vector<const char*> expectedCPP) {
16 SkSL::Program::Settings settings;
17 settings.fCaps = &caps;
18 SkSL::Compiler compiler;
19 SkSL::StringStream output;
20 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
21 SkSL::Program::kFragmentProcessor_Kind,
22 SkString(src),
23 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) {
38 SkDebugf("HEADER MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
39 expected, output.str().c_str());
40 }
41 REPORTER_ASSERT(r, found);
42 }
43 }
44 output.reset();
45 success = compiler.toCPP(*program, "Test", output);
46 if (!success) {
47 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
48 }
49 REPORTER_ASSERT(r, success);
50 if (success) {
51 for (const char* expected : expectedCPP) {
52 bool found = strstr(output.str().c_str(), expected);
53 if (!found) {
54 SkDebugf("CPP MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
55 expected, output.str().c_str());
56 }
57 REPORTER_ASSERT(r, found);
58 }
59 }
60}
61
62DEF_TEST(SkSLFPHelloWorld, r) {
63 test(r,
64 "void main() {"
65 "sk_OutColor = vec4(1);"
66 "}",
67 *SkSL::ShaderCapsFactory::Default(),
68 {
69 "/*\n"
70 " * Copyright 2017 Google Inc.\n"
71 " *\n"
72 " * Use of this source code is governed by a BSD-style license that can be\n"
73 " * found in the LICENSE file.\n"
74 " */\n"
75 "\n"
76 "/*\n"
77 " * This file was autogenerated from GrTest.fp; do not modify.\n"
78 " */\n"
79 "#ifndef GrTest_DEFINED\n"
80 "#define GrTest_DEFINED\n"
Ethan Nicholasceb4d482017-07-10 15:40:20 -040081 "#include \"SkTypes.h\"\n"
82 "#if SK_SUPPORT_GPU\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040083 "#include \"GrFragmentProcessor.h\"\n"
84 "#include \"GrCoordTransform.h\"\n"
Ethan Nicholas68990be2017-07-13 09:36:52 -040085 "#include \"GrColorSpaceXform.h\"\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -040086 "#include \"effects/GrProxyMove.h\"\n"
87 "class GrTest : public GrFragmentProcessor {\n"
88 "public:\n"
89 " static sk_sp<GrFragmentProcessor> Make() {\n"
90 " return sk_sp<GrFragmentProcessor>(new GrTest());\n"
91 " }\n"
92 " const char* name() const override { return \"Test\"; }\n"
93 "private:\n"
94 " GrTest()\n"
95 " : INHERITED(kNone_OptimizationFlags) {\n"
96 " this->initClassID<GrTest>();\n"
97 " }\n"
98 " GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n"
99 " void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) "
100 "const override;\n"
101 " bool onIsEqual(const GrFragmentProcessor&) const override;\n"
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400102 " GR_DECLARE_FRAGMENT_PROCESSOR_TEST\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400103 " typedef GrFragmentProcessor INHERITED;\n"
104 "};\n"
105 "#endif\n"
Ethan Nicholasceb4d482017-07-10 15:40:20 -0400106 "#endif\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400107 },
108 {
109 "/*\n"
110 " * Copyright 2017 Google Inc.\n"
111 " *\n"
112 " * Use of this source code is governed by a BSD-style license that can be\n"
113 " * found in the LICENSE file.\n"
114 " */\n"
115 "\n"
116 "/*\n"
117 " * This file was autogenerated from GrTest.fp; do not modify.\n"
118 " */\n"
119 "#include \"GrTest.h\"\n"
Ethan Nicholasceb4d482017-07-10 15:40:20 -0400120 "#if SK_SUPPORT_GPU\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400121 "#include \"glsl/GrGLSLColorSpaceXformHelper.h\"\n"
122 "#include \"glsl/GrGLSLFragmentProcessor.h\"\n"
123 "#include \"glsl/GrGLSLFragmentShaderBuilder.h\"\n"
124 "#include \"glsl/GrGLSLProgramBuilder.h\"\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400125 "#include \"SkSLCPP.h\"\n"
126 "#include \"SkSLUtil.h\"\n"
127 "class GrGLSLTest : public GrGLSLFragmentProcessor {\n"
128 "public:\n"
129 " GrGLSLTest() {}\n"
130 " void emitCode(EmitArgs& args) override {\n"
131 " GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n"
132 " const GrTest& _outer = args.fFp.cast<GrTest>();\n"
133 " (void) _outer;\n"
134 " fragBuilder->codeAppendf(\"%s = vec4(1.0);\\n\", args.fOutputColor);\n"
135 " }\n"
136 "private:\n"
137 " void onSetData(const GrGLSLProgramDataManager& pdman, "
138 "const GrFragmentProcessor& _proc) override {\n"
139 " }\n"
140 "};\n"
141 "GrGLSLFragmentProcessor* GrTest::onCreateGLSLInstance() const {\n"
142 " return new GrGLSLTest();\n"
143 "}\n"
144 "void GrTest::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
145 "GrProcessorKeyBuilder* b) const {\n"
146 "}\n"
147 "bool GrTest::onIsEqual(const GrFragmentProcessor& other) const {\n"
148 " const GrTest& that = other.cast<GrTest>();\n"
149 " (void) that;\n"
150 " return true;\n"
151 "}\n"
Ethan Nicholasceb4d482017-07-10 15:40:20 -0400152 "#endif\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400153 });
154}
155
156DEF_TEST(SkSLFPInput, r) {
157 test(r,
158 "in vec2 point;"
159 "void main() {"
160 "sk_OutColor = vec4(point, point);"
161 "}",
162 *SkSL::ShaderCapsFactory::Default(),
163 {
164 "SkPoint point() const { return fPoint; }",
165 "static sk_sp<GrFragmentProcessor> Make(SkPoint point) {",
166 "return sk_sp<GrFragmentProcessor>(new GrTest(point));",
167 "GrTest(SkPoint point)",
168 ", fPoint(point)"
169 },
170 {
171 "fragBuilder->codeAppendf(\"%s = vec4(vec2(%f, %f), vec2(%f, %f));\\n\", "
172 "args.fOutputColor, _outer.point().fX, _outer.point().fY, "
173 "_outer.point().fX, _outer.point().fY);",
174 "if (fPoint != that.fPoint) return false;"
175 });
176}
177
178DEF_TEST(SkSLFPUniform, r) {
179 test(r,
180 "uniform vec4 color;"
181 "void main() {"
182 "sk_OutColor = color;"
183 "}",
184 *SkSL::ShaderCapsFactory::Default(),
185 {
186 "static sk_sp<GrFragmentProcessor> Make()"
187 },
188 {
189 "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
190 "kDefault_GrSLPrecision, \"color\");",
191 });
192}
193
194DEF_TEST(SkSLFPInUniform, r) {
195 test(r,
196 "in uniform vec4 color;"
197 "void main() {"
198 "sk_OutColor = color;"
199 "}",
200 *SkSL::ShaderCapsFactory::Default(),
201 {
202 "static sk_sp<GrFragmentProcessor> Make(SkRect color) {",
203 },
204 {
205 "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
206 "kDefault_GrSLPrecision, \"color\");",
207 "const SkRect colorValue = _outer.color();",
Ethan Nicholasee338732017-07-17 15:13:45 -0400208 "pdman.set4fv(fColorVar, 1, (float*) &colorValue);"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400209 });
210}
211
212DEF_TEST(SkSLFPSections, r) {
213 test(r,
214 "@header { header section }"
215 "void main() {"
216 "sk_OutColor = vec4(1);"
217 "}",
218 *SkSL::ShaderCapsFactory::Default(),
219 {
Ethan Nicholasceb4d482017-07-10 15:40:20 -0400220 "#if SK_SUPPORT_GPU\n header section"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400221 },
222 {});
223 test(r,
224 "@class { class section }"
225 "void main() {"
226 "sk_OutColor = vec4(1);"
227 "}",
228 *SkSL::ShaderCapsFactory::Default(),
229 {
230 "class GrTest : public GrFragmentProcessor {\n"
231 "public:\n"
232 " class section"
233 },
234 {});
235 test(r,
236 "@cpp { cpp section }"
237 "void main() {"
238 "sk_OutColor = vec4(1);"
239 "}",
240 *SkSL::ShaderCapsFactory::Default(),
241 {},
242 {"cpp section"});
243 test(r,
244 "@constructorParams { int x, float y, std::vector<float> z }"
245 "in float w;"
246 "void main() {"
247 "sk_OutColor = vec4(1);"
248 "}",
249 *SkSL::ShaderCapsFactory::Default(),
250 {
251 "Make(float w, int x, float y, std::vector<float> z )",
252 "return sk_sp<GrFragmentProcessor>(new GrTest(w, x, y, z));",
253 "GrTest(float w, int x, float y, std::vector<float> z )",
254 ", fW(w) {"
255 },
256 {});
257 test(r,
258 "@constructor { constructor section }"
259 "void main() {"
260 "sk_OutColor = vec4(1);"
261 "}",
262 *SkSL::ShaderCapsFactory::Default(),
263 {
264 "private:\n constructor section"
265 },
266 {});
267 test(r,
268 "@initializers { initializers section }"
269 "void main() {"
270 "sk_OutColor = vec4(1);"
271 "}",
272 *SkSL::ShaderCapsFactory::Default(),
273 {
274 ": INHERITED(kNone_OptimizationFlags)\n , initializers section"
275 },
276 {});
277 test(r,
278 "float x = 10;"
279 "@emitCode { fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2); }"
280 "void main() {"
281 "sk_OutColor = vec4(1);"
282 "}",
283 *SkSL::ShaderCapsFactory::Default(),
284 {},
285 {
286 "x = 10.0;\n"
287 " fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2);"
288 });
289 test(r,
290 "@fields { fields section }"
291 "void main() {"
292 "sk_OutColor = vec4(1);"
293 "}",
294 *SkSL::ShaderCapsFactory::Default(),
295 {
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400296 "GR_DECLARE_FRAGMENT_PROCESSOR_TEST\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400297 " fields section typedef GrFragmentProcessor INHERITED;"
298 },
299 {});
300 test(r,
301 "@make { make section }"
302 "void main() {"
303 "sk_OutColor = vec4(1);"
304 "}",
305 *SkSL::ShaderCapsFactory::Default(),
306 {
307 "public:\n"
308 " make section"
309 },
310 {});
311 test(r,
312 "uniform float calculated;"
313 "in float provided;"
314 "@setData(varName) { varName.set1f(calculated, provided * 2); }"
315 "void main() {"
316 "sk_OutColor = vec4(1);"
317 "}",
318 *SkSL::ShaderCapsFactory::Default(),
319 {},
320 {
321 "void onSetData(const GrGLSLProgramDataManager& varName, "
322 "const GrFragmentProcessor& _proc) override {\n",
323 "UniformHandle& calculated = fCalculatedVar;",
324 "auto provided = _outer.provided();",
325 "varName.set1f(calculated, provided * 2);"
326 });
327 test(r,
328 "@test(testDataName) { testDataName section }"
329 "void main() {"
330 "sk_OutColor = vec4(1);"
331 "}",
332 *SkSL::ShaderCapsFactory::Default(),
333 {},
334 {
335 "#if GR_TEST_UTILS\n"
336 "sk_sp<GrFragmentProcessor> GrTest::TestCreate(GrProcessorTestData* testDataName) {\n"
337 " testDataName section }\n"
338 "#endif"
339 });
340}
341
342DEF_TEST(SkSLFPColorSpaceXform, r) {
343 test(r,
344 "in uniform sampler2D image;"
345 "in uniform colorSpaceXform colorXform;"
346 "void main() {"
347 "sk_OutColor = sk_InColor * texture(image, vec2(0, 0), colorXform);"
348 "}",
349 *SkSL::ShaderCapsFactory::Default(),
350 {
Ethan Nicholasceb4d482017-07-10 15:40:20 -0400351 "sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; }",
352 "GrTest(sk_sp<GrTextureProxy> image, sk_sp<GrColorSpaceXform> colorXform)",
353 "this->addTextureSampler(&fImage);",
354 "sk_sp<GrColorSpaceXform> fColorXform;"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400355 },
356 {
Ethan Nicholas68990be2017-07-13 09:36:52 -0400357 "fragBuilder->codeAppendf(\"vec4 _tmpVar1;%s = %s * %stexture(%s, "
358 "vec2(0.0, 0.0)).%s%s;\\n\", args.fOutputColor, args.fInputColor ? args.fInputColor : "
359 "\"vec4(1)\", fColorSpaceHelper.isValid() ? \"(_tmpVar1 = \" : \"\", "
360 "fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), "
Ethan Nicholasceb4d482017-07-10 15:40:20 -0400361 "fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), "
Ethan Nicholas68990be2017-07-13 09:36:52 -0400362 "fColorSpaceHelper.isValid() ? SkStringPrintf(\", vec4(clamp((%s * vec4(_tmpVar1.rgb, "
363 "1.0)).rgb, 0.0, _tmpVar1.a), _tmpVar1.a))\", args.fUniformHandler->getUniformCStr("
364 "fColorSpaceHelper.gamutXformUniform())).c_str() : \"\");"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400365 });
366}
367
368DEF_TEST(SkSLFPTransformedCoords, r) {
369 test(r,
370 "void main() {"
371 "sk_OutColor = vec4(sk_TransformedCoords2D[0], sk_TransformedCoords2D[0]);"
372 "}",
373 *SkSL::ShaderCapsFactory::Default(),
374 {},
375 {
376 "SkSL::String sk_TransformedCoords2D_0 = "
377 "fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);",
378 "fragBuilder->codeAppendf(\"%s = vec4(%s, %s);\\n\", args.fOutputColor, "
379 "sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str());"
380 });
381
382}
383
384DEF_TEST(SkSLFPLayoutWhen, r) {
385 test(r,
386 "layout(when=someExpression(someOtherExpression())) uniform float sometimes;"
387 "void main() {"
388 "}",
389 *SkSL::ShaderCapsFactory::Default(),
390 {},
391 {
392 "if (someExpression(someOtherExpression())) {\n"
393 " fSometimesVar = args.fUniformHandler->addUniform"
394 });
395
396}
397
398#endif