diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 06fc4bc04..e2e017e52 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -103,6 +103,8 @@ namespace dxvk { void DxvkContext::flushCommandList(DxvkSubmitStatus* status) { + relocateQueuedResources(); + m_device->submitCommandList( this->endRecording(), status); @@ -6475,6 +6477,54 @@ namespace dxvk { } + void DxvkContext::relocateQueuedResources() { + auto resourceList = m_common->memoryManager().pollRelocationList(); + + if (resourceList.empty()) + return; + + std::vector bufferInfos; + std::vector imageInfos; + + // Iterate over resource list and try to create and assign new allocations + // for them based on the mode selected by the allocator. Failures here are + // not fatal, but may lead to weird behaviour down the line - ignore for now. + for (const auto& e : resourceList) { + auto storage = e.resource->relocateStorage(e.mode); + + if (!storage) + continue; + + Rc image = dynamic_cast(e.resource.ptr()); + Rc buffer = dynamic_cast(e.resource.ptr()); + + if (image) { + auto& e = imageInfos.emplace_back(); + e.image = std::move(image); + e.storage = std::move(storage); + } else if (buffer) { + auto& e = bufferInfos.emplace_back(); + e.buffer = std::move(buffer); + e.storage = std::move(storage); + } + } + + if (bufferInfos.empty() && imageInfos.empty()) + return; + + // If there are any resources to relocate, we have to stall the transfer + // queue so that subsequent resource uploads do not overlap with resource + // copies on the graphics timeline. + this->spillRenderPass(true); + + relocateResources( + bufferInfos.size(), bufferInfos.data(), + imageInfos.size(), imageInfos.data()); + + m_cmd->setSubmissionBarrier(); + } + + Rc DxvkContext::createBlitSampler( VkFilter filter) { DxvkSamplerKey samplerKey; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c26788493..28c2e0a91 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1757,6 +1757,8 @@ namespace dxvk { size_t imageCount, const DxvkRelocateImageInfo* imageInfos); + void relocateQueuedResources(); + Rc createBlitSampler( VkFilter filter);