[Impeller] dont use dynamic shader metadata path for precompiled shaders. (#56827)
Should fix https://github.com/flutter/flutter/issues/159520 ~~but I still need to check locally.~~ Seems to do the trick.
All cmd bindings were copying the shader metadata, which meant allocating/de-allocating a lot of strings per draw.
diff --git a/impeller/compiler/code_gen_template.h b/impeller/compiler/code_gen_template.h
index 6c6b90e..15246a2 100644
--- a/impeller/compiler/code_gen_template.h
+++ b/impeller/compiler/code_gen_template.h
@@ -159,7 +159,7 @@
{% 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/impeller/core/resource_binder.h b/impeller/core/resource_binder.h
index 8f25ff0..120d8c9 100644
--- a/impeller/core/resource_binder.h
+++ b/impeller/core/resource_binder.h
@@ -26,13 +26,13 @@
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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) = 0;
};
diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc
index e099df6..dc2c2fe 100644
--- a/impeller/entity/contents/runtime_effect_contents.cc
+++ b/impeller/entity/contents/runtime_effect_contents.cc
@@ -50,9 +50,9 @@
}
}
-static std::shared_ptr<ShaderMetadata> MakeShaderMetadata(
+static std::unique_ptr<ShaderMetadata> MakeShaderMetadata(
const RuntimeUniformDescription& uniform) {
- auto metadata = std::make_shared<ShaderMetadata>();
+ std::unique_ptr<ShaderMetadata> metadata = std::make_unique<ShaderMetadata>();
metadata->name = uniform.name;
metadata->members.emplace_back(ShaderStructMemberMetadata{
.type = GetShaderType(uniform.type),
@@ -206,7 +206,7 @@
size_t buffer_offset = 0;
for (const auto& uniform : runtime_stage_->GetUniforms()) {
- std::shared_ptr<ShaderMetadata> metadata = MakeShaderMetadata(uniform);
+ std::unique_ptr<ShaderMetadata> metadata = MakeShaderMetadata(uniform);
switch (uniform.type) {
case kSampledImage: {
// Sampler uniforms are ordered in the IPLR according to their
@@ -237,9 +237,9 @@
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 @@
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<ShaderMetadata> metadata = MakeShaderMetadata(uniform);
+ std::unique_ptr<ShaderMetadata> metadata = MakeShaderMetadata(uniform);
switch (uniform.type) {
case kSampledImage: {
@@ -296,9 +296,9 @@
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/impeller/entity/contents/test/recording_render_pass.cc b/impeller/entity/contents/test/recording_render_pass.cc
index 1eedfdb..822ce71 100644
--- a/impeller/entity/contents/test/recording_render_pass.cc
+++ b/impeller/entity/contents/test/recording_render_pass.cc
@@ -108,7 +108,7 @@
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 @@
}
// |RenderPass|
-bool RecordingRenderPass::BindResource(
+bool RecordingRenderPass::BindDynamicResource(
ShaderStage stage,
DescriptorType type,
const ShaderUniformSlot& slot,
- const std::shared_ptr<const ShaderMetadata>& metadata,
+ std::unique_ptr<ShaderMetadata> 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<ShaderMetadata> metadata,
+ std::shared_ptr<const Texture> texture,
+ const std::unique_ptr<const Sampler>& 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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) {
pending_.BindResource(stage, type, slot, metadata, texture, sampler);
diff --git a/impeller/entity/contents/test/recording_render_pass.h b/impeller/entity/contents/test/recording_render_pass.h
index 13ee909..3fb9b34 100644
--- a/impeller/entity/contents/test/recording_render_pass.h
+++ b/impeller/entity/contents/test/recording_render_pass.h
@@ -46,29 +46,36 @@
// |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<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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) override;
// |RenderPass|
+ bool BindDynamicResource(ShaderStage stage,
+ DescriptorType type,
+ const ShaderUniformSlot& slot,
+ std::unique_ptr<ShaderMetadata> metadata,
+ BufferView view) override;
+
+ // |RenderPass|
+ 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) override;
+
+ // |RenderPass|
void OnSetLabel(std::string_view label) override;
// |RenderPass|
diff --git a/impeller/renderer/backend/metal/compute_pass_mtl.h b/impeller/renderer/backend/metal/compute_pass_mtl.h
index 64ff69a..e44975e 100644
--- a/impeller/renderer/backend/metal/compute_pass_mtl.h
+++ b/impeller/renderer/backend/metal/compute_pass_mtl.h
@@ -51,14 +51,14 @@
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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) override;
diff --git a/impeller/renderer/backend/metal/compute_pass_mtl.mm b/impeller/renderer/backend/metal/compute_pass_mtl.mm
index ee667fc..ccd51e6 100644
--- a/impeller/renderer/backend/metal/compute_pass_mtl.mm
+++ b/impeller/renderer/backend/metal/compute_pass_mtl.mm
@@ -82,7 +82,7 @@
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 @@
ShaderStage stage,
DescriptorType type,
const SampledImageSlot& slot,
- const ShaderMetadata& metadata,
+ const ShaderMetadata* metadata,
std::shared_ptr<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) {
if (!sampler || !texture->IsValid()) {
diff --git a/impeller/renderer/backend/metal/render_pass_mtl.h b/impeller/renderer/backend/metal/render_pass_mtl.h
index ddef8a7..476cde4 100644
--- a/impeller/renderer/backend/metal/render_pass_mtl.h
+++ b/impeller/renderer/backend/metal/render_pass_mtl.h
@@ -99,24 +99,33 @@
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<const ShaderMetadata>& 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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) override;
+ // |RenderPass|
+ bool BindDynamicResource(ShaderStage stage,
+ DescriptorType type,
+ const ShaderUniformSlot& slot,
+ std::unique_ptr<ShaderMetadata> metadata,
+ BufferView view) override;
+
+ // |RenderPass|
+ 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) override;
+
RenderPassMTL(const RenderPassMTL&) = delete;
RenderPassMTL& operator=(const RenderPassMTL&) = delete;
diff --git a/impeller/renderer/backend/metal/render_pass_mtl.mm b/impeller/renderer/backend/metal/render_pass_mtl.mm
index 80cf59b..6a4ba15 100644
--- a/impeller/renderer/backend/metal/render_pass_mtl.mm
+++ b/impeller/renderer/backend/metal/render_pass_mtl.mm
@@ -385,17 +385,17 @@
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<const ShaderMetadata>& metadata,
+ std::unique_ptr<ShaderMetadata> metadata,
BufferView view) {
return Bind(pass_bindings_, stage, slot.ext_res_0, view);
}
@@ -405,7 +405,20 @@
ShaderStage stage,
DescriptorType type,
const SampledImageSlot& slot,
- const ShaderMetadata& metadata,
+ const ShaderMetadata* metadata,
+ std::shared_ptr<const Texture> texture,
+ const std::unique_ptr<const Sampler>& 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<ShaderMetadata> metadata,
std::shared_ptr<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) {
if (!texture) {
diff --git a/impeller/renderer/backend/vulkan/compute_pass_vk.cc b/impeller/renderer/backend/vulkan/compute_pass_vk.cc
index 402d4bd..f4b61cd 100644
--- a/impeller/renderer/backend/vulkan/compute_pass_vk.cc
+++ b/impeller/renderer/backend/vulkan/compute_pass_vk.cc
@@ -134,7 +134,7 @@
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 @@
ShaderStage stage,
DescriptorType type,
const SampledImageSlot& slot,
- const ShaderMetadata& metadata,
+ const ShaderMetadata* metadata,
std::shared_ptr<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) {
if (bound_image_offset_ >= kMaxBindings) {
diff --git a/impeller/renderer/backend/vulkan/compute_pass_vk.h b/impeller/renderer/backend/vulkan/compute_pass_vk.h
index b281775..78aac09 100644
--- a/impeller/renderer/backend/vulkan/compute_pass_vk.h
+++ b/impeller/renderer/backend/vulkan/compute_pass_vk.h
@@ -71,14 +71,14 @@
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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) override;
diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc
index 3808d84..3453233 100644
--- a/impeller/renderer/backend/vulkan/render_pass_vk.cc
+++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc
@@ -544,17 +544,16 @@
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<const ShaderMetadata>& metadata,
- BufferView view) {
+bool RenderPassVK::BindDynamicResource(ShaderStage stage,
+ DescriptorType type,
+ const ShaderUniformSlot& slot,
+ std::unique_ptr<ShaderMetadata> metadata,
+ BufferView view) {
return BindResource(slot.binding, type, view);
}
@@ -593,10 +592,20 @@
return true;
}
+bool RenderPassVK::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) {
+ 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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) {
if (bound_buffer_offset_ >= kMaxBindings) {
diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.h b/impeller/renderer/backend/vulkan/render_pass_vk.h
index 61ca753..d652f23 100644
--- a/impeller/renderer/backend/vulkan/render_pass_vk.h
+++ b/impeller/renderer/backend/vulkan/render_pass_vk.h
@@ -99,24 +99,33 @@
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<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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) override;
+ // |RenderPass|
+ bool BindDynamicResource(ShaderStage stage,
+ DescriptorType type,
+ const ShaderUniformSlot& slot,
+ std::unique_ptr<ShaderMetadata> metadata,
+ BufferView view) override;
+
+ // |RenderPass|
+ 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) override;
+
bool BindResource(size_t binding, DescriptorType type, BufferView view);
// |RenderPass|
diff --git a/impeller/renderer/command.cc b/impeller/renderer/command.cc
index 0ca99cb..513f694 100644
--- a/impeller/renderer/command.cc
+++ b/impeller/renderer/command.cc
@@ -29,64 +29,35 @@
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<const ShaderMetadata>& metadata,
- BufferView view) {
+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));
- 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<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) {
if (!sampler) {
@@ -95,21 +66,40 @@
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.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 @@
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
diff --git a/impeller/renderer/command.h b/impeller/renderer/command.h
index a63f52f..29e41bb 100644
--- a/impeller/renderer/command.h
+++ b/impeller/renderer/command.h
@@ -39,15 +39,19 @@
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<ShaderMetadata>(metadata)) {}
-
const ShaderMetadata* GetMetadata() const {
return dynamic_metadata_ ? dynamic_metadata_.get() : metadata_;
}
+ static Resource MakeDynamic(std::unique_ptr<ShaderMetadata> metadata,
+ ResourceType p_resource) {
+ return Resource(std::move(metadata), p_resource);
+ }
+
private:
+ Resource(std::unique_ptr<ShaderMetadata> 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 @@
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<const ShaderMetadata>& metadata,
- BufferView view);
-
// |ResourceBinder|
bool BindResource(ShaderStage stage,
DescriptorType type,
const SampledImageSlot& slot,
- const ShaderMetadata& metadata,
+ 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(); }
private:
- template <class T>
- 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<const Sampler>& sampler);
};
} // namespace impeller
diff --git a/impeller/renderer/render_pass.cc b/impeller/renderer/render_pass.cc
index 016a7a1..600d378 100644
--- a/impeller/renderer/render_pass.cc
+++ b/impeller/renderer/render_pass.cc
@@ -216,29 +216,40 @@
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<const ShaderMetadata>& 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<const Texture> texture,
const std::unique_ptr<const Sampler>& 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<ShaderMetadata> 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<ShaderMetadata> metadata,
+ std::shared_ptr<const Texture> texture,
+ const std::unique_ptr<const Sampler>& sampler) {
+ return pending_.BindDynamicResource(stage, type, slot, std::move(metadata),
+ std::move(texture), sampler);
+}
+
} // namespace impeller
diff --git a/impeller/renderer/render_pass.h b/impeller/renderer/render_pass.h
index 0ada25e..dc590d3 100644
--- a/impeller/renderer/render_pass.h
+++ b/impeller/renderer/render_pass.h
@@ -181,25 +181,33 @@
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<const ShaderMetadata>& metadata,
- BufferView view);
-
// |ResourceBinder|
virtual bool BindResource(
ShaderStage stage,
DescriptorType type,
const SampledImageSlot& slot,
- const ShaderMetadata& metadata,
+ const ShaderMetadata* metadata,
std::shared_ptr<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) override;
+ /// @brief Bind with dynamically generated shader metadata.
+ virtual 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);
+
+ virtual bool BindDynamicResource(ShaderStage stage,
+ DescriptorType type,
+ const ShaderUniformSlot& slot,
+ std::unique_ptr<ShaderMetadata> metadata,
+ BufferView view);
+
//----------------------------------------------------------------------------
/// @brief Encode the recorded commands to the underlying command buffer.
///
diff --git a/lib/gpu/render_pass.cc b/lib/gpu/render_pass.cc
index 3987d82..fdbb493 100644
--- a/lib/gpu/render_pass.cc
+++ b/lib/gpu/render_pass.cc
@@ -177,28 +177,34 @@
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<impeller::ShaderMetadata>(*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<impeller::ShaderMetadata>(
+ *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<impeller::ShaderMetadata>(*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<impeller::ShaderMetadata>(
+ *texture.texture.GetMetadata()),
+ texture.texture.resource, *texture.sampler);
}
render_pass_->SetVertexBuffer(vertex_buffer);