From bf671d272cead7e56ae703acb72489cc7e041cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 13 Jan 2021 19:38:06 +0100 Subject: [PATCH] Vk: finally *some* docs on command buffer and render pass usage. --- doc/snippets/MagnumVk.cpp | 43 +++++++++++++++++++++++++++++++---- src/Magnum/Vk/CommandBuffer.h | 33 ++++++++++++++++++++++++--- src/Magnum/Vk/CommandPool.h | 10 +++----- src/Magnum/Vk/Fence.h | 3 +++ src/Magnum/Vk/Queue.h | 6 +++-- src/Magnum/Vk/RenderPass.h | 29 ++++++++++++++++++++--- 6 files changed, 104 insertions(+), 20 deletions(-) diff --git a/doc/snippets/MagnumVk.cpp b/doc/snippets/MagnumVk.cpp index 58b457327..ee1a5017c 100644 --- a/doc/snippets/MagnumVk.cpp +++ b/doc/snippets/MagnumVk.cpp @@ -66,6 +66,7 @@ /* [wrapping-include-both] */ using namespace Magnum; +using namespace Magnum::Math::Literals; #define DOXYGEN_IGNORE(...) __VA_ARGS__ @@ -235,16 +236,33 @@ DOXYGEN_IGNORE() Vk::Device device{DOXYGEN_IGNORE(NoCreate)}; -Vk::CommandPool graphicsCommandPool{device, Vk::CommandPoolCreateInfo{ +Vk::CommandPool commandPool{device, Vk::CommandPoolCreateInfo{ device.properties().pickQueueFamily(Vk::QueueFlag::Graphics) }}; /* [CommandPool-creation] */ +} + +{ +Vk::Device device{NoCreate}; +/* [CommandBuffer-allocation] */ +Vk::CommandPool commandPool{device, DOXYGEN_IGNORE(Vk::CommandPoolCreateInfo{0})}; -/* [CommandPool-allocation] */ -Vk::CommandBuffer commandBuffer = graphicsCommandPool.allocate(); +Vk::CommandBuffer cmd = commandPool.allocate(); +/* [CommandBuffer-allocation] */ -// fill the buffer, submit … -/* [CommandPool-allocation] */ +/* [CommandBuffer-usage] */ +cmd.begin() + DOXYGEN_IGNORE() + .end(); +/* [CommandBuffer-usage] */ + +/* [CommandBuffer-usage-submit] */ +Vk::Queue queue{DOXYGEN_IGNORE(NoCreate)}; + +Vk::Fence fence{device}; +queue.submit({Vk::SubmitInfo{}.setCommandBuffers({cmd})}, fence); +fence.wait(); +/* [CommandBuffer-usage-submit] */ } { @@ -664,6 +682,21 @@ Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{} }) }; /* [RenderPass-dependencies] */ + +Vk::Framebuffer framebuffer{NoCreate}; +/* [RenderPass-usage-begin] */ +Vk::CommandBuffer cmd = DOXYGEN_IGNORE(Vk::CommandBuffer{NoCreate}); +cmd.begin() + DOXYGEN_IGNORE() + .beginRenderPass(Vk::RenderPassBeginInfo{renderPass, framebuffer} + .clearColor(0, 0x1f1f1f_rgbf) + .clearDepthStencil(1, 1.0f, 0)) +/* [RenderPass-usage-begin] */ +/* [RenderPass-usage-end] */ + .endRenderPass() + DOXYGEN_IGNORE() + .end(); +/* [RenderPass-usage-end] */ } { diff --git a/src/Magnum/Vk/CommandBuffer.h b/src/Magnum/Vk/CommandBuffer.h index c12a38d02..c1a75df16 100644 --- a/src/Magnum/Vk/CommandBuffer.h +++ b/src/Magnum/Vk/CommandBuffer.h @@ -46,7 +46,8 @@ namespace Implementation { struct DeviceState; } @brief Command buffer begin info @m_since_latest -Wraps a @type_vk_keyword{CommandBufferBeginInfo}. +Wraps a @type_vk_keyword{CommandBufferBeginInfo}. See +@ref Vk-CommandBuffer-usage "Command buffer usage" for more information. @see @ref CommandBuffer::begin() */ class MAGNUM_VK_EXPORT CommandBufferBeginInfo { @@ -172,8 +173,34 @@ CORRADE_ENUMSET_OPERATORS(CommandBufferResetFlags) @brief Command buffer @m_since_latest -Wraps a @type_vk_keyword{CommandBuffer}. A command buffer instance is usually -allocated from a @ref CommandPool, see its documentation for usage information. +Wraps a @type_vk_keyword{CommandBuffer}. + +@section Vk-CommandBuffer-allocation Command buffer allocation and recycling + +A command buffer instance is allocated from a @ref CommandPool as shown below. +Each command buffers is freed at the end of the @ref CommandBuffer instance +lifetime, you can also put all allocated buffers back to initial state by +calling @ref CommandPool::reset(), or alternatively reset each buffer +separately using @ref reset(), if the pool was created with +@ref CommandPoolCreateInfo::Flag::ResetCommandBuffer. + +@snippet MagnumVk.cpp CommandBuffer-allocation + +@section Vk-CommandBuffer-usage Command buffer recording and submit + +A command buffer recording is initiated with @ref begin(), after which you can +execute commands that are allowed outside a render pass. A render pass is +delimited with @ref beginRenderPass() and @ref endRenderPass(), see +@ref Vk-RenderPass-usage for details. Once a recording is done, call +@ref end(). You can (but don't have to) use method chaining: + +@snippet MagnumVk.cpp CommandBuffer-usage + +Once recorded, the command buffer can be submitted to a compatible @ref Queue +that was set up at @ref Vk-Device-creation "device creation time". Usually +you'd want to wait on the submit completion with a @link Fence @endlink: + +@snippet MagnumVk.cpp CommandBuffer-usage-submit */ class MAGNUM_VK_EXPORT CommandBuffer { public: diff --git a/src/Magnum/Vk/CommandPool.h b/src/Magnum/Vk/CommandPool.h index ebeed1924..2be0ce34a 100644 --- a/src/Magnum/Vk/CommandPool.h +++ b/src/Magnum/Vk/CommandPool.h @@ -89,7 +89,7 @@ CORRADE_ENUMSET_OPERATORS(CommandPoolResetFlags) Wraps a @type_vk_keyword{CommandPool} and handles allocation of @ref CommandBuffer "CommandBuffer"s. -@section Vk-CommandPool-creation Command pool creation and buffer allocation +@section Vk-CommandPool-creation Command pool creation A @ref CommandPoolCreateInfo doesn't need many inputs --- the only required is queue family index coming from @ref DeviceProperties of the device it's created @@ -97,12 +97,8 @@ on: @snippet MagnumVk.cpp CommandPool-creation -After that, you can allocate command buffers as follows. The command buffers -are freed at the end of their instance lifetime, you can also put all allocated -buffers back to initial state by calling @ref reset(), or alternatively reset -each buffer separately using @ref CommandBuffer::reset(). - -@snippet MagnumVk.cpp CommandPool-allocation +After that, you can allocate command buffers and use them. See +@ref CommandBuffer class docs for details. */ class MAGNUM_VK_EXPORT CommandPool { public: diff --git a/src/Magnum/Vk/Fence.h b/src/Magnum/Vk/Fence.h index 32bf8ebdf..e695fe770 100644 --- a/src/Magnum/Vk/Fence.h +++ b/src/Magnum/Vk/Fence.h @@ -62,6 +62,9 @@ By default a fence is created unsignaled. It can be created in a signaled state using @ref FenceCreateInfo::Flag::Signaled and its signaled state reset back via @ref reset(). Fence status can be queried immediately via @ref status() and waited on using @ref wait(). + +See @ref Vk-CommandBuffer-usage for an example usage in command buffer +submission. */ class MAGNUM_VK_EXPORT Fence { public: diff --git a/src/Magnum/Vk/Queue.h b/src/Magnum/Vk/Queue.h index 0e6c16f1a..e856e4dcf 100644 --- a/src/Magnum/Vk/Queue.h +++ b/src/Magnum/Vk/Queue.h @@ -43,8 +43,10 @@ namespace Magnum { namespace Vk { @brief Queue @m_since_latest -Wraps a @type_vk_keyword{Queue}. See @ref Device class docs for an introduction -on how to create a queue. +Wraps a @type_vk_keyword{Queue}. See @ref Vk-Device-creation for information +about how queues are created and retrieved from a device and +@ref Vk-CommandBuffer-usage for an overview of recording and submitting +command buffers to a queue. @see @ref DeviceCreateInfo::addQueues(), @ref submit() */ class MAGNUM_VK_EXPORT Queue { diff --git a/src/Magnum/Vk/RenderPass.h b/src/Magnum/Vk/RenderPass.h index 73c2d1163..86fd7a218 100644 --- a/src/Magnum/Vk/RenderPass.h +++ b/src/Magnum/Vk/RenderPass.h @@ -121,6 +121,26 @@ it to happen before the actual transfer command, and thus an explicit dependency is needed: @snippet MagnumVk.cpp RenderPass-dependencies + +@section Vk-RenderPass-usage Render pass recording + +A render pass recording inside a @ref CommandBuffer is begun with +@ref CommandBuffer::beginRenderPass(), to which point Vulkan schedules all +implicit layout transitions. Together with a render pass you need to supply a +compatible @ref Framebuffer containing actual image views for each attachment +and a clear value for each attachment that had +@ref AttachmentLoadOperation::Clear specified. After that you can execute +@ref CommandBuffer commands that are allowed inside a render pass: + +@snippet MagnumVk.cpp RenderPass-usage-begin + +Advancing to the next subpass (if any) can be done with +@ref CommandBuffer::nextSubpass() "nextSubpass()", and finally +@ref CommandBuffer::endRenderPass() "endRenderPass()" ends the render pass. As +with render pass begin, these make Vulkan schedule implicit layout transitions +between subpasses and at render pass end. + +@snippet MagnumVk.cpp RenderPass-usage-end */ class MAGNUM_VK_EXPORT RenderPass { public: @@ -220,7 +240,8 @@ class MAGNUM_VK_EXPORT RenderPass { @brief Render pass begin info @m_since_latest -Wraps a @type_vk_keyword{RenderPassBeginInfo}. +Wraps a @type_vk_keyword{RenderPassBeginInfo}. See @ref Vk-RenderPass-usage for +more information. @see @ref CommandBuffer::beginRenderPass() */ class MAGNUM_VK_EXPORT RenderPassBeginInfo { @@ -372,7 +393,8 @@ enum class SubpassContents: Int { @brief Subpass begin info @m_since_latest -Wraps @type_vk{SubpassBeginInfo}. +Wraps @type_vk{SubpassBeginInfo}. See @ref Vk-RenderPass-usage for more +information. @see @ref CommandBuffer::beginRenderPass(), @ref CommandBuffer::nextSubpass() */ class MAGNUM_VK_EXPORT SubpassBeginInfo { @@ -424,7 +446,8 @@ class MAGNUM_VK_EXPORT SubpassBeginInfo { @brief Subpass end info @m_since_latest -Wraps @type_vk{SubpassEndInfo}. +Wraps @type_vk{SubpassEndInfo}. See @ref Vk-RenderPass-usage for more +information. @see @ref CommandBuffer::endRenderPass(), @ref CommandBuffer::nextSubpass() */ class MAGNUM_VK_EXPORT SubpassEndInfo {