diff --git a/doc/vulkan-mapping.dox b/doc/vulkan-mapping.dox index afe1d23e8..c9dcebe31 100644 --- a/doc/vulkan-mapping.dox +++ b/doc/vulkan-mapping.dox @@ -189,7 +189,7 @@ Vulkan function | Matching API @fn_vk{GetBufferDeviceAddress} @m_class{m-label m-flat m-success} **KHR, 1.2** | | @fn_vk{GetBufferOpaqueCaptureAddress} @m_class{m-label m-flat m-success} **KHR, 1.2** | | @fn_vk{GetDeviceMemoryOpaqueCaptureAddress} @m_class{m-label m-flat m-success} **KHR, 1.2** | | -@fn_vk{GetBufferMemoryRequirements}, \n @fn_vk{GetBufferMemoryRequirements2} @m_class{m-label m-flat m-success} **KHR, 1.1** | | +@fn_vk{GetBufferMemoryRequirements}, \n @fn_vk{GetBufferMemoryRequirements2} @m_class{m-label m-flat m-success} **KHR, 1.1** | @ref Buffer::memoryRequirements() @fn_vk{GetDescriptorSetLayoutSupport} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @fn_vk{GetDeviceGroupPeerMemoryFeatures} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @fn_vk{GetDeviceMemoryCommitment} | | @@ -311,6 +311,7 @@ Vulkan structure | Matching API Vulkan structure | Matching API --------------------------------------- | ------------ @type_vk{BufferCreateInfo} | @ref BufferCreateInfo +@type_vk{BufferMemoryRequirementsInfo} | not exposed, internal to @ref Buffer::memoryRequirements() @subsection vulkan-mapping-structures-c C diff --git a/src/Magnum/Vk/Buffer.cpp b/src/Magnum/Vk/Buffer.cpp index d8ab43676..ce4a46943 100644 --- a/src/Magnum/Vk/Buffer.cpp +++ b/src/Magnum/Vk/Buffer.cpp @@ -28,6 +28,8 @@ #include "Magnum/Vk/Assert.h" #include "Magnum/Vk/Device.h" #include "Magnum/Vk/Handle.h" +#include "Magnum/Vk/Memory.h" +#include "Magnum/Vk/Implementation/DeviceState.h" namespace Magnum { namespace Vk { @@ -79,10 +81,31 @@ Buffer& Buffer::operator=(Buffer&& other) noexcept { return *this; } +MemoryRequirements Buffer::memoryRequirements() const { + MemoryRequirements requirements; + VkBufferMemoryRequirementsInfo2 info{}; + info.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2; + info.buffer = _handle; + _device->state().getBufferMemoryRequirementsImplementation(*_device, info, requirements); + return requirements; +} + VkBuffer Buffer::release() { const VkBuffer handle = _handle; _handle = {}; return handle; } +void Buffer::getMemoryRequirementsImplementationDefault(Device& device, const VkBufferMemoryRequirementsInfo2& info, VkMemoryRequirements2& requirements) { + device->GetBufferMemoryRequirements(device, info.buffer, &requirements.memoryRequirements); +} + +void Buffer::getMemoryRequirementsImplementationKHR(Device& device, const VkBufferMemoryRequirementsInfo2& info, VkMemoryRequirements2& requirements) { + device->GetBufferMemoryRequirements2KHR(device, &info, &requirements); +} + +void Buffer::getMemoryRequirementsImplementation11(Device& device, const VkBufferMemoryRequirementsInfo2& info, VkMemoryRequirements2& requirements) { + device->GetBufferMemoryRequirements2(device, &info, &requirements); +} + }} diff --git a/src/Magnum/Vk/Buffer.h b/src/Magnum/Vk/Buffer.h index 377698064..b11474238 100644 --- a/src/Magnum/Vk/Buffer.h +++ b/src/Magnum/Vk/Buffer.h @@ -40,6 +40,8 @@ namespace Magnum { namespace Vk { +namespace Implementation { struct DeviceState; } + /** @brief Buffer usage @m_since_latest @@ -222,6 +224,14 @@ class MAGNUM_VK_EXPORT Buffer { /** @brief Handle flags */ HandleFlags handleFlags() const { return _flags; } + /** + * @brief Buffer memory requirements + * + * @see @fn_vk_keyword{GetBufferMemoryRequirements2}, + * @fn_vk_keyword{GetBufferMemoryRequirements} + */ + MemoryRequirements memoryRequirements() const; + /** * @brief Release the underlying Vulkan buffer * @@ -233,6 +243,12 @@ class MAGNUM_VK_EXPORT Buffer { VkBuffer release(); private: + friend Implementation::DeviceState; + + MAGNUM_VK_LOCAL static void getMemoryRequirementsImplementationDefault(Device& device, const VkBufferMemoryRequirementsInfo2& info, VkMemoryRequirements2& requirements); + MAGNUM_VK_LOCAL static void getMemoryRequirementsImplementationKHR(Device& device, const VkBufferMemoryRequirementsInfo2& info, VkMemoryRequirements2& requirements); + MAGNUM_VK_LOCAL static void getMemoryRequirementsImplementation11(Device& device, const VkBufferMemoryRequirementsInfo2& info, VkMemoryRequirements2& requirements); + /* Can't be a reference because of the NoCreate constructor */ Device* _device; diff --git a/src/Magnum/Vk/Implementation/DeviceState.cpp b/src/Magnum/Vk/Implementation/DeviceState.cpp index 6ebc74cd4..aa9151692 100644 --- a/src/Magnum/Vk/Implementation/DeviceState.cpp +++ b/src/Magnum/Vk/Implementation/DeviceState.cpp @@ -25,6 +25,7 @@ #include "DeviceState.h" +#include "Magnum/Vk/Buffer.h" #include "Magnum/Vk/Device.h" #include "Magnum/Vk/Extensions.h" #include "Magnum/Vk/Image.h" @@ -40,10 +41,13 @@ DeviceState::DeviceState(Device& device) { } if(device.isVersionSupported(Version::Vk11)) { + getBufferMemoryRequirementsImplementation = &Buffer::getMemoryRequirementsImplementation11; getImageMemoryRequirementsImplementation = &Image::getMemoryRequirementsImplementation11; } else if(device.isExtensionEnabled()) { + getBufferMemoryRequirementsImplementation = &Buffer::getMemoryRequirementsImplementationKHR; getImageMemoryRequirementsImplementation = &Image::getMemoryRequirementsImplementationKHR; } else { + getBufferMemoryRequirementsImplementation = &Buffer::getMemoryRequirementsImplementationDefault; getImageMemoryRequirementsImplementation = &Image::getMemoryRequirementsImplementationDefault; } diff --git a/src/Magnum/Vk/Implementation/DeviceState.h b/src/Magnum/Vk/Implementation/DeviceState.h index dea6b1856..07a9b0f08 100644 --- a/src/Magnum/Vk/Implementation/DeviceState.h +++ b/src/Magnum/Vk/Implementation/DeviceState.h @@ -34,7 +34,8 @@ struct DeviceState { explicit DeviceState(Device& instance); void(*getDeviceQueueImplementation)(Device&, const VkDeviceQueueInfo2&, VkQueue&); - /** @todo put this eventually into a dedicated image state struct? */ + /** @todo put this eventually into a dedicated buffer / image state struct? */ + void(*getBufferMemoryRequirementsImplementation)(Device&, const VkBufferMemoryRequirementsInfo2&, VkMemoryRequirements2&); void(*getImageMemoryRequirementsImplementation)(Device&, const VkImageMemoryRequirementsInfo2&, VkMemoryRequirements2&); void(*bindImageMemoryImplementation)(Device&, UnsignedInt, const VkBindImageMemoryInfo*); }; diff --git a/src/Magnum/Vk/Memory.h b/src/Magnum/Vk/Memory.h index f344435d9..d52a2230f 100644 --- a/src/Magnum/Vk/Memory.h +++ b/src/Magnum/Vk/Memory.h @@ -125,7 +125,8 @@ MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, MemoryFlags value); @m_since_latest Wraps a @type_vk_keyword{MemoryRequirements2}. Not constructible directly, -returned from @ref Image::memoryRequirements(). +returned from @ref Image::memoryRequirements() and +@ref Buffer::memoryRequirements(). @see @ref DeviceProperties::pickMemory() */ class MAGNUM_VK_EXPORT MemoryRequirements { @@ -176,6 +177,7 @@ class MAGNUM_VK_EXPORT MemoryRequirements { } private: + friend Buffer; friend Image; explicit MemoryRequirements(); diff --git a/src/Magnum/Vk/Test/BufferVkTest.cpp b/src/Magnum/Vk/Test/BufferVkTest.cpp index 065b3202c..9714a3cac 100644 --- a/src/Magnum/Vk/Test/BufferVkTest.cpp +++ b/src/Magnum/Vk/Test/BufferVkTest.cpp @@ -25,6 +25,7 @@ #include "Magnum/Vk/Buffer.h" #include "Magnum/Vk/Handle.h" +#include "Magnum/Vk/Memory.h" #include "Magnum/Vk/Result.h" #include "Magnum/Vk/VulkanTester.h" @@ -37,13 +38,17 @@ struct BufferVkTest: VulkanTester { void constructMove(); void wrap(); + + void memoryRequirements(); }; BufferVkTest::BufferVkTest() { addTests({&BufferVkTest::construct, &BufferVkTest::constructMove, - &BufferVkTest::wrap}); + &BufferVkTest::wrap, + + &BufferVkTest::memoryRequirements}); } void BufferVkTest::construct() { @@ -92,6 +97,13 @@ void BufferVkTest::wrap() { device()->DestroyBuffer(device(), buffer, nullptr); } +void BufferVkTest::memoryRequirements() { + Buffer buffer{device(), BufferCreateInfo{BufferUsage::StorageBuffer, 16384}, NoAllocate}; + + MemoryRequirements requirements = buffer.memoryRequirements(); + CORRADE_COMPARE(requirements.size(), 16384); +} + }}}} CORRADE_TEST_MAIN(Magnum::Vk::Test::BufferVkTest)