blob: 13cecb9ff97421720e4f10750fc37c74f85e0b1f [file] [log] [blame]
Ethan Nicholas842d31b2019-01-22 10:59:11 -05001/*
2 * Copyright 2019 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 Nicholas842d31b2019-01-22 10:59:11 -05009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "tests/Test.h"
Ethan Nicholas842d31b2019-01-22 10:59:11 -050011
12static void test(skiatest::Reporter* r, const char* src, const SkSL::Program::Settings& settings,
13 const char* expected, SkSL::Program::Inputs* inputs,
14 SkSL::Program::Kind kind = SkSL::Program::kFragment_Kind) {
15 SkSL::Compiler compiler;
16 SkSL::String output;
17 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, SkSL::String(src),
18 settings);
19 if (!program) {
20 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
21 }
22 REPORTER_ASSERT(r, program);
23 *inputs = program->fInputs;
24 REPORTER_ASSERT(r, compiler.toMetal(*program, &output));
25 if (program) {
26 SkSL::String skExpected(expected);
27 if (output != skExpected) {
28 SkDebugf("MSL MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
29 expected, output.c_str());
30 }
31 REPORTER_ASSERT(r, output == skExpected);
32 }
33}
34
35static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& caps,
36 const char* expected, SkSL::Program::Kind kind = SkSL::Program::kFragment_Kind) {
37 SkSL::Program::Settings settings;
38 settings.fCaps = &caps;
39 SkSL::Program::Inputs inputs;
40 test(r, src, settings, expected, &inputs, kind);
41}
42
43DEF_TEST(SkSLMetalHelloWorld, r) {
44 test(r,
Ethan Nicholase1f55022019-02-05 17:17:40 -050045 "void main() { sk_FragColor = half4(0.75); }",
Ethan Nicholas842d31b2019-01-22 10:59:11 -050046 *SkSL::ShaderCapsFactory::Default(),
47 "#include <metal_stdlib>\n"
48 "#include <simd/simd.h>\n"
49 "using namespace metal;\n"
50 "struct Inputs {\n"
51 "};\n"
52 "struct Outputs {\n"
53 " float4 sk_FragColor [[color(0)]];\n"
54 "};\n"
Jim Van Verth6bc650e2019-02-07 14:53:23 -050055 "fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {\n"
Ethan Nicholas842d31b2019-01-22 10:59:11 -050056 " Outputs _outputStruct;\n"
57 " thread Outputs* _out = &_outputStruct;\n"
58 " _out->sk_FragColor = float4(0.75);\n"
59 " return *_out;\n"
60 "}\n");
61}
62
63DEF_TEST(SkSLMetalMatrices, r) {
64 test(r,
65 "void main() {"
66 "float2x2 m1 = float2x2(float4(1, 2, 3, 4));"
67 "float2x2 m2 = float2x2(float4(0));"
68 "float2x2 m3 = float2x2(m1);"
69 "float2x2 m4 = float2x2(1);"
70 "float2x2 m5 = float2x2(m1[0][0]);"
71 "float2x2 m6 = float2x2(1, 2, 3, 4);"
72 "float2x2 m7 = float2x2(5, 6, 7, 8);"
73 "float3x3 m8 = float3x3(1);"
74 "float3x3 m9 = float3x3(2);"
75 "float4x4 m10 = float4x4(1);"
76 "float4x4 m11 = float4x4(2);"
Ethan Nicholase1f55022019-02-05 17:17:40 -050077 "sk_FragColor = half4(half(m1[0][0] + m2[0][0] + m3[0][0] + m4[0][0] + m5[0][0] + "
78 "m6[0][0] + m7[0][0] + m8[0][0] + m9[0][0] + m10[0][0] + m11[0][0]));"
Ethan Nicholas842d31b2019-01-22 10:59:11 -050079 "}",
80 *SkSL::ShaderCapsFactory::Default(),
81 "#include <metal_stdlib>\n"
82 "#include <simd/simd.h>\n"
83 "using namespace metal;\n"
84 "struct Inputs {\n"
85 "};\n"
86 "struct Outputs {\n"
87 " float4 sk_FragColor [[color(0)]];\n"
88 "};\n"
Ethan Nicholas842d31b2019-01-22 10:59:11 -050089 "float2x2 float2x2_from_float(float x) {\n"
90 " return float2x2(float2(x, 0), float2(0, x));\n"
91 "}\n"
92 "float2x2 float2x2_from_float4(float4 v) {\n"
93 " return float2x2(float2(v[0], v[1]), float2(v[2], v[3]));\n"
94 "}\n"
Ethan Nicholase1f55022019-02-05 17:17:40 -050095 "float2x2 float2x2_from_float(float x) {\n"
96 " return float2x2(float2(x, 0), float2(0, x));\n"
97 "}\n"
Ethan Nicholas842d31b2019-01-22 10:59:11 -050098 "float3x3 float3x3_from_float(float x) {\n"
99 " return float3x3(float3(x, 0, 0), float3(0, x, 0), float3(0, 0, x));\n"
100 "}\n"
101 "float4x4 float4x4_from_float(float x) {\n"
Ethan Nicholase1f55022019-02-05 17:17:40 -0500102 " return float4x4(float4(x, 0, 0, 0), float4(0, x, 0, 0), float4(0, 0, x, 0), float4(0, 0, 0, x));\n"
Ethan Nicholas842d31b2019-01-22 10:59:11 -0500103 "}\n"
Jim Van Verth6bc650e2019-02-07 14:53:23 -0500104 "fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {\n"
Ethan Nicholas842d31b2019-01-22 10:59:11 -0500105 " Outputs _outputStruct;\n"
106 " thread Outputs* _out = &_outputStruct;\n"
Ethan Nicholase1f55022019-02-05 17:17:40 -0500107 " float2x2 m5 = float2x2_from_float(float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0]);\n"
108 " _out->sk_FragColor = float4((((((((((float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0] + float2x2_from_float4(float4(0.0))[0][0]) + float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0]) + float2x2_from_float(1.0)[0][0]) + m5[0][0]) + float2x2(float2(1.0, 2.0), float2(3.0, 4.0))[0][0]) + float2x2(float2(5.0, 6.0), float2(7.0, 8.0))[0][0]) + float3x3_from_float(1.0)[0][0]) + float3x3_from_float(2.0)[0][0]) + float4x4_from_float(1.0)[0][0]) + float4x4_from_float(2.0)[0][0]);\n"
Ethan Nicholas842d31b2019-01-22 10:59:11 -0500109 " return *_out;\n"
Ethan Nicholase1f55022019-02-05 17:17:40 -0500110 "}\n");
Ethan Nicholas842d31b2019-01-22 10:59:11 -0500111}
Ethan Nicholas5476f2e2019-03-07 15:11:31 -0500112
113DEF_TEST(SkSLMetalConstantSwizzle, r) {
114 test(r,
115 "void main() {"
116 "sk_FragColor = half4(0.5).rgb1;"
117 "}",
118 *SkSL::ShaderCapsFactory::Default(),
119 "#include <metal_stdlib>\n"
120 "#include <simd/simd.h>\n"
121 "using namespace metal;\n"
122 "struct Inputs {\n"
123 "};\n"
124 "struct Outputs {\n"
125 " float4 sk_FragColor [[color(0)]];\n"
126 "};\n"
127 "fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {\n"
128 " Outputs _outputStruct;\n"
129 " thread Outputs* _out = &_outputStruct;\n"
130 " _out->sk_FragColor = float4(float4(0.5).xyz, 1);\n"
131 " return *_out;\n"
132 "}\n");
133}