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

[Impeller] move bindings off of command while recording. #49569

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions impeller/entity/contents/test/contents_test_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,44 @@
#ifndef FLUTTER_IMPELLER_ENTITY_CONTENTS_TEST_CONTENTS_TEST_HELPERS_H_
#define FLUTTER_IMPELLER_ENTITY_CONTENTS_TEST_CONTENTS_TEST_HELPERS_H_

#include "impeller/renderer/command.h"
#include "impeller/core/shader_types.h"
#include "impeller/renderer/render_pass.h"

namespace impeller {

/// @brief Retrieve the [VertInfo] struct data from the provided [command].
template <typename T>
typename T::VertInfo* GetVertInfo(const Command& command) {
auto resource = std::find_if(command.vertex_bindings.buffers.begin(),
command.vertex_bindings.buffers.end(),
[](const BufferAndUniformSlot& data) {
return data.slot.ext_res_0 == 0u;
typename T::VertInfo* GetVertInfo(
const BoundCommand& command,
const std::vector<BoundBuffer>& bound_buffers) {
const auto& end =
bound_buffers.begin() + command.buffer_offset + command.buffer_length;
auto resource = std::find_if(bound_buffers.begin() + command.buffer_offset,
end, [](const BoundBuffer& data) {
return data.slot.ext_res_0 == 0u &&
data.stage == ShaderStage::kVertex;
});
if (resource == command.vertex_bindings.buffers.end()) {
if (resource == end) {
return nullptr;
}

auto data =
(resource->view.resource.contents + resource->view.resource.range.offset);
return reinterpret_cast<typename T::VertInfo*>(data);
}

/// @brief Retrieve the [FragInfo] struct data from the provided [command].
template <typename T>
typename T::FragInfo* GetFragInfo(const Command& command) {
auto resource = std::find_if(command.fragment_bindings.buffers.begin(),
command.fragment_bindings.buffers.end(),
[](const BufferAndUniformSlot& data) {
return data.slot.ext_res_0 == 0u;
typename T::FragInfo* GetFragInfo(
const BoundCommand& command,
const std::vector<BoundBuffer>& bound_buffers) {
const auto& end =
bound_buffers.begin() + command.buffer_offset + command.buffer_length;
auto resource = std::find_if(bound_buffers.begin() + command.buffer_offset,
end, [](const BoundBuffer& data) {
return data.slot.ext_res_0 == 0u &&
data.stage == ShaderStage::kFragment;
});
if (resource == command.fragment_bindings.buffers.end()) {
if (resource == end) {
return nullptr;
}

Expand Down
5 changes: 3 additions & 2 deletions impeller/entity/contents/tiled_texture_contents_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/entity/entity_playground.h"
#include "impeller/playground/playground_test.h"
#include "impeller/renderer/render_pass.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"

namespace impeller {
Expand Down Expand Up @@ -37,7 +38,7 @@ TEST_P(EntityTest, TiledTextureContentsRendersWithCorrectPipeline) {
auto render_pass = buffer->CreateRenderPass(render_target);

ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *render_pass));
const std::vector<Command>& commands = render_pass->GetCommands();
const std::vector<BoundCommand>& commands = render_pass->GetCommands();

ASSERT_EQ(commands.size(), 1u);
ASSERT_STREQ(commands[0].pipeline->GetDescriptor().GetLabel().c_str(),
Expand Down Expand Up @@ -72,7 +73,7 @@ TEST_P(EntityTest, TiledTextureContentsRendersWithCorrectPipelineExternalOES) {
auto render_pass = buffer->CreateRenderPass(render_target);

ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *render_pass));
const std::vector<Command>& commands = render_pass->GetCommands();
const std::vector<BoundCommand>& commands = render_pass->GetCommands();

ASSERT_EQ(commands.size(), 1u);
ASSERT_STREQ(commands[0].pipeline->GetDescriptor().GetLabel().c_str(),
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/vertices_contents_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ TEST_P(EntityTest, RendersDstPerColorWithAlpha) {
ASSERT_TRUE(contents->Render(*content_context, entity, *render_pass));

const auto& cmd = render_pass->GetCommands()[0];
auto* frag_uniforms = GetFragInfo<FS>(cmd);
auto* frag_uniforms = GetFragInfo<FS>(cmd, render_pass->GetBoundBuffers());

ASSERT_EQ(frag_uniforms->alpha, 0.5);
}
Expand Down
42 changes: 25 additions & 17 deletions impeller/renderer/backend/gles/buffer_bindings_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "impeller/renderer/backend/gles/formats_gles.h"
#include "impeller/renderer/backend/gles/sampler_gles.h"
#include "impeller/renderer/backend/gles/texture_gles.h"
#include "impeller/renderer/command.h"

namespace impeller {

Expand Down Expand Up @@ -142,29 +143,30 @@ bool BufferBindingsGLES::BindVertexAttributes(const ProcTableGLES& gl,
return true;
}

bool BufferBindingsGLES::BindUniformData(const ProcTableGLES& gl,
Allocator& transients_allocator,
const Bindings& vertex_bindings,
const Bindings& fragment_bindings) {
for (const auto& buffer : vertex_bindings.buffers) {
if (!BindUniformBuffer(gl, transients_allocator, buffer.view)) {
return false;
}
}
for (const auto& buffer : fragment_bindings.buffers) {
if (!BindUniformBuffer(gl, transients_allocator, buffer.view)) {
bool BufferBindingsGLES::BindUniformData(
const ProcTableGLES& gl,
Allocator& transients_allocator,
const std::vector<BoundBuffer>& bound_buffers,
size_t buffer_offset,
size_t buffer_length,
const std::vector<BoundTexture>& bound_textures,
size_t texture_offset,
size_t texture_length) {
for (auto i = buffer_offset; i < buffer_offset + buffer_length; i++) {
const BoundBuffer& data = bound_buffers[i];
if (!BindUniformBuffer(gl, transients_allocator, data.view)) {
return false;
}
}

std::optional<size_t> next_unit_index =
BindTextures(gl, vertex_bindings, ShaderStage::kVertex);
std::optional<size_t> next_unit_index = BindTextures(
gl, bound_textures, texture_offset, texture_length, ShaderStage::kVertex);
if (!next_unit_index.has_value()) {
return false;
}

if (!BindTextures(gl, fragment_bindings, ShaderStage::kFragment,
*next_unit_index)
if (!BindTextures(gl, bound_textures, texture_offset, texture_length,
ShaderStage::kFragment, *next_unit_index)
.has_value()) {
return false;
}
Expand Down Expand Up @@ -345,11 +347,17 @@ bool BufferBindingsGLES::BindUniformBuffer(const ProcTableGLES& gl,

std::optional<size_t> BufferBindingsGLES::BindTextures(
const ProcTableGLES& gl,
const Bindings& bindings,
const std::vector<BoundTexture>& bound_textures,
size_t offset,
size_t length,
ShaderStage stage,
size_t unit_start_index) {
size_t active_index = unit_start_index;
for (const auto& data : bindings.sampled_images) {
for (auto i = offset; i < offset + length; i++) {
const BoundTexture& data = bound_textures[i];
if (data.stage != stage) {
continue;
}
const auto& texture_gles = TextureGLES::Cast(*data.texture.resource);
if (data.texture.GetMetadata() == nullptr) {
VALIDATION_LOG << "No metadata found for texture binding.";
Expand Down
20 changes: 13 additions & 7 deletions impeller/renderer/backend/gles/buffer_bindings_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <unordered_map>
#include <vector>

#include "flutter/fml/macros.h"
#include "impeller/core/shader_types.h"
#include "impeller/renderer/backend/gles/gles.h"
#include "impeller/renderer/backend/gles/proc_table_gles.h"
Expand Down Expand Up @@ -38,8 +37,12 @@ class BufferBindingsGLES {

bool BindUniformData(const ProcTableGLES& gl,
Allocator& transients_allocator,
const Bindings& vertex_bindings,
const Bindings& fragment_bindings);
const std::vector<BoundBuffer>& bound_buffers,
size_t buffer_offset,
size_t buffer_length,
const std::vector<BoundTexture>& bound_textures,
size_t texture_offset,
size_t texture_length);

bool UnbindVertexAttributes(const ProcTableGLES& gl) const;

Expand Down Expand Up @@ -71,10 +74,13 @@ class BufferBindingsGLES {
Allocator& transients_allocator,
const BufferResource& buffer);

std::optional<size_t> BindTextures(const ProcTableGLES& gl,
const Bindings& bindings,
ShaderStage stage,
size_t unit_start_index = 0);
std::optional<size_t> BindTextures(
const ProcTableGLES& gl,
const std::vector<BoundTexture>& bound_textures,
size_t offset,
size_t length,
ShaderStage stage,
size_t unit_start_index = 0);

BufferBindingsGLES(const BufferBindingsGLES&) = delete;

Expand Down
25 changes: 16 additions & 9 deletions impeller/renderer/backend/gles/render_pass_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
#include "fml/closure.h"
#include "fml/logging.h"
#include "impeller/base/validation.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/renderer/backend/gles/context_gles.h"
#include "impeller/renderer/backend/gles/device_buffer_gles.h"
#include "impeller/renderer/backend/gles/formats_gles.h"
#include "impeller/renderer/backend/gles/gpu_tracer_gles.h"
#include "impeller/renderer/backend/gles/pipeline_gles.h"
#include "impeller/renderer/backend/gles/texture_gles.h"
#include "impeller/renderer/command.h"
#include "impeller/renderer/render_pass.h"

namespace impeller {

Expand Down Expand Up @@ -148,7 +149,9 @@ struct RenderPassData {
const RenderPassData& pass_data,
const std::shared_ptr<Allocator>& transients_allocator,
const ReactorGLES& reactor,
const std::vector<Command>& commands,
const std::vector<BoundCommand>& commands,
const std::vector<BoundBuffer>& bound_buffers,
const std::vector<BoundTexture>& bound_textures,
const std::shared_ptr<GPUTracerGLES>& tracer) {
TRACE_EVENT0("impeller", "RenderPassGLES::EncodeCommandsInReactor");

Expand Down Expand Up @@ -418,11 +421,14 @@ struct RenderPassData {
//--------------------------------------------------------------------------
/// Bind uniform data.
///
if (!vertex_desc_gles->BindUniformData(gl, //
*transients_allocator, //
command.vertex_bindings, //
command.fragment_bindings //
)) {
if (!vertex_desc_gles->BindUniformData(
gl, //
*transients_allocator, //
bound_buffers, //
command.buffer_offset, command.buffer_length, bound_textures,
command.texture_offset,
command.texture_length //
)) {
return false;
}

Expand Down Expand Up @@ -581,8 +587,9 @@ bool RenderPassGLES::OnEncodeCommands(const Context& context) const {
allocator = context.GetResourceAllocator(),
render_pass = std::move(shared_this),
tracer](const auto& reactor) {
auto result = EncodeCommandsInReactor(*pass_data, allocator, reactor,
render_pass->commands_, tracer);
auto result = EncodeCommandsInReactor(
*pass_data, allocator, reactor, render_pass->commands_,
render_pass->bound_buffers_, render_pass->bound_textures_, tracer);
FML_CHECK(result) << "Must be able to encode GL commands without error.";
});
}
Expand Down
1 change: 0 additions & 1 deletion impeller/renderer/backend/gles/render_pass_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include <memory>

#include "flutter/fml/macros.h"
#include "flutter/impeller/renderer/backend/gles/reactor_gles.h"
#include "flutter/impeller/renderer/render_pass.h"

Expand Down
11 changes: 7 additions & 4 deletions impeller/renderer/backend/metal/compute_pass_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ static bool Bind(ComputePassBindingsCache& pass,
ComputePassBindingsCache pass_bindings(encoder);

fml::closure pop_debug_marker = [encoder]() { [encoder popDebugGroup]; };
for (const ComputeCommand& command : commands_) {
for (const BoundComputeCommand& command : commands_) {
#ifdef IMPELLER_DEBUG
fml::ScopedCleanupClosure auto_pop_debug_marker(pop_debug_marker);
if (!command.label.empty()) {
Expand All @@ -224,14 +224,17 @@ static bool Bind(ComputePassBindingsCache& pass,
ComputePipelineMTL::Cast(*command.pipeline)
.GetMTLComputePipelineState());

for (const BufferAndUniformSlot& buffer : command.bindings.buffers) {
for (auto i = command.buffer_offset;
i < command.buffer_offset + command.buffer_length; i++) {
const BoundBuffer& buffer = bound_buffers_[i];
if (!Bind(pass_bindings, *allocator, buffer.slot.ext_res_0,
buffer.view.resource)) {
return false;
}
}

for (const TextureAndSampler& data : command.bindings.sampled_images) {
for (auto i = command.texture_offset;
i < command.texture_offset + command.texture_length; i++) {
const BoundTexture& data = bound_textures_[i];
if (!Bind(pass_bindings, data.slot.texture_index, *data.sampler,
*data.texture.resource)) {
return false;
Expand Down
38 changes: 15 additions & 23 deletions impeller/renderer/backend/metal/render_pass_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -406,24 +406,6 @@ static bool Bind(PassBindingsCache& pass,
bool RenderPassMTL::EncodeCommands(const std::shared_ptr<Allocator>& allocator,
id<MTLRenderCommandEncoder> encoder) const {
PassBindingsCache pass_bindings(encoder);
auto bind_stage_resources = [&allocator, &pass_bindings](
const Bindings& bindings,
ShaderStage stage) -> bool {
for (const BufferAndUniformSlot& buffer : bindings.buffers) {
if (!Bind(pass_bindings, *allocator, stage, buffer.slot.ext_res_0,
buffer.view.resource)) {
return false;
}
}
for (const TextureAndSampler& data : bindings.sampled_images) {
if (!Bind(pass_bindings, stage, data.slot.texture_index, *data.sampler,
*data.texture.resource)) {
return false;
}
}
return true;
};

const auto target_sample_count = render_target_.GetSampleCount();

fml::closure pop_debug_marker = [encoder]() { [encoder popDebugGroup]; };
Expand Down Expand Up @@ -472,12 +454,22 @@ static bool Bind(PassBindingsCache& pass,
return false;
}

if (!bind_stage_resources(command.vertex_bindings, ShaderStage::kVertex)) {
return false;
for (auto i = command.buffer_offset;
i < command.buffer_offset + command.buffer_length; i++) {
const BoundBuffer& data = bound_buffers_[i];
if (!Bind(pass_bindings, *allocator, data.stage, data.slot.ext_res_0,
data.view.resource)) {
return false;
}
}
if (!bind_stage_resources(command.fragment_bindings,
ShaderStage::kFragment)) {
return false;

for (auto i = command.texture_offset;
i < command.texture_offset + command.texture_length; i++) {
const BoundTexture& data = bound_textures_[i];
if (!Bind(pass_bindings, data.stage, data.slot.texture_index,
*data.sampler, *data.texture.resource)) {
return false;
}
}

const PrimitiveType primitive_type = pipeline_desc.GetPrimitiveType();
Expand Down
Loading