diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index 5cfd3f1f7..95cecb232 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -2996,12 +2996,27 @@ using namespace vulkan_internal; } } + // Find sparse fallback: + for (uint32_t i = 0; i < queueFamilyCount; ++i) + { + auto& queueFamily = queueFamilies[i]; + + if (queueFamily.queueFamilyProperties.queueCount > 0 && (queueFamily.queueFamilyProperties.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) + { + sparseFamily = i; + } + } + wi::vector queueCreateInfos; wi::unordered_set uniqueQueueFamilies = { graphicsFamily,copyFamily,computeFamily }; if (videoFamily != VK_QUEUE_FAMILY_IGNORED) { uniqueQueueFamilies.insert(videoFamily); } + if (sparseFamily != VK_QUEUE_FAMILY_IGNORED) + { + uniqueQueueFamilies.insert(sparseFamily); + } float queuePriority = 1.0f; for (uint32_t queueFamily : uniqueQueueFamilies) @@ -3044,6 +3059,10 @@ using namespace vulkan_internal; { vkGetDeviceQueue(device, videoFamily, 0, &videoQueue); } + if (sparseFamily != VK_QUEUE_FAMILY_IGNORED) + { + vkGetDeviceQueue(device, sparseFamily, 0, &sparseQueue); + } queues[QUEUE_GRAPHICS].queue = graphicsQueue; queues[QUEUE_GRAPHICS].locker = queue_lockers[graphicsFamily]; @@ -3051,11 +3070,17 @@ using namespace vulkan_internal; queues[QUEUE_COMPUTE].locker = queue_lockers[computeFamily]; queues[QUEUE_COPY].queue = copyQueue; queues[QUEUE_COPY].locker = queue_lockers[copyFamily]; - queues[QUEUE_VIDEO_DECODE].queue = videoQueue; if (videoFamily != VK_QUEUE_FAMILY_IGNORED) { + queues[QUEUE_VIDEO_DECODE].queue = videoQueue; queues[QUEUE_VIDEO_DECODE].locker = queue_lockers[videoFamily]; } + if (sparseFamily != VK_QUEUE_FAMILY_IGNORED) + { + queue_sparse.queue = sparseQueue; + queue_sparse.locker = queue_lockers[sparseFamily]; + queue_sparse.sparse_binding_supported = true; + } } @@ -7487,21 +7512,16 @@ using namespace vulkan_internal; // Queue command: { - if (!queues[queue].sparse_binding_supported) + CommandQueue* q = &queues[queue]; + if (!q->sparse_binding_supported) { - // 1.) fall back to graphics queue if current one doesn't support sparse, might be better than crashing - queue = QUEUE_GRAPHICS; + // 1.) fall back to any sparse supporting queue + q = &queue_sparse; } - if (!queues[queue].sparse_binding_supported) - { - // 2.) fall back to compute queue if current one doesn't support sparse, might be better than crashing - queue = QUEUE_COMPUTE; - } - CommandQueue& q = queues[queue]; - std::scoped_lock lock(*q.locker); - wilog_assert(q.sparse_binding_supported, "Vulkan QUEUE_TYPE=%d doesn't report sparse binding support! This can result in broken rendering or crash. Try to update the graphics driver if this happens.", int(queue)); + std::scoped_lock lock(*q->locker); + wilog_assert(q->sparse_binding_supported, "Vulkan sparse mapping was used while the feature is not available! This can result in broken rendering or crash. Try to update the graphics driver if this happens."); - vulkan_check(vkQueueBindSparse(q.queue, (uint32_t)sparse_infos.size(), sparse_infos.data(), VK_NULL_HANDLE)); + vulkan_check(vkQueueBindSparse(q->queue, (uint32_t)sparse_infos.size(), sparse_infos.data(), VK_NULL_HANDLE)); } } diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.h b/WickedEngine/wiGraphicsDevice_Vulkan.h index e71f97efd..6e2be34f2 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.h +++ b/WickedEngine/wiGraphicsDevice_Vulkan.h @@ -122,11 +122,13 @@ namespace wi::graphics uint32_t computeFamily = VK_QUEUE_FAMILY_IGNORED; uint32_t copyFamily = VK_QUEUE_FAMILY_IGNORED; uint32_t videoFamily = VK_QUEUE_FAMILY_IGNORED; + uint32_t sparseFamily = VK_QUEUE_FAMILY_IGNORED; wi::vector families; VkQueue graphicsQueue = VK_NULL_HANDLE; VkQueue computeQueue = VK_NULL_HANDLE; VkQueue copyQueue = VK_NULL_HANDLE; VkQueue videoQueue = VK_NULL_HANDLE; + VkQueue sparseQueue = VK_NULL_HANDLE; bool debugUtils = false; VkPhysicalDeviceProperties2 properties2 = {}; @@ -207,6 +209,8 @@ namespace wi::graphics } queues[QUEUE_COUNT]; + CommandQueue queue_sparse; + struct CopyAllocator { GraphicsDevice_Vulkan* device = nullptr; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index a554fb9ae..2f33fb439 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 705; + const int revision = 706; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);