Flutter Impeller
impeller::compiler::testing Namespace Reference

Classes

class  CompilerTestBase
 
class  CompilerTest
 
class  CompilerTestRuntime
 
class  CompilerTestSkSL
 
class  CompilerTestUnknownPlatform
 

Functions

static std::string GetIntermediatesPath ()
 
static std::string ReflectionHeaderName (const char *fixture_name)
 
static std::string ReflectionCCName (const char *fixture_name)
 
static std::string ReflectionJSONName (const char *fixture_name)
 
static std::string SPIRVFileName (const char *fixture_name)
 
static std::string SLFileName (const char *fixture_name, TargetPlatform platform)
 
 INSTANTIATE_TEST_SUITE_P (CompilerSuite, CompilerTest, ::testing::Values(TargetPlatform::kOpenGLES, TargetPlatform::kOpenGLDesktop, TargetPlatform::kMetalDesktop, TargetPlatform::kMetalIOS, TargetPlatform::kVulkan), [](const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);})
 
 INSTANTIATE_TEST_SUITE_P (CompilerSuite, CompilerTestRuntime, ::testing::Values(TargetPlatform::kRuntimeStageMetal, TargetPlatform::kRuntimeStageGLES, TargetPlatform::kRuntimeStageGLES3, TargetPlatform::kRuntimeStageVulkan, TargetPlatform::kSkSL), [](const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);})
 
 INSTANTIATE_TEST_SUITE_P (CompilerSuite, CompilerTestSkSL, ::testing::Values(TargetPlatform::kSkSL), [](const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);})
 
 INSTANTIATE_TEST_SUITE_P (CompilerSuite, CompilerTestUnknownPlatform, ::testing::Values(TargetPlatform::kUnknown), [](const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);})
 
 TEST (CompilerTest, Defines)
 
 TEST (CompilerTest, DeprecatedUnflippedDefines)
 
 TEST (CompilerTest, YFlipInjectionForGLESVertexShaders)
 
 TEST (CompilerTest, YFlipInjectionHandlesEarlyReturnsInGLESVertexShader)
 
 TEST (CompilerTest, ShaderKindMatchingIsSuccessful)
 
 TEST_P (CompilerTest, CanCompile)
 
 TEST_P (CompilerTest, CanCompileHLSL)
 
 TEST_P (CompilerTest, CanCompileHLSLWithMultipleStages)
 
 TEST_P (CompilerTest, CanCompileComputeShader)
 
 TEST_P (CompilerTest, MustFailDueToExceedingResourcesLimit)
 
 TEST_P (CompilerTest, MustFailDueToMultipleLocationPerStructMember)
 
 TEST_P (CompilerTest, UniformBlockInstanceNameCanonicalizedForGL)
 
 TEST_P (CompilerTest, BindingBaseForFragShader)
 
 TEST_P (CompilerTestRuntime, UniformsAppearInJson)
 
 TEST_P (CompilerTestRuntime, PositionedUniformsAppearInJson)
 
 TEST_P (CompilerTest, UniformsHaveBindingAndSet)
 
 TEST_P (CompilerTestSkSL, SkSLTextureLookUpOrderOfOperations)
 
 TEST_P (CompilerTestSkSL, CanCompileStructs)
 
 TEST_P (CompilerTestSkSL, FailsToCompileDueToArrayInitializerWithConstants)
 
 TEST_P (CompilerTestSkSL, FailsToCompileDueToArrayInitializerWithVariables)
 
 TEST_P (CompilerTestSkSL, FailsToCompileDueToArrayAssignment)
 
 TEST_P (CompilerTestSkSL, CompilesWithValidArrayInitialization)
 
 TEST_P (CompilerTestRuntime, Mat2Reflection)
 
 TEST_P (CompilerTestUnknownPlatform, MustFailDueToUnknownPlatform)
 
 TEST (ShaderBundleTest, ParseShaderBundleConfigFailsForInvalidJSON)
 
 TEST (ShaderBundleTest, ParseShaderBundleConfigFailsWhenEntryNotObject)
 
 TEST (ShaderBundleTest, ParseShaderBundleConfigFailsWhenMissingFile)
 
 TEST (ShaderBundleTest, ParseShaderBundleConfigFailsWhenMissingType)
 
 TEST (ShaderBundleTest, ParseShaderBundleConfigFailsForInvalidType)
 
 TEST (ShaderBundleTest, ParseShaderBundleConfigFailsForInvalidLanguage)
 
 TEST (ShaderBundleTest, ParseShaderBundleConfigReturnsExpectedConfig)
 
template<typename T >
const T * FindByName (const std::vector< std::unique_ptr< T >> &collection, const std::string &name)
 
 TEST (ShaderBundleTest, GenerateShaderBundleFlatbufferProducesCorrectResult)
 
 TEST (ShaderBundleTest, GenerateShaderBundleFlatbufferReportsSourceFilesAsDependencies)
 
 TEST (ShaderBundleTest, GenerateShaderBundleFlatbufferIgnoresNullDependencyCollector)
 
 TEST (ShaderBundleTest, DeriveShaderFloatTypeFromDimensions)
 
 TEST (ShaderBundleTest, TargetPlatformDefinesMatchEachBackend)
 
 TEST (ShaderBundleTest, InjectsTargetDefinesDuringCompilation)
 
Switches MakeSwitchesDesktopGL (std::initializer_list< const char * > additional_options={})
 
 TEST (SwitchesTest, DoesntMangleUnicodeIncludes)
 
 TEST (SwitchesTest, SourceLanguageDefaultsToGLSL)
 
 TEST (SwitchesTest, SourceLanguageCanBeSetToHLSL)
 
 TEST (SwitchesTest, DefaultEntryPointIsMain)
 
 TEST (SwitchesTest, EntryPointCanBeSetForHLSL)
 
 TEST (SwitchesTEst, ConvertToEntrypointName)
 
 TEST (SwitchesTest, ShaderBundleModeValid)
 
 TEST (SwitchesTest, EntryPointPrefixIsApplied)
 
 TEST (SwitchesTest, CommandLinePathUtf8)
 

Variables

const std::string kUnlitFragmentBundleConfig
 
const std::string kUnlitVertexBundleConfig
 

Function Documentation

◆ FindByName()

template<typename T >
const T* impeller::compiler::testing::FindByName ( const std::vector< std::unique_ptr< T >> &  collection,
const std::string &  name 
)

Definition at line 120 of file shader_bundle_unittests.cc.

121  {
122  const auto maybe = std::find_if(
123  collection.begin(), collection.end(),
124  [&name](const std::unique_ptr<T>& value) { return value->name == name; });
125  if (maybe == collection.end()) {
126  return nullptr;
127  }
128  return maybe->get();
129 }
int32_t value

References value.

Referenced by TEST().

◆ GetIntermediatesPath()

static std::string impeller::compiler::testing::GetIntermediatesPath ( )
static

Definition at line 17 of file compiler_test.cc.

17  {
18  auto test_name = flutter::testing::GetCurrentTestName();
19  std::replace(test_name.begin(), test_name.end(), '/', '_');
20  std::replace(test_name.begin(), test_name.end(), '.', '_');
21  std::stringstream dir_name;
22  dir_name << test_name << "_" << std::to_string(fml::GetCurrentProcId());
23  return fml::paths::JoinPaths(
24  {flutter::testing::GetFixturesPath(), dir_name.str()});
25 }

◆ INSTANTIATE_TEST_SUITE_P() [1/4]

impeller::compiler::testing::INSTANTIATE_TEST_SUITE_P ( CompilerSuite  ,
CompilerTest  ,
::testing::Values(TargetPlatform::kOpenGLES, TargetPlatform::kOpenGLDesktop, TargetPlatform::kMetalDesktop, TargetPlatform::kMetalIOS, TargetPlatform::kVulkan)  ,
[] (const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);}   
)

◆ INSTANTIATE_TEST_SUITE_P() [2/4]

impeller::compiler::testing::INSTANTIATE_TEST_SUITE_P ( CompilerSuite  ,
CompilerTestRuntime  ,
::testing::Values(TargetPlatform::kRuntimeStageMetal, TargetPlatform::kRuntimeStageGLES, TargetPlatform::kRuntimeStageGLES3, TargetPlatform::kRuntimeStageVulkan, TargetPlatform::kSkSL)  ,
[] (const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);}   
)

◆ INSTANTIATE_TEST_SUITE_P() [3/4]

impeller::compiler::testing::INSTANTIATE_TEST_SUITE_P ( CompilerSuite  ,
CompilerTestSkSL  ,
::testing::Values(TargetPlatform::kSkSL)  ,
[] (const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);}   
)

◆ INSTANTIATE_TEST_SUITE_P() [4/4]

impeller::compiler::testing::INSTANTIATE_TEST_SUITE_P ( CompilerSuite  ,
CompilerTestUnknownPlatform  ,
::testing::Values(TargetPlatform::kUnknown)  ,
[] (const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);}   
)

