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

Commit df6b15d

Browse files
author
Jonah Williams
authored
[Impeller] dont emulate command buffers for compute on Metal/Vulkan. (#49922)
Part of the work for: flutter/flutter#140804 Removes ComputeCommand and has both ComputePassMTL and ComputePassVK immediately record to their respective comand buffers. This combines the commits for Metal/Vulkan as they are both fairly small. After this, I can add barriers to fix compute for Vulkan.
1 parent cc52c56 commit df6b15d

29 files changed

+556
-1057
lines changed

ci/licenses_golden/excluded_files

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@
182182
../../../flutter/impeller/renderer/backend/vulkan/context_vk_unittests.cc
183183
../../../flutter/impeller/renderer/backend/vulkan/descriptor_pool_vk_unittests.cc
184184
../../../flutter/impeller/renderer/backend/vulkan/fence_waiter_vk_unittests.cc
185-
../../../flutter/impeller/renderer/backend/vulkan/pass_bindings_cache_unittests.cc
186185
../../../flutter/impeller/renderer/backend/vulkan/resource_manager_vk_unittests.cc
187186
../../../flutter/impeller/renderer/backend/vulkan/test
188187
../../../flutter/impeller/renderer/blit_pass_unittests.cc

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5387,6 +5387,8 @@ ORIGIN: ../../../flutter/impeller/renderer/backend/metal/blit_pass_mtl.h + ../..
53875387
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/blit_pass_mtl.mm + ../../../flutter/LICENSE
53885388
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.h + ../../../flutter/LICENSE
53895389
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.mm + ../../../flutter/LICENSE
5390+
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/compute_pass_bindings_cache_mtl.h + ../../../flutter/LICENSE
5391+
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/compute_pass_bindings_cache_mtl.mm + ../../../flutter/LICENSE
53905392
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/compute_pass_mtl.h + ../../../flutter/LICENSE
53915393
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm + ../../../flutter/LICENSE
53925394
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/compute_pipeline_mtl.h + ../../../flutter/LICENSE
@@ -5431,8 +5433,6 @@ ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/android_hardware_buffe
54315433
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/android_hardware_buffer_texture_source_vk.h + ../../../flutter/LICENSE
54325434
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/barrier_vk.cc + ../../../flutter/LICENSE
54335435
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/barrier_vk.h + ../../../flutter/LICENSE
5434-
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/binding_helpers_vk.cc + ../../../flutter/LICENSE
5435-
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/binding_helpers_vk.h + ../../../flutter/LICENSE
54365436
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/blit_command_vk.cc + ../../../flutter/LICENSE
54375437
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/blit_command_vk.h + ../../../flutter/LICENSE
54385438
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc + ../../../flutter/LICENSE
@@ -5464,8 +5464,6 @@ ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/formats_vk.cc + ../../
54645464
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/formats_vk.h + ../../../flutter/LICENSE
54655465
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/gpu_tracer_vk.cc + ../../../flutter/LICENSE
54665466
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/gpu_tracer_vk.h + ../../../flutter/LICENSE
5467-
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/pass_bindings_cache.cc + ../../../flutter/LICENSE
5468-
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/pass_bindings_cache.h + ../../../flutter/LICENSE
54695467
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/pipeline_cache_vk.cc + ../../../flutter/LICENSE
54705468
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/pipeline_cache_vk.h + ../../../flutter/LICENSE
54715469
ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/pipeline_library_vk.cc + ../../../flutter/LICENSE
@@ -5519,8 +5517,6 @@ ORIGIN: ../../../flutter/impeller/renderer/command.cc + ../../../flutter/LICENSE
55195517
ORIGIN: ../../../flutter/impeller/renderer/command.h + ../../../flutter/LICENSE
55205518
ORIGIN: ../../../flutter/impeller/renderer/command_buffer.cc + ../../../flutter/LICENSE
55215519
ORIGIN: ../../../flutter/impeller/renderer/command_buffer.h + ../../../flutter/LICENSE
5522-
ORIGIN: ../../../flutter/impeller/renderer/compute_command.cc + ../../../flutter/LICENSE
5523-
ORIGIN: ../../../flutter/impeller/renderer/compute_command.h + ../../../flutter/LICENSE
55245520
ORIGIN: ../../../flutter/impeller/renderer/compute_pass.cc + ../../../flutter/LICENSE
55255521
ORIGIN: ../../../flutter/impeller/renderer/compute_pass.h + ../../../flutter/LICENSE
55265522
ORIGIN: ../../../flutter/impeller/renderer/compute_pipeline_builder.cc + ../../../flutter/LICENSE
@@ -8231,6 +8227,8 @@ FILE: ../../../flutter/impeller/renderer/backend/metal/blit_pass_mtl.h
82318227
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_pass_mtl.mm
82328228
FILE: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.h
82338229
FILE: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.mm
8230+
FILE: ../../../flutter/impeller/renderer/backend/metal/compute_pass_bindings_cache_mtl.h
8231+
FILE: ../../../flutter/impeller/renderer/backend/metal/compute_pass_bindings_cache_mtl.mm
82348232
FILE: ../../../flutter/impeller/renderer/backend/metal/compute_pass_mtl.h
82358233
FILE: ../../../flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm
82368234
FILE: ../../../flutter/impeller/renderer/backend/metal/compute_pipeline_mtl.h
@@ -8275,8 +8273,6 @@ FILE: ../../../flutter/impeller/renderer/backend/vulkan/android_hardware_buffer_
82758273
FILE: ../../../flutter/impeller/renderer/backend/vulkan/android_hardware_buffer_texture_source_vk.h
82768274
FILE: ../../../flutter/impeller/renderer/backend/vulkan/barrier_vk.cc
82778275
FILE: ../../../flutter/impeller/renderer/backend/vulkan/barrier_vk.h
8278-
FILE: ../../../flutter/impeller/renderer/backend/vulkan/binding_helpers_vk.cc
8279-
FILE: ../../../flutter/impeller/renderer/backend/vulkan/binding_helpers_vk.h
82808276
FILE: ../../../flutter/impeller/renderer/backend/vulkan/blit_command_vk.cc
82818277
FILE: ../../../flutter/impeller/renderer/backend/vulkan/blit_command_vk.h
82828278
FILE: ../../../flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc
@@ -8309,8 +8305,6 @@ FILE: ../../../flutter/impeller/renderer/backend/vulkan/formats_vk.h
83098305
FILE: ../../../flutter/impeller/renderer/backend/vulkan/gpu_tracer_vk.cc
83108306
FILE: ../../../flutter/impeller/renderer/backend/vulkan/gpu_tracer_vk.h
83118307
FILE: ../../../flutter/impeller/renderer/backend/vulkan/limits_vk.h
8312-
FILE: ../../../flutter/impeller/renderer/backend/vulkan/pass_bindings_cache.cc
8313-
FILE: ../../../flutter/impeller/renderer/backend/vulkan/pass_bindings_cache.h
83148308
FILE: ../../../flutter/impeller/renderer/backend/vulkan/pipeline_cache_vk.cc
83158309
FILE: ../../../flutter/impeller/renderer/backend/vulkan/pipeline_cache_vk.h
83168310
FILE: ../../../flutter/impeller/renderer/backend/vulkan/pipeline_library_vk.cc
@@ -8364,8 +8358,6 @@ FILE: ../../../flutter/impeller/renderer/command.cc
83648358
FILE: ../../../flutter/impeller/renderer/command.h
83658359
FILE: ../../../flutter/impeller/renderer/command_buffer.cc
83668360
FILE: ../../../flutter/impeller/renderer/command_buffer.h
8367-
FILE: ../../../flutter/impeller/renderer/compute_command.cc
8368-
FILE: ../../../flutter/impeller/renderer/compute_command.h
83698361
FILE: ../../../flutter/impeller/renderer/compute_pass.cc
83708362
FILE: ../../../flutter/impeller/renderer/compute_pass.h
83718363
FILE: ../../../flutter/impeller/renderer/compute_pipeline_builder.cc

impeller/entity/geometry/point_field_geometry.cc

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "impeller/entity/geometry/point_field_geometry.h"
66

77
#include "impeller/renderer/command_buffer.h"
8-
#include "impeller/renderer/compute_command.h"
98

109
namespace impeller {
1110

@@ -168,9 +167,9 @@ GeometryResult PointFieldGeometry::GetPositionBufferGPU(
168167
BufferView output;
169168
{
170169
using PS = PointsComputeShader;
171-
ComputeCommand cmd;
172-
DEBUG_COMMAND_INFO(cmd, "Points Geometry");
173-
cmd.pipeline = renderer.GetPointComputePipeline();
170+
171+
compute_pass->SetPipeline(renderer.GetPointComputePipeline());
172+
compute_pass->SetCommandLabel("Points Geometry");
174173

175174
PS::FrameInfo frame_info;
176175
frame_info.count = points_.size();
@@ -180,11 +179,11 @@ GeometryResult PointFieldGeometry::GetPositionBufferGPU(
180179
frame_info.points_per_circle = points_per_circle;
181180
frame_info.divisions_per_circle = vertices_per_geom;
182181

183-
PS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
184-
PS::BindGeometryData(cmd, geometry_buffer);
185-
PS::BindPointData(cmd, points_data);
182+
PS::BindFrameInfo(*compute_pass, host_buffer.EmplaceUniform(frame_info));
183+
PS::BindGeometryData(*compute_pass, geometry_buffer);
184+
PS::BindPointData(*compute_pass, points_data);
186185

187-
if (!compute_pass->AddCommand(std::move(cmd))) {
186+
if (!compute_pass->Compute(ISize(total, 1)).ok()) {
188187
return {};
189188
}
190189
output = geometry_buffer;
@@ -201,29 +200,25 @@ GeometryResult PointFieldGeometry::GetPositionBufferGPU(
201200

202201
using UV = UvComputeShader;
203202

204-
ComputeCommand cmd;
205-
DEBUG_COMMAND_INFO(cmd, "UV Geometry");
206-
cmd.pipeline = renderer.GetUvComputePipeline();
203+
compute_pass->SetCommandLabel("UV Geometry");
204+
compute_pass->SetPipeline(renderer.GetUvComputePipeline());
207205

208206
UV::FrameInfo frame_info;
209207
frame_info.count = total;
210208
frame_info.effect_transform = effect_transform.value();
211209
frame_info.texture_origin = {0, 0};
212210
frame_info.texture_size = Vector2(texture_coverage.value().GetSize());
213211

214-
UV::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
215-
UV::BindGeometryData(cmd, geometry_buffer);
216-
UV::BindGeometryUVData(cmd, geometry_uv_buffer);
212+
UV::BindFrameInfo(*compute_pass, host_buffer.EmplaceUniform(frame_info));
213+
UV::BindGeometryData(*compute_pass, geometry_buffer);
214+
UV::BindGeometryUVData(*compute_pass, geometry_uv_buffer);
217215

218-
if (!compute_pass->AddCommand(std::move(cmd))) {
216+
if (!compute_pass->Compute(ISize(total, 1)).ok()) {
219217
return {};
220218
}
221219
output = geometry_uv_buffer;
222220
}
223221

224-
compute_pass->SetGridSize(ISize(total, 1));
225-
compute_pass->SetThreadGroupSize(ISize(total, 1));
226-
227222
if (!compute_pass->EncodeCommands() || !cmd_buffer->SubmitCommands()) {
228223
return {};
229224
}

impeller/renderer/BUILD.gn

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ impeller_component("renderer") {
5555
"command.h",
5656
"command_buffer.cc",
5757
"command_buffer.h",
58-
"compute_command.cc",
59-
"compute_command.h",
6058
"compute_pass.cc",
6159
"compute_pass.h",
6260
"compute_pipeline_builder.cc",

impeller/renderer/backend/metal/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ impeller_component("metal") {
1414
"blit_pass_mtl.mm",
1515
"command_buffer_mtl.h",
1616
"command_buffer_mtl.mm",
17+
"compute_pass_bindings_cache_mtl.h",
18+
"compute_pass_bindings_cache_mtl.mm",
1719
"compute_pass_mtl.h",
1820
"compute_pass_mtl.mm",
1921
"compute_pipeline_mtl.h",

impeller/renderer/backend/metal/command_buffer_mtl.mm

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,13 @@ static bool LogMTLCommandBufferErrorIfPresent(id<MTLCommandBuffer> buffer) {
220220
if (!buffer_) {
221221
return nullptr;
222222
}
223+
auto context = context_.lock();
224+
if (!context) {
225+
return nullptr;
226+
}
223227

224228
auto pass =
225-
std::shared_ptr<ComputePassMTL>(new ComputePassMTL(context_, buffer_));
229+
std::shared_ptr<ComputePassMTL>(new ComputePassMTL(context, buffer_));
226230
if (!pass->IsValid()) {
227231
return nullptr;
228232
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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+
#ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_COMPUTE_PASS_BINDINGS_CACHE_MTL_H_
6+
#define FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_COMPUTE_PASS_BINDINGS_CACHE_MTL_H_
7+
8+
#include <Metal/Metal.h>
9+
10+
#include "flutter/fml/macros.h"
11+
#include "impeller/renderer/compute_pass.h"
12+
#include "impeller/renderer/pipeline_descriptor.h"
13+
14+
namespace impeller {
15+
16+
//-----------------------------------------------------------------------------
17+
/// @brief Ensures that bindings on the pass are not redundantly set or
18+
/// updated. Avoids making the driver do additional checks and makes
19+
/// the frame insights during profiling and instrumentation not
20+
/// complain about the same.
21+
///
22+
/// There should be no change to rendering if this caching was
23+
/// absent.
24+
///
25+
struct ComputePassBindingsCacheMTL {
26+
explicit ComputePassBindingsCacheMTL() {}
27+
28+
ComputePassBindingsCacheMTL(const ComputePassBindingsCacheMTL&) = delete;
29+
30+
ComputePassBindingsCacheMTL(ComputePassBindingsCacheMTL&&) = delete;
31+
32+
void SetComputePipelineState(id<MTLComputePipelineState> pipeline);
33+
34+
id<MTLComputePipelineState> GetPipeline() const;
35+
36+
void SetEncoder(id<MTLComputeCommandEncoder> encoder);
37+
38+
void SetBuffer(uint64_t index, uint64_t offset, id<MTLBuffer> buffer);
39+
40+
void SetTexture(uint64_t index, id<MTLTexture> texture);
41+
42+
void SetSampler(uint64_t index, id<MTLSamplerState> sampler);
43+
44+
private:
45+
struct BufferOffsetPair {
46+
id<MTLBuffer> buffer = nullptr;
47+
size_t offset = 0u;
48+
};
49+
using BufferMap = std::map<uint64_t, BufferOffsetPair>;
50+
using TextureMap = std::map<uint64_t, id<MTLTexture>>;
51+
using SamplerMap = std::map<uint64_t, id<MTLSamplerState>>;
52+
53+
id<MTLComputeCommandEncoder> encoder_;
54+
id<MTLComputePipelineState> pipeline_ = nullptr;
55+
BufferMap buffers_;
56+
TextureMap textures_;
57+
SamplerMap samplers_;
58+
};
59+
60+
} // namespace impeller
61+
62+
#endif // FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_COMPUTE_PASS_BINDINGS_CACHE_MTL_H_
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
#include "impeller/renderer/backend/metal/compute_pass_bindings_cache_mtl.h"
6+
7+
namespace impeller {
8+
9+
void ComputePassBindingsCacheMTL::SetComputePipelineState(
10+
id<MTLComputePipelineState> pipeline) {
11+
if (pipeline == pipeline_) {
12+
return;
13+
}
14+
pipeline_ = pipeline;
15+
[encoder_ setComputePipelineState:pipeline_];
16+
}
17+
18+
id<MTLComputePipelineState> ComputePassBindingsCacheMTL::GetPipeline() const {
19+
return pipeline_;
20+
}
21+
22+
void ComputePassBindingsCacheMTL::SetEncoder(
23+
id<MTLComputeCommandEncoder> encoder) {
24+
encoder_ = encoder;
25+
}
26+
27+
void ComputePassBindingsCacheMTL::SetBuffer(uint64_t index,
28+
uint64_t offset,
29+
id<MTLBuffer> buffer) {
30+
auto found = buffers_.find(index);
31+
if (found != buffers_.end() && found->second.buffer == buffer) {
32+
// The right buffer is bound. Check if its offset needs to be updated.
33+
if (found->second.offset == offset) {
34+
// Buffer and its offset is identical. Nothing to do.
35+
return;
36+
}
37+
38+
// Only the offset needs to be updated.
39+
found->second.offset = offset;
40+
41+
[encoder_ setBufferOffset:offset atIndex:index];
42+
return;
43+
}
44+
45+
buffers_[index] = {buffer, static_cast<size_t>(offset)};
46+
[encoder_ setBuffer:buffer offset:offset atIndex:index];
47+
}
48+
49+
void ComputePassBindingsCacheMTL::SetTexture(uint64_t index,
50+
id<MTLTexture> texture) {
51+
auto found = textures_.find(index);
52+
if (found != textures_.end() && found->second == texture) {
53+
// Already bound.
54+
return;
55+
}
56+
textures_[index] = texture;
57+
[encoder_ setTexture:texture atIndex:index];
58+
return;
59+
}
60+
61+
void ComputePassBindingsCacheMTL::SetSampler(uint64_t index,
62+
id<MTLSamplerState> sampler) {
63+
auto found = samplers_.find(index);
64+
if (found != samplers_.end() && found->second == sampler) {
65+
// Already bound.
66+
return;
67+
}
68+
samplers_[index] = sampler;
69+
[encoder_ setSamplerState:sampler atIndex:index];
70+
return;
71+
}
72+
73+
} // namespace impeller

impeller/renderer/backend/metal/compute_pass_mtl.h

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include <Metal/Metal.h>
99

1010
#include "flutter/fml/macros.h"
11+
#include "impeller/renderer/backend/metal/compute_pass_bindings_cache_mtl.h"
1112
#include "impeller/renderer/compute_pass.h"
13+
#include "impeller/renderer/pipeline_descriptor.h"
1214

1315
namespace impeller {
1416

@@ -21,27 +23,48 @@ class ComputePassMTL final : public ComputePass {
2123
friend class CommandBufferMTL;
2224

2325
id<MTLCommandBuffer> buffer_ = nil;
24-
std::string label_;
26+
id<MTLComputeCommandEncoder> encoder_ = nil;
27+
ComputePassBindingsCacheMTL pass_bindings_cache_ =
28+
ComputePassBindingsCacheMTL();
2529
bool is_valid_ = false;
30+
bool has_label_ = false;
2631

27-
ComputePassMTL(std::weak_ptr<const Context> context,
32+
ComputePassMTL(std::shared_ptr<const Context> context,
2833
id<MTLCommandBuffer> buffer);
2934

3035
// |ComputePass|
3136
bool IsValid() const override;
3237

38+
// |ComputePass|
39+
fml::Status Compute(const ISize& grid_size) override;
40+
41+
// |ComputePass|
42+
void SetCommandLabel(std::string_view label) override;
43+
3344
// |ComputePass|
3445
void OnSetLabel(const std::string& label) override;
3546

3647
// |ComputePass|
37-
bool OnEncodeCommands(const Context& context,
38-
const ISize& grid_size,
39-
const ISize& thread_group_size) const override;
48+
void SetPipeline(const std::shared_ptr<Pipeline<ComputePipelineDescriptor>>&
49+
pipeline) override;
4050

41-
bool EncodeCommands(const std::shared_ptr<Allocator>& allocator,
42-
id<MTLComputeCommandEncoder> pass,
43-
const ISize& grid_size,
44-
const ISize& thread_group_size) const;
51+
// |ComputePass|
52+
bool BindResource(ShaderStage stage,
53+
DescriptorType type,
54+
const ShaderUniformSlot& slot,
55+
const ShaderMetadata& metadata,
56+
BufferView view) override;
57+
58+
// |ComputePass|
59+
bool BindResource(ShaderStage stage,
60+
DescriptorType type,
61+
const SampledImageSlot& slot,
62+
const ShaderMetadata& metadata,
63+
std::shared_ptr<const Texture> texture,
64+
std::shared_ptr<const Sampler> sampler) override;
65+
66+
// |ComputePass|
67+
bool EncodeCommands() const override;
4568

4669
ComputePassMTL(const ComputePassMTL&) = delete;
4770

0 commit comments

Comments
 (0)