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