From e725528b5a1f7e84c0bc1fc5484628ff44bd28b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 16 Nov 2020 16:12:12 +0100 Subject: [PATCH] Vk: ability to allocate Image directly during construction. --- src/Magnum/Vk/Image.cpp | 9 +++++++++ src/Magnum/Vk/Image.h | 20 +++++++++++++++++++- src/Magnum/Vk/Test/ImageVkTest.cpp | 24 +++++++++++++++++------- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/Magnum/Vk/Image.cpp b/src/Magnum/Vk/Image.cpp index c7ae90e09..4f2bb9411 100644 --- a/src/Magnum/Vk/Image.cpp +++ b/src/Magnum/Vk/Image.cpp @@ -27,6 +27,7 @@ #include "Magnum/Vk/Assert.h" #include "Magnum/Vk/Device.h" +#include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Handle.h" #include "Magnum/Vk/Integration.h" #include "Magnum/Vk/Implementation/DeviceState.h" @@ -78,6 +79,14 @@ Image::Image(Device& device, const ImageCreateInfo& info, NoAllocateT): _device{ MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreateImage(device, info, nullptr, &_handle)); } +Image::Image(Device& device, const ImageCreateInfo& info, const MemoryFlags memoryFlags): Image{device, info, NoAllocate} { + const MemoryRequirements requirements = memoryRequirements(); + bindDedicatedMemory(Memory{device, MemoryAllocateInfo{ + requirements.size(), + device.properties().pickMemory(memoryFlags, requirements.memories()) + }}); +} + Image::Image(NoCreateT): _device{}, _handle{}, _dedicatedMemory{NoCreate} {} Image::Image(Image&& other) noexcept: _device{other._device}, _handle{other._handle}, _flags{other._flags}, _dedicatedMemory{std::move(other._dedicatedMemory)} { diff --git a/src/Magnum/Vk/Image.h b/src/Magnum/Vk/Image.h index 6b381f817..804e736f8 100644 --- a/src/Magnum/Vk/Image.h +++ b/src/Magnum/Vk/Image.h @@ -355,10 +355,28 @@ class MAGNUM_VK_EXPORT Image { * @param device Vulkan device to create the image on * @param info Image creation info * - * @see @fn_vk_keyword{CreateImage} + * Use @ref memoryRequirements(), @ref Memory and @ref bindMemory() to + * bind a memory (sub)allocation to the image. + * @see @ref Image(Device&, const ImageCreateInfo&, MemoryFlags), + * @fn_vk_keyword{CreateImage} */ explicit Image(Device& device, const ImageCreateInfo& info, NoAllocateT); + /** + * @brief Construct an image + * @param device Vulkan device to create the image on + * @param info Image creation info + * @param memoryFlags Memory allocation flags + * + * Compared to @ref Image(Device&, const ImageCreateInfo&, NoAllocateT) + * allocates a memory satisfying @p memoryFlags as well. + * + * @attention At this point, a dedicated allocation is used, + * subsequently accessible through @ref dedicatedMemory(). This + * behavior may change in the future. + */ + explicit Image(Device& device, const ImageCreateInfo& info, MemoryFlags memoryFlags); + /** * @brief Construct without creating the image * diff --git a/src/Magnum/Vk/Test/ImageVkTest.cpp b/src/Magnum/Vk/Test/ImageVkTest.cpp index 57763a186..1fde01e8f 100644 --- a/src/Magnum/Vk/Test/ImageVkTest.cpp +++ b/src/Magnum/Vk/Test/ImageVkTest.cpp @@ -53,6 +53,8 @@ struct ImageVkTest: VulkanTester { void bindMemory(); void bindDedicatedMemory(); + + void directAllocation(); }; ImageVkTest::ImageVkTest() { @@ -70,7 +72,9 @@ ImageVkTest::ImageVkTest() { &ImageVkTest::memoryRequirements, &ImageVkTest::bindMemory, - &ImageVkTest::bindDedicatedMemory}); + &ImageVkTest::bindDedicatedMemory, + + &ImageVkTest::directAllocation}); } void ImageVkTest::construct1D() { @@ -158,14 +162,11 @@ void ImageVkTest::constructCubeMapArray() { } void ImageVkTest::constructMove() { + /* Verify that also the dedicated memory gets moved */ Image a{device(), ImageCreateInfo2D{ImageUsage::ColorAttachment, - VK_FORMAT_R8G8B8A8_UNORM, {256, 256}, 1}, NoAllocate}; + VK_FORMAT_R8G8B8A8_UNORM, {256, 256}, 1}, + Vk::MemoryFlag::DeviceLocal}; VkImage handle = a.handle(); - - /* Verify that also the dedicated memory gets moved */ - MemoryRequirements requirements = a.memoryRequirements(); - a.bindDedicatedMemory(Vk::Memory{device(), Vk::MemoryAllocateInfo{requirements.size(), - device().properties().pickMemory(Vk::MemoryFlag::DeviceLocal, requirements.memories())}}); VkDeviceMemory memoryHandle = a.dedicatedMemory().handle(); Image b = std::move(a); @@ -263,6 +264,15 @@ void ImageVkTest::bindDedicatedMemory() { CORRADE_COMPARE(image.dedicatedMemory().handle(), handle); } +void ImageVkTest::directAllocation() { + Image image{device(), ImageCreateInfo2D{ImageUsage::Sampled, + VK_FORMAT_R8G8B8A8_UNORM, {256, 256}, 8}, Vk::MemoryFlag::DeviceLocal}; + + /* Not sure what else to test here */ + CORRADE_VERIFY(image.hasDedicatedMemory()); + CORRADE_VERIFY(image.dedicatedMemory().handle()); +} + }}}} CORRADE_TEST_MAIN(Magnum::Vk::Test::ImageVkTest)