| 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"
8 #include "impeller/base/validation.h"
9 #include "impeller/compiler/compiler.h"
10 #include "impeller/compiler/compiler_test.h"
11 #include "impeller/compiler/source_options.h"
12 #include "impeller/compiler/types.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,
33 SourceLanguage::kGLSL));
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",
49 SourceType::kVertexShader,
50 SourceLanguage::kHLSL, "VertexShader"));
51 ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
52 SourceType::kFragmentShader,
53 SourceLanguage::kHLSL, "FragmentShader"));
54 }
55
56 TEST_P(CompilerTest, CanCompileComputeShader) {
57 if (!TargetPlatformIsMetal(GetParam())) {
58 GTEST_SKIP_("Only enabled on Metal backends till ES 3.2 support is added.");
59 }
60 ASSERT_TRUE(CanCompileAndReflect("sample.comp"));
61 ASSERT_TRUE(CanCompileAndReflect("sample.comp", SourceType::kComputeShader));
62 }
63
64 TEST_P(CompilerTest, MustFailDueToExceedingResourcesLimit) {
65 if (GetParam() == TargetPlatform::kSkSL) {
66 GTEST_SKIP() << "Not supported with SkSL";
67 }
68 ScopedValidationDisable disable_validation;
69 ASSERT_FALSE(
70 CanCompileAndReflect("resources_limit.vert", SourceType::kVertexShader));
71 }
72
73 TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) {
74 if (GetParam() == TargetPlatform::kSkSL) {
75 GTEST_SKIP() << "Not supported with SkSL";
76 }
77 ScopedValidationDisable disable_validation;
78 ASSERT_FALSE(CanCompileAndReflect("struct_def_bug.vert"));
79 }
80
81 TEST_P(CompilerTest, BindingBaseForFragShader) {
82 if (!TargetPlatformIsVulkan(GetParam())) {
83 GTEST_SKIP();
84 }
85
86 ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
87 ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
88
89 auto get_binding = [&](const char* fixture) -> uint32_t {
90 auto json_fd = GetReflectionJson(fixture);
91 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
92 return shader_json["buffers"][0]["binding"].get<uint32_t>();
93 };
94
95 auto vert_uniform_binding = get_binding("sample.vert");
96 auto frag_uniform_binding = get_binding("sample.frag");
97
98 ASSERT_GT(frag_uniform_binding, vert_uniform_binding);
99 }
100
101 TEST_P(CompilerTest, UniformsHaveBindingAndSet) {
102 if (GetParam() == TargetPlatform::kSkSL) {
103 GTEST_SKIP() << "Not supported with SkSL";
104 }
105 ASSERT_TRUE(CanCompileAndReflect("sample_with_binding.vert",
106 SourceType::kVertexShader));
107 ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
108
109 struct binding_and_set {
110 uint32_t binding;
111 uint32_t set;
112 };
113
114 auto get_binding = [&](const char* fixture) -> binding_and_set {
115 auto json_fd = GetReflectionJson(fixture);
116 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
117 uint32_t binding = shader_json["buffers"][0]["binding"].get<uint32_t>();
118 uint32_t set = shader_json["buffers"][0]["set"].get<uint32_t>();
119 return {binding, set};
120 };
121
122 auto vert_uniform_binding = get_binding("sample_with_binding.vert");
123 auto frag_uniform_binding = get_binding("sample.frag");
124
125 ASSERT_EQ(frag_uniform_binding.set, 0u);
126 ASSERT_EQ(vert_uniform_binding.set, 3u);
127 ASSERT_EQ(vert_uniform_binding.binding, 17u);
128 }
129
130 TEST_P(CompilerTest, SkSLTextureLookUpOrderOfOperations) {
131 if (GetParam() != TargetPlatform::kSkSL) {
132 GTEST_SKIP() << "Only supported on SkSL";
133 }
134 ASSERT_TRUE(
135 CanCompileAndReflect("texture_lookup.frag", SourceType::kFragmentShader));
136
137 auto shader = GetShaderFile("texture_lookup.frag", GetParam());
138 std::string_view shader_mapping(
139 reinterpret_cast<const char*>(shader->GetMapping()), shader->GetSize());
140
141 constexpr std::string_view expected =
142 "textureA.eval(textureA_size * ( vec2(1.0) + flutter_FragCoord.xy));";
143
144 EXPECT_NE(shader_mapping.find(expected), std::string::npos);
145 }
146
147 TEST_P(CompilerTest, CanCompileStructs) {
148 if (GetParam() != TargetPlatform::kSkSL) {
149 GTEST_SKIP() << "Only supported on SkSL";
150 }
151 ASSERT_TRUE(CanCompileAndReflect("struct_internal.frag",
152 SourceType::kFragmentShader));
153 }
154
155 #define INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(suite_name) \
156 INSTANTIATE_TEST_SUITE_P( \
157 suite_name, CompilerTest, \
158 ::testing::Values(TargetPlatform::kOpenGLES, \
159 TargetPlatform::kOpenGLDesktop, \
160 TargetPlatform::kMetalDesktop, \
161 TargetPlatform::kMetalIOS, TargetPlatform::kSkSL), \
162 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) { \
163 return TargetPlatformToString(info.param); \
164 });
165
166 INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(CompilerSuite);
167
168 } // namespace testing
169 } // namespace compiler
170 } // 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:19
impeller::ScopedValidationDisable
Definition: validation.h:38
impeller::compiler::SourceType::kVertexShader
@ kVertexShader
impeller
Definition: aiks_blur_unittests.cc:20
types.h
impeller::compiler::TargetPlatform::kSkSL
@ kSkSL