mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 22:24:15 +01:00
[dxvk] Limit size of the CS command queue
Prevents memory leaks and fixes stuttering in Heaven.
This commit is contained in:
parent
aaffc8e26f
commit
b7a00e32ec
@ -565,6 +565,8 @@ namespace dxvk {
|
||||
if (((size == bufferSlice.length())
|
||||
&& (bufferSlice.buffer()->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) {
|
||||
auto physicalSlice = bufferSlice.buffer()->allocPhysicalSlice();
|
||||
physicalSlice.resource()->acquire();
|
||||
|
||||
std::memcpy(physicalSlice.mapPtr(0), pSrcData, size);
|
||||
|
||||
EmitCs([
|
||||
@ -572,6 +574,7 @@ namespace dxvk {
|
||||
cPhysicalSlice = std::move(physicalSlice)
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->invalidateBuffer(cDstBuffer, cPhysicalSlice);
|
||||
cPhysicalSlice.resource()->release();
|
||||
});
|
||||
} else {
|
||||
EmitCs([
|
||||
|
@ -98,6 +98,8 @@ namespace dxvk {
|
||||
// it as the 'new' mapped slice. This assumes that the
|
||||
// only way to invalidate a buffer is by mapping it.
|
||||
auto physicalSlice = buffer->allocPhysicalSlice();
|
||||
physicalSlice.resource()->acquire();
|
||||
|
||||
resource->GetBufferInfo()->mappedSlice = physicalSlice;
|
||||
|
||||
EmitCs([
|
||||
@ -105,6 +107,7 @@ namespace dxvk {
|
||||
cPhysicalSlice = physicalSlice
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->invalidateBuffer(cBuffer, cPhysicalSlice);
|
||||
cPhysicalSlice.resource()->release();
|
||||
});
|
||||
} else if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) {
|
||||
// Synchronize with CS thread so that we know whether
|
||||
@ -167,12 +170,14 @@ namespace dxvk {
|
||||
// to be preserved, copy the image's contents into the buffer.
|
||||
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
||||
physicalSlice = textureInfo->imageBuffer->allocPhysicalSlice();
|
||||
physicalSlice.resource()->acquire();
|
||||
|
||||
EmitCs([
|
||||
cImageBuffer = textureInfo->imageBuffer,
|
||||
cPhysicalSlice = physicalSlice
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->invalidateBuffer(cImageBuffer, cPhysicalSlice);
|
||||
cPhysicalSlice.resource()->release();
|
||||
});
|
||||
} else {
|
||||
const VkImageSubresourceLayers subresourceLayers = {
|
||||
|
@ -44,6 +44,10 @@ namespace dxvk {
|
||||
{ std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_chunks.push(std::move(chunk));
|
||||
m_chunksPending += 1;
|
||||
|
||||
m_condOnSync.wait(lock, [this] {
|
||||
return m_stopped.load() || (m_chunksPending < MaxChunksInFlight);
|
||||
});
|
||||
}
|
||||
|
||||
m_condOnAdd.notify_one();
|
||||
@ -78,13 +82,11 @@ namespace dxvk {
|
||||
if (chunk != nullptr) {
|
||||
chunk->executeAll(m_context.ptr());
|
||||
|
||||
const bool doNotify = [this] {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
return --m_chunksPending == 0;
|
||||
}();
|
||||
{ std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_chunksPending -= 1;
|
||||
}
|
||||
|
||||
if (doNotify)
|
||||
m_condOnSync.notify_one();
|
||||
m_condOnSync.notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,9 @@ namespace dxvk {
|
||||
* commands on a DXVK context.
|
||||
*/
|
||||
class DxvkCsThread {
|
||||
|
||||
// Limit the number of chunks in the queue
|
||||
// to prevent memory leaks, stuttering etc.
|
||||
constexpr static uint32_t MaxChunksInFlight = 128;
|
||||
public:
|
||||
|
||||
DxvkCsThread(const Rc<DxvkContext>& context);
|
||||
|
Loading…
Reference in New Issue
Block a user