From 9a09a4e81528430e3b565db8176cb54e1c8241af Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Fri, 2 Apr 2021 22:36:44 +0530 Subject: [PATCH] Extend VkQueue Allocation Code The VkQueue allocation code is rewritten to iterate through all queue families to look for an appropriate queue now --- .idea/vcs.xml | 1 - app/src/main/cpp/skyline/gpu.cpp | 42 ++++++++++++++++++-------------- app/src/main/cpp/skyline/gpu.h | 3 ++- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 9cb13448..f7d4b52b 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -9,7 +9,6 @@ - diff --git a/app/src/main/cpp/skyline/gpu.cpp b/app/src/main/cpp/skyline/gpu.cpp index e290aeb0..15a23a96 100644 --- a/app/src/main/cpp/skyline/gpu.cpp +++ b/app/src/main/cpp/skyline/gpu.cpp @@ -98,10 +98,10 @@ namespace skyline::gpu { return std::move(vk::raii::PhysicalDevices(instance).front()); // We just select the first device as we aren't expecting multiple GPUs } - vk::raii::Device GPU::CreateDevice(const DeviceState &state, const vk::raii::PhysicalDevice &physicalDevice) { - auto properties{physicalDevice.getProperties2().properties}; // We should check for required properties here, if/when we have them + vk::raii::Device GPU::CreateDevice(const DeviceState &state, const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount)& vkQueueFamilyIndex) { + auto properties{physicalDevice.getProperties()}; // We should check for required properties here, if/when we have them - // auto features{physicalDevice.getFeatures2().features}; // Same as above + // auto features{physicalDevice.getFeatures()}; // Same as above constexpr std::array requiredDeviceExtensions{ VK_KHR_SWAPCHAIN_EXTENSION_NAME, @@ -117,17 +117,24 @@ namespace skyline::gpu { throw exception("Cannot find Vulkan device extension: \"{}\"", requiredExtension); } - auto queueFamilies{physicalDevice.getQueueFamilyProperties2()}; - if (auto family{queueFamilies.front().queueFamilyProperties}; !(family.queueFlags & vk::QueueFlagBits::eGraphics && family.queueFlags & vk::QueueFlagBits::eCompute)) - // We only check the first queue family as essentially all mobile GPUs only have a single queue family which supports all operations - throw exception("The first queue family doesn't support both eGraphics and eCompute workloads"); + auto queueFamilies{physicalDevice.getQueueFamilyProperties()}; + float queuePriority{1.f}; //!< The priority of the only queue we use, it's set to the maximum of 1.0 + vk::DeviceQueueCreateInfo queue{[&] { + typeof(vk::DeviceQueueCreateInfo::queueFamilyIndex) index{}; + for (const auto &queueFamily : queueFamilies) { + if (queueFamily.queueFlags & vk::QueueFlagBits::eGraphics && queueFamily.queueFlags & vk::QueueFlagBits::eCompute) { + vkQueueFamilyIndex = index; + return vk::DeviceQueueCreateInfo{ + .queueFamilyIndex = index, + .queueCount = 1, + .pQueuePriorities = &queuePriority, + }; + } + index++; + } + throw exception("Cannot find a queue family with both eGraphics and eCompute bits set"); + }()}; - float queuePriority{1.f}; //!< As we only have one queue, it's priority is set to the maximum of 1.0 - vk::DeviceQueueCreateInfo queue{ - .queueFamilyIndex = 0, - .queueCount = 1, - .pQueuePriorities = &queuePriority, - }; if (state.logger->configLevel >= Logger::LogLevel::Error) { std::string extensionString; @@ -135,10 +142,9 @@ namespace skyline::gpu { extensionString += util::Format("\n* {} (v{}.{}.{})", extension.extensionName, VK_VERSION_MAJOR(extension.specVersion), VK_VERSION_MINOR(extension.specVersion), VK_VERSION_PATCH(extension.specVersion)); std::string queueString; - for (const auto &queueFamily : queueFamilies) { - auto &family{queueFamily.queueFamilyProperties}; - queueString += util::Format("\n* {}x{}{}{}{}{}: TSB{}, MIG({},{},{})", family.queueCount, family.queueFlags & vk::QueueFlagBits::eGraphics ? 'G' : '-', family.queueFlags & vk::QueueFlagBits::eCompute ? 'C' : '-', family.queueFlags & vk::QueueFlagBits::eTransfer ? 'T' : '-', family.queueFlags & vk::QueueFlagBits::eSparseBinding ? 'S' : '-', family.queueFlags & vk::QueueFlagBits::eProtected ? 'P' : '-', family.timestampValidBits, family.minImageTransferGranularity.width, family.minImageTransferGranularity.height, family.minImageTransferGranularity.depth); - } + typeof(vk::DeviceQueueCreateInfo::queueFamilyIndex) familyIndex{}; + for (const auto &queueFamily : queueFamilies) + queueString += util::Format("\n* {}x{}{}{}{}{}: TSB{} MIG({}x{}x{}){}", queueFamily.queueCount, queueFamily.queueFlags & vk::QueueFlagBits::eGraphics ? 'G' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eCompute ? 'C' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eTransfer ? 'T' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eSparseBinding ? 'S' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eProtected ? 'P' : '-', queueFamily.timestampValidBits, queueFamily.minImageTransferGranularity.width, queueFamily.minImageTransferGranularity.height, queueFamily.minImageTransferGranularity.depth, familyIndex++ == vkQueueFamilyIndex ? " <--" : ""); state.logger->Error("Vulkan Device:\nName: {}\nType: {}\nVulkan Version: {}.{}.{}\nDriver Version: {}.{}.{}\nQueues:{}\nExtensions:{}", properties.deviceName, vk::to_string(properties.deviceType), VK_VERSION_MAJOR(properties.apiVersion), VK_VERSION_MINOR(properties.apiVersion), VK_VERSION_PATCH(properties.apiVersion), VK_VERSION_MAJOR(properties.driverVersion), VK_VERSION_MINOR(properties.driverVersion), VK_VERSION_PATCH(properties.driverVersion), queueString, extensionString); } @@ -151,5 +157,5 @@ namespace skyline::gpu { }); } - GPU::GPU(const DeviceState &state) : vkInstance(CreateInstance(state, vkContext)), vkDebugReportCallback(CreateDebugReportCallback(state, vkInstance)), vkPhysicalDevice(CreatePhysicalDevice(state, vkInstance)), vkDevice(CreateDevice(state, vkPhysicalDevice)), vkQueue(vkDevice, 0, 0), presentation(state) {} + GPU::GPU(const DeviceState &state) : vkInstance(CreateInstance(state, vkContext)), vkDebugReportCallback(CreateDebugReportCallback(state, vkInstance)), vkPhysicalDevice(CreatePhysicalDevice(state, vkInstance)), vkDevice(CreateDevice(state, vkPhysicalDevice, vkQueueFamilyIndex)), vkQueue(vkDevice, vkQueueFamilyIndex, 0), presentation(state) {} } diff --git a/app/src/main/cpp/skyline/gpu.h b/app/src/main/cpp/skyline/gpu.h index b17a276b..7f42d6f5 100644 --- a/app/src/main/cpp/skyline/gpu.h +++ b/app/src/main/cpp/skyline/gpu.h @@ -19,13 +19,14 @@ namespace skyline::gpu { static vk::raii::PhysicalDevice CreatePhysicalDevice(const DeviceState &state, const vk::raii::Instance &instance); - static vk::raii::Device CreateDevice(const DeviceState &state, const vk::raii::PhysicalDevice &physicalDevice); + static vk::raii::Device CreateDevice(const DeviceState &state, const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount)& queueConfiguration); public: vk::raii::Context vkContext; //!< An overarching context for Vulkan with vk::raii::Instance vkInstance; //!< An instance of Vulkan with all application context vk::raii::DebugReportCallbackEXT vkDebugReportCallback; //!< An RAII Vulkan debug report manager which calls into DebugCallback vk::raii::PhysicalDevice vkPhysicalDevice; //!< The underlying physical Vulkan device from which we derieve our logical device + typeof(vk::DeviceQueueCreateInfo::queueCount) vkQueueFamilyIndex{}; //!< The index of the family the queue is from vk::raii::Device vkDevice; //!< The logical Vulkan device which we want to render using vk::raii::Queue vkQueue; //!< A Vulkan Queue supporting graphics and compute operations