GPU: Add a Force Progressive Scan option (disable interlacing)
This commit is contained in:
parent
fb0aad0917
commit
df6e079920
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue