mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[d3d9] Unmap unused resources
This commit is contained in:
parent
b4f432f1de
commit
ea76bfd019
@ -560,3 +560,12 @@
|
||||
# - True/False
|
||||
|
||||
# dxvk.enableDebugUtils = False
|
||||
|
||||
# Memory limit for locked D3D9 textures
|
||||
#
|
||||
# How much virtual memory will be used for textures (in MB).
|
||||
# 0 to disable the limit.
|
||||
# THIS DOES NOT IMPACT ACTUAL MEMORY CONSUMPTION OR TEXTURE QUALITY.
|
||||
# DO NOT CHANGE THIS UNLESS YOU HAVE A VERY GOOD REASON.
|
||||
|
||||
# d3d9.textureMemory = 100
|
||||
|
@ -89,6 +89,8 @@ namespace dxvk {
|
||||
D3D9CommonTexture::~D3D9CommonTexture() {
|
||||
if (m_size != 0)
|
||||
m_device->ChangeReportedMemory(m_size);
|
||||
|
||||
m_device->RemoveMappedTexture(this);
|
||||
}
|
||||
|
||||
|
||||
@ -488,7 +490,7 @@ namespace dxvk {
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_NONE;
|
||||
|
||||
#ifdef D3D9_ALLOW_UNMAPPING
|
||||
if (m_desc.Pool != D3DPOOL_DEFAULT)
|
||||
if (m_device->GetOptions()->textureMemory != 0 && m_desc.Pool != D3DPOOL_DEFAULT)
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE;
|
||||
#endif
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "d3d9_device.h"
|
||||
|
||||
#include "d3d9_annotation.h"
|
||||
#include "d3d9_common_texture.h"
|
||||
#include "d3d9_interface.h"
|
||||
#include "d3d9_swapchain.h"
|
||||
#include "d3d9_caps.h"
|
||||
@ -4201,6 +4202,7 @@ namespace dxvk {
|
||||
pResource->GetBuffer(Subresource, !needsReadback);
|
||||
}
|
||||
|
||||
// Don't use MapTexture here to keep the mapped list small while the resource is still locked.
|
||||
mapPtr = pResource->GetData(Subresource);
|
||||
|
||||
if (needsReadback) {
|
||||
@ -4298,6 +4300,8 @@ namespace dxvk {
|
||||
|
||||
pResource->SetLocked(Subresource, true);
|
||||
|
||||
UnmapTextures();
|
||||
|
||||
const bool noDirtyUpdate = Flags & D3DLOCK_NO_DIRTY_UPDATE;
|
||||
if ((desc.Pool == D3DPOOL_DEFAULT || !noDirtyUpdate) && !readOnly) {
|
||||
if (pBox && MipLevel != 0) {
|
||||
@ -4354,6 +4358,7 @@ namespace dxvk {
|
||||
if (unlikely(!pResource->GetLocked(Subresource)))
|
||||
return D3D_OK;
|
||||
|
||||
MapTexture(pResource, Subresource); // Add it to the list of mapped resources
|
||||
pResource->SetLocked(Subresource, false);
|
||||
|
||||
// Flush image contents from staging if we aren't read only
|
||||
@ -4380,6 +4385,7 @@ namespace dxvk {
|
||||
pResource->SetNeedsReadback(Subresource, true);
|
||||
}
|
||||
|
||||
UnmapTextures();
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
@ -4463,7 +4469,7 @@ namespace dxvk {
|
||||
+ srcOffsetBlockCount.y * pitch
|
||||
+ srcOffsetBlockCount.x * formatInfo->elementSize;
|
||||
|
||||
const void* mapPtr = pSrcTexture->GetData(SrcSubresource);
|
||||
const void* mapPtr = MapTexture(pSrcTexture, SrcSubresource);
|
||||
VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize;
|
||||
D3D9BufferSlice slice = AllocStagingBuffer(dirtySize);
|
||||
const void* srcData = reinterpret_cast<const uint8_t*>(mapPtr) + copySrcOffset;
|
||||
@ -4489,7 +4495,7 @@ namespace dxvk {
|
||||
}
|
||||
else {
|
||||
const DxvkFormatInfo* formatInfo = lookupFormatInfo(pDestTexture->GetFormatMapping().FormatColor);
|
||||
const void* mapPtr = pSrcTexture->GetData(SrcSubresource);
|
||||
const void* mapPtr = MapTexture(pSrcTexture, SrcSubresource);
|
||||
|
||||
// Add more blocks for the other planes that we might have.
|
||||
// TODO: PLEASE CLEAN ME
|
||||
@ -4522,6 +4528,7 @@ namespace dxvk {
|
||||
image, dstLayers,
|
||||
slice.slice);
|
||||
}
|
||||
UnmapTextures();
|
||||
}
|
||||
|
||||
void D3D9DeviceEx::EmitGenerateMips(
|
||||
@ -4643,6 +4650,7 @@ namespace dxvk {
|
||||
pResource->SetMapFlags(Flags | oldFlags);
|
||||
pResource->IncrementLockCount();
|
||||
|
||||
UnmapTextures();
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
@ -4675,7 +4683,8 @@ namespace dxvk {
|
||||
pResource->DirtyRange().Clear();
|
||||
TrackBufferMappingBufferSequenceNumber(pResource);
|
||||
|
||||
return D3D_OK;
|
||||
UnmapTextures();
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -7223,4 +7232,61 @@ namespace dxvk {
|
||||
return m_csChunk->empty() ? m_csSeqNum : m_csSeqNum + 1;
|
||||
}
|
||||
|
||||
|
||||
void* D3D9DeviceEx::MapTexture(D3D9CommonTexture* pTexture, UINT Subresource) {
|
||||
// Will only be called inside the device lock
|
||||
void *ptr = pTexture->GetData(Subresource);
|
||||
|
||||
#ifdef D3D9_ALLOW_UNMAPPING
|
||||
if (likely(pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE)) {
|
||||
m_mappedTextures.insert(pTexture);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void D3D9DeviceEx::TouchMappedTexture(D3D9CommonTexture* pTexture) {
|
||||
#ifdef D3D9_ALLOW_UNMAPPING
|
||||
if (pTexture->GetMapMode() != D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE)
|
||||
return;
|
||||
|
||||
D3D9DeviceLock lock = LockDevice();
|
||||
m_mappedTextures.touch(pTexture);
|
||||
#endif
|
||||
}
|
||||
|
||||
void D3D9DeviceEx::RemoveMappedTexture(D3D9CommonTexture* pTexture) {
|
||||
#ifdef D3D9_ALLOW_UNMAPPING
|
||||
if (pTexture->GetMapMode() != D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE)
|
||||
return;
|
||||
|
||||
D3D9DeviceLock lock = LockDevice();
|
||||
m_mappedTextures.remove(pTexture);
|
||||
#endif
|
||||
}
|
||||
|
||||
void D3D9DeviceEx::UnmapTextures() {
|
||||
// Will only be called inside the device lock
|
||||
|
||||
#ifdef D3D9_ALLOW_UNMAPPING
|
||||
uint32_t mappedMemory = m_memoryAllocator.MappedMemory();
|
||||
if (likely(mappedMemory < uint32_t(m_d3d9Options.textureMemory)))
|
||||
return;
|
||||
|
||||
uint32_t threshold = (m_d3d9Options.textureMemory / 4) * 3;
|
||||
|
||||
auto iter = m_mappedTextures.leastRecentlyUsedIter();
|
||||
while (m_memoryAllocator.MappedMemory() >= threshold && iter != m_mappedTextures.leastRecentlyUsedEndIter()) {
|
||||
if (unlikely((*iter)->IsAnySubresourceLocked() != 0)) {
|
||||
iter++;
|
||||
continue;
|
||||
}
|
||||
(*iter)->UnmapData();
|
||||
|
||||
iter = m_mappedTextures.remove(iter);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,10 +28,13 @@
|
||||
|
||||
#include "d3d9_shader_permutations.h"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../util/util_lru.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D9InterfaceEx;
|
||||
@ -934,6 +937,10 @@ namespace dxvk {
|
||||
return &m_memoryAllocator;
|
||||
}
|
||||
|
||||
void* MapTexture(D3D9CommonTexture* pTexture, UINT Subresource);
|
||||
void TouchMappedTexture(D3D9CommonTexture* pTexture);
|
||||
void RemoveMappedTexture(D3D9CommonTexture* pTexture);
|
||||
|
||||
private:
|
||||
|
||||
DxvkCsChunkRef AllocCsChunk() {
|
||||
@ -1142,6 +1149,8 @@ namespace dxvk {
|
||||
D3D9CommonTexture* pResource,
|
||||
UINT Subresource);
|
||||
|
||||
void UnmapTextures();
|
||||
|
||||
uint64_t GetCurrentSequenceNumber();
|
||||
|
||||
Com<D3D9InterfaceEx> m_parent;
|
||||
@ -1282,6 +1291,9 @@ namespace dxvk {
|
||||
|
||||
Direct3DState9 m_state;
|
||||
|
||||
#ifdef D3D9_ALLOW_UNMAPPING
|
||||
lru_list<D3D9CommonTexture*> m_mappedTextures;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ namespace dxvk {
|
||||
this->deviceLocalConstantBuffers = config.getOption<bool> ("d3d9.deviceLocalConstantBuffers", false);
|
||||
this->allowDirectBufferMapping = config.getOption<bool> ("d3d9.allowDirectBufferMapping", true);
|
||||
this->seamlessCubes = config.getOption<bool> ("d3d9.seamlessCubes", false);
|
||||
this->textureMemory = config.getOption<int32_t> ("d3d9.textureMemory", 100) << 20;
|
||||
|
||||
// If we are not Nvidia, enable general hazards.
|
||||
this->generalHazards = adapter != nullptr
|
||||
|
@ -157,6 +157,9 @@ namespace dxvk {
|
||||
|
||||
/// Don't use non seamless cube maps
|
||||
bool seamlessCubes;
|
||||
|
||||
/// How much virtual memory will be used for textures (in MB).
|
||||
int32_t textureMemory;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ namespace dxvk {
|
||||
if (m_texture.IsManaged())
|
||||
m_texture.SetAllNeedUpload();
|
||||
|
||||
m_parent->TouchMappedTexture(&m_texture);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
@ -174,6 +175,7 @@ namespace dxvk {
|
||||
if (m_texture.IsManaged())
|
||||
m_texture.SetAllNeedUpload();
|
||||
|
||||
m_parent->TouchMappedTexture(&m_texture);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
@ -267,6 +269,7 @@ namespace dxvk {
|
||||
}
|
||||
}
|
||||
|
||||
m_parent->TouchMappedTexture(&m_texture);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user