◆ MakeSwitchesDesktopGL()

Switches impeller::compiler::testing::MakeSwitchesDesktopGL ( std::initializer_list< const char * >  additional_options = {})

Definition at line 20 of file switches_unittests.cc.

21  {}) {
22  std::vector<const char*> options = {"--opengl-desktop", "--input=input.vert",
23  "--sl=output.vert",
24  "--spirv=output.spirv"};
25  options.insert(options.end(), additional_options.begin(),
26  additional_options.end());
27 
28  auto cl = fml::CommandLineFromIteratorsWithArgv0("impellerc", options.begin(),
29  options.end());
30  return Switches(cl);
31 }

Referenced by TEST().

◆ ReflectionCCName()

static std::string impeller::compiler::testing::ReflectionCCName ( const char *  fixture_name)
static

Definition at line 48 of file compiler_test.cc.

48  {
49  std::stringstream stream;
50  stream << fixture_name << ".cc";
51  return stream.str();
52 }

Referenced by impeller::compiler::testing::CompilerTestBase::CanCompileAndReflect().

◆ ReflectionHeaderName()

static std::string impeller::compiler::testing::ReflectionHeaderName ( const char *  fixture_name)
static

Definition at line 42 of file compiler_test.cc.

42  {
43  std::stringstream stream;
44  stream << fixture_name << ".h";
45  return stream.str();
46 }

Referenced by impeller::compiler::testing::CompilerTestBase::CanCompileAndReflect().

◆ ReflectionJSONName()

static std::string impeller::compiler::testing::ReflectionJSONName ( const char *  fixture_name)
static

Definition at line 54 of file compiler_test.cc.

54  {
55  std::stringstream stream;
56  stream << fixture_name << ".json";
57  return stream.str();
58 }

Referenced by impeller::compiler::testing::CompilerTestBase::CanCompileAndReflect(), and impeller::compiler::testing::CompilerTestBase::GetReflectionJson().

◆ SLFileName()

static std::string impeller::compiler::testing::SLFileName ( const char *  fixture_name,
TargetPlatform  platform 
)
static

Definition at line 66 of file compiler_test.cc.

67  {
68  std::stringstream stream;
69  stream << fixture_name << "." << TargetPlatformSLExtension(platform);
70  return stream.str();
71 }
std::string TargetPlatformSLExtension(TargetPlatform platform)
Definition: types.cc:218

References impeller::compiler::TargetPlatformSLExtension().

Referenced by impeller::compiler::testing::CompilerTestBase::CanCompileAndReflect(), and impeller::compiler::testing::CompilerTestBase::GetShaderFile().

◆ SPIRVFileName()

static std::string impeller::compiler::testing::SPIRVFileName ( const char *  fixture_name)
static

Definition at line 60 of file compiler_test.cc.

60  {
61  std::stringstream stream;
62  stream << fixture_name << ".spv";
63  return stream.str();
64 }

Referenced by impeller::compiler::testing::CompilerTestBase::CanCompileAndReflect().

◆ TEST() [1/27]

impeller::compiler::testing::TEST ( CompilerTest  ,
Defines   
)

Definition at line 58 of file compiler_unittests.cc.

58  {
59  std::shared_ptr<const fml::Mapping> fixture =
60  flutter::testing::OpenFixtureAsMapping("check_gles_definition.frag");
61 
62  SourceOptions options;
63  options.source_language = SourceLanguage::kGLSL;
64  options.target_platform = TargetPlatform::kRuntimeStageGLES;
65  options.entry_point_name = "main";
66  options.type = SourceType::kFragmentShader;
67 
68  Reflector::Options reflector_options;
69  reflector_options.target_platform = TargetPlatform::kRuntimeStageGLES;
70  Compiler compiler = Compiler(fixture, options, reflector_options);
71 
72  // Should fail as the shader has a compilation error in it.
73  EXPECT_EQ(compiler.GetSPIRVAssembly(), nullptr);
74 
75  // Should succeed as the compilation error is ifdef'd out.
76  options.target_platform = TargetPlatform::kRuntimeStageVulkan;
77  reflector_options.target_platform = TargetPlatform::kRuntimeStageVulkan;
78  Compiler compiler_2 = Compiler(fixture, options, reflector_options);
79  EXPECT_NE(compiler_2.GetSPIRVAssembly(), nullptr);
80 }

References impeller::compiler::SourceOptions::entry_point_name, impeller::compiler::Compiler::GetSPIRVAssembly(), impeller::compiler::kFragmentShader, impeller::compiler::kGLSL, impeller::compiler::kRuntimeStageGLES, impeller::compiler::kRuntimeStageVulkan, impeller::compiler::SourceOptions::source_language, impeller::compiler::Reflector::Options::target_platform, impeller::compiler::SourceOptions::target_platform, and impeller::compiler::SourceOptions::type.

◆ TEST() [2/27]

impeller::compiler::testing::TEST ( CompilerTest  ,
DeprecatedUnflippedDefines   
)

Definition at line 82 of file compiler_unittests.cc.

82  {
83  std::shared_ptr<const fml::Mapping> fixture =
84  flutter::testing::OpenFixtureAsMapping(
85  "check_gles_unflipped_definition.frag");
86 
87  SourceOptions options;
88  options.source_language = SourceLanguage::kGLSL;
89  options.entry_point_name = "main";
90  options.type = SourceType::kFragmentShader;
91 
92  Reflector::Options reflector_options;
93 
94  // Test that IMPELLER_OPENGLES_UNFLIPPED_DEPRECATED is defined on
95  // TargetPlatform::kRuntimeStageGLES.
96  {
97  options.target_platform = TargetPlatform::kRuntimeStageGLES;
98  reflector_options.target_platform = TargetPlatform::kRuntimeStageGLES;
99  Compiler compiler = Compiler(fixture, options, reflector_options);
100  // Should fail as the shader has a compilation error in it.
101  EXPECT_EQ(compiler.GetSPIRVAssembly(), nullptr);
102  }
103 
104  // Test that IMPELLER_OPENGLES_UNFLIPPED_DEPRECATED is defined on
105  // TargetPlatform::kRuntimeStageGLES3.
106  {
107  options.target_platform = TargetPlatform::kRuntimeStageGLES3;
108  reflector_options.target_platform = TargetPlatform::kRuntimeStageGLES3;
109  Compiler compiler = Compiler(fixture, options, reflector_options);
110  // Should fail as the shader has a compilation error in it.
111  EXPECT_EQ(compiler.GetSPIRVAssembly(), nullptr);
112  }
113 
114  // Should succeed as the compilation error is ifdef'd out.
115  {
116  options.target_platform = TargetPlatform::kRuntimeStageVulkan;
117  reflector_options.target_platform = TargetPlatform::kRuntimeStageVulkan;
118  Compiler compiler = Compiler(fixture, options, reflector_options);
119  EXPECT_NE(compiler.GetSPIRVAssembly(), nullptr);
120  }
121 }

References impeller::compiler::SourceOptions::entry_point_name, impeller::compiler::Compiler::GetSPIRVAssembly(), impeller::compiler::kFragmentShader, impeller::compiler::kGLSL, impeller::compiler::kRuntimeStageGLES, impeller::compiler::kRuntimeStageGLES3, impeller::compiler::kRuntimeStageVulkan, impeller::compiler::SourceOptions::source_language, impeller::compiler::Reflector::Options::target_platform, impeller::compiler::SourceOptions::target_platform, and impeller::compiler::SourceOptions::type.

◆ TEST() [3/27]

impeller::compiler::testing::TEST ( CompilerTest  ,
ShaderKindMatchingIsSuccessful   
)

Definition at line 223 of file compiler_unittests.cc.

223  {
224  ASSERT_EQ(SourceTypeFromFileName("hello.vert"), SourceType::kVertexShader);
225  ASSERT_EQ(SourceTypeFromFileName("hello.frag"), SourceType::kFragmentShader);
226  ASSERT_EQ(SourceTypeFromFileName("hello.comp"), SourceType::kComputeShader);
227  ASSERT_EQ(SourceTypeFromFileName("hello.msl"), SourceType::kUnknown);
228  ASSERT_EQ(SourceTypeFromFileName("hello.glsl"), SourceType::kUnknown);
229 }
SourceType SourceTypeFromFileName(const std::filesystem::path &file_name)
Definition: types.cc:17

References impeller::compiler::kComputeShader, impeller::compiler::kFragmentShader, impeller::compiler::kUnknown, impeller::compiler::kVertexShader, and impeller::compiler::SourceTypeFromFileName().

◆ TEST() [4/27]

impeller::compiler::testing::TEST ( CompilerTest  ,
YFlipInjectionForGLESVertexShaders   
)

Definition at line 123 of file compiler_unittests.cc.

