Browse Source

Vk: implement a buffer fill command.

pull/494/head
Vladimír Vondruš 5 years ago
parent
commit
7b431a6dfb
  1. 14
      doc/snippets/MagnumVk.cpp
  2. 2
      doc/vulkan-mapping.dox
  3. 6
      src/Magnum/Vk/Buffer.cpp
  4. 9
      src/Magnum/Vk/Buffer.h
  5. 30
      src/Magnum/Vk/CommandBuffer.h
  6. 48
      src/Magnum/Vk/Test/BufferVkTest.cpp

14
doc/snippets/MagnumVk.cpp

@ -227,6 +227,20 @@ buffer.bindMemory(memory, 0);
/* [Buffer-creation-custom-allocation] */
}
{
Vk::Device device{NoCreate};
Vk::CommandBuffer cmd{NoCreate};
/* [Buffer-usage-fill] */
Vk::Buffer buffer{device, Vk::BufferCreateInfo{
Vk::BufferUsage::TransferDestination|DOXYGEN_IGNORE(Vk::BufferUsage{}), DOXYGEN_IGNORE(0)
}, DOXYGEN_IGNORE(Vk::MemoryFlag{})};
DOXYGEN_IGNORE()
cmd.fillBuffer(buffer, 0x00000000);
/* [Buffer-usage-fill] */
}
{
/* The include should be a no-op here since it was already included above */
/* [CommandPool-creation] */

2
doc/vulkan-mapping.dox

@ -142,7 +142,7 @@ Vulkan function | Matching API
@fn_vk{CmdDrawIndirect} | |
@fn_vk{CmdDrawIndirectCount} @m_class{m-label m-flat m-success} **KHR, 1.2** | |
@fn_vk{CmdExecuteCommands} | |
@fn_vk{CmdFillBuffer} | |
@fn_vk{CmdFillBuffer} | @ref CommandBuffer::fillBuffer()
@fn_vk{CmdInsertDebugUtilsLabelEXT} @m_class{m-label m-flat m-warning} **EXT** | |
@fn_vk{CmdPipelineBarrier} | @ref CommandBuffer::pipelineBarrier()
@fn_vk{CmdPushConstants} | |

6
src/Magnum/Vk/Buffer.cpp

@ -25,6 +25,7 @@
#include "Buffer.h"
#include "BufferCreateInfo.h"
#include "CommandBuffer.h"
#include "Magnum/Vk/Assert.h"
#include "Magnum/Vk/Device.h"
@ -159,4 +160,9 @@ VkResult Buffer::bindMemoryImplementation11(Device& device, UnsignedInt count, c
return device->BindBufferMemory2(device, count, infos);
}
CommandBuffer& CommandBuffer::fillBuffer(const VkBuffer buffer, const UnsignedLong offset, const UnsignedLong size, UnsignedInt value) {
(**_device).CmdFillBuffer(_handle, buffer, offset, size, value);
return *this;
}
}}

9
src/Magnum/Vk/Buffer.h

