GPU: Add a Force Progressive Scan option (disable interlacing)

This commit is contained in:
Connor McLaughlin 2019-12-10 22:52:46 +10:00
parent fb0aad0917
commit df6e079920
8 changed files with 29 additions and 16 deletions

View File

@ -26,10 +26,14 @@ bool GPU::Initialize(HostDisplay* host_display, System* system, DMA* dma, Interr
m_dma = dma;
m_interrupt_controller = interrupt_controller;
m_timers = timers;
m_force_progressive_scan = m_system->GetSettings().gpu_force_progressive_scan;
return true;
}
void GPU::UpdateSettings() {}
void GPU::UpdateSettings()
{
m_force_progressive_scan = m_system->GetSettings().gpu_force_progressive_scan;
}
void GPU::Reset()
{

View File

@ -296,6 +296,9 @@ protected:
// Updates dynamic bits in GPUSTAT (ready to send VRAM/ready to receive DMA)
void UpdateGPUSTAT();
/// Returns true if scanout should be interlaced.
bool IsDisplayInterlaced() const { return !m_force_progressive_scan && m_GPUSTAT.In480iMode(); }
u32 ReadGPUREAD();
void WriteGP0(u32 value);
void WriteGP1(u32 value);
@ -436,6 +439,7 @@ protected:
bool m_drawing_area_changed = false;
bool m_drawing_offset_changed = false;
bool m_force_progressive_scan = false;
struct CRTCState
{

View File

@ -537,12 +537,13 @@ void GPU_HW_D3D11::UpdateDisplay()
const u32 display_height = std::min<u32>(m_crtc_state.display_height, VRAM_HEIGHT - vram_offset_y);
const u32 scaled_display_width = display_width * m_resolution_scale;
const u32 scaled_display_height = display_height * m_resolution_scale;
const bool interlaced = IsDisplayInterlaced();
if (m_GPUSTAT.display_disable)
{
m_host_display->SetDisplayTexture(nullptr, 0, 0, 0, 0, 0, 0, m_crtc_state.display_aspect_ratio);
}
else if (!m_GPUSTAT.display_area_color_depth_24 && !m_GPUSTAT.vertical_interlace)
else if (!m_GPUSTAT.display_area_color_depth_24 && !interlaced)
{
m_host_display->SetDisplayTexture(m_vram_texture.GetD3DSRV(), scaled_vram_offset_x, scaled_vram_offset_y,
scaled_display_width, scaled_display_height, m_vram_texture.GetWidth(),
@ -550,12 +551,10 @@ void GPU_HW_D3D11::UpdateDisplay()
}
else
{
const u32 field_offset = BoolToUInt8(m_GPUSTAT.vertical_interlace && m_GPUSTAT.interlaced_field);
const u32 field_offset = BoolToUInt8(interlaced && m_GPUSTAT.interlaced_field);
ID3D11PixelShader* display_pixel_shader =
m_display_pixel_shaders[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)]
[BoolToUInt8(m_GPUSTAT.vertical_interlace)]
.Get();
m_display_pixel_shaders[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)][BoolToUInt8(interlaced)].Get();
// Because of how the reinterpret shader works, we need to use the downscaled version.
if (m_GPUSTAT.display_area_color_depth_24 && m_resolution_scale > 1)

View File

@ -464,12 +464,13 @@ void GPU_HW_OpenGL::UpdateDisplay()
const u32 display_height = std::min<u32>(m_crtc_state.display_height, VRAM_HEIGHT - vram_offset_y);
const u32 scaled_display_width = display_width * m_resolution_scale;
const u32 scaled_display_height = display_height * m_resolution_scale;
const bool interlaced = IsDisplayInterlaced();
if (m_GPUSTAT.display_disable)
{
m_host_display->SetDisplayTexture(nullptr, 0, 0, 0, 0, 0, 0, m_crtc_state.display_aspect_ratio);
}
else if (!m_GPUSTAT.display_area_color_depth_24 && !m_GPUSTAT.vertical_interlace)
else if (!m_GPUSTAT.display_area_color_depth_24 && !interlaced)
{
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture->GetGLId())),
scaled_vram_offset_x, m_vram_texture->GetHeight() - scaled_vram_offset_y,
@ -482,13 +483,13 @@ void GPU_HW_OpenGL::UpdateDisplay()
const u32 flipped_vram_offset_y = VRAM_HEIGHT - vram_offset_y - display_height;
const u32 scaled_flipped_vram_offset_y =
m_vram_texture->GetHeight() - scaled_vram_offset_y - scaled_display_height;
const u32 field_offset = BoolToUInt8(m_GPUSTAT.vertical_interlace && m_GPUSTAT.interlaced_field);
const u32 field_offset = BoolToUInt8(interlaced && m_GPUSTAT.interlaced_field);
glDisable(GL_BLEND);
glDisable(GL_SCISSOR_TEST);
const GL::Program& prog = m_display_programs[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)]
[BoolToUInt8(m_GPUSTAT.vertical_interlace)];
const GL::Program& prog =
m_display_programs[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)][BoolToUInt8(interlaced)];
prog.Bind();
// Because of how the reinterpret shader works, we need to use the downscaled version.