123  {
124  // Compiles `fixture_name` for `platform` and returns the generated SL
125  // source. See https://github.com/flutter/flutter/issues/186554.
126  auto compile = [](const char* fixture_name, SourceType type,
127  TargetPlatform platform) -> std::string {
128  std::shared_ptr<fml::Mapping> fixture =
129  flutter::testing::OpenFixtureAsMapping(fixture_name);
130  FML_CHECK(fixture);
131 
132  SourceOptions options(fixture_name, type);
133  options.source_language = SourceLanguage::kGLSL;
134  options.target_platform = platform;
135  options.working_directory = std::make_shared<fml::UniqueFD>(
136  flutter::testing::OpenFixturesDirectory());
137  options.entry_point_name = "main";
138 
139  Reflector::Options reflector_options;
140  reflector_options.target_platform = platform;
141  reflector_options.header_file_name = "y_flip_injection.h";
142  reflector_options.shader_name = "shader";
143 
144  Compiler compiler(fixture, options, reflector_options);
145  if (!compiler.IsValid()) {
146  return "";
147  }
148  auto sl = compiler.GetSLShaderSource();
149  if (!sl || !sl->GetMapping()) {
150  return "";
151  }
152  return std::string(reinterpret_cast<const char*>(sl->GetMapping()),
153  sl->GetSize());
154  };
155 
156  // GL vertex shader: gets both the declaration and the epilogue.
157  const std::string gl_vert = compile("sample.vert", SourceType::kVertexShader,
158  TargetPlatform::kOpenGLES);
159  EXPECT_NE(gl_vert.find("uniform float _impeller_y_flip"), std::string::npos)
160  << "GLES vertex shader is missing the y-flip uniform declaration:\n"
161  << gl_vert;
162  EXPECT_NE(gl_vert.find("gl_Position.y *= _impeller_y_flip"),
163  std::string::npos)
164  << "GLES vertex shader is missing the y-flip epilogue:\n"
165  << gl_vert;
166 
167  // GL fragment shader: not injected.
168  const std::string gl_frag = compile(
169  "sample.frag", SourceType::kFragmentShader, TargetPlatform::kOpenGLES);
170  EXPECT_EQ(gl_frag.find("_impeller_y_flip"), std::string::npos)
171  << "GLES fragment shader was unexpectedly injected:\n"
172  << gl_frag;
173 
174  // Metal vertex shader: not injected.
175  const std::string mtl_vert = compile("sample.vert", SourceType::kVertexShader,
176  TargetPlatform::kMetalIOS);
177  EXPECT_EQ(mtl_vert.find("_impeller_y_flip"), std::string::npos)
178  << "Metal vertex shader was unexpectedly injected:\n"
179  << mtl_vert;
180 }

References impeller::compiler::SourceOptions::entry_point_name, impeller::compiler::Compiler::GetSLShaderSource(), impeller::compiler::Reflector::Options::header_file_name, impeller::compiler::Compiler::IsValid(), impeller::compiler::kFragmentShader, impeller::compiler::kGLSL, impeller::compiler::kMetalIOS, impeller::compiler::kOpenGLES, impeller::compiler::kVertexShader, impeller::compiler::Reflector::Options::shader_name, impeller::compiler::SourceOptions::source_language, impeller::compiler::Reflector::Options::target_platform, impeller::compiler::SourceOptions::target_platform, and impeller::compiler::SourceOptions::working_directory.

◆ TEST() [5/27]

impeller::compiler::testing::TEST ( CompilerTest  ,
YFlipInjectionHandlesEarlyReturnsInGLESVertexShader   
)

Definition at line 182 of file compiler_unittests.cc.

182  {
183  // `y_flip_early_return.vert` has an early `return` before main's implicit
184  // exit; the wrap-main injection must flip on both paths.
185  std::shared_ptr<fml::Mapping> fixture =
186  flutter::testing::OpenFixtureAsMapping("y_flip_early_return.vert");
187  FML_CHECK(fixture);
188 
189  SourceOptions options("y_flip_early_return.vert", SourceType::kVertexShader);
190  options.source_language = SourceLanguage::kGLSL;
191  options.target_platform = TargetPlatform::kOpenGLES;
192  options.working_directory = std::make_shared<fml::UniqueFD>(
193  flutter::testing::OpenFixturesDirectory());
194  options.entry_point_name = "main";
195 
196  Reflector::Options reflector_options;
197  reflector_options.target_platform = TargetPlatform::kOpenGLES;
198  reflector_options.header_file_name = "y_flip_early_return.h";
199  reflector_options.shader_name = "shader";
200 
201  Compiler compiler(fixture, options, reflector_options);
202  ASSERT_TRUE(compiler.IsValid());
203  auto sl = compiler.GetSLShaderSource();
204  ASSERT_TRUE(sl && sl->GetMapping());
205  const std::string gl_vert(reinterpret_cast<const char*>(sl->GetMapping()),
206  sl->GetSize());
207 
208  EXPECT_NE(gl_vert.find("void _impeller_user_main("), std::string::npos)
209  << gl_vert;
210  EXPECT_NE(gl_vert.find("_impeller_user_main();"), std::string::npos)
211  << gl_vert;
212  EXPECT_NE(gl_vert.find("gl_Position.y *= _impeller_y_flip"),
213  std::string::npos)
214  << gl_vert;
215 
216  // Only the wrapper's `void main(` should remain after the rename.
217  const size_t first_main = gl_vert.find("\nvoid main(");
218  ASSERT_NE(first_main, std::string::npos);
219  EXPECT_EQ(gl_vert.find("\nvoid main(", first_main + 1), std::string::npos)
220  << gl_vert;
221 }

References impeller::compiler::SourceOptions::entry_point_name, impeller::compiler::Compiler::GetSLShaderSource(), impeller::compiler::Reflector::Options::header_file_name, impeller::compiler::Compiler::IsValid(), impeller::compiler::kGLSL, impeller::compiler::kOpenGLES, impeller::compiler::kVertexShader, impeller::compiler::Reflector::Options::shader_name, impeller::compiler::SourceOptions::source_language, impeller::compiler::Reflector::Options::target_platform, impeller::compiler::SourceOptions::target_platform, and impeller::compiler::SourceOptions::working_directory.

◆ TEST() [6/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
DeriveShaderFloatTypeFromDimensions   
)

Definition at line 273 of file shader_bundle_unittests.cc.

273  {
274  // Non-float types always map to nullopt.
275  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kSignedInt, 1, 1), std::nullopt);
276  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kUnsignedInt, 4, 1),
277  std::nullopt);
278  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kBoolean, 1, 1), std::nullopt);
279 
280  // Scalar and vector floats (columns == 1).
281  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 1, 1),
283  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 2, 1),
284  ShaderFloatType::kVec2);
285  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 3, 1),
286  ShaderFloatType::kVec3);
287  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 4, 1),
288  ShaderFloatType::kVec4);
289 
290  // Square matrices (vec_size == columns).
291  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 2, 2),
292  ShaderFloatType::kMat2);
293  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 3, 3),
294  ShaderFloatType::kMat3);
295  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 4, 4),
296  ShaderFloatType::kMat4);
297 
298  // Non-square matrices and unsupported shapes return nullopt.
299  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 3, 2), std::nullopt);
300  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 2, 3), std::nullopt);
301  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 5, 1), std::nullopt);
302 
303  // Zero values (legacy bundle defaults) map to nullopt.
304  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 0, 0), std::nullopt);
305  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 0, 1), std::nullopt);
306  EXPECT_EQ(DeriveShaderFloatType(ShaderType::kFloat, 1, 0), std::nullopt);
307 }
constexpr std::optional< ShaderFloatType > DeriveShaderFloatType(ShaderType type, size_t vec_size, size_t columns)
Derive the ShaderFloatType from the base ShaderType and the (vec_size, columns) dimensions reported b...
Definition: shader_types.h:92

References impeller::DeriveShaderFloatType(), impeller::kBoolean, impeller::kFloat, impeller::kMat2, impeller::kMat3, impeller::kMat4, impeller::kSignedInt, impeller::kUnsignedInt, impeller::kVec2, impeller::kVec3, and impeller::kVec4.

◆ TEST() [7/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
GenerateShaderBundleFlatbufferIgnoresNullDependencyCollector   
)

Definition at line 251 of file shader_bundle_unittests.cc.

252  {
253  // Passing nullptr as the dependency collector is supported and is
254  // the default behaviour for callers that don't need a depfile.
255  std::string fixtures_path = flutter::testing::GetFixturesPath();
256  std::string config =
257  "{\"UnlitFragment\": {\"type\": \"fragment\", \"file\": \"" +
258  fixtures_path +
259  "/flutter_gpu_unlit.frag\"}, \"UnlitVertex\": {\"type\": \"vertex\", "
260  "\"file\": \"" +
261  fixtures_path + "/flutter_gpu_unlit.vert\"}}";
262 
263  SourceOptions options;
264  options.target_platform = TargetPlatform::kRuntimeStageMetal;
265  options.source_language = SourceLanguage::kGLSL;
266 
267  std::optional<fb::shaderbundle::ShaderBundleT> bundle =
268  GenerateShaderBundleFlatbuffer(config, options, /*out_dependencies=*/
269  nullptr);
270  ASSERT_TRUE(bundle.has_value());
271 }
std::optional< fb::shaderbundle::ShaderBundleT > GenerateShaderBundleFlatbuffer(const std::string &bundle_config_json, const SourceOptions &options, std::set< std::string > *out_dependencies)
Parses the JSON shader bundle configuration and invokes the compiler multiple times to produce a shad...

