From 7159330f63f92d178169fc2220c6778657e705c0 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 8 Mar 2024 13:43:20 +1000 Subject: [PATCH] GPU/HW: Ensure buffers are unmapped before present Darn DX11... --- src/core/gpu.cpp | 4 ++++ src/core/gpu_hw.cpp | 13 +++++++++---- src/util/d3d11_device.cpp | 2 ++ src/util/d3d11_stream_buffer.cpp | 6 ++++++ src/util/d3d11_stream_buffer.h | 2 ++ 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index a07140aad..85b5f2008 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -76,6 +76,8 @@ bool GPU::Initialize() void GPU::UpdateSettings(const Settings& old_settings) { + FlushRender(); + m_force_progressive_scan = g_settings.gpu_disable_interlacing; m_fifo_size = g_settings.gpu_fifo_size; m_max_run_ahead = g_settings.gpu_max_run_ahead; @@ -1665,6 +1667,8 @@ void GPU::SetDisplayParameters(s32 display_width, s32 display_height, s32 active bool GPU::PresentDisplay() { + FlushRender(); + if (!HasDisplayTexture()) return g_gpu_device->BeginPresent(false); diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 7ef0702b1..a9d07dfa0 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -713,6 +713,10 @@ void GPU_HW::DestroyBuffers() { ClearDisplayTexture(); + DebugAssert((m_batch_vertex_ptr != nullptr) == (m_batch_index_ptr != nullptr)); + if (m_batch_vertex_ptr) + UnmapGPUBuffer(0, 0); + m_vram_upload_buffer.reset(); m_vram_readback_download_texture.reset(); g_gpu_device->RecycleTexture(std::move(m_downsample_texture)); @@ -3054,13 +3058,14 @@ void GPU_HW::DispatchRenderCommand() void GPU_HW::FlushRender() { - if (m_batch_index_count == 0) - return; - const u32 base_vertex = m_batch_base_vertex; const u32 base_index = m_batch_base_index; const u32 index_count = m_batch_index_count; - UnmapGPUBuffer(m_batch_vertex_count, m_batch_index_count); + DebugAssert((m_batch_vertex_ptr != nullptr) == (m_batch_index_ptr != nullptr)); + if (m_batch_vertex_ptr) + UnmapGPUBuffer(m_batch_vertex_count, index_count); + if (index_count == 0) + return; #ifdef _DEBUG GL_SCOPE_FMT("Hardware Draw {}", ++s_draw_number); diff --git a/src/util/d3d11_device.cpp b/src/util/d3d11_device.cpp index 9a98178f1..b78119af5 100644 --- a/src/util/d3d11_device.cpp +++ b/src/util/d3d11_device.cpp @@ -1046,12 +1046,14 @@ void D3D11Device::SetScissor(s32 x, s32 y, s32 width, s32 height) void D3D11Device::Draw(u32 vertex_count, u32 base_vertex) { + DebugAssert(!m_vertex_buffer.IsMapped() && !m_index_buffer.IsMapped()); s_stats.num_draws++; m_context->Draw(vertex_count, base_vertex); } void D3D11Device::DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) { + DebugAssert(!m_vertex_buffer.IsMapped() && !m_index_buffer.IsMapped()); s_stats.num_draws++; m_context->DrawIndexed(index_count, base_index, base_vertex); } diff --git a/src/util/d3d11_stream_buffer.cpp b/src/util/d3d11_stream_buffer.cpp index ebf43b271..6dfc85c2d 100644 --- a/src/util/d3d11_stream_buffer.cpp +++ b/src/util/d3d11_stream_buffer.cpp @@ -74,6 +74,8 @@ void D3D11StreamBuffer::Destroy() D3D11StreamBuffer::MappingResult D3D11StreamBuffer::Map(ID3D11DeviceContext1* context, u32 alignment, u32 min_size) { + DebugAssert(!m_mapped); + m_position = Common::AlignUp(m_position, alignment); if ((m_position + min_size) >= m_size || !m_use_map_no_overwrite) { @@ -91,12 +93,16 @@ D3D11StreamBuffer::MappingResult D3D11StreamBuffer::Map(ID3D11DeviceContext1* co Panic("Map failed"); } + m_mapped = true; return MappingResult{static_cast(sr.pData) + m_position, m_position, m_position / alignment, (m_size - m_position) / alignment}; } void D3D11StreamBuffer::Unmap(ID3D11DeviceContext1* context, u32 used_size) { + DebugAssert(m_mapped); + context->Unmap(m_buffer.Get(), 0); m_position += used_size; + m_mapped = false; } diff --git a/src/util/d3d11_stream_buffer.h b/src/util/d3d11_stream_buffer.h index 92dc68158..b21a34022 100644 --- a/src/util/d3d11_stream_buffer.h +++ b/src/util/d3d11_stream_buffer.h @@ -23,6 +23,7 @@ public: ALWAYS_INLINE ID3D11Buffer* const* GetD3DBufferArray() const { return m_buffer.GetAddressOf(); } ALWAYS_INLINE u32 GetSize() const { return m_size; } ALWAYS_INLINE u32 GetPosition() const { return m_position; } + ALWAYS_INLINE bool IsMapped() const { return m_mapped; } bool Create(ID3D11Device* device, D3D11_BIND_FLAG bind_flags, u32 size); void Destroy(); @@ -43,4 +44,5 @@ private: u32 m_size; u32 m_position; bool m_use_map_no_overwrite = false; + bool m_mapped = false; };