Flutter Impeller
compiler_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <cstring>
6 #include "flutter/testing/testing.h"
7 #include "gtest/gtest.h"
13 
14 namespace impeller {
15 namespace compiler {
16 namespace testing {
17 
18 TEST(CompilerTest, ShaderKindMatchingIsSuccessful) {
19  ASSERT_EQ(SourceTypeFromFileName("hello.vert"), SourceType::kVertexShader);
20  ASSERT_EQ(SourceTypeFromFileName("hello.frag"), SourceType::kFragmentShader);
21  ASSERT_EQ(SourceTypeFromFileName("hello.comp"), SourceType::kComputeShader);
22  ASSERT_EQ(SourceTypeFromFileName("hello.msl"), SourceType::kUnknown);
23  ASSERT_EQ(SourceTypeFromFileName("hello.glsl"), SourceType::kUnknown);
24 }
25 
26 TEST_P(CompilerTest, CanCompile) {
27  if (GetParam() == TargetPlatform::kSkSL) {
28  GTEST_SKIP() << "Not supported with SkSL";
29  }
30  ASSERT_TRUE(CanCompileAndReflect("sample.vert"));
31  ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
32  ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader,
34 }
35 
36 TEST_P(CompilerTest, CanCompileHLSL) {
37  if (GetParam() == TargetPlatform::kSkSL) {
38  GTEST_SKIP() << "Not supported with SkSL";
39  }
40  ASSERT_TRUE(CanCompileAndReflect(
41  "simple.vert.hlsl", SourceType::kVertexShader, SourceLanguage::kHLSL));
42 }
43 
44 TEST_P(CompilerTest, CanCompileHLSLWithMultipleStages) {
45  if (GetParam() == TargetPlatform::kSkSL) {
46  GTEST_SKIP() << "Not supported with SkSL";
47  }
48  ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
50  SourceLanguage::kHLSL, "VertexShader"));
51  ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
53  SourceLanguage::kHLSL, "FragmentShader"));
54 }
55 
56 TEST_P(CompilerTest, CanCompileComputeShader) {
57  if (!TargetPlatformIsMetal(GetParam())) {
58  GTEST_SKIP()
59  << "Only enabled on Metal backends till ES 3.2 support is added.";
60  }
61  ASSERT_TRUE(CanCompileAndReflect("sample.comp"));
62  ASSERT_TRUE(CanCompileAndReflect("sample.comp", SourceType::kComputeShader));
63 }
64 
65 TEST_P(CompilerTest, MustFailDueToExceedingResourcesLimit) {
66  if (GetParam() == TargetPlatform::kSkSL) {
67  GTEST_SKIP() << "Not supported with SkSL";
68  }
69  ScopedValidationDisable disable_validation;
70  ASSERT_FALSE(
71  CanCompileAndReflect("resources_limit.vert", SourceType::kVertexShader));
72 }
73 
74 TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) {
75  if (GetParam() == TargetPlatform::kSkSL) {
76  GTEST_SKIP() << "Not supported with SkSL";
77  }
78  ScopedValidationDisable disable_validation;
79  ASSERT_FALSE(CanCompileAndReflect("struct_def_bug.vert"));
80 }
81 
82 TEST_P(CompilerTest, BindingBaseForFragShader) {
83  if (!TargetPlatformIsVulkan(GetParam())) {
84  GTEST_SKIP();
85  }
86 
87  ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
88  ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
89 
90  auto get_binding = [&](const char* fixture) -> uint32_t {
91  auto json_fd = GetReflectionJson(fixture);
92  nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
93  return shader_json["buffers"][0]["binding"].get<uint32_t>();
94  };
95 
96  auto vert_uniform_binding = get_binding("sample.vert");
97  auto frag_uniform_binding = get_binding("sample.frag");
98 
99  ASSERT_GT(frag_uniform_binding, vert_uniform_binding);
100 }
101 
102 TEST_P(CompilerTest, UniformsHaveBindingAndSet) {
103  if (GetParam() == TargetPlatform::kSkSL) {
104  GTEST_SKIP() << "Not supported with SkSL";
105  }
106  ASSERT_TRUE(CanCompileAndReflect("sample_with_binding.vert",
108  ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
109 
110  struct binding_and_set {
111  uint32_t binding;
112  uint32_t set;
113  };
114 
115  auto get_binding = [&](const char* fixture) -> binding_and_set {
116  auto json_fd = GetReflectionJson(fixture);
117  nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
118  uint32_t binding = shader_json["buffers"][0]["binding"].get<uint32_t>();
119  uint32_t set = shader_json["buffers"][0]["set"].get<uint32_t>();
120  return {binding, set};
121  };
122 
123  auto vert_uniform_binding = get_binding("sample_with_binding.vert");
124  auto frag_uniform_binding = get_binding("sample.frag");
125 
126  ASSERT_EQ(frag_uniform_binding.set, 0u);
127  ASSERT_EQ(vert_uniform_binding.set, 3u);
128  ASSERT_EQ(vert_uniform_binding.binding, 17u);
129 }
130 
131 TEST_P(CompilerTest, SkSLTextureLookUpOrderOfOperations) {
132  if (GetParam() != TargetPlatform::kSkSL) {
133  GTEST_SKIP() << "Only supported on SkSL";
134  }
135  ASSERT_TRUE(
136  CanCompileAndReflect("texture_lookup.frag", SourceType::kFragmentShader));
137 
138  auto shader = GetShaderFile("texture_lookup.frag", GetParam());
139  std::string_view shader_mapping(
140  reinterpret_cast<const char*>(shader->GetMapping()), shader->GetSize());
141 
142  constexpr std::string_view expected =
143  "textureA.eval(textureA_size * ( vec2(1.0) + flutter_FragCoord.xy));";
144 
145  EXPECT_NE(shader_mapping.find(expected), std::string::npos);
146 }
147 
148 TEST_P(CompilerTest, CanCompileStructs) {
149  if (GetParam() != TargetPlatform::kSkSL) {
150  GTEST_SKIP() << "Only supported on SkSL";
151  }
152  ASSERT_TRUE(CanCompileAndReflect("struct_internal.frag",
154 }
155 
156 #define INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(suite_name) \
157  INSTANTIATE_TEST_SUITE_P( \
158  suite_name, CompilerTest, \
159  ::testing::Values(TargetPlatform::kOpenGLES, \
160  TargetPlatform::kOpenGLDesktop, \
161  TargetPlatform::kMetalDesktop, \
162  TargetPlatform::kMetalIOS, TargetPlatform::kSkSL), \
163  [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) { \
164  return TargetPlatformToString(info.param); \
165  });
166 
168 
169 } // namespace testing
170 } // namespace compiler
171 } // namespace impeller
impeller::compiler::testing::TEST
TEST(CompilerTest, ShaderKindMatchingIsSuccessful)
Definition: compiler_unittests.cc:18
impeller::compiler::testing::INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P
INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(CompilerSuite)
impeller::compiler::SourceType::kUnknown
@ kUnknown
validation.h
impeller::compiler::SourceLanguage::kGLSL
@ kGLSL
impeller::compiler::SourceLanguage::kHLSL
@ kHLSL
impeller::compiler::SourceType::kFragmentShader
@ kFragmentShader
source_options.h
impeller::compiler::SourceType::kComputeShader
@ kComputeShader
compiler.h
impeller::compiler::TargetPlatformIsMetal
bool TargetPlatformIsMetal(TargetPlatform platform)
Definition: types.cc:284
impeller::compiler::TargetPlatformIsVulkan
bool TargetPlatformIsVulkan(TargetPlatform platform)
Definition: types.cc:302
compiler_test.h
impeller::compiler::SourceTypeFromFileName
SourceType SourceTypeFromFileName(const std::string &file_name)
Definition: types.cc:30
impeller::compiler::testing::TEST_P
TEST_P(CompilerTest, CanCompile)
Definition: compiler_unittests.cc:26
impeller::compiler::testing::CompilerTest
Definition: compiler_test.h:18
impeller::ScopedValidationDisable
Definition: validation.h:56
impeller::compiler::SourceType::kVertexShader
@ kVertexShader
impeller
Definition: allocation.cc:12
types.h
impeller::compiler::TargetPlatform::kSkSL
@ kSkSL