References impeller::compiler::GenerateShaderBundleFlatbuffer(), impeller::compiler::kGLSL, impeller::compiler::kRuntimeStageMetal, impeller::compiler::SourceOptions::source_language, and impeller::compiler::SourceOptions::target_platform.

◆ TEST() [8/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
GenerateShaderBundleFlatbufferProducesCorrectResult   
)

Verify vertex shader.

Verify fragment shader.

Definition at line 131 of file shader_bundle_unittests.cc.

131  {
132  std::string fixtures_path = flutter::testing::GetFixturesPath();
133  std::string config =
134  "{\"UnlitFragment\": {\"type\": \"fragment\", \"file\": \"" +
135  fixtures_path +
136  "/flutter_gpu_unlit.frag\"}, \"UnlitVertex\": {\"type\": "
137  "\"vertex\", \"file\": \"" +
138  fixtures_path + "/flutter_gpu_unlit.vert\"}}";
139 
140  SourceOptions options;
141  options.target_platform = TargetPlatform::kRuntimeStageMetal;
142  options.source_language = SourceLanguage::kGLSL;
143 
144  std::optional<fb::shaderbundle::ShaderBundleT> bundle =
145  GenerateShaderBundleFlatbuffer(config, options);
146  ASSERT_TRUE(bundle.has_value());
147 
148  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
149  const auto& shaders = bundle->shaders;
150 
151  const auto* vertex = FindByName(shaders, "UnlitVertex");
152  const auto* fragment = FindByName(shaders, "UnlitFragment");
153  ASSERT_NE(vertex, nullptr);
154  ASSERT_NE(fragment, nullptr);
155 
156  // --------------------------------------------------------------------------
157  /// Verify vertex shader.
158  ///
159 
160  EXPECT_STREQ(vertex->metal_desktop->entrypoint.c_str(),
161  "flutter_gpu_unlit_vertex_main");
162  EXPECT_EQ(vertex->metal_desktop->stage,
163  fb::shaderbundle::ShaderStage::kVertex);
164 
165  // Inputs.
166  ASSERT_EQ(vertex->metal_desktop->inputs.size(), 1u);
167  const auto& v_in_position = vertex->metal_desktop->inputs[0];
168  EXPECT_STREQ(v_in_position->name.c_str(), "position");
169  EXPECT_EQ(v_in_position->location, 0u);
170  EXPECT_EQ(v_in_position->set, 0u);
171  EXPECT_EQ(v_in_position->binding, 0u);
172  EXPECT_EQ(v_in_position->type, fb::shaderbundle::InputDataType::kFloat);
173  EXPECT_EQ(v_in_position->bit_width, 32u);
174  EXPECT_EQ(v_in_position->vec_size, 2u);
175  EXPECT_EQ(v_in_position->columns, 1u);
176  EXPECT_EQ(v_in_position->offset, 0u);
177 
178  // Uniforms.
179  ASSERT_EQ(vertex->metal_desktop->uniform_structs.size(), 1u);
180  const auto* vert_info =
181  FindByName(vertex->metal_desktop->uniform_structs, "VertInfo");
182  ASSERT_NE(vert_info, nullptr);
183  EXPECT_EQ(vert_info->ext_res_0, 0u);
184  EXPECT_EQ(vert_info->set, 0u);
185  EXPECT_EQ(vert_info->binding, 0u);
186  ASSERT_EQ(vert_info->fields.size(), 2u);
187  const auto& mvp = vert_info->fields[0];
188  EXPECT_STREQ(mvp->name.c_str(), "mvp");
189  EXPECT_EQ(mvp->type, fb::shaderbundle::UniformDataType::kFloat);
190  EXPECT_EQ(mvp->offset_in_bytes, 0u);
191  EXPECT_EQ(mvp->element_size_in_bytes, 64u);
192  EXPECT_EQ(mvp->total_size_in_bytes, 64u);
193  EXPECT_EQ(mvp->array_elements, 0u);
194  EXPECT_EQ(mvp->vec_size, 4u);
195  EXPECT_EQ(mvp->columns, 4u);
196  const auto& color = vert_info->fields[1];
197  EXPECT_STREQ(color->name.c_str(), "color");
198  EXPECT_EQ(color->type, fb::shaderbundle::UniformDataType::kFloat);
199  EXPECT_EQ(color->offset_in_bytes, 64u);
200  EXPECT_EQ(color->element_size_in_bytes, 16u);
201  EXPECT_EQ(color->total_size_in_bytes, 16u);
202  EXPECT_EQ(color->array_elements, 0u);
203  EXPECT_EQ(color->vec_size, 4u);
204  EXPECT_EQ(color->columns, 1u);
205 
206  // --------------------------------------------------------------------------
207  /// Verify fragment shader.
208  ///
209 
210  EXPECT_STREQ(fragment->metal_desktop->entrypoint.c_str(),
211  "flutter_gpu_unlit_fragment_main");
212  EXPECT_EQ(fragment->metal_desktop->stage,
213  fb::shaderbundle::ShaderStage::kFragment);
214 
215  // Inputs (not recorded for fragment shaders).
216  ASSERT_EQ(fragment->metal_desktop->inputs.size(), 0u);
217 
218  // Uniforms.
219  ASSERT_EQ(fragment->metal_desktop->inputs.size(), 0u);
220 }
const T * FindByName(const std::vector< std::unique_ptr< T >> &collection, const std::string &name)

References FindByName(), impeller::compiler::GenerateShaderBundleFlatbuffer(), impeller::kFloat, impeller::compiler::kGLSL, impeller::compiler::kRuntimeStageMetal, impeller::compiler::SourceOptions::source_language, and impeller::compiler::SourceOptions::target_platform.

◆ TEST() [9/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
GenerateShaderBundleFlatbufferReportsSourceFilesAsDependencies   
)

Definition at line 222 of file shader_bundle_unittests.cc.

223  {
224  std::string fixtures_path = flutter::testing::GetFixturesPath();
225  const std::string fragment_path = fixtures_path + "/flutter_gpu_unlit.frag";
226  const std::string vertex_path = fixtures_path + "/flutter_gpu_unlit.vert";
227  std::string config =
228  "{\"UnlitFragment\": {\"type\": \"fragment\", \"file\":\"" +
229  fragment_path +
230  "\"}, \"UnlitVertex\": {\"type\": \"vertex\", \"file\": \"" +
231  vertex_path + "\"}}";
232 
233  SourceOptions options;
234  options.target_platform = TargetPlatform::kRuntimeStageMetal;
235  options.source_language = SourceLanguage::kGLSL;
236 
237  std::set<std::string> dependencies;
238  std::optional<fb::shaderbundle::ShaderBundleT> bundle =
239  GenerateShaderBundleFlatbuffer(config, options, &dependencies);
240  ASSERT_TRUE(bundle.has_value());
241 
242  // Every primary source file referenced by the bundle config should
243  // appear in the dependency set, deduplicated across the multiple
244  // target-platform compiles of each shader. The fixtures used here
245  // don't contain `#include` directives, so the dependency set
246  // contains exactly the two source files.
247  EXPECT_NE(dependencies.find(fragment_path), dependencies.end());
248  EXPECT_NE(dependencies.find(vertex_path), dependencies.end());
249 }

References impeller::compiler::GenerateShaderBundleFlatbuffer(), impeller::compiler::kGLSL, impeller::compiler::kRuntimeStageMetal, impeller::compiler::SourceOptions::source_language, and impeller::compiler::SourceOptions::target_platform.

◆ TEST() [10/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
InjectsTargetDefinesDuringCompilation   
)

Definition at line 333 of file shader_bundle_unittests.cc.

333  {
334  // `check_gles_definition.frag` contains an invalid token guarded by
335  // `#ifdef IMPELLER_TARGET_OPENGLES`. Bundling it must fail because the
336  // OpenGLES backend now receives that define and compiles the error branch.
337  // Without the injected define the OpenGLES backend would compile cleanly.
338  std::string fixtures_path = flutter::testing::GetFixturesPath();
339  std::string config = "{\"Probe\": {\"type\": \"fragment\", \"file\": \"" +
340  fixtures_path + "/check_gles_definition.frag\"}}";
341 
342  SourceOptions options;
343  options.target_platform = TargetPlatform::kRuntimeStageMetal;
344  options.source_language = SourceLanguage::kGLSL;
345 
346  std::optional<fb::shaderbundle::ShaderBundleT> bundle =
347  GenerateShaderBundleFlatbuffer(config, options);
348  EXPECT_FALSE(bundle.has_value());
349 }

