From 8c6cb877eb5a968f83d420d9825fc1bdcdb81e5f Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Mon, 27 Apr 2020 21:49:34 +1000 Subject: [PATCH] GPU: Disable display when CRTC configuration is invalid --- src/core/gpu.cpp | 31 ++++++++++++++++++------------- src/core/gpu.h | 6 ++++++ src/core/gpu_hw_d3d11.cpp | 2 +- src/core/gpu_hw_opengl.cpp | 2 +- src/core/gpu_sw.cpp | 2 +- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index d76b904ff..41c226598 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -517,19 +517,21 @@ void GPU::UpdateCRTCDisplayParameters() if (horizontal_display_end <= cs.horizontal_active_end) { - cs.display_vram_width = - std::max((((horizontal_display_end - std::max(horizontal_display_start, cs.horizontal_active_start)) + - (cs.dot_clock_divider - 1)) / - cs.dot_clock_divider), - 1u); + cs.display_vram_width = std::max( + (((horizontal_display_end - + std::min(horizontal_display_end, std::max(horizontal_display_start, cs.horizontal_active_start))) + + (cs.dot_clock_divider - 1)) / + cs.dot_clock_divider), + 1u); } else { - cs.display_vram_width = - std::max((((cs.horizontal_active_end - std::max(horizontal_display_start, cs.horizontal_active_start)) + - (cs.dot_clock_divider - 1)) / - cs.dot_clock_divider), - 1u); + cs.display_vram_width = std::max( + (((cs.horizontal_active_end - + std::min(cs.horizontal_active_end, std::max(horizontal_display_start, cs.horizontal_active_start))) + + (cs.dot_clock_divider - 1)) / + cs.dot_clock_divider), + 1u); } if (vertical_display_start >= cs.vertical_active_start) @@ -545,13 +547,16 @@ void GPU::UpdateCRTCDisplayParameters() if (vertical_display_end <= cs.vertical_active_end) { - cs.display_vram_height = (vertical_display_end - std::max(vertical_display_start, cs.vertical_active_start)) + cs.display_vram_height = (vertical_display_end - std::min(vertical_display_end, std::max(vertical_display_start, + cs.vertical_active_start))) << height_shift; } else { - cs.display_vram_height = (cs.vertical_active_end - std::max(vertical_display_start, cs.vertical_active_start)) - << height_shift; + cs.display_vram_height = + (cs.vertical_active_end - + std::min(vertical_display_end, std::max(vertical_display_start, cs.vertical_active_start))) + << height_shift; } } diff --git a/src/core/gpu.h b/src/core/gpu.h index fdc7b123e..d43503679 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -334,6 +334,12 @@ protected: // Ticks for hblank/vblank. void Execute(TickCount ticks); + /// Returns false if the DAC is loading any data from VRAM. + ALWAYS_INLINE bool IsDisplayDisabled() const + { + return m_GPUSTAT.display_disable || m_crtc_state.display_vram_width == 0 || m_crtc_state.display_vram_height == 0; + } + /// Returns true if scanout should be interlaced. ALWAYS_INLINE bool IsInterlacedDisplayEnabled() const { return (!m_force_progressive_scan) & m_GPUSTAT.In480iMode(); } diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index 017697d46..ee65bc35c 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -552,7 +552,7 @@ void GPU_HW_D3D11::UpdateDisplay() const u32 scaled_display_height = display_height * m_resolution_scale; const bool interlaced = IsInterlacedDisplayEnabled(); - if (m_GPUSTAT.display_disable) + if (IsDisplayDisabled()) { m_host_display->ClearDisplayTexture(); } diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index dc7ba8c1f..f2e546927 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -544,7 +544,7 @@ void GPU_HW_OpenGL::UpdateDisplay() const u32 scaled_display_height = display_height * m_resolution_scale; const bool interlaced = IsInterlacedDisplayEnabled(); - if (m_GPUSTAT.display_disable) + if (IsDisplayDisabled()) { m_host_display->ClearDisplayTexture(); } diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index 9bda22730..7e5c44809 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -144,7 +144,7 @@ void GPU_SW::UpdateDisplay() if (!m_system->GetSettings().debugging.show_vram) { - if (m_GPUSTAT.display_disable) + if (IsDisplayDisabled()) { m_host_display->ClearDisplayTexture(); return;