mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-12 01:14:33 +00:00
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:
@@ -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;
|
||||
|
||||
@@ -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() &&
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user