77#include < array>
88#include < filesystem>
99#include < memory>
10+ #include < optional>
1011#include < sstream>
12+ #include < string>
1113#include < utility>
1214
1315#include " flutter/fml/paths.h"
@@ -25,16 +27,36 @@ const uint32_t kFragBindingBase = 128;
2527const size_t kNumUniformKinds =
2628 static_cast <int >(shaderc_uniform_kind::shaderc_uniform_kind_buffer) + 1 ;
2729
30+ static uint32_t ParseMSLVersion (const std::string& msl_version) {
31+ std::stringstream sstream (msl_version);
32+ std::string version_part;
33+ uint32_t major = 1 ;
34+ uint32_t minor = 2 ;
35+ uint32_t patch = 0 ;
36+ if (std::getline (sstream, version_part, ' .' )) {
37+ major = std::stoi (version_part);
38+ if (std::getline (sstream, version_part, ' .' )) {
39+ minor = std::stoi (version_part);
40+ if (std::getline (sstream, version_part, ' .' )) {
41+ patch = std::stoi (version_part);
42+ }
43+ }
44+ }
45+ if (major < 1 || minor < 2 ) {
46+ std::cerr << " --metal-version version must be at least 1.2. Have "
47+ << msl_version << std::endl;
48+ }
49+ return spirv_cross::CompilerMSL::Options::make_msl_version (major, minor,
50+ patch);
51+ }
52+
2853static CompilerBackend CreateMSLCompiler (const spirv_cross::ParsedIR& ir,
2954 const SourceOptions& source_options) {
3055 auto sl_compiler = std::make_shared<spirv_cross::CompilerMSL>(ir);
3156 spirv_cross::CompilerMSL::Options sl_options;
3257 sl_options.platform =
3358 TargetPlatformToMSLPlatform (source_options.target_platform );
34- // If this version specification changes, the GN rules that process the
35- // Metal to AIR must be updated as well.
36- sl_options.msl_version =
37- spirv_cross::CompilerMSL::Options::make_msl_version (1 , 2 );
59+ sl_options.msl_version = ParseMSLVersion (source_options.metal_version );
3860 sl_options.use_framebuffer_fetch_subpasses = true ;
3961 sl_compiler->set_msl_options (sl_options);
4062
@@ -357,9 +379,9 @@ Compiler::Compiler(const fml::Mapping& source_mapping,
357379 shaderc_optimization_level::shaderc_optimization_level_performance);
358380 spirv_options.SetTargetEnvironment (
359381 shaderc_target_env::shaderc_target_env_vulkan,
360- shaderc_env_version::shaderc_env_version_vulkan_1_0 );
382+ shaderc_env_version::shaderc_env_version_vulkan_1_1 );
361383 spirv_options.SetTargetSpirv (
362- shaderc_spirv_version::shaderc_spirv_version_1_0 );
384+ shaderc_spirv_version::shaderc_spirv_version_1_3 );
363385 break ;
364386 case TargetPlatform::kRuntimeStageMetal :
365387 case TargetPlatform::kRuntimeStageGLES :
@@ -437,7 +459,11 @@ Compiler::Compiler(const fml::Mapping& source_mapping,
437459 << ShaderCErrorToString (spv_result_->GetCompilationStatus ())
438460 << " . " << spv_result_->GetNumErrors () << " error(s) and "
439461 << spv_result_->GetNumWarnings () << " warning(s)." ;
440- if (spv_result_->GetNumErrors () > 0 || spv_result_->GetNumWarnings () > 0 ) {
462+ // It should normally be enough to check that there are errors or warnings,
463+ // but some cases result in no errors or warnings and still have an error
464+ // message. If there's a message we should print it.
465+ if (spv_result_->GetNumErrors () > 0 || spv_result_->GetNumWarnings () > 0 ||
466+ !spv_result_->GetErrorMessage ().empty ()) {
441467 COMPILER_ERROR_NO_PREFIX << spv_result_->GetErrorMessage ();
442468 }
443469 return ;
0 commit comments