diff --git a/impeller/compiler/compiler.cc b/impeller/compiler/compiler.cc index 7ae15aab5806d..8e1150d4cf376 100644 --- a/impeller/compiler/compiler.cc +++ b/impeller/compiler/compiler.cc @@ -206,6 +206,7 @@ CompilerTargetPlatformToCompilerMSLTargetPlatform( return spirv_cross::CompilerMSL::Options::Platform::iOS; case Compiler::TargetPlatform::kMacOS: // Unknown should not happen due to prior validation. + case Compiler::TargetPlatform::kFlutterSPIRV: case Compiler::TargetPlatform::kUnknown: return spirv_cross::CompilerMSL::Options::Platform::macOS; } @@ -239,18 +240,29 @@ Compiler::Compiler(const fml::Mapping& source_mapping, // will be processed later by backend specific compilers. So optimizations // here are irrelevant and get in the way of generating reflection code. options.SetGenerateDebugInfo(); - options.SetOptimizationLevel( - shaderc_optimization_level::shaderc_optimization_level_zero); // Expects GLSL 4.60 (Core Profile). // https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf options.SetSourceLanguage( shaderc_source_language::shaderc_source_language_glsl); options.SetForcedVersionProfile(460, shaderc_profile::shaderc_profile_core); - options.SetTargetEnvironment( - shaderc_target_env::shaderc_target_env_vulkan, - shaderc_env_version::shaderc_env_version_vulkan_1_1); - options.SetTargetSpirv(shaderc_spirv_version::shaderc_spirv_version_1_3); + if (source_options.target_platform == TargetPlatform::kFlutterSPIRV) { + options.SetOptimizationLevel( + shaderc_optimization_level::shaderc_optimization_level_size); + options.SetTargetEnvironment( + shaderc_target_env::shaderc_target_env_opengl, + shaderc_env_version::shaderc_env_version_opengl_4_5 + ); + options.SetTargetSpirv(shaderc_spirv_version::shaderc_spirv_version_1_0); + } else { + options.SetOptimizationLevel( + shaderc_optimization_level::shaderc_optimization_level_zero); + options.SetTargetEnvironment( + shaderc_target_env::shaderc_target_env_vulkan, + shaderc_env_version::shaderc_env_version_vulkan_1_1 + ); + options.SetTargetSpirv(shaderc_spirv_version::shaderc_spirv_version_1_3); + } options.SetAutoBindUniforms(true); options.SetAutoMapLocations(true); @@ -295,6 +307,11 @@ Compiler::Compiler(const fml::Mapping& source_mapping, included_file_names_ = std::move(included_file_names); } + if (!TargetPlatformNeedsMSL(source_options.target_platform)) { + is_valid_ = true; + return; + } + // MSL Generation. spirv_cross::Parser parser(spv_result_->cbegin(), spv_result_->cend() - spv_result_->cbegin()); @@ -418,6 +435,26 @@ std::string Compiler::EntryPointFromSourceName(const std::string& file_name, return stream.str(); } +bool Compiler::TargetPlatformNeedsMSL(TargetPlatform platform) { + switch (platform) { + case TargetPlatform::kIPhoneOS: + case TargetPlatform::kMacOS: + return true; + default: + return false; + } +} + +bool Compiler::TargetPlatformNeedsReflection(TargetPlatform platform) { + switch (platform) { + case TargetPlatform::kIPhoneOS: + case TargetPlatform::kMacOS: + return true; + default: + return false; + } +} + std::string Compiler::GetSourcePrefix() const { std::stringstream stream; stream << options_.file_name << ": "; diff --git a/impeller/compiler/compiler.h b/impeller/compiler/compiler.h index 9310bdc9bcf93..6acbde58e618d 100644 --- a/impeller/compiler/compiler.h +++ b/impeller/compiler/compiler.h @@ -31,6 +31,7 @@ class Compiler { kUnknown, kMacOS, kIPhoneOS, + kFlutterSPIRV, }; static SourceType SourceTypeFromFileName(const std::string& file_name); @@ -38,6 +39,10 @@ class Compiler { static std::string EntryPointFromSourceName(const std::string& file_name, SourceType type); + static bool TargetPlatformNeedsMSL(TargetPlatform platform); + + static bool TargetPlatformNeedsReflection(TargetPlatform platform); + struct SourceOptions { SourceType type = SourceType::kUnknown; TargetPlatform target_platform = TargetPlatform::kUnknown; diff --git a/impeller/compiler/compiler_unittests.cc b/impeller/compiler/compiler_unittests.cc index eca4561887772..3ca5da7ca8613 100644 --- a/impeller/compiler/compiler_unittests.cc +++ b/impeller/compiler/compiler_unittests.cc @@ -23,14 +23,15 @@ class CompilerTest : public ::testing::Test { ~CompilerTest() = default; - bool CanCompileFixture(const char* fixture_name) const { + bool CanCompileFixture(const char* fixture_name, + Compiler::TargetPlatform target_platform) const { auto fixture = flutter::testing::OpenFixtureAsMapping(fixture_name); if (!fixture->GetMapping()) { VALIDATION_LOG << "Could not find shader in fixtures: " << fixture_name; return false; } Compiler::SourceOptions compiler_options(fixture_name); - compiler_options.target_platform = Compiler::TargetPlatform::kMacOS; + compiler_options.target_platform = target_platform; compiler_options.working_directory = std::make_shared( flutter::testing::OpenFixturesDirectory()); Reflector::Options reflector_options; @@ -60,7 +61,13 @@ TEST_F(CompilerTest, ShaderKindMatchingIsSuccessful) { } TEST_F(CompilerTest, CanCompileSample) { - ASSERT_TRUE(CanCompileFixture("sample.vert")); + ASSERT_TRUE(CanCompileFixture( + "sample.vert", Compiler::TargetPlatform::kMacOS)); +} + +TEST_F(CompilerTest, CanTargetFlutterSPIRV) { + ASSERT_TRUE(CanCompileFixture( + "test_texture.frag", Compiler::TargetPlatform::kFlutterSPIRV)); } } // namespace testing diff --git a/impeller/compiler/impellerc_main.cc b/impeller/compiler/impellerc_main.cc index 8dd49a9a25951..bb25d8daa59e3 100644 --- a/impeller/compiler/impellerc_main.cc +++ b/impeller/compiler/impellerc_main.cc @@ -69,49 +69,65 @@ bool Main(const fml::CommandLine& command_line) { return false; } - if (!fml::WriteAtomically(*switches.working_directory, - switches.metal_file_name.c_str(), - *compiler.GetMSLShaderSource())) { - std::cerr << "Could not write file to " << switches.spirv_file_name - << std::endl; - return false; - } - - if (!switches.reflection_json_name.empty()) { + if (Compiler::TargetPlatformNeedsMSL(options.target_platform)) { if (!fml::WriteAtomically(*switches.working_directory, - switches.reflection_json_name.c_str(), - *compiler.GetReflector()->GetReflectionJSON())) { - std::cerr << "Could not write reflection json to " - << switches.reflection_json_name << std::endl; + switches.metal_file_name.c_str(), + *compiler.GetMSLShaderSource())) { + std::cerr << "Could not write file to " << switches.spirv_file_name + << std::endl; return false; } } - if (!switches.reflection_header_name.empty()) { - if (!fml::WriteAtomically( - *switches.working_directory, - switches.reflection_header_name.c_str(), - *compiler.GetReflector()->GetReflectionHeader())) { - std::cerr << "Could not write reflection header to " - << switches.reflection_header_name << std::endl; - return false; + + if (Compiler::TargetPlatformNeedsReflection(options.target_platform)) { + if (!switches.reflection_json_name.empty()) { + if (!fml::WriteAtomically(*switches.working_directory, + switches.reflection_json_name.c_str(), + *compiler.GetReflector()->GetReflectionJSON())) { + std::cerr << "Could not write reflection json to " + << switches.reflection_json_name << std::endl; + return false; + } } - } - if (!switches.reflection_cc_name.empty()) { - if (!fml::WriteAtomically(*switches.working_directory, - switches.reflection_cc_name.c_str(), - *compiler.GetReflector()->GetReflectionCC())) { - std::cerr << "Could not write reflection CC to " - << switches.reflection_cc_name << std::endl; - return false; + if (!switches.reflection_header_name.empty()) { + if (!fml::WriteAtomically( + *switches.working_directory, + switches.reflection_header_name.c_str(), + *compiler.GetReflector()->GetReflectionHeader())) { + std::cerr << "Could not write reflection header to " + << switches.reflection_header_name << std::endl; + return false; + } + } + + if (!switches.reflection_cc_name.empty()) { + if (!fml::WriteAtomically(*switches.working_directory, + switches.reflection_cc_name.c_str(), + *compiler.GetReflector()->GetReflectionCC())) { + std::cerr << "Could not write reflection CC to " + << switches.reflection_cc_name << std::endl; + return false; + } } } if (!switches.depfile_path.empty()) { + std::string result_file; + switch (switches.target_platform) { + case Compiler::TargetPlatform::kMacOS: + case Compiler::TargetPlatform::kIPhoneOS: + result_file = switches.metal_file_name; + break; + case Compiler::TargetPlatform::kFlutterSPIRV: + case Compiler::TargetPlatform::kUnknown: + result_file = switches.spirv_file_name; + break; + } if (!fml::WriteAtomically( *switches.working_directory, switches.depfile_path.c_str(), - *compiler.CreateDepfileContents({switches.metal_file_name}))) { + *compiler.CreateDepfileContents({result_file}))) { std::cerr << "Could not write depfile to " << switches.depfile_path << std::endl; return false; diff --git a/impeller/compiler/switches.cc b/impeller/compiler/switches.cc index 5ab2bf7453cdb..ef55ae07522e3 100644 --- a/impeller/compiler/switches.cc +++ b/impeller/compiler/switches.cc @@ -15,6 +15,7 @@ namespace compiler { static const std::map kKnownPlatforms = { {"macos", Compiler::TargetPlatform::kMacOS}, {"ios", Compiler::TargetPlatform::kIPhoneOS}, + {"flutter-spirv", Compiler::TargetPlatform::kFlutterSPIRV}, }; void Switches::PrintHelp(std::ostream& stream) { @@ -112,7 +113,7 @@ bool Switches::AreValid(std::ostream& explain) const { valid = false; } - if (metal_file_name.empty()) { + if (metal_file_name.empty() && Compiler::TargetPlatformNeedsMSL(target_platform)) { explain << "Metal file name was empty." << std::endl; valid = false; } diff --git a/impeller/fixtures/BUILD.gn b/impeller/fixtures/BUILD.gn index 07bbc65499781..64bf53e9e5b54 100644 --- a/impeller/fixtures/BUILD.gn +++ b/impeller/fixtures/BUILD.gn @@ -21,13 +21,14 @@ impeller_shaders("shader_fixtures") { test_fixtures("file_fixtures") { fixtures = [ - "sample.vert", - "types.h", "airplane.jpg", "bay_bridge.jpg", "boston.jpg", "embarcadero.jpg", "kalimba.jpg", + "sample.vert", + "types.h", + "test_texture.frag", "//flutter/third_party/txt/third_party/fonts/Roboto-Regular.ttf", "//flutter/third_party/txt/third_party/fonts/NotoColorEmoji.ttf", "//flutter/third_party/txt/third_party/fonts/HomemadeApple.ttf",