1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-22 16:54:27 +01:00

[d3d11] Throttle resource uploads via UpdateSubresource

Otherwise, some games (e.g. Frostpunk, New World) end up allocating over
a gigabyte of staging memory.
This commit is contained in:
Philip Rebohle 2024-10-07 15:11:37 +02:00 committed by Philip Rebohle
parent ec18dd7846
commit df60a061a4
3 changed files with 40 additions and 3 deletions

View File

@ -3010,6 +3010,9 @@ namespace dxvk {
CopyTiledResourceData(pDestTiledResource, CopyTiledResourceData(pDestTiledResource,
pDestTileRegionStartCoordinate, pDestTileRegionStartCoordinate,
pDestTileRegionSize, slice, Flags); pDestTileRegionSize, slice, Flags);
if constexpr (!IsDeferred)
static_cast<ContextType*>(this)->ThrottleAllocation();
} }
@ -5099,6 +5102,9 @@ namespace dxvk {
if (pDstBuffer->HasSequenceNumber()) if (pDstBuffer->HasSequenceNumber())
GetTypedContext()->TrackBufferSequenceNumber(pDstBuffer); GetTypedContext()->TrackBufferSequenceNumber(pDstBuffer);
if constexpr (!IsDeferred)
static_cast<ContextType*>(this)->ThrottleAllocation();
} }
@ -5151,6 +5157,9 @@ namespace dxvk {
UpdateImage(pDstTexture, &subresource, UpdateImage(pDstTexture, &subresource,
offset, extent, std::move(stagingSlice)); offset, extent, std::move(stagingSlice));
if constexpr (!IsDeferred)
static_cast<ContextType*>(this)->ThrottleAllocation();
} }

View File

@ -20,6 +20,7 @@ namespace dxvk {
m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize), m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize),
m_submissionFence(new sync::CallbackFence()), m_submissionFence(new sync::CallbackFence()),
m_flushTracker(pParent->GetOptions()->reproducibleCommandStream), m_flushTracker(pParent->GetOptions()->reproducibleCommandStream),
m_stagingBufferFence(new sync::Fence(0)),
m_multithread(this, false, pParent->GetOptions()->enableContextLock), m_multithread(this, false, pParent->GetOptions()->enableContextLock),
m_videoContext(this, Device) { m_videoContext(this, Device) {
EmitCs([ EmitCs([
@ -956,9 +957,12 @@ namespace dxvk {
EmitCs<false>([ EmitCs<false>([
cSubmissionFence = m_submissionFence, cSubmissionFence = m_submissionFence,
cSubmissionId = submissionId, cSubmissionId = submissionId,
cSubmissionStatus = synchronizeSubmission ? &m_submitStatus : nullptr cSubmissionStatus = synchronizeSubmission ? &m_submitStatus : nullptr,
cStagingFence = m_stagingBufferFence,
cStagingMemory = m_staging.getStatistics().allocatedTotal
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
ctx->signal(cSubmissionFence, cSubmissionId); ctx->signal(cSubmissionFence, cSubmissionId);
ctx->signal(cStagingFence, cStagingMemory);
ctx->flushCommandList(cSubmissionStatus); ctx->flushCommandList(cSubmissionStatus);
}); });
@ -978,4 +982,24 @@ namespace dxvk {
ResetStagingBuffer(); ResetStagingBuffer();
} }
void D3D11ImmediateContext::ThrottleAllocation() {
DxvkStagingBufferStats stats = m_staging.getStatistics();
VkDeviceSize stagingMemoryInFlight = stats.allocatedTotal - m_stagingBufferFence->value();
if (stagingMemoryInFlight > stats.allocatedSinceLastReset + D3D11Initializer::MaxMemoryInFlight) {
// Stall calling thread to avoid situation where we keep growing the staging
// buffer indefinitely, but ignore the newly allocated amount so that we don't
// wait for the GPU to go fully idle in case of a large allocation.
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, false);
m_stagingBufferFence->wait(stats.allocatedTotal - stats.allocatedSinceLastReset - D3D11Initializer::MaxMemoryInFlight);
} else if (stats.allocatedSinceLastReset >= D3D11Initializer::MaxMemoryPerSubmission) {
// Flush somewhat aggressively if there's a lot of memory in flight
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, false);
}
}
} }

View File

@ -126,6 +126,8 @@ namespace dxvk {
uint64_t m_flushSeqNum = 0ull; uint64_t m_flushSeqNum = 0ull;
GpuFlushTracker m_flushTracker; GpuFlushTracker m_flushTracker;
Rc<sync::Fence> m_stagingBufferFence;
D3D10Multithread m_multithread; D3D10Multithread m_multithread;
D3D11VideoContext m_videoContext; D3D11VideoContext m_videoContext;
@ -195,6 +197,8 @@ namespace dxvk {
HANDLE hEvent, HANDLE hEvent,
BOOL Synchronize); BOOL Synchronize);
void ThrottleAllocation();
}; };
} }