mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
20 KiB
400 lines
20 KiB
#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, 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::DeviceCreateInfo |
|
* @m_since_latest |
|
*/ |
|
|
|
#include <cstddef> |
|
#include <Corrade/Containers/Pointer.h> |
|
|
|
#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. |
|
* |
|
* This flag also affects enabling of |
|
* @vk_extension{KHR,portability_subset},which is *required* to be |
|
* enabled by the spec on any device that advertises it, and |
|
* behavior of related @ref DeviceFeatures. See |
|
* @ref Vk-Device-portability-subset for details. |
|
*/ |
|
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<Flag> 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 global or |
|
* null-terminated, use the @link Containers::Literals::operator""_s() @endlink |
|
* literal to prevent that where possible. |
|
* |
|
* The following @type_vk{DeviceCreateInfo} fields are set by this |
|
* function: |
|
* |
|
* - `enabledExtensionCount` to the count of extensions added |
|
* previously by this function plus @cpp extensions.size() @ce |
|
* - `pEnabledExtensionNames` to an array containing all extension |
|
* strings added previously by this function together with ones |
|
* from @p extensions |
|
*/ |
|
DeviceCreateInfo& addEnabledExtensions(Containers::ArrayView<const Containers::StringView> extensions) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& addEnabledExtensions(Containers::ArrayView<const Containers::StringView> extensions) &&; |
|
/** @overload */ |
|
DeviceCreateInfo& addEnabledExtensions(std::initializer_list<Containers::StringView> extension) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& addEnabledExtensions(std::initializer_list<Containers::StringView> extension) &&; |
|
/** @overload */ |
|
DeviceCreateInfo& addEnabledExtensions(Containers::ArrayView<const Extension> extensions) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& addEnabledExtensions(Containers::ArrayView<const Extension> extensions) &&; |
|
/** @overload */ |
|
DeviceCreateInfo& addEnabledExtensions(std::initializer_list<Extension> extension) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& addEnabledExtensions(std::initializer_list<Extension> extension) &&; |
|
/** @overload */ |
|
template<class ...E> DeviceCreateInfo& addEnabledExtensions() & { |
|
static_assert(Implementation::IsExtension<E...>::value, "expected only Vulkan device extensions"); |
|
return addEnabledExtensions(std::initializer_list<Extension>{E{}...}); |
|
} |
|
/** @overload */ |
|
template<class ...E> DeviceCreateInfo&& addEnabledExtensions() && { |
|
addEnabledExtensions<E...>(); |
|
return std::move(*this); |
|
} |
|
|
|
/** |
|
* @brief Add enabled device features |
|
* @return Reference to self (for method chaining) |
|
* |
|
* All enabled features are expected to be reported as supported by the |
|
* device and either their core version supported by the device or the |
|
* corresponding extension enabled via @ref addEnabledExtensions(). Use |
|
* @ref DeviceProperties::features() to check for feature support. |
|
* |
|
* If Vulkan 1.1 is not supported and |
|
* @vk_extension{KHR,get_physical_device_properties2} is not enabled on |
|
* the instance, the `pEnabledFeatures` field in |
|
* @type_vk{DeviceCreateInfo} is set to the Vulkan 1.0 subset of |
|
* @p features. Otherwise, depending on what features are enabled, a |
|
* subset of the following structures will be added to the `pNext` |
|
* chain: |
|
* |
|
* - @type_vk_keyword{PhysicalDeviceProtectedMemoryFeatures} (Vulkan |
|
* 1.1) |
|
* - @type_vk_keyword{PhysicalDeviceMultiviewFeatures} (Vulkan 1.1, |
|
* @vk_extension{KHR,multiview}) |
|
* - @type_vk_keyword{PhysicalDeviceShaderDrawParametersFeatures} |
|
* (Vulkan 1.1, @vk_extension{KHR,shader_draw_parameters}) |
|
* - @type_vk_keyword{PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT} |
|
* (@vk_extension{EXT,texture_compression_astc_hdr}) |
|
* - @type_vk_keyword{PhysicalDeviceShaderFloat16Int8Features} |
|
* (Vulkan 1.2, @vk_extension{KHR,shader_float16_int8}) |
|
* - @type_vk_keyword{PhysicalDevice16BitStorageFeatures} (Vulkan |
|
* 1.1, @vk_extension{KHR,16bit_storage}) |
|
* - @type_vk_keyword{PhysicalDeviceImagelessFramebufferFeatures} |
|
* (Vulkan 1.2, @vk_extension{KHR,imageless_framebuffer}) |
|
* - @type_vk_keyword{PhysicalDeviceVariablePointersFeatures} |
|
* (Vulkan 1.1, @vk_extension{KHR,variable_pointers}) |
|
* - @type_vk_keyword{PhysicalDeviceAccelerationStructureFeaturesKHR} |
|
* (@vk_extension{KHR,acceleration_structure}) |
|
* - @type_vk_keyword{PhysicalDeviceSamplerYcbcrConversionFeatures} |
|
* (Vulkan 1.1, @vk_extension{KHR,sampler_ycbcr_conversion}) |
|
* - @type_vk_keyword{PhysicalDeviceDescriptorIndexingFeatures} |
|
* (Vulkan 1.2, @vk_extension{EXT,descriptor_indexing}) |
|
* - @type_vk_keyword{PhysicalDevicePortabilitySubsetFeaturesKHR} |
|
* (@vk_extension{KHR,portability_subset}) |
|
* - @type_vk_keyword{PhysicalDeviceShaderSubgroupExtendedTypesFeatures} |
|
* (Vulkan 1.2, @vk_extension{KHR,shader_subgroup_extended_types}) |
|
* - @type_vk_keyword{PhysicalDevice8BitStorageFeatures} (Vulkan |
|
* 1.2, @vk_extension{KHR,8bit_storage}) |
|
* - @type_vk_keyword{PhysicalDeviceShaderAtomicInt64Features} |
|
* (Vulkan 1.2, @vk_extension{KHR,shader_atomic_int64}) |
|
* - @type_vk_keyword{PhysicalDeviceVertexAttributeDivisorFeaturesEXT} |
|
* (@vk_extension{EXT,vertex_attribute_divisor}) |
|
* - @type_vk_keyword{PhysicalDeviceTimelineSemaphoreFeatures} |
|
* (Vulkan 1.2, @vk_extension{KHR,timeline_semaphore}) |
|
* - @type_vk_keyword{PhysicalDeviceVulkanMemoryModelFeatures} |
|
* (Vulkan 1.2, @vk_extension{KHR,vulkan_memory_model}) |
|
* - @type_vk_keyword{PhysicalDeviceScalarBlockLayoutFeatures} |
|
* (Vulkan 1.2, @vk_extension{EXT,scalar_block_layout}) |
|
* - @type_vk_keyword{PhysicalDeviceSeparateDepthStencilLayoutsFeatures} |
|
* (Vulkan 1.2, @vk_extension{KHR,separate_depth_stencil_layouts}) |
|
* - @type_vk_keyword{PhysicalDeviceUniformBufferStandardLayoutFeatures} |
|
* (Vulkan 1.2, @vk_extension{KHR,uniform_buffer_standard_layout}) |
|
* - @type_vk_keyword{PhysicalDeviceBufferDeviceAddressFeatures} |
|
* (Vulkan 1.2, @vk_extension{KHR,buffer_device_address}) |
|
* - @type_vk_keyword{PhysicalDeviceHostQueryResetFeatures} (Vulkan |
|
* 1.2, @vk_extension{EXT,host_query_reset}) |
|
* - @type_vk_keyword{PhysicalDeviceIndexTypeUint8FeaturesEXT} |
|
* (@vk_extension{EXT,index_type_uint8}) |
|
* - @type_vk_keyword{PhysicalDeviceExtendedDynamicStateFeaturesEXT} |
|
* (@vk_extension{EXT,extended_dynamic_state}) |
|
* - @type_vk_keyword{PhysicalDeviceRobustness2FeaturesEXT} |
|
* (@vk_extension{EXT,robustness2}) |
|
* - @type_vk_keyword{PhysicalDeviceImageRobustnessFeaturesEXT} |
|
* (@vk_extension{EXT,image_robustness}) |
|
* - @type_vk_keyword{PhysicalDeviceRayTracingPipelineFeaturesKHR} |
|
* (@vk_extension{KHR,ray_tracing_pipeline}) |
|
* - @type_vk_keyword{PhysicalDeviceRayQueryFeaturesKHR} |
|
* (@vk_extension{KHR,ray_query}) |
|
*/ |
|
DeviceCreateInfo& setEnabledFeatures(const DeviceFeatures& features) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& setEnabledFeatures(const DeviceFeatures& features) &&; |
|
|
|
/** |
|
* @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. |
|
* |
|
* The following @type_vk{DeviceCreateInfo} fields are set by this |
|
* function: |
|
* |
|
* - `queueCreateInfoCount` to the count of queues added previously |
|
* by this function plus @cpp queues.size() @ce |
|
* - `pQueueCreateInfos` to an array containing all queue create |
|
* infos added previously by this function together with ones |
|
* from @p family and @p priorities |
|
* |
|
* @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<const Float> priorities, Containers::ArrayView<const Containers::Reference<Queue>> output) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& addQueues(UnsignedInt family, Containers::ArrayView<const Float> priorities, Containers::ArrayView<const Containers::Reference<Queue>> output) &&; |
|
/** @overload */ |
|
DeviceCreateInfo& addQueues(UnsignedInt family, std::initializer_list<Float> priorities, std::initializer_list<Containers::Reference<Queue>> output) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& addQueues(UnsignedInt family, std::initializer_list<Float> priorities, std::initializer_list<Containers::Reference<Queue>> 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<const Float> priorities, Containers::ArrayView<const Containers::Reference<Queue>> output) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& addQueues(QueueFlags flags, Containers::ArrayView<const Float> priorities, Containers::ArrayView<const Containers::Reference<Queue>> output) &&; |
|
/** @overload */ |
|
DeviceCreateInfo& addQueues(QueueFlags flags, std::initializer_list<Float> priorities, std::initializer_list<Containers::Reference<Queue>> output) &; |
|
/** @overload */ |
|
DeviceCreateInfo&& addQueues(QueueFlags flags, std::initializer_list<Float> priorities, std::initializer_list<Containers::Reference<Queue>> 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 used as-is, |
|
* with all pointers expected to stay in scope until device creation. |
|
* |
|
* The following @type_vk{DeviceCreateInfo} fields are set by this |
|
* function: |
|
* |
|
* - `queueCreateInfoCount` to the count of queues added previously |
|
* by this function plus @cpp 1 @ce |
|
* - `pQueueCreateInfos` to an array containing all queue create |
|
* infos added previously by this function together with @p info |
|
*/ |
|
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> _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
|
|
|