From 4d974685c9c26e41df4406f9fbf30ce46c9234f6 Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Sun, 17 Sep 2023 21:53:12 +0300 Subject: [PATCH] [d3d9] Mark presenter for recreation on device reset with deferSurfaceCreation --- src/d3d9/d3d9_device.cpp | 3 +++ src/d3d9/d3d9_device.h | 7 +++++++ src/d3d9/d3d9_swapchain.cpp | 2 ++ 3 files changed, 12 insertions(+) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index a2f6e9c3..30a4a5b2 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -482,6 +482,9 @@ namespace dxvk { Flush(); SynchronizeCsThread(DxvkCsThread::SynchronizeAll); + if (m_d3d9Options.deferSurfaceCreation) + m_deviceHasBeenReset = true; + return D3D_OK; } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index b4a29285..99a2a743 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1033,6 +1033,12 @@ namespace dxvk { bool CanSWVP() const { return m_behaviorFlags & (D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING); } + + // Device Reset detection for D3D9SwapChainEx::Present + bool IsDeviceReset() { + return std::exchange(m_deviceHasBeenReset, false); + } + void DetermineConstantLayouts(bool canSWVP); D3D9BufferSlice AllocUPBuffer(VkDeviceSize size); @@ -1337,6 +1343,7 @@ namespace dxvk { VkImageLayout m_hazardLayout = VK_IMAGE_LAYOUT_GENERAL; bool m_usingGraphicsPipelines = false; + bool m_deviceHasBeenReset = false; DxvkDepthBiasRepresentation m_depthBiasRepresentation = { VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT, false }; float m_depthBiasScale = 0.0f; diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 9e950be0..1d9c50c1 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -147,6 +147,8 @@ namespace dxvk { bool recreate = false; recreate |= m_wctx->presenter == nullptr; recreate |= m_dialog != m_lastDialog; + if (options->deferSurfaceCreation) + recreate |= m_parent->IsDeviceReset(); if (m_wctx->presenter != nullptr) { m_dirty |= m_wctx->presenter->setSyncInterval(presentInterval) != VK_SUCCESS;