From 7e503fa053651091a49790590c8abde88a6d849e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 21 Feb 2025 12:48:22 +0100 Subject: [PATCH] [dxvk] Enable VK_EXT_multi_draw if supported --- src/dxvk/dxvk_adapter.cpp | 26 ++++++++++++++++++++++++++ src/dxvk/dxvk_cmdlist.h | 28 ++++++++++++++++++++++++++-- src/dxvk/dxvk_device_info.h | 4 +++- src/dxvk/dxvk_extensions.h | 1 + src/vulkan/vulkan_loader.h | 5 +++++ 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 12ede57b0..5c07fc88d 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -400,6 +400,10 @@ namespace dxvk { m_deviceFeatures.extLineRasterization.smoothLines; } + // Enable multi-draw for draw batching + enabledFeatures.extMultiDraw.multiDraw = + m_deviceFeatures.extMultiDraw.multiDraw; + // Enable memory priority and pageable memory if supported // to improve driver-side memory management enabledFeatures.extMemoryPriority.memoryPriority = @@ -600,6 +604,10 @@ namespace dxvk { enabledFeatures.extMemoryPriority = *reinterpret_cast(f); break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT: + enabledFeatures.extMultiDraw = *reinterpret_cast(f); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT: enabledFeatures.extNonSeamlessCubeMap = *reinterpret_cast(f); break; @@ -791,6 +799,11 @@ namespace dxvk { m_deviceInfo.extLineRasterization.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extLineRasterization); } + if (m_deviceExtensions.supports(VK_EXT_MULTI_DRAW_EXTENSION_NAME)) { + m_deviceInfo.extMultiDraw.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT; + m_deviceInfo.extMultiDraw.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extMultiDraw); + } + if (m_deviceExtensions.supports(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) { m_deviceInfo.extRobustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT; m_deviceInfo.extRobustness2.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extRobustness2); @@ -891,6 +904,11 @@ namespace dxvk { m_deviceFeatures.extMemoryPriority.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extMemoryPriority); } + if (m_deviceExtensions.supports(VK_EXT_MULTI_DRAW_EXTENSION_NAME)) { + m_deviceFeatures.extMultiDraw.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT; + m_deviceFeatures.extMultiDraw.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extMultiDraw); + } + if (m_deviceExtensions.supports(VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME)) { m_deviceFeatures.extNonSeamlessCubeMap.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT; m_deviceFeatures.extNonSeamlessCubeMap.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extNonSeamlessCubeMap); @@ -1017,6 +1035,7 @@ namespace dxvk { &devExtensions.extLineRasterization, &devExtensions.extMemoryBudget, &devExtensions.extMemoryPriority, + &devExtensions.extMultiDraw, &devExtensions.extNonSeamlessCubeMap, &devExtensions.extPageableDeviceLocalMemory, &devExtensions.extRobustness2, @@ -1116,6 +1135,11 @@ namespace dxvk { enabledFeatures.extMemoryPriority.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extMemoryPriority); } + if (devExtensions.extMultiDraw) { + enabledFeatures.extMultiDraw.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT; + enabledFeatures.extMultiDraw.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extMultiDraw); + } + if (devExtensions.extNonSeamlessCubeMap) { enabledFeatures.extNonSeamlessCubeMap.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT; enabledFeatures.extNonSeamlessCubeMap.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extNonSeamlessCubeMap); @@ -1308,6 +1332,8 @@ namespace dxvk { "\n extension supported : ", features.extMemoryBudget ? "1" : "0", "\n", VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, "\n memoryPriority : ", features.extMemoryPriority.memoryPriority ? "1" : "0", + "\n", VK_EXT_MULTI_DRAW_EXTENSION_NAME, + "\n multiDraw : ", features.extMultiDraw.multiDraw ? "1" : "0", "\n", VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, "\n nonSeamlessCubeMap : ", features.extNonSeamlessCubeMap.nonSeamlessCubeMap ? "1" : "0", "\n", VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME, diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 9139d12fc..ac1a9cd93 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -722,6 +722,18 @@ namespace dxvk { vertexCount, instanceCount, firstVertex, firstInstance); } + + + void cmdDrawMulti( + uint32_t drawCount, + const VkMultiDrawInfoEXT* drawInfos, + uint32_t instanceCount, + uint32_t firstInstance) { + m_statCounters.addCtr(DxvkStatCounter::CmdDrawCalls, 1); + + m_vkd->vkCmdDrawMultiEXT(getCmdBuffer(), + drawCount, drawInfos, instanceCount, firstInstance, sizeof(*drawInfos)); + } void cmdDrawIndirect( @@ -745,8 +757,8 @@ namespace dxvk { uint32_t stride) { m_statCounters.addCtr(DxvkStatCounter::CmdDrawCalls, 1); - m_vkd->vkCmdDrawIndirectCount(getCmdBuffer(), - buffer, offset, countBuffer, countOffset, maxDrawCount, stride); + m_vkd->vkCmdDrawIndirectCount(getCmdBuffer(), buffer, + offset, countBuffer, countOffset, maxDrawCount, stride); } @@ -765,6 +777,18 @@ namespace dxvk { } + void cmdDrawMultiIndexed( + uint32_t drawCount, + const VkMultiDrawIndexedInfoEXT* drawInfos, + uint32_t instanceCount, + uint32_t firstInstance) { + m_statCounters.addCtr(DxvkStatCounter::CmdDrawCalls, 1); + + m_vkd->vkCmdDrawMultiIndexedEXT(getCmdBuffer(), drawCount, + drawInfos, instanceCount, firstInstance, sizeof(*drawInfos), nullptr); + } + + void cmdDrawIndexedIndirect( VkBuffer buffer, VkDeviceSize offset, diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index b1e1eaf1d..9ab82ee6c 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -25,6 +25,7 @@ namespace dxvk { VkPhysicalDeviceExtendedDynamicState3PropertiesEXT extExtendedDynamicState3; VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT extGraphicsPipelineLibrary; VkPhysicalDeviceLineRasterizationPropertiesEXT extLineRasterization; + VkPhysicalDeviceMultiDrawPropertiesEXT extMultiDraw; VkPhysicalDeviceRobustness2PropertiesEXT extRobustness2; VkPhysicalDeviceTransformFeedbackPropertiesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT extVertexAttributeDivisor; @@ -58,6 +59,7 @@ namespace dxvk { VkPhysicalDeviceLineRasterizationFeaturesEXT extLineRasterization; VkBool32 extMemoryBudget; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; + VkPhysicalDeviceMultiDrawFeaturesEXT extMultiDraw; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT extPageableDeviceLocalMemory; VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; @@ -80,4 +82,4 @@ namespace dxvk { VkBool32 khrWin32KeyedMutex; }; -} \ No newline at end of file +} diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 4019ac5d2..76a94bff3 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -308,6 +308,7 @@ namespace dxvk { DxvkExt extLineRasterization = { VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extMultiDraw = { VK_EXT_MULTI_DRAW_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extNonSeamlessCubeMap = { VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extPageableDeviceLocalMemory = { VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Required }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index edc9d6df6..22ce278f5 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -405,6 +405,11 @@ namespace dxvk::vk { VULKAN_FN(vkSetDeviceMemoryPriorityEXT); #endif + #ifdef VK_EXT_multi_draw + VULKAN_FN(vkCmdDrawMultiEXT); + VULKAN_FN(vkCmdDrawMultiIndexedEXT); + #endif + #ifdef VK_EXT_shader_module_identifier VULKAN_FN(vkGetShaderModuleCreateInfoIdentifierEXT); VULKAN_FN(vkGetShaderModuleIdentifierEXT);