diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index cea209d9..1285c4ee 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -293,6 +293,11 @@ namespace dxvk { enabledFeatures.vk12.bufferDeviceAddress = VK_TRUE; } + // If we don't have pageable device memory support, at least use + // the legacy AMD extension to ensure we can oversubscribe VRAM + if (!m_deviceExtensions.supports(devExtensions.extPageableDeviceLocalMemory.name())) + devExtensions.amdMemoryOverallocationBehaviour.setMode(DxvkExtMode::Optional); + DxvkNameSet extensionsEnabled; if (!m_deviceExtensions.enableExtensions( @@ -387,9 +392,12 @@ namespace dxvk { m_deviceFeatures.extLineRasterization.smoothLines; } - // Enable memory priority if supported to improve memory management + // Enable memory priority and pageable memory if supported + // to improve driver-side memory management enabledFeatures.extMemoryPriority.memoryPriority = m_deviceFeatures.extMemoryPriority.memoryPriority; + enabledFeatures.extPageableDeviceLocalMemory.pageableDeviceLocalMemory = + m_deviceFeatures.extPageableDeviceLocalMemory.pageableDeviceLocalMemory; // Require robustBufferAccess2 since we use the robustness alignment // info in a number of places, and require null descriptor support @@ -588,6 +596,10 @@ namespace dxvk { enabledFeatures.extNonSeamlessCubeMap = *reinterpret_cast(f); break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT: + enabledFeatures.extPageableDeviceLocalMemory = *reinterpret_cast(f); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: enabledFeatures.extRobustness2 = *reinterpret_cast(f); break; @@ -876,6 +888,11 @@ namespace dxvk { m_deviceFeatures.extNonSeamlessCubeMap.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extNonSeamlessCubeMap); } + if (m_deviceExtensions.supports(VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME)) { + m_deviceFeatures.extPageableDeviceLocalMemory.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT; + m_deviceFeatures.extPageableDeviceLocalMemory.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extPageableDeviceLocalMemory); + } + if (m_deviceExtensions.supports(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) { m_deviceFeatures.extRobustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; m_deviceFeatures.extRobustness2.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extRobustness2); @@ -993,6 +1010,7 @@ namespace dxvk { &devExtensions.extMemoryBudget, &devExtensions.extMemoryPriority, &devExtensions.extNonSeamlessCubeMap, + &devExtensions.extPageableDeviceLocalMemory, &devExtensions.extRobustness2, &devExtensions.extShaderModuleIdentifier, &devExtensions.extShaderStencilExport, @@ -1094,9 +1112,9 @@ namespace dxvk { enabledFeatures.extNonSeamlessCubeMap.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extNonSeamlessCubeMap); } - if (devExtensions.extShaderModuleIdentifier) { - enabledFeatures.extShaderModuleIdentifier.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT; - enabledFeatures.extShaderModuleIdentifier.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderModuleIdentifier); + if (devExtensions.extPageableDeviceLocalMemory) { + enabledFeatures.extPageableDeviceLocalMemory.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT; + enabledFeatures.extPageableDeviceLocalMemory.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extPageableDeviceLocalMemory); } if (devExtensions.extRobustness2) { @@ -1104,6 +1122,11 @@ namespace dxvk { enabledFeatures.extRobustness2.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extRobustness2); } + if (devExtensions.extShaderModuleIdentifier) { + enabledFeatures.extShaderModuleIdentifier.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT; + enabledFeatures.extShaderModuleIdentifier.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderModuleIdentifier); + } + if (devExtensions.extShaderStencilExport) enabledFeatures.extShaderStencilExport = VK_TRUE; @@ -1275,6 +1298,8 @@ namespace dxvk { "\n memoryPriority : ", features.extMemoryPriority.memoryPriority ? "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, + "\n pageableDeviceLocalMemory : ", features.extPageableDeviceLocalMemory.pageableDeviceLocalMemory ? "1" : "0", "\n", VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, "\n robustBufferAccess2 : ", features.extRobustness2.robustBufferAccess2 ? "1" : "0", "\n robustImageAccess2 : ", features.extRobustness2.robustImageAccess2 ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 0c4c4e4c..87f444a9 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -59,6 +59,7 @@ namespace dxvk { VkBool32 extMemoryBudget; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; + VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT extPageableDeviceLocalMemory; VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; VkBool32 extShaderStencilExport; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 20ea46ef..b8df6d1e 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -294,7 +294,7 @@ namespace dxvk { * used by DXVK if supported by the implementation. */ struct DxvkDeviceExtensions { - DxvkExt amdMemoryOverallocationBehaviour = { VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt amdMemoryOverallocationBehaviour = { VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME, DxvkExtMode::Disabled }; DxvkExt amdShaderFragmentMask = { VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extAttachmentFeedbackLoopLayout = { VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extConservativeRasterization = { VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, DxvkExtMode::Optional }; @@ -309,6 +309,7 @@ namespace dxvk { DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_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 }; DxvkExt extShaderModuleIdentifier = { VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 66ecf420..32928db7 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -1163,6 +1163,10 @@ namespace dxvk { return DxvkDeviceMemory(); } + // Technically redundant if EXT_memory_priority is also supported, but this shouldn't hurt + if (m_device->features().extPageableDeviceLocalMemory.pageableDeviceLocalMemory) + vk->vkSetDeviceMemoryPriorityEXT(vk->device(), result.memory, priorityInfo.priority); + // Create global buffer if the allocation supports it if (type.bufferUsage && !next) { VkBuffer buffer = VK_NULL_HANDLE; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 0445a654..61402fbd 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -401,6 +401,10 @@ namespace dxvk::vk { VULKAN_FN(vkSetHdrMetadataEXT); #endif + #ifdef VK_EXT_pageable_device_local_memory + VULKAN_FN(vkSetDeviceMemoryPriorityEXT); + #endif + #ifdef VK_EXT_shader_module_identifier VULKAN_FN(vkGetShaderModuleCreateInfoIdentifierEXT); VULKAN_FN(vkGetShaderModuleIdentifierEXT);