View File

@ -359,12 +359,13 @@ void GPU_HW_OpenGL_ES::UpdateDisplay()
const u32 display_height = std::min<u32>(m_crtc_state.display_height, VRAM_HEIGHT - vram_offset_y);
const u32 scaled_display_width = display_width * m_resolution_scale;
const u32 scaled_display_height = display_height * m_resolution_scale;
const bool interlaced = IsDisplayInterlaced();
if (m_GPUSTAT.display_disable)
{
m_host_display->SetDisplayTexture(nullptr, 0, 0, 0, 0, 0, 0, m_crtc_state.display_aspect_ratio);
}
else if (!m_GPUSTAT.display_area_color_depth_24 && !m_GPUSTAT.vertical_interlace)
else if (!m_GPUSTAT.display_area_color_depth_24 && !interlaced)
{
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture->GetGLId())),
scaled_vram_offset_x, m_vram_texture->GetHeight() - scaled_vram_offset_y,
@ -377,13 +378,13 @@ void GPU_HW_OpenGL_ES::UpdateDisplay()
const u32 flipped_vram_offset_y = VRAM_HEIGHT - vram_offset_y - display_height;
const u32 scaled_flipped_vram_offset_y =
m_vram_texture->GetHeight() - scaled_vram_offset_y - scaled_display_height;
const u32 field_offset = BoolToUInt8(m_GPUSTAT.vertical_interlace && m_GPUSTAT.interlaced_field);
const u32 field_offset = BoolToUInt8(interlaced && m_GPUSTAT.interlaced_field);
glDisable(GL_BLEND);
glDisable(GL_SCISSOR_TEST);
const GL::Program& prog = m_display_programs[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)]
[BoolToUInt8(m_GPUSTAT.vertical_interlace)];
const GL::Program& prog =
m_display_programs[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)][BoolToUInt8(interlaced)];
prog.Bind();
// Because of how the reinterpret shader works, we need to use the downscaled version.

View File

@ -24,6 +24,8 @@ void Settings::SetDefaults()
gpu_renderer = GPURenderer::HardwareOpenGL;
gpu_resolution_scale = 1;
gpu_true_color = true;
gpu_texture_filtering = false;
gpu_force_progressive_scan = true;
display_linear_filtering = true;

View File

@ -21,6 +21,7 @@ struct Settings
mutable u32 max_gpu_resolution_scale = 1;
bool gpu_true_color = false;
bool gpu_texture_filtering = false;
bool gpu_force_progressive_scan = false;
bool display_linear_filtering = true;
bool display_fullscreen = false;

View File

@ -1180,8 +1180,9 @@ void SDLHostInterface::DrawSettingsWindow()
gpu_settings_changed = true;
}
ImGui::Checkbox("True 24-bit Color (disables dithering)", &m_settings.gpu_true_color);
ImGui::Checkbox("Texture Filtering", &m_settings.gpu_texture_filtering);
gpu_settings_changed |= ImGui::Checkbox("True 24-bit Color (disables dithering)", &m_settings.gpu_true_color);
gpu_settings_changed |= ImGui::Checkbox("Texture Filtering", &m_settings.gpu_texture_filtering);
gpu_settings_changed |= ImGui::Checkbox("Force Progressive Scan", &m_settings.gpu_force_progressive_scan);
}
ImGui::EndTabItem();