Browse Source

Vk: command buffer begin and end.

pull/491/head
Vladimír Vondruš 5 years ago
parent
commit
7ee30c55e3
  1. 4
      doc/vulkan-mapping.dox
  2. 21
      src/Magnum/Vk/CommandBuffer.cpp
  3. 119
      src/Magnum/Vk/CommandBuffer.h
  4. 35
      src/Magnum/Vk/Test/CommandBufferTest.cpp
  5. 20
      src/Magnum/Vk/Test/CommandBufferVkTest.cpp
  6. 1
      src/Magnum/Vk/Vk.h

4
doc/vulkan-mapping.dox

@ -62,7 +62,7 @@ Vulkan function | Matching API
Vulkan function | Matching API
--------------------------------------- | ------------
@fn_vk{BeginCommandBuffer}, \n \fn_vk{EndCommandBuffer} | |
@fn_vk{BeginCommandBuffer}, \n \fn_vk{EndCommandBuffer} | @ref CommandBuffer::begin(), \n @ref CommandBuffer::end()
@fn_vk{BindBufferMemory}, \n @fn_vk{BindBufferMemory2} @m_class{m-label m-flat m-success} **KHR, 1.1** | @ref Buffer::bindMemory()
@fn_vk{BindImageMemory}, \n @fn_vk{BindImageMemory2} @m_class{m-label m-flat m-success} **KHR, 1.1** | @ref Image::bindMemory()
@fn_vk{BuildAccelerationStructuresKHR} @m_class{m-label m-flat m-warning} **KHR** | |
@ -385,7 +385,7 @@ Vulkan structure | Matching API
@type_vk{ClearValue} | |
@type_vk{ClearRect} | convertible from/to @ref Range3Di using @ref Magnum/Vk/Integration.h
@type_vk{CommandBufferAllocateInfo} | not exposed, internal to @ref CommandPool::allocate()
@type_vk{CommandBufferBeginInfo} | |
@type_vk{CommandBufferBeginInfo} | @ref CommandBufferBeginInfo
@type_vk{CommandBufferInheritanceInfo} | |
@type_vk{CommandPoolCreateInfo} | @ref CommandPoolCreateInfo
@type_vk{ComponentMapping} | |

21
src/Magnum/Vk/CommandBuffer.cpp

