diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 3e26d7cac..ca225673c 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -974,6 +974,12 @@ void GPU::WriteGP1(u32 value) new_GPUSTAT.reverse_flag = dm.reverse_flag; Log_DebugPrintf("Set display mode <- 0x%08X", dm.bits); + if (!m_GPUSTAT.vertical_interlace && dm.vertical_interlace && !m_force_progressive_scan) + { + // bit of a hack, technically we should pull the previous frame in, but this may not exist anymore + ClearDisplay(); + } + if (m_GPUSTAT.bits != new_GPUSTAT.bits) { // Have to be careful when setting this because Synchronize() can modify GPUSTAT. @@ -1069,6 +1075,8 @@ void GPU::HandleGetGPUInfoCommand(u32 value) } } +void GPU::ClearDisplay() {} + void GPU::UpdateDisplay() {} void GPU::ReadVRAM(u32 x, u32 y, u32 width, u32 height) {} diff --git a/src/core/gpu.h b/src/core/gpu.h index a8572aa36..239bcbbde 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -427,6 +427,7 @@ protected: virtual void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height); virtual void DispatchRenderCommand(); virtual void FlushRender(); + virtual void ClearDisplay(); virtual void UpdateDisplay(); virtual void DrawRendererStats(bool is_idle_frame); diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index a08280c68..dbc2cef07 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -549,6 +549,14 @@ void GPU_HW_D3D11::SetScissorFromDrawingArea() m_context->RSSetScissorRects(1, &rc); } +void GPU_HW_D3D11::ClearDisplay() +{ + GPU_HW::ClearDisplay(); + + static constexpr std::array clear_color = { 0.0f, 0.0f, 0.0f, 1.0f }; + m_context->ClearRenderTargetView(m_display_texture.GetD3DRTV(), clear_color.data()); +} + void GPU_HW_D3D11::UpdateDisplay() { GPU_HW::UpdateDisplay(); diff --git a/src/core/gpu_hw_d3d11.h b/src/core/gpu_hw_d3d11.h index 8c402633a..7a0b45e03 100644 --- a/src/core/gpu_hw_d3d11.h +++ b/src/core/gpu_hw_d3d11.h @@ -27,6 +27,7 @@ public: void UpdateSettings() override; protected: + void ClearDisplay() override; void UpdateDisplay() override; void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override; void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override; diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 95fedac64..b40324546 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -560,6 +560,18 @@ void GPU_HW_OpenGL::UploadUniformBuffer(const void* data, u32 data_size) m_renderer_stats.num_uniform_buffer_updates++; } +void GPU_HW_OpenGL::ClearDisplay() +{ + GPU_HW::ClearDisplay(); + + m_display_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER); + glDisable(GL_SCISSOR_TEST); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_SCISSOR_TEST); + m_vram_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER); +} + void GPU_HW_OpenGL::UpdateDisplay() { GPU_HW::UpdateDisplay(); diff --git a/src/core/gpu_hw_opengl.h b/src/core/gpu_hw_opengl.h index f725be305..3e8720b06 100644 --- a/src/core/gpu_hw_opengl.h +++ b/src/core/gpu_hw_opengl.h @@ -23,6 +23,7 @@ public: void UpdateSettings() override; protected: + void ClearDisplay() override; void UpdateDisplay() override; void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override; void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override; diff --git a/src/core/gpu_hw_vulkan.cpp b/src/core/gpu_hw_vulkan.cpp index f3a6f327b..208c423a9 100644 --- a/src/core/gpu_hw_vulkan.cpp +++ b/src/core/gpu_hw_vulkan.cpp @@ -467,6 +467,7 @@ bool GPU_HW_Vulkan::CreateFramebuffer() old_vram_texture.Destroy(true); } + ClearDisplay(); SetFullVRAMDirtyRectangle(); return true; } @@ -888,6 +889,18 @@ void GPU_HW_Vulkan::SetScissorFromDrawingArea() Vulkan::Util::SetScissor(g_vulkan_context->GetCurrentCommandBuffer(), left, top, right - left, bottom - top); } +void GPU_HW_Vulkan::ClearDisplay() +{ + GPU_HW::ClearDisplay(); + + VkCommandBuffer cmdbuf = g_vulkan_context->GetCurrentCommandBuffer(); + m_display_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + static const VkClearColorValue cc = {0.0f, 0.0f, 0.0f, 1.0f}; + static const VkImageSubresourceRange srr = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + vkCmdClearColorImage(cmdbuf, m_display_texture.GetImage(), m_display_texture.GetLayout(), &cc, 1, &srr); +} + void GPU_HW_Vulkan::UpdateDisplay() { GPU_HW::UpdateDisplay(); diff --git a/src/core/gpu_hw_vulkan.h b/src/core/gpu_hw_vulkan.h index c4815f7e9..24a6863c0 100644 --- a/src/core/gpu_hw_vulkan.h +++ b/src/core/gpu_hw_vulkan.h @@ -22,6 +22,7 @@ public: void UpdateSettings() override; protected: + void ClearDisplay() override; void UpdateDisplay() override; void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override; void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override; diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index c68a4f975..928cfdde6 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -142,6 +142,11 @@ void GPU_SW::CopyOut24Bit(u32 src_x, u32 src_y, u32* dst_ptr, u32 dst_stride, u3 } } +void GPU_SW::ClearDisplay() +{ + std::memset(m_display_texture_buffer.data(), 0, sizeof(u32) * m_display_texture_buffer.size()); +} + void GPU_SW::UpdateDisplay() { // fill display texture diff --git a/src/core/gpu_sw.h b/src/core/gpu_sw.h index f6940aa74..a9113e2fb 100644 --- a/src/core/gpu_sw.h +++ b/src/core/gpu_sw.h @@ -51,6 +51,7 @@ protected: bool interleaved); void CopyOut24Bit(u32 src_x, u32 src_y, u32* dst_ptr, u32 dst_stride, u32 width, u32 height, bool interlaced, bool interleaved); + void ClearDisplay() override; void UpdateDisplay() override; //////////////////////////////////////////////////////////////////////////