[d3d11] Synchronize with CS thread before present

Fixes flickering by synchronizing with the presenter. This has
to do for now, a more efficient solution can be added later.
This commit is contained in:
Philip Rebohle 2018-01-21 18:04:22 +01:00
parent 7c3a9beb22
commit 07f5a7f069
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 24 additions and 18 deletions

View File

@ -15,8 +15,8 @@ namespace dxvk {
D3D11ImmediateContext::~D3D11ImmediateContext() {
Flush();
SynchronizeCs();
Synchronize();
SynchronizeCsThread();
SynchronizeDevice();
}
@ -114,15 +114,14 @@ namespace dxvk {
} else if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) {
// Synchronize with CS thread so that we know whether
// the buffer is currently in use by the GPU or not
SynchronizeCs();
SynchronizeCsThread();
if (buffer->isInUse()) {
if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT)
return DXGI_ERROR_WAS_STILL_DRAWING;
Flush();
SynchronizeCs();
Synchronize();
SynchronizeDevice();
}
}
@ -200,8 +199,8 @@ namespace dxvk {
});
Flush();
SynchronizeCs();
Synchronize();
SynchronizeCsThread();
SynchronizeDevice();
physicalSlice = textureInfo->imageBuffer->slice();
}
@ -249,7 +248,16 @@ namespace dxvk {
}
void D3D11ImmediateContext::Synchronize() {
void D3D11ImmediateContext::SynchronizeCsThread() {
// Dispatch current chunk so that all commands
// recorded prior to this function will be run
EmitCsChunk();
m_csThread.synchronize();
}
void D3D11ImmediateContext::SynchronizeDevice() {
// FIXME waiting until the device finished executing *all*
// pending commands is too pessimistic. Instead we should
// wait for individual command submissions to complete.
@ -258,13 +266,6 @@ namespace dxvk {
}
void D3D11ImmediateContext::SynchronizeCs() {
EmitCsChunk();
m_csThread.synchronize();
}
void D3D11ImmediateContext::EmitCsChunk() {
if (m_csChunk->commandCount() > 0)
m_csChunk = m_csThread.dispatchChunk(std::move(m_csChunk));

View File

@ -42,13 +42,13 @@ namespace dxvk {
ID3D11Resource* pResource,
UINT Subresource) final;
void SynchronizeCsThread();
private:
DxvkCsThread m_csThread;
void Synchronize();
void SynchronizeCs();
void SynchronizeDevice();
void EmitCsChunk();

View File

@ -1,4 +1,5 @@
#include "d3d11_device.h"
#include "d3d11_context_imm.h"
#include "d3d11_present.h"
namespace dxvk {
@ -57,7 +58,11 @@ namespace dxvk {
Com<ID3D11DeviceContext> deviceContext = nullptr;
m_device->GetImmediateContext(&deviceContext);
deviceContext->Flush();
// The presentation code is run from the main rendering thread
// rather than the command stream thread, so we synchronize.
auto immediateContext = static_cast<D3D11ImmediateContext*>(deviceContext.ptr());
immediateContext->Flush();
immediateContext->SynchronizeCsThread();
return S_OK;
}