References impeller::compiler::GenerateShaderBundleFlatbuffer(), impeller::compiler::kGLSL, impeller::compiler::kRuntimeStageMetal, impeller::compiler::SourceOptions::source_language, and impeller::compiler::SourceOptions::target_platform.

◆ TEST() [11/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
ParseShaderBundleConfigFailsForInvalidJSON   
)

Definition at line 25 of file shader_bundle_unittests.cc.

25  {
26  std::string bundle = "";
27  std::stringstream error;
28  auto result = ParseShaderBundleConfig(bundle, error);
29  ASSERT_FALSE(result.has_value());
30  ASSERT_STREQ(error.str().c_str(),
31  "The shader bundle is not a valid JSON object.\n");
32 }
std::optional< ShaderBundleConfig > ParseShaderBundleConfig(const std::string &bundle_config_json, std::ostream &error_stream)
Parse a shader bundle configuration from a given JSON string.

References impeller::compiler::ParseShaderBundleConfig().

◆ TEST() [12/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
ParseShaderBundleConfigFailsForInvalidLanguage   
)

Definition at line 77 of file shader_bundle_unittests.cc.

77  {
78  std::string bundle =
79  "{\"UnlitVertex\": {\"type\": \"vertex\", \"language\": \"invalid\", "
80  "\"file\": \"shaders/flutter_gpu_unlit.vert\"}}";
81  std::stringstream error;
82  auto result = ParseShaderBundleConfig(bundle, error);
83  ASSERT_FALSE(result.has_value());
84  ASSERT_STREQ(error.str().c_str(),
85  "Invalid shader entry \"UnlitVertex\": Unknown language type "
86  "\"invalid\".\n");
87 }

References impeller::compiler::ParseShaderBundleConfig().

◆ TEST() [13/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
ParseShaderBundleConfigFailsForInvalidType   
)

Definition at line 65 of file shader_bundle_unittests.cc.

65  {
66  std::string bundle =
67  "{\"UnlitVertex\": {\"type\": \"invalid\", \"file\": "
68  "\"shaders/flutter_gpu_unlit.vert\"}}";
69  std::stringstream error;
70  auto result = ParseShaderBundleConfig(bundle, error);
71  ASSERT_FALSE(result.has_value());
72  ASSERT_STREQ(error.str().c_str(),
73  "Invalid shader entry \"UnlitVertex\": Shader type "
74  "\"invalid\" is unknown.\n");
75 }

References impeller::compiler::ParseShaderBundleConfig().

◆ TEST() [14/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
ParseShaderBundleConfigFailsWhenEntryNotObject   
)

Definition at line 34 of file shader_bundle_unittests.cc.

34  {
35  std::string bundle = "{\"UnlitVertex\": []}";
36  std::stringstream error;
37  auto result = ParseShaderBundleConfig(bundle, error);
38  ASSERT_FALSE(result.has_value());
39  ASSERT_STREQ(
40  error.str().c_str(),
41  "Invalid shader entry \"UnlitVertex\": Entry is not a JSON object.\n");
42 }

References impeller::compiler::ParseShaderBundleConfig().

◆ TEST() [15/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
ParseShaderBundleConfigFailsWhenMissingFile   
)

Definition at line 44 of file shader_bundle_unittests.cc.

44  {
45  std::string bundle = "{\"UnlitVertex\": {\"type\": \"vertex\"}}";
46  std::stringstream error;
47  auto result = ParseShaderBundleConfig(bundle, error);
48  ASSERT_FALSE(result.has_value());
49  ASSERT_STREQ(error.str().c_str(),
50  "Invalid shader entry \"UnlitVertex\": Missing required "
51  "\"file\" field.\n");
52 }

References impeller::compiler::ParseShaderBundleConfig().

◆ TEST() [16/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
ParseShaderBundleConfigFailsWhenMissingType   
)

Definition at line 54 of file shader_bundle_unittests.cc.

54  {
55  std::string bundle =
56  "{\"UnlitVertex\": {\"file\": \"shaders/flutter_gpu_unlit.vert\"}}";
57  std::stringstream error;
58  auto result = ParseShaderBundleConfig(bundle, error);
59  ASSERT_FALSE(result.has_value());
60  ASSERT_STREQ(error.str().c_str(),
61  "Invalid shader entry \"UnlitVertex\": Missing required "
62  "\"type\" field.\n");
63 }

References impeller::compiler::ParseShaderBundleConfig().

◆ TEST() [17/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
ParseShaderBundleConfigReturnsExpectedConfig   
)

Definition at line 89 of file shader_bundle_unittests.cc.

89  {
90  std::string bundle =
92  std::stringstream error;
93  auto result = ParseShaderBundleConfig(bundle, error);
94  ASSERT_TRUE(result.has_value());
95  ASSERT_STREQ(error.str().c_str(), "");
96 
97  // NOLINTBEGIN(bugprone-unchecked-optional-access)
98  auto maybe_vertex = result->find("UnlitVertex");
99  auto maybe_fragment = result->find("UnlitFragment");
100  ASSERT_TRUE(maybe_vertex != result->end());
101  ASSERT_TRUE(maybe_fragment != result->end());
102  auto vertex = maybe_vertex->second;
103  auto fragment = maybe_fragment->second;
104  // NOLINTEND(bugprone-unchecked-optional-access)
105 
106  EXPECT_EQ(vertex.type, SourceType::kVertexShader);
107  EXPECT_EQ(vertex.language, SourceLanguage::kGLSL);
108  EXPECT_STREQ(vertex.entry_point.c_str(), "main");
109  EXPECT_STREQ(vertex.source_file_name.c_str(),
110  "shaders/flutter_gpu_unlit.vert");
111 
112  EXPECT_EQ(fragment.type, SourceType::kFragmentShader);
113  EXPECT_EQ(fragment.language, SourceLanguage::kGLSL);
114  EXPECT_STREQ(fragment.entry_point.c_str(), "main");
115  EXPECT_STREQ(fragment.source_file_name.c_str(),
116  "shaders/flutter_gpu_unlit.frag");
117 }
const std::string kUnlitFragmentBundleConfig

References impeller::compiler::kFragmentShader, impeller::compiler::kGLSL, kUnlitFragmentBundleConfig, kUnlitVertexBundleConfig, impeller::compiler::kVertexShader, and impeller::compiler::ParseShaderBundleConfig().

◆ TEST() [18/27]

impeller::compiler::testing::TEST ( ShaderBundleTest  ,
TargetPlatformDefinesMatchEachBackend   
)

Definition at line 309 of file shader_bundle_unittests.cc.

309  {
310  EXPECT_EQ(GetShaderBundleTargetPlatformDefines(TargetPlatform::kMetalIOS),
311  (std::vector<std::string_view>{"IMPELLER_TARGET_METAL",
312  "IMPELLER_TARGET_METAL_IOS"}));
313  EXPECT_EQ(GetShaderBundleTargetPlatformDefines(TargetPlatform::kMetalDesktop),
314  (std::vector<std::string_view>{"IMPELLER_TARGET_METAL",
315  "IMPELLER_TARGET_METAL_DESKTOP"}));
316  EXPECT_EQ(GetShaderBundleTargetPlatformDefines(TargetPlatform::kOpenGLES),
317  (std::vector<std::string_view>{"IMPELLER_TARGET_OPENGLES"}));
318  EXPECT_EQ(
319  GetShaderBundleTargetPlatformDefines(TargetPlatform::kOpenGLDesktop),
320  (std::vector<std::string_view>{"IMPELLER_TARGET_OPENGL"}));
321  EXPECT_EQ(GetShaderBundleTargetPlatformDefines(TargetPlatform::kVulkan),
322  (std::vector<std::string_view>{"IMPELLER_TARGET_VULKAN"}));
323 
324  // Runtime stages and SkSL receive their defines elsewhere; the shader bundle
325  // adds none for them.
326  EXPECT_TRUE(
327  GetShaderBundleTargetPlatformDefines(TargetPlatform::kRuntimeStageVulkan)
328  .empty());
329  EXPECT_TRUE(
330  GetShaderBundleTargetPlatformDefines(TargetPlatform::kUnknown).empty());
331 }
std::vector< std::string_view > GetShaderBundleTargetPlatformDefines(TargetPlatform platform)
The platform-discriminating preprocessor defines injected when compiling a bundled shader for platfor...

References impeller::compiler::GetShaderBundleTargetPlatformDefines(), impeller::compiler::kMetalDesktop, impeller::compiler::kMetalIOS, impeller::compiler::kOpenGLDesktop, impeller::compiler::kOpenGLES, impeller::compiler::kRuntimeStageVulkan, impeller::compiler::kUnknown, and impeller::compiler::kVulkan.

◆ TEST() [19/27]

impeller::compiler::testing::TEST ( SwitchesTest  ,
CommandLinePathUtf8   
)

Definition at line 109 of file switches_unittests.cc.

