Flutter Engine
 
Loading...
Searching...
No Matches
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>
7#include "gtest/gtest.h"
13
14namespace impeller {
15namespace compiler {
16namespace testing {
17
18TEST(CompilerTest, Defines) {
19 std::shared_ptr<const fml::Mapping> fixture =
20 flutter::testing::OpenFixtureAsMapping("check_gles_definition.frag");
21
22 SourceOptions options;
25 options.entry_point_name = "main";
27
28 Reflector::Options reflector_options;
30 Compiler compiler = Compiler(fixture, options, reflector_options);
31
32 // Should fail as the shader has a compilation error in it.
33 EXPECT_EQ(compiler.GetSPIRVAssembly(), nullptr);
34
35 // Should succeed as the compilation error is ifdef'd out.
38 Compiler compiler_2 = Compiler(fixture, options, reflector_options);
39 EXPECT_NE(compiler_2.GetSPIRVAssembly(), nullptr);
40}
41
42TEST(CompilerTest, ShaderKindMatchingIsSuccessful) {
43 ASSERT_EQ(SourceTypeFromFileName("hello.vert"), SourceType::kVertexShader);
45 ASSERT_EQ(SourceTypeFromFileName("hello.comp"), SourceType::kComputeShader);
46 ASSERT_EQ(SourceTypeFromFileName("hello.msl"), SourceType::kUnknown);
47 ASSERT_EQ(SourceTypeFromFileName("hello.glsl"), SourceType::kUnknown);
48}
49
50TEST_P(CompilerTest, CanCompile) {
51 if (GetParam() == TargetPlatform::kSkSL) {
52 GTEST_SKIP() << "Not supported with SkSL";
53 }
54 ASSERT_TRUE(CanCompileAndReflect("sample.vert"));
55 ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
56 ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader,
58}
59
60TEST_P(CompilerTest, CanCompileHLSL) {
61 if (GetParam() == TargetPlatform::kSkSL) {
62 GTEST_SKIP() << "Not supported with SkSL";
63 }
64 ASSERT_TRUE(CanCompileAndReflect(
66}
67
68TEST_P(CompilerTest, CanCompileHLSLWithMultipleStages) {
69 if (GetParam() == TargetPlatform::kSkSL) {
70 GTEST_SKIP() << "Not supported with SkSL";
71 }
72 ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
74 SourceLanguage::kHLSL, "VertexShader"));
75 ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
77 SourceLanguage::kHLSL, "FragmentShader"));
78}
79
80TEST_P(CompilerTest, CanCompileComputeShader) {
81 if (!TargetPlatformIsMetal(GetParam())) {
82 GTEST_SKIP()
83 << "Only enabled on Metal backends till ES 3.2 support is added.";
84 }
85 ASSERT_TRUE(CanCompileAndReflect("sample.comp"));
86 ASSERT_TRUE(CanCompileAndReflect("sample.comp", SourceType::kComputeShader));
87}
88
89TEST_P(CompilerTest, MustFailDueToExceedingResourcesLimit) {
90 if (GetParam() == TargetPlatform::kSkSL) {
91 GTEST_SKIP() << "Not supported with SkSL";
92 }
93 ScopedValidationDisable disable_validation;
94 ASSERT_FALSE(
95 CanCompileAndReflect("resources_limit.vert", SourceType::kVertexShader));
96}
97
98TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) {
99 if (GetParam() == TargetPlatform::kSkSL) {
100 GTEST_SKIP() << "Not supported with SkSL";
101 }
102 ScopedValidationDisable disable_validation;
103 ASSERT_FALSE(CanCompileAndReflect("struct_def_bug.vert"));
104}
105
106TEST_P(CompilerTest, BindingBaseForFragShader) {
107 if (!TargetPlatformIsVulkan(GetParam())) {
108 GTEST_SKIP();
109 }
110
111 ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
112 ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
113
114 auto get_binding = [&](const char* fixture) -> uint32_t {
115 auto json_fd = GetReflectionJson(fixture);
116 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
117 return shader_json["buffers"][0]["binding"].get<uint32_t>();
118 };
119
120 auto vert_uniform_binding = get_binding("sample.vert");
121 auto frag_uniform_binding = get_binding("sample.frag");
122
123 ASSERT_GT(frag_uniform_binding, vert_uniform_binding);
124}
125
126TEST_P(CompilerTest, UniformsHaveBindingAndSet) {
127 if (GetParam() == TargetPlatform::kSkSL) {
128 GTEST_SKIP() << "Not supported with SkSL";
129 }
130 ASSERT_TRUE(CanCompileAndReflect("sample_with_binding.vert",
132 ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
133
134 struct binding_and_set {
135 uint32_t binding;
136 uint32_t set;
137 };
138
139 auto get_binding = [&](const char* fixture) -> binding_and_set {
140 auto json_fd = GetReflectionJson(fixture);
141 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
142 uint32_t binding = shader_json["buffers"][0]["binding"].get<uint32_t>();
143 uint32_t set = shader_json["buffers"][0]["set"].get<uint32_t>();
144 return {binding, set};
145 };
146
147 auto vert_uniform_binding = get_binding("sample_with_binding.vert");
148 auto frag_uniform_binding = get_binding("sample.frag");
149
150 ASSERT_EQ(frag_uniform_binding.set, 0u);
151 ASSERT_EQ(vert_uniform_binding.set, 3u);
152 ASSERT_EQ(vert_uniform_binding.binding, 17u);
153}
154
155TEST_P(CompilerTest, SkSLTextureLookUpOrderOfOperations) {
156 if (GetParam() != TargetPlatform::kSkSL) {
157 GTEST_SKIP() << "Only supported on SkSL";
158 }
159 ASSERT_TRUE(
160 CanCompileAndReflect("texture_lookup.frag", SourceType::kFragmentShader));
161
162 auto shader = GetShaderFile("texture_lookup.frag", GetParam());
163 std::string_view shader_mapping(
164 reinterpret_cast<const char*>(shader->GetMapping()), shader->GetSize());
165
166 constexpr std::string_view expected =
167 "textureA.eval(textureA_size * ( vec2(1.0) + flutter_FragCoord.xy));";
168
169 EXPECT_NE(shader_mapping.find(expected), std::string::npos);
170}
171
172TEST_P(CompilerTest, CanCompileStructs) {
173 if (GetParam() != TargetPlatform::kSkSL) {
174 GTEST_SKIP() << "Only supported on SkSL";
175 }
176 ASSERT_TRUE(CanCompileAndReflect("struct_internal.frag",
178}
179
180#define INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(suite_name) \
181 INSTANTIATE_TEST_SUITE_P( \
182 suite_name, CompilerTest, \
183 ::testing::Values(TargetPlatform::kOpenGLES, \
184 TargetPlatform::kOpenGLDesktop, \
185 TargetPlatform::kMetalDesktop, \
186 TargetPlatform::kMetalIOS, TargetPlatform::kSkSL), \
187 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) { \
188 return TargetPlatformToString(info.param); \
189 });
190
192
193} // namespace testing
194} // namespace compiler
195} // namespace impeller
std::shared_ptr< fml::Mapping > GetSPIRVAssembly() const
Definition compiler.cc:486
#define INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(suite_name)
std::unique_ptr< fml::Mapping > OpenFixtureAsMapping(const std::string &fixture_name)
Opens a fixture of the given file name and returns a mapping to its contents.
Definition testing.cc:58
TEST_P(CompilerTest, CanCompile)
TEST(CompilerTest, Defines)
SourceType SourceTypeFromFileName(const std::string &file_name)
Definition types.cc:30
bool TargetPlatformIsMetal(TargetPlatform platform)
Definition types.cc:290
bool TargetPlatformIsVulkan(TargetPlatform platform)
Definition types.cc:309