Skip to content

Commit 22416c2

Browse files
author
Jonah Williams
committed
[Impeller] order metal samplers according to declared order and not usage order (flutter#38115)
* [Impeller] order metal samplers according to declared order and not use order * ++ * always enabl remapping * Revert "always enabl remapping" This reverts commit 2fffb05. * ++ * add test * ++ * ++ * only run on mac
1 parent 7b74620 commit 22416c2

File tree

11 files changed

+173
-0
lines changed

11 files changed

+173
-0
lines changed

impeller/compiler/compiler.cc

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,58 @@ static CompilerBackend CreateMSLCompiler(const spirv_cross::ParsedIR& ir,
3535
sl_options.msl_version =
3636
spirv_cross::CompilerMSL::Options::make_msl_version(1, 2);
3737
sl_compiler->set_msl_options(sl_options);
38+
39+
// Set metal resource mappings to be consistent with location based mapping
40+
// used on other backends when creating fragment shaders. This doesn't seem
41+
// to work with the generated bindings for compute shaders, nor for certain
42+
// shaders in the flutter/engine tree.
43+
if (source_options.remap_samplers) {
44+
std::vector<uint32_t> sampler_offsets;
45+
std::vector<uint32_t> float_offsets;
46+
ir.for_each_typed_id<spirv_cross::SPIRVariable>(
47+
[&](uint32_t, const spirv_cross::SPIRVariable& var) {
48+
if (var.storage != spv::StorageClassUniformConstant) {
49+
return;
50+
}
51+
const auto spir_type = sl_compiler->get_type(var.basetype);
52+
auto location = sl_compiler->get_decoration(
53+
var.self, spv::Decoration::DecorationLocation);
54+
if (spir_type.basetype ==
55+
spirv_cross::SPIRType::BaseType::SampledImage) {
56+
sampler_offsets.push_back(location);
57+
} else if (spir_type.basetype ==
58+
spirv_cross::SPIRType::BaseType::Float) {
59+
float_offsets.push_back(location);
60+
}
61+
});
62+
if (sampler_offsets.size() > 0) {
63+
auto start_offset =
64+
*std::min_element(sampler_offsets.begin(), sampler_offsets.end());
65+
for (auto offset : sampler_offsets) {
66+
sl_compiler->add_msl_resource_binding({
67+
.stage = spv::ExecutionModel::ExecutionModelFragment,
68+
.basetype = spirv_cross::SPIRType::BaseType::SampledImage,
69+
.binding = offset,
70+
.count = 1u,
71+
.msl_texture = offset - start_offset,
72+
});
73+
}
74+
}
75+
if (float_offsets.size() > 0) {
76+
auto start_offset =
77+
*std::min_element(float_offsets.begin(), float_offsets.end());
78+
for (auto offset : float_offsets) {
79+
sl_compiler->add_msl_resource_binding({
80+
.stage = spv::ExecutionModel::ExecutionModelFragment,
81+
.basetype = spirv_cross::SPIRType::BaseType::Float,
82+
.binding = offset,
83+
.count = 1u,
84+
.msl_buffer = offset - start_offset,
85+
});
86+
}
87+
}
88+
}
89+
3890
return CompilerBackend(sl_compiler);
3991
}
4092

impeller/compiler/impellerc_main.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ bool Main(const fml::CommandLine& command_line) {
7373
switches.source_file_name, options.type, options.source_language,
7474
switches.entry_point);
7575
options.json_format = switches.json_format;
76+
options.remap_samplers = switches.remap_samplers;
7677
options.gles_language_version = switches.gles_language_version;
7778

7879
Reflector::Options reflector_options;

impeller/compiler/source_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct SourceOptions {
2727
uint32_t gles_language_version = 100;
2828
std::vector<std::string> defines;
2929
bool json_format = false;
30+
bool remap_samplers = false;
3031

3132
SourceOptions();
3233

impeller/compiler/switches.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ void Switches::PrintHelp(std::ostream& stream) {
7171
stream << "[optional] --depfile=<depfile_path>" << std::endl;
7272
stream << "[optional] --gles-language-verision=<number>" << std::endl;
7373
stream << "[optional] --json" << std::endl;
74+
stream << "[optional] --remap-samplers (force metal sampler index to match "
75+
"declared order)"
76+
<< std::endl;
7477
}
7578

7679
Switches::Switches() = default;
@@ -125,6 +128,7 @@ Switches::Switches(const fml::CommandLine& command_line)
125128
command_line.GetOptionValueWithDefault("reflection-cc", "")),
126129
depfile_path(command_line.GetOptionValueWithDefault("depfile", "")),
127130
json_format(command_line.HasOption("json")),
131+
remap_samplers(command_line.HasOption("remap-samplers")),
128132
gles_language_version(
129133
stoi(command_line.GetOptionValueWithDefault("gles-language-version",
130134
"0"))),

impeller/compiler/switches.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct Switches {
3232
std::string depfile_path;
3333
std::vector<std::string> defines;
3434
bool json_format;
35+
bool remap_samplers;
3536
SourceLanguage source_language = SourceLanguage::kUnknown;
3637
uint32_t gles_language_version;
3738
std::string entry_point;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Declare matrix in different order than usage.
6+
uniform mat4 matrix;
7+
uniform float floatB;
8+
9+
out vec4 frag_color;
10+
11+
void main() {
12+
vec4 sample_1 = vec4(floatB);
13+
vec4 sample_2 = sample_1 * matrix;
14+
frag_color = sample_1 + sample_2;
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Declare floats in different order than usage.
6+
uniform float floatA;
7+
uniform float floatB;
8+
9+
out vec4 frag_color;
10+
11+
void main() {
12+
vec4 sample_1 = vec4(floatB);
13+
vec4 sample_2 = vec4(floatA);
14+
frag_color = sample_1 + sample_2;
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Declare samplers in different order than usage.
6+
uniform sampler2D textureA;
7+
uniform sampler2D textureB;
8+
9+
out vec4 frag_color;
10+
11+
void main() {
12+
vec4 sample_1 = texture(textureB, vec2(1.0));
13+
vec4 sample_2 = texture(textureA, vec2(1.0));
14+
frag_color = sample_1 + sample_2;
15+
}

impeller/tools/impeller.gni

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,13 @@ template("impellerc") {
233233
iplr = invoker.iplr
234234
}
235235
json = false
236+
remap_samplers = false
236237
if (defined(invoker.json) && invoker.json) {
237238
json = invoker.json
238239
}
240+
if (defined(invoker.remap_samplers) && invoker.remap_samplers) {
241+
remap_samplers = invoker.remap_samplers
242+
}
239243

240244
# Not needed on every path.
241245
not_needed([
@@ -248,6 +252,8 @@ template("impellerc") {
248252
# Optional: invoker.intermediates_subdir specifies the subdirectory in which
249253
# to put intermediates.
250254
# Optional: invoker.json Causes output format to be JSON instead of flatbuffer.
255+
# Optional: invoker.remap_samplers Output metal samplers according to
256+
# declaration order instead of usage order.
251257

252258
_impellerc(target_name) {
253259
sources = invoker.shaders
@@ -284,6 +290,9 @@ template("impellerc") {
284290
if (json) {
285291
args += [ "--json" ]
286292
}
293+
if (remap_samplers) {
294+
args += [ "--remap-samplers" ]
295+
}
287296

288297
if (sksl) {
289298
sl_intermediate =

lib/ui/fixtures/shaders/BUILD.gn

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,24 @@ if (enable_unittests) {
3333
json = true
3434
}
3535

36+
impellerc("sampler_order_fixture") {
37+
shaders = [
38+
"//flutter/impeller/fixtures/ordering/shader_with_samplers.frag",
39+
"//flutter/impeller/fixtures/ordering/shader_with_ordered_floats.frag",
40+
"//flutter/impeller/fixtures/ordering/shader_with_matrix.frag",
41+
]
42+
shader_target_flag = "--runtime-stage-metal"
43+
intermediates_subdir = "iplr-remap"
44+
sl_file_extension = "iplr"
45+
iplr = true
46+
remap_samplers = true
47+
}
48+
3649
test_fixtures("fixtures") {
3750
deps = [
3851
":ink_sparkle",
3952
":ink_sparkle_web",
53+
":sampler_order_fixture",
4054
]
4155
fixtures = get_target_outputs(":ink_sparkle")
4256
dest = "$root_gen_dir/flutter/lib/ui"

0 commit comments

Comments
 (0)