From 445bd02cad2f5658670e0cccaa9997a02557adf2 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Wed, 27 May 2020 00:27:25 +1000 Subject: [PATCH] GPU/HW: Interlace at native resolution rather than 1x Also fixes screen bobbing when interlacing is disabled. --- src/core/gpu_hw_d3d11.cpp | 6 +++--- src/core/gpu_hw_opengl.cpp | 7 +++---- src/core/gpu_hw_shadergen.cpp | 6 +++--- src/core/gpu_sw.cpp | 12 +++++------- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index 7e3cb69f8..2d9999a26 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -583,7 +583,7 @@ void GPU_HW_D3D11::UpdateDisplay() else { const u32 vram_offset_x = m_crtc_state.display_vram_left; - const u32 vram_offset_y = m_crtc_state.display_vram_top + GetActiveLineLSB(); + const u32 vram_offset_y = m_crtc_state.display_vram_top; 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 display_width = m_crtc_state.display_vram_width; @@ -613,8 +613,8 @@ void GPU_HW_D3D11::UpdateDisplay() const u32 reinterpret_field_offset = GetInterlacedDisplayField(); const u32 reinterpret_start_x = m_crtc_state.regs.X * m_resolution_scale; const u32 reinterpret_crop_left = (m_crtc_state.display_vram_left - m_crtc_state.regs.X) * m_resolution_scale; - const u32 uniforms[4] = {reinterpret_start_x, scaled_vram_offset_y, reinterpret_crop_left, - reinterpret_field_offset}; + const u32 uniforms[4] = {reinterpret_start_x, scaled_vram_offset_y + reinterpret_field_offset, + reinterpret_crop_left, reinterpret_field_offset}; ID3D11PixelShader* display_pixel_shader = m_display_pixel_shaders[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)][static_cast(interlaced)].Get(); diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index f364dfb69..dfb326fda 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -580,7 +580,7 @@ void GPU_HW_OpenGL::UpdateDisplay() else { const u32 vram_offset_x = m_crtc_state.display_vram_left; - const u32 vram_offset_y = m_crtc_state.display_vram_top + GetActiveLineLSB(); + const u32 vram_offset_y = m_crtc_state.display_vram_top; 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 display_width = m_crtc_state.display_vram_width; @@ -613,10 +613,9 @@ void GPU_HW_OpenGL::UpdateDisplay() m_vram_texture.Bind(); const u8 height_div2 = BoolToUInt8(interlaced == GPU_HW::InterlacedRenderMode::SeparateFields); - const u32 flipped_vram_offset_y = VRAM_HEIGHT - vram_offset_y - (display_height >> height_div2); - const u32 scaled_flipped_vram_offset_y = - m_vram_texture.GetHeight() - scaled_vram_offset_y - (scaled_display_height >> height_div2); const u32 reinterpret_field_offset = GetInterlacedDisplayField(); + const u32 scaled_flipped_vram_offset_y = m_vram_texture.GetHeight() - scaled_vram_offset_y - + reinterpret_field_offset - (scaled_display_height >> height_div2); const u32 reinterpret_start_x = m_crtc_state.regs.X * m_resolution_scale; const u32 reinterpret_crop_left = (m_crtc_state.display_vram_left - m_crtc_state.regs.X) * m_resolution_scale; const u32 uniforms[4] = {reinterpret_start_x, scaled_flipped_vram_offset_y, reinterpret_crop_left, diff --git a/src/core/gpu_hw_shadergen.cpp b/src/core/gpu_hw_shadergen.cpp index 0eff401fb..b68468741 100644 --- a/src/core/gpu_hw_shadergen.cpp +++ b/src/core/gpu_hw_shadergen.cpp @@ -668,7 +668,7 @@ float4 SampleFromVRAM(uint4 texpage, uint2 icoord) float oalpha; #if INTERLACING - if (((fixYCoord(uint(v_pos.y)) / RESOLUTION_SCALE) & 1u) == u_interlaced_displayed_field) + if ((fixYCoord(uint(v_pos.y)) & 1u) == u_interlaced_displayed_field) discard; #endif @@ -979,7 +979,7 @@ std::string GPU_HW_ShaderGen::GenerateInterlacedFillFragmentShader() ss << R"( { - if (((fixYCoord(uint(v_pos.y)) / RESOLUTION_SCALE) & 1u) == u_interlaced_displayed_field) + if ((fixYCoord(uint(v_pos.y)) & 1u) == u_interlaced_displayed_field) discard; o_col0 = u_fill_color; @@ -1026,7 +1026,7 @@ std::string GPU_HW_ShaderGen::GenerateDisplayFragmentShader(bool depth_24bit, GP uint2 icoords = uint2(v_pos.xy); #if INTERLACED - if (((fixYCoord(icoords.y) / RESOLUTION_SCALE) & 1u) != u_field_offset) + if ((fixYCoord(icoords.y) & 1u) != u_field_offset) discard; #if !INTERLEAVED diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index a6095fcbe..bfb7a2131 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -157,7 +157,7 @@ void GPU_SW::UpdateDisplay() } const u32 vram_offset_x = m_crtc_state.display_vram_left; - const u32 vram_offset_y = m_crtc_state.display_vram_top + GetActiveLineLSB(); + const u32 vram_offset_y = m_crtc_state.display_vram_top; const u32 display_width = m_crtc_state.display_vram_width; const u32 display_height = m_crtc_state.display_vram_height; const u32 texture_offset_x = m_crtc_state.display_vram_left - m_crtc_state.regs.X; @@ -166,15 +166,13 @@ void GPU_SW::UpdateDisplay() const u32 field = GetInterlacedDisplayField(); if (m_GPUSTAT.display_area_color_depth_24) { - CopyOut24Bit(m_crtc_state.regs.X, vram_offset_y, - m_display_texture_buffer.data() + field * VRAM_WIDTH, VRAM_WIDTH, display_width + texture_offset_x, - display_height, true, m_GPUSTAT.vertical_resolution); + CopyOut24Bit(m_crtc_state.regs.X, vram_offset_y + field, m_display_texture_buffer.data() + field * VRAM_WIDTH, + VRAM_WIDTH, display_width + texture_offset_x, display_height, true, m_GPUSTAT.vertical_resolution); } else { - CopyOut15Bit(m_crtc_state.regs.X, vram_offset_y, - m_display_texture_buffer.data() + field * VRAM_WIDTH, VRAM_WIDTH, display_width + texture_offset_x, - display_height, true, m_GPUSTAT.vertical_resolution); + CopyOut15Bit(m_crtc_state.regs.X, vram_offset_y + field, m_display_texture_buffer.data() + field * VRAM_WIDTH, + VRAM_WIDTH, display_width + texture_offset_x, display_height, true, m_GPUSTAT.vertical_resolution); } } else