GPU: Simplify 480i mode handling in CRTC

This commit is contained in:
Connor McLaughlin 2019-11-14 00:58:15 +10:00
parent b48accf0bf
commit 7152d54104
5 changed files with 20 additions and 13 deletions

View File

@ -336,8 +336,9 @@ void GPU::UpdateCRTCConfig()
// check for a change in resolution // check for a change in resolution
const u32 old_horizontal_resolution = cs.display_width; const u32 old_horizontal_resolution = cs.display_width;
const u32 old_vertical_resolution = cs.display_height; const u32 old_vertical_resolution = cs.display_height;
const u32 visible_lines = cs.regs.Y2 - cs.regs.Y1;
cs.display_width = std::max<u32>((cs.regs.X2 - cs.regs.X1) / cs.dot_clock_divider, 1); cs.display_width = std::max<u32>((cs.regs.X2 - cs.regs.X1) / cs.dot_clock_divider, 1);
cs.display_height = cs.regs.Y2 - cs.regs.Y1; cs.display_height = visible_lines << BoolToUInt8(m_GPUSTAT.In480iMode());
if (cs.display_width != old_horizontal_resolution || cs.display_height != old_vertical_resolution) if (cs.display_width != old_horizontal_resolution || cs.display_height != old_vertical_resolution)
Log_InfoPrintf("Visible resolution is now %ux%u", cs.display_width, cs.display_height); Log_InfoPrintf("Visible resolution is now %ux%u", cs.display_width, cs.display_height);
@ -354,7 +355,7 @@ void GPU::UpdateCRTCConfig()
// Convert active dots/lines to time. // Convert active dots/lines to time.
const float visible_dots_per_scanline = static_cast<float>(cs.display_width); const float visible_dots_per_scanline = static_cast<float>(cs.display_width);
const float horizontal_active_time = horizontal_period * visible_dots_per_scanline; const float horizontal_active_time = horizontal_period * visible_dots_per_scanline;
const float vertical_active_time = horizontal_active_time * static_cast<float>(cs.display_height); const float vertical_active_time = horizontal_active_time * static_cast<float>(visible_lines);
// Use the reference active time/lines for the signal to work out the border area, and thus aspect ratio // Use the reference active time/lines for the signal to work out the border area, and thus aspect ratio
// transformation for the active area in our framebuffer. For the purposes of these calculations, we're assuming // transformation for the active area in our framebuffer. For the purposes of these calculations, we're assuming
@ -435,11 +436,18 @@ void GPU::Execute(TickCount ticks)
// start the new frame // start the new frame
m_crtc_state.current_scanline = 0; m_crtc_state.current_scanline = 0;
if (m_GPUSTAT.vertical_interlace & m_GPUSTAT.vertical_resolution) // switch fields for interlaced modes
if (m_GPUSTAT.vertical_interlace)
{ {
// extra line for NTSC m_GPUSTAT.interlaced_field ^= true;
m_crtc_state.current_scanline = BoolToUInt32(m_GPUSTAT.drawing_even_line); m_crtc_state.current_scanline = BoolToUInt32(m_GPUSTAT.interlaced_field);
m_GPUSTAT.drawing_even_line ^= true;
if (m_GPUSTAT.vertical_resolution)
m_GPUSTAT.drawing_even_line = m_GPUSTAT.interlaced_field;
}
else
{
m_GPUSTAT.interlaced_field = false;
} }
} }
@ -464,7 +472,7 @@ void GPU::Execute(TickCount ticks)
} }
// alternating even line bit in 240-line mode // alternating even line bit in 240-line mode
if (!(m_GPUSTAT.vertical_interlace & m_GPUSTAT.vertical_resolution)) if (!m_GPUSTAT.In480iMode())
m_GPUSTAT.drawing_even_line = ConvertToBoolUnchecked(m_crtc_state.current_scanline & u32(1)); m_GPUSTAT.drawing_even_line = ConvertToBoolUnchecked(m_crtc_state.current_scanline & u32(1));
} }

View File

