20
20
namespace impeller {
21
21
namespace compiler {
22
22
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
+
23
41
const uint32_t kFragBindingBase = 128 ;
24
42
const size_t kNumUniformKinds =
25
43
static_cast <int >(shaderc_uniform_kind::shaderc_uniform_kind_buffer) + 1 ;
@@ -34,42 +52,40 @@ static CompilerBackend CreateMSLCompiler(const spirv_cross::ParsedIR& ir,
34
52
// Metal to AIR must be updated as well.
35
53
sl_options.msl_version =
36
54
spirv_cross::CompilerMSL::Options::make_msl_version (1 , 2 );
55
+ sl_options.enable_decoration_binding = true ;
37
56
sl_compiler->set_msl_options (sl_options);
38
57
39
58
// 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
+ });
73
89
}
74
90
}
75
91
0 commit comments