From 909dd781dfd3fc6edead0b540956dbdc1780cb7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 11 Dec 2020 14:07:16 +0100 Subject: [PATCH] Vk: put CreateInfo structures to dedicated headers. After I implemented the render pass wrapper, seeing how the RenderPassCreateInfo structure and its dependencies were HUGE compared to the actual tiny and lean RenderPass, I felt uneasy dragging their definition along to every place where a RenderPass gets used. It's not as bad with the others, but as new extensions are implemented I expect that to get the same. This change makes it easier for me to accept that Image.h / Buffer.h depends on Memory.h. There isn't a real measurable difference when building Magnum itself (50 ms out of 7 seconds for the Vk library alone), but that's because most of the code (and tests) needs the CreateInfo structures anyway. --- doc/snippets/MagnumVk.cpp | 70 +- doc/vulkan-wrapping.dox | 51 +- src/Magnum/Vk/Buffer.cpp | 2 + src/Magnum/Vk/Buffer.h | 131 +-- src/Magnum/Vk/BufferCreateInfo.h | 178 +++ src/Magnum/Vk/CMakeLists.txt | 8 + src/Magnum/Vk/CommandPool.cpp | 1 + src/Magnum/Vk/CommandPool.h | 93 +- src/Magnum/Vk/CommandPoolCreateInfo.h | 140 +++ src/Magnum/Vk/Device.cpp | 1 + src/Magnum/Vk/Device.h | 241 +--- src/Magnum/Vk/DeviceCreateInfo.h | 288 +++++ src/Magnum/Vk/Image.cpp | 2 + src/Magnum/Vk/Image.h | 373 +----- src/Magnum/Vk/ImageCreateInfo.h | 420 +++++++ src/Magnum/Vk/Instance.cpp | 3 + src/Magnum/Vk/Instance.h | 199 +--- src/Magnum/Vk/InstanceCreateInfo.h | 240 ++++ src/Magnum/Vk/Memory.cpp | 1 + src/Magnum/Vk/Memory.h | 143 --- src/Magnum/Vk/MemoryAllocateInfo.h | 189 +++ src/Magnum/Vk/RenderPass.cpp | 1 + src/Magnum/Vk/RenderPass.h | 966 +--------------- src/Magnum/Vk/RenderPassCreateInfo.h | 1009 +++++++++++++++++ src/Magnum/Vk/Shader.cpp | 1 + src/Magnum/Vk/Shader.h | 147 +-- src/Magnum/Vk/ShaderCreateInfo.h | 191 ++++ src/Magnum/Vk/Test/BufferTest.cpp | 2 +- src/Magnum/Vk/Test/BufferVkTest.cpp | 4 +- src/Magnum/Vk/Test/CommandBufferVkTest.cpp | 2 +- src/Magnum/Vk/Test/CommandPoolTest.cpp | 2 +- src/Magnum/Vk/Test/CommandPoolVkTest.cpp | 2 +- src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp | 2 +- src/Magnum/Vk/Test/DeviceTest.cpp | 2 +- src/Magnum/Vk/Test/DeviceVkTest.cpp | 4 +- src/Magnum/Vk/Test/ImageTest.cpp | 2 +- src/Magnum/Vk/Test/ImageVkTest.cpp | 4 +- src/Magnum/Vk/Test/InstanceTest.cpp | 2 +- src/Magnum/Vk/Test/InstanceVkTest.cpp | 2 +- src/Magnum/Vk/Test/MemoryTest.cpp | 2 +- src/Magnum/Vk/Test/MemoryVkTest.cpp | 2 +- src/Magnum/Vk/Test/RenderPassTest.cpp | 2 +- src/Magnum/Vk/Test/RenderPassVkTest.cpp | 2 +- src/Magnum/Vk/Test/ShaderTest.cpp | 2 +- src/Magnum/Vk/Test/ShaderVkTest.cpp | 2 +- src/Magnum/Vk/Vk.h | 10 +- src/Magnum/Vk/VulkanTester.cpp | 2 + src/Magnum/Vk/vk-info.cpp | 2 +- 48 files changed, 2817 insertions(+), 2328 deletions(-) create mode 100644 src/Magnum/Vk/BufferCreateInfo.h create mode 100644 src/Magnum/Vk/CommandPoolCreateInfo.h create mode 100644 src/Magnum/Vk/DeviceCreateInfo.h create mode 100644 src/Magnum/Vk/ImageCreateInfo.h create mode 100644 src/Magnum/Vk/InstanceCreateInfo.h create mode 100644 src/Magnum/Vk/MemoryAllocateInfo.h create mode 100644 src/Magnum/Vk/RenderPassCreateInfo.h create mode 100644 src/Magnum/Vk/ShaderCreateInfo.h diff --git a/doc/snippets/MagnumVk.cpp b/doc/snippets/MagnumVk.cpp index 0410e3020..2a839ce2a 100644 --- a/doc/snippets/MagnumVk.cpp +++ b/doc/snippets/MagnumVk.cpp @@ -30,22 +30,32 @@ #include "Magnum/Magnum.h" #include "Magnum/Math/Color.h" -#include "Magnum/Vk/Buffer.h" +#include "Magnum/Vk/BufferCreateInfo.h" #include "Magnum/Vk/CommandBuffer.h" -#include "Magnum/Vk/CommandPool.h" -#include "Magnum/Vk/Device.h" +#include "Magnum/Vk/CommandPoolCreateInfo.h" +#include "Magnum/Vk/DeviceCreateInfo.h" #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Extensions.h" #include "Magnum/Vk/ExtensionProperties.h" -#include "Magnum/Vk/Instance.h" +#include "Magnum/Vk/InstanceCreateInfo.h" #include "Magnum/Vk/Integration.h" -#include "Magnum/Vk/Image.h" +#include "Magnum/Vk/ImageCreateInfo.h" #include "Magnum/Vk/LayerProperties.h" +#include "Magnum/Vk/MemoryAllocateInfo.h" #include "Magnum/Vk/Queue.h" -#include "Magnum/Vk/RenderPass.h" -#include "Magnum/Vk/Shader.h" +#include "Magnum/Vk/RenderPassCreateInfo.h" +#include "Magnum/Vk/ShaderCreateInfo.h" #include "MagnumExternal/Vulkan/flextVkGlobal.h" +/* [wrapping-include-createinfo] */ +#include +/* [wrapping-include-createinfo] */ + +/* [wrapping-include-both] */ +#include +#include +/* [wrapping-include-both] */ + using namespace Magnum; #define DOXYGEN_IGNORE(...) __VA_ARGS__ @@ -121,7 +131,12 @@ Vk::Device device{instance, std::move(info)}; { Vk::Device device{NoCreate}; +/* The include should be a no-op here since it was already included above */ /* [Buffer-creation] */ +#include + +DOXYGEN_IGNORE() + Vk::Buffer buffer{device, Vk::BufferCreateInfo{Vk::BufferUsage::VertexBuffer, 1024*1024}, Vk::MemoryFlag::DeviceLocal @@ -149,7 +164,12 @@ buffer.bindMemory(memory, 0); } { +/* The include should be a no-op here since it was already included above */ /* [CommandPool-creation] */ +#include + +DOXYGEN_IGNORE() + Vk::Device device{DOXYGEN_IGNORE(NoCreate)}; Vk::CommandPool graphicsCommandPool{device, Vk::CommandPoolCreateInfo{ @@ -166,7 +186,12 @@ Vk::CommandBuffer commandBuffer = graphicsCommandPool.allocate(); { Vk::Instance instance; +/* The include should be a no-op here since it was already included above */ /* [Device-creation-construct-queue] */ +#include + +DOXYGEN_IGNORE() + Vk::Queue queue{NoCreate}; Vk::Device device{instance, Vk::DeviceCreateInfo{Vk::pickDevice(instance)} .addQueues(Vk::QueueFlag::Graphics, {0.0f}, {queue}) @@ -218,8 +243,7 @@ device->ResetQueryPoolEXT(device, DOXYGEN_IGNORE(pool, 0, 0)); { VkQueryPool pool{}; -/* Header included again inside a function, but it's fine as the guards will - make it empty */ +/* The include should be a no-op here since it was already included above */ /* [Device-global-function-pointers] */ #include @@ -246,7 +270,12 @@ if(device.isExtensionEnabled()) { { Vk::Device device{NoCreate}; +/* The include should be a no-op here since it was already included above */ /* [Image-creation] */ +#include + +DOXYGEN_IGNORE() + Vk::Image image{device, Vk::ImageCreateInfo2D{ Vk::ImageUsage::Sampled, VK_FORMAT_R8G8B8A8_SRGB, {1024, 1024}, 1 }, Vk::MemoryFlag::DeviceLocal @@ -276,7 +305,12 @@ image.bindMemory(memory, 0); { int argc{}; const char** argv{}; +/* The include should be a no-op here since it was already included above */ /* [Instance-creation-minimal] */ +#include + +DOXYGEN_IGNORE() + Vk::Instance instance{{argc, argv}}; /* [Instance-creation-minimal] */ } @@ -344,8 +378,7 @@ instance->EnumeratePhysicalDeviceGroupsKHR(instance, &count, properties); { Vk::Instance instance; -/* Header included again inside a function, but it's fine as the guards will - make it empty */ +/* The include should be a no-op here since it was already included above */ /* [Instance-global-function-pointers] */ #include @@ -375,7 +408,12 @@ if(instance.isExtensionEnabled()) { { Vk::Device device{NoCreate}; Containers::ArrayView vertexData, indexData; +/* The include should be a no-op here since it was already included above */ /* [Memory-allocation] */ +#include + +DOXYGEN_IGNORE() + /* Create buffers without allocating them */ Vk::Buffer vertices{device, Vk::BufferCreateInfo{Vk::BufferUsage::VertexBuffer, vertexData.size()}, @@ -419,7 +457,12 @@ indices.bindMemory(memory, indicesOffset); { Vk::Device device{DOXYGEN_IGNORE(NoCreate)}; +/* The include should be a no-op here since it was already included above */ /* [RenderPass-creation] */ +#include + +DOXYGEN_IGNORE() + Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{} .setAttachments({ VK_FORMAT_R8G8B8A8_SRGB, @@ -470,7 +513,12 @@ Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{} { Vk::Device device{DOXYGEN_IGNORE(NoCreate)}; +/* The include should be a no-op here since it was already included above */ /* [Shader-creation] */ +#include + +DOXYGEN_IGNORE() + Vk::ShaderCreateInfo info{ CORRADE_INTERNAL_ASSERT_EXPRESSION(Utility::Directory::read("shader.spv")) }; diff --git a/doc/vulkan-wrapping.dox b/doc/vulkan-wrapping.dox index 4754592d7..c3bed5cd1 100644 --- a/doc/vulkan-wrapping.dox +++ b/doc/vulkan-wrapping.dox @@ -35,6 +35,41 @@ The @ref Magnum::Vk library is a thin but high-level abstraction of the [Vulkan](https://www.khronos.org/vulkan/) GPU API, providing sane defaults with ability to opt-in for greater control and performance. +@section vulkan-wrapping-create-info CreateInfo structure wrappers + +The `*CreateInfo` / `*AllocateInfo` structures tend to be rather complex +compared to the created object and because they're only needed once when +constructing the object, their definition is put in a separate header. This +should help compile times in larger codebases where Vulkan objects are +constructed in one place and then passed around to functions, without needing +to know anything about the `CreateInfo`-related definitions anymore. Then, for +convenience, each `ThingCreateInfo.h` header is guaranteed to include the +`Thing.h` as well, so if you want both you can do for example just + +@snippet MagnumVk.cpp wrapping-include-createinfo + + + +@m_class{m-noindent} + +instead of having to verbosely include both: + +@snippet MagnumVk.cpp wrapping-include-both + +Unless said otherwise in the particular constructor docs, a `Vk::*CreateInfo` +instance has all required fields set to valid values upon construction, with +everything else optional. One exception is for example +@ref Vk::DeviceCreateInfo, where the user is expected to call +@ref Vk::DeviceCreateInfo::addQueues() "addQueues()" as well. + +To completely mitigate the overhead from instantiating wrapper `*CreateInfo` +classes, each of them can also be constructed using the @ref NoInit tag, which +will skip all initialization and leave the contents unspecified to be filled +later. In case the structure contains some heap-allocated state, the +@ref NoInit constructor is guaranteed to not allocate. Note that with +@ref NoInit constructors you have the full responsibility to correctly set up +all members. + @section vulkan-wrapping-instance-device Instance and device wrappers Compared to OpenGL, which has a concept of "current context", Vulkan doesn't @@ -65,22 +100,6 @@ tied to a particular instance/device still apply: @snippet MagnumVk.cpp Instance-global-function-pointers -@section vulkan-wrapping-create-info CreateInfo structure wrappers - -Unless said otherwise in the particular constructor docs, a`Vk::*CreateInfo` -instance has all required fields set to valid values upon construction, with -everything else optional. One exception is for example -@ref Vk::DeviceCreateInfo, where the user is expected to call -@ref Vk::DeviceCreateInfo::addQueues() "addQueues()" as well. - -To completely mitigate the overhead from instantiating wrapper `*CreateInfo` -classes, each of them can also be constructed using the @ref NoInit tag, which -will skip all initialization and leave the contents unspecified to be filled -later. In case the structure contains some heap-allocated state, the -@ref NoInit constructor is guaranteed to not allocate. Note that with -@ref NoInit constructors you have the full responsibility to correctly set up -all members. - @section vulkan-wrapping-host-allocation Host memory allocation As opposed to device memory allocation, which is exposed through diff --git a/src/Magnum/Vk/Buffer.cpp b/src/Magnum/Vk/Buffer.cpp index 9aaa235b6..1ee4ed0e0 100644 --- a/src/Magnum/Vk/Buffer.cpp +++ b/src/Magnum/Vk/Buffer.cpp @@ -24,11 +24,13 @@ */ #include "Buffer.h" +#include "BufferCreateInfo.h" #include "Magnum/Vk/Assert.h" #include "Magnum/Vk/Device.h" #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Handle.h" +#include "Magnum/Vk/MemoryAllocateInfo.h" #include "Magnum/Vk/Implementation/DeviceState.h" namespace Magnum { namespace Vk { diff --git a/src/Magnum/Vk/Buffer.h b/src/Magnum/Vk/Buffer.h index 70952c1bc..97e89f8fc 100644 --- a/src/Magnum/Vk/Buffer.h +++ b/src/Magnum/Vk/Buffer.h @@ -26,7 +26,7 @@ */ /** @file - * @brief Class @ref Magnum::Vk::BufferCreateInfo, @ref Magnum::Vk::Buffer, enum @ref Magnum::Vk::BufferUsage, enum set @ref Magnum::Vk::BufferUsages + * @brief Class @ref Magnum::Vk::Buffer * @m_since_latest */ @@ -43,135 +43,6 @@ namespace Magnum { namespace Vk { namespace Implementation { struct DeviceState; } -/** -@brief Buffer usage -@m_since_latest - -Wraps a @type_vk_keyword{BufferUsageFlagBits}. -@see @ref BufferUsages, @ref BufferCreateInfo -@m_enum_values_as_keywords -*/ -enum class BufferUsage: UnsignedInt { - /** Source of a transfer command */ - TransferSource = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - - /** Destination of a transfer command */ - TransferDestination = VK_BUFFER_USAGE_TRANSFER_DST_BIT, - - /** Suitable for creating a uniform texel buffer view */ - UniformTexelBuffer = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, - - /** Suitable for creating a storage texel buffer view */ - StorageTexelBuffer = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, - - /** Suitable for a uniform buffer */ - UniformBuffer = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - - /** Suitable for a storage buffer */ - StorageBuffer = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - - /** Suitable for an index buffer */ - IndexBuffer = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - - /** Suitable for a vertex buffer */ - VertexBuffer = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - - /** Suitable for a indirect draw buffer */ - IndirectBuffer = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, - - /** @todo VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, 1.2 */ -}; - -/** -@brief Buffer usages -@m_since_latest - -Type-safe wrapper for @type_vk_keyword{BufferUsageFlags}. -@see @ref BufferCreateInfo -*/ -typedef Containers::EnumSet BufferUsages; - -CORRADE_ENUMSET_OPERATORS(BufferUsages) - -/** -@brief Buffer creation info -@m_since_latest - -Wraps a @type_vk_keyword{BufferCreateInfo}. See -@ref Vk-Buffer-creation "Buffer creation" for usage information. -*/ -class MAGNUM_VK_EXPORT BufferCreateInfo { - public: - /** - * @brief Buffer creation flag - * - * Wraps @type_vk_keyword{BufferCreateFlagBits}. - * @see @ref Flags, @ref BufferCreateInfo() - * @m_enum_values_as_keywords - */ - enum class Flag: UnsignedInt { - /** @todo sparse binding, protected ... */ - }; - - /** - * @brief Buffer creation flags - * - * Type-safe wrapper for @type_vk_keyword{BufferCreateFlags}. - * @see @ref BufferCreateInfo() - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param usages Desired buffer usage. At least one flag is - * required. - * @param size Buffer size - * @param flags Buffer creation flags - * - * The following @type_vk{BufferCreateInfo} fields are pre-filled in - * addition to `sType`, everything else is zero-filled: - * - * - `flags` - * - `size` - * - `usage` to @p usages - * - `sharingMode` to @val_vk{SHARING_MODE_EXCLUSIVE,SharingMode} - */ - explicit BufferCreateInfo(BufferUsages usages, UnsignedLong size, 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 BufferCreateInfo(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 BufferCreateInfo(const VkBufferCreateInfo& info); - - /** @brief Underlying @type_vk{BufferCreateInfo} structure */ - VkBufferCreateInfo& operator*() { return _info; } - /** @overload */ - const VkBufferCreateInfo& operator*() const { return _info; } - /** @overload */ - VkBufferCreateInfo* operator->() { return &_info; } - /** @overload */ - const VkBufferCreateInfo* operator->() const { return &_info; } - /** @overload */ - operator const VkBufferCreateInfo*() const { return &_info; } - - private: - VkBufferCreateInfo _info; -}; - -CORRADE_ENUMSET_OPERATORS(BufferCreateInfo::Flags) - /** @brief Buffer @m_since_latest diff --git a/src/Magnum/Vk/BufferCreateInfo.h b/src/Magnum/Vk/BufferCreateInfo.h new file mode 100644 index 000000000..04ba371a5 --- /dev/null +++ b/src/Magnum/Vk/BufferCreateInfo.h @@ -0,0 +1,178 @@ +#ifndef Magnum_Vk_BufferCreateInfo_h +#define Magnum_Vk_BufferCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::BufferCreateInfo, enum @ref Magnum::Vk::BufferUsage, enum set @ref Magnum::Vk::BufferUsages + * @m_since_latest + */ + +#include + +#include "Magnum/Magnum.h" +#include "Magnum/Tags.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Buffer usage +@m_since_latest + +Wraps a @type_vk_keyword{BufferUsageFlagBits}. +@see @ref BufferUsages, @ref BufferCreateInfo +@m_enum_values_as_keywords +*/ +enum class BufferUsage: UnsignedInt { + /** Source of a transfer command */ + TransferSource = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + + /** Destination of a transfer command */ + TransferDestination = VK_BUFFER_USAGE_TRANSFER_DST_BIT, + + /** Suitable for creating a uniform texel buffer view */ + UniformTexelBuffer = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, + + /** Suitable for creating a storage texel buffer view */ + StorageTexelBuffer = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, + + /** Suitable for a uniform buffer */ + UniformBuffer = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + + /** Suitable for a storage buffer */ + StorageBuffer = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + + /** Suitable for an index buffer */ + IndexBuffer = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + + /** Suitable for a vertex buffer */ + VertexBuffer = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + + /** Suitable for a indirect draw buffer */ + IndirectBuffer = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, + + /** @todo VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, 1.2 */ +}; + +/** +@brief Buffer usages +@m_since_latest + +Type-safe wrapper for @type_vk_keyword{BufferUsageFlags}. +@see @ref BufferCreateInfo +*/ +typedef Containers::EnumSet BufferUsages; + +CORRADE_ENUMSET_OPERATORS(BufferUsages) + +/** +@brief Buffer creation info +@m_since_latest + +Wraps a @type_vk_keyword{BufferCreateInfo}. See +@ref Vk-Buffer-creation "Buffer creation" for usage information. +*/ +class MAGNUM_VK_EXPORT BufferCreateInfo { + public: + /** + * @brief Buffer creation flag + * + * Wraps @type_vk_keyword{BufferCreateFlagBits}. + * @see @ref Flags, @ref BufferCreateInfo() + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt { + /** @todo sparse binding, protected ... */ + }; + + /** + * @brief Buffer creation flags + * + * Type-safe wrapper for @type_vk_keyword{BufferCreateFlags}. + * @see @ref BufferCreateInfo() + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param usages Desired buffer usage. At least one flag is + * required. + * @param size Buffer size + * @param flags Buffer creation flags + * + * The following @type_vk{BufferCreateInfo} fields are pre-filled in + * addition to `sType`, everything else is zero-filled: + * + * - `flags` + * - `size` + * - `usage` to @p usages + * - `sharingMode` to @val_vk{SHARING_MODE_EXCLUSIVE,SharingMode} + */ + explicit BufferCreateInfo(BufferUsages usages, UnsignedLong size, 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 BufferCreateInfo(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 BufferCreateInfo(const VkBufferCreateInfo& info); + + /** @brief Underlying @type_vk{BufferCreateInfo} structure */ + VkBufferCreateInfo& operator*() { return _info; } + /** @overload */ + const VkBufferCreateInfo& operator*() const { return _info; } + /** @overload */ + VkBufferCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkBufferCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkBufferCreateInfo*() const { return &_info; } + + private: + VkBufferCreateInfo _info; +}; + +CORRADE_ENUMSET_OPERATORS(BufferCreateInfo::Flags) + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/Buffer.h" + +#endif diff --git a/src/Magnum/Vk/CMakeLists.txt b/src/Magnum/Vk/CMakeLists.txt index 4992c92af..2c3fae6fa 100644 --- a/src/Magnum/Vk/CMakeLists.txt +++ b/src/Magnum/Vk/CMakeLists.txt @@ -54,23 +54,31 @@ set(MagnumVk_GracefulAssert_SRCS set(MagnumVk_HEADERS Assert.h Buffer.h + BufferCreateInfo.h CommandBuffer.h CommandPool.h + CommandPoolCreateInfo.h Device.h + DeviceCreateInfo.h DeviceProperties.h Enums.h Extensions.h ExtensionProperties.h Handle.h Image.h + ImageCreateInfo.h Instance.h + InstanceCreateInfo.h Integration.h LayerProperties.h Memory.h + MemoryAllocateInfo.h Queue.h RenderPass.h + RenderPassCreateInfo.h Result.h Shader.h + ShaderCreateInfo.h TypeTraits.h Version.h Vk.h diff --git a/src/Magnum/Vk/CommandPool.cpp b/src/Magnum/Vk/CommandPool.cpp index 3008f7bb2..2eb139a61 100644 --- a/src/Magnum/Vk/CommandPool.cpp +++ b/src/Magnum/Vk/CommandPool.cpp @@ -24,6 +24,7 @@ */ #include "CommandPool.h" +#include "CommandPoolCreateInfo.h" #include "Magnum/Vk/Assert.h" #include "Magnum/Vk/CommandBuffer.h" diff --git a/src/Magnum/Vk/CommandPool.h b/src/Magnum/Vk/CommandPool.h index 2570a61d7..f5c736c6b 100644 --- a/src/Magnum/Vk/CommandPool.h +++ b/src/Magnum/Vk/CommandPool.h @@ -26,7 +26,7 @@ */ /** @file - * @brief Class @ref Magnum::Vk::CommandPoolCreateInfo, @ref Magnum::Vk::CommandPool, enum @ref Magnum::Vk::CommandBufferLevel, @ref Magnum::Vk::CommandPoolResetFlag, enum set @ref Magnum::Vk::CommandPoolResetFlags + * @brief Class @ref Magnum::Vk::CommandPool, enum @ref Magnum::Vk::CommandBufferLevel, @ref Magnum::Vk::CommandPoolResetFlag, enum set @ref Magnum::Vk::CommandPoolResetFlags * @m_since_latest */ @@ -40,97 +40,6 @@ namespace Magnum { namespace Vk { -/** -@brief Command pool creation info -@m_since_latest - -Wraps a @type_vk_keyword{CommandPoolCreateInfo}. See -@ref Vk-CommandPool-creation "Command pool creation" for usage information. -*/ -class MAGNUM_VK_EXPORT CommandPoolCreateInfo { - public: - /** - * @brief Command pool creation flag - * - * Wraps @type_vk_keyword{CommandPoolCreateFlagBits}. - * @see @ref Flags, @ref CommandPoolCreateInfo(UnsignedInt, Flags) - * @m_enum_values_as_keywords - */ - enum class Flag: UnsignedInt { - /** Command buffers allocated from this pool will be short-lived */ - Transient = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, - - /** - * Allow individual command buffers to be reset to initial state - * using @ref CommandBuffer::reset() instead of just the whole pool - * using @ref CommandPool::reset(). - * - * @m_class{m-note m-success} - * - * @par - * Not using this flag may help the driver to use simpler - * per-pool allocators instead of per-buffer. - */ - ResetCommandBuffer = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT - }; - - /** - * @brief Command pool creation flags - * - * Type-safe wrapper for @type_vk_keyword{CommandPoolCreateFlags}. - * @see @ref CommandPoolCreateInfo(UnsignedInt, Flags) - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param queueFamilyIndex Queue family index - * @param flags Command pool creation flags - * - * The following @type_vk{CommandPoolCreateInfo} fields are pre-filled - * in addition to `sType`, everything else is zero-filled: - * - * - `flags` - * - `queueFamilyIndex` - * - * @see @ref DeviceProperties::pickQueueFamily() - */ - explicit CommandPoolCreateInfo(UnsignedInt queueFamilyIndex, 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 CommandPoolCreateInfo(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 CommandPoolCreateInfo(const VkCommandPoolCreateInfo& info); - - /** @brief Underlying @type_vk{CommandPoolCreateInfo} structure */ - VkCommandPoolCreateInfo& operator*() { return _info; } - /** @overload */ - const VkCommandPoolCreateInfo& operator*() const { return _info; } - /** @overload */ - VkCommandPoolCreateInfo* operator->() { return &_info; } - /** @overload */ - const VkCommandPoolCreateInfo* operator->() const { return &_info; } - /** @overload */ - operator const VkCommandPoolCreateInfo*() const { return &_info; } - - private: - VkCommandPoolCreateInfo _info; -}; - -CORRADE_ENUMSET_OPERATORS(CommandPoolCreateInfo::Flags) - /** @brief Command buffer level @m_since_latest diff --git a/src/Magnum/Vk/CommandPoolCreateInfo.h b/src/Magnum/Vk/CommandPoolCreateInfo.h new file mode 100644 index 000000000..61fe50c23 --- /dev/null +++ b/src/Magnum/Vk/CommandPoolCreateInfo.h @@ -0,0 +1,140 @@ +#ifndef Magnum_Vk_CommandPoolCreateInfo_h +#define Magnum_Vk_CommandPoolCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::CommandPoolCreateInfo + * @m_since_latest + */ + +#include + +#include "Magnum/Tags.h" +#include "Magnum/Magnum.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Command pool creation info +@m_since_latest + +Wraps a @type_vk_keyword{CommandPoolCreateInfo}. See +@ref Vk-CommandPool-creation "Command pool creation" for usage information. +*/ +class MAGNUM_VK_EXPORT CommandPoolCreateInfo { + public: + /** + * @brief Command pool creation flag + * + * Wraps @type_vk_keyword{CommandPoolCreateFlagBits}. + * @see @ref Flags, @ref CommandPoolCreateInfo(UnsignedInt, Flags) + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt { + /** Command buffers allocated from this pool will be short-lived */ + Transient = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, + + /** + * Allow individual command buffers to be reset to initial state + * using @ref CommandBuffer::reset() instead of just the whole pool + * using @ref CommandPool::reset(). + * + * @m_class{m-note m-success} + * + * @par + * Not using this flag may help the driver to use simpler + * per-pool allocators instead of per-buffer. + */ + ResetCommandBuffer = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT + }; + + /** + * @brief Command pool creation flags + * + * Type-safe wrapper for @type_vk_keyword{CommandPoolCreateFlags}. + * @see @ref CommandPoolCreateInfo(UnsignedInt, Flags) + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param queueFamilyIndex Queue family index + * @param flags Command pool creation flags + * + * The following @type_vk{CommandPoolCreateInfo} fields are pre-filled + * in addition to `sType`, everything else is zero-filled: + * + * - `flags` + * - `queueFamilyIndex` + * + * @see @ref DeviceProperties::pickQueueFamily() + */ + explicit CommandPoolCreateInfo(UnsignedInt queueFamilyIndex, 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 CommandPoolCreateInfo(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 CommandPoolCreateInfo(const VkCommandPoolCreateInfo& info); + + /** @brief Underlying @type_vk{CommandPoolCreateInfo} structure */ + VkCommandPoolCreateInfo& operator*() { return _info; } + /** @overload */ + const VkCommandPoolCreateInfo& operator*() const { return _info; } + /** @overload */ + VkCommandPoolCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkCommandPoolCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkCommandPoolCreateInfo*() const { return &_info; } + + private: + VkCommandPoolCreateInfo _info; +}; + +CORRADE_ENUMSET_OPERATORS(CommandPoolCreateInfo::Flags) + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/CommandPool.h" + +#endif diff --git a/src/Magnum/Vk/Device.cpp b/src/Magnum/Vk/Device.cpp index 81d1ecad8..02bd0f56a 100644 --- a/src/Magnum/Vk/Device.cpp +++ b/src/Magnum/Vk/Device.cpp @@ -24,6 +24,7 @@ */ #include "Device.h" +#include "DeviceCreateInfo.h" #include #include diff --git a/src/Magnum/Vk/Device.h b/src/Magnum/Vk/Device.h index f8ca10a2d..6f3bc6e76 100644 --- a/src/Magnum/Vk/Device.h +++ b/src/Magnum/Vk/Device.h @@ -26,13 +26,12 @@ */ /** @file - * @brief Class @ref Magnum::Vk::DeviceCreateInfo, @ref Magnum::Vk::Device + * @brief Class @ref Magnum::Vk::Device * @m_since_latest */ #include #include -#include #include "Magnum/Tags.h" #include "Magnum/Math/BoolVector.h" @@ -49,244 +48,6 @@ namespace Implementation { struct DeviceState; } -/** -@brief Device creation info -@m_since_latest - -Wraps a @type_vk_keyword{DeviceCreateInfo}. See -@ref Vk-Device-creation "Device creation" for usage information. -*/ -class MAGNUM_VK_EXPORT DeviceCreateInfo { - public: - /** - * @brief Device creation flag - * - * Wraps @type_vk_keyword{DeviceCreateFlagBits}. - * @see @ref Flags, @ref DeviceCreateInfo(DeviceProperties&, const ExtensionProperties*, Flags) - */ - enum class Flag: UnsignedInt { - /* Any magnum-specific flags added here have to be filtered out - when passing them to _info.flags in the constructor. Using the - highest bits in a hope to prevent conflicts with Vulkan instance - flags added in the future. */ - - /** - * Don't implicitly enable any extensions. - * - * By default, the engine enables various extensions such as - * @vk_extension{KHR,get_memory_requirements2} to provide a broader - * functionality. If you want to have a complete control over what - * gets enabled, set this flag. - */ - NoImplicitExtensions = 1u << 31 - }; - - /** - * @brief Device creation flags - * - * Type-safe wrapper for @type_vk_keyword{DeviceCreateFlags}. - * @see @ref DeviceCreateInfo(DeviceProperties&, const ExtensionProperties*, Flags) - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param deviceProperties A device to use - * @param extensionProperties Existing @ref ExtensionProperties - * instance for querying available Vulkan extensions. If - * @cpp nullptr @ce, a new instance may be created internally if - * needed. If a r-value is passed, the instance is later available - * through @ref Device::properties(). - * @param flags Device creation flags - * - * The following @type_vk{DeviceCreateInfo} fields are pre-filled in - * addition to `sType`: - * - * - `flags` - * - * You need to call at least @ref addQueues() for a valid setup. - */ - explicit DeviceCreateInfo(DeviceProperties& deviceProperties, const ExtensionProperties* extensionProperties, Flags flags = {}); - - /** @overload */ - explicit DeviceCreateInfo(DeviceProperties& deviceProperties, Flags flags = {}): DeviceCreateInfo{deviceProperties, nullptr, flags} {} - - /** - * @brief Construct with allowing to reuse already populated device properties - * - * Compared to @ref DeviceCreateInfo(DeviceProperties&, const ExtensionProperties*, Flags), - * if the @ref Device is subsequently constructed via - * @ref Device::Device(Instance&, DeviceCreateInfo&&), the - * @p deviceProperties instance gets directly transferred to the - * device, meaning @ref Device::properties() and any APIs relying on it - * can reuse what was possibly already queried without having to repeat - * the potentially complex queries second time. - */ - explicit DeviceCreateInfo(DeviceProperties&& deviceProperties, const ExtensionProperties* extensionProperties, Flags flags = {}); - - /** @overload */ - explicit DeviceCreateInfo(DeviceProperties&& deviceProperties, Flags flags = {}): DeviceCreateInfo{std::move(deviceProperties), nullptr, 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 DeviceCreateInfo(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 DeviceCreateInfo(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo& info); - - /** @brief Copying is not allowed */ - DeviceCreateInfo(const DeviceCreateInfo&) = delete; - - /** @brief Move constructor */ - DeviceCreateInfo(DeviceCreateInfo&& other) noexcept; - - ~DeviceCreateInfo(); - - /** @brief Copying is not allowed */ - DeviceCreateInfo& operator=(const DeviceCreateInfo&) = delete; - - /** @brief Move assignment */ - DeviceCreateInfo& operator=(DeviceCreateInfo&& other) noexcept; - - /* All the && overloads below are there in order to allow code like - - Device device{instance, DeviceCreateInfo{pickDevice(instance)} - .addQueues(...) - .addEnabledExtensions(...) - ... - }; - - to work and correctly move the DeviceProperties to the Device. - When adding new APIs, expand DeviceVkTest::createInfoRvalue() to - verify everything still works. */ - - /** - * @brief Add enabled device extensions - * @return Reference to self (for method chaining) - * - * All listed extensions are expected to be supported either globally - * or in at least one of the enabled layers, use - * @ref ExtensionProperties::isSupported() to check for their presence. - * - * The function makes copies of string views that are not owning or - * null-terminated, use the @link Containers::Literals::operator""_s() @endlink - * literal to prevent that where possible. - */ - DeviceCreateInfo& addEnabledExtensions(Containers::ArrayView extensions) &; - /** @overload */ - DeviceCreateInfo&& addEnabledExtensions(Containers::ArrayView extensions) &&; - /** @overload */ - DeviceCreateInfo& addEnabledExtensions(std::initializer_list extension) &; - /** @overload */ - DeviceCreateInfo&& addEnabledExtensions(std::initializer_list extension) &&; - /** @overload */ - DeviceCreateInfo& addEnabledExtensions(Containers::ArrayView extensions) &; - /** @overload */ - DeviceCreateInfo&& addEnabledExtensions(Containers::ArrayView extensions) &&; - /** @overload */ - DeviceCreateInfo& addEnabledExtensions(std::initializer_list extension) &; - /** @overload */ - DeviceCreateInfo&& addEnabledExtensions(std::initializer_list extension) &&; - /** @overload */ - template DeviceCreateInfo& addEnabledExtensions() & { - static_assert(Implementation::IsExtension::value, "expected only Vulkan device extensions"); - return addEnabledExtensions(std::initializer_list{E{}...}); - } - /** @overload */ - template DeviceCreateInfo&& addEnabledExtensions() && { - addEnabledExtensions(); - return std::move(*this); - } - - /** - * @brief Add queues - * @param[in] family Family index, smaller than - * @ref DeviceProperties::queueFamilyCount() - * @param[in] priorities Queue priorities. Size of the array implies - * how many queues to add and has to be at least one. - * @param[out] output Where to save resulting queues once the - * device is created. Has to have the same sizes as @p priorities. - * @return Reference to self (for method chaining) - * - * At least one queue has to be added. - * @see @ref DeviceProperties::pickQueueFamily() - * @todoc link to addQueues(QueueFlags) once doxygen finally GROWS UP - * and can link to &-qualified functions FFS - */ - DeviceCreateInfo& addQueues(UnsignedInt family, Containers::ArrayView priorities, Containers::ArrayView> output) &; - /** @overload */ - DeviceCreateInfo&& addQueues(UnsignedInt family, Containers::ArrayView priorities, Containers::ArrayView> output) &&; - /** @overload */ - DeviceCreateInfo& addQueues(UnsignedInt family, std::initializer_list priorities, std::initializer_list> output) &; - /** @overload */ - DeviceCreateInfo&& addQueues(UnsignedInt family, std::initializer_list priorities, std::initializer_list> output) &&; - - /** - * @brief Add queues of family matching given flags - * - * Equivalent to picking a queue family first using - * @ref DeviceProperties::pickQueueFamily() based on @p flags and then - * calling the above @ref addQueues() variant with the family index. - * - * Note that @ref DeviceProperties::pickQueueFamily() exits in case it - * doesn't find any family satisfying given @p flags --- for a - * failproof scenario you may want to go with the above overload and - * @ref DeviceProperties::tryPickQueueFamily() instead. - * @todoc link to addQueues(UnsignedInt) above once doxygen finally - * GROWS UP and can link to &-qualified functions FFS - */ - DeviceCreateInfo& addQueues(QueueFlags flags, Containers::ArrayView priorities, Containers::ArrayView> output) &; - /** @overload */ - DeviceCreateInfo&& addQueues(QueueFlags flags, Containers::ArrayView priorities, Containers::ArrayView> output) &&; - /** @overload */ - DeviceCreateInfo& addQueues(QueueFlags flags, std::initializer_list priorities, std::initializer_list> output) &; - /** @overload */ - DeviceCreateInfo&& addQueues(QueueFlags flags, std::initializer_list priorities, std::initializer_list> output) &&; - - /** - * @brief Add queues using raw info - * @return Reference to self (for method chaining) - * - * Compared to @ref addQueues() this allows you to specify additional - * queue properties using the `pNext` chain. The info is uses as-is, - * with all pointers expected to stay in scope until device creation. - */ - DeviceCreateInfo& addQueues(const VkDeviceQueueCreateInfo& info) &; - /** @overload */ - DeviceCreateInfo&& addQueues(const VkDeviceQueueCreateInfo& info) &&; - - /** @brief Underlying @type_vk{DeviceCreateInfo} structure */ - VkDeviceCreateInfo& operator*() { return _info; } - /** @overload */ - const VkDeviceCreateInfo& operator*() const { return _info; } - /** @overload */ - VkDeviceCreateInfo* operator->() { return &_info; } - /** @overload */ - const VkDeviceCreateInfo* operator->() const { return &_info; } - /** @overload */ - operator const VkDeviceCreateInfo*() const { return &_info; } - - private: - friend Device; - - VkPhysicalDevice _physicalDevice; - VkDeviceCreateInfo _info; - struct State; - Containers::Pointer _state; -}; - -CORRADE_ENUMSET_OPERATORS(DeviceCreateInfo::Flags) - /** @brief Device @m_since_latest diff --git a/src/Magnum/Vk/DeviceCreateInfo.h b/src/Magnum/Vk/DeviceCreateInfo.h new file mode 100644 index 000000000..2a017cb34 --- /dev/null +++ b/src/Magnum/Vk/DeviceCreateInfo.h @@ -0,0 +1,288 @@ +#ifndef Magnum_Vk_DeviceCreateInfo_h +#define Magnum_Vk_DeviceCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::DeviceCreateInfo + * @m_since_latest + */ + +#include +#include + +#include "Magnum/Tags.h" +#include "Magnum/Vk/TypeTraits.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Device creation info +@m_since_latest + +Wraps a @type_vk_keyword{DeviceCreateInfo}. See +@ref Vk-Device-creation "Device creation" for usage information. +*/ +class MAGNUM_VK_EXPORT DeviceCreateInfo { + public: + /** + * @brief Device creation flag + * + * Wraps @type_vk_keyword{DeviceCreateFlagBits}. + * @see @ref Flags, @ref DeviceCreateInfo(DeviceProperties&, const ExtensionProperties*, Flags) + */ + enum class Flag: UnsignedInt { + /* Any magnum-specific flags added here have to be filtered out + when passing them to _info.flags in the constructor. Using the + highest bits in a hope to prevent conflicts with Vulkan instance + flags added in the future. */ + + /** + * Don't implicitly enable any extensions. + * + * By default, the engine enables various extensions such as + * @vk_extension{KHR,get_memory_requirements2} to provide a broader + * functionality. If you want to have a complete control over what + * gets enabled, set this flag. + */ + NoImplicitExtensions = 1u << 31 + }; + + /** + * @brief Device creation flags + * + * Type-safe wrapper for @type_vk_keyword{DeviceCreateFlags}. + * @see @ref DeviceCreateInfo(DeviceProperties&, const ExtensionProperties*, Flags) + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param deviceProperties A device to use + * @param extensionProperties Existing @ref ExtensionProperties + * instance for querying available Vulkan extensions. If + * @cpp nullptr @ce, a new instance may be created internally if + * needed. If a r-value is passed, the instance is later available + * through @ref Device::properties(). + * @param flags Device creation flags + * + * The following @type_vk{DeviceCreateInfo} fields are pre-filled in + * addition to `sType`: + * + * - `flags` + * + * You need to call at least @ref addQueues() for a valid setup. + */ + explicit DeviceCreateInfo(DeviceProperties& deviceProperties, const ExtensionProperties* extensionProperties, Flags flags = {}); + + /** @overload */ + explicit DeviceCreateInfo(DeviceProperties& deviceProperties, Flags flags = {}): DeviceCreateInfo{deviceProperties, nullptr, flags} {} + + /** + * @brief Construct with allowing to reuse already populated device properties + * + * Compared to @ref DeviceCreateInfo(DeviceProperties&, const ExtensionProperties*, Flags), + * if the @ref Device is subsequently constructed via + * @ref Device::Device(Instance&, DeviceCreateInfo&&), the + * @p deviceProperties instance gets directly transferred to the + * device, meaning @ref Device::properties() and any APIs relying on it + * can reuse what was possibly already queried without having to repeat + * the potentially complex queries second time. + */ + explicit DeviceCreateInfo(DeviceProperties&& deviceProperties, const ExtensionProperties* extensionProperties, Flags flags = {}); + + /** @overload */ + explicit DeviceCreateInfo(DeviceProperties&& deviceProperties, Flags flags = {}): DeviceCreateInfo{std::move(deviceProperties), nullptr, 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 DeviceCreateInfo(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 DeviceCreateInfo(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo& info); + + /** @brief Copying is not allowed */ + DeviceCreateInfo(const DeviceCreateInfo&) = delete; + + /** @brief Move constructor */ + DeviceCreateInfo(DeviceCreateInfo&& other) noexcept; + + ~DeviceCreateInfo(); + + /** @brief Copying is not allowed */ + DeviceCreateInfo& operator=(const DeviceCreateInfo&) = delete; + + /** @brief Move assignment */ + DeviceCreateInfo& operator=(DeviceCreateInfo&& other) noexcept; + + /* All the && overloads below are there in order to allow code like + + Device device{instance, DeviceCreateInfo{pickDevice(instance)} + .addQueues(...) + .addEnabledExtensions(...) + ... + }; + + to work and correctly move the DeviceProperties to the Device. + When adding new APIs, expand DeviceVkTest::createInfoRvalue() to + verify everything still works. */ + + /** + * @brief Add enabled device extensions + * @return Reference to self (for method chaining) + * + * All listed extensions are expected to be supported either globally + * or in at least one of the enabled layers, use + * @ref ExtensionProperties::isSupported() to check for their presence. + * + * The function makes copies of string views that are not owning or + * null-terminated, use the @link Containers::Literals::operator""_s() @endlink + * literal to prevent that where possible. + */ + DeviceCreateInfo& addEnabledExtensions(Containers::ArrayView extensions) &; + /** @overload */ + DeviceCreateInfo&& addEnabledExtensions(Containers::ArrayView extensions) &&; + /** @overload */ + DeviceCreateInfo& addEnabledExtensions(std::initializer_list extension) &; + /** @overload */ + DeviceCreateInfo&& addEnabledExtensions(std::initializer_list extension) &&; + /** @overload */ + DeviceCreateInfo& addEnabledExtensions(Containers::ArrayView extensions) &; + /** @overload */ + DeviceCreateInfo&& addEnabledExtensions(Containers::ArrayView extensions) &&; + /** @overload */ + DeviceCreateInfo& addEnabledExtensions(std::initializer_list extension) &; + /** @overload */ + DeviceCreateInfo&& addEnabledExtensions(std::initializer_list extension) &&; + /** @overload */ + template DeviceCreateInfo& addEnabledExtensions() & { + static_assert(Implementation::IsExtension::value, "expected only Vulkan device extensions"); + return addEnabledExtensions(std::initializer_list{E{}...}); + } + /** @overload */ + template DeviceCreateInfo&& addEnabledExtensions() && { + addEnabledExtensions(); + return std::move(*this); + } + + /** + * @brief Add queues + * @param[in] family Family index, smaller than + * @ref DeviceProperties::queueFamilyCount() + * @param[in] priorities Queue priorities. Size of the array implies + * how many queues to add and has to be at least one. + * @param[out] output Where to save resulting queues once the + * device is created. Has to have the same sizes as @p priorities. + * @return Reference to self (for method chaining) + * + * At least one queue has to be added. + * @see @ref DeviceProperties::pickQueueFamily() + * @todoc link to addQueues(QueueFlags) once doxygen finally GROWS UP + * and can link to &-qualified functions FFS + */ + DeviceCreateInfo& addQueues(UnsignedInt family, Containers::ArrayView priorities, Containers::ArrayView> output) &; + /** @overload */ + DeviceCreateInfo&& addQueues(UnsignedInt family, Containers::ArrayView priorities, Containers::ArrayView> output) &&; + /** @overload */ + DeviceCreateInfo& addQueues(UnsignedInt family, std::initializer_list priorities, std::initializer_list> output) &; + /** @overload */ + DeviceCreateInfo&& addQueues(UnsignedInt family, std::initializer_list priorities, std::initializer_list> output) &&; + + /** + * @brief Add queues of family matching given flags + * + * Equivalent to picking a queue family first using + * @ref DeviceProperties::pickQueueFamily() based on @p flags and then + * calling the above @ref addQueues() variant with the family index. + * + * Note that @ref DeviceProperties::pickQueueFamily() exits in case it + * doesn't find any family satisfying given @p flags --- for a + * failproof scenario you may want to go with the above overload and + * @ref DeviceProperties::tryPickQueueFamily() instead. + * @todoc link to addQueues(UnsignedInt) above once doxygen finally + * GROWS UP and can link to &-qualified functions FFS + */ + DeviceCreateInfo& addQueues(QueueFlags flags, Containers::ArrayView priorities, Containers::ArrayView> output) &; + /** @overload */ + DeviceCreateInfo&& addQueues(QueueFlags flags, Containers::ArrayView priorities, Containers::ArrayView> output) &&; + /** @overload */ + DeviceCreateInfo& addQueues(QueueFlags flags, std::initializer_list priorities, std::initializer_list> output) &; + /** @overload */ + DeviceCreateInfo&& addQueues(QueueFlags flags, std::initializer_list priorities, std::initializer_list> output) &&; + + /** + * @brief Add queues using raw info + * @return Reference to self (for method chaining) + * + * Compared to @ref addQueues() this allows you to specify additional + * queue properties using the `pNext` chain. The info is uses as-is, + * with all pointers expected to stay in scope until device creation. + */ + DeviceCreateInfo& addQueues(const VkDeviceQueueCreateInfo& info) &; + /** @overload */ + DeviceCreateInfo&& addQueues(const VkDeviceQueueCreateInfo& info) &&; + + /** @brief Underlying @type_vk{DeviceCreateInfo} structure */ + VkDeviceCreateInfo& operator*() { return _info; } + /** @overload */ + const VkDeviceCreateInfo& operator*() const { return _info; } + /** @overload */ + VkDeviceCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkDeviceCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkDeviceCreateInfo*() const { return &_info; } + + private: + friend Device; + + VkPhysicalDevice _physicalDevice; + VkDeviceCreateInfo _info; + struct State; + Containers::Pointer _state; +}; + +CORRADE_ENUMSET_OPERATORS(DeviceCreateInfo::Flags) + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/Device.h" + +#endif diff --git a/src/Magnum/Vk/Image.cpp b/src/Magnum/Vk/Image.cpp index 70bb26c31..a97dd8923 100644 --- a/src/Magnum/Vk/Image.cpp +++ b/src/Magnum/Vk/Image.cpp @@ -24,12 +24,14 @@ */ #include "Image.h" +#include "ImageCreateInfo.h" #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/MemoryAllocateInfo.h" #include "Magnum/Vk/Implementation/DeviceState.h" namespace Magnum { namespace Vk { diff --git a/src/Magnum/Vk/Image.h b/src/Magnum/Vk/Image.h index 5f332694d..ce58b770d 100644 --- a/src/Magnum/Vk/Image.h +++ b/src/Magnum/Vk/Image.h @@ -26,15 +26,11 @@ */ /** @file - * @brief Class @ref Magnum::Vk::ImageCreateInfo, @ref Magnum::Vk::ImageCreateInfo1D, @ref Magnum::Vk::ImageCreateInfo2D, @ref Magnum::Vk::ImageCreateInfo3D, @ref Magnum::Vk::ImageCreateInfo1DArray, @ref Magnum::Vk::ImageCreateInfo2DArray, @ref Magnum::Vk::ImageCreateInfoCubeMap, @ref Magnum::Vk::ImageCreateInfoCubeMapArray, @ref Magnum::Vk::Image, enum @ref Magnum::Vk::ImageLayout, @ref Magnum::Vk::ImageUsage, enum set @ref Magnum::Vk::ImageUsages + * @brief Class @ref Magnum::Vk::Image, enum @ref Magnum::Vk::ImageLayout * @m_since_latest */ -#include - -#include "Magnum/DimensionTraits.h" #include "Magnum/Magnum.h" -#include "Magnum/Math/Vector3.h" #include "Magnum/Vk/Memory.h" #include "Magnum/Vk/Vk.h" #include "Magnum/Vk/Vulkan.h" @@ -44,75 +40,6 @@ namespace Magnum { namespace Vk { namespace Implementation { struct DeviceState; } -/** -@brief Image usage -@m_since_latest - -Wraps a @type_vk_keyword{ImageUsageFlagBits}. -@see @ref ImageUsages, @ref ImageCreateInfo -@m_enum_values_as_keywords -*/ -enum class ImageUsage: UnsignedInt { - /** - * Source of a transfer command - * - * @see @ref ImageLayout::TransferSource - */ - TransferSource = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - - /** - * Destination of a transfer command - * - * @see @ref ImageLayout::TransferDestination - */ - TransferDestination = VK_IMAGE_USAGE_TRANSFER_DST_BIT, - - /** - * Sampled by a shader - * - * @see @ref ImageLayout::ShaderReadOnly - */ - Sampled = VK_IMAGE_USAGE_SAMPLED_BIT, - - /** Shader storage */ - Storage = VK_IMAGE_USAGE_STORAGE_BIT, - - /** - * Color attachment - * - * @see @ref ImageLayout::ColorAttachment - */ - ColorAttachment = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - - /** - * Depth/stencil attachment - * - * @see @ref ImageLayout::DepthStencilAttachment - */ - DepthStencilAttachment = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - - /** Transient attachment */ - TransientAttachment = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - - /** - * Input attachment in a shader or framebuffer - * - * @see @ref ImageLayout::ShaderReadOnly - */ - InputAttachment = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT -}; - -/** -@brief Image usages -@m_since_latest - -Type-safe wrapper for @type_vk_keyword{ImageUsageFlags}. -@see @ref ImageCreateInfo -*/ -typedef Containers::EnumSet ImageUsages; - -CORRADE_ENUMSET_OPERATORS(ImageUsages) - /** @brief Image layout @m_since_latest @@ -221,304 +148,6 @@ enum class ImageLayout: Int { @vk_extension{KHR,separate_depth_stencil_layouts} (1.2) */ }; -/** -@brief Image creation info -@m_since_latest - -Wraps a @type_vk_keyword{ImageCreateInfo}. See -@ref Vk-Image-creation "Image creation" for usage information. -@see @ref ImageCreateInfo1D, @ref ImageCreateInfo2D, @ref ImageCreateInfo3D, - @ref ImageCreateInfo1DArray, @ref ImageCreateInfo2DArray, - @ref ImageCreateInfoCubeMap, @ref ImageCreateInfoCubeMapArray -*/ -class MAGNUM_VK_EXPORT ImageCreateInfo { - public: - /** - * @brief Image creation flag - * - * Wraps @type_vk_keyword{ImageCreateFlagBits}. - * @see @ref Flags, @ref ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) - * @m_enum_values_as_keywords - */ - enum class Flag: UnsignedInt { - /** @todo sparse binding/residency/aliased */ - - /** - * Allow creating a view of different format - * - * @todo implement @vk_extension{KHR,image_format_list} - */ - MutableFormat = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, - - /** Allow creating a cube map view */ - CubeCompatible = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, - - /** @todo alias, 2D array compatible ... (Vulkan 1.1+) */ - }; - - /** - * @brief Image creation flags - * - * Type-safe wrapper for @type_vk_keyword{ImageCreateFlags}. - * @see @ref ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags), - * @ref ImageCreateInfo1D, @ref ImageCreateInfo2D, - * @ref ImageCreateInfo3D, @ref ImageCreateInfo1DArray, - * @ref ImageCreateInfo2DArray, @ref ImageCreateInfoCubeMap, - * @ref ImageCreateInfoCubeMapArray - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param type Image type - * @param usages Desired image usage. At least one flag is - * required. - * @param format Image format - * @param size Image size - * @param layers Array layer count - * @param levels Mip level count - * @param samples Sample count - * @param initialLayout Initial layout. Can be only either - * @ref ImageLayout::Undefined or @ref ImageLayout::Preinitialized. - * @param flags Image creation flags - * - * The following @type_vk{ImageCreateInfo} fields are pre-filled in - * addition to `sType`, everything else is zero-filled: - * - * - `flags` - * - `imageType` to @p type - * - `format` - * - `extent` to @p size - * - `mipLevels` to @p levels - * - `arrayLayers` to @p layers - * - `samples` - * - `tiling` to @val_vk{IMAGE_TILING_OPTIMAL,ImageTiling} - * - `usage` to @p usages - * - `sharingMode` to @val_vk{SHARING_MODE_EXCLUSIVE,SharingMode} - * - `initialLayout` to @p initialLayout - * - * There are various restrictions on @p size, @p layers, @p levels for - * a particular @p type --- for common image types you're encouraged to - * make use of @ref ImageCreateInfo1D, @ref ImageCreateInfo2D, - * @ref ImageCreateInfo3D, @ref ImageCreateInfo1DArray, - * @ref ImageCreateInfo2DArray, @ref ImageCreateInfoCubeMap and - * @ref ImageCreateInfoCubeMapArray convenience classes instead of - * this constructor. - */ - explicit ImageCreateInfo(VkImageType type, ImageUsages usages, VkFormat format, const Vector3i& size, Int layers, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}); - /* No overload w/o initialLayout here as the general public is expected - to use the convenience classes anyway */ - - /** - * @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 ImageCreateInfo(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 ImageCreateInfo(const VkImageCreateInfo& info); - - /** @brief Underlying @type_vk{ImageCreateInfo} structure */ - VkImageCreateInfo& operator*() { return _info; } - /** @overload */ - const VkImageCreateInfo& operator*() const { return _info; } - /** @overload */ - VkImageCreateInfo* operator->() { return &_info; } - /** @overload */ - const VkImageCreateInfo* operator->() const { return &_info; } - /** @overload */ - operator const VkImageCreateInfo*() const { return &_info; } - - private: - VkImageCreateInfo _info; -}; - -CORRADE_ENUMSET_OPERATORS(ImageCreateInfo::Flags) - -/** -@brief Convenience constructor for 1D images -@m_since_latest - -Compared to the base @ref ImageCreateInfo constructor creates an image of type -@val_vk{IMAGE_TYPE_1D,ImageType} with the last two `size` components and -`layers` set to @cpp 1 @ce. - -Note that same as with the -@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) -constructor, at least one @ref ImageUsage value is required. -*/ -class ImageCreateInfo1D: public ImageCreateInfo { - public: - /** @brief Constructor */ - explicit ImageCreateInfo1D(ImageUsages usages, VkFormat format, Int size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_1D, usages, format, {size, 1, 1}, 1, levels, samples, initialLayout, flags} {} - - /** @overload - * - * Equivalent to the above with @p initialLayout set to - * @ref ImageLayout::Undefined. - */ - explicit ImageCreateInfo1D(ImageUsages usages, VkFormat format, Int size, Int levels, Int samples, Flags flags): ImageCreateInfo1D{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} -}; - -/** -@brief Convenience constructor for 2D images -@m_since_latest - -Compared to the base @ref ImageCreateInfo constructor creates an image of type -@val_vk{IMAGE_TYPE_2D,ImageType} with the last `size` component and `layers` -set to @cpp 1 @ce. - -Note that same as with the -@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) -constructor, at least one @ref ImageUsage value is required. -*/ -class ImageCreateInfo2D: public ImageCreateInfo { - public: - /** @brief Constructor */ - explicit ImageCreateInfo2D(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_2D, usages, format, {size, 1}, 1, levels, samples, initialLayout, flags} {} - - /** @overload - * - * Equivalent to the above with @p initialLayout set to - * @ref ImageLayout::Undefined. - */ - explicit ImageCreateInfo2D(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples, Flags flags): ImageCreateInfo2D{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} -}; - -/** -@brief Convenience constructor for 3D images -@m_since_latest - -Compared to the base @ref ImageCreateInfo constructor creates an image of type -@val_vk{IMAGE_TYPE_3D,ImageType} with `layers` set to @cpp 1 @ce. - -Note that same as with the -@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) -constructor, at least one @ref ImageUsage value is required. -*/ -class ImageCreateInfo3D: public ImageCreateInfo { - public: - /** @brief Constructor */ - explicit ImageCreateInfo3D(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_3D, usages, format, size, 1, levels, samples, initialLayout, flags} {} - - /** @overload - * - * Equivalent to the above with @p initialLayout set to - * @ref ImageLayout::Undefined. - */ - explicit ImageCreateInfo3D(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples, Flags flags): ImageCreateInfo3D{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} -}; - -/** -@brief Convenience constructor for 1D array images -@m_since_latest - -Compared to the base @ref ImageCreateInfo constructor creates an image of type -@val_vk{IMAGE_TYPE_1D,ImageType} with the last two `size` components set to -@cpp 1 @ce and `layers` set to @cpp size.y() @ce. - -Note that same as with the -@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) -constructor, at least one @ref ImageUsage value is required. -*/ -class ImageCreateInfo1DArray: public ImageCreateInfo { - public: - /** @brief Constructor */ - explicit ImageCreateInfo1DArray(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_1D, usages, format, {size.x(), 1, 1}, size.y(), levels, samples, initialLayout, flags} {} - - /** @overload - * - * Equivalent to the above with @p initialLayout set to - * @ref ImageLayout::Undefined. - */ - explicit ImageCreateInfo1DArray(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples, Flags flags): ImageCreateInfo1DArray{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} -}; - -/** -@brief Convenience constructor for 2D array images -@m_since_latest - -Compared to the base @ref ImageCreateInfo constructor creates an image of type -@val_vk{IMAGE_TYPE_2D,ImageType} with the last `size` component set to -@cpp 1 @ce and `layers` set to @cpp size.z() @ce. - -Note that same as with the -@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) -constructor, at least one @ref ImageUsage value is required. -*/ -class ImageCreateInfo2DArray: public ImageCreateInfo { - public: - /** @brief Constructor */ - explicit ImageCreateInfo2DArray(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_2D, usages, format, {size.xy(), 1}, size.z(), levels, samples, initialLayout, flags} {} - - /** @overload - * - * Equivalent to the above with @p initialLayout set to - * @ref ImageLayout::Undefined. - */ - explicit ImageCreateInfo2DArray(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples, Flags flags): ImageCreateInfo2DArray{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} -}; - -/** -@brief Convenience constructor for cube map images -@m_since_latest - -Compared to the base @ref ImageCreateInfo constructor creates an image of type -@val_vk{IMAGE_TYPE_2D,ImageType} with the last `size` component set to -@cpp 1 @ce, `layers` set to @cpp 6 @ce and `flags` additionally having -@ref Flag::CubeCompatible. - -Note that same as with the -@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) -constructor, at least one @ref ImageUsage value is required. -*/ -class ImageCreateInfoCubeMap: public ImageCreateInfo { - public: - /** @brief Constructor */ - explicit ImageCreateInfoCubeMap(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_2D, usages, format, {size, 1}, 6, levels, samples, initialLayout, flags|Flag::CubeCompatible} {} - - /** @overload - * - * Equivalent to the above with @p initialLayout set to - * @ref ImageLayout::Undefined. - */ - explicit ImageCreateInfoCubeMap(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples, Flags flags): ImageCreateInfoCubeMap{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} -}; - -/** -@brief Convenience constructor for cube map array images -@m_since_latest - -Compared to the base @ref ImageCreateInfo constructor creates an image of type -@val_vk{IMAGE_TYPE_2D,ImageType} with the last `size` component set to -@cpp 1 @ce, `layers` set to @cpp size.y() @ce and `flags` additionally having -@ref Flag::CubeCompatible. - -Note that same as with the -@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) -constructor, at least one @ref ImageUsage value is required. -*/ -class ImageCreateInfoCubeMapArray: public ImageCreateInfo { - public: - /** @brief Constructor */ - explicit ImageCreateInfoCubeMapArray(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_2D, usages, format, {size.xy(), 1}, size.z(), levels, samples, initialLayout, flags|Flag::CubeCompatible} {} - - /** @overload - * - * Equivalent to the above with @p initialLayout set to - * @ref ImageLayout::Undefined. - */ - explicit ImageCreateInfoCubeMapArray(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples, Flags flags): ImageCreateInfoCubeMapArray{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} -}; - /** @brief Image @m_since_latest diff --git a/src/Magnum/Vk/ImageCreateInfo.h b/src/Magnum/Vk/ImageCreateInfo.h new file mode 100644 index 000000000..2a4a445fa --- /dev/null +++ b/src/Magnum/Vk/ImageCreateInfo.h @@ -0,0 +1,420 @@ +#ifndef Magnum_Vk_ImageCreateInfo_h +#define Magnum_Vk_ImageCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::ImageCreateInfo, @ref Magnum::Vk::ImageCreateInfo1D, @ref Magnum::Vk::ImageCreateInfo2D, @ref Magnum::Vk::ImageCreateInfo3D, @ref Magnum::Vk::ImageCreateInfo1DArray, @ref Magnum::Vk::ImageCreateInfo2DArray, @ref Magnum::Vk::ImageCreateInfoCubeMap, @ref Magnum::Vk::ImageCreateInfoCubeMapArray, enum @ref Magnum::Vk::ImageUsage, enum set @ref Magnum::Vk::ImageUsages + * @m_since_latest + */ + +#include + +#include "Magnum/DimensionTraits.h" +#include "Magnum/Magnum.h" +#include "Magnum/Math/Vector3.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. Compared to other cases we do this + on top as we need the ImageLayout definition here. */ +#include "Magnum/Vk/Image.h" + +namespace Magnum { namespace Vk { + +/** +@brief Image usage +@m_since_latest + +Wraps a @type_vk_keyword{ImageUsageFlagBits}. +@see @ref ImageUsages, @ref ImageCreateInfo +@m_enum_values_as_keywords +*/ +enum class ImageUsage: UnsignedInt { + /** + * Source of a transfer command + * + * @see @ref ImageLayout::TransferSource + */ + TransferSource = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + + /** + * Destination of a transfer command + * + * @see @ref ImageLayout::TransferDestination + */ + TransferDestination = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + + /** + * Sampled by a shader + * + * @see @ref ImageLayout::ShaderReadOnly + */ + Sampled = VK_IMAGE_USAGE_SAMPLED_BIT, + + /** Shader storage */ + Storage = VK_IMAGE_USAGE_STORAGE_BIT, + + /** + * Color attachment + * + * @see @ref ImageLayout::ColorAttachment + */ + ColorAttachment = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + + /** + * Depth/stencil attachment + * + * @see @ref ImageLayout::DepthStencilAttachment + */ + DepthStencilAttachment = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + + /** Transient attachment */ + TransientAttachment = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + + /** + * Input attachment in a shader or framebuffer + * + * @see @ref ImageLayout::ShaderReadOnly + */ + InputAttachment = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT +}; + +/** +@brief Image usages +@m_since_latest + +Type-safe wrapper for @type_vk_keyword{ImageUsageFlags}. +@see @ref ImageCreateInfo +*/ +typedef Containers::EnumSet ImageUsages; + +CORRADE_ENUMSET_OPERATORS(ImageUsages) + +/** +@brief Image creation info +@m_since_latest + +Wraps a @type_vk_keyword{ImageCreateInfo}. See +@ref Vk-Image-creation "Image creation" for usage information. +@see @ref ImageCreateInfo1D, @ref ImageCreateInfo2D, @ref ImageCreateInfo3D, + @ref ImageCreateInfo1DArray, @ref ImageCreateInfo2DArray, + @ref ImageCreateInfoCubeMap, @ref ImageCreateInfoCubeMapArray +*/ +class MAGNUM_VK_EXPORT ImageCreateInfo { + public: + /** + * @brief Image creation flag + * + * Wraps @type_vk_keyword{ImageCreateFlagBits}. + * @see @ref Flags, @ref ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt { + /** @todo sparse binding/residency/aliased */ + + /** + * Allow creating a view of different format + * + * @todo implement @vk_extension{KHR,image_format_list} + */ + MutableFormat = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, + + /** Allow creating a cube map view */ + CubeCompatible = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, + + /** @todo alias, 2D array compatible ... (Vulkan 1.1+) */ + }; + + /** + * @brief Image creation flags + * + * Type-safe wrapper for @type_vk_keyword{ImageCreateFlags}. + * @see @ref ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags), + * @ref ImageCreateInfo1D, @ref ImageCreateInfo2D, + * @ref ImageCreateInfo3D, @ref ImageCreateInfo1DArray, + * @ref ImageCreateInfo2DArray, @ref ImageCreateInfoCubeMap, + * @ref ImageCreateInfoCubeMapArray + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param type Image type + * @param usages Desired image usage. At least one flag is + * required. + * @param format Image format + * @param size Image size + * @param layers Array layer count + * @param levels Mip level count + * @param samples Sample count + * @param initialLayout Initial layout. Can be only either + * @ref ImageLayout::Undefined or @ref ImageLayout::Preinitialized. + * @param flags Image creation flags + * + * The following @type_vk{ImageCreateInfo} fields are pre-filled in + * addition to `sType`, everything else is zero-filled: + * + * - `flags` + * - `imageType` to @p type + * - `format` + * - `extent` to @p size + * - `mipLevels` to @p levels + * - `arrayLayers` to @p layers + * - `samples` + * - `tiling` to @val_vk{IMAGE_TILING_OPTIMAL,ImageTiling} + * - `usage` to @p usages + * - `sharingMode` to @val_vk{SHARING_MODE_EXCLUSIVE,SharingMode} + * - `initialLayout` to @p initialLayout + * + * There are various restrictions on @p size, @p layers, @p levels for + * a particular @p type --- for common image types you're encouraged to + * make use of @ref ImageCreateInfo1D, @ref ImageCreateInfo2D, + * @ref ImageCreateInfo3D, @ref ImageCreateInfo1DArray, + * @ref ImageCreateInfo2DArray, @ref ImageCreateInfoCubeMap and + * @ref ImageCreateInfoCubeMapArray convenience classes instead of + * this constructor. + */ + explicit ImageCreateInfo(VkImageType type, ImageUsages usages, VkFormat format, const Vector3i& size, Int layers, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}); + /* No overload w/o initialLayout here as the general public is expected + to use the convenience classes anyway */ + + /** + * @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 ImageCreateInfo(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 ImageCreateInfo(const VkImageCreateInfo& info); + + /** @brief Underlying @type_vk{ImageCreateInfo} structure */ + VkImageCreateInfo& operator*() { return _info; } + /** @overload */ + const VkImageCreateInfo& operator*() const { return _info; } + /** @overload */ + VkImageCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkImageCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkImageCreateInfo*() const { return &_info; } + + private: + VkImageCreateInfo _info; +}; + +CORRADE_ENUMSET_OPERATORS(ImageCreateInfo::Flags) + +/** +@brief Convenience constructor for 1D images +@m_since_latest + +Compared to the base @ref ImageCreateInfo constructor creates an image of type +@val_vk{IMAGE_TYPE_1D,ImageType} with the last two `size` components and +`layers` set to @cpp 1 @ce. + +Note that same as with the +@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) +constructor, at least one @ref ImageUsage value is required. +*/ +class ImageCreateInfo1D: public ImageCreateInfo { + public: + /** @brief Constructor */ + explicit ImageCreateInfo1D(ImageUsages usages, VkFormat format, Int size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_1D, usages, format, {size, 1, 1}, 1, levels, samples, initialLayout, flags} {} + + /** @overload + * + * Equivalent to the above with @p initialLayout set to + * @ref ImageLayout::Undefined. + */ + explicit ImageCreateInfo1D(ImageUsages usages, VkFormat format, Int size, Int levels, Int samples, Flags flags): ImageCreateInfo1D{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} +}; + +/** +@brief Convenience constructor for 2D images +@m_since_latest + +Compared to the base @ref ImageCreateInfo constructor creates an image of type +@val_vk{IMAGE_TYPE_2D,ImageType} with the last `size` component and `layers` +set to @cpp 1 @ce. + +Note that same as with the +@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) +constructor, at least one @ref ImageUsage value is required. +*/ +class ImageCreateInfo2D: public ImageCreateInfo { + public: + /** @brief Constructor */ + explicit ImageCreateInfo2D(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_2D, usages, format, {size, 1}, 1, levels, samples, initialLayout, flags} {} + + /** @overload + * + * Equivalent to the above with @p initialLayout set to + * @ref ImageLayout::Undefined. + */ + explicit ImageCreateInfo2D(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples, Flags flags): ImageCreateInfo2D{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} +}; + +/** +@brief Convenience constructor for 3D images +@m_since_latest + +Compared to the base @ref ImageCreateInfo constructor creates an image of type +@val_vk{IMAGE_TYPE_3D,ImageType} with `layers` set to @cpp 1 @ce. + +Note that same as with the +@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) +constructor, at least one @ref ImageUsage value is required. +*/ +class ImageCreateInfo3D: public ImageCreateInfo { + public: + /** @brief Constructor */ + explicit ImageCreateInfo3D(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_3D, usages, format, size, 1, levels, samples, initialLayout, flags} {} + + /** @overload + * + * Equivalent to the above with @p initialLayout set to + * @ref ImageLayout::Undefined. + */ + explicit ImageCreateInfo3D(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples, Flags flags): ImageCreateInfo3D{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} +}; + +/** +@brief Convenience constructor for 1D array images +@m_since_latest + +Compared to the base @ref ImageCreateInfo constructor creates an image of type +@val_vk{IMAGE_TYPE_1D,ImageType} with the last two `size` components set to +@cpp 1 @ce and `layers` set to @cpp size.y() @ce. + +Note that same as with the +@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) +constructor, at least one @ref ImageUsage value is required. +*/ +class ImageCreateInfo1DArray: public ImageCreateInfo { + public: + /** @brief Constructor */ + explicit ImageCreateInfo1DArray(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_1D, usages, format, {size.x(), 1, 1}, size.y(), levels, samples, initialLayout, flags} {} + + /** @overload + * + * Equivalent to the above with @p initialLayout set to + * @ref ImageLayout::Undefined. + */ + explicit ImageCreateInfo1DArray(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples, Flags flags): ImageCreateInfo1DArray{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} +}; + +/** +@brief Convenience constructor for 2D array images +@m_since_latest + +Compared to the base @ref ImageCreateInfo constructor creates an image of type +@val_vk{IMAGE_TYPE_2D,ImageType} with the last `size` component set to +@cpp 1 @ce and `layers` set to @cpp size.z() @ce. + +Note that same as with the +@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) +constructor, at least one @ref ImageUsage value is required. +*/ +class ImageCreateInfo2DArray: public ImageCreateInfo { + public: + /** @brief Constructor */ + explicit ImageCreateInfo2DArray(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_2D, usages, format, {size.xy(), 1}, size.z(), levels, samples, initialLayout, flags} {} + + /** @overload + * + * Equivalent to the above with @p initialLayout set to + * @ref ImageLayout::Undefined. + */ + explicit ImageCreateInfo2DArray(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples, Flags flags): ImageCreateInfo2DArray{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} +}; + +/** +@brief Convenience constructor for cube map images +@m_since_latest + +Compared to the base @ref ImageCreateInfo constructor creates an image of type +@val_vk{IMAGE_TYPE_2D,ImageType} with the last `size` component set to +@cpp 1 @ce, `layers` set to @cpp 6 @ce and `flags` additionally having +@ref Flag::CubeCompatible. + +Note that same as with the +@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) +constructor, at least one @ref ImageUsage value is required. +*/ +class ImageCreateInfoCubeMap: public ImageCreateInfo { + public: + /** @brief Constructor */ + explicit ImageCreateInfoCubeMap(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_2D, usages, format, {size, 1}, 6, levels, samples, initialLayout, flags|Flag::CubeCompatible} {} + + /** @overload + * + * Equivalent to the above with @p initialLayout set to + * @ref ImageLayout::Undefined. + */ + explicit ImageCreateInfoCubeMap(ImageUsages usages, VkFormat format, const Vector2i& size, Int levels, Int samples, Flags flags): ImageCreateInfoCubeMap{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} +}; + +/** +@brief Convenience constructor for cube map array images +@m_since_latest + +Compared to the base @ref ImageCreateInfo constructor creates an image of type +@val_vk{IMAGE_TYPE_2D,ImageType} with the last `size` component set to +@cpp 1 @ce, `layers` set to @cpp size.y() @ce and `flags` additionally having +@ref Flag::CubeCompatible. + +Note that same as with the +@ref ImageCreateInfo::ImageCreateInfo(VkImageType, ImageUsages, VkFormat, const Vector3i&, Int, Int, Int, ImageLayout, Flags) +constructor, at least one @ref ImageUsage value is required. +*/ +class ImageCreateInfoCubeMapArray: public ImageCreateInfo { + public: + /** @brief Constructor */ + explicit ImageCreateInfoCubeMapArray(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples = 1, ImageLayout initialLayout = ImageLayout::Undefined, Flags flags = {}): ImageCreateInfo{VK_IMAGE_TYPE_2D, usages, format, {size.xy(), 1}, size.z(), levels, samples, initialLayout, flags|Flag::CubeCompatible} {} + + /** @overload + * + * Equivalent to the above with @p initialLayout set to + * @ref ImageLayout::Undefined. + */ + explicit ImageCreateInfoCubeMapArray(ImageUsages usages, VkFormat format, const Vector3i& size, Int levels, Int samples, Flags flags): ImageCreateInfoCubeMapArray{usages, format, size, levels, samples, ImageLayout::Undefined, flags} {} +}; + +}} + +/* Image.h included at the top */ + +#endif diff --git a/src/Magnum/Vk/Instance.cpp b/src/Magnum/Vk/Instance.cpp index 1d0dd1a63..b93401e3b 100644 --- a/src/Magnum/Vk/Instance.cpp +++ b/src/Magnum/Vk/Instance.cpp @@ -24,6 +24,7 @@ */ #include "Instance.h" +#include "InstanceCreateInfo.h" #include #include @@ -301,6 +302,8 @@ Instance::Instance(const InstanceCreateInfo& info): _flags{HandleFlag::DestroyOn initialize(version, 0, nullptr); } +Instance::Instance(): Instance{InstanceCreateInfo{}} {} + Instance::Instance(NoCreateT): _handle{}, _functionPointers{} {} Instance::Instance(Instance&& other) noexcept: _handle{other._handle}, diff --git a/src/Magnum/Vk/Instance.h b/src/Magnum/Vk/Instance.h index 684d0b485..8c0e7868c 100644 --- a/src/Magnum/Vk/Instance.h +++ b/src/Magnum/Vk/Instance.h @@ -26,7 +26,7 @@ */ /** @file - * @brief Class @ref Magnum::Vk::InstanceCreateInfo, @ref Magnum::Vk::Instance + * @brief Class @ref Magnum::Vk::Instance * @m_since_latest */ @@ -47,197 +47,6 @@ namespace Implementation { struct InstanceState; } -/** -@brief Instance creation info -@m_since_latest - -Wraps a @type_vk_keyword{InstanceCreateInfo} and -@type_vk_keyword{ApplicationInfo}. See -@ref Vk-Instance-creation "Instance creation" for usage information. -*/ -class MAGNUM_VK_EXPORT InstanceCreateInfo { - public: - /** - * @brief Instance creation flag - * - * Wraps @type_vk_keyword{InstanceCreateFlagBits}. - * @see @ref Flags, @ref InstanceCreateInfo(Int, const char**, const LayerProperties*, const InstanceExtensionProperties*, Flags) - */ - enum class Flag: UnsignedInt { - /* Any magnum-specific flags added here have to be filtered out - when passing them to _info.flags in the constructor. Using the - highest bits in a hope to prevent conflicts with Vulkan instance - flags added in the future. */ - - /** - * Don't implicitly enable any extensions. - * - * By default, the engine enables various extensions such as - * @vk_extension{KHR,get_physical_device_properties2} to provide a - * broader functionality. If you want to have a complete control - * over what gets enabled, set this flag. - */ - NoImplicitExtensions = 1u << 31 - }; - - /** - * @brief Instance creation flags - * - * Type-safe wrapper for @type_vk_keyword{InstanceCreateFlags}. - * @see @ref InstanceCreateInfo(Int, const char**, const LayerProperties*, const InstanceExtensionProperties*, Flags) - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param argc Command-line argument count. Can be @cpp 0 @ce. - * @param argv Command-line argument values. Can be - * @cpp nullptr @ce. If set, is expected to stay in scope for the - * whole instance lifetime. - * @param layerProperties Existing @ref LayerProperties instance for - * querying available Vulkan layers. If @cpp nullptr @ce, a new - * instance may be created internally if needed. - * @param extensionProperties Existing @ref InstanceExtensionProperties - * instance for querying available Vulkan extensions. If - * @cpp nullptr @ce, a new instance may be created internally if - * needed. - * @param flags Instance creation flags - * - * The following @type_vk{InstanceCreateInfo} fields are pre-filled in - * addition to `sType`, everything else is zero-filled: - * - * - `pApplicationInfo` - * - @cpp pApplicationInfo->apiVersion @ce to - * @ref enumerateInstanceVersion() - * - @cpp pApplicationInfo->engineName @ce to @cpp "Magnum" @ce - */ - /* All those are implicit in order to allow writing - Instance instance{{argc, argv}}; - It's a tradeoff between a completely verbose way and - Instance instance{argc, argv}; - in which case all these overloads would need to be duplicated on - Instance as well. */ - /*implicit*/ InstanceCreateInfo(Int argc, const char** argv, const LayerProperties* layerProperties, const InstanceExtensionProperties* const extensionProperties, Flags flags = {}); - - /** @overload */ - /*implicit*/ InstanceCreateInfo(Int argc, char** argv, const LayerProperties* layerProperties, const InstanceExtensionProperties* extensionProperties, Flags flags = {}): InstanceCreateInfo{argc, const_cast(argv), layerProperties, extensionProperties, flags} {} - - /** @overload */ - /*implicit*/ InstanceCreateInfo(Int argc, std::nullptr_t argv, const LayerProperties* layerProperties, const InstanceExtensionProperties* extensionProperties, Flags flags = {}): InstanceCreateInfo{argc, static_cast(argv), layerProperties, extensionProperties, flags} {} - - /** @overload */ - /*implicit*/ InstanceCreateInfo(Int argc, const char** argv, Flags flags = {}): InstanceCreateInfo{argc, argv, nullptr, nullptr, flags} {} - - /** @overload */ - /*implicit*/ InstanceCreateInfo(Int argc, char** argv, Flags flags = {}): InstanceCreateInfo{argc, argv, nullptr, nullptr, flags} {} - - /** @overload */ - /*implicit*/ InstanceCreateInfo(Int argc, std::nullptr_t argv, Flags flags = {}): InstanceCreateInfo{argc, argv, nullptr, nullptr, flags} {} - - /** @overload */ - /*implicit*/ InstanceCreateInfo(Flags flags = {}): InstanceCreateInfo{0, nullptr, 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 InstanceCreateInfo(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 InstanceCreateInfo(const VkInstanceCreateInfo& info); - - ~InstanceCreateInfo(); - - /** - * @brief Set application info - * @return Reference to self (for method chaining) - * - * Use the @ref version() helper to create the @p version value. The - * name is @cpp nullptr @ce by default. - * - * The function makes copies of string views that are not owning or - * null-terminated, use the @link Containers::Literals::operator""_s() @endlink - * literal to prevent that where possible. - */ - InstanceCreateInfo& setApplicationInfo(Containers::StringView name, Version version); - - /** - * @brief Add enabled layers - * @return Reference to self (for method chaining) - * - * All listed layers are expected be supported, use - * @ref LayerProperties::isSupported() to check for their presence. If - * a particular layer is listed among `--magnum-disable-layers` in - * @ref Vk-Instance-command-line "command-line options", it's not - * added. - * - * The function makes copies of string views that are not owning or - * null-terminated, use the @link Containers::Literals::operator""_s() @endlink - * literal to prevent that where possible. - */ - InstanceCreateInfo& addEnabledLayers(Containers::ArrayView layers); - /** @overload */ - InstanceCreateInfo& addEnabledLayers(std::initializer_list layers); - - /** - * @brief Add enabled instance extensions - * @return Reference to self (for method chaining) - * - * All listed extensions are expected to be supported either globally - * or in at least one of the enabled layers, use - * @ref InstanceExtensionProperties::isSupported() to check for their - * presence. If a particular extension is listed among - * `--magnum-disable-extensions` in - * @ref Vk-Instance-command-line "command-line options", it's not - * added. - * - * The function makes copies of string views that are not owning or - * null-terminated, use the @link Containers::Literals::operator""_s() @endlink - * literal to prevent that where possible. - */ - InstanceCreateInfo& addEnabledExtensions(Containers::ArrayView extensions); - /** @overload */ - InstanceCreateInfo& addEnabledExtensions(std::initializer_list extension); - /** @overload */ - InstanceCreateInfo& addEnabledExtensions(Containers::ArrayView extensions); - /** @overload */ - InstanceCreateInfo& addEnabledExtensions(std::initializer_list extension); - /** @overload */ - template InstanceCreateInfo& addEnabledExtensions() { - static_assert(Implementation::IsInstanceExtension::value, "expected only Vulkan instance extensions"); - return addEnabledExtensions({E{}...}); - } - - /** @brief Underlying @type_vk{InstanceCreateInfo} structure */ - VkInstanceCreateInfo& operator*() { return _info; } - /** @overload */ - const VkInstanceCreateInfo& operator*() const { return _info; } - /** @overload */ - VkInstanceCreateInfo* operator->() { return &_info; } - /** @overload */ - const VkInstanceCreateInfo* operator->() const { return &_info; } - /** @overload */ - operator const VkInstanceCreateInfo*() const { return &_info; } - - private: - friend Instance; - - VkInstanceCreateInfo _info; - VkApplicationInfo _applicationInfo; - struct State; - Containers::Pointer _state; -}; - -CORRADE_ENUMSET_OPERATORS(InstanceCreateInfo::Flags) - /** @brief Instance @m_since_latest @@ -401,7 +210,13 @@ class MAGNUM_VK_EXPORT Instance { * * @see @fn_vk_keyword{CreateInstance} */ + #ifdef DOXYGEN_GENERATING_OUTPUT explicit Instance(const InstanceCreateInfo& info = InstanceCreateInfo{}); + #else + /* To avoid dependency on InstanceCreateInfo.h */ + explicit Instance(const InstanceCreateInfo& info); + explicit Instance(); + #endif /** * @brief Construct without creating the instance diff --git a/src/Magnum/Vk/InstanceCreateInfo.h b/src/Magnum/Vk/InstanceCreateInfo.h new file mode 100644 index 000000000..d12411927 --- /dev/null +++ b/src/Magnum/Vk/InstanceCreateInfo.h @@ -0,0 +1,240 @@ +#ifndef Magnum_Vk_InstanceCreateInfo_h +#define Magnum_Vk_InstanceCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::InstanceCreateInfo + * @m_since_latest + */ + +#include + +#include "Magnum/Tags.h" +#include "Magnum/Vk/TypeTraits.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Instance creation info +@m_since_latest + +Wraps a @type_vk_keyword{InstanceCreateInfo} and +@type_vk_keyword{ApplicationInfo}. See +@ref Vk-Instance-creation "Instance creation" for usage information. +*/ +class MAGNUM_VK_EXPORT InstanceCreateInfo { + public: + /** + * @brief Instance creation flag + * + * Wraps @type_vk_keyword{InstanceCreateFlagBits}. + * @see @ref Flags, @ref InstanceCreateInfo(Int, const char**, const LayerProperties*, const InstanceExtensionProperties*, Flags) + */ + enum class Flag: UnsignedInt { + /* Any magnum-specific flags added here have to be filtered out + when passing them to _info.flags in the constructor. Using the + highest bits in a hope to prevent conflicts with Vulkan instance + flags added in the future. */ + + /** + * Don't implicitly enable any extensions. + * + * By default, the engine enables various extensions such as + * @vk_extension{KHR,get_physical_device_properties2} to provide a + * broader functionality. If you want to have a complete control + * over what gets enabled, set this flag. + */ + NoImplicitExtensions = 1u << 31 + }; + + /** + * @brief Instance creation flags + * + * Type-safe wrapper for @type_vk_keyword{InstanceCreateFlags}. + * @see @ref InstanceCreateInfo(Int, const char**, const LayerProperties*, const InstanceExtensionProperties*, Flags) + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param argc Command-line argument count. Can be @cpp 0 @ce. + * @param argv Command-line argument values. Can be + * @cpp nullptr @ce. If set, is expected to stay in scope for the + * whole instance lifetime. + * @param layerProperties Existing @ref LayerProperties instance for + * querying available Vulkan layers. If @cpp nullptr @ce, a new + * instance may be created internally if needed. + * @param extensionProperties Existing @ref InstanceExtensionProperties + * instance for querying available Vulkan extensions. If + * @cpp nullptr @ce, a new instance may be created internally if + * needed. + * @param flags Instance creation flags + * + * The following @type_vk{InstanceCreateInfo} fields are pre-filled in + * addition to `sType`, everything else is zero-filled: + * + * - `pApplicationInfo` + * - @cpp pApplicationInfo->apiVersion @ce to + * @ref enumerateInstanceVersion() + * - @cpp pApplicationInfo->engineName @ce to @cpp "Magnum" @ce + */ + /* All those are implicit in order to allow writing + Instance instance{{argc, argv}}; + It's a tradeoff between a completely verbose way and + Instance instance{argc, argv}; + in which case all these overloads would need to be duplicated on + Instance as well. */ + /*implicit*/ InstanceCreateInfo(Int argc, const char** argv, const LayerProperties* layerProperties, const InstanceExtensionProperties* const extensionProperties, Flags flags = {}); + + /** @overload */ + /*implicit*/ InstanceCreateInfo(Int argc, char** argv, const LayerProperties* layerProperties, const InstanceExtensionProperties* extensionProperties, Flags flags = {}): InstanceCreateInfo{argc, const_cast(argv), layerProperties, extensionProperties, flags} {} + + /** @overload */ + /*implicit*/ InstanceCreateInfo(Int argc, std::nullptr_t argv, const LayerProperties* layerProperties, const InstanceExtensionProperties* extensionProperties, Flags flags = {}): InstanceCreateInfo{argc, static_cast(argv), layerProperties, extensionProperties, flags} {} + + /** @overload */ + /*implicit*/ InstanceCreateInfo(Int argc, const char** argv, Flags flags = {}): InstanceCreateInfo{argc, argv, nullptr, nullptr, flags} {} + + /** @overload */ + /*implicit*/ InstanceCreateInfo(Int argc, char** argv, Flags flags = {}): InstanceCreateInfo{argc, argv, nullptr, nullptr, flags} {} + + /** @overload */ + /*implicit*/ InstanceCreateInfo(Int argc, std::nullptr_t argv, Flags flags = {}): InstanceCreateInfo{argc, argv, nullptr, nullptr, flags} {} + + /** @overload */ + /*implicit*/ InstanceCreateInfo(Flags flags = {}): InstanceCreateInfo{0, nullptr, 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 InstanceCreateInfo(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 InstanceCreateInfo(const VkInstanceCreateInfo& info); + + ~InstanceCreateInfo(); + + /** + * @brief Set application info + * @return Reference to self (for method chaining) + * + * Use the @ref version() helper to create the @p version value. The + * name is @cpp nullptr @ce by default. + * + * The function makes copies of string views that are not owning or + * null-terminated, use the @link Containers::Literals::operator""_s() @endlink + * literal to prevent that where possible. + */ + InstanceCreateInfo& setApplicationInfo(Containers::StringView name, Version version); + + /** + * @brief Add enabled layers + * @return Reference to self (for method chaining) + * + * All listed layers are expected be supported, use + * @ref LayerProperties::isSupported() to check for their presence. If + * a particular layer is listed among `--magnum-disable-layers` in + * @ref Vk-Instance-command-line "command-line options", it's not + * added. + * + * The function makes copies of string views that are not owning or + * null-terminated, use the @link Containers::Literals::operator""_s() @endlink + * literal to prevent that where possible. + */ + InstanceCreateInfo& addEnabledLayers(Containers::ArrayView layers); + /** @overload */ + InstanceCreateInfo& addEnabledLayers(std::initializer_list layers); + + /** + * @brief Add enabled instance extensions + * @return Reference to self (for method chaining) + * + * All listed extensions are expected to be supported either globally + * or in at least one of the enabled layers, use + * @ref InstanceExtensionProperties::isSupported() to check for their + * presence. If a particular extension is listed among + * `--magnum-disable-extensions` in + * @ref Vk-Instance-command-line "command-line options", it's not + * added. + * + * The function makes copies of string views that are not owning or + * null-terminated, use the @link Containers::Literals::operator""_s() @endlink + * literal to prevent that where possible. + */ + InstanceCreateInfo& addEnabledExtensions(Containers::ArrayView extensions); + /** @overload */ + InstanceCreateInfo& addEnabledExtensions(std::initializer_list extension); + /** @overload */ + InstanceCreateInfo& addEnabledExtensions(Containers::ArrayView extensions); + /** @overload */ + InstanceCreateInfo& addEnabledExtensions(std::initializer_list extension); + /** @overload */ + template InstanceCreateInfo& addEnabledExtensions() { + static_assert(Implementation::IsInstanceExtension::value, "expected only Vulkan instance extensions"); + return addEnabledExtensions({E{}...}); + } + + /** @brief Underlying @type_vk{InstanceCreateInfo} structure */ + VkInstanceCreateInfo& operator*() { return _info; } + /** @overload */ + const VkInstanceCreateInfo& operator*() const { return _info; } + /** @overload */ + VkInstanceCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkInstanceCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkInstanceCreateInfo*() const { return &_info; } + + private: + friend Instance; + + VkInstanceCreateInfo _info; + VkApplicationInfo _applicationInfo; + struct State; + Containers::Pointer _state; +}; + +CORRADE_ENUMSET_OPERATORS(InstanceCreateInfo::Flags) + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/Instance.h" + +#endif diff --git a/src/Magnum/Vk/Memory.cpp b/src/Magnum/Vk/Memory.cpp index d4126789f..ad7428785 100644 --- a/src/Magnum/Vk/Memory.cpp +++ b/src/Magnum/Vk/Memory.cpp @@ -24,6 +24,7 @@ */ #include "Memory.h" +#include "MemoryAllocateInfo.h" #include #include diff --git a/src/Magnum/Vk/Memory.h b/src/Magnum/Vk/Memory.h index 407794f8c..02ce102a5 100644 --- a/src/Magnum/Vk/Memory.h +++ b/src/Magnum/Vk/Memory.h @@ -113,149 +113,6 @@ CORRADE_ENUMSET_OPERATORS(MemoryFlags) */ MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, MemoryFlags value); -/** -@brief Device memory requirements -@m_since_latest - -Wraps a @type_vk_keyword{MemoryRequirements2}. Not constructible directly, -returned from @ref Image::memoryRequirements() and -@ref Buffer::memoryRequirements(). -@see @ref DeviceProperties::pickMemory() -*/ -class MAGNUM_VK_EXPORT MemoryRequirements { - public: - /** - * @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 MemoryRequirements(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 MemoryRequirements(const VkMemoryRequirements2& requirements); - - /** @brief Underlying @type_vk{MemoryRequirements} structure */ - VkMemoryRequirements2& requirements() { return _requirements; } - /** @overload */ - const VkMemoryRequirements2& requirements() const { return _requirements; } - /** @overload */ - operator VkMemoryRequirements2&() { return _requirements; } - /** @overload */ - operator const VkMemoryRequirements2&() const { return _requirements; } - /** @overload */ - VkMemoryRequirements2* operator->() { return &_requirements; } - /** @overload */ - const VkMemoryRequirements2* operator->() const { return &_requirements; } - - /** - * @brief Required memory size - * - * @see @ref alignedSize() - */ - UnsignedLong size() const { - return _requirements.memoryRequirements.size; - } - - /** - * @brief Required memory alignment - * - * @see @ref alignedSize() - */ - UnsignedLong alignment() const { - return _requirements.memoryRequirements.alignment; - } - - /** - * @brief Required memory size rounded up for given alignment - * - * Pads @ref size() with given alignment requirements. For example, a - * 13765-byte buffer aligned to 4 kB would be 16384 bytes. See the - * @ref Memory class for more information and example usage. - * - * The alignment is expected to be non-zero. - */ - UnsignedLong alignedSize(UnsignedLong alignment) const; - - /** @brief Bits indicating which memory */ - UnsignedInt memories() const { - return _requirements.memoryRequirements.memoryTypeBits; - } - - private: - friend Buffer; - friend Image; - - explicit MemoryRequirements(); - - VkMemoryRequirements2 _requirements; -}; - -/** -@brief Memory allocation info -@m_since_latest - -Wraps a @type_vk_keyword{MemoryAllocateInfo}. See -@ref Vk-Memory-allocation "Memory allocation" for usage information. -*/ -class MAGNUM_VK_EXPORT MemoryAllocateInfo { - public: - /** @todo Flags, in VkMemoryAllocateFlagsInfo (1.1) */ - - /** - * @brief Constructor - * @param size Allocation size in bytes - * @param memory Memory index, smaller than - * @ref DeviceProperties::memoryCount() - * - * The following @type_vk{MemoryAllocateInfo} fields are pre-filled in - * addition to `sType`, everything else is zero-filled: - * - * - `allocationSize` to @p size - * - `memoryTypeIndex` to @p memory - * - * @see @ref DeviceProperties::pickMemory() - */ - explicit MemoryAllocateInfo(UnsignedLong size, UnsignedInt memory); - - /** - * @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 MemoryAllocateInfo(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 MemoryAllocateInfo(const VkMemoryAllocateInfo& info); - - /** @brief Underlying @type_vk{MemoryAllocateInfo} structure */ - VkMemoryAllocateInfo& operator*() { return _info; } - /** @overload */ - const VkMemoryAllocateInfo& operator*() const { return _info; } - /** @overload */ - VkMemoryAllocateInfo* operator->() { return &_info; } - /** @overload */ - const VkMemoryAllocateInfo* operator->() const { return &_info; } - /** @overload */ - operator const VkMemoryAllocateInfo*() const { return &_info; } - - private: - VkMemoryAllocateInfo _info; -}; - /** @brief Device memory @m_since_latest diff --git a/src/Magnum/Vk/MemoryAllocateInfo.h b/src/Magnum/Vk/MemoryAllocateInfo.h new file mode 100644 index 000000000..321afb40c --- /dev/null +++ b/src/Magnum/Vk/MemoryAllocateInfo.h @@ -0,0 +1,189 @@ +#ifndef Magnum_Vk_MemoryAllocateInfo_h +#define Magnum_Vk_MemoryAllocateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::MemoryRequirements, @ref Magnum::Vk::MemoryAllocateInfo + */ + +#include "Magnum/Magnum.h" +#include "Magnum/Tags.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Device memory requirements +@m_since_latest + +Wraps a @type_vk_keyword{MemoryRequirements2}. Not constructible directly, +returned from @ref Image::memoryRequirements() and +@ref Buffer::memoryRequirements(). +@see @ref DeviceProperties::pickMemory() +*/ +class MAGNUM_VK_EXPORT MemoryRequirements { + public: + /** + * @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 MemoryRequirements(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 MemoryRequirements(const VkMemoryRequirements2& requirements); + + /** @brief Underlying @type_vk{MemoryRequirements} structure */ + VkMemoryRequirements2& requirements() { return _requirements; } + /** @overload */ + const VkMemoryRequirements2& requirements() const { return _requirements; } + /** @overload */ + operator VkMemoryRequirements2&() { return _requirements; } + /** @overload */ + operator const VkMemoryRequirements2&() const { return _requirements; } + /** @overload */ + VkMemoryRequirements2* operator->() { return &_requirements; } + /** @overload */ + const VkMemoryRequirements2* operator->() const { return &_requirements; } + + /** + * @brief Required memory size + * + * @see @ref alignedSize() + */ + UnsignedLong size() const { + return _requirements.memoryRequirements.size; + } + + /** + * @brief Required memory alignment + * + * @see @ref alignedSize() + */ + UnsignedLong alignment() const { + return _requirements.memoryRequirements.alignment; + } + + /** + * @brief Required memory size rounded up for given alignment + * + * Pads @ref size() with given alignment requirements. For example, a + * 13765-byte buffer aligned to 4 kB would be 16384 bytes. See the + * @ref Memory class for more information and example usage. + * + * The alignment is expected to be non-zero. + */ + UnsignedLong alignedSize(UnsignedLong alignment) const; + + /** @brief Bits indicating which memory */ + UnsignedInt memories() const { + return _requirements.memoryRequirements.memoryTypeBits; + } + + private: + friend Buffer; + friend Image; + + explicit MemoryRequirements(); + + VkMemoryRequirements2 _requirements; +}; + +/** +@brief Memory allocation info +@m_since_latest + +Wraps a @type_vk_keyword{MemoryAllocateInfo}. See +@ref Vk-Memory-allocation "Memory allocation" for usage information. +*/ +class MAGNUM_VK_EXPORT MemoryAllocateInfo { + public: + /** @todo Flags, in VkMemoryAllocateFlagsInfo (1.1) */ + + /** + * @brief Constructor + * @param size Allocation size in bytes + * @param memory Memory index, smaller than + * @ref DeviceProperties::memoryCount() + * + * The following @type_vk{MemoryAllocateInfo} fields are pre-filled in + * addition to `sType`, everything else is zero-filled: + * + * - `allocationSize` to @p size + * - `memoryTypeIndex` to @p memory + * + * @see @ref DeviceProperties::pickMemory() + */ + explicit MemoryAllocateInfo(UnsignedLong size, UnsignedInt memory); + + /** + * @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 MemoryAllocateInfo(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 MemoryAllocateInfo(const VkMemoryAllocateInfo& info); + + /** @brief Underlying @type_vk{MemoryAllocateInfo} structure */ + VkMemoryAllocateInfo& operator*() { return _info; } + /** @overload */ + const VkMemoryAllocateInfo& operator*() const { return _info; } + /** @overload */ + VkMemoryAllocateInfo* operator->() { return &_info; } + /** @overload */ + const VkMemoryAllocateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkMemoryAllocateInfo*() const { return &_info; } + + private: + VkMemoryAllocateInfo _info; +}; + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/Memory.h" + +#endif diff --git a/src/Magnum/Vk/RenderPass.cpp b/src/Magnum/Vk/RenderPass.cpp index 7590489a6..d4e14974b 100644 --- a/src/Magnum/Vk/RenderPass.cpp +++ b/src/Magnum/Vk/RenderPass.cpp @@ -24,6 +24,7 @@ */ #include "RenderPass.h" +#include "RenderPassCreateInfo.h" #include #include diff --git a/src/Magnum/Vk/RenderPass.h b/src/Magnum/Vk/RenderPass.h index 36f21e668..2bab9f65f 100644 --- a/src/Magnum/Vk/RenderPass.h +++ b/src/Magnum/Vk/RenderPass.h @@ -26,980 +26,18 @@ */ /** @file - * @brief Class @ref Magnum::Vk::AttachmentDescription, @ref Magnum::Vk::AttachmentReference, @ref Magnum::Vk::SubpassDescription, @ref Magnum::Vk::SubpassDependency, @ref Magnum::Vk::RenderPassCreateInfo, @ref Magnum::Vk::RenderPass, enum @ref Magnum::Vk::AttachmentLoadOperation, @ref Magnum::Vk::AttachmentStoreOperation + * @brief Class @ref Magnum::Vk::RenderPass */ -#include -#include -#include - #include "Magnum/Magnum.h" #include "Magnum/Tags.h" +#include "Magnum/Vk/Handle.h" #include "Magnum/Vk/Vk.h" #include "Magnum/Vk/Vulkan.h" #include "Magnum/Vk/visibility.h" namespace Magnum { namespace Vk { -/** -@brief Attachment load operation -@m_since_latest - -Wraps a @type_vk_keyword{AttachmentLoadOp}, specifies how previous contents of -an attached image within the render area are treated at the beginning of a -subpass. -@see @ref AttachmentStoreOperation, @ref AttachmentDescription -@m_enum_values_as_keywords -*/ -enum class AttachmentLoadOperation: Int { - /** - * Previous contents are preserved. This is the conservative default when - * using the @ref AttachmentDescription::AttachmentDescription(VkFormat, Int, Flags) - * constructor. - * - * This value is also guaranteed to be @cpp 0 @ce, which means you're - * encouraged to simply use @cpp {} @ce in function calls and elsewhere. - */ - Load = VK_ATTACHMENT_LOAD_OP_LOAD, - - /** - * Previous contents are cleared to a value specified when a render pass - * instance is begun. - * - * @m_class{m-note m-success} - * - * @par - * Compared to @ref AttachmentLoadOperation::Load, if you don't need - * the previous contents, this can avoid a potentially expensive - * memory load on certain architectures. - */ - Clear = VK_ATTACHMENT_LOAD_OP_CLEAR, - - /** - * Previous contents don't need to be preserved. - * - * @m_class{m-note m-success} - * - * @par - * Compared to @ref AttachmentLoadOperation::Load and - * @ref AttachmentLoadOperation::Clear, if you will be fully - * overwriting the contents anyway, this can avoid a potentially - * expensive memory load or clear operation. - */ - DontCare = VK_ATTACHMENT_LOAD_OP_DONT_CARE -}; - -/** -@brief Attachment load operation -@m_since_latest - -Wraps a @type_vk_keyword{AttachmentStoreOp}, specifies how contents of an -attached image generated during the render pass within the render area are -treated at the end of a subpass. -@see @ref AttachmentLoadOperation, @ref AttachmentDescription -@m_enum_values_as_keywords -*/ -enum class AttachmentStoreOperation: Int { - /** - * Generated contents are written to memory. This is the conservative - * default when using the @ref AttachmentDescription::AttachmentDescription(VkFormat, Int, Flags) - * constructor. - * - * This value is also guaranteed to be @cpp 0 @ce, which means you're - * encouraged to simply use @cpp {} @ce in function calls and elsewhere. - */ - Store = VK_ATTACHMENT_STORE_OP_STORE, - - /** - * Generated contentgs don't need to be preserved. - * - * @m_class{m-note m-success} - * - * @par - * Compared to @ref AttachmentStoreOperation::Store, if the attachment - * was only used temporarily during a subpass, this can avoid a - * potentially expensive memory store operation on certain - * architectures. - */ - DontCare = VK_ATTACHMENT_STORE_OP_DONT_CARE -}; - -/** -@brief Attachment description -@m_since_latest - -Wraps a @type_vk_keyword{AttachmentDescription2}. This class is subsequently -passed to a @ref RenderPass, see its documentation for a high-level usage -information. - -@section Vk-AttachmentDescription-compatibility Compatibility with VkAttachmentDescription - -While the class operates on the @type_vk{AttachmentDescription2} structure -that's new in Vulkan 1.2 or is provided by the -@vk_extension{KHR,create_renderpass2} extenstion, conversion from and to -@type_vk{AttachmentDescription} is provided to some extent --- you can create -an @ref AttachmentDescription from it, call various methods on the instance and -then get a @type_vk{AttachmentDescription} back again using -@ref vkAttachmentDescription(). - -For direct editing of the Vulkan structure, it's recommended to edit the -@type_vk{AttachmentDescription2} fields and then perform the conversion -instead of editing the resulting @type_vk{AttachmentDescription}. - -Please note that the conversion to @type_vk{AttachmentDescription} will ignore -all fields that are present only in @type_vk{AttachmentDescription2} and its -substructures --- in particular, the whole `pNext` pointer chain is omitted. -When performing the conversion it's your responsibility to ensure nothing -significant was in the fields that were left out. -*/ -class MAGNUM_VK_EXPORT AttachmentDescription { - public: - /** - * @brief Attachment description flag - * - * Wraps @type_vk_keyword{AttachmentDescriptionFlagBits}. - * @see @ref Flags, @ref AttachmentDescription() - * @m_enum_values_as_keywords - */ - enum class Flag: UnsignedInt { - /** Aliases the same device memory as other attachments */ - MayAlias = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT - }; - - /** - * @brief Attachment description flags - * - * Type-safe wrapper for @type_vk_keyword{AttachmentDescriptionFlags}. - * @see @ref AttachmentDescription() - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param format Image format - * @param loadOperation How previous attachment contents are - * treated at the beginning of a subpass - * @param storeOperation How previous attachment contents are - * treated at the beginning of a subpass - * @param initialLayout Initial image layout. Can only be - * @ref ImageLayout::General, @ref ImageLayout::ShaderReadOnly, - * @ref ImageLayout::TransferSource, - * @ref ImageLayout::TransferDestination, and - * @ref ImageLayout::ColorAttachment in case of a color @p format - * or @ref ImageLayout::DepthStencilAttachment in case of a - * depth/stencil @p format. - * @param finalLayout Final image layout. Can only be - * @ref ImageLayout::General, @ref ImageLayout::ShaderReadOnly, - * @ref ImageLayout::TransferSource, - * @ref ImageLayout::TransferDestination, and - * @ref ImageLayout::ColorAttachment in case of a color @p format - * or @ref ImageLayout::DepthStencilAttachment in case of a - * depth/stencil @p format. - * @param samples Sample count - * @param flags Attachment description flags - * - * The following @type_vk{AttachmentDescription} fields are pre-filled - * in addition to `sType`, everything else is zero-filled: - * - * - `flags` - * - `format` - * - `samples` - * - `loadOp` to @p loadOperation - * - `storeOp` to @p storeOperation - * - `initialLayout` - * - `finalLayout` - * - * See also @ref AttachmentDescription(VkFormat, std::pair, std::pair, ImageLayout, ImageLayout, Int, Flags) - * for a constructing a combined depth/stencil attachment description. - */ - /*implicit*/ AttachmentDescription(VkFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); - - /** - * @brief Construct with implicit conservative layout - * - * Equivalent to calling @ref AttachmentDescription(VkFormat, AttachmentLoadOperation, AttachmentStoreOperation, ImageLayout, ImageLayout, Int, Flags) - * with both @p initialLayout and @p finalLayout set to - * @ref ImageLayout::General. - */ - /*implicit*/ AttachmentDescription(VkFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, Int samples = 1, Flags flags = {}); - - /** - * @brief Construct for a combined depth/stencil attachment - * @param format Image format - * @param depthStencilLoadOperation How previous depth and stencil - * attachment contents are treated at the beginning of a subpass - * @param depthStencilStoreOperation How generated depth and stencil - * attachment contents are treated at the end of a subpass - * @param initialLayout Initial image layout. Can only - * be @ref ImageLayout::General, @ref ImageLayout::ShaderReadOnly, - * @ref ImageLayout::TransferSource, - * @ref ImageLayout::TransferDestination, and - * @ref ImageLayout::DepthStencilAttachment - * @param finalLayout Final image layout. Can only be - * @ref ImageLayout::General, @ref ImageLayout::ShaderReadOnly, - * @ref ImageLayout::TransferSource, - * @ref ImageLayout::TransferDestination, and - * @ref ImageLayout::DepthStencilAttachment - * @param samples Sample count - * @param flags Attachment description flags - * - * The following @type_vk{AttachmentDescription} fields are pre-filled - * in addition to `sType`, everything else is zero-filled: - * - * - `flags` - * - `format` - * - `samples` - * - `loadOp` and `stencilLoadOp` to @p loadOperation - * - `storeOp` and `stencilStoreOp` to @p storeOperation - * - `initialLayout` - * - `finalLayout` - * - * @todo Implement @vk_extension{KHR,separate_depth_stencil_layouts} - * and provide a pair of layouts as well - */ - /*implicit*/ AttachmentDescription(VkFormat format, std::pair depthStencilLoadOperation, std::pair depthStencilStoreOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); - - /** - * @brief Construct for a combined depth/stencil attachment with implicit conservative layout - * - * Equivalent to calling @ref AttachmentDescription(VkFormat, std::pair, std::pair, ImageLayout, ImageLayout, Int, Flags) - * with both @p initialLayout and @p finalLayout set to - * @ref ImageLayout::General. - */ - /*implicit*/ AttachmentDescription(VkFormat format, std::pair depthStencilLoadOperation, std::pair depthStencilStoreOperation, Int samples = 1, Flags flags = {}); - - /** - * @brief Construct with implicit conservative load/store operation and layout - * - * Equivalent to calling @ref AttachmentDescription(VkFormat, std::pair, std::pair, ImageLayout, ImageLayout, Int, Flags) - * with @ref AttachmentLoadOperation::Load and - * @ref AttachmentStoreOperation::Store and both @p initialLayout and - * @p finalLayout set to @ref ImageLayout::General. - */ - /*implicit*/ AttachmentDescription(VkFormat format, Int samples = 1, Flags flags = {}): AttachmentDescription{format, AttachmentLoadOperation{}, AttachmentStoreOperation{}, samples, 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 AttachmentDescription(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 AttachmentDescription(const VkAttachmentDescription2& description); - - /** - * @brief Construct from a @type_vk{AttachmentDescription} - * - * Compared to the above, fills the common subset of - * @type_vk{AttachmentDescription2}, sets `sType` and zero-fills - * `pNext`. - * @see @ref vkAttachmentDescription() - */ - explicit AttachmentDescription(const VkAttachmentDescription& description); - - /** @brief Underlying @type_vk{AttachmentDescription2} structure */ - VkAttachmentDescription2& operator*() { return _description; } - /** @overload */ - const VkAttachmentDescription2& operator*() const { return _description; } - /** @overload */ - VkAttachmentDescription2* operator->() { return &_description; } - /** @overload */ - const VkAttachmentDescription2* operator->() const { return &_description; } - /** @overload */ - operator const VkAttachmentDescription2*() const { return &_description; } - - /** - * @overload - * - * The class is implicitly convertible to a reference in addition to - * a pointer because the type is commonly used in arrays as well, which - * would be annoying to do with a pointer conversion. - */ - operator const VkAttachmentDescription2&() const { return _description; } - - /** - * @brief Corresponding @type_vk{AttachmentDescription} structure - * - * Provided for compatibility with Vulkan implementations that don't - * support version 1.2 or the @vk_extension{KHR,create_renderpass2} - * extension. See @ref Vk-AttachmentDescription-compatibility for more - * information. - * @see @ref AttachmentDescription(const VkAttachmentDescription&), - * @ref AttachmentReference::vkAttachmentReference(), - * @ref SubpassDescription::vkSubpassDescription(), - * @ref SubpassDependency::vkSubpassDependency(), - * @ref RenderPassCreateInfo::vkRenderPassCreateInfo() - */ - VkAttachmentDescription vkAttachmentDescription() const; - - private: - VkAttachmentDescription2 _description; -}; - -CORRADE_ENUMSET_OPERATORS(AttachmentDescription::Flags) - -/** -@brief Attachment reference -@m_since_latest - -Wraps a @type_vk_keyword{AttachmentReference2}. Used to reference attachments -inside a @ref SubpassDescription, which is subsequently passed to a -@ref RenderPass. See its documentation for a high-level overview. - -@section Vk-AttachmentReference-compatibility Compatibility with VkAttachmentReference - -While the class operates on the @type_vk{AttachmentReference2} structure that's -new in Vulkan 1.2 or is provided by the @vk_extension{KHR,create_renderpass2} -extenstion, conversion from and to @type_vk{AttachmentReference} is provided to -some extent --- you can create an @ref AttachmentReference from it, call -various methods on the instance and then get a @type_vk{AttachmentReference} -back again using @ref vkAttachmentReference(). - -For direct editing of the Vulkan structure, it's recommended to edit the -@type_vk{AttachmentReference2} fields and then perform the conversion instead -of editing the resulting @type_vk{AttachmentReference}. - -Please note that the conversion to @type_vk{AttachmentReference} will ignore -all fields that are present only in @type_vk{AttachmentReference2} --- in -particular, the whole `pNext` pointer chain is omitted. When performing the -conversion it's your responsibility to ensure nothing significant was in the -fields that were left out. -*/ -class MAGNUM_VK_EXPORT AttachmentReference { - public: - /** - * @brief Constructor - * @param attachment Attachment index from the list passed to - * @ref RenderPassCreateInfo::setAttachments() - * @param layout Image layout. Should correspond to what's - * passed to @p initialLayout and @p finalLayout in - * @ref AttachmentDescription constructor - * - * The following @type_vk{AttachmentReference2} fields are pre-filled - * in addition to `sType`, everything else is zero-filled: - * - * - `attachment` - * - `layout` - */ - /*implicit*/ AttachmentReference(UnsignedInt attachment, ImageLayout layout = - #ifdef DOXYGEN_GENERATING_OUTPUT - /* To avoid Image.h dependency */ - ImageLayout::General - #else - ImageLayout(VK_IMAGE_LAYOUT_GENERAL) - #endif - ); - - /** - * @brief Construct with no attachment - * - * The following @type_vk{AttachmentReference2} fields are pre-filled - * in addition to `sType`, everything else is zero-filled: - * - * - `attachment` to @def_vk{ATTACHMENT_UNUSED} - * - `layout` to @ref ImageLayout::Undefined - */ - /*implicit*/ AttachmentReference(); - - /** - * @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 AttachmentReference(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 AttachmentReference(const VkAttachmentReference2& reference); - - /** - * @brief Construct from a @type_vk{AttachmentReference} - * - * Compared to the above, fills the common subset of - * @type_vk{AttachmentReference2}, sets `sType` and zero-fills `pNext` - * and `aspectMask`. - * @see @ref vkAttachmentReference() - */ - explicit AttachmentReference(const VkAttachmentReference& reference); - - /** @brief Underlying @type_vk{AttachmentReference2} structure */ - VkAttachmentReference2& operator*() { return _reference; } - /** @overload */ - const VkAttachmentReference2& operator*() const { return _reference; } - /** @overload */ - VkAttachmentReference2* operator->() { return &_reference; } - /** @overload */ - const VkAttachmentReference2* operator->() const { return &_reference; } - /** @overload */ - operator const VkAttachmentReference2*() const { return &_reference; } - - /** - * @overload - * - * The class is implicitly convertible to a reference in addition to - * a pointer because the type is commonly used in arrays as well, which - * would be annoying to do with a pointer conversion. - */ - operator const VkAttachmentReference2&() const { return _reference; } - - /** - * @brief Corresponding @type_vk{AttachmentReference} structure - * - * Provided for compatibility with Vulkan implementations that don't - * support version 1.2 or the @vk_extension{KHR,create_renderpass2} - * extension. See @ref Vk-AttachmentReference-compatibility for more - * information. - * @see @ref AttachmentReference(const VkAttachmentReference&), - * @ref AttachmentDescription::vkAttachmentDescription(), - * @ref SubpassDescription::vkSubpassDescription(), - * @ref SubpassDependency::vkSubpassDependency(), - * @ref RenderPassCreateInfo::vkRenderPassCreateInfo() - */ - VkAttachmentReference vkAttachmentReference() const; - - private: - VkAttachmentReference2 _reference; -}; - -/** -@brief Subpass description -@m_since_latest - -Wraps a @type_vk_keyword{SubpassDescription2}. This class is subsequently -passed to a @ref RenderPass, see its documentation for a high-level usage -information. - -@section Vk-SubpassDescription-compatibility Compatibility with VkSubpassDescription - -While the class operates on the @type_vk{SubpassDescription2} structure that's -new in Vulkan 1.2 or is provided by the @vk_extension{KHR,create_renderpass2} -extenstion, conversion from and to @type_vk{SubpassDescription} is provided to -some extent --- you can create a @ref SubpassDescription from it, call various -methods on the instance and then get a @type_vk{SubpassDescription} back again -using @ref vkSubpassDescription(). Note that, because of the nested data -references, some internal pointers may still point to the originating instance, -so be sure to keep it in scope for as long as needed. - -For direct editing of the Vulkan structure, it's recommended to edit the -@type_vk{SubpassDescription2} fields and then perform the conversion instead of -editing the resulting @type_vk{SubpassDescription}. - -Please note that the conversion to @type_vk{SubpassDescription} will ignore all -fields that are present only in @type_vk{SubpassDescription2} and its -substructures --- in particular, the whole `pNext` pointer chain is omitted. -When performing the conversion it's your responsibility to ensure nothing -significant was in the fields that were left out. -*/ -class MAGNUM_VK_EXPORT SubpassDescription { - public: - /** - * @brief Subpass description flag - * - * Wraps @type_vk_keyword{SubpassDescriptionFlagBits}. - * @see @ref Flags, @ref SubpassDescription() - * @m_enum_values_as_keywords - */ - enum class Flag: UnsignedInt {}; - - /** - * @brief Subpass description flags - * - * Type-safe wrapper for @type_vk_keyword{SubpassDescriptionFlags}. - * @see @ref SubpassDescription() - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * - * The following @type_vk{SubpassDescription2} fields are pre-filled - * in addition to `sType`, everything else is zero-filled: - * - * - `flags` - * - `pipelineBindPoint` to @val_vk{PIPELINE_BIND_POINT_GRAPHICS,PipelineBindPoint} - * - * Use @ref setInputAttachments(), @ref setColorAttachments(), - * @ref setDepthStencilAttachment() and @ref setPreserveAttachments() - * to set attachments. Note that a subpass without any attachment is - * valid as well. - */ - explicit SubpassDescription(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 SubpassDescription(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 SubpassDescription(const VkSubpassDescription2& description); - - /** - * @brief Construct from a @type_vk{SubpassDescription} - * - * Compared to the above, fills the common subset of - * @type_vk{SubpassDescription2}, sets `sType` and zero-fills `pNext` - * and `viewMask`. - * @see @ref vkSubpassDescription() - */ - explicit SubpassDescription(const VkSubpassDescription& description); - - /** @brief Copying is not allowed */ - SubpassDescription(const SubpassDescription&) = delete; - - /** @brief Move constructor */ - SubpassDescription(SubpassDescription&&) noexcept; - - ~SubpassDescription(); - - /** @brief Copying is not allowed */ - SubpassDescription& operator=(const SubpassDescription&) = delete; - - /** @brief Move assignment */ - SubpassDescription& operator=(SubpassDescription&&) noexcept; - - /** - * @brief Set input attachments - * @return Reference to self (for method chaining) - */ - SubpassDescription& setInputAttachments(Containers::ArrayView attachments) &; - /** @overload */ - SubpassDescription&& setInputAttachments(Containers::ArrayView attachments) &&; - /** @overload */ - SubpassDescription& setInputAttachments(std::initializer_list attachments) &; - /** @overload */ - SubpassDescription&& setInputAttachments(std::initializer_list attachments) &&; - - /** - * @brief Set color attachments - * @return Reference to self (for method chaining) - * - * The @p resolveAttachments list is expected to be either empty or - * have the same size as @p attachments. If non-empty, each item has to - * have the same format as the corresponding item in @p attachments. - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - SubpassDescription& setColorAttachments(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments = {}) &; - /** @overload */ - SubpassDescription&& setColorAttachments(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments = {}) &&; - #else - /* So we don't need to include ArrayView */ - SubpassDescription& setColorAttachments(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments) &; - SubpassDescription&& setColorAttachments(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments) &&; - SubpassDescription& setColorAttachments(Containers::ArrayView attachments) &; - SubpassDescription&& setColorAttachments(Containers::ArrayView attachments) &&; - #endif - /** @overload */ - SubpassDescription& setColorAttachments(std::initializer_list attachments, std::initializer_list resolveAttachments = {}) &; - /** @overload */ - SubpassDescription&& setColorAttachments(std::initializer_list attachments, std::initializer_list resolveAttachments = {}) &&; - - /** - * @brief Set depth/stencil attachment - * @return Reference to self (for method chaining) - * - * Calling this function with a default-constructed - * @ref AttachmentReference is equivalent to not calling it at all, and - * both mean there's no depth/stencil attachment. - */ - SubpassDescription& setDepthStencilAttachment(AttachmentReference attachment) &; - /** @overload */ - SubpassDescription&& setDepthStencilAttachment(AttachmentReference attachment) &&; - - /** - * @brief Set preserve attachments - * @return Reference to self (for method chaining) - * - * The @p attachment values are indices into the list passed to - * @ref RenderPassCreateInfo::setAttachments() - */ - SubpassDescription& setPreserveAttachments(Containers::ArrayView attachments) &; - /** @overload */ - SubpassDescription&& setPreserveAttachments(Containers::ArrayView attachments) &&; - /** @overload */ - SubpassDescription& setPreserveAttachments(Containers::Array&& attachments) &; - /** @overload */ - SubpassDescription&& setPreserveAttachments(Containers::Array&& attachments) &&; - /** @overload */ - SubpassDescription& setPreserveAttachments(std::initializer_list attachments) &; - /** @overload */ - SubpassDescription&& setPreserveAttachments(std::initializer_list attachments) &&; - - /** @brief Underlying @type_vk{SubpassDescription2} structure */ - VkSubpassDescription2& operator*() { return _description; } - /** @overload */ - const VkSubpassDescription2& operator*() const { return _description; } - /** @overload */ - VkSubpassDescription2* operator->() { return &_description; } - /** @overload */ - const VkSubpassDescription2* operator->() const { return &_description; } - /** @overload */ - operator const VkSubpassDescription2*() const { return &_description; } - - /** - * @overload - * - * The class is implicitly convertible to a reference in addition to - * a pointer because the type is commonly used in arrays as well, which - * would be annoying to do with a pointer conversion. - */ - operator const VkSubpassDescription2&() const { return _description; } - - /** - * @brief Corresponding @type_vk{SubpassDescription} structure - * - * Provided for compatibility with Vulkan implementations that don't - * support version 1.2 or the @vk_extension{KHR,create_renderpass2} - * extension. Because the type references structures not present in - * @type_vk{SubpassDescription2}, it's returned wrapped it in a - * single-item array with the extra data appended at the end of the - * allocation. Note that, however, some internal pointers such as - * `pPreserveAttachments` may still point to the originating - * @ref SubpassDescription instance, the returned allocation is not - * completely standalone. See @ref Vk-SubpassDescription-compatibility - * for more information. - * @see @ref SubpassDescription(const VkSubpassDescription&), - * @ref AttachmentDescription::vkAttachmentDescription(), - * @ref AttachmentReference::vkAttachmentReference(), - * @ref SubpassDependency::vkSubpassDependency(), - * @ref RenderPassCreateInfo::vkRenderPassCreateInfo() - */ - Containers::Array vkSubpassDescription() const; - - private: - friend class RenderPassCreateInfo; - - template void setInputAttachmentsInternal(Containers::ArrayView attachments); - template void setColorAttachmentsInternal(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments); - VkSubpassDescription2 _description; - struct State; - Containers::Pointer _state; -}; - -CORRADE_ENUMSET_OPERATORS(SubpassDescription::Flags) - -/** -@brief Subpass dependency -@m_since_latest - -Wraps a @type_vk_keyword{SubpassDependency2}. This class is subsequently -passed to a @ref RenderPass, see its documentation for a high-level usage -information. - -@section Vk-SubpassDependency-compatibility Compatibility with VkSubpassDependency - -While the class operates on the @type_vk{SubpassDependency2} structure that's -new in Vulkan 1.2 or is provided by the @vk_extension{KHR,create_renderpass2} -extenstion, conversion from and to @type_vk{SubpassDependency} is provided to -some extent --- you can create a @ref SubpassDependency from it, call various -methods on the instance and then get a @type_vk{SubpassDependency} back again -using @ref vkSubpassDependency(). - -For direct editing of the Vulkan structure, it's recommended to edit the -@type_vk{SubpassDependency2} fields and then perform the conversion instead -of editing the resulting @type_vk{SubpassDependency}. - -Please note that the conversion to @type_vk{SubpassDependency} will ignore -all fields that are present only in @type_vk{SubpassDependency2} --- in -particular, the whole `pNext` pointer chain is omitted. When performing the -conversion it's your responsibility to ensure nothing significant was in the -fields that were left out. -*/ -class MAGNUM_VK_EXPORT SubpassDependency { - public: - /** - * @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 SubpassDependency(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 SubpassDependency(const VkSubpassDependency2& dependency); - - /** - * @brief Construct from a @type_vk{SubpassDependency} - * - * Compared to the above, fills the common subset of - * @type_vk{SubpassDescription2}, sets `sType` and zero-fills `pNext` - * and `viewOffset`. - * @see @ref vkSubpassDependency() - */ - explicit SubpassDependency(const VkSubpassDependency& dependency); - - /** @brief Underlying @type_vk{SubpassDependency2} structure */ - VkSubpassDependency2& operator*() { return _dependency; } - /** @overload */ - const VkSubpassDependency2& operator*() const { return _dependency; } - /** @overload */ - VkSubpassDependency2* operator->() { return &_dependency; } - /** @overload */ - const VkSubpassDependency2* operator->() const { return &_dependency; } - /** @overload */ - operator const VkSubpassDependency2*() const { return &_dependency; } - - /** - * @overload - * - * The class is implicitly convertible to a reference in addition to - * a pointer because the type is commonly used in arrays as well, which - * would be annoying to do with a pointer conversion. - */ - operator const VkSubpassDependency2&() const { return _dependency; } - - /** - * @brief Corresponding @type_vk{SubpassDependency} structure - * - * Provided for compatibility with Vulkan implementations that don't - * support version 1.2 or the @vk_extension{KHR,create_renderpass2} - * extension. See @ref Vk-SubpassDependency-compatibility for more - * information. - * @see @ref SubpassDependency(const VkSubpassDependency&), - * @ref AttachmentDescription::vkAttachmentDescription(), - * @ref AttachmentReference::vkAttachmentReference(), - * @ref SubpassDescription::vkSubpassDescription(), - * @ref RenderPassCreateInfo::vkRenderPassCreateInfo() - */ - VkSubpassDependency vkSubpassDependency() const; - - private: - VkSubpassDependency2 _dependency; -}; - -/** -@brief Render pass creation info -@m_since_latest - -Wraps a @type_vk_keyword{RenderPassCreateInfo2} / -@type_vk_keyword{RenderPassCreateInfo}. See -@ref Vk-RenderPass-creation "Render pass creation" for usage information. - -@section Vk-RenderPassCreateInfo-compatibility Compatibility with VkRenderPassCreateInfo - -While the class operates on the @type_vk{RenderPassCreateInfo2} structure -that's new in Vulkan 1.2 or is provided by the -@vk_extension{KHR,create_renderpass2} extenstion, conversion from and to -@type_vk{RenderPassCreateInfo} is provided to some extent ---- you can create a -@ref RenderPassCreateInfo from it, call various methods on the instance and -then get a @type_vk{RenderPassCreateInfo} back again using -@ref vkRenderPassCreateInfo(). Note that, because of the nested data -references, some internal pointers may still point to the originating instance, -so be sure to keep it in scope for as long as needed. - -For direct editing of the Vulkan structure, it's recommended to edit the -@type_vk{RenderPassCreateInfo2} fields and then perform the conversion instead -of editing the resulting @type_vk{RenderPassCreateInfo}. - -Please note that the conversion to @type_vk{RenderPassCreateInfo} will ignore -all fields that are present only in @type_vk{RenderPassCreateInfo2} and its -substructures --- in particular, `pCorrelatedViewMasks` are omitted. When -performing the conversion it's your responsibility to ensure nothing -significant was in the fields that were left out. -*/ -class MAGNUM_VK_EXPORT RenderPassCreateInfo { - public: - /** - * @brief Render pass creation flag - * - * Wraps @type_vk_keyword{RenderPassCreateFlagBits}. - * @see @ref Flags, @ref RenderPassCreateInfo() - * @m_enum_values_as_keywords - */ - enum class Flag: UnsignedInt {}; - - /** - * @brief Render pass creation flags - * - * Type-safe wrapper for @type_vk_keyword{RenderPassCreateFlags}. - * @see @ref RenderPassCreateInfo() - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param flags Render pass creation flags - * - * The following @type_vk{RenderPassCreateInfo2} fields are pre-filled - * in addition to `sType`, everything else is zero-filled: - * - * - `flags` - * - * You need to call @ref addSubpass() at least once for a valid setup. - */ - explicit RenderPassCreateInfo(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 RenderPassCreateInfo(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 RenderPassCreateInfo(const VkRenderPassCreateInfo2& info); - - /** - * @brief Construct from a @type_vk{RenderPassCreateInfo} - * - * Compared to the above, fills the common subset of - * @type_vk{RenderPassCreateInfo2}, sets `sType`, zero-fills - * `correlatedViewMaskCount` and `pCorrelatedViewMasks` and then calls - * @ref setAttachments(), @ref addSubpass() and @ref setDependencies() - * with instances created using - * @ref AttachmentDescription::AttachmentDescription(const VkAttachmentDescription&), - * @ref SubpassDescription::SubpassDescription(const VkSubpassDescription&) - * and @ref SubpassDependency::SubpassDependency(const VkSubpassDependency&). - * - * @attention The `pNext` member is currently taken as-is even though - * @type_vk{RenderPassCreateInfo2} accepts only a subset of the - * structure chain allowed by @type_vk{RenderPassCreateInfo}. This - * may change in the future, however now you have to take care to - * not list disallowed structures in the chain. - * - * @todo handle @type_vk{RenderPassInputAttachmentAspectCreateInfo} - * (@vk_extension{KHR,maintenance2}) and others here - * @see @ref vkRenderPassCreateInfo() - */ - explicit RenderPassCreateInfo(const VkRenderPassCreateInfo& info); - - /** @brief Copying is not allowed */ - RenderPassCreateInfo(const RenderPassCreateInfo&) = delete; - - /** @brief Move constructor */ - RenderPassCreateInfo(RenderPassCreateInfo&& other) noexcept; - - ~RenderPassCreateInfo(); - - /** @brief Copying is not allowed */ - RenderPassCreateInfo& operator=(const RenderPassCreateInfo&) = delete; - - /** @brief Move assignment */ - RenderPassCreateInfo& operator=(RenderPassCreateInfo&& other) noexcept; - - /** - * @brief Set attachments - * @return Reference to self (for method chaining) - * - * Subsequent calls to this function will *replace* the previous set, - * not append to it. - */ - RenderPassCreateInfo& setAttachments(Containers::ArrayView attachments); - /** @overload */ - RenderPassCreateInfo& setAttachments(std::initializer_list attachments); - - /** - * @brief Add a subpass - * @return Reference to self (for method chaining) - * - * At least one subpass has to be added. - * - * @m_class{m-note m-dim} - * - * @par - * Unlike @ref setAttachments() and @ref setDependencies(), due - * to nested allocations inside @ref SubpassDescription, it's more - * efficient to *move* the instances one by one than having to - * deep-copy a list. - */ - RenderPassCreateInfo& addSubpass(SubpassDescription&& subpass); - - /** - * @brief Set subpass dependencies - * @return Reference to self (for method chaining) - * - * ubsequent calls to this function will *replace* the previous set, - * not append to it. - */ - RenderPassCreateInfo& setDependencies(Containers::ArrayView dependencies); - /** @overload */ - RenderPassCreateInfo& setDependencies(std::initializer_list dependencies); - - /** @brief Underlying @type_vk{ShaderModuleCreateInfo} structure */ - VkRenderPassCreateInfo2& operator*() { return _info; } - /** @overload */ - const VkRenderPassCreateInfo2& operator*() const { return _info; } - /** @overload */ - VkRenderPassCreateInfo2* operator->() { return &_info; } - /** @overload */ - const VkRenderPassCreateInfo2* operator->() const { return &_info; } - /** @overload */ - operator const VkRenderPassCreateInfo2*() const { return &_info; } - - /** - * @brief Corresponding @type_vk{RenderPassCreateInfo} structure - * - * Provided for compatibility with Vulkan implementations that don't - * support version 1.2 or the @vk_extension{KHR,create_renderpass2} - * extension. Because the type references structures not present in - * @type_vk{RenderPassCreateInfo2}, it's returned wrapped it in a - * single-item array with the extra data appended at the end of the - * allocation. Note that, however, some internal pointers such as - * `pNext` may still point to the originating @ref RenderPassCreateInfo - * instance, the returned allocation is not completely standalone. See - * @ref Vk-RenderPassCreateInfo-compatibility for more information. - * - * @attention The `pNext` member is currently taken as-is without - * converting the @type_vk{RenderPassCreateInfo2}-only fields to - * extra structures in the `pNext` chain for - * @type_vk{RenderPassCreateInfo}. This may change in the future, - * however now you have to take care to do needed modifications - * yourself afterwards. - * - * @see @ref RenderPassCreateInfo(const VkRenderPassCreateInfo&), - * @ref AttachmentDescription::vkAttachmentDescription(), - * @ref AttachmentReference::vkAttachmentReference(), - * @ref SubpassDescription::vkSubpassDescription(), - * @ref SubpassDependency::vkSubpassDependency() - */ - Containers::Array vkRenderPassCreateInfo() const; - - private: - template void setAttachmentsInternal(Containers::ArrayView attachments); - template void setDependenciesInternal(Containers::ArrayView dependencies); - - VkRenderPassCreateInfo2 _info; - struct State; - Containers::Pointer _state; -}; - -CORRADE_ENUMSET_OPERATORS(RenderPassCreateInfo::Flags) - namespace Implementation { struct DeviceState; } /** diff --git a/src/Magnum/Vk/RenderPassCreateInfo.h b/src/Magnum/Vk/RenderPassCreateInfo.h new file mode 100644 index 000000000..55256e23c --- /dev/null +++ b/src/Magnum/Vk/RenderPassCreateInfo.h @@ -0,0 +1,1009 @@ +#ifndef Magnum_Vk_RenderPassCreateInfo_h +#define Magnum_Vk_RenderPassCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::AttachmentDescription, @ref Magnum::Vk::AttachmentReference, @ref Magnum::Vk::SubpassDescription, @ref Magnum::Vk::SubpassDependency, @ref Magnum::Vk::RenderPassCreateInfo, enum @ref Magnum::Vk::AttachmentLoadOperation, @ref Magnum::Vk::AttachmentStoreOperation + */ + +#include +#include +#include + +#include "Magnum/Magnum.h" +#include "Magnum/Tags.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Attachment load operation +@m_since_latest + +Wraps a @type_vk_keyword{AttachmentLoadOp}, specifies how previous contents of +an attached image within the render area are treated at the beginning of a +subpass. +@see @ref AttachmentStoreOperation, @ref AttachmentDescription +@m_enum_values_as_keywords +*/ +enum class AttachmentLoadOperation: Int { + /** + * Previous contents are preserved. This is the conservative default when + * using the @ref AttachmentDescription::AttachmentDescription(VkFormat, Int, Flags) + * constructor. + * + * This value is also guaranteed to be @cpp 0 @ce, which means you're + * encouraged to simply use @cpp {} @ce in function calls and elsewhere. + */ + Load = VK_ATTACHMENT_LOAD_OP_LOAD, + + /** + * Previous contents are cleared to a value specified when a render pass + * instance is begun. + * + * @m_class{m-note m-success} + * + * @par + * Compared to @ref AttachmentLoadOperation::Load, if you don't need + * the previous contents, this can avoid a potentially expensive + * memory load on certain architectures. + */ + Clear = VK_ATTACHMENT_LOAD_OP_CLEAR, + + /** + * Previous contents don't need to be preserved. + * + * @m_class{m-note m-success} + * + * @par + * Compared to @ref AttachmentLoadOperation::Load and + * @ref AttachmentLoadOperation::Clear, if you will be fully + * overwriting the contents anyway, this can avoid a potentially + * expensive memory load or clear operation. + */ + DontCare = VK_ATTACHMENT_LOAD_OP_DONT_CARE +}; + +/** +@brief Attachment load operation +@m_since_latest + +Wraps a @type_vk_keyword{AttachmentStoreOp}, specifies how contents of an +attached image generated during the render pass within the render area are +treated at the end of a subpass. +@see @ref AttachmentLoadOperation, @ref AttachmentDescription +@m_enum_values_as_keywords +*/ +enum class AttachmentStoreOperation: Int { + /** + * Generated contents are written to memory. This is the conservative + * default when using the @ref AttachmentDescription::AttachmentDescription(VkFormat, Int, Flags) + * constructor. + * + * This value is also guaranteed to be @cpp 0 @ce, which means you're + * encouraged to simply use @cpp {} @ce in function calls and elsewhere. + */ + Store = VK_ATTACHMENT_STORE_OP_STORE, + + /** + * Generated contentgs don't need to be preserved. + * + * @m_class{m-note m-success} + * + * @par + * Compared to @ref AttachmentStoreOperation::Store, if the attachment + * was only used temporarily during a subpass, this can avoid a + * potentially expensive memory store operation on certain + * architectures. + */ + DontCare = VK_ATTACHMENT_STORE_OP_DONT_CARE +}; + +/** +@brief Attachment description +@m_since_latest + +Wraps a @type_vk_keyword{AttachmentDescription2}. This class is subsequently +passed to a @ref RenderPass, see its documentation for a high-level usage +information. + +@section Vk-AttachmentDescription-compatibility Compatibility with VkAttachmentDescription + +While the class operates on the @type_vk{AttachmentDescription2} structure +that's new in Vulkan 1.2 or is provided by the +@vk_extension{KHR,create_renderpass2} extenstion, conversion from and to +@type_vk{AttachmentDescription} is provided to some extent --- you can create +an @ref AttachmentDescription from it, call various methods on the instance and +then get a @type_vk{AttachmentDescription} back again using +@ref vkAttachmentDescription(). + +For direct editing of the Vulkan structure, it's recommended to edit the +@type_vk{AttachmentDescription2} fields and then perform the conversion +instead of editing the resulting @type_vk{AttachmentDescription}. + +Please note that the conversion to @type_vk{AttachmentDescription} will ignore +all fields that are present only in @type_vk{AttachmentDescription2} and its +substructures --- in particular, the whole `pNext` pointer chain is omitted. +When performing the conversion it's your responsibility to ensure nothing +significant was in the fields that were left out. +*/ +class MAGNUM_VK_EXPORT AttachmentDescription { + public: + /** + * @brief Attachment description flag + * + * Wraps @type_vk_keyword{AttachmentDescriptionFlagBits}. + * @see @ref Flags, @ref AttachmentDescription() + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt { + /** Aliases the same device memory as other attachments */ + MayAlias = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT + }; + + /** + * @brief Attachment description flags + * + * Type-safe wrapper for @type_vk_keyword{AttachmentDescriptionFlags}. + * @see @ref AttachmentDescription() + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param format Image format + * @param loadOperation How previous attachment contents are + * treated at the beginning of a subpass + * @param storeOperation How previous attachment contents are + * treated at the beginning of a subpass + * @param initialLayout Initial image layout. Can only be + * @ref ImageLayout::General, @ref ImageLayout::ShaderReadOnly, + * @ref ImageLayout::TransferSource, + * @ref ImageLayout::TransferDestination, and + * @ref ImageLayout::ColorAttachment in case of a color @p format + * or @ref ImageLayout::DepthStencilAttachment in case of a + * depth/stencil @p format. + * @param finalLayout Final image layout. Can only be + * @ref ImageLayout::General, @ref ImageLayout::ShaderReadOnly, + * @ref ImageLayout::TransferSource, + * @ref ImageLayout::TransferDestination, and + * @ref ImageLayout::ColorAttachment in case of a color @p format + * or @ref ImageLayout::DepthStencilAttachment in case of a + * depth/stencil @p format. + * @param samples Sample count + * @param flags Attachment description flags + * + * The following @type_vk{AttachmentDescription} fields are pre-filled + * in addition to `sType`, everything else is zero-filled: + * + * - `flags` + * - `format` + * - `samples` + * - `loadOp` to @p loadOperation + * - `storeOp` to @p storeOperation + * - `initialLayout` + * - `finalLayout` + * + * See also @ref AttachmentDescription(VkFormat, std::pair, std::pair, ImageLayout, ImageLayout, Int, Flags) + * for a constructing a combined depth/stencil attachment description. + */ + /*implicit*/ AttachmentDescription(VkFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); + + /** + * @brief Construct with implicit conservative layout + * + * Equivalent to calling @ref AttachmentDescription(VkFormat, AttachmentLoadOperation, AttachmentStoreOperation, ImageLayout, ImageLayout, Int, Flags) + * with both @p initialLayout and @p finalLayout set to + * @ref ImageLayout::General. + */ + /*implicit*/ AttachmentDescription(VkFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, Int samples = 1, Flags flags = {}); + + /** + * @brief Construct for a combined depth/stencil attachment + * @param format Image format + * @param depthStencilLoadOperation How previous depth and stencil + * attachment contents are treated at the beginning of a subpass + * @param depthStencilStoreOperation How generated depth and stencil + * attachment contents are treated at the end of a subpass + * @param initialLayout Initial image layout. Can only + * be @ref ImageLayout::General, @ref ImageLayout::ShaderReadOnly, + * @ref ImageLayout::TransferSource, + * @ref ImageLayout::TransferDestination, and + * @ref ImageLayout::DepthStencilAttachment + * @param finalLayout Final image layout. Can only be + * @ref ImageLayout::General, @ref ImageLayout::ShaderReadOnly, + * @ref ImageLayout::TransferSource, + * @ref ImageLayout::TransferDestination, and + * @ref ImageLayout::DepthStencilAttachment + * @param samples Sample count + * @param flags Attachment description flags + * + * The following @type_vk{AttachmentDescription} fields are pre-filled + * in addition to `sType`, everything else is zero-filled: + * + * - `flags` + * - `format` + * - `samples` + * - `loadOp` and `stencilLoadOp` to @p loadOperation + * - `storeOp` and `stencilStoreOp` to @p storeOperation + * - `initialLayout` + * - `finalLayout` + * + * @todo Implement @vk_extension{KHR,separate_depth_stencil_layouts} + * and provide a pair of layouts as well + */ + /*implicit*/ AttachmentDescription(VkFormat format, std::pair depthStencilLoadOperation, std::pair depthStencilStoreOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); + + /** + * @brief Construct for a combined depth/stencil attachment with implicit conservative layout + * + * Equivalent to calling @ref AttachmentDescription(VkFormat, std::pair, std::pair, ImageLayout, ImageLayout, Int, Flags) + * with both @p initialLayout and @p finalLayout set to + * @ref ImageLayout::General. + */ + /*implicit*/ AttachmentDescription(VkFormat format, std::pair depthStencilLoadOperation, std::pair depthStencilStoreOperation, Int samples = 1, Flags flags = {}); + + /** + * @brief Construct with implicit conservative load/store operation and layout + * + * Equivalent to calling @ref AttachmentDescription(VkFormat, std::pair, std::pair, ImageLayout, ImageLayout, Int, Flags) + * with @ref AttachmentLoadOperation::Load and + * @ref AttachmentStoreOperation::Store and both @p initialLayout and + * @p finalLayout set to @ref ImageLayout::General. + */ + /*implicit*/ AttachmentDescription(VkFormat format, Int samples = 1, Flags flags = {}): AttachmentDescription{format, AttachmentLoadOperation{}, AttachmentStoreOperation{}, samples, 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 AttachmentDescription(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 AttachmentDescription(const VkAttachmentDescription2& description); + + /** + * @brief Construct from a @type_vk{AttachmentDescription} + * + * Compared to the above, fills the common subset of + * @type_vk{AttachmentDescription2}, sets `sType` and zero-fills + * `pNext`. + * @see @ref vkAttachmentDescription() + */ + explicit AttachmentDescription(const VkAttachmentDescription& description); + + /** @brief Underlying @type_vk{AttachmentDescription2} structure */ + VkAttachmentDescription2& operator*() { return _description; } + /** @overload */ + const VkAttachmentDescription2& operator*() const { return _description; } + /** @overload */ + VkAttachmentDescription2* operator->() { return &_description; } + /** @overload */ + const VkAttachmentDescription2* operator->() const { return &_description; } + /** @overload */ + operator const VkAttachmentDescription2*() const { return &_description; } + + /** + * @overload + * + * The class is implicitly convertible to a reference in addition to + * a pointer because the type is commonly used in arrays as well, which + * would be annoying to do with a pointer conversion. + */ + operator const VkAttachmentDescription2&() const { return _description; } + + /** + * @brief Corresponding @type_vk{AttachmentDescription} structure + * + * Provided for compatibility with Vulkan implementations that don't + * support version 1.2 or the @vk_extension{KHR,create_renderpass2} + * extension. See @ref Vk-AttachmentDescription-compatibility for more + * information. + * @see @ref AttachmentDescription(const VkAttachmentDescription&), + * @ref AttachmentReference::vkAttachmentReference(), + * @ref SubpassDescription::vkSubpassDescription(), + * @ref SubpassDependency::vkSubpassDependency(), + * @ref RenderPassCreateInfo::vkRenderPassCreateInfo() + */ + VkAttachmentDescription vkAttachmentDescription() const; + + private: + VkAttachmentDescription2 _description; +}; + +CORRADE_ENUMSET_OPERATORS(AttachmentDescription::Flags) + +/** +@brief Attachment reference +@m_since_latest + +Wraps a @type_vk_keyword{AttachmentReference2}. Used to reference attachments +inside a @ref SubpassDescription, which is subsequently passed to a +@ref RenderPass. See its documentation for a high-level overview. + +@section Vk-AttachmentReference-compatibility Compatibility with VkAttachmentReference + +While the class operates on the @type_vk{AttachmentReference2} structure that's +new in Vulkan 1.2 or is provided by the @vk_extension{KHR,create_renderpass2} +extenstion, conversion from and to @type_vk{AttachmentReference} is provided to +some extent --- you can create an @ref AttachmentReference from it, call +various methods on the instance and then get a @type_vk{AttachmentReference} +back again using @ref vkAttachmentReference(). + +For direct editing of the Vulkan structure, it's recommended to edit the +@type_vk{AttachmentReference2} fields and then perform the conversion instead +of editing the resulting @type_vk{AttachmentReference}. + +Please note that the conversion to @type_vk{AttachmentReference} will ignore +all fields that are present only in @type_vk{AttachmentReference2} --- in +particular, the whole `pNext` pointer chain is omitted. When performing the +conversion it's your responsibility to ensure nothing significant was in the +fields that were left out. +*/ +class MAGNUM_VK_EXPORT AttachmentReference { + public: + /** + * @brief Constructor + * @param attachment Attachment index from the list passed to + * @ref RenderPassCreateInfo::setAttachments() + * @param layout Image layout. Should correspond to what's + * passed to @p initialLayout and @p finalLayout in + * @ref AttachmentDescription constructor + * + * The following @type_vk{AttachmentReference2} fields are pre-filled + * in addition to `sType`, everything else is zero-filled: + * + * - `attachment` + * - `layout` + */ + /*implicit*/ AttachmentReference(UnsignedInt attachment, ImageLayout layout = + #ifdef DOXYGEN_GENERATING_OUTPUT + /* To avoid Image.h dependency */ + ImageLayout::General + #else + ImageLayout(VK_IMAGE_LAYOUT_GENERAL) + #endif + ); + + /** + * @brief Construct with no attachment + * + * The following @type_vk{AttachmentReference2} fields are pre-filled + * in addition to `sType`, everything else is zero-filled: + * + * - `attachment` to @def_vk{ATTACHMENT_UNUSED} + * - `layout` to @ref ImageLayout::Undefined + */ + /*implicit*/ AttachmentReference(); + + /** + * @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 AttachmentReference(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 AttachmentReference(const VkAttachmentReference2& reference); + + /** + * @brief Construct from a @type_vk{AttachmentReference} + * + * Compared to the above, fills the common subset of + * @type_vk{AttachmentReference2}, sets `sType` and zero-fills `pNext` + * and `aspectMask`. + * @see @ref vkAttachmentReference() + */ + explicit AttachmentReference(const VkAttachmentReference& reference); + + /** @brief Underlying @type_vk{AttachmentReference2} structure */ + VkAttachmentReference2& operator*() { return _reference; } + /** @overload */ + const VkAttachmentReference2& operator*() const { return _reference; } + /** @overload */ + VkAttachmentReference2* operator->() { return &_reference; } + /** @overload */ + const VkAttachmentReference2* operator->() const { return &_reference; } + /** @overload */ + operator const VkAttachmentReference2*() const { return &_reference; } + + /** + * @overload + * + * The class is implicitly convertible to a reference in addition to + * a pointer because the type is commonly used in arrays as well, which + * would be annoying to do with a pointer conversion. + */ + operator const VkAttachmentReference2&() const { return _reference; } + + /** + * @brief Corresponding @type_vk{AttachmentReference} structure + * + * Provided for compatibility with Vulkan implementations that don't + * support version 1.2 or the @vk_extension{KHR,create_renderpass2} + * extension. See @ref Vk-AttachmentReference-compatibility for more + * information. + * @see @ref AttachmentReference(const VkAttachmentReference&), + * @ref AttachmentDescription::vkAttachmentDescription(), + * @ref SubpassDescription::vkSubpassDescription(), + * @ref SubpassDependency::vkSubpassDependency(), + * @ref RenderPassCreateInfo::vkRenderPassCreateInfo() + */ + VkAttachmentReference vkAttachmentReference() const; + + private: + VkAttachmentReference2 _reference; +}; + +/** +@brief Subpass description +@m_since_latest + +Wraps a @type_vk_keyword{SubpassDescription2}. This class is subsequently +passed to a @ref RenderPass, see its documentation for a high-level usage +information. + +@section Vk-SubpassDescription-compatibility Compatibility with VkSubpassDescription + +While the class operates on the @type_vk{SubpassDescription2} structure that's +new in Vulkan 1.2 or is provided by the @vk_extension{KHR,create_renderpass2} +extenstion, conversion from and to @type_vk{SubpassDescription} is provided to +some extent --- you can create a @ref SubpassDescription from it, call various +methods on the instance and then get a @type_vk{SubpassDescription} back again +using @ref vkSubpassDescription(). Note that, because of the nested data +references, some internal pointers may still point to the originating instance, +so be sure to keep it in scope for as long as needed. + +For direct editing of the Vulkan structure, it's recommended to edit the +@type_vk{SubpassDescription2} fields and then perform the conversion instead of +editing the resulting @type_vk{SubpassDescription}. + +Please note that the conversion to @type_vk{SubpassDescription} will ignore all +fields that are present only in @type_vk{SubpassDescription2} and its +substructures --- in particular, the whole `pNext` pointer chain is omitted. +When performing the conversion it's your responsibility to ensure nothing +significant was in the fields that were left out. +*/ +class MAGNUM_VK_EXPORT SubpassDescription { + public: + /** + * @brief Subpass description flag + * + * Wraps @type_vk_keyword{SubpassDescriptionFlagBits}. + * @see @ref Flags, @ref SubpassDescription() + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt {}; + + /** + * @brief Subpass description flags + * + * Type-safe wrapper for @type_vk_keyword{SubpassDescriptionFlags}. + * @see @ref SubpassDescription() + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * + * The following @type_vk{SubpassDescription2} fields are pre-filled + * in addition to `sType`, everything else is zero-filled: + * + * - `flags` + * - `pipelineBindPoint` to @val_vk{PIPELINE_BIND_POINT_GRAPHICS,PipelineBindPoint} + * + * Use @ref setInputAttachments(), @ref setColorAttachments(), + * @ref setDepthStencilAttachment() and @ref setPreserveAttachments() + * to set attachments. Note that a subpass without any attachment is + * valid as well. + */ + explicit SubpassDescription(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 SubpassDescription(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 SubpassDescription(const VkSubpassDescription2& description); + + /** + * @brief Construct from a @type_vk{SubpassDescription} + * + * Compared to the above, fills the common subset of + * @type_vk{SubpassDescription2}, sets `sType` and zero-fills `pNext` + * and `viewMask`. + * @see @ref vkSubpassDescription() + */ + explicit SubpassDescription(const VkSubpassDescription& description); + + /** @brief Copying is not allowed */ + SubpassDescription(const SubpassDescription&) = delete; + + /** @brief Move constructor */ + SubpassDescription(SubpassDescription&&) noexcept; + + ~SubpassDescription(); + + /** @brief Copying is not allowed */ + SubpassDescription& operator=(const SubpassDescription&) = delete; + + /** @brief Move assignment */ + SubpassDescription& operator=(SubpassDescription&&) noexcept; + + /** + * @brief Set input attachments + * @return Reference to self (for method chaining) + */ + SubpassDescription& setInputAttachments(Containers::ArrayView attachments) &; + /** @overload */ + SubpassDescription&& setInputAttachments(Containers::ArrayView attachments) &&; + /** @overload */ + SubpassDescription& setInputAttachments(std::initializer_list attachments) &; + /** @overload */ + SubpassDescription&& setInputAttachments(std::initializer_list attachments) &&; + + /** + * @brief Set color attachments + * @return Reference to self (for method chaining) + * + * The @p resolveAttachments list is expected to be either empty or + * have the same size as @p attachments. If non-empty, each item has to + * have the same format as the corresponding item in @p attachments. + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + SubpassDescription& setColorAttachments(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments = {}) &; + /** @overload */ + SubpassDescription&& setColorAttachments(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments = {}) &&; + #else + /* So we don't need to include ArrayView */ + SubpassDescription& setColorAttachments(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments) &; + SubpassDescription&& setColorAttachments(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments) &&; + SubpassDescription& setColorAttachments(Containers::ArrayView attachments) &; + SubpassDescription&& setColorAttachments(Containers::ArrayView attachments) &&; + #endif + /** @overload */ + SubpassDescription& setColorAttachments(std::initializer_list attachments, std::initializer_list resolveAttachments = {}) &; + /** @overload */ + SubpassDescription&& setColorAttachments(std::initializer_list attachments, std::initializer_list resolveAttachments = {}) &&; + + /** + * @brief Set depth/stencil attachment + * @return Reference to self (for method chaining) + * + * Calling this function with a default-constructed + * @ref AttachmentReference is equivalent to not calling it at all, and + * both mean there's no depth/stencil attachment. + */ + SubpassDescription& setDepthStencilAttachment(AttachmentReference attachment) &; + /** @overload */ + SubpassDescription&& setDepthStencilAttachment(AttachmentReference attachment) &&; + + /** + * @brief Set preserve attachments + * @return Reference to self (for method chaining) + * + * The @p attachment values are indices into the list passed to + * @ref RenderPassCreateInfo::setAttachments() + */ + SubpassDescription& setPreserveAttachments(Containers::ArrayView attachments) &; + /** @overload */ + SubpassDescription&& setPreserveAttachments(Containers::ArrayView attachments) &&; + /** @overload */ + SubpassDescription& setPreserveAttachments(Containers::Array&& attachments) &; + /** @overload */ + SubpassDescription&& setPreserveAttachments(Containers::Array&& attachments) &&; + /** @overload */ + SubpassDescription& setPreserveAttachments(std::initializer_list attachments) &; + /** @overload */ + SubpassDescription&& setPreserveAttachments(std::initializer_list attachments) &&; + + /** @brief Underlying @type_vk{SubpassDescription2} structure */ + VkSubpassDescription2& operator*() { return _description; } + /** @overload */ + const VkSubpassDescription2& operator*() const { return _description; } + /** @overload */ + VkSubpassDescription2* operator->() { return &_description; } + /** @overload */ + const VkSubpassDescription2* operator->() const { return &_description; } + /** @overload */ + operator const VkSubpassDescription2*() const { return &_description; } + + /** + * @overload + * + * The class is implicitly convertible to a reference in addition to + * a pointer because the type is commonly used in arrays as well, which + * would be annoying to do with a pointer conversion. + */ + operator const VkSubpassDescription2&() const { return _description; } + + /** + * @brief Corresponding @type_vk{SubpassDescription} structure + * + * Provided for compatibility with Vulkan implementations that don't + * support version 1.2 or the @vk_extension{KHR,create_renderpass2} + * extension. Because the type references structures not present in + * @type_vk{SubpassDescription2}, it's returned wrapped it in a + * single-item array with the extra data appended at the end of the + * allocation. Note that, however, some internal pointers such as + * `pPreserveAttachments` may still point to the originating + * @ref SubpassDescription instance, the returned allocation is not + * completely standalone. See @ref Vk-SubpassDescription-compatibility + * for more information. + * @see @ref SubpassDescription(const VkSubpassDescription&), + * @ref AttachmentDescription::vkAttachmentDescription(), + * @ref AttachmentReference::vkAttachmentReference(), + * @ref SubpassDependency::vkSubpassDependency(), + * @ref RenderPassCreateInfo::vkRenderPassCreateInfo() + */ + Containers::Array vkSubpassDescription() const; + + private: + friend class RenderPassCreateInfo; + + template void setInputAttachmentsInternal(Containers::ArrayView attachments); + template void setColorAttachmentsInternal(Containers::ArrayView attachments, Containers::ArrayView resolveAttachments); + VkSubpassDescription2 _description; + struct State; + Containers::Pointer _state; +}; + +CORRADE_ENUMSET_OPERATORS(SubpassDescription::Flags) + +/** +@brief Subpass dependency +@m_since_latest + +Wraps a @type_vk_keyword{SubpassDependency2}. This class is subsequently +passed to a @ref RenderPass, see its documentation for a high-level usage +information. + +@section Vk-SubpassDependency-compatibility Compatibility with VkSubpassDependency + +While the class operates on the @type_vk{SubpassDependency2} structure that's +new in Vulkan 1.2 or is provided by the @vk_extension{KHR,create_renderpass2} +extenstion, conversion from and to @type_vk{SubpassDependency} is provided to +some extent --- you can create a @ref SubpassDependency from it, call various +methods on the instance and then get a @type_vk{SubpassDependency} back again +using @ref vkSubpassDependency(). + +For direct editing of the Vulkan structure, it's recommended to edit the +@type_vk{SubpassDependency2} fields and then perform the conversion instead +of editing the resulting @type_vk{SubpassDependency}. + +Please note that the conversion to @type_vk{SubpassDependency} will ignore +all fields that are present only in @type_vk{SubpassDependency2} --- in +particular, the whole `pNext` pointer chain is omitted. When performing the +conversion it's your responsibility to ensure nothing significant was in the +fields that were left out. +*/ +class MAGNUM_VK_EXPORT SubpassDependency { + public: + /** + * @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 SubpassDependency(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 SubpassDependency(const VkSubpassDependency2& dependency); + + /** + * @brief Construct from a @type_vk{SubpassDependency} + * + * Compared to the above, fills the common subset of + * @type_vk{SubpassDescription2}, sets `sType` and zero-fills `pNext` + * and `viewOffset`. + * @see @ref vkSubpassDependency() + */ + explicit SubpassDependency(const VkSubpassDependency& dependency); + + /** @brief Underlying @type_vk{SubpassDependency2} structure */ + VkSubpassDependency2& operator*() { return _dependency; } + /** @overload */ + const VkSubpassDependency2& operator*() const { return _dependency; } + /** @overload */ + VkSubpassDependency2* operator->() { return &_dependency; } + /** @overload */ + const VkSubpassDependency2* operator->() const { return &_dependency; } + /** @overload */ + operator const VkSubpassDependency2*() const { return &_dependency; } + + /** + * @overload + * + * The class is implicitly convertible to a reference in addition to + * a pointer because the type is commonly used in arrays as well, which + * would be annoying to do with a pointer conversion. + */ + operator const VkSubpassDependency2&() const { return _dependency; } + + /** + * @brief Corresponding @type_vk{SubpassDependency} structure + * + * Provided for compatibility with Vulkan implementations that don't + * support version 1.2 or the @vk_extension{KHR,create_renderpass2} + * extension. See @ref Vk-SubpassDependency-compatibility for more + * information. + * @see @ref SubpassDependency(const VkSubpassDependency&), + * @ref AttachmentDescription::vkAttachmentDescription(), + * @ref AttachmentReference::vkAttachmentReference(), + * @ref SubpassDescription::vkSubpassDescription(), + * @ref RenderPassCreateInfo::vkRenderPassCreateInfo() + */ + VkSubpassDependency vkSubpassDependency() const; + + private: + VkSubpassDependency2 _dependency; +}; + +/** +@brief Render pass creation info +@m_since_latest + +Wraps a @type_vk_keyword{RenderPassCreateInfo2} / +@type_vk_keyword{RenderPassCreateInfo}. See +@ref Vk-RenderPass-creation "Render pass creation" for usage information. + +@section Vk-RenderPassCreateInfo-compatibility Compatibility with VkRenderPassCreateInfo + +While the class operates on the @type_vk{RenderPassCreateInfo2} structure +that's new in Vulkan 1.2 or is provided by the +@vk_extension{KHR,create_renderpass2} extenstion, conversion from and to +@type_vk{RenderPassCreateInfo} is provided to some extent ---- you can create a +@ref RenderPassCreateInfo from it, call various methods on the instance and +then get a @type_vk{RenderPassCreateInfo} back again using +@ref vkRenderPassCreateInfo(). Note that, because of the nested data +references, some internal pointers may still point to the originating instance, +so be sure to keep it in scope for as long as needed. + +For direct editing of the Vulkan structure, it's recommended to edit the +@type_vk{RenderPassCreateInfo2} fields and then perform the conversion instead +of editing the resulting @type_vk{RenderPassCreateInfo}. + +Please note that the conversion to @type_vk{RenderPassCreateInfo} will ignore +all fields that are present only in @type_vk{RenderPassCreateInfo2} and its +substructures --- in particular, `pCorrelatedViewMasks` are omitted. When +performing the conversion it's your responsibility to ensure nothing +significant was in the fields that were left out. +*/ +class MAGNUM_VK_EXPORT RenderPassCreateInfo { + public: + /** + * @brief Render pass creation flag + * + * Wraps @type_vk_keyword{RenderPassCreateFlagBits}. + * @see @ref Flags, @ref RenderPassCreateInfo() + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt {}; + + /** + * @brief Render pass creation flags + * + * Type-safe wrapper for @type_vk_keyword{RenderPassCreateFlags}. + * @see @ref RenderPassCreateInfo() + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param flags Render pass creation flags + * + * The following @type_vk{RenderPassCreateInfo2} fields are pre-filled + * in addition to `sType`, everything else is zero-filled: + * + * - `flags` + * + * You need to call @ref addSubpass() at least once for a valid setup. + */ + explicit RenderPassCreateInfo(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 RenderPassCreateInfo(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 RenderPassCreateInfo(const VkRenderPassCreateInfo2& info); + + /** + * @brief Construct from a @type_vk{RenderPassCreateInfo} + * + * Compared to the above, fills the common subset of + * @type_vk{RenderPassCreateInfo2}, sets `sType`, zero-fills + * `correlatedViewMaskCount` and `pCorrelatedViewMasks` and then calls + * @ref setAttachments(), @ref addSubpass() and @ref setDependencies() + * with instances created using + * @ref AttachmentDescription::AttachmentDescription(const VkAttachmentDescription&), + * @ref SubpassDescription::SubpassDescription(const VkSubpassDescription&) + * and @ref SubpassDependency::SubpassDependency(const VkSubpassDependency&). + * + * @attention The `pNext` member is currently taken as-is even though + * @type_vk{RenderPassCreateInfo2} accepts only a subset of the + * structure chain allowed by @type_vk{RenderPassCreateInfo}. This + * may change in the future, however now you have to take care to + * not list disallowed structures in the chain. + * + * @todo handle @type_vk{RenderPassInputAttachmentAspectCreateInfo} + * (@vk_extension{KHR,maintenance2}) and others here + * @see @ref vkRenderPassCreateInfo() + */ + explicit RenderPassCreateInfo(const VkRenderPassCreateInfo& info); + + /** @brief Copying is not allowed */ + RenderPassCreateInfo(const RenderPassCreateInfo&) = delete; + + /** @brief Move constructor */ + RenderPassCreateInfo(RenderPassCreateInfo&& other) noexcept; + + ~RenderPassCreateInfo(); + + /** @brief Copying is not allowed */ + RenderPassCreateInfo& operator=(const RenderPassCreateInfo&) = delete; + + /** @brief Move assignment */ + RenderPassCreateInfo& operator=(RenderPassCreateInfo&& other) noexcept; + + /** + * @brief Set attachments + * @return Reference to self (for method chaining) + * + * Subsequent calls to this function will *replace* the previous set, + * not append to it. + */ + RenderPassCreateInfo& setAttachments(Containers::ArrayView attachments); + /** @overload */ + RenderPassCreateInfo& setAttachments(std::initializer_list attachments); + + /** + * @brief Add a subpass + * @return Reference to self (for method chaining) + * + * At least one subpass has to be added. + * + * @m_class{m-note m-dim} + * + * @par + * Unlike @ref setAttachments() and @ref setDependencies(), due + * to nested allocations inside @ref SubpassDescription, it's more + * efficient to *move* the instances one by one than having to + * deep-copy a list. + */ + RenderPassCreateInfo& addSubpass(SubpassDescription&& subpass); + + /** + * @brief Set subpass dependencies + * @return Reference to self (for method chaining) + * + * ubsequent calls to this function will *replace* the previous set, + * not append to it. + */ + RenderPassCreateInfo& setDependencies(Containers::ArrayView dependencies); + /** @overload */ + RenderPassCreateInfo& setDependencies(std::initializer_list dependencies); + + /** @brief Underlying @type_vk{ShaderModuleCreateInfo} structure */ + VkRenderPassCreateInfo2& operator*() { return _info; } + /** @overload */ + const VkRenderPassCreateInfo2& operator*() const { return _info; } + /** @overload */ + VkRenderPassCreateInfo2* operator->() { return &_info; } + /** @overload */ + const VkRenderPassCreateInfo2* operator->() const { return &_info; } + /** @overload */ + operator const VkRenderPassCreateInfo2*() const { return &_info; } + + /** + * @brief Corresponding @type_vk{RenderPassCreateInfo} structure + * + * Provided for compatibility with Vulkan implementations that don't + * support version 1.2 or the @vk_extension{KHR,create_renderpass2} + * extension. Because the type references structures not present in + * @type_vk{RenderPassCreateInfo2}, it's returned wrapped it in a + * single-item array with the extra data appended at the end of the + * allocation. Note that, however, some internal pointers such as + * `pNext` may still point to the originating @ref RenderPassCreateInfo + * instance, the returned allocation is not completely standalone. See + * @ref Vk-RenderPassCreateInfo-compatibility for more information. + * + * @attention The `pNext` member is currently taken as-is without + * converting the @type_vk{RenderPassCreateInfo2}-only fields to + * extra structures in the `pNext` chain for + * @type_vk{RenderPassCreateInfo}. This may change in the future, + * however now you have to take care to do needed modifications + * yourself afterwards. + * + * @see @ref RenderPassCreateInfo(const VkRenderPassCreateInfo&), + * @ref AttachmentDescription::vkAttachmentDescription(), + * @ref AttachmentReference::vkAttachmentReference(), + * @ref SubpassDescription::vkSubpassDescription(), + * @ref SubpassDependency::vkSubpassDependency() + */ + Containers::Array vkRenderPassCreateInfo() const; + + private: + template void setAttachmentsInternal(Containers::ArrayView attachments); + template void setDependenciesInternal(Containers::ArrayView dependencies); + + VkRenderPassCreateInfo2 _info; + struct State; + Containers::Pointer _state; +}; + +CORRADE_ENUMSET_OPERATORS(RenderPassCreateInfo::Flags) + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/RenderPass.h" + +#endif diff --git a/src/Magnum/Vk/Shader.cpp b/src/Magnum/Vk/Shader.cpp index ad7995c9a..6bdef52d1 100644 --- a/src/Magnum/Vk/Shader.cpp +++ b/src/Magnum/Vk/Shader.cpp @@ -24,6 +24,7 @@ */ #include "Shader.h" +#include "ShaderCreateInfo.h" #include diff --git a/src/Magnum/Vk/Shader.h b/src/Magnum/Vk/Shader.h index 34f5f5e0b..a06a74a1f 100644 --- a/src/Magnum/Vk/Shader.h +++ b/src/Magnum/Vk/Shader.h @@ -26,147 +26,19 @@ */ /** @file - * @brief Class @ref Magnum::Vk::ShaderCreateInfo, @ref Magnum::Vk::Shader + * @brief Class @ref Magnum::Vk::Shader * @m_since_latest */ -#include - #include "Magnum/Magnum.h" #include "Magnum/Tags.h" +#include "Magnum/Vk/Handle.h" #include "Magnum/Vk/Vk.h" #include "Magnum/Vk/Vulkan.h" #include "Magnum/Vk/visibility.h" namespace Magnum { namespace Vk { -/** -@brief Shader creation info -@m_since_latest - -Wraps a @type_vk_keyword{ShaderModuleCreateInfo}. See -@ref Vk-Shader-creation "Shader creation" for usage information. -*/ -class MAGNUM_VK_EXPORT ShaderCreateInfo { - public: - /** - * @brief Shader creation flag - * - * Wraps @type_vk_keyword{ShaderModuleCreateFlagBits}. - * @see @ref Flags, @ref ShaderCreateInfo() - * @m_enum_values_as_keywords - */ - enum class Flag: UnsignedInt {}; - - /** - * @brief Shader creation flags - * - * Type-safe wrapper for @type_vk_keyword{ShaderModuleCreateFlags}. - * @see @ref ShaderCreateInfo() - */ - typedef Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param code Shader code - * @param flags Shader creation flags - * - * The following @type_vk{ShaderModuleCreateInfo} fields are pre-filled - * in addition to `sType`, everything else is zero-filled: - * - * - `flags` - * - `pCode` and `codeSize` to @p code - * - * @attention The class doesn't make any copy of @p code, so you either - * have to ensure it stays in scope until @ref Shader is - * constructed, or instantiate a temporary @ref ShaderCreateInfo - * directly in @ref Shader constructor call expression, as shown - * in its usage docs. If you have the data in - * @ref Corrade::Containers::Array, there's also - * @ref ShaderCreateInfo(Containers::Array&&, Flags). - */ - explicit ShaderCreateInfo(Containers::ArrayView code, Flags flags = {}); - - /** - * @brief Construct taking ownership of a r-value array instance - * - * Behaves like @ref ShaderCreateInfo(Containers::ArrayView, Flags) - * but in addition ensures @p code stays in scope until @ref Shader is - * created, deleting it on destruction. The cleanup relies on the - * pointer and size stored in @type_vk{ShaderModuleCreateInfo}, - * changing the `pCode` and `codeSize` members afterwards may result in - * memory corruption. - */ - template explicit ShaderCreateInfo(Containers::Array&& code, Flags flags = {}); - - /** - * @overload - * - * Sorry, custom @ref Corrade::Containers::Array deleter types can't be - * taken over. - */ - template explicit ShaderCreateInfo(Containers::Array&& code, Flags flags = {}) = delete; - - /** - * @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 ShaderCreateInfo(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 ShaderCreateInfo(const VkShaderModuleCreateInfo& info); - - /** @brief Copying is not allowed */ - ShaderCreateInfo(const ShaderCreateInfo&) = delete; - - /** @brief Move constructor */ - ShaderCreateInfo(ShaderCreateInfo&& other) noexcept; - - /** - * @brief Destructor - * - * If the @ref ShaderCreateInfo(Containers::Array&&, Flags) - * constructor was used, calls deleter on the stored array. - */ - ~ShaderCreateInfo(); - - /** @brief Copying is not allowed */ - ShaderCreateInfo& operator=(const ShaderCreateInfo&) = delete; - - /** @brief Move assignment */ - ShaderCreateInfo& operator=(ShaderCreateInfo&& other) noexcept; - - /** @brief Underlying @type_vk{ShaderModuleCreateInfo} structure */ - VkShaderModuleCreateInfo& operator*() { return _info; } - /** @overload */ - const VkShaderModuleCreateInfo& operator*() const { return _info; } - /** @overload */ - VkShaderModuleCreateInfo* operator->() { return &_info; } - /** @overload */ - const VkShaderModuleCreateInfo* operator->() const { return &_info; } - /** @overload */ - operator const VkShaderModuleCreateInfo*() const { return &_info; } - - private: - VkShaderModuleCreateInfo _info; - - /* Used by the Array&& constructor. Instead of wrapping an Array of an - arbitrary type we just take its deleter, the pointer + size pair is - stored in _info already. */ - void(*_originalDeleter)(){}; - void(*_deleter)(void(*)(), const void*, std::size_t){}; -}; - -CORRADE_ENUMSET_OPERATORS(ShaderCreateInfo::Flags) - /** @brief Shader @m_since_latest @@ -266,21 +138,6 @@ class MAGNUM_VK_EXPORT Shader { HandleFlags _flags; }; -template /*implicit*/ ShaderCreateInfo::ShaderCreateInfo(Containers::Array&& code, Flags flags): ShaderCreateInfo{code, flags} { - /* Remember the deleter. The pointer and size is stored in - VkShaderModuleCreateInfo and we assume it won't get stomped on - afterwards */ - _originalDeleter = reinterpret_cast(code.deleter() ? code.deleter() : static_cast([](T* data, std::size_t) { delete[] data; })); - _deleter = [](void(*originalDeleter)(), const void* data, std::size_t size) { - /* VkShaderModuleCreateInfo stores the size in bytes, convert it back - to the element count for the deleter */ - reinterpret_cast(originalDeleter)(reinterpret_cast(const_cast(data)), size/sizeof(T)); - }; - - /* Release the original array so the deleter isn't called too early */ - code.release(); -} - }} #endif diff --git a/src/Magnum/Vk/ShaderCreateInfo.h b/src/Magnum/Vk/ShaderCreateInfo.h new file mode 100644 index 000000000..e28344c26 --- /dev/null +++ b/src/Magnum/Vk/ShaderCreateInfo.h @@ -0,0 +1,191 @@ +#ifndef Magnum_Vk_ShaderCreateInfo_h +#define Magnum_Vk_ShaderCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::ShaderCreateInfo + * @m_since_latest + */ + +#include + +#include "Magnum/Magnum.h" +#include "Magnum/Tags.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Shader creation info +@m_since_latest + +Wraps a @type_vk_keyword{ShaderModuleCreateInfo}. See +@ref Vk-Shader-creation "Shader creation" for usage information. +*/ +class MAGNUM_VK_EXPORT ShaderCreateInfo { + public: + /** + * @brief Shader creation flag + * + * Wraps @type_vk_keyword{ShaderModuleCreateFlagBits}. + * @see @ref Flags, @ref ShaderCreateInfo() + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt {}; + + /** + * @brief Shader creation flags + * + * Type-safe wrapper for @type_vk_keyword{ShaderModuleCreateFlags}. + * @see @ref ShaderCreateInfo() + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param code Shader code + * @param flags Shader creation flags + * + * The following @type_vk{ShaderModuleCreateInfo} fields are pre-filled + * in addition to `sType`, everything else is zero-filled: + * + * - `flags` + * - `pCode` and `codeSize` to @p code + * + * @attention The class doesn't make any copy of @p code, so you either + * have to ensure it stays in scope until @ref Shader is + * constructed, or instantiate a temporary @ref ShaderCreateInfo + * directly in @ref Shader constructor call expression, as shown + * in its usage docs. If you have the data in + * @ref Corrade::Containers::Array, there's also + * @ref ShaderCreateInfo(Containers::Array&&, Flags). + */ + explicit ShaderCreateInfo(Containers::ArrayView code, Flags flags = {}); + + /** + * @brief Construct taking ownership of a r-value array instance + * + * Behaves like @ref ShaderCreateInfo(Containers::ArrayView, Flags) + * but in addition ensures @p code stays in scope until @ref Shader is + * created, deleting it on destruction. The cleanup relies on the + * pointer and size stored in @type_vk{ShaderModuleCreateInfo}, + * changing the `pCode` and `codeSize` members afterwards may result in + * memory corruption. + */ + template explicit ShaderCreateInfo(Containers::Array&& code, Flags flags = {}); + + /** + * @overload + * + * Sorry, custom @ref Corrade::Containers::Array deleter types can't be + * taken over. + */ + template explicit ShaderCreateInfo(Containers::Array&& code, Flags flags = {}) = delete; + + /** + * @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 ShaderCreateInfo(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 ShaderCreateInfo(const VkShaderModuleCreateInfo& info); + + /** @brief Copying is not allowed */ + ShaderCreateInfo(const ShaderCreateInfo&) = delete; + + /** @brief Move constructor */ + ShaderCreateInfo(ShaderCreateInfo&& other) noexcept; + + /** + * @brief Destructor + * + * If the @ref ShaderCreateInfo(Containers::Array&&, Flags) + * constructor was used, calls deleter on the stored array. + */ + ~ShaderCreateInfo(); + + /** @brief Copying is not allowed */ + ShaderCreateInfo& operator=(const ShaderCreateInfo&) = delete; + + /** @brief Move assignment */ + ShaderCreateInfo& operator=(ShaderCreateInfo&& other) noexcept; + + /** @brief Underlying @type_vk{ShaderModuleCreateInfo} structure */ + VkShaderModuleCreateInfo& operator*() { return _info; } + /** @overload */ + const VkShaderModuleCreateInfo& operator*() const { return _info; } + /** @overload */ + VkShaderModuleCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkShaderModuleCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkShaderModuleCreateInfo*() const { return &_info; } + + private: + VkShaderModuleCreateInfo _info; + + /* Used by the Array&& constructor. Instead of wrapping an Array of an + arbitrary type we just take its deleter, the pointer + size pair is + stored in _info already. */ + void(*_originalDeleter)(){}; + void(*_deleter)(void(*)(), const void*, std::size_t){}; +}; + +CORRADE_ENUMSET_OPERATORS(ShaderCreateInfo::Flags) + +template /*implicit*/ ShaderCreateInfo::ShaderCreateInfo(Containers::Array&& code, Flags flags): ShaderCreateInfo{code, flags} { + /* Remember the deleter. The pointer and size is stored in + VkShaderModuleCreateInfo and we assume it won't get stomped on + afterwards */ + _originalDeleter = reinterpret_cast(code.deleter() ? code.deleter() : static_cast([](T* data, std::size_t) { delete[] data; })); + _deleter = [](void(*originalDeleter)(), const void* data, std::size_t size) { + /* VkShaderModuleCreateInfo stores the size in bytes, convert it back + to the element count for the deleter */ + reinterpret_cast(originalDeleter)(reinterpret_cast(const_cast(data)), size/sizeof(T)); + }; + + /* Release the original array so the deleter isn't called too early */ + code.release(); +} + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/Shader.h" + +#endif diff --git a/src/Magnum/Vk/Test/BufferTest.cpp b/src/Magnum/Vk/Test/BufferTest.cpp index 46064a3fd..e7f881683 100644 --- a/src/Magnum/Vk/Test/BufferTest.cpp +++ b/src/Magnum/Vk/Test/BufferTest.cpp @@ -28,7 +28,7 @@ #include #include -#include "Magnum/Vk/Buffer.h" +#include "Magnum/Vk/BufferCreateInfo.h" namespace Magnum { namespace Vk { namespace Test { namespace { diff --git a/src/Magnum/Vk/Test/BufferVkTest.cpp b/src/Magnum/Vk/Test/BufferVkTest.cpp index 433f22f6b..cf529efc4 100644 --- a/src/Magnum/Vk/Test/BufferVkTest.cpp +++ b/src/Magnum/Vk/Test/BufferVkTest.cpp @@ -25,10 +25,10 @@ #include -#include "Magnum/Vk/Buffer.h" +#include "Magnum/Vk/BufferCreateInfo.h" #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Handle.h" -#include "Magnum/Vk/Memory.h" +#include "Magnum/Vk/MemoryAllocateInfo.h" #include "Magnum/Vk/Result.h" #include "Magnum/Vk/VulkanTester.h" diff --git a/src/Magnum/Vk/Test/CommandBufferVkTest.cpp b/src/Magnum/Vk/Test/CommandBufferVkTest.cpp index 024461c26..3c50fdcc0 100644 --- a/src/Magnum/Vk/Test/CommandBufferVkTest.cpp +++ b/src/Magnum/Vk/Test/CommandBufferVkTest.cpp @@ -24,7 +24,7 @@ */ #include "Magnum/Vk/CommandBuffer.h" -#include "Magnum/Vk/CommandPool.h" +#include "Magnum/Vk/CommandPoolCreateInfo.h" #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Handle.h" #include "Magnum/Vk/Result.h" diff --git a/src/Magnum/Vk/Test/CommandPoolTest.cpp b/src/Magnum/Vk/Test/CommandPoolTest.cpp index def2159ea..67b881032 100644 --- a/src/Magnum/Vk/Test/CommandPoolTest.cpp +++ b/src/Magnum/Vk/Test/CommandPoolTest.cpp @@ -26,7 +26,7 @@ #include #include -#include "Magnum/Vk/CommandPool.h" +#include "Magnum/Vk/CommandPoolCreateInfo.h" namespace Magnum { namespace Vk { namespace Test { namespace { diff --git a/src/Magnum/Vk/Test/CommandPoolVkTest.cpp b/src/Magnum/Vk/Test/CommandPoolVkTest.cpp index a4fd4ea99..8cd968b73 100644 --- a/src/Magnum/Vk/Test/CommandPoolVkTest.cpp +++ b/src/Magnum/Vk/Test/CommandPoolVkTest.cpp @@ -24,7 +24,7 @@ */ #include "Magnum/Vk/CommandBuffer.h" -#include "Magnum/Vk/CommandPool.h" +#include "Magnum/Vk/CommandPoolCreateInfo.h" #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Handle.h" #include "Magnum/Vk/Result.h" diff --git a/src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp b/src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp index 5bc3d42e4..e4a04e2ff 100644 --- a/src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp +++ b/src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp @@ -35,7 +35,7 @@ #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Extensions.h" #include "Magnum/Vk/ExtensionProperties.h" -#include "Magnum/Vk/Instance.h" +#include "Magnum/Vk/InstanceCreateInfo.h" #include "Magnum/Vk/LayerProperties.h" #include "Magnum/Vk/Memory.h" #include "Magnum/Vk/Result.h" diff --git a/src/Magnum/Vk/Test/DeviceTest.cpp b/src/Magnum/Vk/Test/DeviceTest.cpp index c17177293..197f39ddc 100644 --- a/src/Magnum/Vk/Test/DeviceTest.cpp +++ b/src/Magnum/Vk/Test/DeviceTest.cpp @@ -26,7 +26,7 @@ #include #include -#include "Magnum/Vk/Device.h" +#include "Magnum/Vk/DeviceCreateInfo.h" namespace Magnum { namespace Vk { namespace Test { namespace { diff --git a/src/Magnum/Vk/Test/DeviceVkTest.cpp b/src/Magnum/Vk/Test/DeviceVkTest.cpp index de2075fd4..1d0ca2bc8 100644 --- a/src/Magnum/Vk/Test/DeviceVkTest.cpp +++ b/src/Magnum/Vk/Test/DeviceVkTest.cpp @@ -30,12 +30,12 @@ #include #include -#include "Magnum/Vk/Device.h" +#include "Magnum/Vk/DeviceCreateInfo.h" #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Extensions.h" #include "Magnum/Vk/ExtensionProperties.h" #include "Magnum/Vk/Handle.h" -#include "Magnum/Vk/Instance.h" +#include "Magnum/Vk/InstanceCreateInfo.h" #include "Magnum/Vk/LayerProperties.h" #include "Magnum/Vk/Queue.h" #include "Magnum/Vk/Result.h" diff --git a/src/Magnum/Vk/Test/ImageTest.cpp b/src/Magnum/Vk/Test/ImageTest.cpp index 9238012b2..da952d5c6 100644 --- a/src/Magnum/Vk/Test/ImageTest.cpp +++ b/src/Magnum/Vk/Test/ImageTest.cpp @@ -28,7 +28,7 @@ #include #include -#include "Magnum/Vk/Image.h" +#include "Magnum/Vk/ImageCreateInfo.h" #include "Magnum/Vk/Integration.h" namespace Magnum { namespace Vk { namespace Test { namespace { diff --git a/src/Magnum/Vk/Test/ImageVkTest.cpp b/src/Magnum/Vk/Test/ImageVkTest.cpp index d5d90a9f4..e68f94285 100644 --- a/src/Magnum/Vk/Test/ImageVkTest.cpp +++ b/src/Magnum/Vk/Test/ImageVkTest.cpp @@ -28,8 +28,8 @@ #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Handle.h" -#include "Magnum/Vk/Image.h" -#include "Magnum/Vk/Memory.h" +#include "Magnum/Vk/ImageCreateInfo.h" +#include "Magnum/Vk/MemoryAllocateInfo.h" #include "Magnum/Vk/Result.h" #include "Magnum/Vk/VulkanTester.h" diff --git a/src/Magnum/Vk/Test/InstanceTest.cpp b/src/Magnum/Vk/Test/InstanceTest.cpp index 5ef40246b..874ff2501 100644 --- a/src/Magnum/Vk/Test/InstanceTest.cpp +++ b/src/Magnum/Vk/Test/InstanceTest.cpp @@ -26,7 +26,7 @@ #include #include -#include "Magnum/Vk/Instance.h" +#include "Magnum/Vk/InstanceCreateInfo.h" namespace Magnum { namespace Vk { namespace Test { namespace { diff --git a/src/Magnum/Vk/Test/InstanceVkTest.cpp b/src/Magnum/Vk/Test/InstanceVkTest.cpp index 4ce261e36..76622c7b6 100644 --- a/src/Magnum/Vk/Test/InstanceVkTest.cpp +++ b/src/Magnum/Vk/Test/InstanceVkTest.cpp @@ -34,7 +34,7 @@ #include "Magnum/Vk/ExtensionProperties.h" #include "Magnum/Vk/Handle.h" #include "Magnum/Vk/LayerProperties.h" -#include "Magnum/Vk/Instance.h" +#include "Magnum/Vk/InstanceCreateInfo.h" #include "Magnum/Vk/Result.h" #include "Magnum/Vk/Version.h" diff --git a/src/Magnum/Vk/Test/MemoryTest.cpp b/src/Magnum/Vk/Test/MemoryTest.cpp index c85c42841..925fbd9ea 100644 --- a/src/Magnum/Vk/Test/MemoryTest.cpp +++ b/src/Magnum/Vk/Test/MemoryTest.cpp @@ -29,7 +29,7 @@ #include #include "Magnum/Vk/Device.h" -#include "Magnum/Vk/Memory.h" +#include "Magnum/Vk/MemoryAllocateInfo.h" namespace Magnum { namespace Vk { namespace Test { namespace { diff --git a/src/Magnum/Vk/Test/MemoryVkTest.cpp b/src/Magnum/Vk/Test/MemoryVkTest.cpp index ff820390b..df115ecf1 100644 --- a/src/Magnum/Vk/Test/MemoryVkTest.cpp +++ b/src/Magnum/Vk/Test/MemoryVkTest.cpp @@ -27,7 +27,7 @@ #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Handle.h" -#include "Magnum/Vk/Memory.h" +#include "Magnum/Vk/MemoryAllocateInfo.h" #include "Magnum/Vk/Result.h" #include "Magnum/Vk/VulkanTester.h" diff --git a/src/Magnum/Vk/Test/RenderPassTest.cpp b/src/Magnum/Vk/Test/RenderPassTest.cpp index 1f9518ef7..eda69fea2 100644 --- a/src/Magnum/Vk/Test/RenderPassTest.cpp +++ b/src/Magnum/Vk/Test/RenderPassTest.cpp @@ -31,7 +31,7 @@ #include #include "Magnum/Vk/Image.h" -#include "Magnum/Vk/RenderPass.h" +#include "Magnum/Vk/RenderPassCreateInfo.h" namespace Magnum { namespace Vk { namespace Test { namespace { diff --git a/src/Magnum/Vk/Test/RenderPassVkTest.cpp b/src/Magnum/Vk/Test/RenderPassVkTest.cpp index 03dc99648..568405c59 100644 --- a/src/Magnum/Vk/Test/RenderPassVkTest.cpp +++ b/src/Magnum/Vk/Test/RenderPassVkTest.cpp @@ -28,7 +28,7 @@ #include #include "Magnum/Vk/Handle.h" -#include "Magnum/Vk/RenderPass.h" +#include "Magnum/Vk/RenderPassCreateInfo.h" #include "Magnum/Vk/Result.h" #include "Magnum/Vk/VulkanTester.h" diff --git a/src/Magnum/Vk/Test/ShaderTest.cpp b/src/Magnum/Vk/Test/ShaderTest.cpp index aab20d9e4..7fed28435 100644 --- a/src/Magnum/Vk/Test/ShaderTest.cpp +++ b/src/Magnum/Vk/Test/ShaderTest.cpp @@ -26,7 +26,7 @@ #include #include -#include "Magnum/Vk/Shader.h" +#include "Magnum/Vk/ShaderCreateInfo.h" namespace Magnum { namespace Vk { namespace Test { namespace { diff --git a/src/Magnum/Vk/Test/ShaderVkTest.cpp b/src/Magnum/Vk/Test/ShaderVkTest.cpp index a44ca5d6c..abc591bff 100644 --- a/src/Magnum/Vk/Test/ShaderVkTest.cpp +++ b/src/Magnum/Vk/Test/ShaderVkTest.cpp @@ -28,7 +28,7 @@ #include #include -#include "Magnum/Vk/Shader.h" +#include "Magnum/Vk/ShaderCreateInfo.h" #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Handle.h" #include "Magnum/Vk/Memory.h" diff --git a/src/Magnum/Vk/Vk.h b/src/Magnum/Vk/Vk.h index 75cca50ff..7af86bb02 100644 --- a/src/Magnum/Vk/Vk.h +++ b/src/Magnum/Vk/Vk.h @@ -37,8 +37,10 @@ namespace Magnum { namespace Vk { #ifndef DOXYGEN_GENERATING_OUTPUT class Buffer; +class BufferCreateInfo; class CommandBuffer; class CommandPool; +class CommandPoolCreateInfo; class Device; class DeviceCreateInfo; class DeviceProperties; @@ -47,14 +49,17 @@ class Extension; class ExtensionProperties; enum class HandleFlag: UnsignedByte; typedef Containers::EnumSet HandleFlags; -enum class ImageLayout: Int; class Image; +enum class ImageLayout: Int; +class ImageCreateInfo; +/* Not forward-declaring ImageCreateInfo1D etc right now, I see no need */ class Instance; class InstanceCreateInfo; class InstanceExtension; class InstanceExtensionProperties; class LayerProperties; class Memory; +class MemoryAllocateInfo; class MemoryMapDeleter; class MemoryRequirements; enum class MemoryFlag: UnsignedInt; @@ -65,7 +70,10 @@ class Queue; enum class QueueFlag: UnsignedInt; typedef Containers::EnumSet QueueFlags; class RenderPass; +class RenderPassCreateInfo; enum class Result: Int; +class Shader; +class ShaderCreateInfo; enum class Version: UnsignedInt; #endif diff --git a/src/Magnum/Vk/VulkanTester.cpp b/src/Magnum/Vk/VulkanTester.cpp index dc28df383..1e9c9ef6f 100644 --- a/src/Magnum/Vk/VulkanTester.cpp +++ b/src/Magnum/Vk/VulkanTester.cpp @@ -28,7 +28,9 @@ #include /* sigh, for setSkippedArgumentPrefixes() */ #include +#include "Magnum/Vk/DeviceCreateInfo.h" #include "Magnum/Vk/DeviceProperties.h" +#include "Magnum/Vk/InstanceCreateInfo.h" namespace Magnum { namespace Vk { diff --git a/src/Magnum/Vk/vk-info.cpp b/src/Magnum/Vk/vk-info.cpp index ff6f71f34..92d44509d 100644 --- a/src/Magnum/Vk/vk-info.cpp +++ b/src/Magnum/Vk/vk-info.cpp @@ -27,7 +27,7 @@ #include "Magnum/Vk/Extensions.h" #include "Magnum/Vk/ExtensionProperties.h" -#include "Magnum/Vk/Instance.h" +#include "Magnum/Vk/InstanceCreateInfo.h" #include "Magnum/Vk/LayerProperties.h" #include "Magnum/Vk/Memory.h" #include "Magnum/Vk/DeviceProperties.h"