SkSLMetalTest.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. #include "src/sksl/SkSLCompiler.h"
  8. #include "tests/Test.h"
  9. static void test(skiatest::Reporter* r, const char* src, const SkSL::Program::Settings& settings,
  10. const char* expected, SkSL::Program::Inputs* inputs,
  11. SkSL::Program::Kind kind = SkSL::Program::kFragment_Kind) {
  12. SkSL::Compiler compiler;
  13. SkSL::String output;
  14. std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, SkSL::String(src),
  15. settings);
  16. if (!program) {
  17. SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
  18. }
  19. REPORTER_ASSERT(r, program);
  20. *inputs = program->fInputs;
  21. REPORTER_ASSERT(r, compiler.toMetal(*program, &output));
  22. if (program) {
  23. SkSL::String skExpected(expected);
  24. if (output != skExpected) {
  25. SkDebugf("MSL MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
  26. expected, output.c_str());
  27. }
  28. REPORTER_ASSERT(r, output == skExpected);
  29. }
  30. }
  31. static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& caps,
  32. const char* expected, SkSL::Program::Kind kind = SkSL::Program::kFragment_Kind) {
  33. SkSL::Program::Settings settings;
  34. settings.fCaps = &caps;
  35. SkSL::Program::Inputs inputs;
  36. test(r, src, settings, expected, &inputs, kind);
  37. }
  38. DEF_TEST(SkSLMetalHelloWorld, r) {
  39. test(r,
  40. "void main() { sk_FragColor = half4(0.75); }",
  41. *SkSL::ShaderCapsFactory::Default(),
  42. "#include <metal_stdlib>\n"
  43. "#include <simd/simd.h>\n"
  44. "using namespace metal;\n"
  45. "struct Inputs {\n"
  46. "};\n"
  47. "struct Outputs {\n"
  48. " float4 sk_FragColor [[color(0)]];\n"
  49. "};\n"
  50. "fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {\n"
  51. " Outputs _outputStruct;\n"
  52. " thread Outputs* _out = &_outputStruct;\n"
  53. " _out->sk_FragColor = float4(0.75);\n"
  54. " return *_out;\n"
  55. "}\n");
  56. }
  57. DEF_TEST(SkSLMetalMatrices, r) {
  58. test(r,
  59. "void main() {"
  60. "float2x2 m1 = float2x2(float4(1, 2, 3, 4));"
  61. "float2x2 m2 = float2x2(float4(0));"
  62. "float2x2 m3 = float2x2(m1);"
  63. "float2x2 m4 = float2x2(1);"
  64. "float2x2 m5 = float2x2(m1[0][0]);"
  65. "float2x2 m6 = float2x2(1, 2, 3, 4);"
  66. "float2x2 m7 = float2x2(5, 6, 7, 8);"
  67. "float3x3 m8 = float3x3(1);"
  68. "float3x3 m9 = float3x3(2);"
  69. "float4x4 m10 = float4x4(1);"
  70. "float4x4 m11 = float4x4(2);"
  71. "sk_FragColor = half4(half(m1[0][0] + m2[0][0] + m3[0][0] + m4[0][0] + m5[0][0] + "
  72. "m6[0][0] + m7[0][0] + m8[0][0] + m9[0][0] + m10[0][0] + m11[0][0]));"
  73. "}",
  74. *SkSL::ShaderCapsFactory::Default(),
  75. "#include <metal_stdlib>\n"
  76. "#include <simd/simd.h>\n"
  77. "using namespace metal;\n"
  78. "struct Inputs {\n"
  79. "};\n"
  80. "struct Outputs {\n"
  81. " float4 sk_FragColor [[color(0)]];\n"
  82. "};\n"
  83. "float2x2 float2x2_from_float(float x) {\n"
  84. " return float2x2(float2(x, 0), float2(0, x));\n"
  85. "}\n"
  86. "float2x2 float2x2_from_float4(float4 v) {\n"
  87. " return float2x2(float2(v[0], v[1]), float2(v[2], v[3]));\n"
  88. "}\n"
  89. "float2x2 float2x2_from_float(float x) {\n"
  90. " return float2x2(float2(x, 0), float2(0, x));\n"
  91. "}\n"
  92. "float3x3 float3x3_from_float(float x) {\n"
  93. " return float3x3(float3(x, 0, 0), float3(0, x, 0), float3(0, 0, x));\n"
  94. "}\n"
  95. "float4x4 float4x4_from_float(float x) {\n"
  96. " return float4x4(float4(x, 0, 0, 0), float4(0, x, 0, 0), float4(0, 0, x, 0), float4(0, 0, 0, x));\n"
  97. "}\n"
  98. "fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {\n"
  99. " Outputs _outputStruct;\n"
  100. " thread Outputs* _out = &_outputStruct;\n"
  101. " float2x2 m5 = float2x2_from_float(float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0]);\n"
  102. " _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"
  103. " return *_out;\n"
  104. "}\n");
  105. }
  106. DEF_TEST(SkSLMetalConstantSwizzle, r) {
  107. test(r,
  108. "void main() {"
  109. "sk_FragColor = half4(0.5).rgb1;"
  110. "}",
  111. *SkSL::ShaderCapsFactory::Default(),
  112. "#include <metal_stdlib>\n"
  113. "#include <simd/simd.h>\n"
  114. "using namespace metal;\n"
  115. "struct Inputs {\n"
  116. "};\n"
  117. "struct Outputs {\n"
  118. " float4 sk_FragColor [[color(0)]];\n"
  119. "};\n"
  120. "fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {\n"
  121. " Outputs _outputStruct;\n"
  122. " thread Outputs* _out = &_outputStruct;\n"
  123. " _out->sk_FragColor = float4(float4(0.5).xyz, 1);\n"
  124. " return *_out;\n"
  125. "}\n");
  126. }