From 919a51054909ebe2b19e1ae4c2b849ce622cca4a Mon Sep 17 00:00:00 2001 From: saschawillems Date: Fri, 22 Jul 2016 22:24:27 +0200 Subject: [PATCH] VulkanDevice class, setup debugging before creating the logical device --- base/vulkandevice.hpp | 99 ++++++++++++++++---------------------- base/vulkanexamplebase.cpp | 74 +++++++++------------------- 2 files changed, 63 insertions(+), 110 deletions(-) diff --git a/base/vulkandevice.hpp b/base/vulkandevice.hpp index cb074f4f..c7467c18 100644 --- a/base/vulkandevice.hpp +++ b/base/vulkandevice.hpp @@ -115,7 +115,6 @@ namespace vk */ uint32_t getQueueFamiliyIndex(VkQueueFlagBits queueFlags) { - uint32_t queueIndex; uint32_t queueCount; // Get number of available queue families on this device @@ -150,16 +149,53 @@ namespace vk } /** - * Create the logical device based on the assigned physical device + * Create the logical device based on the assigned physical device, also gets default queue family indices * - * @param queueCreateInfos A vector containing queue create infos for all queues to be requested on the device * @param enabledFeatures Can be used to enable certain features upon device creation * @param useSwapChain Set to false for headless rendering to omit the swapchain device extensions - * + * * @return VkResult of the device creation call */ - VkResult createLogicalDevice(std::vector &queueCreateInfos, VkPhysicalDeviceFeatures enabledFeatures, bool useSwapChain = true) + VkResult createLogicalDevice(VkPhysicalDeviceFeatures enabledFeatures, bool useSwapChain = true) { + // Get queue family indices for graphics and compute + // Note that the indices may overlap depending on the implementation + queueFamilyIndices.graphics = getQueueFamiliyIndex(VK_QUEUE_GRAPHICS_BIT); + queueFamilyIndices.compute = getQueueFamiliyIndex(VK_QUEUE_COMPUTE_BIT); + //todo: Transfer? + + // Pass queue information for graphics and compute, so examples can later on request queues from both + std::vector queuePriorities; + + std::vector queueCreateInfos{}; + // We need one queue create info per queue family index + // If graphics and compute share the same queue family index we only need one queue create info but + // with two queues to request + queueCreateInfos.resize(1); + // Graphics + queuePriorities.push_back(0.0f); + queueCreateInfos[0] = {}; + queueCreateInfos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfos[0].queueFamilyIndex = queueFamilyIndices.graphics; + queueCreateInfos[0].queueCount = 1; + // Compute + // If compute has a different queue family index, add another create info, else just add + if (queueFamilyIndices.graphics != queueFamilyIndices.compute) + { + queueCreateInfos.resize(2); + queueCreateInfos[1] = {}; + queueCreateInfos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfos[1].queueFamilyIndex = queueFamilyIndices.compute; + queueCreateInfos[1].queueCount = 1; + queueCreateInfos[1].pQueuePriorities = queuePriorities.data(); + } + else + { + queueCreateInfos[0].queueCount++; + queuePriorities.push_back(0.0f); + } + queueCreateInfos[0].pQueuePriorities = queuePriorities.data(); + // Create the logical device representation std::vector deviceExtensions; if (useSwapChain) @@ -191,59 +227,6 @@ namespace vk return vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &logicalDevice); } - /** - * Create the logical device based on the assigned physical device - * - * @note Using this overload will implicitly get default queue family indices for graphics and compute - * - * @param enabledFeatures Can be used to enable certain features upon device creation - * @param useSwapChain Set to false for headless rendering to omit the swapchain device extensions - * - * @return VkResult of the device creation call - */ - VkResult createLogicalDevice(VkPhysicalDeviceFeatures enabledFeatures, bool useSwapChain = true) - { - // Get queue family indices for graphics and compute - // Note that the indices may overlap depending on the implementation - queueFamilyIndices.graphics = getQueueFamiliyIndex(VK_QUEUE_GRAPHICS_BIT); - queueFamilyIndices.compute = getQueueFamiliyIndex(VK_QUEUE_COMPUTE_BIT); - //todo: Transfer? - - // Pass queue information for graphics and compute, so examples can later on request queues from both - std::vector queuePriorities; - - std::vector queueCreateInfos{}; - // We need one queue create info per queue family index - // If graphics and compute share the same queue family index we only need one queue create info but - // with two queues to request - queueCreateInfos.resize(1); - queuePriorities.resize(1, 0.0f); - // Graphics - queueCreateInfos[0] = {}; - queueCreateInfos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfos[0].queueFamilyIndex = queueFamilyIndices.graphics; - queueCreateInfos[0].queueCount = 1; - queueCreateInfos[0].pQueuePriorities = queuePriorities.data(); - // Compute - // If compute has a different queue family index, add another create info, else just add - if (queueFamilyIndices.graphics != queueFamilyIndices.compute) - { - queueCreateInfos.resize(2); - queueCreateInfos[1] = {}; - queueCreateInfos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfos[1].queueFamilyIndex = queueFamilyIndices.compute; - queueCreateInfos[1].queueCount = 1; - queueCreateInfos[1].pQueuePriorities = queuePriorities.data(); - } - else - { - queueCreateInfos[0].queueCount++; - queuePriorities.push_back(0.0f); - } - - return createLogicalDevice(queueCreateInfos, enabledFeatures, useSwapChain); - } - /** * Create a buffer on the device * diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index 8cfd583e..b5706ed8 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -208,14 +208,6 @@ void VulkanExampleBase::createPipelineCache() void VulkanExampleBase::prepare() { - if (enableValidation) - { - // The report flags determine what type of messages for the layers will be displayed - // For validating (debugging) an appplication the error and warning bits should suffice - VkDebugReportFlagsEXT debugReportFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT; // VK_DEBUG_REPORT_WARNING_BIT_EXT (enable to also display warnings) - // Additional flags include performance info, loader and layer debug messages, etc. - vkDebug::setupDebugging(instance, debugReportFlags, VK_NULL_HANDLE); - } if (enableDebugMarkers) { vkDebug::DebugMarker::setup(device); @@ -698,11 +690,6 @@ VulkanExampleBase::VulkanExampleBase(bool enableValidation, PFN_GetEnabledFeatur this->enabledFeatures = enabledFeaturesFn(); } -#if !defined(__ANDROID__) - // Android Vulkan initialization is handled in APP_CMD_INIT_WINDOW event - initVulkan(enableValidation); -#endif - #if defined(_WIN32) // Enable console if validation is active // Debug message callback will output to it @@ -711,6 +698,11 @@ VulkanExampleBase::VulkanExampleBase(bool enableValidation, PFN_GetEnabledFeatur setupConsole("VulkanExample"); } #endif + +#if !defined(__ANDROID__) + // Android Vulkan initialization is handled in APP_CMD_INIT_WINDOW event + initVulkan(enableValidation); +#endif } VulkanExampleBase::~VulkanExampleBase() @@ -793,6 +785,16 @@ void VulkanExampleBase::initVulkan(bool enableValidation) loadVulkanFunctions(instance); #endif + // If requested, we enable the default validation layers for debugging + if (enableValidation) + { + // The report flags determine what type of messages for the layers will be displayed + // For validating (debugging) an appplication the error and warning bits should suffice + VkDebugReportFlagsEXT debugReportFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; + // Additional flags include performance info, loader and layer debug messages, etc. + vkDebug::setupDebugging(instance, debugReportFlags, VK_NULL_HANDLE); + } + // Physical device uint32_t gpuCount = 0; // Get number of available physical devices @@ -812,42 +814,14 @@ void VulkanExampleBase::initVulkan(bool enableValidation) // and want to use another one physicalDevice = physicalDevices[0]; - vulkanDevice = new vk::VulkanDevice(physicalDevice); - - // Find a queue that supports graphics operations - uint32_t graphicsQueueIndex = 0; - uint32_t queueCount; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL); - assert(queueCount >= 1); - - std::vector queueProps; - queueProps.resize(queueCount); - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, queueProps.data()); - - for (graphicsQueueIndex = 0; graphicsQueueIndex < queueCount; graphicsQueueIndex++) - { - if (queueProps[graphicsQueueIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) - break; - } - assert(graphicsQueueIndex < queueCount); - // Vulkan device creation - - // We will be requesting queues from one family only - // todo: Multiple queue families for transfer and async compute - std::vector queuePriorities = { 0.0f }; - std::vector queueCreateInfos = {}; - queueCreateInfos.resize(1); - queueCreateInfos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfos[0].queueFamilyIndex = graphicsQueueIndex; - queueCreateInfos[0].queueCount = 1; - queueCreateInfos[0].pQueuePriorities = queuePriorities.data(); - - VK_CHECK_RESULT(vulkanDevice->createLogicalDevice(queueCreateInfos, enabledFeatures)); - - // Assign device to base class context + // This is handled by a separate class that gets a logical device representation + // and encapsulates functions related to a device + vulkanDevice = new vk::VulkanDevice(physicalDevice); + VK_CHECK_RESULT(vulkanDevice->createLogicalDevice(enabledFeatures)); device = vulkanDevice->logicalDevice; + // todo: remove // Store properties (including limits) and features of the phyiscal device // So examples can check against them and see if a feature is actually supported vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties); @@ -855,8 +829,8 @@ void VulkanExampleBase::initVulkan(bool enableValidation) // Gather physical device memory properties vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties); - // Get the graphics queue - vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); + // Get a graphics queue from the device + vkGetDeviceQueue(device, vulkanDevice->queueFamilyIndices.graphics, 0, &queue); // Find a suitable depth format VkBool32 validDepthFormat = vkTools::getSupportedDepthFormat(physicalDevice, &depthFormat); @@ -897,10 +871,6 @@ void VulkanExampleBase::setupConsole(std::string title) FILE *stream; freopen_s(&stream, "CONOUT$", "w+", stdout); SetConsoleTitle(TEXT(title.c_str())); - if (enableValidation) - { - std::cout << "Validation enabled:\n"; - } } HWND VulkanExampleBase::setupWindow(HINSTANCE hinstance, WNDPROC wndproc)