| 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()
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",
107 SourceType::kVertexShader));
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",
153 SourceType::kFragmentShader));
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
167 INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(CompilerSuite);
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