@ -64,6 +64,27 @@ void CommandBuffer::reset(const CommandBufferResetFlags flags) {
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS((**_device).ResetCommandBuffer(_handle, VkCommandBufferResetFlags(flags)));
}
CommandBufferBeginInfo::CommandBufferBeginInfo(const Flags flags): _info{} {
_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
_info.flags = VkCommandBufferUsageFlags(flags);
}
CommandBufferBeginInfo::CommandBufferBeginInfo(NoInitT) noexcept {}
CommandBufferBeginInfo::CommandBufferBeginInfo(const VkCommandBufferBeginInfo& info):
/* Can't use {} with GCC 4.8 here because it tries to initialize the first
member instead of doing a copy */
_info(info) {}
CommandBuffer& CommandBuffer::begin(const CommandBufferBeginInfo& info) {
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS((**_device).BeginCommandBuffer(_handle, info));
return *this;
}
void CommandBuffer::end() {
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS((**_device).EndCommandBuffer(_handle));
}
VkCommandBuffer CommandBuffer::release() {
const VkCommandBuffer handle = _handle;
_handle = nullptr;

119
src/Magnum/Vk/CommandBuffer.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Class @ref Magnum::Vk::CommandBuffer, enum @ref Magnum::Vk::CommandPoolResetFlag, enum set @ref Magnum::Vk::CommandPoolResetFlags
* @brief Class @ref Magnum::Vk::CommandBuffer, @ref Magnum::Vk::CommandBufferBeginInfo, enum @ref Magnum::Vk::CommandPoolResetFlag, enum set @ref Magnum::Vk::CommandPoolResetFlags
* @m_since_latest
*/
@ -40,6 +40,106 @@
namespace Magnum { namespace Vk {
/**
@brief Command buffer begin info
@m_since_latest
Wraps a @type_vk_keyword{CommandBufferBeginInfo}.
@see @ref CommandBuffer::begin()
*/
class MAGNUM_VK_EXPORT CommandBufferBeginInfo {
public:
/**
* @brief Command buffer begin flag
*
* Wraps @type_vk_keyword{CommandBufferBeginFlagBits}.
* @see @ref Flags, @ref CommandBufferBeginInfo(Flags)
*/
enum class Flag: UnsignedInt {
/**
* Each recording will be submitted only once and the command
* buffer will be reset and recorded again between each submission.
*
* @m_class{m-note m-success}
*
* @par
* Setting this flag on single-use command buffers might help
* drivers pick a better tradeoff between CPU time spent
* optimizing the commands and GPU time spent executing them.
*/
OneTimeSubmit = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
/**
* Specifies that a @ref CommandBufferLevel::Secondary buffer is
* entirely inside a render pass. Ignored for
* @ref CommandBufferLevel::Primary command buffers (the default).
*/
RenderPassContinue = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
/**
* A command buffer can be resubmitted to a queue while it is in
* the pending state, and recorded into multiple primary command
* buffers.
*/
SimultaneousUse = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
};
/**
* @brief Command buffer begin flags
*
* Type-safe wrapper for @type_vk_keyword{CommandBufferBeginFlags}.
* @see @ref CommandBufferBeginInfo(Flags)
*/
typedef Containers::EnumSet<Flag> Flags;
/**
* @brief Constructor
* @param flags Command buffer begin flags
*
* The following @type_vk{CommandBufferBeginInfo} fields are pre-filled
* in addition to `sType`, everything else is zero-filled:
*
* - `flags`
*/
/* cmd.begin(CommandBufferBeginInfo::Flag::OneTimeSubmit) doesn't work
anyway (would need an extra conversion from Flag to Flags), so no
point in making this implicit. */
explicit CommandBufferBeginInfo(Flags flags = {});
/**
* @brief Construct without initializing the contents
*
* Note that not even the `sType` field is set --- the structure has to
* be fully initialized afterwards in order to be usable.
*/
explicit CommandBufferBeginInfo(NoInitT) noexcept;
/**
* @brief Construct from existing data
*
* Copies the existing values verbatim, pointers are kept unchanged
* without taking over the ownership. Modifying the newly created
* instance will not modify the original data nor the pointed-to data.
*/
explicit CommandBufferBeginInfo(const VkCommandBufferBeginInfo& info);
/** @brief Underlying @type_vk{CommandBufferBeginInfo} structure */
VkCommandBufferBeginInfo& operator*() { return _info; }
/** @overload */
const VkCommandBufferBeginInfo& operator*() const { return _info; }
/** @overload */
VkCommandBufferBeginInfo* operator->() { return &_info; }
/** @overload */
const VkCommandBufferBeginInfo* operator->() const { return &_info; }
/** @overload */
operator const VkCommandBufferBeginInfo*() const { return &_info; }
private:
VkCommandBufferBeginInfo _info;
};
CORRADE_ENUMSET_OPERATORS(CommandBufferBeginInfo::Flags)
/**
@brief Command buffer reset flag
@m_since_latest
@ -150,6 +250,23 @@ class MAGNUM_VK_EXPORT CommandBuffer {
*/
VkCommandBuffer release();
/**
* @brief Begin command buffer recording
* @return Reference to self (for method chaining)
*
* @see @fn_vk_keyword{BeginCommandBuffer}
*/
CommandBuffer& begin(const CommandBufferBeginInfo& info = CommandBufferBeginInfo{});
/**
* @brief End command buffer recording
*
* As this function is expected to be called last, it doesn't return a
* reference to self for method chaining.
* @see @fn_vk_keyword{EndCommandBuffer}
*/
void end();
private:
friend CommandPool;

35
src/Magnum/Vk/Test/CommandBufferTest.cpp

@ -33,15 +33,48 @@ namespace Magnum { namespace Vk { namespace Test { namespace {
struct CommandBufferTest: TestSuite::Tester {
explicit CommandBufferTest();
void beginInfoConstruct();
void beginInfoConstructNoInit();
void beginInfoConstructFromVk();
void constructNoCreate();
void constructCopy();
};
CommandBufferTest::CommandBufferTest() {
addTests({&CommandBufferTest::constructNoCreate,
addTests({&CommandBufferTest::beginInfoConstruct,
&CommandBufferTest::beginInfoConstructNoInit,
&CommandBufferTest::beginInfoConstructFromVk,
&CommandBufferTest::constructNoCreate,
&CommandBufferTest::constructCopy});
}
void CommandBufferTest::beginInfoConstruct() {
CommandBufferBeginInfo info{CommandBufferBeginInfo::Flag::OneTimeSubmit};
CORRADE_COMPARE(info->flags, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
}
void CommandBufferTest::beginInfoConstructNoInit() {
CommandBufferBeginInfo info{NoInit};
info->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
new(&info) CommandBufferBeginInfo{NoInit};
CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
CORRADE_VERIFY((std::is_nothrow_constructible<CommandBufferBeginInfo, NoInitT>::value));
/* Implicit construction is not allowed */
CORRADE_VERIFY(!(std::is_convertible<NoInitT, CommandBufferBeginInfo>::value));
}
void CommandBufferTest::beginInfoConstructFromVk() {
VkCommandBufferBeginInfo vkInfo;
vkInfo.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
CommandBufferBeginInfo info{vkInfo};
CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
}
void CommandBufferTest::constructNoCreate() {
{
CommandBuffer buffer{NoCreate};

20
src/Magnum/Vk/Test/CommandBufferVkTest.cpp

@ -40,6 +40,8 @@ struct CommandBufferVkTest: VulkanTester {
void wrap();
void reset();
void beginEnd();
};
CommandBufferVkTest::CommandBufferVkTest() {
@ -47,7 +49,9 @@ CommandBufferVkTest::CommandBufferVkTest() {
&CommandBufferVkTest::constructMove,
&CommandBufferVkTest::wrap,
&CommandBufferVkTest::reset});
&CommandBufferVkTest::reset,
&CommandBufferVkTest::beginEnd});
}
void CommandBufferVkTest::construct() {
@ -122,6 +126,20 @@ void CommandBufferVkTest::reset() {
CORRADE_VERIFY(true);
}
void CommandBufferVkTest::beginEnd() {
CommandPool pool{device(), CommandPoolCreateInfo{
device().properties().pickQueueFamily(QueueFlag::Graphics)}};
pool.allocate()
.begin(CommandBufferBeginInfo{
CommandBufferBeginInfo::Flag::OneTimeSubmit
})
.end();
/* Does not do anything visible, so just test that it didn't blow up */
CORRADE_VERIFY(true);
}
}}}}
CORRADE_TEST_MAIN(Magnum::Vk::Test::CommandBufferVkTest)

1
src/Magnum/Vk/Vk.h

@ -39,6 +39,7 @@ namespace Magnum { namespace Vk {
class Buffer;
class BufferCreateInfo;
class CommandBuffer;
/* CommandBufferBeginInfo is useful only in combination with CommandBuffer */
class CommandPool;
class CommandPoolCreateInfo;
class Device;

Loading…
Cancel
Save