GPU: Claer interlaced field buffer when enabling

Fixes old frames getting briefly displayed.
This commit is contained in:
Connor McLaughlin 2020-08-03 03:26:11 +10:00
parent 23df239469
commit 818892cb1b
10 changed files with 51 additions and 0 deletions

View file

@ -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) {}

View file

@ -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);

View file

@ -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<float, 4> 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();

View file

@ -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;

View file

@ -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();

View file

@ -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;

View file

@ -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();

View file

@ -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;

View file

@ -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

View file

@ -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;
//////////////////////////////////////////////////////////////////////////