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_("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",
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",
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 
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