109  {
110  std::u16string filename = u"test\u1234";
111  std::string input_flag = "--input=" + fml::Utf16ToUtf8(filename);
112  Switches switches = MakeSwitchesDesktopGL({input_flag.c_str()});
113  ASSERT_TRUE(switches.AreValid(std::cout));
114  ASSERT_EQ(switches.source_file_name, filename);
115 }
Switches MakeSwitchesDesktopGL(std::initializer_list< const char * > additional_options={})

References impeller::compiler::Switches::AreValid(), MakeSwitchesDesktopGL(), and impeller::compiler::Switches::source_file_name.

◆ TEST() [20/27]

impeller::compiler::testing::TEST ( SwitchesTEst  ,
ConvertToEntrypointName   
)

Definition at line 74 of file switches_unittests.cc.

74  {
75  ASSERT_EQ(ConvertToEntrypointName("mandelbrot_unrolled"),
76  "mandelbrot_unrolled");
77  ASSERT_EQ(ConvertToEntrypointName("mandelbrot-unrolled"),
78  "mandelbrotunrolled");
79  ASSERT_EQ(ConvertToEntrypointName("7_"), "i_7_");
80  ASSERT_EQ(ConvertToEntrypointName("415"), "i_415");
81  ASSERT_EQ(ConvertToEntrypointName("#$%"), "i_");
82  ASSERT_EQ(ConvertToEntrypointName(""), "");
83 }
std::string ConvertToEntrypointName(std::string_view string)
Ensure that the entrypoint name is a valid identifier in the target language.
Definition: utilities.cc:68

References impeller::compiler::ConvertToEntrypointName().

◆ TEST() [21/27]

impeller::compiler::testing::TEST ( SwitchesTest  ,
DefaultEntryPointIsMain   
)

Definition at line 62 of file switches_unittests.cc.

62  {
63  Switches switches = MakeSwitchesDesktopGL({});
64  ASSERT_TRUE(switches.AreValid(std::cout));
65  ASSERT_EQ(switches.entry_point, "main");
66 }

References impeller::compiler::Switches::AreValid(), impeller::compiler::Switches::entry_point, and MakeSwitchesDesktopGL().

◆ TEST() [22/27]

impeller::compiler::testing::TEST ( SwitchesTest  ,
DoesntMangleUnicodeIncludes   
)

Definition at line 33 of file switches_unittests.cc.

33  {
34  const char* directory_name = "test_shader_include_�";
35  fml::CreateDirectory(flutter::testing::OpenFixturesDirectory(),
36  {directory_name}, fml::FilePermission::kRead);
37 
38  auto include_path =
39  std::string(flutter::testing::GetFixturesPath()) + "/" + directory_name;
40  auto include_option = "--include=" + include_path;
41 
42  Switches switches = MakeSwitchesDesktopGL({include_option.c_str()});
43 
44  ASSERT_TRUE(switches.AreValid(std::cout));
45  ASSERT_EQ(switches.include_directories.size(), 1u);
46  ASSERT_NE(switches.include_directories[0].dir, nullptr);
47  ASSERT_EQ(switches.include_directories[0].name, include_path);
48 }

References impeller::compiler::Switches::AreValid(), impeller::compiler::Switches::include_directories, and MakeSwitchesDesktopGL().

◆ TEST() [23/27]

impeller::compiler::testing::TEST ( SwitchesTest  ,
EntryPointCanBeSetForHLSL   
)

Definition at line 68 of file switches_unittests.cc.

68  {
69  Switches switches = MakeSwitchesDesktopGL({"--entry-point=CustomEntryPoint"});
70  ASSERT_TRUE(switches.AreValid(std::cout));
71  ASSERT_EQ(switches.entry_point, "CustomEntryPoint");
72 }

References impeller::compiler::Switches::AreValid(), impeller::compiler::Switches::entry_point, and MakeSwitchesDesktopGL().

◆ TEST() [24/27]

impeller::compiler::testing::TEST ( SwitchesTest  ,
EntryPointPrefixIsApplied   
)

Definition at line 98 of file switches_unittests.cc.

98  {
99  Switches switches =
100  MakeSwitchesDesktopGL({"--entry-point-prefix=my_prefix_"});
101  ASSERT_TRUE(switches.AreValid(std::cout));
102  EXPECT_EQ(switches.entry_point_prefix, "my_prefix_");
103 
104  switches.source_file_name = "test.frag";
105  auto options = switches.CreateSourceOptions();
106  EXPECT_EQ(options.entry_point_name, "my_prefix_test_fragment_main");
107 }

References impeller::compiler::Switches::AreValid(), impeller::compiler::Switches::CreateSourceOptions(), impeller::compiler::Switches::entry_point_prefix, MakeSwitchesDesktopGL(), and impeller::compiler::Switches::source_file_name.

◆ TEST() [25/27]

impeller::compiler::testing::TEST ( SwitchesTest  ,
ShaderBundleModeValid   
)

Definition at line 85 of file switches_unittests.cc.

85  {
86  // Shader bundles process multiple shaders, and so the single-file input/spirv
87  // flags are not required.
88  std::vector<const char*> options = {
89  "--shader-bundle={}", "--sl=test.shaderbundle", "--runtime-stage-metal"};
90 
91  auto cl = fml::CommandLineFromIteratorsWithArgv0("impellerc", options.begin(),
92  options.end());
93  Switches switches(cl);
94  ASSERT_TRUE(switches.AreValid(std::cout));
95  ASSERT_EQ(switches.shader_bundle, "{}");
96 }

References impeller::compiler::Switches::AreValid(), and impeller::compiler::Switches::shader_bundle.

◆ TEST() [26/27]

impeller::compiler::testing::TEST ( SwitchesTest  ,
SourceLanguageCanBeSetToHLSL   
)

Definition at line 56 of file switches_unittests.cc.

56  {
57  Switches switches = MakeSwitchesDesktopGL({"--source-language=hLsL"});
58  ASSERT_TRUE(switches.AreValid(std::cout));
59  ASSERT_EQ(switches.source_language, SourceLanguage::kHLSL);
60 }

References impeller::compiler::Switches::AreValid(), impeller::compiler::kHLSL, MakeSwitchesDesktopGL(), and impeller::compiler::Switches::source_language.

◆ TEST() [27/27]

impeller::compiler::testing::TEST ( SwitchesTest  ,
SourceLanguageDefaultsToGLSL   
)

Definition at line 50 of file switches_unittests.cc.

50  {
51  Switches switches = MakeSwitchesDesktopGL();
52  ASSERT_TRUE(switches.AreValid(std::cout));
53  ASSERT_EQ(switches.source_language, SourceLanguage::kGLSL);
54 }

References impeller::compiler::Switches::AreValid(), impeller::compiler::kGLSL, MakeSwitchesDesktopGL(), and impeller::compiler::Switches::source_language.

◆ TEST_P() [1/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
BindingBaseForFragShader   
)

Definition at line 285 of file compiler_unittests.cc.

285  {
286  if (!TargetPlatformIsVulkan(GetParam())) {
287  GTEST_SKIP();
288  }
289 
290  ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
291  ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
292 
293  auto get_binding = [&](const char* fixture) -> uint32_t {
294  auto json_fd = GetReflectionJson(fixture);
295  nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
296  return shader_json["buffers"][0]["binding"].get<uint32_t>();
297  };
298 
299  auto vert_uniform_binding = get_binding("sample.vert");
300  auto frag_uniform_binding = get_binding("sample.frag");
301 
302  ASSERT_GT(frag_uniform_binding, vert_uniform_binding);
303 }
bool TargetPlatformIsVulkan(TargetPlatform platform)
Definition: types.cc:277

References impeller::compiler::kFragmentShader, impeller::compiler::kVertexShader, and impeller::compiler::TargetPlatformIsVulkan().

◆ TEST_P() [2/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
CanCompile   
)

Definition at line 231 of file compiler_unittests.cc.

231  {
232  ASSERT_TRUE(CanCompileAndReflect("sample.vert"));
233  ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
234  ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader,
235  SourceLanguage::kGLSL));
236 }

References impeller::compiler::kGLSL, and impeller::compiler::kVertexShader.

◆ TEST_P() [3/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
CanCompileComputeShader   
)

Definition at line 252 of file compiler_unittests.cc.

252  {
253  ASSERT_TRUE(CanCompileAndReflect("sample.comp", SourceType::kComputeShader,
254  SourceLanguage::kGLSL, "main"));
255 }

References impeller::compiler::kComputeShader, and impeller::compiler::kGLSL.

◆ TEST_P() [4/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
CanCompileHLSL   
)

Definition at line 238 of file compiler_unittests.cc.

238  {
239  ASSERT_TRUE(CanCompileAndReflect(
240  "simple.vert.hlsl", SourceType::kVertexShader, SourceLanguage::kHLSL));
241 }

References impeller::compiler::kHLSL, and impeller::compiler::kVertexShader.

