1 /*
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
8 #include "SkSLCompiler.h"
9
10 #include "Test.h"
11
test(skiatest::Reporter * r,const char * src,const SkSL::Program::Settings & settings,const char * expected,SkSL::Program::Inputs * inputs,SkSL::Program::Kind kind=SkSL::Program::kFragment_Kind)12 static 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
test(skiatest::Reporter * r,const char * src,const GrShaderCaps & caps,const char * expected,SkSL::Program::Kind kind=SkSL::Program::kFragment_Kind)35 static 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 = ∩︀
39 SkSL::Program::Inputs inputs;
40 test(r, src, settings, expected, &inputs, kind);
41 }
42
DEF_TEST(SkSLMetalHelloWorld,r)43 DEF_TEST(SkSLMetalHelloWorld, r) {
44 test(r,
45 "void main() { sk_FragColor = float4(0.75); }",
46 *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"
55 "struct sksl_synthetic_uniforms {\n"
56 " float u_skRTHeight;\n"
57 "};\n"
58 "fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant sksl_synthetic_uniforms& _anonInterface0 [[buffer(1)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {\n"
59 " Outputs _outputStruct;\n"
60 " thread Outputs* _out = &_outputStruct;\n"
61 " _out->sk_FragColor = float4(0.75);\n"
62 " return *_out;\n"
63 "}\n");
64 }
65
DEF_TEST(SkSLMetalMatrices,r)66 DEF_TEST(SkSLMetalMatrices, r) {
67 test(r,
68 "void main() {"
69 "float2x2 m1 = float2x2(float4(1, 2, 3, 4));"
70 "float2x2 m2 = float2x2(float4(0));"
71 "float2x2 m3 = float2x2(m1);"
72 "float2x2 m4 = float2x2(1);"
73 "float2x2 m5 = float2x2(m1[0][0]);"
74 "float2x2 m6 = float2x2(1, 2, 3, 4);"
75 "float2x2 m7 = float2x2(5, 6, 7, 8);"
76 "float3x3 m8 = float3x3(1);"
77 "float3x3 m9 = float3x3(2);"
78 "float4x4 m10 = float4x4(1);"
79 "float4x4 m11 = float4x4(2);"
80 "sk_FragColor = half4(m1[0][0] + m2[0][0] + m3[0][0] + m4[0][0] + m5[0][0] + m6[0][0] + "
81 "m7[0][0] + m8[0][0] + m9[0][0] + m10[0][0] + m11[0][0]);"
82 "}",
83 *SkSL::ShaderCapsFactory::Default(),
84 "#include <metal_stdlib>\n"
85 "#include <simd/simd.h>\n"
86 "using namespace metal;\n"
87 "struct Inputs {\n"
88 "};\n"
89 "struct Outputs {\n"
90 " float4 sk_FragColor [[color(0)]];\n"
91 "};\n"
92 "struct sksl_synthetic_uniforms {\n"
93 " float u_skRTHeight;\n"
94 "};\n"
95 "float2x2 float2x2_from_float(float x) {\n"
96 " return float2x2(float2(x, 0), float2(0, x));\n"
97 "}\n"
98 "float2x2 float2x2_from_float4(float4 v) {\n"
99 " return float2x2(float2(v[0], v[1]), float2(v[2], v[3]));\n"
100 "}\n"
101 "float3x3 float3x3_from_float(float x) {\n"
102 " return float3x3(float3(x, 0, 0), float3(0, x, 0), float3(0, 0, x));\n"
103 "}\n"
104 "float4x4 float4x4_from_float(float x) {\n"
105 " return float4x4(float4(x, 0, 0, 0), float4(0, x, 0, 0), float4(0, 0, x, 0), float4(0,"
106 " 0, 0, x));\n"
107 "}\n"
108 "fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant sksl_synthetic_uniforms& "
109 "_anonInterface0 [[buffer(1)]], bool _frontFacing [[front_facing]], float4 "
110 "_fragCoord [[position]]) {\n"
111 " Outputs _outputStruct;\n"
112 " thread Outputs* _out = &_outputStruct;\n"
113 " float2x2 m5 = float2x2_from_float(float2x2_from_float4(float4(1.0, 2.0, 3.0, "
114 "4.0))[0][0]);\n"
115 " _out->sk_FragColor = float4((((((((((float2x2_from_float4(float4(1.0, 2.0, 3.0, "
116 "4.0))[0][0] + float2x2_from_float4(float4(0.0))[0][0]) + "
117 "float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0]) + "
118 "float2x2_from_float(1.0)[0][0]) + m5[0][0]) + float2x2(float2(1.0, 2.0), "
119 "float2(3.0, 4.0))[0][0]) + float2x2(float2(5.0, 6.0), float2(7.0, 8.0))[0][0]) + "
120 "float3x3_from_float(1.0)[0][0]) + float3x3_from_float(2.0)[0][0]) + "
121 "float4x4_from_float(1.0)[0][0]) + float4x4_from_float(2.0)[0][0]);\n"
122 " return *_out;\n"
123 "}\n"
124
125 );
126 }
127