@ -76,6 +76,15 @@ available through @ref dedicatedMemory(). This matches current behavior of the
above, except that you have more control over choosing and allocating the
memory.
@section Vk-Buffer-usage Buffer usage
@subsection Vk-Buffer-usage-fill Clearing / filling buffer data
The following snippet shows zero-filling the whole buffer using
@ref CommandBuffer::fillBuffer():
@snippet MagnumVk.cpp Buffer-usage-fill
@see @ref Image
*/
class MAGNUM_VK_EXPORT Buffer {

30
src/Magnum/Vk/CommandBuffer.h

@ -426,6 +426,36 @@ class MAGNUM_VK_EXPORT CommandBuffer {
/** @overload */
CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, std::initializer_list<ImageMemoryBarrier> imageMemoryBarriers, DependencyFlags dependencyFlags = {});
/**
* @brief Fill a buffer region with a fixed value
* @param buffer Source @p Buffer or a raw Vulkan buffer handle to
* fill. Expected to have been created with
* @ref BufferUsage::TransferDestination.
* @param offset Offset of the region to fill, in bytes
* @param size Size of the region to fill, in bytes
* @param value A 4-byte value to repeat in the region, interpreted
* accoding to the machine endianness. If @p size is not divisible
* by 4, the last remaining bytes are not filled.
* @return Reference to self (for method chaining)
*
* Allowed only outside of a render pass. See @ref Vk-Buffer-usage-fill
* for a usage example.
* @see @fn_vk_keyword{CmdFillBuffer}
*/
CommandBuffer& fillBuffer(VkBuffer buffer, UnsignedLong offset, UnsignedLong size, UnsignedInt value);
/**
* @brief Fill the whole buffer with a fixed value
* @return Reference to self (for method chaining)
*
* Allowed only outside of a render pass. Equivalent to
* @ref fillBuffer(VkBuffer, UnsignedLong, UnsignedLong, UnsignedInt)
* with @p offset set to @cpp 0 @ce and @p size to @def_vk{WHOLE_SIZE}.
*/
CommandBuffer& fillBuffer(VkBuffer buffer, UnsignedInt value) {
return fillBuffer(buffer, 0, VK_WHOLE_SIZE, value);
}
private:
friend CommandPool;
friend Implementation::DeviceState;

48
src/Magnum/Vk/Test/BufferVkTest.cpp

@ -23,12 +23,19 @@
DEALINGS IN THE SOFTWARE.
*/
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/StringView.h>
#include <Corrade/TestSuite/Compare/Numeric.h>
#include <Corrade/Utility/Algorithms.h>
#include "Magnum/Vk/BufferCreateInfo.h"
#include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/CommandPoolCreateInfo.h"
#include "Magnum/Vk/DeviceProperties.h"
#include "Magnum/Vk/Fence.h"
#include "Magnum/Vk/Handle.h"
#include "Magnum/Vk/MemoryAllocateInfo.h"
#include "Magnum/Vk/Pipeline.h"
#include "Magnum/Vk/Result.h"
#include "Magnum/Vk/VulkanTester.h"
@ -48,6 +55,8 @@ struct BufferVkTest: VulkanTester {
void bindDedicatedMemory();
void directAllocation();
void cmdFillBuffer();
};
BufferVkTest::BufferVkTest() {
@ -61,9 +70,13 @@ BufferVkTest::BufferVkTest() {
&BufferVkTest::bindMemory,
&BufferVkTest::bindDedicatedMemory,
&BufferVkTest::directAllocation});
&BufferVkTest::directAllocation,
&BufferVkTest::cmdFillBuffer});
}
using namespace Containers::Literals;
void BufferVkTest::construct() {
{
Buffer buffer{device(), BufferCreateInfo{BufferUsage::StorageBuffer, 1024}, NoAllocate};
@ -169,6 +182,39 @@ void BufferVkTest::directAllocation() {
CORRADE_VERIFY(buffer.dedicatedMemory().handle());
}
void BufferVkTest::cmdFillBuffer() {
CommandPool pool{device(), CommandPoolCreateInfo{
device().properties().pickQueueFamily(QueueFlag::Graphics)}};
CommandBuffer cmd = pool.allocate();
Buffer a{device(), BufferCreateInfo{
BufferUsage::TransferSource|BufferUsage::TransferDestination, 16
}, MemoryFlag::HostVisible};
Utility::copy("0123456789abcdef"_s, a.dedicatedMemory().map());
cmd.begin()
.fillBuffer(a, 4, 8, 0x2e2e2e2e)
.pipelineBarrier(
PipelineStage::Transfer, PipelineStage::Host,
{{Access::TransferWrite, Access::HostRead}},
{}, {})
.end();
queue().submit({SubmitInfo{}.setCommandBuffers({cmd})}).wait();
CORRADE_COMPARE(arrayView(a.dedicatedMemory().mapRead()), "0123........cdef"_s);
/* Test the full fill as well */
pool.reset();
cmd.begin()
.fillBuffer(a, 0x2e2e2e2e)
.pipelineBarrier(
PipelineStage::Transfer, PipelineStage::Host,
{{Access::TransferWrite, Access::HostRead}},
{}, {})
.end();
queue().submit({SubmitInfo{}.setCommandBuffers({cmd})}).wait();
CORRADE_COMPARE(arrayView(a.dedicatedMemory().mapRead()), "................"_s);
}
}}}}
CORRADE_TEST_MAIN(Magnum::Vk::Test::BufferVkTest)

Loading…
Cancel
Save