@ -331,6 +331,8 @@ protected:
BitField<u32, bool, 28, 1> ready_to_recieve_dma; BitField<u32, bool, 28, 1> ready_to_recieve_dma;
BitField<u32, DMADirection, 29, 2> dma_direction; BitField<u32, DMADirection, 29, 2> dma_direction;
BitField<u32, bool, 31, 1> drawing_even_line; BitField<u32, bool, 31, 1> drawing_even_line;
bool In480iMode() const { return vertical_interlace & vertical_resolution; }
} m_GPUSTAT = {}; } m_GPUSTAT = {};
struct RenderState struct RenderState

View File

@ -519,8 +519,7 @@ void GPU_HW_D3D11::UpdateDisplay()
const u32 scaled_vram_offset_x = vram_offset_x * m_resolution_scale; const u32 scaled_vram_offset_x = vram_offset_x * m_resolution_scale;
const u32 scaled_vram_offset_y = vram_offset_y * m_resolution_scale; const u32 scaled_vram_offset_y = vram_offset_y * m_resolution_scale;
const u32 display_width = std::min<u32>(m_crtc_state.display_width, VRAM_WIDTH - vram_offset_x); const u32 display_width = std::min<u32>(m_crtc_state.display_width, VRAM_WIDTH - vram_offset_x);
const u32 display_height = std::min<u32>(m_crtc_state.display_height << BoolToUInt8(m_GPUSTAT.vertical_interlace), const u32 display_height = std::min<u32>(m_crtc_state.display_height, VRAM_HEIGHT - vram_offset_y);
VRAM_HEIGHT - vram_offset_y);
const u32 scaled_display_width = display_width * m_resolution_scale; const u32 scaled_display_width = display_width * m_resolution_scale;
const u32 scaled_display_height = display_height * m_resolution_scale; const u32 scaled_display_height = display_height * m_resolution_scale;

View File

@ -427,8 +427,7 @@ void GPU_HW_OpenGL::UpdateDisplay()
const u32 scaled_vram_offset_x = vram_offset_x * m_resolution_scale; const u32 scaled_vram_offset_x = vram_offset_x * m_resolution_scale;
const u32 scaled_vram_offset_y = vram_offset_y * m_resolution_scale; const u32 scaled_vram_offset_y = vram_offset_y * m_resolution_scale;
const u32 display_width = std::min<u32>(m_crtc_state.display_width, VRAM_WIDTH - vram_offset_x); const u32 display_width = std::min<u32>(m_crtc_state.display_width, VRAM_WIDTH - vram_offset_x);
const u32 display_height = std::min<u32>(m_crtc_state.display_height << BoolToUInt8(m_GPUSTAT.vertical_interlace), const u32 display_height = std::min<u32>(m_crtc_state.display_height, VRAM_HEIGHT - vram_offset_y);
VRAM_HEIGHT - vram_offset_y);
const u32 scaled_display_width = display_width * m_resolution_scale; const u32 scaled_display_width = display_width * m_resolution_scale;
const u32 scaled_display_height = display_height * m_resolution_scale; const u32 scaled_display_height = display_height * m_resolution_scale;

View File

@ -125,8 +125,7 @@ void GPU_SW::UpdateDisplay()
const u32 vram_offset_x = m_crtc_state.regs.X; const u32 vram_offset_x = m_crtc_state.regs.X;
const u32 vram_offset_y = m_crtc_state.regs.Y; const u32 vram_offset_y = m_crtc_state.regs.Y;
display_width = std::min<u32>(m_crtc_state.display_width, VRAM_WIDTH - vram_offset_x); display_width = std::min<u32>(m_crtc_state.display_width, VRAM_WIDTH - vram_offset_x);
display_height = std::min<u32>(m_crtc_state.display_height << BoolToUInt8(m_GPUSTAT.vertical_interlace), display_height = std::min<u32>(m_crtc_state.display_height, VRAM_HEIGHT - vram_offset_y);
VRAM_HEIGHT - vram_offset_y);
display_aspect_ratio = m_crtc_state.display_aspect_ratio; display_aspect_ratio = m_crtc_state.display_aspect_ratio;
if (m_GPUSTAT.display_disable) if (m_GPUSTAT.display_disable)