From 36955f77f64230494e3de8ccfa65759ea7d9b252 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 24 Mar 2023 17:52:48 -0700 Subject: [PATCH 1/3] [Impeller] allow metal shaders to compile through SPIR-V with openGL semantics --- impeller/compiler/compiler.cc | 16 ++++++++++++++++ impeller/compiler/impellerc_main.cc | 1 + impeller/compiler/source_options.h | 4 ++++ impeller/compiler/switches.cc | 7 ++++--- impeller/compiler/switches.h | 1 + impeller/tools/impeller.gni | 26 +++++++++++++++++++++++++- 6 files changed, 51 insertions(+), 4 deletions(-) diff --git a/impeller/compiler/compiler.cc b/impeller/compiler/compiler.cc index 38ea2a2b495ec..f7423ba2ec3de 100644 --- a/impeller/compiler/compiler.cc +++ b/impeller/compiler/compiler.cc @@ -364,6 +364,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 e50a5d76db94d..5629ca0754dd6 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 27fe2a6bf368f..6ad6d0de9dbe5 100644 --- a/impeller/compiler/switches.cc +++ b/impeller/compiler/switches.cc @@ -71,8 +71,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; } @@ -134,7 +134,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..6c5ce9f9b2bf0 100644 --- a/impeller/compiler/switches.h +++ b/impeller/compiler/switches.h @@ -36,6 +36,7 @@ struct Switches { uint32_t gles_language_version; std::string metal_version; std::string entry_point; + bool use_half_textures; Switches(); diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index c9a46c15a2511..3ee03ad2f9cc9 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, @@ -666,12 +675,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 = false + } + + not_needed([ + "metal_version", + "use_half_textures", + ]) enable_opengles = impeller_enable_opengles if (defined(invoker.enable_opengles)) { @@ -685,6 +708,7 @@ template("impeller_shaders") { name = invoker.name shaders = invoker.shaders metal_version = metal_version + use_half_textures = use_half_textures } } From 726fbc913f750ef6a3f2667f663adfcf381d7d85 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sat, 25 Mar 2023 10:24:46 -0700 Subject: [PATCH 2/3] ++ --- impeller/tools/impeller.gni | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index 3ee03ad2f9cc9..d5bf709255d1e 100644 --- a/impeller/tools/impeller.gni +++ b/impeller/tools/impeller.gni @@ -422,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) { @@ -688,7 +689,7 @@ template("impeller_shaders") { use_half_textures = false if (defined(invoker.use_half_textures) && invoker.use_half_textures) { - use_half_textures = false + use_half_textures = true } not_needed([ From 19ed6f317d6099980bbd60157c53df6f95397e05 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 28 Mar 2023 13:25:48 -0700 Subject: [PATCH 3/3] default initialize struct --- impeller/compiler/switches.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/impeller/compiler/switches.h b/impeller/compiler/switches.h index 6c5ce9f9b2bf0..66884370b091d 100644 --- a/impeller/compiler/switches.h +++ b/impeller/compiler/switches.h @@ -19,24 +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; - bool use_half_textures; + uint32_t gles_language_version = 0; + std::string metal_version = ""; + std::string entry_point = ""; + bool use_half_textures = false; Switches();