Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 9390126

Browse files
author
Jonah Williams
authored
[Impeller] partially remove remap sampler support (#39147)
* partially remove remap sampler support * Update runtime_effect_contents.cc
1 parent d85ec02 commit 9390126

3 files changed

Lines changed: 40 additions & 81 deletions

File tree

impeller/compiler/compiler.cc

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -36,44 +36,6 @@ static CompilerBackend CreateMSLCompiler(const spirv_cross::ParsedIR& ir,
3636
spirv_cross::CompilerMSL::Options::make_msl_version(1, 2);
3737
sl_compiler->set_msl_options(sl_options);
3838

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-
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-
auto location = sl_compiler->get_decoration(
52-
var.self, spv::Decoration::DecorationLocation);
53-
if (spir_type.basetype ==
54-
spirv_cross::SPIRType::BaseType::SampledImage) {
55-
sampler_offsets.push_back(location);
56-
}
57-
});
58-
if (sampler_offsets.size() > 0) {
59-
auto start_offset =
60-
*std::min_element(sampler_offsets.begin(), sampler_offsets.end());
61-
for (auto offset : sampler_offsets) {
62-
sl_compiler->add_msl_resource_binding({
63-
.stage = spv::ExecutionModel::ExecutionModelFragment,
64-
.basetype = spirv_cross::SPIRType::BaseType::SampledImage,
65-
.binding = offset,
66-
.count = 1u,
67-
// A sampled image is both an image and a sampler, so both
68-
// offsets need to be set or depending on the partiular shader
69-
// the bindings may be incorrect.
70-
.msl_texture = offset - start_offset,
71-
.msl_sampler = offset - start_offset,
72-
});
73-
}
74-
}
75-
}
76-
7739
return CompilerBackend(sl_compiler);
7840
}
7941

impeller/entity/contents/runtime_effect_contents.cc

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -151,30 +151,26 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
151151
/// Fragment stage uniforms.
152152
///
153153

154+
size_t minimum_sampler_index = 100000000;
154155
size_t buffer_index = 0;
155156
size_t buffer_offset = 0;
156-
size_t sampler_index = 0;
157157
for (auto uniform : runtime_stage_->GetUniforms()) {
158158
// TODO(113715): Populate this metadata once GLES is able to handle
159159
// non-struct uniform names.
160160
ShaderMetadata metadata;
161161

162162
switch (uniform.type) {
163163
case kSampledImage: {
164-
FML_DCHECK(sampler_index < texture_inputs_.size());
165-
auto& input = texture_inputs_[sampler_index];
166-
167-
auto sampler =
168-
context->GetSamplerLibrary()->GetSampler(input.sampler_descriptor);
169-
170-
SampledImageSlot image_slot;
171-
image_slot.name = uniform.name.c_str();
172-
image_slot.texture_index = sampler_index;
173-
image_slot.sampler_index = sampler_index;
174-
cmd.BindResource(ShaderStage::kFragment, image_slot, metadata,
175-
input.texture, sampler);
176-
177-
sampler_index++;
164+
// Sampler uniforms are ordered in the IPLR according to their
165+
// declaration and the uniform location reflects the correct offset to
166+
// be mapped to - except that it may include all proceeding float
167+
// uniforms. For example, a float sampler that comes after 4 float
168+
// uniforms may have a location of 4. To convert to the actual offset we
169+
// need to find the largest location assigned to a float uniform and
170+
// then subtract this from all uniform locations. This is more or less
171+
// the same operation we previously performed in the shader compiler.
172+
minimum_sampler_index =
173+
std::min(minimum_sampler_index, uniform.location);
178174
break;
179175
}
180176
case kFloat: {
@@ -210,6 +206,35 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
210206
}
211207
}
212208

209+
size_t sampler_index = 0;
210+
for (auto uniform : runtime_stage_->GetUniforms()) {
211+
// TODO(113715): Populate this metadata once GLES is able to handle
212+
// non-struct uniform names.
213+
ShaderMetadata metadata;
214+
215+
switch (uniform.type) {
216+
case kSampledImage: {
217+
FML_DCHECK(sampler_index < texture_inputs_.size());
218+
auto& input = texture_inputs_[sampler_index];
219+
220+
auto sampler =
221+
context->GetSamplerLibrary()->GetSampler(input.sampler_descriptor);
222+
223+
SampledImageSlot image_slot;
224+
image_slot.name = uniform.name.c_str();
225+
image_slot.texture_index = uniform.location - minimum_sampler_index;
226+
image_slot.sampler_index = uniform.location - minimum_sampler_index;
227+
cmd.BindResource(ShaderStage::kFragment, image_slot, metadata,
228+
input.texture, sampler);
229+
230+
sampler_index++;
231+
break;
232+
}
233+
default:
234+
continue;
235+
}
236+
}
237+
213238
pass.AddCommand(std::move(cmd));
214239

215240
if (geometry_result.prevent_overdraw) {

testing/dart/fragment_shader_test.dart

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -332,34 +332,6 @@ void main() async {
332332
shader.dispose();
333333
});
334334

335-
// This test can't rely on actual pixels rendered since it needs to run on a
336-
// metal shader on iOS. instead parse the source code.
337-
test('impellerc orders samplers in metal shader according to declaration and not usage', () async {
338-
if (!Platform.isMacOS) {
339-
return;
340-
}
341-
final Directory directory = shaderDirectory('iplr-remap');
342-
final String data = readAsStringLossy(File(path.join(directory.path, 'shader_with_samplers.frag.iplr')));
343-
344-
const String expected = 'texture2d<float> textureA [[texture(0)]],'
345-
' texture2d<float> textureB [[texture(1)]]';
346-
347-
expect(data, contains(expected));
348-
});
349-
350-
test('impellerc orders samplers in metal shader according to declaration and not usage in glow', () async {
351-
if (!Platform.isMacOS) {
352-
return;
353-
}
354-
final Directory directory = shaderDirectory('iplr-remap');
355-
final String data = readAsStringLossy(File(path.join(directory.path, 'glow_shader.frag.iplr')));
356-
357-
const String expected = 'texture2d<float> tInput [[texture(0)]], texture2d<float> tNoise [[texture(1)]], '
358-
'sampler tInputSmplr [[sampler(0)]], sampler tNoiseSmplr [[sampler(1)]]';
359-
360-
expect(data, contains(expected));
361-
});
362-
363335
// Test all supported GLSL ops. See lib/spirv/lib/src/constants.dart
364336
final Map<String, FragmentProgram> iplrSupportedGLSLOpShaders = await _loadShaderAssets(
365337
path.join('supported_glsl_op_shaders', 'iplr'),

0 commit comments

Comments
 (0)