◆ TEST_P() [5/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
CanCompileHLSLWithMultipleStages   
)

Definition at line 243 of file compiler_unittests.cc.

243  {
244  ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
245  SourceType::kVertexShader,
246  SourceLanguage::kHLSL, "VertexShader"));
247  ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
248  SourceType::kFragmentShader,
249  SourceLanguage::kHLSL, "FragmentShader"));
250 }

References impeller::compiler::kFragmentShader, impeller::compiler::kHLSL, and impeller::compiler::kVertexShader.

◆ TEST_P() [6/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
MustFailDueToExceedingResourcesLimit   
)

Definition at line 257 of file compiler_unittests.cc.

257  {
258  ScopedValidationDisable disable_validation;
259  ASSERT_FALSE(
260  CanCompileAndReflect("resources_limit.vert", SourceType::kVertexShader));
261 }

References impeller::compiler::kVertexShader.

◆ TEST_P() [7/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
MustFailDueToMultipleLocationPerStructMember   
)

Definition at line 263 of file compiler_unittests.cc.

263  {
264  ScopedValidationDisable disable_validation;
265  ASSERT_FALSE(CanCompileAndReflect("struct_def_bug.vert"));
266 }

◆ TEST_P() [8/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
UniformBlockInstanceNameCanonicalizedForGL   
)

Definition at line 268 of file compiler_unittests.cc.

268  {
269  if (!TargetPlatformIsOpenGL(GetParam())) {
270  GTEST_SKIP() << "Only GL targets lower uniform blocks to flat structs.";
271  }
272  // `mat2_test.frag` has `uniform Params { ... } uParams;`. Without
273  // canonicalization, BufferBindingsGLES cannot resolve `uParams.uMat2`.
274  ASSERT_TRUE(
275  CanCompileAndReflect("mat2_test.frag", SourceType::kFragmentShader));
276  auto sl_source = GetCompiler()->GetSLShaderSource();
277  ASSERT_NE(sl_source, nullptr);
278  const std::string source(
279  reinterpret_cast<const char*>(sl_source->GetMapping()),
280  sl_source->GetSize());
281  EXPECT_EQ(source.find("uParams."), std::string::npos) << source;
282  EXPECT_NE(source.find("_Params."), std::string::npos) << source;
283 }
bool TargetPlatformIsOpenGL(TargetPlatform platform)
Definition: types.cc:239

References impeller::compiler::kFragmentShader, and impeller::compiler::TargetPlatformIsOpenGL().

◆ TEST_P() [9/19]

impeller::compiler::testing::TEST_P ( CompilerTest  ,
UniformsHaveBindingAndSet   
)

Definition at line 489 of file compiler_unittests.cc.

489  {
490  if (GetParam() == TargetPlatform::kSkSL) {
491  GTEST_SKIP() << "Not supported with SkSL";
492  }
493  ASSERT_TRUE(CanCompileAndReflect("sample_with_binding.vert",
494  SourceType::kVertexShader));
495  ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
496 
497  struct binding_and_set {
498  uint32_t binding;
499  uint32_t set;
500  };
501 
502  auto get_binding = [&](const char* fixture) -> binding_and_set {
503  auto json_fd = GetReflectionJson(fixture);
504  nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
505  uint32_t binding = shader_json["buffers"][0]["binding"].get<uint32_t>();
506  uint32_t set = shader_json["buffers"][0]["set"].get<uint32_t>();
507  return {binding, set};
508  };
509 
510  auto vert_uniform_binding = get_binding("sample_with_binding.vert");
511  auto frag_uniform_binding = get_binding("sample.frag");
512 
513  ASSERT_EQ(frag_uniform_binding.set, 0u);
514  ASSERT_EQ(vert_uniform_binding.set, 3u);
515  ASSERT_EQ(vert_uniform_binding.binding, 17u);
516 }

References impeller::compiler::kFragmentShader, impeller::compiler::kSkSL, and impeller::compiler::kVertexShader.

◆ TEST_P() [10/19]

impeller::compiler::testing::TEST_P ( CompilerTestRuntime  ,
Mat2Reflection   
)

Definition at line 625 of file compiler_unittests.cc.

625  {
626  if (GetParam() == TargetPlatform::kSkSL) {
627  GTEST_SKIP() << "Not supported with SkSL";
628  }
629 
630  ASSERT_TRUE(CanCompileAndReflect(
631  "mat2_test.frag", SourceType::kFragmentShader, SourceLanguage::kGLSL));
632 
633  std::unique_ptr<fml::FileMapping> json_fd =
634  GetReflectionJson("mat2_test.frag");
635  ASSERT_TRUE(json_fd);
636  nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
637  nlohmann::json::value_type buffers = shader_json["buffers"];
638 
639  // uParams should be in buffers.
640  ASSERT_GE(buffers.size(), 1u);
641  nlohmann::json::value_type uParams = buffers[0];
642  EXPECT_EQ(uParams["name"], "Params");
643 
644  nlohmann::json::value_type members = uParams["type"]["members"];
645  // We expect 1 member (for the mat2) which is a Point (vec2) with array
646  // size 2.
647  ASSERT_EQ(members.size(), 1u);
648 
649  nlohmann::json::value_type mat2Member = members[0];
650 
651  // Should be Mat2 (vec2)
652  EXPECT_EQ(mat2Member["type"], "Mat2");
653 
654  // Size 8 bytes (vec2)
655  EXPECT_EQ(mat2Member["size"], 8u);
656 
657  // Byte length should be total array size (stride * count)
658  // Stride 16 * 2 = 32.
659  EXPECT_EQ(mat2Member["byte_length"], 32u);
660 
661  // Array elements should be 2 (columns).
662  EXPECT_EQ(mat2Member["array_elements"], 2u);
663 
664  // Offset 0
665  EXPECT_EQ(mat2Member["offset"], 0u);
666 }

References impeller::compiler::kFragmentShader, impeller::compiler::kGLSL, and impeller::compiler::kSkSL.

◆ TEST_P() [11/19]

impeller::compiler::testing::TEST_P ( CompilerTestRuntime  ,
PositionedUniformsAppearInJson   
)

Definition at line 435 of file compiler_unittests.cc.

435  {
436  if (GetParam() == TargetPlatform::kRuntimeStageVulkan) {
437  // TODO(https://github.com/flutter/flutter/issues/182578): Investigate why
438  // this does not pass.
439  GTEST_SKIP() << "Not supported with Vulkan";
440  }
441 
442  ASSERT_TRUE(CanCompileAndReflect("sample_with_positioned_uniforms.frag",
443  SourceType::kFragmentShader,
444  SourceLanguage::kGLSL));
445 
446  auto json_fd = GetReflectionJson("sample_with_positioned_uniforms.frag");
447  ASSERT_TRUE(json_fd);
448  nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
449  auto sampler_list = shader_json["sampled_images"];
450  auto float_list = shader_json["uniforms"];
451  ASSERT_EQ(sampler_list.size(), 3u);
452  ASSERT_EQ(float_list.size(), 7u);
453 
454  {
455  // clang-format off
456  std::array expected_infos = {
457  UniformInfo::Sampler("uSamplerNotPositioned1", 1u),
458  UniformInfo::Sampler("uSampler", 0u),
459  UniformInfo::Sampler("uSamplerNotPositioned2", 3u),
460  };
461  // clang-format on
462  ASSERT_EQ(sampler_list.size(), expected_infos.size());
463  for (size_t i = 0; i < expected_infos.size(); i++) {
464  EXPECT_EQ(UniformInfo::fromJson(sampler_list[i]), expected_infos[i])
465  << "index: " << i;
466  }
467  }
468 
469  {
470  // clang-format off
471  std::array expected_infos = {
472  UniformInfo::Float("uFloatNotPositioned1", 0u),
473  UniformInfo::Float("uFloat", 6u),
474  UniformInfo::Vec2("uVec2", 5u),
475  UniformInfo::Vec3("uVec3", 3u),
476  UniformInfo::Vec4("uVec4", 2u),
477  UniformInfo::Mat4("uMat4", 1u),
478  UniformInfo::Float("uFloatNotPositioned2", 2u),
479  };
480  // clang-format on
481  ASSERT_EQ(float_list.size(), expected_infos.size());
482  for (size_t i = 0; i < expected_infos.size(); i++) {
483  EXPECT_EQ(UniformInfo::fromJson(float_list[i]), expected_infos[i])
484  << "index: " << i;
485  }
486  }
487 }

References impeller::compiler::kFragmentShader, impeller::compiler::kGLSL, and impeller::compiler::kRuntimeStageVulkan.

◆ TEST_P() [12/19]

impeller::compiler::testing::TEST_P ( CompilerTestRuntime  ,
UniformsAppearInJson   
)

Definition at line 383 of file compiler_unittests.cc.

