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