Skip to content

Commit dd0c7ec

Browse files
committed
GPU: Insert null field buffer if display disabled
Don't throw away all buffers. 240p Test Suite flips display disabled during vblank every frame.
1 parent f9cab70 commit dd0c7ec

File tree

4 files changed

+38
-16
lines changed

4 files changed

+38
-16
lines changed

src/core/gpu.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,9 +1512,6 @@ void GPU::WriteGP1(u32 value)
15121512
DEBUG_LOG("Display {}", disable ? "disabled" : "enabled");
15131513
SynchronizeCRTC();
15141514

1515-
if (!m_GPUSTAT.display_disable && disable && IsInterlacedDisplayEnabled())
1516-
ClearDisplay();
1517-
15181515
m_GPUSTAT.display_disable = disable;
15191516
}
15201517
break;

src/core/gpu_hw.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3976,6 +3976,9 @@ void GPU_HW::UpdateDisplay(const GPUBackendUpdateDisplayCommand* cmd)
39763976
if (cmd->display_disabled)
39773977
{
39783978
m_presenter.ClearDisplayTexture();
3979+
if (interlaced)
3980+
m_presenter.Deinterlace(interlaced_field);
3981+
39793982
return;
39803983
}
39813984
else if (!cmd->display_24bit && line_skip == 0 && !IsUsingMultisampling() &&

src/core/gpu_presenter.cpp

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,13 +1006,16 @@ void GPUPresenter::DestroyDeinterlaceTextures()
10061006

10071007
bool GPUPresenter::Deinterlace(u32 field)
10081008
{
1009-
GPUTexture* src = m_display_texture;
1009+
GPUTexture* const src = m_display_texture;
1010+
if (src)
1011+
src->MakeReadyForSampling();
1012+
10101013
const u32 x = m_display_texture_view_x;
10111014
const u32 y = m_display_texture_view_y;
10121015
const u32 width = m_display_texture_view_width;
10131016
const u32 height = m_display_texture_view_height;
10141017

1015-
const auto copy_to_field_buffer = [&](u32 buffer) {
1018+
const auto copy_to_field_buffer = [this, &src, &x, &y, &width, &height](u32 buffer) {
10161019
if (!g_gpu_device->ResizeTexture(&m_deinterlace_buffers[buffer], width, height, GPUTexture::Type::Texture,
10171020
src->GetFormat(), GPUTexture::Flags::None, false)) [[unlikely]]
10181021
{
@@ -1027,8 +1030,6 @@ bool GPUPresenter::Deinterlace(u32 field)
10271030
return true;
10281031
};
10291032

1030-
src->MakeReadyForSampling();
1031-
10321033
switch (g_gpu_settings.display_deinterlacing_mode)
10331034
{
10341035
case DisplayDeinterlacingMode::Disabled:
@@ -1072,13 +1073,20 @@ bool GPUPresenter::Deinterlace(u32 field)
10721073
const u32 this_buffer = m_current_deinterlace_buffer;
10731074
m_current_deinterlace_buffer = (m_current_deinterlace_buffer + 1u) % NUM_BLEND_BUFFERS;
10741075
GL_INS_FMT("Current buffer: {}", this_buffer);
1075-
if (!DeinterlaceSetTargetSize(width, height, false) || !copy_to_field_buffer(this_buffer)) [[unlikely]]
1076+
if (src)
10761077
{
1077-
ClearDisplayTexture();
1078-
return false;
1078+
if (!DeinterlaceSetTargetSize(width, height, false) || !copy_to_field_buffer(this_buffer))
1079+
{
1080+
ClearDisplayTexture();
1081+
return false;
1082+
}
1083+
}
1084+
else
1085+
{
1086+
// Clear the buffer, make it sample black.
1087+
GL_INS("No source texture, clearing deinterlace buffer");
1088+
g_gpu_device->RecycleTexture(std::move(m_deinterlace_buffers[this_buffer]));
10791089
}
1080-
1081-
copy_to_field_buffer(this_buffer);
10821090

10831091
// TODO: could be implemented with alpha blending instead..
10841092
g_gpu_device->InvalidateRenderTarget(m_deinterlace_texture.get());
@@ -1103,10 +1111,20 @@ bool GPUPresenter::Deinterlace(u32 field)
11031111
const u32 full_height = height * 2;
11041112
m_current_deinterlace_buffer = (m_current_deinterlace_buffer + 1u) % DEINTERLACE_BUFFER_COUNT;
11051113
GL_INS_FMT("Current buffer: {}", this_buffer);
1106-
if (!DeinterlaceSetTargetSize(width, full_height, false) || !copy_to_field_buffer(this_buffer)) [[unlikely]]
1114+
1115+
if (src)
11071116
{
1108-
ClearDisplayTexture();
1109-
return false;
1117+
if (!DeinterlaceSetTargetSize(width, full_height, false) || !copy_to_field_buffer(this_buffer)) [[unlikely]]
1118+
{
1119+
ClearDisplayTexture();
1120+
return false;
1121+
}
1122+
}
1123+
else
1124+
{
1125+
// Clear the buffer, make it sample black.
1126+
GL_INS("No source texture, clearing deinterlace buffer");
1127+
g_gpu_device->RecycleTexture(std::move(m_deinterlace_buffers[this_buffer]));
11101128
}
11111129

11121130
g_gpu_device->SetRenderTarget(m_deinterlace_texture.get());

src/core/gpu_sw.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,14 +385,18 @@ void GPU_SW::UpdateDisplay(const GPUBackendUpdateDisplayCommand* cmd)
385385
{
386386
if (!g_gpu_settings.gpu_show_vram)
387387
{
388+
const u32 field = BoolToUInt32(cmd->interlaced_display_field);
389+
388390
if (cmd->display_disabled)
389391
{
390392
m_presenter.ClearDisplayTexture();
393+
if (cmd->interlaced_display_enabled)
394+
m_presenter.Deinterlace(field);
395+
391396
return;
392397
}
393398

394399
const bool is_24bit = cmd->display_24bit;
395-
const u32 field = BoolToUInt32(cmd->interlaced_display_field);
396400
const u32 line_skip = BoolToUInt32(cmd->interlaced_display_interleaved);
397401
const u32 src_x = is_24bit ? cmd->X : cmd->display_vram_left;
398402
const u32 skip_x = is_24bit ? (cmd->display_vram_left - cmd->X) : 0;

0 commit comments

Comments
 (0)