Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify binding descriptor sets. #111

Merged
merged 2 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/release-logs/0.4.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions src/Backends/DirectX12/include/litefx/backends/dx12.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,9 @@ namespace LiteFX::Rendering::Backends {
/// <inheritdoc />
void use(const DirectX12PipelineState& pipeline) const noexcept override;

/// <inheritdoc />
void bind(const DirectX12DescriptorSet& descriptorSet) const override;

/// <inheritdoc />
void bind(const DirectX12DescriptorSet& descriptorSet, const DirectX12PipelineState& pipeline) const noexcept override;

Expand Down
10 changes: 10 additions & 0 deletions src/Backends/DirectX12/src/command_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class DirectX12CommandBuffer::DirectX12CommandBufferImpl : public Implement<Dire
bool m_recording{ false }, m_secondary{ false };
const DirectX12Queue& m_queue;
Array<SharedPtr<const IStateResource>> m_sharedResources;
const DirectX12PipelineState* m_lastPipeline = nullptr;

public:
DirectX12CommandBufferImpl(DirectX12CommandBuffer* parent, const DirectX12Queue& queue) :
Expand Down Expand Up @@ -328,9 +329,18 @@ void DirectX12CommandBuffer::transfer(SharedPtr<IDirectX12Image> 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);
Expand Down
3 changes: 3 additions & 0 deletions src/Backends/Vulkan/include/litefx/backends/vulkan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,9 @@ namespace LiteFX::Rendering::Backends {
/// <inheritdoc />
void use(const VulkanPipelineState& pipeline) const noexcept override;

/// <inheritdoc />
void bind(const VulkanDescriptorSet& descriptorSet) const override;

/// <inheritdoc />
void bind(const VulkanDescriptorSet& descriptorSet, const VulkanPipelineState& pipeline) const noexcept override;

Expand Down
10 changes: 10 additions & 0 deletions src/Backends/Vulkan/src/command_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class VulkanCommandBuffer::VulkanCommandBufferImpl : public Implement<VulkanComm
bool m_recording{ false }, m_secondary{ false };
Optional<VkCommandPool> m_commandPool;
Array<SharedPtr<const IStateResource>> m_sharedResources;
const VulkanPipelineState* m_lastPipeline = nullptr;

public:
VulkanCommandBufferImpl(VulkanCommandBuffer* parent, const VulkanQueue& queue) :
Expand Down Expand Up @@ -398,9 +399,18 @@ void VulkanCommandBuffer::transfer(SharedPtr<IVulkanImage> 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);
Expand Down
7 changes: 7 additions & 0 deletions src/Rendering/include/litefx/rendering.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,9 @@ namespace LiteFX::Rendering {
/// <inheritdoc />
virtual void use(const pipeline_type& pipeline) const noexcept = 0;

/// <inheritdoc />
virtual void bind(const descriptor_set_type& descriptorSet) const = 0;

/// <inheritdoc />
virtual void bind(const descriptor_set_type& descriptorSet, const pipeline_type& pipeline) const noexcept = 0;

Expand Down Expand Up @@ -615,6 +618,10 @@ namespace LiteFX::Rendering {
this->use(dynamic_cast<const pipeline_type&>(pipeline));
}

void cmdBind(const IDescriptorSet& descriptorSet) const override {
this->bind(dynamic_cast<const descriptor_set_type&>(descriptorSet));
}

void cmdBind(const IDescriptorSet& descriptorSet, const IPipeline& pipeline) const noexcept override {
this->bind(dynamic_cast<const descriptor_set_type&>(descriptorSet), dynamic_cast<const pipeline_type&>(pipeline));
}
Expand Down
12 changes: 10 additions & 2 deletions src/Rendering/include/litefx/rendering_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
/// <summary>
/// Binds the provided descriptor to the last pipeline that was used by the command buffer.
/// </summary>
/// <param name="descriptorSet">The descriptor set to bind.</param>
/// <exception cref="RuntimeException">Thrown, if no pipeline has been used before attempting to bind the descriptor set.</exception>
/// <seealso cref="use" />
void bind(const IDescriptorSet& descriptorSet) const {
this->cmdBind(descriptorSet);
}

/// <summary>
/// Binds the provided descriptor set to the provided pipeline.
Expand Down Expand Up @@ -4359,6 +4366,7 @@ namespace LiteFX::Rendering {
virtual void cmdTransfer(SharedPtr<IImage> source, IImage& target, UInt32 sourceSubresource, UInt32 targetSubresource, UInt32 subresources) const = 0;
virtual void cmdTransfer(SharedPtr<IImage> 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;
Expand Down
4 changes: 2 additions & 2 deletions src/Samples/BasicRendering/src/sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,8 @@ void SampleApp::drawFrame()
transformBuffer.map(reinterpret_cast<const void*>(&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);
Expand Down
Loading