diff --git a/docs/release-logs/0.4.1.md b/docs/release-logs/0.4.1.md
index 91a68496f..986269e7c 100644
--- a/docs/release-logs/0.4.1.md
+++ b/docs/release-logs/0.4.1.md
@@ -10,10 +10,11 @@
- Improvements to C++ core guideline conformance ([See PR #103](https://github.com/crud89/LiteFX/pull/103)).
- New event infrastructure. ([See PR #81](https://github.com/crud89/LiteFX/pull/81))
- Add support for user-defined debug markers. ([See PR #82](https://github.com/crud89/LiteFX/pull/82))
-- Improved resource allocation and binding: ([See PR #83](https://github.com/crud89/LiteFX/pull/83) and [PR #110](https://github.com/crud89/LiteFX/pull/110))
+- Improved resource allocation and binding: ([See PR #83](https://github.com/crud89/LiteFX/pull/83), [PR #110](https://github.com/crud89/LiteFX/pull/110) and [PR #111](https://github.com/crud89/LiteFX/pull/111))
- Resources can now be created without querying the descriptor set layout or descriptor layout in advance.
- When allocating descriptor sets, default bindings can be provided to make bind-once scenarios more straightforward.
- Descriptor sets can also be allocated without providing any binding index (in which case continous counting is assumed) or resources (which enables late binding or resource updating).
+ - Descriptor set binding has been simplified by caching last used pipeline on command buffers.
- Improved handling of temporary command buffers. ([See PR #89](https://github.com/crud89/LiteFX/pull/89))
- Command buffers can now be submitted with shared ownership to a command queue, which then stores them and releases the references, if the submit fence is passed (during `waitFor`).
- Command buffer transfers can now receive resources with shared ownership. Resource references are released in a similar fashion.
diff --git a/src/Backends/DirectX12/include/litefx/backends/dx12.hpp b/src/Backends/DirectX12/include/litefx/backends/dx12.hpp
index 170c60c7c..1143e1638 100644
--- a/src/Backends/DirectX12/include/litefx/backends/dx12.hpp
+++ b/src/Backends/DirectX12/include/litefx/backends/dx12.hpp
@@ -901,6 +901,9 @@ namespace LiteFX::Rendering::Backends {
///
void use(const DirectX12PipelineState& pipeline) const noexcept override;
+ ///
+ void bind(const DirectX12DescriptorSet& descriptorSet) const override;
+
///
void bind(const DirectX12DescriptorSet& descriptorSet, const DirectX12PipelineState& pipeline) const noexcept override;
diff --git a/src/Backends/DirectX12/src/command_buffer.cpp b/src/Backends/DirectX12/src/command_buffer.cpp
index 28445e46a..07ee31bb7 100644
--- a/src/Backends/DirectX12/src/command_buffer.cpp
+++ b/src/Backends/DirectX12/src/command_buffer.cpp
@@ -15,6 +15,7 @@ class DirectX12CommandBuffer::DirectX12CommandBufferImpl : public Implement> m_sharedResources;
+ const DirectX12PipelineState* m_lastPipeline = nullptr;
public:
DirectX12CommandBufferImpl(DirectX12CommandBuffer* parent, const DirectX12Queue& queue) :
@@ -328,9 +329,18 @@ void DirectX12CommandBuffer::transfer(SharedPtr source, IDirect
void DirectX12CommandBuffer::use(const DirectX12PipelineState& pipeline) const noexcept
{
+ m_impl->m_lastPipeline = &pipeline;
pipeline.use(*this);
}
+void DirectX12CommandBuffer::bind(const DirectX12DescriptorSet& descriptorSet) const
+{
+ if (m_impl->m_lastPipeline) [[likely]]
+ m_impl->m_queue.device().bindDescriptorSet(*this, descriptorSet, *m_impl->m_lastPipeline);
+ else
+ throw RuntimeException("No pipeline has been used on the command buffer before attempting to bind the descriptor set.");
+}
+
void DirectX12CommandBuffer::bind(const DirectX12DescriptorSet& descriptorSet, const DirectX12PipelineState& pipeline) const noexcept
{
m_impl->m_queue.device().bindDescriptorSet(*this, descriptorSet, pipeline);
diff --git a/src/Backends/Vulkan/include/litefx/backends/vulkan.hpp b/src/Backends/Vulkan/include/litefx/backends/vulkan.hpp
index 2aa76b2a8..fcd5d782b 100644
--- a/src/Backends/Vulkan/include/litefx/backends/vulkan.hpp
+++ b/src/Backends/Vulkan/include/litefx/backends/vulkan.hpp
@@ -914,6 +914,9 @@ namespace LiteFX::Rendering::Backends {
///
void use(const VulkanPipelineState& pipeline) const noexcept override;
+ ///
+ void bind(const VulkanDescriptorSet& descriptorSet) const override;
+
///
void bind(const VulkanDescriptorSet& descriptorSet, const VulkanPipelineState& pipeline) const noexcept override;
diff --git a/src/Backends/Vulkan/src/command_buffer.cpp b/src/Backends/Vulkan/src/command_buffer.cpp
index 6b6322edf..cbc78b270 100644
--- a/src/Backends/Vulkan/src/command_buffer.cpp
+++ b/src/Backends/Vulkan/src/command_buffer.cpp
@@ -15,6 +15,7 @@ class VulkanCommandBuffer::VulkanCommandBufferImpl : public Implement m_commandPool;
Array> m_sharedResources;
+ const VulkanPipelineState* m_lastPipeline = nullptr;
public:
VulkanCommandBufferImpl(VulkanCommandBuffer* parent, const VulkanQueue& queue) :
@@ -398,9 +399,18 @@ void VulkanCommandBuffer::transfer(SharedPtr source, IVulkanBuffer
void VulkanCommandBuffer::use(const VulkanPipelineState& pipeline) const noexcept
{
+ m_impl->m_lastPipeline = &pipeline;
pipeline.use(*this);
}
+void VulkanCommandBuffer::bind(const VulkanDescriptorSet& descriptorSet) const
+{
+ if (m_impl->m_lastPipeline) [[likely]]
+ m_impl->m_lastPipeline->bind(*this, descriptorSet);
+ else
+ throw RuntimeException("No pipeline has been used on the command buffer before attempting to bind the descriptor set.");
+}
+
void VulkanCommandBuffer::bind(const VulkanDescriptorSet& descriptorSet, const VulkanPipelineState& pipeline) const noexcept
{
pipeline.bind(*this, descriptorSet);
diff --git a/src/Rendering/include/litefx/rendering.hpp b/src/Rendering/include/litefx/rendering.hpp
index 94a3d36d5..14c4d615e 100644
--- a/src/Rendering/include/litefx/rendering.hpp
+++ b/src/Rendering/include/litefx/rendering.hpp
@@ -533,6 +533,9 @@ namespace LiteFX::Rendering {
///
virtual void use(const pipeline_type& pipeline) const noexcept = 0;
+ ///
+ virtual void bind(const descriptor_set_type& descriptorSet) const = 0;
+
///
virtual void bind(const descriptor_set_type& descriptorSet, const pipeline_type& pipeline) const noexcept = 0;
@@ -615,6 +618,10 @@ namespace LiteFX::Rendering {
this->use(dynamic_cast(pipeline));
}
+ void cmdBind(const IDescriptorSet& descriptorSet) const override {
+ this->bind(dynamic_cast(descriptorSet));
+ }
+
void cmdBind(const IDescriptorSet& descriptorSet, const IPipeline& pipeline) const noexcept override {
this->bind(dynamic_cast(descriptorSet), dynamic_cast(pipeline));
}
diff --git a/src/Rendering/include/litefx/rendering_api.hpp b/src/Rendering/include/litefx/rendering_api.hpp
index 924e17568..8a43e150c 100644
--- a/src/Rendering/include/litefx/rendering_api.hpp
+++ b/src/Rendering/include/litefx/rendering_api.hpp
@@ -4167,8 +4167,15 @@ namespace LiteFX::Rendering {
this->cmdUse(pipeline);
}
- // TODO: Allow bind to last used pipeline (throw, if no pipeline is in use).
- //void bind(const IDescriptorSet& descriptorSet) const;
+ ///
+ /// Binds the provided descriptor to the last pipeline that was used by the command buffer.
+ ///
+ /// The descriptor set to bind.
+ /// Thrown, if no pipeline has been used before attempting to bind the descriptor set.
+ ///
+ void bind(const IDescriptorSet& descriptorSet) const {
+ this->cmdBind(descriptorSet);
+ }
///
/// Binds the provided descriptor set to the provided pipeline.
@@ -4359,6 +4366,7 @@ namespace LiteFX::Rendering {
virtual void cmdTransfer(SharedPtr source, IImage& target, UInt32 sourceSubresource, UInt32 targetSubresource, UInt32 subresources) const = 0;
virtual void cmdTransfer(SharedPtr source, IBuffer& target, UInt32 firstSubresource, UInt32 targetElement, UInt32 subresources) const = 0;
virtual void cmdUse(const IPipeline& pipeline) const noexcept = 0;
+ virtual void cmdBind(const IDescriptorSet& descriptorSet) const = 0;
virtual void cmdBind(const IDescriptorSet& descriptorSet, const IPipeline& pipeline) const noexcept = 0;
virtual void cmdBind(const IVertexBuffer& buffer) const noexcept = 0;
virtual void cmdBind(const IIndexBuffer& buffer) const noexcept = 0;
diff --git a/src/Samples/BasicRendering/src/sample.cpp b/src/Samples/BasicRendering/src/sample.cpp
index 0c5df79e6..d88da522f 100644
--- a/src/Samples/BasicRendering/src/sample.cpp
+++ b/src/Samples/BasicRendering/src/sample.cpp
@@ -390,8 +390,8 @@ void SampleApp::drawFrame()
transformBuffer.map(reinterpret_cast(&transform), sizeof(transform), backBuffer);
// Bind both descriptor sets to the pipeline.
- commandBuffer->bind(cameraBindings, geometryPipeline);
- commandBuffer->bind(transformBindings, geometryPipeline);
+ commandBuffer->bind(cameraBindings);
+ commandBuffer->bind(transformBindings);
// Bind the vertex and index buffers.
commandBuffer->bind(vertexBuffer);