diff --git a/dxvk.conf b/dxvk.conf index bbebc70b700..8fc0ff4b738 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -546,3 +546,10 @@ # - True/False # dxvk.enableDebugUtils = False + +# Unmapping delay +# +# DXVK will unmap D3D9 managed data after a certain number of frames. +# 0 to disable unmapping. + +# d3d9.unmapDelay = 16 diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 3df702d187d..9cb10d68e24 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -501,6 +501,21 @@ namespace dxvk { return VK_IMAGE_LAYOUT_GENERAL; } + D3D9_COMMON_TEXTURE_MAP_MODE D3D9CommonTexture::DetermineMapMode() const { + if (m_desc.Format == D3D9Format::NULL_FORMAT) + return D3D9_COMMON_TEXTURE_MAP_MODE_NONE; + + if (m_desc.Pool == D3DPOOL_SYSTEMMEM || m_desc.Pool == D3DPOOL_SCRATCH) + return D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM; + +#ifdef D3D9_ALLOW_UNMAPPING + if (IsManaged() && m_device->GetOptions()->unmapDelay != 0) + return D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE; +#endif + + return D3D9_COMMON_TEXTURE_MAP_MODE_BACKED; +} + void D3D9CommonTexture::ExportImageInfo() { /* From MSDN: diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index ba81f75f592..35480bef8b6 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -570,20 +570,7 @@ namespace dxvk { VkFormat Format, VkImageTiling Tiling) const; - D3D9_COMMON_TEXTURE_MAP_MODE DetermineMapMode() const { - if (m_desc.Format == D3D9Format::NULL_FORMAT) - return D3D9_COMMON_TEXTURE_MAP_MODE_NONE; - - if (m_desc.Pool == D3DPOOL_SYSTEMMEM || m_desc.Pool == D3DPOOL_SCRATCH) - return D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM; - -#ifdef D3D9_ALLOW_UNMAPPING - if (IsManaged()) - return D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE; -#endif - - return D3D9_COMMON_TEXTURE_MAP_MODE_BACKED; - } + D3D9_COMMON_TEXTURE_MAP_MODE DetermineMapMode() const; VkImageLayout OptimizeLayout( VkImageUsageFlags Usage) const; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index d1db198f4f1..8d4f983a5fb 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -7415,9 +7415,12 @@ namespace dxvk { void D3D9DeviceEx::UnmapTextures() { // Will only be called inside the device lock #ifdef D3D9_USE_MEM_FILE_FOR_MANAGED + if (m_d3d9Options.unmapDelay == 0) + return; + const bool force = m_memoryAllocator.MappedMemory() > 512 << 20; for (auto iter = m_mappedTextures.begin(); iter != m_mappedTextures.end();) { - const bool mappingBufferUnused = (m_frameCounter - (*iter)->GetMappingFrame() > 16 || force) && !(*iter)->IsAnySubresourceLocked(); + const bool mappingBufferUnused = (m_frameCounter - (*iter)->GetMappingFrame() > uint32_t(m_d3d9Options.unmapDelay) || force) && !(*iter)->IsAnySubresourceLocked(); if (!mappingBufferUnused) { iter++; continue; diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index bc62e00891e..e901aed3301 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -72,6 +72,7 @@ namespace dxvk { this->apitraceMode = config.getOption ("d3d9.apitraceMode", false); this->deviceLocalConstantBuffers = config.getOption ("d3d9.deviceLocalConstantBuffers", false); this->allowDirectBufferMapping = config.getOption ("d3d9.allowDirectBufferMapping", true); + this->unmapDelay = config.getOption ("d3d9.unmapDelay", 16); // If we are not Nvidia, enable general hazards. this->generalHazards = adapter != nullptr diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 23c04f0c33e..0d5c5e0ec4c 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -154,6 +154,9 @@ namespace dxvk { /// Disable direct buffer mapping bool allowDirectBufferMapping; + + /// How many frames need to pass before managed data gets unmapped + int32_t unmapDelay; }; }