383  {
384  if (GetParam() == TargetPlatform::kRuntimeStageVulkan) {
385  // TODO(https://github.com/flutter/flutter/issues/182578): Investigate why
386  // this does not pass.
387  GTEST_SKIP() << "Not supported with Vulkan";
388  }
389 
390  ASSERT_TRUE(CanCompileAndReflect("sample_with_uniforms.frag",
391  SourceType::kFragmentShader,
392  SourceLanguage::kGLSL));
393 
394  auto json_fd = GetReflectionJson("sample_with_uniforms.frag");
395  ASSERT_TRUE(json_fd);
396  nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
397  auto sampler_list = shader_json["sampled_images"];
398  auto float_list = shader_json["uniforms"];
399  ASSERT_EQ(sampler_list.size(), 2u);
400  ASSERT_EQ(float_list.size(), 6u);
401 
402  {
403  // clang-format off
404  std::array expected_infos = {
405  UniformInfo::Sampler("uFirstSampler", 1u),
406  UniformInfo::Sampler("uSampler", 7u),
407  };
408  // clang-format on
409  ASSERT_EQ(sampler_list.size(), expected_infos.size());
410  for (size_t i = 0; i < expected_infos.size(); i++) {
411  EXPECT_EQ(UniformInfo::fromJson(sampler_list[i]), expected_infos[i])
412  << "index: " << i;
413  }
414  }
415 
416  {
417  // clang-format off
418  std::array expected_infos = {
419  UniformInfo::Float("uFirstFloat", 0u),
420  UniformInfo::Float("uFloat", 2u),
421  UniformInfo::Vec2("uVec2", 3u),
422  UniformInfo::Vec3("uVec3", 4u),
423  UniformInfo::Vec4("uVec4", 5u),
424  UniformInfo::Mat4("uMat4", 6u),
425  };
426  // clang-format on
427  ASSERT_EQ(float_list.size(), expected_infos.size());
428  for (size_t i = 0; i < expected_infos.size(); i++) {
429  EXPECT_EQ(UniformInfo::fromJson(float_list[i]), expected_infos[i])
430  << "index: " << i;
431  }
432  }
433 }

References impeller::compiler::kFragmentShader, impeller::compiler::kGLSL, and impeller::compiler::kRuntimeStageVulkan.

◆ TEST_P() [13/19]

impeller::compiler::testing::TEST_P ( CompilerTestSkSL  ,
CanCompileStructs   
)

Definition at line 532 of file compiler_unittests.cc.

532  {
533  ASSERT_TRUE(CanCompileAndReflect("struct_internal.frag",
534  SourceType::kFragmentShader));
535 }

References impeller::compiler::kFragmentShader.

◆ TEST_P() [14/19]

impeller::compiler::testing::TEST_P ( CompilerTestSkSL  ,
CompilesWithValidArrayInitialization   
)

Definition at line 619 of file compiler_unittests.cc.

619  {
620  ASSERT_TRUE(
621  CanCompileAndReflect("array_initialization_without_initializer.frag",
622  SourceType::kFragmentShader));
623 }

References impeller::compiler::kFragmentShader.

◆ TEST_P() [15/19]

impeller::compiler::testing::TEST_P ( CompilerTestSkSL  ,
FailsToCompileDueToArrayAssignment   
)

Definition at line 557 of file compiler_unittests.cc.

557  {
558  // Does not EXIT because the backend SkSL compiler doesn't detect the invalid
559  // SkSL. Returns false because the Impeller Compiler's post-compile validation
560  // fails.
561  ASSERT_FALSE(CanCompileAndReflect("array_assignment.frag",
562  SourceType::kFragmentShader));
563 
564  const Compiler* compiler = GetCompiler();
565  ASSERT_TRUE(compiler);
566  // Truncated error message.
567  ASSERT_STREQ(
568  compiler->GetErrorMessages().c_str(),
569  "\"array_assignment.frag\": \n"
570  "Compiled to invalid SkSL:\n"
571  " // This SkSL shader is autogenerated by spirv-cross.\n"
572  " \n"
573  " float4 flutter_FragCoord;\n"
574  " \n"
575  " vec4 frag_color;\n"
576  " \n"
577  "... (truncated 16 lines)\n"
578  "SkSL Error:\n"
579  " error: 12: initializers are not permitted on arrays (or structs "
580  "containing arrays)\n"
581  " float more_nums[2] = nums;\n"
582  " ^^^^\n"
583  " 1 error\n");
584  // Full error message.
585  ASSERT_STREQ(compiler->GetVerboseErrorMessages().c_str(),
586  "\"array_assignment.frag\": \n"
587  "Compiled to invalid SkSL:\n"
588  "// This SkSL shader is autogenerated by spirv-cross.\n"
589  "\n"
590  "float4 flutter_FragCoord;\n"
591  "\n"
592  "vec4 frag_color;\n"
593  "\n"
594  "void FLT_main()\n"
595  "{\n"
596  " float nums[2];\n"
597  " nums[0] = 1.0;\n"
598  " nums[1] = 0.5;\n"
599  " float more_nums[2] = nums;\n"
600  " frag_color = vec4(nums[0], nums[1], 1.0, 1.0);\n"
601  "}\n"
602  "\n"
603  "half4 main(float2 iFragCoord)\n"
604  "{\n"
605  " flutter_FragCoord = float4(iFragCoord, 0, 0);\n"
606  " FLT_main();\n"
607  " return frag_color;\n"
608  "}\n"
609  "\n"
610  "SkSL Error:\n"
611  "error: 12: initializers are not permitted on arrays (or "
612  "structs containing arrays)\n"
613  " float more_nums[2] = nums;\n"
614  " ^^^^\n"
615  "1 error\n"
616  "\n");
617 }

References impeller::compiler::Compiler::GetErrorMessages(), impeller::compiler::Compiler::GetVerboseErrorMessages(), and impeller::compiler::kFragmentShader.

◆ TEST_P() [16/19]

impeller::compiler::testing::TEST_P ( CompilerTestSkSL  ,
FailsToCompileDueToArrayInitializerWithConstants   
)

Definition at line 537 of file compiler_unittests.cc.

537  {
538  auto expected_err =
539  "There was a compiler error: SkSL does not support array initializers: "
540  "array_initializer_with_constants.frag:6";
541 
542  EXPECT_EXIT(CanCompileAndReflect("array_initializer_with_constants.frag",
543  SourceType::kFragmentShader),
544  ::testing::ExitedWithCode(1), expected_err);
545 }

References impeller::compiler::kFragmentShader.

◆ TEST_P() [17/19]

impeller::compiler::testing::TEST_P ( CompilerTestSkSL  ,
FailsToCompileDueToArrayInitializerWithVariables   
)

Definition at line 547 of file compiler_unittests.cc.

547  {
548  auto expected_err =
549  "There was a compiler error: SkSL does not support array initializers: "
550  "array_initializer_with_variables.frag:12";
551 
552  EXPECT_EXIT(CanCompileAndReflect("array_initializer_with_variables.frag",
553  SourceType::kFragmentShader),
554  ::testing::ExitedWithCode(1), expected_err);
555 }

References impeller::compiler::kFragmentShader.

◆ TEST_P() [18/19]

impeller::compiler::testing::TEST_P ( CompilerTestSkSL  ,
SkSLTextureLookUpOrderOfOperations   
)

Definition at line 518 of file compiler_unittests.cc.

518  {
519  ASSERT_TRUE(
520  CanCompileAndReflect("texture_lookup.frag", SourceType::kFragmentShader));
521 
522  auto shader = GetShaderFile("texture_lookup.frag", GetParam());
523  std::string_view shader_mapping(
524  reinterpret_cast<const char*>(shader->GetMapping()), shader->GetSize());
525 
526  constexpr std::string_view expected =
527  "textureA.eval(textureA_size * ( vec2(1.0) + flutter_FragCoord.xy));";
528 
529  EXPECT_NE(shader_mapping.find(expected), std::string::npos);
530 }

References impeller::compiler::kFragmentShader.

◆ TEST_P() [19/19]

impeller::compiler::testing::TEST_P ( CompilerTestUnknownPlatform  ,
MustFailDueToUnknownPlatform   
)

Definition at line 668 of file compiler_unittests.cc.

668  {
669  ASSERT_FALSE(
670  CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
671 }

References impeller::compiler::kFragmentShader.

Variable Documentation

◆ kUnlitFragmentBundleConfig

const std::string impeller::compiler::testing::kUnlitFragmentBundleConfig
Initial value:
=
"\"UnlitFragment\": {\"type\": \"fragment\", \"file\": "
"\"shaders/flutter_gpu_unlit.frag\"}"

Definition at line 18 of file shader_bundle_unittests.cc.

Referenced by TEST().

◆ kUnlitVertexBundleConfig

const std::string impeller::compiler::testing::kUnlitVertexBundleConfig
Initial value:
=
"\"UnlitVertex\": {\"type\": \"vertex\", \"file\": "
"\"shaders/flutter_gpu_unlit.vert\"}"

Definition at line 21 of file shader_bundle_unittests.cc.

Referenced by TEST().