GPU: Insert null field buffer if display disabled

Don't throw away all buffers. 240p Test Suite flips display disabled
during vblank every frame.
This commit is contained in:
Stenzek
2025-11-05 16:03:17 +10:00
parent f9cab709bd
commit dd0c7ec9fe
4 changed files with 38 additions and 16 deletions

View File

@@ -1512,9 +1512,6 @@ void GPU::WriteGP1(u32 value)
DEBUG_LOG("Display {}", disable ? "disabled" : "enabled");
SynchronizeCRTC();
if (!m_GPUSTAT.display_disable && disable && IsInterlacedDisplayEnabled())
ClearDisplay();
m_GPUSTAT.display_disable = disable;
}
break;

View File

@@ -3976,6 +3976,9 @@ void GPU_HW::UpdateDisplay(const GPUBackendUpdateDisplayCommand* cmd)
if (cmd->display_disabled)
{
m_presenter.ClearDisplayTexture();
if (interlaced)
m_presenter.Deinterlace(interlaced_field);
return;
}
else if (!cmd->display_24bit && line_skip == 0 && !IsUsingMultisampling() &&

View File

@@ -1006,13 +1006,16 @@ void GPUPresenter::DestroyDeinterlaceTextures()
bool GPUPresenter::Deinterlace(u32 field)
{
GPUTexture* src = m_display_texture;
GPUTexture* const src = m_display_texture;
if (src)
src->MakeReadyForSampling();
const u32 x = m_display_texture_view_x;
const u32 y = m_display_texture_view_y;
const u32 width = m_display_texture_view_width;
const u32 height = m_display_texture_view_height;
const auto copy_to_field_buffer = [&](u32 buffer) {
const auto copy_to_field_buffer = [this, &src, &x, &y, &width, &height](u32 buffer) {
if (!g_gpu_device->ResizeTexture(&m_deinterlace_buffers[buffer], width, height, GPUTexture::Type::Texture,
src->GetFormat(), GPUTexture::Flags::None, false)) [[unlikely]]
{
@@ -1027,8 +1030,6 @@ bool GPUPresenter::Deinterlace(u32 field)
return true;
};
src->MakeReadyForSampling();
switch (g_gpu_settings.display_deinterlacing_mode)
{
case DisplayDeinterlacingMode::Disabled:
@@ -1072,13 +1073,20 @@ bool GPUPresenter::Deinterlace(u32 field)
const u32 this_buffer = m_current_deinterlace_buffer;
m_current_deinterlace_buffer = (m_current_deinterlace_buffer + 1u) % NUM_BLEND_BUFFERS;
GL_INS_FMT("Current buffer: {}", this_buffer);
if (!DeinterlaceSetTargetSize(width, height, false) || !copy_to_field_buffer(this_buffer)) [[unlikely]]
if (src)
{
ClearDisplayTexture();
return false;
if (!DeinterlaceSetTargetSize(width, height, false) || !copy_to_field_buffer(this_buffer))
{
ClearDisplayTexture();
return false;
}
}
else
{
// Clear the buffer, make it sample black.
GL_INS("No source texture, clearing deinterlace buffer");
g_gpu_device->RecycleTexture(std::move(m_deinterlace_buffers[this_buffer]));
}
copy_to_field_buffer(this_buffer);
// TODO: could be implemented with alpha blending instead..
g_gpu_device->InvalidateRenderTarget(m_deinterlace_texture.get());
@@ -1103,10 +1111,20 @@ bool GPUPresenter::Deinterlace(u32 field)
const u32 full_height = height * 2;
m_current_deinterlace_buffer = (m_current_deinterlace_buffer + 1u) % DEINTERLACE_BUFFER_COUNT;
GL_INS_FMT("Current buffer: {}", this_buffer);
if (!DeinterlaceSetTargetSize(width, full_height, false) || !copy_to_field_buffer(this_buffer)) [[unlikely]]
if (src)
{
ClearDisplayTexture();
return false;
if (!DeinterlaceSetTargetSize(width, full_height, false) || !copy_to_field_buffer(this_buffer)) [[unlikely]]
{
ClearDisplayTexture();
return false;
}
}
else
{
// Clear the buffer, make it sample black.
GL_INS("No source texture, clearing deinterlace buffer");
g_gpu_device->RecycleTexture(std::move(m_deinterlace_buffers[this_buffer]));
}
g_gpu_device->SetRenderTarget(m_deinterlace_texture.get());

View File

@@ -385,14 +385,18 @@ void GPU_SW::UpdateDisplay(const GPUBackendUpdateDisplayCommand* cmd)
{
if (!g_gpu_settings.gpu_show_vram)
{
const u32 field = BoolToUInt32(cmd->interlaced_display_field);
if (cmd->display_disabled)
{
m_presenter.ClearDisplayTexture();
if (cmd->interlaced_display_enabled)
m_presenter.Deinterlace(field);
return;
}
const bool is_24bit = cmd->display_24bit;
const u32 field = BoolToUInt32(cmd->interlaced_display_field);
const u32 line_skip = BoolToUInt32(cmd->interlaced_display_interleaved);
const u32 src_x = is_24bit ? cmd->X : cmd->display_vram_left;
const u32 skip_x = is_24bit ? (cmd->display_vram_left - cmd->X) : 0;