[Impeller] store GLES bindings on render pass w/ offsets instead of per-command. (flutter/engine#56910)
To reduce heap fragmentation from tons of little vectors.
This commit is contained in:
parent
4453a2b85b
commit
7b1b6d13f2
@ -229,8 +229,6 @@ impeller_component("entity_test_helpers") {
|
|||||||
testonly = true
|
testonly = true
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
"contents/test/contents_test_helpers.cc",
|
|
||||||
"contents/test/contents_test_helpers.h",
|
|
||||||
"contents/test/recording_render_pass.cc",
|
"contents/test/recording_render_pass.cc",
|
||||||
"contents/test/recording_render_pass.h",
|
"contents/test/recording_render_pass.h",
|
||||||
]
|
]
|
||||||
|
@ -24,6 +24,38 @@
|
|||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr char kPaddingType = 0;
|
||||||
|
constexpr char kFloatType = 1;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// static
|
||||||
|
BufferView RuntimeEffectContents::EmplaceVulkanUniform(
|
||||||
|
const std::shared_ptr<const std::vector<uint8_t>>& input_data,
|
||||||
|
HostBuffer& host_buffer,
|
||||||
|
const RuntimeUniformDescription& uniform) {
|
||||||
|
// TODO(jonahwilliams): rewrite this to emplace directly into
|
||||||
|
// HostBuffer.
|
||||||
|
std::vector<float> uniform_buffer;
|
||||||
|
uniform_buffer.reserve(uniform.struct_layout.size());
|
||||||
|
size_t uniform_byte_index = 0u;
|
||||||
|
for (char byte_type : uniform.struct_layout) {
|
||||||
|
if (byte_type == kPaddingType) {
|
||||||
|
uniform_buffer.push_back(0.f);
|
||||||
|
} else {
|
||||||
|
FML_DCHECK(byte_type == kFloatType);
|
||||||
|
uniform_buffer.push_back(reinterpret_cast<const float*>(
|
||||||
|
input_data->data())[uniform_byte_index++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t alignment = std::max(sizeof(float) * uniform_buffer.size(),
|
||||||
|
DefaultUniformAlignment());
|
||||||
|
|
||||||
|
return host_buffer.Emplace(
|
||||||
|
reinterpret_cast<const void*>(uniform_buffer.data()),
|
||||||
|
sizeof(float) * uniform_buffer.size(), alignment);
|
||||||
|
}
|
||||||
|
|
||||||
void RuntimeEffectContents::SetRuntimeStage(
|
void RuntimeEffectContents::SetRuntimeStage(
|
||||||
std::shared_ptr<RuntimeStage> runtime_stage) {
|
std::shared_ptr<RuntimeStage> runtime_stage) {
|
||||||
runtime_stage_ = std::move(runtime_stage);
|
runtime_stage_ = std::move(runtime_stage);
|
||||||
@ -251,30 +283,11 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
|
|||||||
uniform_slot.binding = uniform.location;
|
uniform_slot.binding = uniform.location;
|
||||||
uniform_slot.name = uniform.name.c_str();
|
uniform_slot.name = uniform.name.c_str();
|
||||||
|
|
||||||
// TODO(jonahwilliams): rewrite this to emplace directly into
|
pass.BindResource(
|
||||||
// HostBuffer.
|
ShaderStage::kFragment, DescriptorType::kUniformBuffer,
|
||||||
std::vector<float> uniform_buffer;
|
uniform_slot, nullptr,
|
||||||
uniform_buffer.reserve(uniform.struct_layout.size());
|
EmplaceVulkanUniform(uniform_data_,
|
||||||
size_t uniform_byte_index = 0u;
|
renderer.GetTransientsBuffer(), uniform));
|
||||||
for (const auto& byte_type : uniform.struct_layout) {
|
|
||||||
if (byte_type == 0) {
|
|
||||||
uniform_buffer.push_back(0.f);
|
|
||||||
} else if (byte_type == 1) {
|
|
||||||
uniform_buffer.push_back(reinterpret_cast<float*>(
|
|
||||||
uniform_data_->data())[uniform_byte_index++]);
|
|
||||||
} else {
|
|
||||||
FML_UNREACHABLE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
size_t alignment = std::max(sizeof(float) * uniform_buffer.size(),
|
|
||||||
DefaultUniformAlignment());
|
|
||||||
|
|
||||||
BufferView buffer_view = renderer.GetTransientsBuffer().Emplace(
|
|
||||||
reinterpret_cast<const void*>(uniform_buffer.data()),
|
|
||||||
sizeof(float) * uniform_buffer.size(), alignment);
|
|
||||||
pass.BindResource(ShaderStage::kFragment,
|
|
||||||
DescriptorType::kUniformBuffer, uniform_slot,
|
|
||||||
nullptr, std::move(buffer_view));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "impeller/core/host_buffer.h"
|
||||||
#include "impeller/core/sampler_descriptor.h"
|
#include "impeller/core/sampler_descriptor.h"
|
||||||
#include "impeller/entity/contents/color_source_contents.h"
|
#include "impeller/entity/contents/color_source_contents.h"
|
||||||
#include "impeller/runtime_stage/runtime_stage.h"
|
#include "impeller/runtime_stage/runtime_stage.h"
|
||||||
@ -35,6 +36,12 @@ class RuntimeEffectContents final : public ColorSourceContents {
|
|||||||
/// Load the runtime effect and ensure a default PSO is initialized.
|
/// Load the runtime effect and ensure a default PSO is initialized.
|
||||||
bool BootstrapShader(const ContentContext& renderer) const;
|
bool BootstrapShader(const ContentContext& renderer) const;
|
||||||
|
|
||||||
|
// Visible for testing
|
||||||
|
static BufferView EmplaceVulkanUniform(
|
||||||
|
const std::shared_ptr<const std::vector<uint8_t>>& input_data,
|
||||||
|
HostBuffer& host_buffer,
|
||||||
|
const RuntimeUniformDescription& uniform);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool RegisterShader(const ContentContext& renderer) const;
|
bool RegisterShader(const ContentContext& renderer) const;
|
||||||
|
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "impeller/entity/contents/test/contents_test_helpers.h"
|
|
||||||
|
|
||||||
namespace impeller::testing {
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
} // namespace impeller::testing
|
|
@ -1,49 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#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"
|
|
||||||
|
|
||||||
namespace impeller::testing {
|
|
||||||
|
|
||||||
/// @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;
|
|
||||||
});
|
|
||||||
if (resource == command.vertex_bindings.buffers.end()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto data = (resource->view.resource.buffer->OnGetContents() +
|
|
||||||
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 ||
|
|
||||||
data.slot.binding == 64;
|
|
||||||
});
|
|
||||||
if (resource == command.fragment_bindings.buffers.end()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto data = (resource->view.resource.buffer->OnGetContents() +
|
|
||||||
resource->view.resource.range.offset);
|
|
||||||
return reinterpret_cast<typename T::FragInfo*>(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace impeller::testing
|
|
||||||
|
|
||||||
#endif // FLUTTER_IMPELLER_ENTITY_CONTENTS_TEST_CONTENTS_TEST_HELPERS_H_
|
|
@ -110,7 +110,6 @@ bool RecordingRenderPass::BindResource(ShaderStage stage,
|
|||||||
const ShaderUniformSlot& slot,
|
const ShaderUniformSlot& slot,
|
||||||
const ShaderMetadata* metadata,
|
const ShaderMetadata* metadata,
|
||||||
BufferView view) {
|
BufferView view) {
|
||||||
pending_.BindResource(stage, type, slot, metadata, view);
|
|
||||||
if (delegate_) {
|
if (delegate_) {
|
||||||
return delegate_->BindResource(stage, type, slot, metadata, view);
|
return delegate_->BindResource(stage, type, slot, metadata, view);
|
||||||
}
|
}
|
||||||
@ -124,7 +123,6 @@ bool RecordingRenderPass::BindDynamicResource(
|
|||||||
const ShaderUniformSlot& slot,
|
const ShaderUniformSlot& slot,
|
||||||
std::unique_ptr<ShaderMetadata> metadata,
|
std::unique_ptr<ShaderMetadata> metadata,
|
||||||
BufferView view) {
|
BufferView view) {
|
||||||
pending_.BindResource(stage, type, slot, metadata.get(), view);
|
|
||||||
if (delegate_) {
|
if (delegate_) {
|
||||||
return delegate_->BindDynamicResource(stage, type, slot,
|
return delegate_->BindDynamicResource(stage, type, slot,
|
||||||
std::move(metadata), view);
|
std::move(metadata), view);
|
||||||
@ -140,7 +138,6 @@ bool RecordingRenderPass::BindDynamicResource(
|
|||||||
std::unique_ptr<ShaderMetadata> metadata,
|
std::unique_ptr<ShaderMetadata> metadata,
|
||||||
std::shared_ptr<const Texture> texture,
|
std::shared_ptr<const Texture> texture,
|
||||||
const std::unique_ptr<const Sampler>& sampler) {
|
const std::unique_ptr<const Sampler>& sampler) {
|
||||||
pending_.BindResource(stage, type, slot, metadata.get(), texture, sampler);
|
|
||||||
if (delegate_) {
|
if (delegate_) {
|
||||||
return delegate_->BindDynamicResource(
|
return delegate_->BindDynamicResource(
|
||||||
stage, type, slot, std::move(metadata), texture, sampler);
|
stage, type, slot, std::move(metadata), texture, sampler);
|
||||||
@ -155,7 +152,6 @@ bool RecordingRenderPass::BindResource(
|
|||||||
const ShaderMetadata* metadata,
|
const ShaderMetadata* metadata,
|
||||||
std::shared_ptr<const Texture> texture,
|
std::shared_ptr<const Texture> texture,
|
||||||
const std::unique_ptr<const Sampler>& sampler) {
|
const std::unique_ptr<const Sampler>& sampler) {
|
||||||
pending_.BindResource(stage, type, slot, metadata, texture, sampler);
|
|
||||||
if (delegate_) {
|
if (delegate_) {
|
||||||
return delegate_->BindResource(stage, type, slot, metadata, texture,
|
return delegate_->BindResource(stage, type, slot, metadata, texture,
|
||||||
sampler);
|
sampler);
|
||||||
|
@ -1843,27 +1843,16 @@ TEST_P(EntityTest, RuntimeEffectSetsRightSizeWhenUniformIsStruct) {
|
|||||||
auto uniform_data = std::make_shared<std::vector<uint8_t>>();
|
auto uniform_data = std::make_shared<std::vector<uint8_t>>();
|
||||||
uniform_data->resize(sizeof(FragUniforms));
|
uniform_data->resize(sizeof(FragUniforms));
|
||||||
memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
|
memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
|
||||||
contents->SetUniformData(uniform_data);
|
|
||||||
|
|
||||||
Entity entity;
|
auto buffer_view = RuntimeEffectContents::EmplaceVulkanUniform(
|
||||||
entity.SetContents(contents);
|
uniform_data, GetContentContext()->GetTransientsBuffer(),
|
||||||
|
runtime_stage->GetUniforms()[0]);
|
||||||
|
|
||||||
auto context = GetContentContext();
|
|
||||||
RenderTarget target = context->GetRenderTargetCache()->CreateOffscreen(
|
|
||||||
*context->GetContext(), {1, 1}, 1u);
|
|
||||||
|
|
||||||
testing::MockRenderPass pass(GetContext(), target);
|
|
||||||
ASSERT_TRUE(contents->Render(*context, entity, pass));
|
|
||||||
ASSERT_EQ(pass.GetCommands().size(), 1u);
|
|
||||||
const auto& command = pass.GetCommands()[0];
|
|
||||||
ASSERT_EQ(command.fragment_bindings.buffers.size(), 1u);
|
|
||||||
// 16 bytes:
|
// 16 bytes:
|
||||||
// 8 bytes for iResolution
|
// 8 bytes for iResolution
|
||||||
// 4 bytes for iTime
|
// 4 bytes for iTime
|
||||||
// 4 bytes padding
|
// 4 bytes padding
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(buffer_view.GetRange().length, 16u);
|
||||||
command.fragment_bindings.buffers[0].view.resource.GetRange().length,
|
|
||||||
16u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(EntityTest, ColorFilterWithForegroundColorAdvancedBlend) {
|
TEST_P(EntityTest, ColorFilterWithForegroundColorAdvancedBlend) {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "impeller/renderer/backend/gles/formats_gles.h"
|
#include "impeller/renderer/backend/gles/formats_gles.h"
|
||||||
#include "impeller/renderer/backend/gles/sampler_gles.h"
|
#include "impeller/renderer/backend/gles/sampler_gles.h"
|
||||||
#include "impeller/renderer/backend/gles/texture_gles.h"
|
#include "impeller/renderer/backend/gles/texture_gles.h"
|
||||||
|
#include "impeller/renderer/command.h"
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
@ -179,27 +180,23 @@ bool BufferBindingsGLES::BindVertexAttributes(const ProcTableGLES& gl,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferBindingsGLES::BindUniformData(const ProcTableGLES& gl,
|
bool BufferBindingsGLES::BindUniformData(
|
||||||
const Bindings& vertex_bindings,
|
const ProcTableGLES& gl,
|
||||||
const Bindings& fragment_bindings) {
|
const std::vector<TextureAndSampler>& bound_textures,
|
||||||
for (const auto& buffer : vertex_bindings.buffers) {
|
const std::vector<BufferResource>& bound_buffers,
|
||||||
if (!BindUniformBuffer(gl, buffer.view)) {
|
Range texture_range,
|
||||||
|
Range buffer_range) {
|
||||||
|
for (auto i = 0u; i < buffer_range.length; i++) {
|
||||||
|
if (!BindUniformBuffer(gl, bound_buffers[buffer_range.offset + i])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& buffer : fragment_bindings.buffers) {
|
|
||||||
if (!BindUniformBuffer(gl, buffer.view)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<size_t> next_unit_index =
|
std::optional<size_t> next_unit_index =
|
||||||
BindTextures(gl, vertex_bindings, ShaderStage::kVertex);
|
BindTextures(gl, bound_textures, texture_range, ShaderStage::kVertex);
|
||||||
if (!next_unit_index.has_value()) {
|
if (!next_unit_index.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!BindTextures(gl, bound_textures, texture_range, ShaderStage::kFragment,
|
||||||
if (!BindTextures(gl, fragment_bindings, ShaderStage::kFragment,
|
|
||||||
*next_unit_index)
|
*next_unit_index)
|
||||||
.has_value()) {
|
.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
@ -389,11 +386,16 @@ bool BufferBindingsGLES::BindUniformBuffer(const ProcTableGLES& gl,
|
|||||||
|
|
||||||
std::optional<size_t> BufferBindingsGLES::BindTextures(
|
std::optional<size_t> BufferBindingsGLES::BindTextures(
|
||||||
const ProcTableGLES& gl,
|
const ProcTableGLES& gl,
|
||||||
const Bindings& bindings,
|
const std::vector<TextureAndSampler>& bound_textures,
|
||||||
|
Range texture_range,
|
||||||
ShaderStage stage,
|
ShaderStage stage,
|
||||||
size_t unit_start_index) {
|
size_t unit_start_index) {
|
||||||
size_t active_index = unit_start_index;
|
size_t active_index = unit_start_index;
|
||||||
for (const auto& data : bindings.sampled_images) {
|
for (auto i = 0u; i < texture_range.length; i++) {
|
||||||
|
const TextureAndSampler& data = bound_textures[texture_range.offset + i];
|
||||||
|
if (data.stage != stage) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const auto& texture_gles = TextureGLES::Cast(*data.texture.resource);
|
const auto& texture_gles = TextureGLES::Cast(*data.texture.resource);
|
||||||
if (data.texture.GetMetadata() == nullptr) {
|
if (data.texture.GetMetadata() == nullptr) {
|
||||||
VALIDATION_LOG << "No metadata found for texture binding.";
|
VALIDATION_LOG << "No metadata found for texture binding.";
|
||||||
|
@ -42,8 +42,10 @@ class BufferBindingsGLES {
|
|||||||
size_t vertex_offset);
|
size_t vertex_offset);
|
||||||
|
|
||||||
bool BindUniformData(const ProcTableGLES& gl,
|
bool BindUniformData(const ProcTableGLES& gl,
|
||||||
const Bindings& vertex_bindings,
|
const std::vector<TextureAndSampler>& bound_textures,
|
||||||
const Bindings& fragment_bindings);
|
const std::vector<BufferResource>& bound_buffers,
|
||||||
|
Range texture_range,
|
||||||
|
Range buffer_range);
|
||||||
|
|
||||||
bool UnbindVertexAttributes(const ProcTableGLES& gl);
|
bool UnbindVertexAttributes(const ProcTableGLES& gl);
|
||||||
|
|
||||||
@ -75,10 +77,12 @@ class BufferBindingsGLES {
|
|||||||
|
|
||||||
bool BindUniformBuffer(const ProcTableGLES& gl, const BufferResource& buffer);
|
bool BindUniformBuffer(const ProcTableGLES& gl, const BufferResource& buffer);
|
||||||
|
|
||||||
std::optional<size_t> BindTextures(const ProcTableGLES& gl,
|
std::optional<size_t> BindTextures(
|
||||||
const Bindings& bindings,
|
const ProcTableGLES& gl,
|
||||||
ShaderStage stage,
|
const std::vector<TextureAndSampler>& bound_textures,
|
||||||
size_t unit_start_index = 0);
|
Range texture_range,
|
||||||
|
ShaderStage stage,
|
||||||
|
size_t unit_start_index = 0);
|
||||||
|
|
||||||
BufferBindingsGLES(const BufferBindingsGLES&) = delete;
|
BufferBindingsGLES(const BufferBindingsGLES&) = delete;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "impeller/renderer/backend/gles/buffer_bindings_gles.h"
|
#include "impeller/renderer/backend/gles/buffer_bindings_gles.h"
|
||||||
#include "impeller/renderer/backend/gles/device_buffer_gles.h"
|
#include "impeller/renderer/backend/gles/device_buffer_gles.h"
|
||||||
#include "impeller/renderer/backend/gles/test/mock_gles.h"
|
#include "impeller/renderer/backend/gles/test/mock_gles.h"
|
||||||
#include "impeller/renderer/testing/mocks.h"
|
#include "impeller/renderer/command.h"
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@ -18,7 +18,8 @@ TEST(BufferBindingsGLESTest, BindUniformData) {
|
|||||||
uniform_bindings["SHADERMETADATA.FOOBAR"] = 1;
|
uniform_bindings["SHADERMETADATA.FOOBAR"] = 1;
|
||||||
bindings.SetUniformBindings(std::move(uniform_bindings));
|
bindings.SetUniformBindings(std::move(uniform_bindings));
|
||||||
std::shared_ptr<MockGLES> mock_gl = MockGLES::Init();
|
std::shared_ptr<MockGLES> mock_gl = MockGLES::Init();
|
||||||
Bindings vertex_bindings;
|
std::vector<BufferResource> bound_buffers;
|
||||||
|
std::vector<TextureAndSampler> bound_textures;
|
||||||
|
|
||||||
ShaderMetadata shader_metadata = {
|
ShaderMetadata shader_metadata = {
|
||||||
.name = "shader_metadata",
|
.name = "shader_metadata",
|
||||||
@ -33,14 +34,11 @@ TEST(BufferBindingsGLESTest, BindUniformData) {
|
|||||||
DeviceBufferGLES device_buffer(DeviceBufferDescriptor{.size = sizeof(float)},
|
DeviceBufferGLES device_buffer(DeviceBufferDescriptor{.size = sizeof(float)},
|
||||||
reactor, backing_store);
|
reactor, backing_store);
|
||||||
BufferView buffer_view(&device_buffer, Range(0, sizeof(float)));
|
BufferView buffer_view(&device_buffer, Range(0, sizeof(float)));
|
||||||
vertex_bindings.buffers.push_back(BufferAndUniformSlot{
|
bound_buffers.push_back(BufferResource(&shader_metadata, buffer_view));
|
||||||
.slot =
|
|
||||||
ShaderUniformSlot{
|
EXPECT_TRUE(bindings.BindUniformData(mock_gl->GetProcTable(), bound_textures,
|
||||||
.name = "foobar", .ext_res_0 = 0, .set = 0, .binding = 0},
|
bound_buffers, Range{0, 0},
|
||||||
.view = BufferResource(&shader_metadata, buffer_view)});
|
Range{0, 1}));
|
||||||
Bindings fragment_bindings;
|
|
||||||
EXPECT_TRUE(bindings.BindUniformData(mock_gl->GetProcTable(), vertex_bindings,
|
|
||||||
fragment_bindings));
|
|
||||||
std::vector<std::string> captured_calls = mock_gl->GetCapturedCalls();
|
std::vector<std::string> captured_calls = mock_gl->GetCapturedCalls();
|
||||||
EXPECT_TRUE(std::find(captured_calls.begin(), captured_calls.end(),
|
EXPECT_TRUE(std::find(captured_calls.begin(), captured_calls.end(),
|
||||||
"glUniform1fv") != captured_calls.end());
|
"glUniform1fv") != captured_calls.end());
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "impeller/renderer/backend/gles/gpu_tracer_gles.h"
|
#include "impeller/renderer/backend/gles/gpu_tracer_gles.h"
|
||||||
#include "impeller/renderer/backend/gles/pipeline_gles.h"
|
#include "impeller/renderer/backend/gles/pipeline_gles.h"
|
||||||
#include "impeller/renderer/backend/gles/texture_gles.h"
|
#include "impeller/renderer/backend/gles/texture_gles.h"
|
||||||
|
#include "impeller/renderer/command.h"
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
@ -188,9 +189,10 @@ void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
|
|||||||
|
|
||||||
[[nodiscard]] bool EncodeCommandsInReactor(
|
[[nodiscard]] bool EncodeCommandsInReactor(
|
||||||
const RenderPassData& pass_data,
|
const RenderPassData& pass_data,
|
||||||
const std::shared_ptr<Allocator>& transients_allocator,
|
|
||||||
const ReactorGLES& reactor,
|
const ReactorGLES& reactor,
|
||||||
const std::vector<Command>& commands,
|
const std::vector<Command>& commands,
|
||||||
|
const std::vector<TextureAndSampler>& bound_textures,
|
||||||
|
const std::vector<BufferResource>& bound_buffers,
|
||||||
const std::shared_ptr<GPUTracerGLES>& tracer) {
|
const std::shared_ptr<GPUTracerGLES>& tracer) {
|
||||||
TRACE_EVENT0("impeller", "RenderPassGLES::EncodeCommandsInReactor");
|
TRACE_EVENT0("impeller", "RenderPassGLES::EncodeCommandsInReactor");
|
||||||
|
|
||||||
@ -456,10 +458,13 @@ void RenderPassGLES::ResetGLState(const ProcTableGLES& gl) {
|
|||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
/// Bind uniform data.
|
/// Bind uniform data.
|
||||||
///
|
///
|
||||||
if (!vertex_desc_gles->BindUniformData(gl, //
|
if (!vertex_desc_gles->BindUniformData(
|
||||||
command.vertex_bindings, //
|
gl, //
|
||||||
command.fragment_bindings //
|
bound_textures, //
|
||||||
)) {
|
bound_buffers, //
|
||||||
|
/*texture_range=*/command.bound_textures, //
|
||||||
|
/*buffer_range=*/command.bound_buffers //
|
||||||
|
)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,13 +607,18 @@ bool RenderPassGLES::OnEncodeCommands(const Context& context) const {
|
|||||||
CanDiscardAttachmentWhenDone(stencil0->store_action);
|
CanDiscardAttachmentWhenDone(stencil0->store_action);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const RenderPassGLES> shared_this = shared_from_this();
|
|
||||||
auto tracer = ContextGLES::Cast(context).GetGPUTracer();
|
|
||||||
return reactor_->AddOperation(
|
return reactor_->AddOperation(
|
||||||
[pass_data, allocator = context.GetResourceAllocator(),
|
[pass_data = std::move(pass_data), render_pass = shared_from_this(),
|
||||||
render_pass = std::move(shared_this), tracer](const auto& reactor) {
|
tracer =
|
||||||
auto result = EncodeCommandsInReactor(*pass_data, allocator, reactor,
|
ContextGLES::Cast(context).GetGPUTracer()](const auto& reactor) {
|
||||||
render_pass->commands_, tracer);
|
auto result = EncodeCommandsInReactor(
|
||||||
|
/*pass_data=*/*pass_data, //
|
||||||
|
/*reactor=*/reactor, //
|
||||||
|
/*commands=*/render_pass->commands_, //
|
||||||
|
/*bound_textures=*/render_pass->bound_textures_, //
|
||||||
|
/*bound_buffers=*/render_pass->bound_buffers_, //
|
||||||
|
/*tracer=*/tracer //
|
||||||
|
);
|
||||||
FML_CHECK(result)
|
FML_CHECK(result)
|
||||||
<< "Must be able to encode GL commands without error.";
|
<< "Must be able to encode GL commands without error.";
|
||||||
},
|
},
|
||||||
|
@ -48,9 +48,6 @@ class RenderPassMTL final : public RenderPass {
|
|||||||
const RenderTarget& target,
|
const RenderTarget& target,
|
||||||
id<MTLCommandBuffer> buffer);
|
id<MTLCommandBuffer> buffer);
|
||||||
|
|
||||||
// |RenderPass|
|
|
||||||
void ReserveCommands(size_t command_count) override {}
|
|
||||||
|
|
||||||
// |RenderPass|
|
// |RenderPass|
|
||||||
bool IsValid() const override;
|
bool IsValid() const override;
|
||||||
|
|
||||||
|
@ -92,9 +92,6 @@ class RenderPassVK final : public RenderPass {
|
|||||||
// |RenderPass|
|
// |RenderPass|
|
||||||
fml::Status Draw() override;
|
fml::Status Draw() override;
|
||||||
|
|
||||||
// |RenderPass|
|
|
||||||
void ReserveCommands(size_t command_count) override {}
|
|
||||||
|
|
||||||
// |ResourceBinder|
|
// |ResourceBinder|
|
||||||
bool BindResource(ShaderStage stage,
|
bool BindResource(ShaderStage stage,
|
||||||
DescriptorType type,
|
DescriptorType type,
|
||||||
|
@ -4,11 +4,8 @@
|
|||||||
|
|
||||||
#include "impeller/renderer/command.h"
|
#include "impeller/renderer/command.h"
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "impeller/base/validation.h"
|
#include "impeller/base/validation.h"
|
||||||
#include "impeller/core/formats.h"
|
#include "impeller/core/formats.h"
|
||||||
#include "impeller/renderer/vertex_descriptor.h"
|
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
@ -26,112 +23,4 @@ bool Command::BindVertices(const VertexBuffer& buffer) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Command::BindResource(ShaderStage stage,
|
|
||||||
DescriptorType type,
|
|
||||||
const ShaderUniformSlot& slot,
|
|
||||||
const ShaderMetadata* metadata,
|
|
||||||
BufferView view) {
|
|
||||||
FML_DCHECK(slot.ext_res_0 != VertexDescriptor::kReservedVertexBufferIndex);
|
|
||||||
if (!view) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
BufferResource resouce = BufferResource(metadata, std::move(view));
|
|
||||||
return BindBuffer(stage, slot, std::move(resouce));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Command::BindDynamicResource(ShaderStage stage,
|
|
||||||
DescriptorType type,
|
|
||||||
const ShaderUniformSlot& slot,
|
|
||||||
std::unique_ptr<ShaderMetadata> metadata,
|
|
||||||
BufferView view) {
|
|
||||||
FML_DCHECK(slot.ext_res_0 != VertexDescriptor::kReservedVertexBufferIndex);
|
|
||||||
if (!view) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
BufferResource resouce =
|
|
||||||
BufferResource::MakeDynamic(std::move(metadata), std::move(view));
|
|
||||||
|
|
||||||
return BindBuffer(stage, slot, std::move(resouce));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Command::BindResource(ShaderStage stage,
|
|
||||||
DescriptorType type,
|
|
||||||
const SampledImageSlot& slot,
|
|
||||||
const ShaderMetadata* metadata,
|
|
||||||
std::shared_ptr<const Texture> texture,
|
|
||||||
const std::unique_ptr<const Sampler>& sampler) {
|
|
||||||
if (!sampler) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!texture || !texture->IsValid()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TextureResource resource = TextureResource(metadata, std::move(texture));
|
|
||||||
return BindTexture(stage, slot, std::move(resource), sampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Command::BindDynamicResource(
|
|
||||||
ShaderStage stage,
|
|
||||||
DescriptorType type,
|
|
||||||
const SampledImageSlot& slot,
|
|
||||||
std::unique_ptr<ShaderMetadata> metadata,
|
|
||||||
std::shared_ptr<const Texture> texture,
|
|
||||||
const std::unique_ptr<const Sampler>& sampler) {
|
|
||||||
if (!sampler) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!texture || !texture->IsValid()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TextureResource resource =
|
|
||||||
TextureResource::MakeDynamic(std::move(metadata), std::move(texture));
|
|
||||||
return BindTexture(stage, slot, std::move(resource), sampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Command::BindBuffer(ShaderStage stage,
|
|
||||||
const ShaderUniformSlot& slot,
|
|
||||||
BufferResource resource) {
|
|
||||||
BufferAndUniformSlot data =
|
|
||||||
BufferAndUniformSlot{.slot = slot, .view = std::move(resource)};
|
|
||||||
|
|
||||||
switch (stage) {
|
|
||||||
case ShaderStage::kVertex:
|
|
||||||
vertex_bindings.buffers.push_back(std::move(data));
|
|
||||||
return true;
|
|
||||||
case ShaderStage::kFragment:
|
|
||||||
fragment_bindings.buffers.push_back(std::move(data));
|
|
||||||
return true;
|
|
||||||
case ShaderStage::kCompute:
|
|
||||||
VALIDATION_LOG << "Use ComputeCommands for compute shader stages.";
|
|
||||||
case ShaderStage::kUnknown:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Command::BindTexture(ShaderStage stage,
|
|
||||||
const SampledImageSlot& slot,
|
|
||||||
TextureResource resource,
|
|
||||||
const std::unique_ptr<const Sampler>& sampler) {
|
|
||||||
TextureAndSampler data = TextureAndSampler{
|
|
||||||
.slot = slot,
|
|
||||||
.texture = std::move(resource),
|
|
||||||
.sampler = &sampler,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (stage) {
|
|
||||||
case ShaderStage::kVertex:
|
|
||||||
vertex_bindings.sampled_images.push_back(std::move(data));
|
|
||||||
return true;
|
|
||||||
case ShaderStage::kFragment:
|
|
||||||
fragment_bindings.sampled_images.push_back((std::move(data)));
|
|
||||||
return true;
|
|
||||||
case ShaderStage::kCompute:
|
|
||||||
VALIDATION_LOG << "Use ComputeCommands for compute shader stages.";
|
|
||||||
case ShaderStage::kUnknown:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "impeller/core/buffer_view.h"
|
#include "impeller/core/buffer_view.h"
|
||||||
#include "impeller/core/formats.h"
|
#include "impeller/core/formats.h"
|
||||||
#include "impeller/core/resource_binder.h"
|
|
||||||
#include "impeller/core/sampler.h"
|
#include "impeller/core/sampler.h"
|
||||||
#include "impeller/core/shader_types.h"
|
#include "impeller/core/shader_types.h"
|
||||||
#include "impeller/core/texture.h"
|
#include "impeller/core/texture.h"
|
||||||
@ -22,12 +21,6 @@
|
|||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
#ifdef IMPELLER_DEBUG
|
|
||||||
#define DEBUG_COMMAND_INFO(obj, arg) obj.label = arg;
|
|
||||||
#else
|
|
||||||
#define DEBUG_COMMAND_INFO(obj, arg)
|
|
||||||
#endif // IMPELLER_DEBUG
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class Resource {
|
class Resource {
|
||||||
public:
|
public:
|
||||||
@ -65,21 +58,11 @@ using TextureResource = Resource<std::shared_ptr<const Texture>>;
|
|||||||
/// @brief combines the texture, sampler and sampler slot information.
|
/// @brief combines the texture, sampler and sampler slot information.
|
||||||
struct TextureAndSampler {
|
struct TextureAndSampler {
|
||||||
SampledImageSlot slot;
|
SampledImageSlot slot;
|
||||||
|
ShaderStage stage;
|
||||||
TextureResource texture;
|
TextureResource texture;
|
||||||
const std::unique_ptr<const Sampler>* sampler;
|
const std::unique_ptr<const Sampler>* sampler;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief combines the buffer resource and its uniform slot information.
|
|
||||||
struct BufferAndUniformSlot {
|
|
||||||
ShaderUniformSlot slot;
|
|
||||||
BufferResource view;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Bindings {
|
|
||||||
std::vector<TextureAndSampler> sampled_images;
|
|
||||||
std::vector<BufferAndUniformSlot> buffers;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/// @brief An object used to specify work to the GPU along with references
|
/// @brief An object used to specify work to the GPU along with references
|
||||||
/// to resources the GPU will used when doing said work.
|
/// to resources the GPU will used when doing said work.
|
||||||
@ -94,21 +77,16 @@ struct Bindings {
|
|||||||
/// referenced in commands views into buffers managed by other
|
/// referenced in commands views into buffers managed by other
|
||||||
/// allocators and resource managers.
|
/// allocators and resource managers.
|
||||||
///
|
///
|
||||||
struct Command : public ResourceBinder {
|
struct Command {
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
/// The pipeline to use for this command.
|
/// The pipeline to use for this command.
|
||||||
///
|
///
|
||||||
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
|
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/// The buffer, texture, and sampler bindings used by the vertex pipeline
|
/// An offset into render pass storage where bound buffers/texture metadata is
|
||||||
/// stage.
|
/// stored.
|
||||||
///
|
Range bound_buffers = Range{0, 0};
|
||||||
Bindings vertex_bindings;
|
Range bound_textures = Range{0, 0};
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/// The buffer, texture, and sampler bindings used by the fragment pipeline
|
|
||||||
/// stage.
|
|
||||||
///
|
|
||||||
Bindings fragment_bindings;
|
|
||||||
|
|
||||||
#ifdef IMPELLER_DEBUG
|
#ifdef IMPELLER_DEBUG
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -184,45 +162,7 @@ struct Command : public ResourceBinder {
|
|||||||
///
|
///
|
||||||
bool BindVertices(const VertexBuffer& buffer);
|
bool BindVertices(const VertexBuffer& buffer);
|
||||||
|
|
||||||
// |ResourceBinder|
|
|
||||||
bool BindResource(ShaderStage stage,
|
|
||||||
DescriptorType type,
|
|
||||||
const ShaderUniformSlot& slot,
|
|
||||||
const ShaderMetadata* metadata,
|
|
||||||
BufferView view) override;
|
|
||||||
|
|
||||||
// |ResourceBinder|
|
|
||||||
bool BindResource(ShaderStage stage,
|
|
||||||
DescriptorType type,
|
|
||||||
const SampledImageSlot& slot,
|
|
||||||
const ShaderMetadata* metadata,
|
|
||||||
std::shared_ptr<const Texture> texture,
|
|
||||||
const std::unique_ptr<const Sampler>& sampler) override;
|
|
||||||
|
|
||||||
bool BindDynamicResource(ShaderStage stage,
|
|
||||||
DescriptorType type,
|
|
||||||
const ShaderUniformSlot& slot,
|
|
||||||
std::unique_ptr<ShaderMetadata> metadata,
|
|
||||||
BufferView view);
|
|
||||||
|
|
||||||
bool BindDynamicResource(ShaderStage stage,
|
|
||||||
DescriptorType type,
|
|
||||||
const SampledImageSlot& slot,
|
|
||||||
std::unique_ptr<ShaderMetadata> metadata,
|
|
||||||
std::shared_ptr<const Texture> texture,
|
|
||||||
const std::unique_ptr<const Sampler>& sampler);
|
|
||||||
|
|
||||||
bool IsValid() const { return pipeline && pipeline->IsValid(); }
|
bool IsValid() const { return pipeline && pipeline->IsValid(); }
|
||||||
|
|
||||||
private:
|
|
||||||
bool BindBuffer(ShaderStage stage,
|
|
||||||
const ShaderUniformSlot& slot,
|
|
||||||
BufferResource resource);
|
|
||||||
|
|
||||||
bool BindTexture(ShaderStage stage,
|
|
||||||
const SampledImageSlot& slot,
|
|
||||||
TextureResource resource,
|
|
||||||
const std::unique_ptr<const Sampler>& sampler);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -194,8 +194,12 @@ bool RenderPass::ValidateIndexBuffer(const BufferView& index_buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fml::Status RenderPass::Draw() {
|
fml::Status RenderPass::Draw() {
|
||||||
|
pending_.bound_buffers.offset = bound_buffers_start_.value_or(0u);
|
||||||
|
pending_.bound_textures.offset = bound_textures_start_.value_or(0u);
|
||||||
auto result = AddCommand(std::move(pending_));
|
auto result = AddCommand(std::move(pending_));
|
||||||
pending_ = Command{};
|
pending_ = Command{};
|
||||||
|
bound_textures_start_ = std::nullopt;
|
||||||
|
bound_buffers_start_ = std::nullopt;
|
||||||
if (result) {
|
if (result) {
|
||||||
return fml::Status();
|
return fml::Status();
|
||||||
}
|
}
|
||||||
@ -209,7 +213,12 @@ bool RenderPass::BindResource(ShaderStage stage,
|
|||||||
const ShaderUniformSlot& slot,
|
const ShaderUniformSlot& slot,
|
||||||
const ShaderMetadata* metadata,
|
const ShaderMetadata* metadata,
|
||||||
BufferView view) {
|
BufferView view) {
|
||||||
return pending_.BindResource(stage, type, slot, metadata, view);
|
FML_DCHECK(slot.ext_res_0 != VertexDescriptor::kReservedVertexBufferIndex);
|
||||||
|
if (!view) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
BufferResource resouce = BufferResource(metadata, std::move(view));
|
||||||
|
return BindBuffer(stage, slot, std::move(resouce));
|
||||||
}
|
}
|
||||||
|
|
||||||
// |ResourceBinder|
|
// |ResourceBinder|
|
||||||
@ -219,8 +228,14 @@ bool RenderPass::BindResource(ShaderStage stage,
|
|||||||
const ShaderMetadata* metadata,
|
const ShaderMetadata* metadata,
|
||||||
std::shared_ptr<const Texture> texture,
|
std::shared_ptr<const Texture> texture,
|
||||||
const std::unique_ptr<const Sampler>& sampler) {
|
const std::unique_ptr<const Sampler>& sampler) {
|
||||||
return pending_.BindResource(stage, type, slot, metadata, std::move(texture),
|
if (!sampler) {
|
||||||
sampler);
|
return false;
|
||||||
|
}
|
||||||
|
if (!texture || !texture->IsValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TextureResource resource = TextureResource(metadata, std::move(texture));
|
||||||
|
return BindTexture(stage, slot, std::move(resource), sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderPass::BindDynamicResource(ShaderStage stage,
|
bool RenderPass::BindDynamicResource(ShaderStage stage,
|
||||||
@ -228,8 +243,14 @@ bool RenderPass::BindDynamicResource(ShaderStage stage,
|
|||||||
const ShaderUniformSlot& slot,
|
const ShaderUniformSlot& slot,
|
||||||
std::unique_ptr<ShaderMetadata> metadata,
|
std::unique_ptr<ShaderMetadata> metadata,
|
||||||
BufferView view) {
|
BufferView view) {
|
||||||
return pending_.BindDynamicResource(stage, type, slot, std::move(metadata),
|
FML_DCHECK(slot.ext_res_0 != VertexDescriptor::kReservedVertexBufferIndex);
|
||||||
std::move(view));
|
if (!view) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
BufferResource resouce =
|
||||||
|
BufferResource::MakeDynamic(std::move(metadata), std::move(view));
|
||||||
|
|
||||||
|
return BindBuffer(stage, slot, std::move(resouce));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderPass::BindDynamicResource(
|
bool RenderPass::BindDynamicResource(
|
||||||
@ -239,8 +260,46 @@ bool RenderPass::BindDynamicResource(
|
|||||||
std::unique_ptr<ShaderMetadata> metadata,
|
std::unique_ptr<ShaderMetadata> metadata,
|
||||||
std::shared_ptr<const Texture> texture,
|
std::shared_ptr<const Texture> texture,
|
||||||
const std::unique_ptr<const Sampler>& sampler) {
|
const std::unique_ptr<const Sampler>& sampler) {
|
||||||
return pending_.BindDynamicResource(stage, type, slot, std::move(metadata),
|
if (!sampler) {
|
||||||
std::move(texture), sampler);
|
return false;
|
||||||
|
}
|
||||||
|
if (!texture || !texture->IsValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TextureResource resource =
|
||||||
|
TextureResource::MakeDynamic(std::move(metadata), std::move(texture));
|
||||||
|
return BindTexture(stage, slot, std::move(resource), sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderPass::BindBuffer(ShaderStage stage,
|
||||||
|
const ShaderUniformSlot& slot,
|
||||||
|
BufferResource resource) {
|
||||||
|
if (!bound_buffers_start_.has_value()) {
|
||||||
|
bound_buffers_start_ = bound_buffers_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
pending_.bound_buffers.length++;
|
||||||
|
bound_buffers_.push_back(std::move(resource));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderPass::BindTexture(ShaderStage stage,
|
||||||
|
const SampledImageSlot& slot,
|
||||||
|
TextureResource resource,
|
||||||
|
const std::unique_ptr<const Sampler>& sampler) {
|
||||||
|
TextureAndSampler data = TextureAndSampler{
|
||||||
|
.stage = stage,
|
||||||
|
.texture = std::move(resource),
|
||||||
|
.sampler = &sampler,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!bound_textures_start_.has_value()) {
|
||||||
|
bound_textures_start_ = bound_textures_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
pending_.bound_textures.length++;
|
||||||
|
bound_textures_.push_back(std::move(data));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -18,9 +18,6 @@
|
|||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
class HostBuffer;
|
|
||||||
class Allocator;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/// @brief Render passes encode render commands directed as one specific
|
/// @brief Render passes encode render commands directed as one specific
|
||||||
/// render target into an underlying command buffer.
|
/// render target into an underlying command buffer.
|
||||||
@ -46,13 +43,6 @@ class RenderPass : public ResourceBinder {
|
|||||||
|
|
||||||
void SetLabel(std::string_view label);
|
void SetLabel(std::string_view label);
|
||||||
|
|
||||||
/// @brief Reserve [command_count] commands in the HAL command buffer.
|
|
||||||
///
|
|
||||||
/// Note: this is not the native command buffer.
|
|
||||||
virtual void ReserveCommands(size_t command_count) {
|
|
||||||
commands_.reserve(command_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
/// The pipeline to use for this command.
|
/// The pipeline to use for this command.
|
||||||
virtual void SetPipeline(
|
virtual void SetPipeline(
|
||||||
@ -202,6 +192,7 @@ class RenderPass : public ResourceBinder {
|
|||||||
std::shared_ptr<const Texture> texture,
|
std::shared_ptr<const Texture> texture,
|
||||||
const std::unique_ptr<const Sampler>& sampler);
|
const std::unique_ptr<const Sampler>& sampler);
|
||||||
|
|
||||||
|
/// @brief Bind with dynamically generated shader metadata.
|
||||||
virtual bool BindDynamicResource(ShaderStage stage,
|
virtual bool BindDynamicResource(ShaderStage stage,
|
||||||
DescriptorType type,
|
DescriptorType type,
|
||||||
const ShaderUniformSlot& slot,
|
const ShaderUniformSlot& slot,
|
||||||
@ -253,6 +244,8 @@ class RenderPass : public ResourceBinder {
|
|||||||
const ISize render_target_size_;
|
const ISize render_target_size_;
|
||||||
const RenderTarget render_target_;
|
const RenderTarget render_target_;
|
||||||
std::vector<Command> commands_;
|
std::vector<Command> commands_;
|
||||||
|
std::vector<BufferResource> bound_buffers_;
|
||||||
|
std::vector<TextureAndSampler> bound_textures_;
|
||||||
const Matrix orthographic_;
|
const Matrix orthographic_;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -284,7 +277,18 @@ class RenderPass : public ResourceBinder {
|
|||||||
|
|
||||||
RenderPass& operator=(const RenderPass&) = delete;
|
RenderPass& operator=(const RenderPass&) = delete;
|
||||||
|
|
||||||
|
bool BindBuffer(ShaderStage stage,
|
||||||
|
const ShaderUniformSlot& slot,
|
||||||
|
BufferResource resource);
|
||||||
|
|
||||||
|
bool BindTexture(ShaderStage stage,
|
||||||
|
const SampledImageSlot& slot,
|
||||||
|
TextureResource resource,
|
||||||
|
const std::unique_ptr<const Sampler>& sampler);
|
||||||
|
|
||||||
Command pending_;
|
Command pending_;
|
||||||
|
std::optional<size_t> bound_buffers_start_ = std::nullopt;
|
||||||
|
std::optional<size_t> bound_textures_start_ = std::nullopt;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -417,7 +417,7 @@ static bool BindUniform(
|
|||||||
|
|
||||||
uniform_map->insert_or_assign(
|
uniform_map->insert_or_assign(
|
||||||
uniform_struct,
|
uniform_struct,
|
||||||
impeller::BufferAndUniformSlot{
|
flutter::gpu::RenderPass::BufferAndUniformSlot{
|
||||||
.slot = uniform_struct->slot,
|
.slot = uniform_struct->slot,
|
||||||
.view = impeller::BufferResource{
|
.view = impeller::BufferResource{
|
||||||
&uniform_struct->metadata,
|
&uniform_struct->metadata,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "flutter/lib/ui/dart_wrapper.h"
|
#include "flutter/lib/ui/dart_wrapper.h"
|
||||||
#include "fml/memory/ref_ptr.h"
|
#include "fml/memory/ref_ptr.h"
|
||||||
#include "impeller/core/formats.h"
|
#include "impeller/core/formats.h"
|
||||||
|
#include "impeller/core/shader_types.h"
|
||||||
#include "impeller/renderer/command.h"
|
#include "impeller/renderer/command.h"
|
||||||
#include "impeller/renderer/render_pass.h"
|
#include "impeller/renderer/render_pass.h"
|
||||||
#include "impeller/renderer/render_target.h"
|
#include "impeller/renderer/render_target.h"
|
||||||
@ -56,9 +57,14 @@ class RenderPass : public RefCountedDartWrappable<RenderPass> {
|
|||||||
|
|
||||||
bool Draw();
|
bool Draw();
|
||||||
|
|
||||||
|
struct BufferAndUniformSlot {
|
||||||
|
impeller::ShaderUniformSlot slot;
|
||||||
|
impeller::BufferResource view;
|
||||||
|
};
|
||||||
|
|
||||||
using BufferUniformMap =
|
using BufferUniformMap =
|
||||||
std::unordered_map<const flutter::gpu::Shader::UniformBinding*,
|
std::unordered_map<const flutter::gpu::Shader::UniformBinding*,
|
||||||
impeller::BufferAndUniformSlot>;
|
BufferAndUniformSlot>;
|
||||||
using TextureUniformMap =
|
using TextureUniformMap =
|
||||||
std::unordered_map<const flutter::gpu::Shader::TextureBinding*,
|
std::unordered_map<const flutter::gpu::Shader::TextureBinding*,
|
||||||
impeller::TextureAndSampler>;
|
impeller::TextureAndSampler>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user