|
| 1 | +# Vulkan Device |
| 2 | + |
| 3 | +A [Vulkan Device](https://registry.khronos.org/vulkan/specs/latest/man/html/VkDevice.html) is a logical instance of a Physical Device, and will the primary interface for everything Vulkan now onwards. [Vulkan Queues](https://registry.khronos.org/vulkan/specs/latest/man/html/VkQueue.html) are owned by the Device, we will need one from the queue family stored in the `Gpu`, to submit recorded command buffers. We also need to explicitly declare all features we want to use, eg [Dynamic Rendering](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_dynamic_rendering.html) and [Synchronization2](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_synchronization2.html). |
| 4 | + |
| 5 | +Setup a `vk::QueueCreateInfo` object: |
| 6 | + |
| 7 | +```cpp |
| 8 | + auto queue_ci = vk::DeviceQueueCreateInfo{}; |
| 9 | + // since we use only one queue, it has the entire priority range, ie, 1.0 |
| 10 | + static constexpr auto queue_priorities_v = std::array{1.0f}; |
| 11 | + queue_ci.setQueueFamilyIndex(m_gpu.queue_family) |
| 12 | + .setQueueCount(1) |
| 13 | + .setQueuePriorities(queue_priorities_v); |
| 14 | +``` |
| 15 | +
|
| 16 | +Setup the core device features: |
| 17 | +
|
| 18 | +```cpp |
| 19 | + auto enabled_features = vk::PhysicalDeviceFeatures{}; |
| 20 | + enabled_features.fillModeNonSolid = m_gpu.features.fillModeNonSolid; |
| 21 | + enabled_features.wideLines = m_gpu.features.wideLines; |
| 22 | + enabled_features.samplerAnisotropy = m_gpu.features.samplerAnisotropy; |
| 23 | + enabled_features.sampleRateShading = m_gpu.features.sampleRateShading; |
| 24 | +``` |
| 25 | + |
| 26 | +Setup the additional features, using `setPNext()` to chain them: |
| 27 | + |
| 28 | +```cpp |
| 29 | + auto sync_feature = vk::PhysicalDeviceSynchronization2Features{vk::True}; |
| 30 | + auto dynamic_rendering_feature = |
| 31 | + vk::PhysicalDeviceDynamicRenderingFeatures{vk::True}; |
| 32 | + sync_feature.setPNext(&dynamic_rendering_feature); |
| 33 | +``` |
| 34 | +
|
| 35 | +Setup a `vk::DeviceCreateInfo` object: |
| 36 | +
|
| 37 | +```cpp |
| 38 | + auto device_ci = vk::DeviceCreateInfo{}; |
| 39 | + static constexpr auto extensions_v = |
| 40 | + std::array{VK_KHR_SWAPCHAIN_EXTENSION_NAME}; |
| 41 | + device_ci.setPEnabledExtensionNames(extensions_v) |
| 42 | + .setQueueCreateInfos(queue_ci) |
| 43 | + .setPEnabledFeatures(&enabled_features) |
| 44 | + .setPNext(&sync_feature); |
| 45 | +``` |
| 46 | + |
| 47 | +Declare a `vk::UniqueDevice` member after `m_gpu`, create it, and initialize the dispatcher against it: |
| 48 | + |
| 49 | +```cpp |
| 50 | + m_device = m_gpu.device.createDeviceUnique(device_ci); |
| 51 | + VULKAN_HPP_DEFAULT_DISPATCHER.init(*m_device); |
| 52 | +``` |
| 53 | + |
| 54 | +Declare a `vk::Queue` member (order doesn't matter since it's just a handle, the actual Queue is owned by the Device) and initialize it: |
| 55 | + |
| 56 | +```cpp |
| 57 | + static constexpr std::uint32_t queue_index_v{0}; |
| 58 | + m_queue = m_device->getQueue(m_gpu.queue_family, queue_index_v); |
| 59 | +``` |
0 commit comments