blob: 64b4e71d8e33e3921ddb22572eb1bf48e3d32613 [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"
81 "#include \"GrFragmentProcessor.h\"\n"
82 "#include \"GrCoordTransform.h\"\n"
83 "#include \"effects/GrProxyMove.h\"\n"
84 "class GrTest : public GrFragmentProcessor {\n"
85 "public:\n"
86 " static sk_sp<GrFragmentProcessor> Make() {\n"
87 " return sk_sp<GrFragmentProcessor>(new GrTest());\n"
88 " }\n"
89 " const char* name() const override { return \"Test\"; }\n"
90 "private:\n"
91 " GrTest()\n"
92 " : INHERITED(kNone_OptimizationFlags) {\n"
93 " this->initClassID<GrTest>();\n"
94 " }\n"
95 " GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n"
96 " void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) "
97 "const override;\n"
98 " bool onIsEqual(const GrFragmentProcessor&) const override;\n"
Brian Salomon0c26a9d2017-07-06 10:09:38 -040099 " GR_DECLARE_FRAGMENT_PROCESSOR_TEST\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400100 " typedef GrFragmentProcessor INHERITED;\n"
101 "};\n"
102 "#endif\n"
103 },
104 {
105 "/*\n"
106 " * Copyright 2017 Google Inc.\n"
107 " *\n"
108 " * Use of this source code is governed by a BSD-style license that can be\n"
109 " * found in the LICENSE file.\n"
110 " */\n"
111 "\n"
112 "/*\n"
113 " * This file was autogenerated from GrTest.fp; do not modify.\n"
114 " */\n"
115 "#include \"GrTest.h\"\n"
116 "#include \"glsl/GrGLSLColorSpaceXformHelper.h\"\n"
117 "#include \"glsl/GrGLSLFragmentProcessor.h\"\n"
118 "#include \"glsl/GrGLSLFragmentShaderBuilder.h\"\n"
119 "#include \"glsl/GrGLSLProgramBuilder.h\"\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400120 "#include \"SkSLCPP.h\"\n"
121 "#include \"SkSLUtil.h\"\n"
122 "class GrGLSLTest : public GrGLSLFragmentProcessor {\n"
123 "public:\n"
124 " GrGLSLTest() {}\n"
125 " void emitCode(EmitArgs& args) override {\n"
126 " GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n"
127 " const GrTest& _outer = args.fFp.cast<GrTest>();\n"
128 " (void) _outer;\n"
129 " fragBuilder->codeAppendf(\"%s = vec4(1.0);\\n\", args.fOutputColor);\n"
130 " }\n"
131 "private:\n"
132 " void onSetData(const GrGLSLProgramDataManager& pdman, "
133 "const GrFragmentProcessor& _proc) override {\n"
134 " }\n"
135 "};\n"
136 "GrGLSLFragmentProcessor* GrTest::onCreateGLSLInstance() const {\n"
137 " return new GrGLSLTest();\n"
138 "}\n"
139 "void GrTest::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
140 "GrProcessorKeyBuilder* b) const {\n"
141 "}\n"
142 "bool GrTest::onIsEqual(const GrFragmentProcessor& other) const {\n"
143 " const GrTest& that = other.cast<GrTest>();\n"
144 " (void) that;\n"
145 " return true;\n"
146 "}\n"
147 });
148}
149
150DEF_TEST(SkSLFPInput, r) {
151 test(r,
152 "in vec2 point;"
153 "void main() {"
154 "sk_OutColor = vec4(point, point);"
155 "}",
156 *SkSL::ShaderCapsFactory::Default(),
157 {
158 "SkPoint point() const { return fPoint; }",
159 "static sk_sp<GrFragmentProcessor> Make(SkPoint point) {",
160 "return sk_sp<GrFragmentProcessor>(new GrTest(point));",
161 "GrTest(SkPoint point)",
162 ", fPoint(point)"
163 },
164 {
165 "fragBuilder->codeAppendf(\"%s = vec4(vec2(%f, %f), vec2(%f, %f));\\n\", "
166 "args.fOutputColor, _outer.point().fX, _outer.point().fY, "
167 "_outer.point().fX, _outer.point().fY);",
168 "if (fPoint != that.fPoint) return false;"
169 });
170}
171
172DEF_TEST(SkSLFPUniform, r) {
173 test(r,
174 "uniform vec4 color;"
175 "void main() {"
176 "sk_OutColor = color;"
177 "}",
178 *SkSL::ShaderCapsFactory::Default(),
179 {
180 "static sk_sp<GrFragmentProcessor> Make()"
181 },
182 {
183 "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
184 "kDefault_GrSLPrecision, \"color\");",
185 });
186}
187
188DEF_TEST(SkSLFPInUniform, r) {
189 test(r,
190 "in uniform vec4 color;"
191 "void main() {"
192 "sk_OutColor = color;"
193 "}",
194 *SkSL::ShaderCapsFactory::Default(),
195 {
196 "static sk_sp<GrFragmentProcessor> Make(SkRect color) {",
197 },
198 {
199 "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
200 "kDefault_GrSLPrecision, \"color\");",
201 "const SkRect colorValue = _outer.color();",
202 "pdman.set4fv(fColorVar, 4, (float*) &colorValue);"
203 });
204}
205
206DEF_TEST(SkSLFPSections, r) {
207 test(r,
208 "@header { header section }"
209 "void main() {"
210 "sk_OutColor = vec4(1);"
211 "}",
212 *SkSL::ShaderCapsFactory::Default(),
213 {
Ethan Nicholas9fb036f2017-07-05 16:19:09 -0400214 "#define GrTest_DEFINED\n header section"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400215 },
216 {});
217 test(r,
218 "@class { class section }"
219 "void main() {"
220 "sk_OutColor = vec4(1);"
221 "}",
222 *SkSL::ShaderCapsFactory::Default(),
223 {
224 "class GrTest : public GrFragmentProcessor {\n"
225 "public:\n"
226 " class section"
227 },
228 {});
229 test(r,
230 "@cpp { cpp section }"
231 "void main() {"
232 "sk_OutColor = vec4(1);"
233 "}",
234 *SkSL::ShaderCapsFactory::Default(),
235 {},
236 {"cpp section"});
237 test(r,
238 "@constructorParams { int x, float y, std::vector<float> z }"
239 "in float w;"
240 "void main() {"
241 "sk_OutColor = vec4(1);"
242 "}",
243 *SkSL::ShaderCapsFactory::Default(),
244 {
245 "Make(float w, int x, float y, std::vector<float> z )",
246 "return sk_sp<GrFragmentProcessor>(new GrTest(w, x, y, z));",
247 "GrTest(float w, int x, float y, std::vector<float> z )",
248 ", fW(w) {"
249 },
250 {});
251 test(r,
252 "@constructor { constructor section }"
253 "void main() {"
254 "sk_OutColor = vec4(1);"
255 "}",
256 *SkSL::ShaderCapsFactory::Default(),
257 {
258 "private:\n constructor section"
259 },
260 {});
261 test(r,
262 "@initializers { initializers section }"
263 "void main() {"
264 "sk_OutColor = vec4(1);"
265 "}",
266 *SkSL::ShaderCapsFactory::Default(),
267 {
268 ": INHERITED(kNone_OptimizationFlags)\n , initializers section"
269 },
270 {});
271 test(r,
272 "float x = 10;"
273 "@emitCode { fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2); }"
274 "void main() {"
275 "sk_OutColor = vec4(1);"
276 "}",
277 *SkSL::ShaderCapsFactory::Default(),
278 {},
279 {
280 "x = 10.0;\n"
281 " fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2);"
282 });
283 test(r,
284 "@fields { fields section }"
285 "void main() {"
286 "sk_OutColor = vec4(1);"
287 "}",
288 *SkSL::ShaderCapsFactory::Default(),
289 {
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400290 "GR_DECLARE_FRAGMENT_PROCESSOR_TEST\n"
Ethan Nicholas762466e2017-06-29 10:03:38 -0400291 " fields section typedef GrFragmentProcessor INHERITED;"
292 },
293 {});
294 test(r,
295 "@make { make section }"
296 "void main() {"
297 "sk_OutColor = vec4(1);"
298 "}",
299 *SkSL::ShaderCapsFactory::Default(),
300 {
301 "public:\n"
302 " make section"
303 },
304 {});
305 test(r,
306 "uniform float calculated;"
307 "in float provided;"
308 "@setData(varName) { varName.set1f(calculated, provided * 2); }"
309 "void main() {"
310 "sk_OutColor = vec4(1);"
311 "}",
312 *SkSL::ShaderCapsFactory::Default(),
313 {},
314 {
315 "void onSetData(const GrGLSLProgramDataManager& varName, "
316 "const GrFragmentProcessor& _proc) override {\n",
317 "UniformHandle& calculated = fCalculatedVar;",
318 "auto provided = _outer.provided();",
319 "varName.set1f(calculated, provided * 2);"
320 });
321 test(r,
322 "@test(testDataName) { testDataName section }"
323 "void main() {"
324 "sk_OutColor = vec4(1);"
325 "}",
326 *SkSL::ShaderCapsFactory::Default(),
327 {},
328 {
329 "#if GR_TEST_UTILS\n"
330 "sk_sp<GrFragmentProcessor> GrTest::TestCreate(GrProcessorTestData* testDataName) {\n"
331 " testDataName section }\n"
332 "#endif"
333 });
334}
335
336DEF_TEST(SkSLFPColorSpaceXform, r) {
337 test(r,
338 "in uniform sampler2D image;"
339 "in uniform colorSpaceXform colorXform;"
340 "void main() {"
341 "sk_OutColor = sk_InColor * texture(image, vec2(0, 0), colorXform);"
342 "}",
343 *SkSL::ShaderCapsFactory::Default(),
344 {
345 "sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; }",
346 "GrTest(sk_sp<GrTextureProxy> image, sk_sp<GrColorSpaceXform> colorXform)",
347 "this->addTextureSampler(&fImage);",
348 "sk_sp<GrColorSpaceXform> fColorXform;"
349 },
350 {
351 "fragBuilder->codeAppendf(\"vec4 _tmp0;\\n%s = %s * "
352 "(_tmp0 = texture(%s, vec2(0.0, 0.0)) , %s != mat4(1.0) ? "
353 "vec4(clamp((%s * vec4(_tmp0.xyz, 1.0)).xyz, 0.0, _tmp0.w), _tmp0.w) : "
354 "_tmp0);\\n\", args.fOutputColor, args.fInputColor ? args.fInputColor : "
355 "\"vec4(1)\", fragBuilder->getProgramBuilder()->samplerVariable("
356 "args.fTexSamplers[0]).c_str(), fColorSpaceHelper.isValid() ? "
357 "args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "
358 "\"mat4(1.0)\", fColorSpaceHelper.isValid() ? "
359 "args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "
360 "\"mat4(1.0)\");"
361 });
362}
363
364DEF_TEST(SkSLFPTransformedCoords, r) {
365 test(r,
366 "void main() {"
367 "sk_OutColor = vec4(sk_TransformedCoords2D[0], sk_TransformedCoords2D[0]);"
368 "}",
369 *SkSL::ShaderCapsFactory::Default(),
370 {},
371 {
372 "SkSL::String sk_TransformedCoords2D_0 = "
373 "fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);",
374 "fragBuilder->codeAppendf(\"%s = vec4(%s, %s);\\n\", args.fOutputColor, "
375 "sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str());"
376 });
377
378}
379
380DEF_TEST(SkSLFPLayoutWhen, r) {
381 test(r,
382 "layout(when=someExpression(someOtherExpression())) uniform float sometimes;"
383 "void main() {"
384 "}",
385 *SkSL::ShaderCapsFactory::Default(),
386 {},
387 {
388 "if (someExpression(someOtherExpression())) {\n"
389 " fSometimesVar = args.fUniformHandler->addUniform"
390 });
391
392}
393
394#endif