1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-18 20:52:10 +01:00

[d3d11] Don't immediately synchronize after present

This will actually enable asynchronous presentation.
Improves performance in Quake Champions.
This commit is contained in:
Philip Rebohle 2019-07-05 14:59:24 +02:00
parent 77db8158c8
commit c631953ab6
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 38 additions and 8 deletions

View File

@ -34,6 +34,7 @@ namespace dxvk {
InitRenderState();
InitSamplers();
InitShaders();
InitOptions();
}
@ -194,8 +195,7 @@ namespace dxvk {
void D3D11SwapChain::PresentImage(UINT SyncInterval) {
// Wait for the sync event so that we
// respect the maximum frame latency
// Wait for the sync event so that we respect the maximum frame latency
Rc<DxvkEvent> syncEvent = m_dxgiDevice->GetFrameSyncEvent(m_desc.BufferCount);
syncEvent->wait();
@ -203,6 +203,9 @@ namespace dxvk {
m_hud->update();
for (uint32_t i = 0; i < SyncInterval || i < 1; i++) {
if (m_asyncPresent)
SynchronizePresent();
m_context->beginRecording(
m_device->createCommandList());
@ -309,15 +312,26 @@ namespace dxvk {
m_device->presentImage(m_presenter,
sync.present, &m_presentStatus);
status = m_device->waitForSubmission(&m_presentStatus);
if (status != VK_SUCCESS)
RecreateSwapChain(m_vsync);
if (!m_asyncPresent)
SynchronizePresent();
}
}
void D3D11SwapChain::SynchronizePresent() {
// Recreate swap chain if the previous present call failed
VkResult status = m_device->waitForSubmission(&m_presentStatus);
if (status != VK_SUCCESS)
RecreateSwapChain(m_vsync);
}
void D3D11SwapChain::RecreateSwapChain(BOOL Vsync) {
// Ensure that we can safely destroy the swap chain
m_device->waitForSubmission(&m_presentStatus);
m_presentStatus.result = VK_SUCCESS;
vk::PresenterDesc presenterDesc;
presenterDesc.imageExtent = { m_desc.Width, m_desc.Height };
presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1);
@ -582,6 +596,16 @@ namespace dxvk {
}
void D3D11SwapChain::InitOptions() {
// Not synchronizing after present seems to increase
// the likelyhood of hangs on Nvidia for some reason.
m_asyncPresent = !m_device->adapter()->matchesDriver(
DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0);
applyTristate(m_asyncPresent, m_parent->GetOptions()->asyncPresent);
}
void D3D11SwapChain::InitRenderState() {
m_iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
m_iaState.primitiveRestart = VK_FALSE;

View File

@ -120,8 +120,12 @@ namespace dxvk {
bool m_dirty = true;
bool m_vsync = true;
bool m_asyncPresent = false;
void PresentImage(UINT SyncInterval);
void SynchronizePresent();
void FlushImmediateContext();
void RecreateSwapChain(
@ -141,6 +145,8 @@ namespace dxvk {
void CreateHud();
void InitOptions();
void InitRenderState();
void InitSamplers();