diff --git a/engine/src/flutter/impeller/compiler/code_gen_template.h b/engine/src/flutter/impeller/compiler/code_gen_template.h index 6c6b90e763f..15246a28d5d 100644 --- a/engine/src/flutter/impeller/compiler/code_gen_template.h +++ b/engine/src/flutter/impeller/compiler/code_gen_template.h @@ -159,7 +159,7 @@ struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader { {% endfor %}) { return {{ proto.args.0.argument_name }}.BindResource({% for arg in proto.args %} {% if loop.is_first %} -{{to_shader_stage(shader_stage)}}, {{ proto.descriptor_type }}, kResource{{ proto.name }}, kMetadata{{ proto.name }}, {% else %} +{{to_shader_stage(shader_stage)}}, {{ proto.descriptor_type }}, kResource{{ proto.name }}, &kMetadata{{ proto.name }}, {% else %} std::move({{ arg.argument_name }}){% if not loop.is_last %}, {% endif %} {% endif %} {% endfor %}); diff --git a/engine/src/flutter/impeller/core/resource_binder.h b/engine/src/flutter/impeller/core/resource_binder.h index 8f25ff0c7fe..120d8c96963 100644 --- a/engine/src/flutter/impeller/core/resource_binder.h +++ b/engine/src/flutter/impeller/core/resource_binder.h @@ -26,13 +26,13 @@ struct ResourceBinder { virtual bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) = 0; virtual bool BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) = 0; }; diff --git a/engine/src/flutter/impeller/entity/contents/runtime_effect_contents.cc b/engine/src/flutter/impeller/entity/contents/runtime_effect_contents.cc index e099df6f053..dc2c2fea8b7 100644 --- a/engine/src/flutter/impeller/entity/contents/runtime_effect_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/runtime_effect_contents.cc @@ -50,9 +50,9 @@ static ShaderType GetShaderType(RuntimeUniformType type) { } } -static std::shared_ptr MakeShaderMetadata( +static std::unique_ptr MakeShaderMetadata( const RuntimeUniformDescription& uniform) { - auto metadata = std::make_shared(); + std::unique_ptr metadata = std::make_unique(); metadata->name = uniform.name; metadata->members.emplace_back(ShaderStructMemberMetadata{ .type = GetShaderType(uniform.type), @@ -206,7 +206,7 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, size_t buffer_offset = 0; for (const auto& uniform : runtime_stage_->GetUniforms()) { - std::shared_ptr metadata = MakeShaderMetadata(uniform); + std::unique_ptr metadata = MakeShaderMetadata(uniform); switch (uniform.type) { case kSampledImage: { // Sampler uniforms are ordered in the IPLR according to their @@ -237,9 +237,9 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, ShaderUniformSlot uniform_slot; uniform_slot.name = uniform.name.c_str(); uniform_slot.ext_res_0 = uniform.location; - pass.BindResource(ShaderStage::kFragment, - DescriptorType::kUniformBuffer, uniform_slot, - metadata, std::move(buffer_view)); + pass.BindDynamicResource(ShaderStage::kFragment, + DescriptorType::kUniformBuffer, uniform_slot, + std::move(metadata), std::move(buffer_view)); buffer_index++; buffer_offset += uniform.GetSize(); break; @@ -274,14 +274,14 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, sizeof(float) * uniform_buffer.size(), alignment); pass.BindResource(ShaderStage::kFragment, DescriptorType::kUniformBuffer, uniform_slot, - ShaderMetadata{}, std::move(buffer_view)); + nullptr, std::move(buffer_view)); } } } size_t sampler_index = 0; for (const auto& uniform : runtime_stage_->GetUniforms()) { - std::shared_ptr metadata = MakeShaderMetadata(uniform); + std::unique_ptr metadata = MakeShaderMetadata(uniform); switch (uniform.type) { case kSampledImage: { @@ -296,9 +296,9 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, image_slot.name = uniform.name.c_str(); image_slot.binding = uniform.binding; image_slot.texture_index = uniform.location - minimum_sampler_index; - pass.BindResource(ShaderStage::kFragment, - DescriptorType::kSampledImage, image_slot, - *metadata, input.texture, sampler); + pass.BindDynamicResource(ShaderStage::kFragment, + DescriptorType::kSampledImage, image_slot, + std::move(metadata), input.texture, sampler); sampler_index++; break; diff --git a/engine/src/flutter/impeller/entity/contents/test/recording_render_pass.cc b/engine/src/flutter/impeller/entity/contents/test/recording_render_pass.cc index 1eedfdb48d7..822ce710218 100644 --- a/engine/src/flutter/impeller/entity/contents/test/recording_render_pass.cc +++ b/engine/src/flutter/impeller/entity/contents/test/recording_render_pass.cc @@ -108,7 +108,7 @@ bool RecordingRenderPass::OnEncodeCommands(const Context& context) const { bool RecordingRenderPass::BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) { pending_.BindResource(stage, type, slot, metadata, view); if (delegate_) { @@ -118,25 +118,41 @@ bool RecordingRenderPass::BindResource(ShaderStage stage, } // |RenderPass| -bool RecordingRenderPass::BindResource( +bool RecordingRenderPass::BindDynamicResource( ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, + std::unique_ptr metadata, BufferView view) { - pending_.BindResource(stage, type, slot, metadata, view); + pending_.BindResource(stage, type, slot, metadata.get(), view); if (delegate_) { - return delegate_->BindResource(stage, type, slot, metadata, view); + return delegate_->BindDynamicResource(stage, type, slot, + std::move(metadata), view); } return true; } // |RenderPass| +bool RecordingRenderPass::BindDynamicResource( + ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler) { + pending_.BindResource(stage, type, slot, metadata.get(), texture, sampler); + if (delegate_) { + return delegate_->BindDynamicResource( + stage, type, slot, std::move(metadata), texture, sampler); + } + return true; +} + bool RecordingRenderPass::BindResource( ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) { pending_.BindResource(stage, type, slot, metadata, texture, sampler); diff --git a/engine/src/flutter/impeller/entity/contents/test/recording_render_pass.h b/engine/src/flutter/impeller/entity/contents/test/recording_render_pass.h index 13ee9090a34..3fb9b34d344 100644 --- a/engine/src/flutter/impeller/entity/contents/test/recording_render_pass.h +++ b/engine/src/flutter/impeller/entity/contents/test/recording_render_pass.h @@ -46,28 +46,35 @@ class RecordingRenderPass : public RenderPass { // |RenderPass| fml::Status Draw() override; - // |RenderPass| bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) override; - // |RenderPass| - bool BindResource(ShaderStage stage, - DescriptorType type, - const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, - BufferView view) override; - - // |RenderPass| bool BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) override; + // |RenderPass| + bool BindDynamicResource(ShaderStage stage, + DescriptorType type, + const ShaderUniformSlot& slot, + std::unique_ptr metadata, + BufferView view) override; + + // |RenderPass| + bool BindDynamicResource( + ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler) override; + // |RenderPass| void OnSetLabel(std::string_view label) override; diff --git a/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.h b/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.h index 64ff69a70db..e44975eee12 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.h +++ b/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.h @@ -51,14 +51,14 @@ class ComputePassMTL final : public ComputePass { bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) override; // |ComputePass| bool BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) override; diff --git a/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm index ee667fccaac..ccd51e67c91 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm @@ -82,7 +82,7 @@ void ComputePassMTL::AddTextureMemoryBarrier() { bool ComputePassMTL::BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) { if (!view.GetBuffer()) { return false; @@ -109,7 +109,7 @@ bool ComputePassMTL::BindResource( ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) { if (!sampler || !texture->IsValid()) { diff --git a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.h b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.h index ddef8a7b83c..476cde4b93c 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.h +++ b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.h @@ -99,24 +99,33 @@ class RenderPassMTL final : public RenderPass { bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, - BufferView view) override; - - // |RenderPass| - bool BindResource(ShaderStage stage, - DescriptorType type, - const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, + const ShaderMetadata* metadata, BufferView view) override; // |RenderPass| bool BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) override; + // |RenderPass| + bool BindDynamicResource(ShaderStage stage, + DescriptorType type, + const ShaderUniformSlot& slot, + std::unique_ptr metadata, + BufferView view) override; + + // |RenderPass| + bool BindDynamicResource( + ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler) override; + RenderPassMTL(const RenderPassMTL&) = delete; RenderPassMTL& operator=(const RenderPassMTL&) = delete; diff --git a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm index 80cf59bb5f1..6a4ba15bc46 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -385,17 +385,17 @@ fml::Status RenderPassMTL::Draw() { bool RenderPassMTL::BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) { return Bind(pass_bindings_, stage, slot.ext_res_0, view); } // |RenderPass| -bool RenderPassMTL::BindResource( +bool RenderPassMTL::BindDynamicResource( ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, + std::unique_ptr metadata, BufferView view) { return Bind(pass_bindings_, stage, slot.ext_res_0, view); } @@ -405,7 +405,20 @@ bool RenderPassMTL::BindResource( ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler) { + if (!texture) { + return false; + } + return Bind(pass_bindings_, stage, slot.texture_index, sampler, *texture); +} + +bool RenderPassMTL::BindDynamicResource( + ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, std::shared_ptr texture, const std::unique_ptr& sampler) { if (!texture) { diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.cc index 402d4bd24a8..f4b61cdba64 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.cc @@ -134,7 +134,7 @@ fml::Status ComputePassVK::Compute(const ISize& grid_size) { bool ComputePassVK::BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) { return BindResource(slot.binding, type, view); } @@ -144,7 +144,7 @@ bool ComputePassVK::BindResource( ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) { if (bound_image_offset_ >= kMaxBindings) { diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.h index b281775259b..78aac09c6da 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.h @@ -71,14 +71,14 @@ class ComputePassVK final : public ComputePass { bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) override; // |ResourceBinder| bool BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) override; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc index 3808d84fd34..34532332353 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -544,17 +544,16 @@ fml::Status RenderPassVK::Draw() { bool RenderPassVK::BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) { return BindResource(slot.binding, type, view); } -bool RenderPassVK::BindResource( - ShaderStage stage, - DescriptorType type, - const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, - BufferView view) { +bool RenderPassVK::BindDynamicResource(ShaderStage stage, + DescriptorType type, + const ShaderUniformSlot& slot, + std::unique_ptr metadata, + BufferView view) { return BindResource(slot.binding, type, view); } @@ -593,10 +592,20 @@ bool RenderPassVK::BindResource(size_t binding, return true; } +bool RenderPassVK::BindDynamicResource( + ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler) { + return BindResource(stage, type, slot, nullptr, texture, sampler); +} + bool RenderPassVK::BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) { if (bound_buffer_offset_ >= kMaxBindings) { diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h index 61ca7533b0e..d652f23f50b 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h @@ -99,24 +99,33 @@ class RenderPassVK final : public RenderPass { bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, - BufferView view) override; - - // |RenderPass| - bool BindResource(ShaderStage stage, - DescriptorType type, - const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, + const ShaderMetadata* metadata, BufferView view) override; // |ResourceBinder| bool BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) override; + // |RenderPass| + bool BindDynamicResource(ShaderStage stage, + DescriptorType type, + const ShaderUniformSlot& slot, + std::unique_ptr metadata, + BufferView view) override; + + // |RenderPass| + bool BindDynamicResource( + ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler) override; + bool BindResource(size_t binding, DescriptorType type, BufferView view); // |RenderPass| diff --git a/engine/src/flutter/impeller/renderer/command.cc b/engine/src/flutter/impeller/renderer/command.cc index 0ca99cbd311..513f694ab4a 100644 --- a/engine/src/flutter/impeller/renderer/command.cc +++ b/engine/src/flutter/impeller/renderer/command.cc @@ -29,64 +29,35 @@ bool Command::BindVertices(const VertexBuffer& buffer) { bool Command::BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) { FML_DCHECK(slot.ext_res_0 != VertexDescriptor::kReservedVertexBufferIndex); if (!view) { return false; } - - switch (stage) { - case ShaderStage::kVertex: - vertex_bindings.buffers.emplace_back(BufferAndUniformSlot{ - .slot = slot, .view = BufferResource(metadata, std::move(view))}); - return true; - case ShaderStage::kFragment: - fragment_bindings.buffers.emplace_back(BufferAndUniformSlot{ - .slot = slot, .view = BufferResource(metadata, std::move(view))}); - return true; - case ShaderStage::kCompute: - VALIDATION_LOG << "Use ComputeCommands for compute shader stages."; - case ShaderStage::kUnknown: - return false; - } - - return false; + BufferResource resouce = BufferResource(metadata, std::move(view)); + return BindBuffer(stage, slot, std::move(resouce)); } -bool Command::BindResource( - ShaderStage stage, - DescriptorType type, - const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, - BufferView view) { +bool Command::BindDynamicResource(ShaderStage stage, + DescriptorType type, + const ShaderUniformSlot& slot, + std::unique_ptr 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)); - switch (stage) { - case ShaderStage::kVertex: - vertex_bindings.buffers.emplace_back(BufferAndUniformSlot{ - .slot = slot, .view = BufferResource(*metadata, std::move(view))}); - return true; - case ShaderStage::kFragment: - fragment_bindings.buffers.emplace_back(BufferAndUniformSlot{ - .slot = slot, .view = BufferResource(*metadata, std::move(view))}); - return true; - case ShaderStage::kCompute: - VALIDATION_LOG << "Use ComputeCommands for compute shader stages."; - case ShaderStage::kUnknown: - return false; - } - - return false; + return BindBuffer(stage, slot, std::move(resouce)); } bool Command::BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) { if (!sampler) { @@ -95,21 +66,40 @@ bool Command::BindResource(ShaderStage stage, 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 metadata, + std::shared_ptr texture, + const std::unique_ptr& 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.sampled_images.emplace_back(TextureAndSampler{ - .slot = slot, - .texture = TextureResource(metadata, std::move(texture)), - .sampler = &sampler, - }); + vertex_bindings.buffers.push_back(std::move(data)); return true; case ShaderStage::kFragment: - fragment_bindings.sampled_images.emplace_back(TextureAndSampler{ - .slot = slot, - .texture = TextureResource(metadata, std::move(texture)), - .sampler = &sampler, - }); + fragment_bindings.buffers.push_back(std::move(data)); return true; case ShaderStage::kCompute: VALIDATION_LOG << "Use ComputeCommands for compute shader stages."; @@ -120,4 +110,28 @@ bool Command::BindResource(ShaderStage stage, return false; } +bool Command::BindTexture(ShaderStage stage, + const SampledImageSlot& slot, + TextureResource resource, + const std::unique_ptr& 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 diff --git a/engine/src/flutter/impeller/renderer/command.h b/engine/src/flutter/impeller/renderer/command.h index a63f52f35a9..29e41bb530f 100644 --- a/engine/src/flutter/impeller/renderer/command.h +++ b/engine/src/flutter/impeller/renderer/command.h @@ -39,15 +39,19 @@ class Resource { Resource(const ShaderMetadata* metadata, ResourceType p_resource) : resource(p_resource), metadata_(metadata) {} - Resource(const ShaderMetadata& metadata, ResourceType p_resource) - : resource(p_resource), - dynamic_metadata_(std::make_unique(metadata)) {} - const ShaderMetadata* GetMetadata() const { return dynamic_metadata_ ? dynamic_metadata_.get() : metadata_; } + static Resource MakeDynamic(std::unique_ptr metadata, + ResourceType p_resource) { + return Resource(std::move(metadata), p_resource); + } + private: + Resource(std::unique_ptr metadata, ResourceType p_resource) + : resource(p_resource), dynamic_metadata_(std::move(metadata)) {} + // Static shader metadata (typically generated by ImpellerC). const ShaderMetadata* metadata_ = nullptr; @@ -184,31 +188,41 @@ struct Command : public ResourceBinder { bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) override; - bool BindResource(ShaderStage stage, - DescriptorType type, - const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, - BufferView view); - // |ResourceBinder| bool BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) override; + bool BindDynamicResource(ShaderStage stage, + DescriptorType type, + const ShaderUniformSlot& slot, + std::unique_ptr metadata, + BufferView view); + + bool BindDynamicResource(ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler); + bool IsValid() const { return pipeline && pipeline->IsValid(); } private: - template - bool DoBindResource(ShaderStage stage, - const ShaderUniformSlot& slot, - T metadata, - BufferView view); + bool BindBuffer(ShaderStage stage, + const ShaderUniformSlot& slot, + BufferResource resource); + + bool BindTexture(ShaderStage stage, + const SampledImageSlot& slot, + TextureResource resource, + const std::unique_ptr& sampler); }; } // namespace impeller diff --git a/engine/src/flutter/impeller/renderer/render_pass.cc b/engine/src/flutter/impeller/renderer/render_pass.cc index 016a7a16f13..600d3788b13 100644 --- a/engine/src/flutter/impeller/renderer/render_pass.cc +++ b/engine/src/flutter/impeller/renderer/render_pass.cc @@ -216,29 +216,40 @@ fml::Status RenderPass::Draw() { bool RenderPass::BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) { return pending_.BindResource(stage, type, slot, metadata, view); } -bool RenderPass::BindResource( - ShaderStage stage, - DescriptorType type, - const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, - BufferView view) { - return pending_.BindResource(stage, type, slot, metadata, std::move(view)); -} - // |ResourceBinder| bool RenderPass::BindResource(ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) { return pending_.BindResource(stage, type, slot, metadata, std::move(texture), sampler); } +bool RenderPass::BindDynamicResource(ShaderStage stage, + DescriptorType type, + const ShaderUniformSlot& slot, + std::unique_ptr metadata, + BufferView view) { + return pending_.BindDynamicResource(stage, type, slot, std::move(metadata), + std::move(view)); +} + +bool RenderPass::BindDynamicResource( + ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler) { + return pending_.BindDynamicResource(stage, type, slot, std::move(metadata), + std::move(texture), sampler); +} + } // namespace impeller diff --git a/engine/src/flutter/impeller/renderer/render_pass.h b/engine/src/flutter/impeller/renderer/render_pass.h index 0ada25e7445..dc590d307d1 100644 --- a/engine/src/flutter/impeller/renderer/render_pass.h +++ b/engine/src/flutter/impeller/renderer/render_pass.h @@ -181,25 +181,33 @@ class RenderPass : public ResourceBinder { virtual bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, BufferView view) override; - virtual bool BindResource( - ShaderStage stage, - DescriptorType type, - const ShaderUniformSlot& slot, - const std::shared_ptr& metadata, - BufferView view); - // |ResourceBinder| virtual bool BindResource( ShaderStage stage, DescriptorType type, const SampledImageSlot& slot, - const ShaderMetadata& metadata, + const ShaderMetadata* metadata, std::shared_ptr texture, const std::unique_ptr& sampler) override; + /// @brief Bind with dynamically generated shader metadata. + virtual bool BindDynamicResource( + ShaderStage stage, + DescriptorType type, + const SampledImageSlot& slot, + std::unique_ptr metadata, + std::shared_ptr texture, + const std::unique_ptr& sampler); + + virtual bool BindDynamicResource(ShaderStage stage, + DescriptorType type, + const ShaderUniformSlot& slot, + std::unique_ptr metadata, + BufferView view); + //---------------------------------------------------------------------------- /// @brief Encode the recorded commands to the underlying command buffer. /// diff --git a/engine/src/flutter/lib/gpu/render_pass.cc b/engine/src/flutter/lib/gpu/render_pass.cc index 3987d823f5a..fdbb493b483 100644 --- a/engine/src/flutter/lib/gpu/render_pass.cc +++ b/engine/src/flutter/lib/gpu/render_pass.cc @@ -177,28 +177,34 @@ bool RenderPass::Draw() { render_pass_->SetPipeline(GetOrCreatePipeline()); for (const auto& [_, buffer] : vertex_uniform_bindings) { - render_pass_->BindResource(impeller::ShaderStage::kVertex, - impeller::DescriptorType::kUniformBuffer, - buffer.slot, *buffer.view.GetMetadata(), - buffer.view.resource); + render_pass_->BindDynamicResource( + impeller::ShaderStage::kVertex, + impeller::DescriptorType::kUniformBuffer, buffer.slot, + std::make_unique(*buffer.view.GetMetadata()), + buffer.view.resource); } for (const auto& [_, texture] : vertex_texture_bindings) { - render_pass_->BindResource(impeller::ShaderStage::kVertex, - impeller::DescriptorType::kSampledImage, - texture.slot, *texture.texture.GetMetadata(), - texture.texture.resource, *texture.sampler); + render_pass_->BindDynamicResource( + impeller::ShaderStage::kVertex, impeller::DescriptorType::kSampledImage, + texture.slot, + std::make_unique( + *texture.texture.GetMetadata()), + texture.texture.resource, *texture.sampler); } for (const auto& [_, buffer] : fragment_uniform_bindings) { - render_pass_->BindResource(impeller::ShaderStage::kFragment, - impeller::DescriptorType::kUniformBuffer, - buffer.slot, *buffer.view.GetMetadata(), - buffer.view.resource); + render_pass_->BindDynamicResource( + impeller::ShaderStage::kFragment, + impeller::DescriptorType::kUniformBuffer, buffer.slot, + std::make_unique(*buffer.view.GetMetadata()), + buffer.view.resource); } for (const auto& [_, texture] : fragment_texture_bindings) { - render_pass_->BindResource(impeller::ShaderStage::kFragment, - impeller::DescriptorType::kSampledImage, - texture.slot, *texture.texture.GetMetadata(), - texture.texture.resource, *texture.sampler); + render_pass_->BindDynamicResource( + impeller::ShaderStage::kFragment, + impeller::DescriptorType::kSampledImage, texture.slot, + std::make_unique( + *texture.texture.GetMetadata()), + texture.texture.resource, *texture.sampler); } render_pass_->SetVertexBuffer(vertex_buffer);