diff --git a/impeller/compiler/compiler.cc b/impeller/compiler/compiler.cc index 373b5ee8f1cb6..72cc10fa91ea1 100644 --- a/impeller/compiler/compiler.cc +++ b/impeller/compiler/compiler.cc @@ -366,6 +366,22 @@ Compiler::Compiler(const fml::Mapping& source_mapping, switch (source_options.target_platform) { case TargetPlatform::kMetalDesktop: case TargetPlatform::kMetalIOS: + spirv_options.SetOptimizationLevel( + shaderc_optimization_level::shaderc_optimization_level_performance); + if (source_options.use_half_textures) { + spirv_options.SetTargetEnvironment( + shaderc_target_env::shaderc_target_env_opengl, + shaderc_env_version::shaderc_env_version_opengl_4_5); + spirv_options.SetTargetSpirv( + shaderc_spirv_version::shaderc_spirv_version_1_0); + } else { + spirv_options.SetTargetEnvironment( + shaderc_target_env::shaderc_target_env_vulkan, + shaderc_env_version::shaderc_env_version_vulkan_1_1); + spirv_options.SetTargetSpirv( + shaderc_spirv_version::shaderc_spirv_version_1_3); + } + break; case TargetPlatform::kOpenGLES: case TargetPlatform::kOpenGLDesktop: spirv_options.SetOptimizationLevel( diff --git a/impeller/compiler/impellerc_main.cc b/impeller/compiler/impellerc_main.cc index dc334ef1132ec..74eb3a501bbbf 100644 --- a/impeller/compiler/impellerc_main.cc +++ b/impeller/compiler/impellerc_main.cc @@ -75,6 +75,7 @@ bool Main(const fml::CommandLine& command_line) { options.json_format = switches.json_format; options.gles_language_version = switches.gles_language_version; options.metal_version = switches.metal_version; + options.use_half_textures = switches.use_half_textures; Reflector::Options reflector_options; reflector_options.target_platform = switches.target_platform; diff --git a/impeller/compiler/source_options.h b/impeller/compiler/source_options.h index c10e97f1f178b..797cb70a026f1 100644 --- a/impeller/compiler/source_options.h +++ b/impeller/compiler/source_options.h @@ -29,6 +29,10 @@ struct SourceOptions { bool json_format = false; std::string metal_version; + /// @brief Whether half-precision textures should be supported, requiring + /// opengl semantics. Only used on metal targets. + bool use_half_textures = false; + SourceOptions(); ~SourceOptions(); diff --git a/impeller/compiler/switches.cc b/impeller/compiler/switches.cc index 69f081c25fe1f..ab365a0711705 100644 --- a/impeller/compiler/switches.cc +++ b/impeller/compiler/switches.cc @@ -72,8 +72,8 @@ void Switches::PrintHelp(std::ostream& stream) { stream << "[optional] --depfile=" << std::endl; stream << "[optional] --gles-language-verision=" << std::endl; stream << "[optional] --json" << std::endl; - stream << "[optional] --remap-samplers (force metal sampler index to match " - "declared order)" + stream << "[optional] --use-half-textures (force openGL semantics when " + "targeting metal)" << std::endl; } @@ -135,7 +135,8 @@ Switches::Switches(const fml::CommandLine& command_line) metal_version( command_line.GetOptionValueWithDefault("metal-version", "1.2")), entry_point( - command_line.GetOptionValueWithDefault("entry-point", "main")) { + command_line.GetOptionValueWithDefault("entry-point", "main")), + use_half_textures(command_line.HasOption("use-half-textures")) { auto language = command_line.GetOptionValueWithDefault("source-language", "glsl"); std::transform(language.begin(), language.end(), language.begin(), diff --git a/impeller/compiler/switches.h b/impeller/compiler/switches.h index f9703f2e766b8..66884370b091d 100644 --- a/impeller/compiler/switches.h +++ b/impeller/compiler/switches.h @@ -19,23 +19,24 @@ namespace compiler { struct Switches { TargetPlatform target_platform = TargetPlatform::kUnknown; - std::shared_ptr working_directory; - std::vector include_directories; - std::string source_file_name; - SourceType input_type; - std::string sl_file_name; - bool iplr; - std::string spirv_file_name; - std::string reflection_json_name; - std::string reflection_header_name; - std::string reflection_cc_name; - std::string depfile_path; - std::vector defines; - bool json_format; + std::shared_ptr working_directory = nullptr; + std::vector include_directories = {}; + std::string source_file_name = ""; + SourceType input_type = SourceType::kUnknown; + std::string sl_file_name = ""; + bool iplr = false; + std::string spirv_file_name = ""; + std::string reflection_json_name = ""; + std::string reflection_header_name = ""; + std::string reflection_cc_name = ""; + std::string depfile_path = ""; + std::vector defines = {}; + bool json_format = false; SourceLanguage source_language = SourceLanguage::kUnknown; - uint32_t gles_language_version; - std::string metal_version; - std::string entry_point; + uint32_t gles_language_version = 0; + std::string metal_version = ""; + std::string entry_point = ""; + bool use_half_textures = false; Switches(); diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index c9a46c15a2511..d5bf709255d1e 100644 --- a/impeller/tools/impeller.gni +++ b/impeller/tools/impeller.gni @@ -305,6 +305,10 @@ template("impellerc") { args += [ "--metal-version=$metal_version" ] } + if (defined(invoker.use_half_textures) && invoker.use_half_textures) { + args += [ "--use-half-textures" ] + } + if (json) { args += [ "--json" ] } @@ -403,6 +407,11 @@ template("_impeller_shaders_metal") { metal_version = invoker.metal_version } + use_half_textures = false + if (defined(invoker.use_half_textures) && invoker.use_half_textures) { + use_half_textures = invoker.use_half_textures + } + shaders_base_name = string_join("", [ invoker.name, @@ -413,6 +422,7 @@ template("_impeller_shaders_metal") { shaders = invoker.shaders metal_version = metal_version sl_file_extension = "metal" + use_half_textures = use_half_textures shader_target_flag = "" defines = [ "IMPELLER_TARGET_METAL" ] if (is_ios) { @@ -666,12 +676,26 @@ template("_impeller_shaders_vk") { # # The SPIR-V version required by the shaders. # +# @param[options] use_half_textures +# +# Whether the metal shader is using half-precision textures and requires +# openGL semantics when compilig SPIR-V. +# template("impeller_shaders") { metal_version = "1.2" if (defined(invoker.metal_version)) { metal_version = invoker.metal_version } - not_needed([ "metal_version" ]) + + use_half_textures = false + if (defined(invoker.use_half_textures) && invoker.use_half_textures) { + use_half_textures = true + } + + not_needed([ + "metal_version", + "use_half_textures", + ]) enable_opengles = impeller_enable_opengles if (defined(invoker.enable_opengles)) { @@ -685,6 +709,7 @@ template("impeller_shaders") { name = invoker.name shaders = invoker.shaders metal_version = metal_version + use_half_textures = use_half_textures } }