Browse Source

Vk: add a DescriptorPool wrapper.

pull/504/head
Vladimír Vondruš 5 years ago
parent
commit
c045d1666c
  1. 16
      doc/snippets/MagnumVk.cpp
  2. 10
      doc/vulkan-mapping.dox
  3. 3
      src/Magnum/Vk/CMakeLists.txt
  4. 131
      src/Magnum/Vk/DescriptorPool.cpp
  5. 144
      src/Magnum/Vk/DescriptorPool.h
  6. 183
      src/Magnum/Vk/DescriptorPoolCreateInfo.h
  7. 2
      src/Magnum/Vk/DescriptorSetLayout.h
  8. 13
      src/Magnum/Vk/DescriptorSetLayoutCreateInfo.h
  9. 2
      src/Magnum/Vk/DescriptorType.h
  10. 4
      src/Magnum/Vk/Test/CMakeLists.txt
  11. 183
      src/Magnum/Vk/Test/DescriptorPoolTest.cpp
  12. 103
      src/Magnum/Vk/Test/DescriptorPoolVkTest.cpp
  13. 2
      src/Magnum/Vk/Vk.h

16
doc/snippets/MagnumVk.cpp

@ -39,6 +39,7 @@
#include "Magnum/Vk/CommandBuffer.h" #include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/CommandPoolCreateInfo.h" #include "Magnum/Vk/CommandPoolCreateInfo.h"
#include "Magnum/Vk/ComputePipelineCreateInfo.h" #include "Magnum/Vk/ComputePipelineCreateInfo.h"
#include "Magnum/Vk/DescriptorPoolCreateInfo.h"
#include "Magnum/Vk/DescriptorSetLayoutCreateInfo.h" #include "Magnum/Vk/DescriptorSetLayoutCreateInfo.h"
#include "Magnum/Vk/DescriptorType.h" #include "Magnum/Vk/DescriptorType.h"
#include "Magnum/Vk/DeviceCreateInfo.h" #include "Magnum/Vk/DeviceCreateInfo.h"
@ -314,6 +315,21 @@ fence.wait();
/* [CommandBuffer-usage-submit] */ /* [CommandBuffer-usage-submit] */
} }
{
Vk::Device device{NoCreate};
/* The include should be a no-op here since it was already included above */
/* [DescriptorPool-creation] */
#include <Magnum/Vk/DescriptorPoolCreateInfo.h>
DOXYGEN_IGNORE()
Vk::DescriptorPool pool{device, Vk::DescriptorPoolCreateInfo{8, {
{Vk::DescriptorType::UniformBuffer, 24},
{Vk::DescriptorType::CombinedImageSampler, 16}
}}};
/* [DescriptorPool-creation] */
}
{ {
Vk::Device device{NoCreate}; Vk::Device device{NoCreate};
/* The include should be a no-op here since it was already included above */ /* The include should be a no-op here since it was already included above */

10
doc/vulkan-mapping.dox

@ -58,7 +58,7 @@ Vulkan handle | Matching API
@type_vk{DeferredOperationKHR} @m_class{m-label m-flat m-warning} **KHR** | | @type_vk{DeferredOperationKHR} @m_class{m-label m-flat m-warning} **KHR** | |
@type_vk{DebugReportCallbackEXT} @m_class{m-label m-danger} **deprecated** @m_class{m-label m-flat m-warning} **EXT** | | @type_vk{DebugReportCallbackEXT} @m_class{m-label m-danger} **deprecated** @m_class{m-label m-flat m-warning} **EXT** | |
@type_vk{DebugUtilsMessengerEXT} @m_class{m-label m-flat m-warning} **EXT** | | @type_vk{DebugUtilsMessengerEXT} @m_class{m-label m-flat m-warning} **EXT** | |
@type_vk{DescriptorPool} | | @type_vk{DescriptorPool} | @ref DescriptorPool
@type_vk{DescriptorSet} | | @type_vk{DescriptorSet} | |
@type_vk{DescriptorSetLayout} | @ref DescriptorSetLayout @type_vk{DescriptorSetLayout} | @ref DescriptorSetLayout
@type_vk{DescriptorUpdateTemplate} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @type_vk{DescriptorUpdateTemplate} @m_class{m-label m-flat m-success} **KHR, 1.1** | |
@ -190,7 +190,7 @@ Vulkan function | Matching API
@fn_vk{CreateDebugReportCallbackEXT} @m_class{m-label m-danger} **deprecated** @m_class{m-label m-flat m-warning} **EXT**, \n @fn_vk{DestroyDebugReportCallbackEXT} @m_class{m-label m-danger} **deprecated** @m_class{m-label m-flat m-warning} **EXT** | | @fn_vk{CreateDebugReportCallbackEXT} @m_class{m-label m-danger} **deprecated** @m_class{m-label m-flat m-warning} **EXT**, \n @fn_vk{DestroyDebugReportCallbackEXT} @m_class{m-label m-danger} **deprecated** @m_class{m-label m-flat m-warning} **EXT** | |
@fn_vk{CreateDebugUtilsMessengerEXT} @m_class{m-label m-flat m-warning} **EXT**, \n @fn_vk{DestroyDebugUtilsMessengerEXT} @m_class{m-label m-flat m-warning} **EXT** | | @fn_vk{CreateDebugUtilsMessengerEXT} @m_class{m-label m-flat m-warning} **EXT**, \n @fn_vk{DestroyDebugUtilsMessengerEXT} @m_class{m-label m-flat m-warning} **EXT** | |
@fn_vk{CreateDeferredOperationKHR} @m_class{m-label m-flat m-warning} **KHR**, \n @fn_vk{DestroyDeferredOperationKHR} @m_class{m-label m-flat m-warning} **KHR** | | @fn_vk{CreateDeferredOperationKHR} @m_class{m-label m-flat m-warning} **KHR**, \n @fn_vk{DestroyDeferredOperationKHR} @m_class{m-label m-flat m-warning} **KHR** | |
@fn_vk{CreateDescriptorPool}, \n @fn_vk{DestroyDescriptorPool} | | @fn_vk{CreateDescriptorPool}, \n @fn_vk{DestroyDescriptorPool} | @ref DescriptorPool constructor and destructor
@fn_vk{CreateDescriptorSetLayout}, \n @fn_vk{DestroyDescriptorSetLayout} | @ref DescriptorSetLayout constructor and destructor @fn_vk{CreateDescriptorSetLayout}, \n @fn_vk{DestroyDescriptorSetLayout} | @ref DescriptorSetLayout constructor and destructor
@fn_vk{CreateDescriptorUpdateTemplate} @m_class{m-label m-flat m-success} **KHR, 1.1**, \n @fn_vk{DestroyDescriptorUpdateTemplate} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @fn_vk{CreateDescriptorUpdateTemplate} @m_class{m-label m-flat m-success} **KHR, 1.1**, \n @fn_vk{DestroyDescriptorUpdateTemplate} @m_class{m-label m-flat m-success} **KHR, 1.1** | |
@fn_vk{CreateDevice}, \n @fn_vk{DestroyDevice} | @ref Device constructor and destructor @fn_vk{CreateDevice}, \n @fn_vk{DestroyDevice} | @ref Device constructor and destructor
@ -463,8 +463,8 @@ Vulkan structure | Matching API
@type_vk{DebugUtilsObjectTagInfoEXT} @m_class{m-label m-flat m-warning} **EXT** | | @type_vk{DebugUtilsObjectTagInfoEXT} @m_class{m-label m-flat m-warning} **EXT** | |
@type_vk{DescriptorBufferInfo} | | @type_vk{DescriptorBufferInfo} | |
@type_vk{DescriptorImageInfo} | | @type_vk{DescriptorImageInfo} | |
@type_vk{DescriptorPoolCreateInfo} | | @type_vk{DescriptorPoolCreateInfo} | @ref DescriptorPoolCreateInfo
@type_vk{DescriptorPoolSize} | | @type_vk{DescriptorPoolSize} | @ref DescriptorPoolCreateInfo
@type_vk{DescriptorSetAllocateInfo} | | @type_vk{DescriptorSetAllocateInfo} | |
@type_vk{DescriptorSetLayoutBinding} | @ref DescriptorSetLayoutBinding @type_vk{DescriptorSetLayoutBinding} | @ref DescriptorSetLayoutBinding
@type_vk{DescriptorSetLayoutBindingFlagsCreateInfo} @m_class{m-label m-flqat m-success} **EXT, 1.2** | @ref DescriptorSetLayoutCreateInfo @type_vk{DescriptorSetLayoutBindingFlagsCreateInfo} @m_class{m-label m-flqat m-success} **EXT, 1.2** | @ref DescriptorSetLayoutCreateInfo
@ -826,7 +826,7 @@ Vulkan enum | Matching API
@type_vk{DebugUtilsMessageSeverityFlagBitsEXT} @m_class{m-label m-flat m-warning} **EXT**, \n @type_vk{DebugUtilsMessageTypeFlagsEXT} @m_class{m-label m-flat m-warning} **EXT** | | @type_vk{DebugUtilsMessageSeverityFlagBitsEXT} @m_class{m-label m-flat m-warning} **EXT**, \n @type_vk{DebugUtilsMessageTypeFlagsEXT} @m_class{m-label m-flat m-warning} **EXT** | |
@type_vk{DependencyFlagBits}, \n @type_vk{DependencyFlags} | @ref DependencyFlag, \n @ref DependencyFlags @type_vk{DependencyFlagBits}, \n @type_vk{DependencyFlags} | @ref DependencyFlag, \n @ref DependencyFlags
@type_vk{DescriptorBindingFlagBits} @m_class{m-label m-flat m-success} **EXT, 1.2**, \n @type_vk{DescriptorBindingFlags} @m_class{m-label m-flat m-success} **EXT, 1.2** | @ref DescriptorSetLayoutBinding::Flag, \n @ref DescriptorSetLayoutBinding::Flags @type_vk{DescriptorBindingFlagBits} @m_class{m-label m-flat m-success} **EXT, 1.2**, \n @type_vk{DescriptorBindingFlags} @m_class{m-label m-flat m-success} **EXT, 1.2** | @ref DescriptorSetLayoutBinding::Flag, \n @ref DescriptorSetLayoutBinding::Flags
@type_vk{DescriptorPoolCreateFlagBits}, \n @type_vk{DescriptorPoolCreateFlags} | | @type_vk{DescriptorPoolCreateFlagBits}, \n @type_vk{DescriptorPoolCreateFlags} | @ref DescriptorPoolCreateInfo::Flag, \n @ref DescriptorPoolCreateInfo::Flags
@type_vk{DescriptorSetLayoutCreateFlagBits}, \n @type_vk{DescriptorSetLayoutCreateFlags} | @ref DescriptorSetLayoutCreateInfo::Flag, \n @ref DescriptorSetLayoutCreateInfo::Flags @type_vk{DescriptorSetLayoutCreateFlagBits}, \n @type_vk{DescriptorSetLayoutCreateFlags} | @ref DescriptorSetLayoutCreateInfo::Flag, \n @ref DescriptorSetLayoutCreateInfo::Flags
@type_vk{DescriptorUpdateTemplateType} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @type_vk{DescriptorUpdateTemplateType} @m_class{m-label m-flat m-success} **KHR, 1.1** | |
@type_vk{DescriptorType} | @ref DescriptorType @type_vk{DescriptorType} | @ref DescriptorType

3
src/Magnum/Vk/CMakeLists.txt

@ -48,6 +48,7 @@ set(MagnumVk_SRCS
set(MagnumVk_GracefulAssert_SRCS set(MagnumVk_GracefulAssert_SRCS
Buffer.cpp Buffer.cpp
DescriptorPool.cpp
Device.cpp Device.cpp
DeviceProperties.cpp DeviceProperties.cpp
DeviceFeatures.cpp DeviceFeatures.cpp
@ -74,6 +75,8 @@ set(MagnumVk_HEADERS
CommandPool.h CommandPool.h
CommandPoolCreateInfo.h CommandPoolCreateInfo.h
ComputePipelineCreateInfo.h ComputePipelineCreateInfo.h
DescriptorPool.h
DescriptorPoolCreateInfo.h
DescriptorSetLayout.h DescriptorSetLayout.h
DescriptorSetLayoutCreateInfo.h DescriptorSetLayoutCreateInfo.h
DescriptorType.h DescriptorType.h

131
src/Magnum/Vk/DescriptorPool.cpp

@ -0,0 +1,131 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
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.
*/
#include "DescriptorPool.h"
#include "DescriptorPoolCreateInfo.h"
#include <Corrade/Containers/ArrayView.h>
#include "Magnum/Vk/Assert.h"
#include "Magnum/Vk/DescriptorType.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/Result.h"
namespace Magnum { namespace Vk {
DescriptorPoolCreateInfo::DescriptorPoolCreateInfo(const UnsignedInt maxSets, const Containers::ArrayView<const std::pair<DescriptorType, UnsignedInt>> poolSizes, const Flags flags): _info{} {
CORRADE_ASSERT(maxSets,
"Vk::DescriptorPoolCreateInfo: there has to be at least one set", );
CORRADE_ASSERT(poolSizes,
"Vk::DescriptorPoolCreateInfo: there has to be at least one pool", );
Containers::ArrayView<VkDescriptorPoolSize> poolSizesCopy;
_data = Containers::ArrayTuple{
{Containers::NoInit, poolSizes.size(), poolSizesCopy}
};
for(std::size_t i = 0; i != poolSizes.size(); ++i) {
CORRADE_ASSERT(poolSizes[i].second,
"Vk::DescriptorPoolCreateInfo: pool" << i << "of" << poolSizes[i].first << "has no descriptors", );
poolSizesCopy[i].type = VkDescriptorType(poolSizes[i].first);
poolSizesCopy[i].descriptorCount = poolSizes[i].second;
}
_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
_info.flags = VkDescriptorPoolCreateFlags(flags);
_info.maxSets = maxSets;
_info.poolSizeCount = poolSizesCopy.size();
_info.pPoolSizes = poolSizesCopy;
}
DescriptorPoolCreateInfo::DescriptorPoolCreateInfo(const UnsignedInt maxSets, const std::initializer_list<std::pair<DescriptorType, UnsignedInt>> poolSizes, const Flags flags): DescriptorPoolCreateInfo{maxSets, Containers::arrayView(poolSizes), flags} {}
DescriptorPoolCreateInfo::DescriptorPoolCreateInfo(NoInitT) noexcept {}
DescriptorPoolCreateInfo::DescriptorPoolCreateInfo(const VkDescriptorPoolCreateInfo& info):
/* Can't use {} with GCC 4.8 here because it tries to initialize the first
member instead of doing a copy */
_info(info) {}
DescriptorPoolCreateInfo::DescriptorPoolCreateInfo(DescriptorPoolCreateInfo&& other) noexcept:
/* Can't use {} with GCC 4.8 here because it tries to initialize the first
member instead of doing a copy */
_info(other._info),
_data{std::move(other._data)}
{
/* Ensure the previous instance doesn't reference state that's now ours */
/** @todo this is now more like a destructible move, do it more selectively
and clear only what's really ours and not external? */
other._info.pNext = nullptr;
other._info.poolSizeCount = 0;
other._info.pPoolSizes = nullptr;
}
DescriptorPoolCreateInfo::~DescriptorPoolCreateInfo() = default;
DescriptorPoolCreateInfo& DescriptorPoolCreateInfo::operator=(DescriptorPoolCreateInfo&& other) noexcept {
using std::swap;
swap(other._info, _info);
swap(other._data, _data);
return *this;
}
DescriptorPool DescriptorPool::wrap(Device& device, const VkDescriptorPool handle, const HandleFlags flags) {
DescriptorPool out{NoCreate};
out._device = &device;
out._handle = handle;
out._flags = flags;
return out;
}
DescriptorPool::DescriptorPool(Device& device, const DescriptorPoolCreateInfo& info): _device{&device}, _flags{HandleFlag::DestroyOnDestruction} {
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreateDescriptorPool(device, info, nullptr, &_handle));
}
DescriptorPool::DescriptorPool(NoCreateT): _device{}, _handle{} {}
DescriptorPool::DescriptorPool(DescriptorPool&& other) noexcept: _device{other._device}, _handle{other._handle}, _flags{other._flags} {
other._handle = {};
}
DescriptorPool::~DescriptorPool() {
if(_handle && (_flags & HandleFlag::DestroyOnDestruction))
(**_device).DestroyDescriptorPool(*_device, _handle, nullptr);
}
DescriptorPool& DescriptorPool::operator=(DescriptorPool&& other) noexcept {
using std::swap;
swap(other._device, _device);
swap(other._handle, _handle);
swap(other._flags, _flags);
return *this;
}
VkDescriptorPool DescriptorPool::release() {
const VkDescriptorPool handle = _handle;
_handle = {};
return handle;
}
}}

144
src/Magnum/Vk/DescriptorPool.h

@ -0,0 +1,144 @@
#ifndef Magnum_Vk_DescriptorPool_h
#define Magnum_Vk_DescriptorPool_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
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::DescriptorPool
* @m_since_latest
*/
#include "Magnum/Tags.h"
#include "Magnum/Vk/Handle.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Vk.h"
#include "Magnum/Vk/Vulkan.h"
namespace Magnum { namespace Vk {
/**
@brief Descriptor pool
@m_since_latest
Wraps @type_vk_keyword{DescriptorPool}, which is used for allocating descriptor
sets.
@section Vk-DescriptorPool-creation Descriptor pool creation
The @ref DescriptorPoolCreateInfo class takes a maximum number of descriptor
sets that can be allocated from a pool and then a list of total available
descriptor counts for desired @ref DescriptorType "DescriptorTypes". The
following snippet creates a pool allowing to allocate at most 8 descriptor sets
with 24 sampler bindings and 16 uniform bindings:
@snippet MagnumVk.cpp DescriptorPool-creation
*/
class MAGNUM_VK_EXPORT DescriptorPool {
public:
/**
* @brief Wrap existing Vulkan handle
* @param device Vulkan device the descriptor pool is
* created on
* @param handle The @type_vk{DescriptorPool} handle
* @param flags Handle flags
*
* The @p handle is expected to be originating from @p device. Unlike
* a descriptor pool created using a constructor, the Vulkan descriptor
* pool is by default not deleted on destruction, use @p flags for
* different behavior.
* @see @ref release()
*/
static DescriptorPool wrap(Device& device, VkDescriptorPool handle, HandleFlags flags = {});
/**
* @brief Constructor
* @param device Vulkan device to create the descriptor pool on
* @param info Descriptor pool creation info
*
* @see @fn_vk_keyword{CreateDescriptorPool}
*/
explicit DescriptorPool(Device& device, const DescriptorPoolCreateInfo& info);
/**
* @brief Construct without creating the fence
*
* The constructed instance is equivalent to moved-from state. Useful
* in cases where you will overwrite the instance later anyway. Move
* another object over it to make it useful.
*/
explicit DescriptorPool(NoCreateT);
/** @brief Copying is not allowed */
DescriptorPool(const DescriptorPool&) = delete;
/** @brief Move constructor */
DescriptorPool(DescriptorPool&& other) noexcept;
/**
* @brief Destructor
*
* Destroys associated @type_vk{DescriptorPool} handle, unless the
* instance was created using @ref wrap() without
* @ref HandleFlag::DestroyOnDestruction specified.
* @see @fn_vk_keyword{DestroyDescriptorPool}, @ref release()
*/
~DescriptorPool();
/** @brief Copying is not allowed */
DescriptorPool& operator=(const DescriptorPool&) = delete;
/** @brief Move assignment */
DescriptorPool& operator=(DescriptorPool&& other) noexcept;
/** @brief Underlying @type_vk{DescriptorPool} handle */
VkDescriptorPool handle() { return _handle; }
/** @overload */
operator VkDescriptorPool() { return _handle; }
/** @brief Handle flags */
HandleFlags handleFlags() const { return _flags; }
/**
* @brief Release the underlying Vulkan descriptor pool
*
* Releases ownership of the Vulkan descriptor pool and returns its
* handle so @fn_vk{DestroyDescriptorPool} is not called on
* destruction. The internal state is then equivalent to moved-from
* state.
* @see @ref wrap()
*/
VkDescriptorPool release();
private:
/* Can't be a reference because of the NoCreate constructor */
Device* _device;
VkDescriptorPool _handle;
HandleFlags _flags;
};
}}
#endif

183
src/Magnum/Vk/DescriptorPoolCreateInfo.h

@ -0,0 +1,183 @@
#ifndef Magnum_Vk_DescriptorPoolCreateInfo_h
#define Magnum_Vk_DescriptorPoolCreateInfo_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
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::DescriptorPoolCreateInfo
* @m_since_latest
*/
#include <utility>
#include <Corrade/Containers/ArrayTuple.h>
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Magnum.h"
#include "Magnum/Tags.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Vk.h"
#include "Magnum/Vk/Vulkan.h"
namespace Magnum { namespace Vk {
/**
@brief Descriptor pool creation info
@m_since_latest
Wraps a @type_vk_keyword{DescriptorPoolCreateInfo} and the nested
@type_vk_keyword{DescriptorPoolSize} structures. See
@ref Vk-DescriptorPool-creation "Descriptor pool creation" for usage
information.
*/
class MAGNUM_VK_EXPORT DescriptorPoolCreateInfo {
public:
/**
* @brief Descriptor pool creation flag
*
* Wraps @type_vk_keyword{DescriptorPoolCreateFlagBits}.
* @see @ref Flags, @ref DescriptorPoolCreateInfo()
* @m_enum_values_as_keywords
*/
enum class Flag: UnsignedInt {
/**
* Allow individual descriptor sets to be freed instead of just the
* whole pool.
* @todoc reference relevant functions once they exist
*
* @m_class{m-note m-success}
*
* @par
* Not using this flag may help the driver to use simpler
* per-pool allocators instead of per-set. Without this flag
* set, descriptor pool fragmentation can't occur.
*/
FreeDescriptorSet = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
/**
* Descriptor sets allocated from this pool can use bindings with
* the @ref DescriptorSetLayoutBinding::Flag::UpdateAfterBind set.
* @requires_vk_feature @ref DeviceFeature::DescriptorBindingSampledImageUpdateAfterBind
* if used on a @ref DescriptorType::CombinedImageSampler /
* @relativeref{DescriptorType,SampledImage}
* @requires_vk_feature @ref DeviceFeature::DescriptorBindingStorageImageUpdateAfterBind
* if used on a @ref DescriptorType::StorageImage
* @requires_vk_feature @ref DeviceFeature::DescriptorBindingUniformTexelBufferUpdateAfterBind
* if used on a @ref DescriptorType::UniformTexelBuffer
* @requires_vk_feature @ref DeviceFeature::DescriptorBindingStorageTexelBufferUpdateAfterBind
* if used on a @ref DescriptorType::StorageTexelBuffer
* @requires_vk_feature @ref DeviceFeature::DescriptorBindingUniformBufferUpdateAfterBind
* if used on a @ref DescriptorType::UniformBuffer /
* @relativeref{DescriptorType,UniformBufferDynamic}
* @requires_vk_feature @ref DeviceFeature::DescriptorBindingStorageBufferUpdateAfterBind
* if used on a @ref DescriptorType::StorageBuffer /
* @relativeref{DescriptorType,StorageBufferDynamic}
*/
UpdateAfterBind = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT
};
/**
* @brief DescriptorPool creation flags
*
* Type-safe wrapper for @type_vk_keyword{DescriptorPoolCreateFlags}.
* @see @ref DescriptorPoolCreateInfo()
*/
typedef Containers::EnumSet<Flag> Flags;
/**
* @brief Constructor
* @param maxSets Maximum count of descriptor sets that can be
* allocated from this pool. Has to be at least one.
* @param poolSizes Pool sizes for each descriptor type. There has
* to be at least one, and pool sizes can't be zero.
* @param flags DescriptorPool creation flags
*
* The following @type_vk{DescriptorPoolCreateInfo} fields are
* pre-filled in addition to `sType`, everything else is zero-filled:
*
* - `flags`
* - `maxSets`
* - `poolSizeCount` and `pPoolSizes` to @p poolSizes converted to
* a list of @type_vk{DescriptorPoolSize} structures
*/
explicit DescriptorPoolCreateInfo(UnsignedInt maxSets, Containers::ArrayView<const std::pair<DescriptorType, UnsignedInt>> poolSizes, Flags flags = {});
/** @overload */
explicit DescriptorPoolCreateInfo(UnsignedInt maxSets, std::initializer_list<std::pair<DescriptorType, UnsignedInt>> poolSizes, 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 DescriptorPoolCreateInfo(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 DescriptorPoolCreateInfo(const VkDescriptorPoolCreateInfo& info);
/** @brief Copying is not allowed */
DescriptorPoolCreateInfo(const DescriptorPoolCreateInfo&) = delete;
/** @brief Move constructor */
DescriptorPoolCreateInfo(DescriptorPoolCreateInfo&& other) noexcept;
~DescriptorPoolCreateInfo();
/** @brief Copying is not allowed */
DescriptorPoolCreateInfo& operator=(const DescriptorPoolCreateInfo&) = delete;
/** @brief Move assignment */
DescriptorPoolCreateInfo& operator=(DescriptorPoolCreateInfo&& other) noexcept;
/** @brief Underlying @type_vk{DescriptorPoolCreateInfo} structure */
VkDescriptorPoolCreateInfo& operator*() { return _info; }
/** @overload */
const VkDescriptorPoolCreateInfo& operator*() const { return _info; }
/** @overload */
VkDescriptorPoolCreateInfo* operator->() { return &_info; }
/** @overload */
const VkDescriptorPoolCreateInfo* operator->() const { return &_info; }
/** @overload */
operator const VkDescriptorPoolCreateInfo*() const { return &_info; }
private:
VkDescriptorPoolCreateInfo _info;
Containers::ArrayTuple _data;
};
CORRADE_ENUMSET_OPERATORS(DescriptorPoolCreateInfo::Flags)
}}
/* Make the definition complete -- it doesn't make sense to have a CreateInfo
without the corresponding object anyway. */
#include "Magnum/Vk/DescriptorPool.h"
#endif

2
src/Magnum/Vk/DescriptorSetLayout.h

@ -89,7 +89,7 @@ specify additional flags per binding. All of them require a certain
@section Vk-DescriptorSetLayout-usage Descriptor set layout usage @section Vk-DescriptorSetLayout-usage Descriptor set layout usage
A descriptor set layout is used in a @ref PipelineLayout creation and A descriptor set layout is used in a @ref PipelineLayout creation and
subsequently for descriptor set allocation from a descriptor pool. See the subsequently for descriptor set allocation from a @ref DescriptorPool. See the
corresponding class documentation for more information. corresponding class documentation for more information.
*/ */
class MAGNUM_VK_EXPORT DescriptorSetLayout { class MAGNUM_VK_EXPORT DescriptorSetLayout {

13
src/Magnum/Vk/DescriptorSetLayoutCreateInfo.h

@ -74,6 +74,11 @@ class MAGNUM_VK_EXPORT DescriptorSetLayoutBinding {
* submission will use the most recently set descriptors for * submission will use the most recently set descriptors for
* the binding and the updates do not invalidate the command * the binding and the updates do not invalidate the command
* buffer. * buffer.
*
* Descriptor set layouts using this flag can be only allocated
* from a @ref DescriptorPool that has
* @ref DescriptorPoolCreateInfo::Flag::UpdateAfterBind set as
* well.
* @requires_vk_feature @ref DeviceFeature::DescriptorBindingSampledImageUpdateAfterBind * @requires_vk_feature @ref DeviceFeature::DescriptorBindingSampledImageUpdateAfterBind
* if used on a @ref DescriptorType::CombinedImageSampler / * if used on a @ref DescriptorType::CombinedImageSampler /
* @relativeref{DescriptorType,SampledImage} * @relativeref{DescriptorType,SampledImage}
@ -114,6 +119,10 @@ class MAGNUM_VK_EXPORT DescriptorSetLayoutBinding {
* This descriptor binding has a variable size that will be * This descriptor binding has a variable size that will be
* specified when a descriptor set is allocated using this layout, * specified when a descriptor set is allocated using this layout,
* and the @p descriptorCount value is treated as an upper bound. * and the @p descriptorCount value is treated as an upper bound.
*
* Allowed only on the last binding number in the layout, not
* allowed on a @ref DescriptorType::UniformBufferDynamic or
* @ref DescriptorType::StorageBufferDynamic.
* @requires_vk_feature @ref DeviceFeature::DescriptorBindingVariableDescriptorCount * @requires_vk_feature @ref DeviceFeature::DescriptorBindingVariableDescriptorCount
*/ */
VariableDescriptorCount = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT VariableDescriptorCount = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
@ -135,7 +144,9 @@ class MAGNUM_VK_EXPORT DescriptorSetLayoutBinding {
* @param descriptorType Descriptor type * @param descriptorType Descriptor type
* @param descriptorCount Number of descriptors contained in the * @param descriptorCount Number of descriptors contained in the
* binding. If the shader binding is not an array, use @cpp 1 @ce, * binding. If the shader binding is not an array, use @cpp 1 @ce,
* zero is allowed as well. * zero is allowed as well. For a @ref Flag::VariableDescriptorCount
* this is used as an upper bound and a concrete size is specified
* during descriptor set allocation.
* @param stages Shader stages that access the binding. * @param stages Shader stages that access the binding.
* Use @cpp ~Vk::ShaderStages{} @ce to specify that all stages * Use @cpp ~Vk::ShaderStages{} @ce to specify that all stages
* may access the binding. * may access the binding.

2
src/Magnum/Vk/DescriptorType.h

@ -41,7 +41,7 @@ namespace Magnum { namespace Vk {
@m_since_latest @m_since_latest
Wraps @type_vk_keyword{DescriptorType}. Wraps @type_vk_keyword{DescriptorType}.
@see @ref DescriptorSetLayoutBinding @see @ref DescriptorSetLayoutBinding, @ref DescriptorPoolCreateInfo
@m_enum_values_as_keywords @m_enum_values_as_keywords
*/ */
enum class DescriptorType: Int { enum class DescriptorType: Int {

4
src/Magnum/Vk/Test/CMakeLists.txt

@ -27,6 +27,7 @@
corrade_add_test(VkBufferTest BufferTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkBufferTest BufferTest.cpp LIBRARIES MagnumVkTestLib)
corrade_add_test(VkCommandBufferTest CommandBufferTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkCommandBufferTest CommandBufferTest.cpp LIBRARIES MagnumVk)
corrade_add_test(VkCommandPoolTest CommandPoolTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkCommandPoolTest CommandPoolTest.cpp LIBRARIES MagnumVk)
corrade_add_test(VkDescriptorPoolTest DescriptorPoolTest.cpp LIBRARIES MagnumVkTestLib)
corrade_add_test(VkDescriptorSetLayoutTest DescriptorSetLayoutTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkDescriptorSetLayoutTest DescriptorSetLayoutTest.cpp LIBRARIES MagnumVk)
corrade_add_test(VkDescriptorTypeTest DescriptorTypeTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkDescriptorTypeTest DescriptorTypeTest.cpp LIBRARIES MagnumVk)
corrade_add_test(VkDeviceTest DeviceTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkDeviceTest DeviceTest.cpp LIBRARIES MagnumVk)
@ -131,6 +132,7 @@ set_target_properties(
VkBufferTest VkBufferTest
VkCommandBufferTest VkCommandBufferTest
VkCommandPoolTest VkCommandPoolTest
VkDescriptorPoolTest
VkDescriptorSetLayoutTest VkDescriptorSetLayoutTest
VkDescriptorTypeTest VkDescriptorTypeTest
VkDeviceTest VkDeviceTest
@ -196,6 +198,7 @@ if(BUILD_VK_TESTS)
corrade_add_test(VkBufferVkTest BufferVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester) corrade_add_test(VkBufferVkTest BufferVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester)
corrade_add_test(VkCommandBufferVkTest CommandBufferVkTest.cpp LIBRARIES MagnumVulkanTester) corrade_add_test(VkCommandBufferVkTest CommandBufferVkTest.cpp LIBRARIES MagnumVulkanTester)
corrade_add_test(VkCommandPoolVkTest CommandPoolVkTest.cpp LIBRARIES MagnumVulkanTester) corrade_add_test(VkCommandPoolVkTest CommandPoolVkTest.cpp LIBRARIES MagnumVulkanTester)
corrade_add_test(VkDescriptorPoolVkTest DescriptorPoolVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester)
corrade_add_test(VkDescriptorSetLayoutVkTest DescriptorSetLayoutVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkDescriptorSetLayoutVkTest DescriptorSetLayoutVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester)
corrade_add_test(VkDeviceVkTest DeviceVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester) corrade_add_test(VkDeviceVkTest DeviceVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester)
corrade_add_test(VkDevicePropertiesVkTest DevicePropertiesVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester) corrade_add_test(VkDevicePropertiesVkTest DevicePropertiesVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester)
@ -248,6 +251,7 @@ if(BUILD_VK_TESTS)
VkBufferVkTest VkBufferVkTest
VkCommandBufferVkTest VkCommandBufferVkTest
VkCommandPoolVkTest VkCommandPoolVkTest
VkDescriptorPoolVkTest
VkDescriptorSetLayoutVkTest VkDescriptorSetLayoutVkTest
VkDeviceVkTest VkDeviceVkTest
VkDevicePropertiesVkTest VkDevicePropertiesVkTest

183
src/Magnum/Vk/Test/DescriptorPoolTest.cpp

@ -0,0 +1,183 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
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.
*/
#include <new>
#include <sstream>
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/Vk/DescriptorPoolCreateInfo.h"
#include "Magnum/Vk/DescriptorType.h"
namespace Magnum { namespace Vk { namespace Test { namespace {
struct DescriptorPoolTest: TestSuite::Tester {
explicit DescriptorPoolTest();
void createInfoConstruct();
void createInfoConstructNoSets();
void createInfoConstructNoPools();
void createInfoConstructEmptyPool();
void createInfoConstructNoInit();
void createInfoConstructFromVk();
void createInfoConstructCopy();
void createInfoConstructMove();
void constructNoCreate();
void constructCopy();
};
DescriptorPoolTest::DescriptorPoolTest() {
addTests({&DescriptorPoolTest::createInfoConstruct,
&DescriptorPoolTest::createInfoConstructNoSets,
&DescriptorPoolTest::createInfoConstructNoPools,
&DescriptorPoolTest::createInfoConstructEmptyPool,
&DescriptorPoolTest::createInfoConstructNoInit,
&DescriptorPoolTest::createInfoConstructFromVk,
&DescriptorPoolTest::createInfoConstructCopy,
&DescriptorPoolTest::createInfoConstructMove,
&DescriptorPoolTest::constructNoCreate,
&DescriptorPoolTest::constructCopy});
}
void DescriptorPoolTest::createInfoConstruct() {
DescriptorPoolCreateInfo info{5, {
{DescriptorType::CombinedImageSampler, 7},
{DescriptorType::UniformBuffer, 3}
}, DescriptorPoolCreateInfo::Flag::FreeDescriptorSet|DescriptorPoolCreateInfo::Flag::UpdateAfterBind};
CORRADE_COMPARE(info->flags, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT|VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT);
CORRADE_COMPARE(info->maxSets, 5);
CORRADE_COMPARE(info->poolSizeCount, 2);
CORRADE_VERIFY(info->pPoolSizes);
CORRADE_COMPARE(info->pPoolSizes[0].type, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
CORRADE_COMPARE(info->pPoolSizes[0].descriptorCount, 7);
CORRADE_COMPARE(info->pPoolSizes[1].type, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
CORRADE_COMPARE(info->pPoolSizes[1].descriptorCount, 3);
}
void DescriptorPoolTest::createInfoConstructNoSets() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream out;
Error redirectError{&out};
DescriptorPoolCreateInfo{0, {}};
CORRADE_COMPARE(out.str(), "Vk::DescriptorPoolCreateInfo: there has to be at least one set\n");
}
void DescriptorPoolTest::createInfoConstructNoPools() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream out;
Error redirectError{&out};
DescriptorPoolCreateInfo{5, {}};
CORRADE_COMPARE(out.str(), "Vk::DescriptorPoolCreateInfo: there has to be at least one pool\n");
}
void DescriptorPoolTest::createInfoConstructEmptyPool() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream out;
Error redirectError{&out};
DescriptorPoolCreateInfo{5, {
{DescriptorType::InputAttachment, 2},
{DescriptorType::UniformBuffer, 0},
}};
CORRADE_COMPARE(out.str(), "Vk::DescriptorPoolCreateInfo: pool 1 of Vk::DescriptorType::UniformBuffer has no descriptors\n");
}
void DescriptorPoolTest::createInfoConstructNoInit() {
DescriptorPoolCreateInfo info{NoInit};
info->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
new(&info) DescriptorPoolCreateInfo{NoInit};
CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
CORRADE_VERIFY(std::is_nothrow_constructible<DescriptorPoolCreateInfo, NoInitT>::value);
/* Implicit construction is not allowed */
CORRADE_VERIFY(!std::is_convertible<NoInitT, DescriptorPoolCreateInfo>::value);
}
void DescriptorPoolTest::createInfoConstructFromVk() {
VkDescriptorPoolCreateInfo vkInfo;
vkInfo.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
DescriptorPoolCreateInfo info{vkInfo};
CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
}
void DescriptorPoolTest::createInfoConstructCopy() {
CORRADE_VERIFY(!std::is_copy_constructible<DescriptorPoolCreateInfo>{});
CORRADE_VERIFY(!std::is_copy_assignable<DescriptorPoolCreateInfo>{});
}
void DescriptorPoolTest::createInfoConstructMove() {
DescriptorPoolCreateInfo a{5, {
{DescriptorType::CombinedImageSampler, 7},
{DescriptorType::UniformBuffer, 3}
}};
CORRADE_COMPARE(a->poolSizeCount, 2);
CORRADE_VERIFY(a->pPoolSizes);
DescriptorPoolCreateInfo b = std::move(a);
CORRADE_COMPARE(a->poolSizeCount, 0);
CORRADE_VERIFY(!a->pPoolSizes);
CORRADE_COMPARE(b->poolSizeCount, 2);
CORRADE_VERIFY(b->pPoolSizes);
CORRADE_COMPARE(b->pPoolSizes[1].type, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
DescriptorPoolCreateInfo c{VkDescriptorPoolCreateInfo{}};
c = std::move(b);
CORRADE_COMPARE(b->poolSizeCount, 0);
CORRADE_VERIFY(!b->pPoolSizes);
CORRADE_COMPARE(c->poolSizeCount, 2);
CORRADE_VERIFY(c->pPoolSizes);
CORRADE_COMPARE(c->pPoolSizes[1].type, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
}
void DescriptorPoolTest::constructNoCreate() {
{
DescriptorPool pool{NoCreate};
CORRADE_VERIFY(!pool.handle());
}
/* Implicit construction is not allowed */
CORRADE_VERIFY(!std::is_convertible<NoCreateT, DescriptorPool>::value);
}
void DescriptorPoolTest::constructCopy() {
CORRADE_VERIFY(!std::is_copy_constructible<DescriptorPool>{});
CORRADE_VERIFY(!std::is_copy_assignable<DescriptorPool>{});
}
}}}}
CORRADE_TEST_MAIN(Magnum::Vk::Test::DescriptorPoolTest)

103
src/Magnum/Vk/Test/DescriptorPoolVkTest.cpp

@ -0,0 +1,103 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
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.
*/
#include "Magnum/Vk/DescriptorPoolCreateInfo.h"
#include "Magnum/Vk/DescriptorType.h"
#include "Magnum/Vk/Result.h"
#include "Magnum/Vk/VulkanTester.h"
namespace Magnum { namespace Vk { namespace Test { namespace {
struct DescriptorPoolVkTest: VulkanTester {
explicit DescriptorPoolVkTest();
void construct();
void constructMove();
void wrap();
};
DescriptorPoolVkTest::DescriptorPoolVkTest() {
addTests({&DescriptorPoolVkTest::construct,
&DescriptorPoolVkTest::constructMove,
&DescriptorPoolVkTest::wrap});
}
void DescriptorPoolVkTest::construct() {
{
DescriptorPool pool{device(), DescriptorPoolCreateInfo{5, {
{DescriptorType::UniformBuffer, 2}
}}};
CORRADE_VERIFY(pool.handle());
CORRADE_COMPARE(pool.handleFlags(), HandleFlag::DestroyOnDestruction);
}
/* Shouldn't crash or anything */
CORRADE_VERIFY(true);
}
void DescriptorPoolVkTest::constructMove() {
DescriptorPool a{device(), DescriptorPoolCreateInfo{5, {
{DescriptorType::UniformBuffer, 2}
}}};
VkDescriptorPool handle = a.handle();
DescriptorPool b = std::move(a);
CORRADE_VERIFY(!a.handle());
CORRADE_COMPARE(b.handle(), handle);
CORRADE_COMPARE(b.handleFlags(), HandleFlag::DestroyOnDestruction);
DescriptorPool c{NoCreate};
c = std::move(b);
CORRADE_VERIFY(!b.handle());
CORRADE_COMPARE(b.handleFlags(), HandleFlags{});
CORRADE_COMPARE(c.handle(), handle);
CORRADE_COMPARE(c.handleFlags(), HandleFlag::DestroyOnDestruction);
CORRADE_VERIFY(std::is_nothrow_move_constructible<DescriptorPool>::value);
CORRADE_VERIFY(std::is_nothrow_move_assignable<DescriptorPool>::value);
}
void DescriptorPoolVkTest::wrap() {
VkDescriptorPool pool{};
CORRADE_COMPARE(Result(device()->CreateDescriptorPool(device(),
DescriptorPoolCreateInfo{5, {
{DescriptorType::UniformBuffer, 2}
}},
nullptr, &pool)), Result::Success);
auto wrapped = DescriptorPool::wrap(device(), pool, HandleFlag::DestroyOnDestruction);
CORRADE_COMPARE(wrapped.handle(), pool);
/* Release the handle again, destroy by hand */
CORRADE_COMPARE(wrapped.release(), pool);
CORRADE_VERIFY(!wrapped.handle());
device()->DestroyDescriptorPool(device(), pool, nullptr);
}
}}}}
CORRADE_TEST_MAIN(Magnum::Vk::Test::DescriptorPoolVkTest)

2
src/Magnum/Vk/Vk.h

@ -57,6 +57,8 @@ class CopyImageToBufferInfo;
/* Not forward-declaring CopyBufferToImageInfo1D etc right now, I see no need */ /* Not forward-declaring CopyBufferToImageInfo1D etc right now, I see no need */
enum class DependencyFlag: UnsignedInt; enum class DependencyFlag: UnsignedInt;
typedef Containers::EnumSet<DependencyFlag> DependencyFlags; typedef Containers::EnumSet<DependencyFlag> DependencyFlags;
class DescriptorPool;
class DescriptorPoolCreateInfo;
class DescriptorSetLayout; class DescriptorSetLayout;
class DescriptorSetLayoutCreateInfo; class DescriptorSetLayoutCreateInfo;
enum class DescriptorType: Int; enum class DescriptorType: Int;

Loading…
Cancel
Save