From 91cca1c980428988934b938a8e1de81c463ea823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 24 Jan 2023 16:48:13 +0100 Subject: [PATCH] Improve scissor rect clipping. Affected D3D11 validation when maximizing/minimizing. --- Common/GPU/D3D11/thin3d_d3d11.cpp | 2 ++ Common/UI/Context.cpp | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index 5558456da8..29bea57c32 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -437,6 +437,8 @@ void D3D11DrawContext::SetViewports(int count, Viewport *viewports) { } void D3D11DrawContext::SetScissorRect(int left, int top, int width, int height) { + _assert_(width >= 0); + _assert_(height >= 0); DisplayRect frc{ (float)left, (float)top, (float)width, (float)height }; if (curRenderTargetView_ == bbRenderTargetView_) // Only the backbuffer is actually rotated wrong! RotateRectToDisplay(frc, curRTWidth_, curRTHeight_); diff --git a/Common/UI/Context.cpp b/Common/UI/Context.cpp index be795ad0de..f6effabb32 100644 --- a/Common/UI/Context.cpp +++ b/Common/UI/Context.cpp @@ -173,12 +173,21 @@ void UIContext::ActivateTopScissor() { if (x < 0 || y < 0 || x + w > pixel_xres || y + h > pixel_yres) { // This won't actually report outside a game, but we can try. ERROR_LOG(G3D, "UI scissor out of bounds in %sScreen: %d,%d-%d,%d / %d,%d", screenTag_ ? screenTag_ : "N/A", x, y, w, h, pixel_xres, pixel_yres); - x = std::max(0, x); - y = std::max(0, y); - w = std::min(w, pixel_xres - x); - h = std::min(h, pixel_yres - y); + if (x < 0) { w += x; x = 0; } + if (y < 0) { h += y; y = 0; } + if (x >= pixel_xres) { x = pixel_xres - 1; } + if (y >= pixel_yres) { y = pixel_yres - 1; } + if (x + w > pixel_xres) { w = std::min(w, pixel_xres - x); } + if (y + w > pixel_yres) { h = std::min(h, pixel_yres - y); } + if (w == 0) w = 1; + if (h == 0) h = 1; + draw_->SetScissorRect(x, y, w, h); + } else { + // Avoid invalid rects + if (w == 0) w = 1; + if (h == 0) h = 1; + draw_->SetScissorRect(x, y, w, h); } - draw_->SetScissorRect(x, y, w, h); } else { // Avoid rounding errors draw_->SetScissorRect(0, 0, pixel_xres, pixel_yres);