diff --git a/src/Device.cpp b/src/Device.cpp index 1ac37b7..41d2cdd 100644 --- a/src/Device.cpp +++ b/src/Device.cpp @@ -104,3 +104,52 @@ uint32_t Device::evaluatePhysicalDevice(vk::raii::PhysicalDevice& device) { return score; } + +bool Device::createLogicalDevice() { + + if(physicalDevice_ == nullptr) { + std::cout << "[" << __FUNCTION__ << ": " << __LINE__ << "] Error: cannot create logical device without a valid physical device." << std::endl; + return false; + } + + // specify queue family requirements + std::vector queueFamilyProperties = physicalDevice_.getQueueFamilyProperties(); + auto graphicsQueueFamilyProperty = std::ranges::find_if(queueFamilyProperties, [](auto const &qfp) { return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast(0); }); + auto graphicsIndex = static_cast(std::distance(queueFamilyProperties.begin(), graphicsQueueFamilyProperty)); + float queuePriority = 1.0f; + vk::DeviceQueueCreateInfo deviceQueueCreateInfo { + .queueFamilyIndex = graphicsIndex, + .queueCount = 1, + .pQueuePriorities = &queuePriority + }; + + // specify device feature requirements + vk::PhysicalDeviceVulkan13Features deviceFeatures = { .dynamicRendering = true }; + vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT deviceStateFeatures = { . extendedDynamicState = true }; + vk::StructureChain featureChain = { + {}, // empty for now + deviceFeatures, + deviceStateFeatures + }; + + // create logical device + vk::DeviceCreateInfo deviceCreateInfo { + .pNext = &featureChain.get(), + .queueCreateInfoCount = 1, + .pQueueCreateInfos = &deviceQueueCreateInfo, + .enabledExtensionCount = static_cast(requiredDeviceExtensions_.size()), + .ppEnabledExtensionNames = requiredDeviceExtensions_.data() + }; + logicalDevice_ = vk::raii::Device(physicalDevice_, deviceCreateInfo); + + // initialize the graphics queue + graphicsQueue_ = vk::raii::Queue(logicalDevice_, graphicsIndex, 0); + + if(logicalDevice_ != nullptr) { + return true; + } else { + std::cout << "[" << __FUNCTION__ << ": " << __LINE__ << "] Error: could not create a valid logical device." << std::endl; + return false; + } + +} diff --git a/src/Device.hpp b/src/Device.hpp index 623980e..61bd35b 100644 --- a/src/Device.hpp +++ b/src/Device.hpp @@ -13,6 +13,9 @@ class Device { // assigns a capable gpu vkdevice to physicalDevice bool selectPhysicalDevice(); + // initializes the logical device + bool createLogicalDevice(); + private: // gives a device a score to attempt to select the most capable device @@ -20,6 +23,8 @@ class Device { vk::raii::Instance* instance_ = nullptr; vk::raii::PhysicalDevice physicalDevice_ = nullptr; + vk::raii::Device logicalDevice_ = nullptr; + vk::raii::Queue graphicsQueue_ = nullptr; // required extensions for the physical device std::vector requiredDeviceExtensions_ = { vk::KHRSwapchainExtensionName }; diff --git a/src/Engine.cpp b/src/Engine.cpp index 2bcbebe..ad7ca36 100644 --- a/src/Engine.cpp +++ b/src/Engine.cpp @@ -23,8 +23,9 @@ void Engine::init() { // device selection and setup Device device(&instance_); - device.selectPhysicalDevice(); - + (void)device.selectPhysicalDevice(); + (void)device.createLogicalDevice(); + // next steps: // queue creation // vulkan memory allocator