2020namespace impeller {
2121namespace compiler {
2222
23+ static std::optional<spv::ExecutionModel> SourceTypeToExecutionModel (
24+ const SourceType& type) {
25+ switch (type) {
26+ case SourceType::kUnknown :
27+ return std::nullopt ;
28+ case SourceType::kVertexShader :
29+ return spv::ExecutionModel::ExecutionModelVertex;
30+ case SourceType::kFragmentShader :
31+ return spv::ExecutionModel::ExecutionModelFragment;
32+ case SourceType::kTessellationControlShader :
33+ return spv::ExecutionModel::ExecutionModelTessellationControl;
34+ case SourceType::kTessellationEvaluationShader :
35+ return spv::ExecutionModel::ExecutionModelTessellationEvaluation;
36+ case SourceType::kComputeShader :
37+ return spv::ExecutionModel::ExecutionModelGLCompute;
38+ }
39+ }
40+
2341const uint32_t kFragBindingBase = 128 ;
2442const size_t kNumUniformKinds =
2543 static_cast <int >(shaderc_uniform_kind::shaderc_uniform_kind_buffer) + 1 ;
@@ -34,42 +52,40 @@ static CompilerBackend CreateMSLCompiler(const spirv_cross::ParsedIR& ir,
3452 // Metal to AIR must be updated as well.
3553 sl_options.msl_version =
3654 spirv_cross::CompilerMSL::Options::make_msl_version (1 , 2 );
55+ sl_options.enable_decoration_binding = true ;
3756 sl_compiler->set_msl_options (sl_options);
3857
3958 // Set metal resource mappings to be consistent with location based mapping
40- // used on other backends when creating fragment shaders. This relies on the
41- // fact that the order of uniforms in the IR mirrors the declared order in the
42- // shader source.
43- if (source_options.remap_samplers ) {
44- std::vector<uint32_t > sampler_offsets;
45- ir.for_each_typed_id <spirv_cross::SPIRVariable>(
46- [&](uint32_t , const spirv_cross::SPIRVariable& var) {
47- if (var.storage != spv::StorageClassUniformConstant) {
48- return ;
49- }
50- const auto spir_type = sl_compiler->get_type (var.basetype );
51- if (spir_type.basetype !=
52- spirv_cross::SPIRType::BaseType::SampledImage) {
53- return ;
54- }
55- auto location = sl_compiler->get_decoration (
56- var.self , spv::Decoration::DecorationLocation);
57- sampler_offsets.push_back (location);
58- });
59- if (sampler_offsets.size () > 0 ) {
60- auto start_offset =
61- *std::min_element (sampler_offsets.begin (), sampler_offsets.end ());
62- for (auto offset : sampler_offsets) {
63- sl_compiler->add_msl_resource_binding ({
64- .stage = spv::ExecutionModel::ExecutionModelFragment,
65- .basetype = spirv_cross::SPIRType::BaseType::SampledImage,
66- .binding = offset,
67- .count = 1u ,
68- .msl_buffer = offset - start_offset,
69- .msl_texture = offset - start_offset,
70- .msl_sampler = offset - start_offset,
71- });
72- }
59+ // used on other backends when creating shaders.
60+ std::vector<uint32_t > sampler_offsets;
61+ ir.for_each_typed_id <spirv_cross::SPIRVariable>(
62+ [&](uint32_t , const spirv_cross::SPIRVariable& var) {
63+ if (var.storage != spv::StorageClassUniformConstant) {
64+ return ;
65+ }
66+ const auto spir_type = sl_compiler->get_type (var.basetype );
67+ if (spir_type.basetype !=
68+ spirv_cross::SPIRType::BaseType::SampledImage) {
69+ return ;
70+ }
71+ auto location = sl_compiler->get_decoration (
72+ var.self , spv::Decoration::DecorationLocation);
73+ sampler_offsets.push_back (location);
74+ });
75+ auto stage = SourceTypeToExecutionModel (source_options.type );
76+ if (stage.has_value () && sampler_offsets.size () > 0 ) {
77+ auto start_offset =
78+ *std::min_element (sampler_offsets.begin (), sampler_offsets.end ());
79+ for (auto offset : sampler_offsets) {
80+ sl_compiler->add_msl_resource_binding ({
81+ .stage = stage.value (),
82+ .basetype = spirv_cross::SPIRType::BaseType::SampledImage,
83+ .binding = offset,
84+ .count = 1u ,
85+ .msl_buffer = offset - start_offset,
86+ .msl_texture = offset - start_offset,
87+ .msl_sampler = offset - start_offset,
88+ });
7389 }
7490 }
7591
0 commit comments