diff --git a/src/Magnum/Vk/Device.cpp b/src/Magnum/Vk/Device.cpp index da1d70710..772c4f688 100644 --- a/src/Magnum/Vk/Device.cpp +++ b/src/Magnum/Vk/Device.cpp @@ -32,25 +32,25 @@ namespace Magnum { namespace Vk { -Device::Device(PhysicalDevice& physicalDevice, const std::vector& requestedQueues, - const std::vector& extensions, const std::vector& validationLayers, - const VkPhysicalDeviceFeatures& features): +Device::Device(PhysicalDevice& physicalDevice, + const std::vector& requestedQueues, + const std::vector& extensions, + const std::vector& validationLayers, + const DeviceFeatures& features): _physicalDevice(physicalDevice) { VkDeviceCreateInfo deviceCreateInfo = { - VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - nullptr, - 0, /* flags */ - requestedQueues.size(), requestedQueues.data(), + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, nullptr, 0, + requestedQueues.size(), reinterpret_cast(requestedQueues.data()), validationLayers.size(), validationLayers.data(), extensions.size(), extensions.data(), - &features}; + &VkPhysicalDeviceFeatures(features)}; - vkCreateDevice(physicalDevice.vkPhysicalDevice(), &deviceCreateInfo, nullptr, &_device); + vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &_device); - for(const VkDeviceQueueCreateInfo& info : requestedQueues) { - for(UnsignedInt i = 0; i < info.queueCount; ++i) { - _queues.emplace_back(new Queue{*this, info.queueFamilyIndex, i}); + for(const DeviceQueueCreateInfo& info : requestedQueues) { + for(UnsignedInt i = 0; i < info.queueCount(); ++i) { + _queues.emplace_back(new Queue{*this, info.queueFamilyIndex(), i}); } } } diff --git a/src/Magnum/Vk/Device.h b/src/Magnum/Vk/Device.h index 25cf658e0..eed975c36 100644 --- a/src/Magnum/Vk/Device.h +++ b/src/Magnum/Vk/Device.h @@ -32,6 +32,8 @@ #include +#include + #include "Magnum/Magnum.h" #include "Magnum/Vk/Instance.h" #include "Magnum/Vk/PhysicalDevice.h" @@ -41,6 +43,127 @@ namespace Magnum { namespace Vk { +constexpr UnsignedInt deviceFeaturesCount = sizeof(VkPhysicalDeviceFeatures) / 4; + +/** @todoc */ +enum class DeviceFeature : UnsignedInt { + RobustBufferAccess = 0, + FullDrawIndexUint32, + ImageCubeArray, + IndependentBlend, + GeometryShader, + TessellationShader, + SampleRateShading, + DualSrcBlend, + LogicOp, + MultiDrawIndirect, + DrawIndirectFirstInstance, + DepthClamp, + DepthBiasClamp, + FillModeNonSolid, + DepthBounds, + WideLines, + LargePoints, + AlphaToOne, + MultiViewport, + SamplerAnisotropy, + TextureCompressionETC2, + TextureCompressionASTC_LDR, + TextureCompressionBC, + OcclusionQueryPrecise, + PipelineStatisticsQuery, + VertexPipelineStoresAndAtomics, + FragmentStoresAndAtomics, + ShaderTessellationAndGeometryPointSize, + ShaderImageGatherExtended, + ShaderStorageImageExtendedFormats, + ShaderStorageImageMultisample, + ShaderStorageImageReadWithoutFormat, + ShaderStorageImageWriteWithoutFormat, + ShaderUniformBufferArrayDynamicIndexing, + ShaderSampledImageArrayDynamicIndexing, + ShaderStorageBufferArrayDynamicIndexing, + ShaderStorageImageArrayDynamicIndexing, + ShaderClipDistance, + ShaderCullDistance, + ShaderFloat64, + ShaderInt64, + ShaderInt16, + ShaderResourceResidency, + ShaderResourceMinLod, + SparseBinding, + SparseResidencyBuffer, + SparseResidencyImage2D, + SparseResidencyImage3D, + SparseResidency2Samples, + SparseResidency4Samples, + SparseResidency8Samples, + SparseResidency16Samples, + SparseResidencyAliased, + VariableMultisampleRate, + InheritedQueries, +}; + +/** +@brief Device features class + +Container for physical device features. +*/ +class DeviceFeatures : Containers::Array { +public: + + DeviceFeatures(const std::initializer_list& features): + Containers::Array(Containers::Array::zeroInitialized(deviceFeaturesCount)) + { + std::copy(features.begin(), features.end(), this->end()); + } + + operator const VkPhysicalDeviceFeatures&() const { + return *reinterpret_cast(this->data()); + } +}; + +struct DeviceQueueCreateInfo { + + DeviceQueueCreateInfo(UnsignedInt queueFamilyIndex, std::initializer_list priorities) : + _queueFamilyIndex{ queueFamilyIndex }, + _queueCount{UnsignedInt(priorities.size())}, + _queuePriorities{new float[priorities.size()]} + { + std::copy(priorities.begin(), priorities.end(), _queuePriorities); + } + + DeviceQueueCreateInfo(UnsignedInt queueFamilyIndex, const std::vector& priorities) : + _queueFamilyIndex{ queueFamilyIndex }, + _queueCount{ UnsignedInt(priorities.size()) }, + _queuePriorities{ new float[priorities.size()] } + { + std::copy(priorities.begin(), priorities.end(), _queuePriorities); + } + + ~DeviceQueueCreateInfo() { + delete _queuePriorities; + } + + UnsignedInt queueCount() const { + return _queueCount; + } + + UnsignedInt queueFamilyIndex() const { + return _queueFamilyIndex; + } + +private: + const VkStructureType _type = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + const void* _next = nullptr; + const VkDeviceQueueCreateFlags _flags = 0; + UnsignedInt _queueFamilyIndex; + UnsignedInt _queueCount; + float* _queuePriorities; +}; + +static_assert(sizeof(DeviceQueueCreateInfo) == sizeof(VkDeviceQueueCreateInfo), "DeviceQueueCreateInfo and VkDeviceQueueCreateInfo are required to be of same size."); + class CommandPool; class Queue; @@ -54,10 +177,10 @@ class MAGNUM_VK_EXPORT Device { Device(Device&& other); Device(PhysicalDevice& physicalDevice, - const std::vector& requestedQueues, + const std::vector& requestedQueues, const std::vector& extensions, const std::vector& validationLayers, - const VkPhysicalDeviceFeatures& features); + const DeviceFeatures& features); /** * @brief Destructor @@ -110,7 +233,7 @@ class MAGNUM_VK_EXPORT Device { private: VkDevice _device; - PhysicalDevice& _physicalDevice; + PhysicalDevice _physicalDevice; std::vector> _queues; };