[dxvk] Limit size of the CS command queue

Prevents memory leaks and fixes stuttering in Heaven.
This commit is contained in:
Philip Rebohle 2018-01-21 00:49:07 +01:00
parent aaffc8e26f
commit b7a00e32ec
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 19 additions and 7 deletions

View File

@ -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([

View File

@ -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 = {

View File

@ -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();
}
}
}

View File

@ -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);