diff --git a/Core/Core/RenderEngine.cpp b/Core/Core/RenderEngine.cpp index 49954f9..ba4ec23 100644 --- a/Core/Core/RenderEngine.cpp +++ b/Core/Core/RenderEngine.cpp @@ -1,5 +1,7 @@ #include "RenderEngine.h" +#include +#include #include #include @@ -44,36 +46,41 @@ std::vector RenderEngine::get_required_extensions() bool RenderEngine::QueueFamilyIndices::is_complete() { - return graphycs_family.has_value(); + return graphycs_family.has_value() && present_family.has_value(); } -bool RenderEngine::is_device_suitable(VkPhysicalDevice device) +bool RenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface) { VkPhysicalDeviceProperties device_properties; VkPhysicalDeviceFeatures device_features; vkGetPhysicalDeviceProperties(device, &device_properties); vkGetPhysicalDeviceFeatures(device, &device_features); - QueueFamilyIndices indices = find_queue_family_indices(device); + QueueFamilyIndices indices = find_queue_family_indices(device, surface); return device_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && device_features.geometryShader && indices.is_complete(); } -RenderEngine::QueueFamilyIndices RenderEngine::find_queue_family_indices(VkPhysicalDevice device) +RenderEngine::QueueFamilyIndices RenderEngine::find_queue_family_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface) { QueueFamilyIndices queue_family_indices; uint32_t queueFamilyCount = 0; - vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, nullptr); std::vector family_propertieses(queueFamilyCount); - vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, family_propertieses.data()); + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, family_propertieses.data()); for (uint32_t i = 0; i < family_propertieses.size(); ++i) { if (family_propertieses[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) queue_family_indices.graphycs_family = i; + + VkBool32 present_support = false; + VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, &present_support)); + if (present_support) + queue_family_indices.present_family = i; if(queue_family_indices.is_complete()) break; } @@ -128,7 +135,7 @@ void RenderEngine::pick_physical_device() for (const auto& device : devices) { - if (is_device_suitable(device)) + if (is_device_suitable(device, surface_)) { physical_device_ = device; VkPhysicalDeviceProperties device_properties; @@ -144,21 +151,28 @@ void RenderEngine::pick_physical_device() void RenderEngine::create_logical_device() { - QueueFamilyIndices indices = find_queue_family_indices(physical_device_); + QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_); VkPhysicalDeviceFeatures device_features{}; + + std::vector queue_create_infos; + std::set unique_queue_families = {indices.graphycs_family.value(), indices.present_family.value()}; float queue_priority = 1.0f; VkDeviceQueueCreateInfo device_queue_create_info{}; device_queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - device_queue_create_info.queueFamilyIndex = indices.graphycs_family.value(); - device_queue_create_info.queueCount = 1; - device_queue_create_info.pQueuePriorities = &queue_priority; + device_queue_create_info.pQueuePriorities = &queue_priority; + for (auto queue_family : unique_queue_families) + { + device_queue_create_info.queueFamilyIndex = queue_family; + device_queue_create_info.queueCount = 1; + queue_create_infos.push_back(device_queue_create_info); + } VkDeviceCreateInfo device_create_info{}; device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - device_create_info.queueCreateInfoCount = 1; - device_create_info.pQueueCreateInfos = &device_queue_create_info; + device_create_info.queueCreateInfoCount = static_cast(unique_queue_families.size()); + device_create_info.pQueueCreateInfos = queue_create_infos.data(); device_create_info.pEnabledFeatures = &device_features; device_create_info.enabledExtensionCount = 0; device_create_info.ppEnabledExtensionNames = nullptr; @@ -176,6 +190,7 @@ void RenderEngine::create_logical_device() #endif VK_CHECK(vkCreateDevice(physical_device_, &device_create_info, nullptr, &device_)); vkGetDeviceQueue(device_, indices.graphycs_family.value(), 0, &graphics_queue_); + vkGetDeviceQueue(device_, indices.present_family.value(), 0, &present_queue_); } void RenderEngine::create_surface() diff --git a/Core/Core/RenderEngine.h b/Core/Core/RenderEngine.h index 5508c66..51fc3c1 100644 --- a/Core/Core/RenderEngine.h +++ b/Core/Core/RenderEngine.h @@ -22,6 +22,7 @@ class RenderEngine struct QueueFamilyIndices { std::optional graphycs_family; + std::optional present_family; bool is_complete(); }; @@ -32,6 +33,7 @@ class RenderEngine VkPhysicalDevice physical_device_ = VK_NULL_HANDLE; VkDevice device_ = VK_NULL_HANDLE; VkQueue graphics_queue_ = VK_NULL_HANDLE; + VkQueue present_queue_ = VK_NULL_HANDLE; #ifdef _DEBUG VkResult enable_layer_validation(VkDebugUtilsMessengerCreateInfoEXT* create_info); @@ -39,8 +41,8 @@ class RenderEngine #endif static std::vector get_required_extensions(); - static bool is_device_suitable(VkPhysicalDevice device); - static QueueFamilyIndices find_queue_family_indices(VkPhysicalDevice device); + static bool is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface); + static QueueFamilyIndices find_queue_family_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface); void create_instance(); void create_surface();