diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp index a1d4dda0d38..2839e05b739 100644 --- a/Source/Core/VideoBackends/Software/Rasterizer.cpp +++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp @@ -18,6 +18,7 @@ #include "VideoCommon/PerfQueryBase.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/VideoCommon.h" +#include "VideoCommon/XFMemory.h" namespace Rasterizer { @@ -113,7 +114,9 @@ void Init() void ScissorChanged() { - scissors = std::move(BPFunctions::ComputeScissorRects().m_result); + auto scissor_result = BPFunctions::ComputeScissorRects(bpmem.scissorTL, bpmem.scissorBR, + bpmem.scissorOffset, xfmem.viewport); + scissors = std::move(scissor_result.rectangles); } // Returns approximation of log2(f) in s28.4 diff --git a/Source/Core/VideoCommon/AbstractGfx.cpp b/Source/Core/VideoCommon/AbstractGfx.cpp index 27424b25f54..90b85ddffff 100644 --- a/Source/Core/VideoCommon/AbstractGfx.cpp +++ b/Source/Core/VideoCommon/AbstractGfx.cpp @@ -12,6 +12,7 @@ #include "VideoCommon/ShaderCache.h" #include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VideoConfig.h" +#include "VideoCommon/XFMemory.h" std::unique_ptr g_gfx; @@ -35,7 +36,8 @@ void AbstractGfx::EndUtilityDrawing() { // Reset framebuffer/scissor/viewport. Pipeline will be reset at next draw. g_framebuffer_manager->BindEFBFramebuffer(); - BPFunctions::SetScissorAndViewport(); + BPFunctions::SetScissorAndViewport(g_framebuffer_manager.get(), bpmem.scissorTL, bpmem.scissorBR, + bpmem.scissorOffset, xfmem.viewport); } void AbstractGfx::SetFramebuffer(AbstractFramebuffer* framebuffer) diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp index 7d1bd054823..660d85c5989 100644 --- a/Source/Core/VideoCommon/BPFunctions.cpp +++ b/Source/Core/VideoCommon/BPFunctions.cpp @@ -11,13 +11,12 @@ #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" #include "Common/SmallVector.h" +#include "Core/System.h" -#include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractGfx.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/EFBInterface.h" #include "VideoCommon/FramebufferManager.h" -#include "VideoCommon/RenderState.h" #include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexShaderManager.h" #include "VideoCommon/VideoCommon.h" @@ -98,18 +97,18 @@ static RangeList ComputeScissorRanges(int start, int end, int offset, int efb_di } } // namespace -ScissorResult::ScissorResult(const BPMemory& bpmemory, const XFMemory& xfmemory) - : ScissorResult(bpmemory, - std::minmax(xfmemory.viewport.xOrig - xfmemory.viewport.wd, - xfmemory.viewport.xOrig + xfmemory.viewport.wd), - std::minmax(xfmemory.viewport.yOrig - xfmemory.viewport.ht, - xfmemory.viewport.yOrig + xfmemory.viewport.ht)) +ScissorResult::ScissorResult(ScissorPos scissor_top_left, ScissorPos scissor_bottom_right, + ScissorOffset scissor_offset, const Viewport& viewport) + : ScissorResult(scissor_top_left, scissor_bottom_right, scissor_offset, + std::minmax(viewport.xOrig - viewport.wd, viewport.xOrig + viewport.wd), + std::minmax(viewport.yOrig - viewport.ht, viewport.yOrig + viewport.ht)) { } -ScissorResult::ScissorResult(const BPMemory& bpmemory, std::pair viewport_x, +ScissorResult::ScissorResult(ScissorPos scissor_top_left, ScissorPos scissor_bottom_right, + ScissorOffset scissor_offset, std::pair viewport_x, std::pair viewport_y) - : scissor_tl{.hex = bpmemory.scissorTL.hex}, scissor_br{.hex = bpmemory.scissorBR.hex}, - scissor_off{.hex = bpmemory.scissorOffset.hex}, viewport_left(viewport_x.first), + : scissor_tl{.hex = scissor_top_left.hex}, scissor_br{.hex = scissor_bottom_right.hex}, + scissor_off{.hex = scissor_offset.hex}, viewport_left(viewport_x.first), viewport_right(viewport_x.second), viewport_top(viewport_y.first), viewport_bottom(viewport_y.second) { @@ -132,7 +131,7 @@ ScissorResult::ScissorResult(const BPMemory& bpmemory, std::pair v RangeList x_ranges = ComputeScissorRanges(left, right, x_off, EFB_WIDTH); RangeList y_ranges = ComputeScissorRanges(top, bottom, y_off, EFB_HEIGHT); - m_result.reserve(x_ranges.size() * y_ranges.size()); + rectangles.reserve(x_ranges.size() * y_ranges.size()); // Now we need to form actual rectangles from the x and y ranges, // which is a simple Cartesian product of x_ranges_clamped and y_ranges_clamped. @@ -146,12 +145,12 @@ ScissorResult::ScissorResult(const BPMemory& bpmemory, std::pair v { DEBUG_ASSERT(y_range.start < y_range.end); DEBUG_ASSERT(static_cast(y_range.end) <= EFB_HEIGHT); - m_result.emplace_back(x_range, y_range); + rectangles.emplace_back(x_range, y_range); } } auto cmp = [&](const ScissorRect& lhs, const ScissorRect& rhs) { return IsWorse(lhs, rhs); }; - std::ranges::sort(m_result, cmp); + std::ranges::sort(rectangles, cmp); } ScissorRect ScissorResult::Best() const @@ -159,9 +158,9 @@ ScissorRect ScissorResult::Best() const // For now, simply choose the best rectangle (see ScissorResult::IsWorse). // This does mean we calculate all rectangles and only choose one, which is not optimal, but this // is called infrequently. Eventually, all backends will support multiple scissor rects. - if (!m_result.empty()) + if (!rectangles.empty()) { - return m_result.back(); + return rectangles.back(); } else { @@ -172,23 +171,28 @@ ScissorRect ScissorResult::Best() const } } -ScissorResult ComputeScissorRects() +ScissorResult ComputeScissorRects(ScissorPos scissor_top_left, ScissorPos scissor_bottom_right, + ScissorOffset scissor_offset, const Viewport& viewport) { - return ScissorResult{bpmem, xfmem}; + return ScissorResult{scissor_top_left, scissor_bottom_right, scissor_offset, viewport}; } -void SetScissorAndViewport() +void SetScissorAndViewport(FramebufferManager* frame_buffer_manager, ScissorPos scissor_top_left, + ScissorPos scissor_bottom_right, ScissorOffset scissor_offset, + Viewport viewport) { - auto native_rc = ComputeScissorRects().Best(); + const auto result = BPFunctions::ComputeScissorRects(scissor_top_left, scissor_bottom_right, + scissor_offset, viewport); + auto native_rc = result.Best(); - auto target_rc = g_framebuffer_manager->ConvertEFBRectangle(native_rc.rect); + auto target_rc = frame_buffer_manager->ConvertEFBRectangle(native_rc.rect); auto converted_rc = g_gfx->ConvertFramebufferRectangle(target_rc, g_gfx->GetCurrentFramebuffer()); g_gfx->SetScissorRect(converted_rc); - float raw_x = (xfmem.viewport.xOrig - native_rc.x_off) - xfmem.viewport.wd; - float raw_y = (xfmem.viewport.yOrig - native_rc.y_off) + xfmem.viewport.ht; - float raw_width = 2.0f * xfmem.viewport.wd; - float raw_height = -2.0f * xfmem.viewport.ht; + float raw_x = (viewport.xOrig - native_rc.x_off) - viewport.wd; + float raw_y = (viewport.yOrig - native_rc.y_off) + viewport.ht; + float raw_width = 2.0f * viewport.wd; + float raw_height = -2.0f * viewport.ht; if (g_ActiveConfig.UseVertexRounding()) { // Round the viewport to match full 1x IR pixels as well. @@ -199,12 +203,12 @@ void SetScissorAndViewport() raw_height = std::round(raw_height); } - float x = g_framebuffer_manager->EFBToScaledXf(raw_x); - float y = g_framebuffer_manager->EFBToScaledYf(raw_y); - float width = g_framebuffer_manager->EFBToScaledXf(raw_width); - float height = g_framebuffer_manager->EFBToScaledYf(raw_height); - float min_depth = (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f; - float max_depth = xfmem.viewport.farZ / 16777216.0f; + float x = frame_buffer_manager->EFBToScaledXf(raw_x); + float y = frame_buffer_manager->EFBToScaledYf(raw_y); + float width = frame_buffer_manager->EFBToScaledXf(raw_width); + float height = frame_buffer_manager->EFBToScaledYf(raw_height); + float min_depth = (viewport.farZ - viewport.zRange) / 16777216.0f; + float max_depth = viewport.farZ / 16777216.0f; if (width < 0.f) { x += width; @@ -228,7 +232,7 @@ void SetScissorAndViewport() { // We need to ensure depth values are clamped the maximum value supported by the console GPU. // Taking into account whether the depth range is inverted or not. - if (xfmem.viewport.zRange < 0.0f && g_backend_info.bSupportsReversedDepthRange) + if (viewport.zRange < 0.0f && g_backend_info.bSupportsReversedDepthRange) { min_depth = MAX_EFB_DEPTH; max_depth = 0.0f; @@ -291,24 +295,21 @@ void SetBlendMode() - convert the RGBA8 color to RGBA6/RGB8/RGB565 and convert it to RGBA8 again - convert the Z24 depth value to Z16 and back to Z24 */ -void ClearScreen(const MathUtil::Rectangle& rc) +bool ClearScreen(FramebufferManager* frame_buffer_manager, const MathUtil::Rectangle& rc, + bool color_enable, bool alpha_enable, bool z_enable, PixelFormat pixel_format, + u32 clear_color_ar, u32 clear_color_gb, u32 clear_z_value) { - bool colorEnable = (bpmem.blendmode.color_update != 0); - bool alphaEnable = (bpmem.blendmode.alpha_update != 0); - bool zEnable = (bpmem.zmode.update_enable != 0); - auto pixel_format = bpmem.zcontrol.pixel_format; - // (1): Disable unused color channels if (pixel_format == PixelFormat::RGB8_Z24 || pixel_format == PixelFormat::RGB565_Z16 || pixel_format == PixelFormat::Z24) { - alphaEnable = false; + alpha_enable = false; } - if (colorEnable || alphaEnable || zEnable) + if (color_enable || alpha_enable || z_enable) { - u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB; - u32 z = bpmem.clearZValue; + u32 color = (clear_color_ar << 16) | clear_color_gb; + u32 z = clear_z_value; // (2) drop additional accuracy if (pixel_format == PixelFormat::RGBA6_Z24) @@ -320,11 +321,16 @@ void ClearScreen(const MathUtil::Rectangle& rc) color = RGBA8ToRGB565ToRGBA8(color); z = Z24ToZ16ToZ24(z); } - g_framebuffer_manager->ClearEFB(rc, colorEnable, alphaEnable, zEnable, color, z); + frame_buffer_manager->ClearEFB(rc, color_enable, alpha_enable, z_enable, color, z, + pixel_format); + return true; } + + return false; } -void OnPixelFormatChange() +void OnPixelFormatChange(FramebufferManager* frame_buffer_manager, PixelFormat pixel_format, + DepthFormat z_format) { // TODO : Check for Z compression format change // When using 16bit Z, the game may enable a special compression format which we might need to @@ -342,11 +348,11 @@ void OnPixelFormatChange() if (!g_ActiveConfig.bEFBEmulateFormatChanges) return; - const auto old_format = g_framebuffer_manager->GetPrevPixelFormat(); - const auto new_format = bpmem.zcontrol.pixel_format; - g_framebuffer_manager->StorePixelFormat(new_format); + const auto old_format = frame_buffer_manager->GetPrevPixelFormat(); + const auto new_format = pixel_format; + frame_buffer_manager->StorePixelFormat(new_format); - DEBUG_LOG_FMT(VIDEO, "pixelfmt: pixel={}, zc={}", new_format, bpmem.zcontrol.zformat); + DEBUG_LOG_FMT(VIDEO, "pixelfmt: pixel={}, zc={}", new_format, z_format); // no need to reinterpret pixel data in these cases if (new_format == old_format || old_format == PixelFormat::INVALID_FMT) diff --git a/Source/Core/VideoCommon/BPFunctions.h b/Source/Core/VideoCommon/BPFunctions.h index f2fc66757ca..a91b98cc401 100644 --- a/Source/Core/VideoCommon/BPFunctions.h +++ b/Source/Core/VideoCommon/BPFunctions.h @@ -12,7 +12,9 @@ #include "Common/MathUtil.h" #include "VideoCommon/BPMemory.h" -struct XFMemory; + +class FramebufferManager; +struct Viewport; namespace BPFunctions { @@ -67,13 +69,14 @@ struct ScissorRect // under [Settings] to True in GFX.ini. struct ScissorResult { - ScissorResult(const BPMemory& bpmem, const XFMemory& xfmem); + ScissorResult(ScissorPos scissor_top_left, ScissorPos scissor_bottom_right, + ScissorOffset scissor_offset, const Viewport& viewport); ~ScissorResult() = default; ScissorResult(const ScissorResult& other) : scissor_tl{.hex = other.scissor_tl.hex}, scissor_br{.hex = other.scissor_br.hex}, scissor_off{.hex = other.scissor_off.hex}, viewport_left{other.viewport_left}, viewport_right{other.viewport_right}, viewport_top{other.viewport_top}, - viewport_bottom{other.viewport_bottom}, m_result{other.m_result} + viewport_bottom{other.viewport_bottom}, rectangles{other.rectangles} { } ScissorResult& operator=(const ScissorResult& other) @@ -87,14 +90,14 @@ struct ScissorResult viewport_right = other.viewport_right; viewport_top = other.viewport_top; viewport_bottom = other.viewport_bottom; - m_result = other.m_result; + rectangles = other.rectangles; return *this; } ScissorResult(ScissorResult&& other) : scissor_tl{.hex = other.scissor_tl.hex}, scissor_br{.hex = other.scissor_br.hex}, scissor_off{.hex = other.scissor_off.hex}, viewport_left{other.viewport_left}, viewport_right{other.viewport_right}, viewport_top{other.viewport_top}, - viewport_bottom{other.viewport_bottom}, m_result{std::move(other.m_result)} + viewport_bottom{other.viewport_bottom}, rectangles{std::move(other.rectangles)} { } ScissorResult& operator=(ScissorResult&& other) @@ -108,7 +111,7 @@ struct ScissorResult viewport_right = other.viewport_right; viewport_top = other.viewport_top; viewport_bottom = other.viewport_bottom; - m_result = std::move(other.m_result); + rectangles = std::move(other.rectangles); return *this; } @@ -121,8 +124,7 @@ struct ScissorResult float viewport_top; float viewport_bottom; - // Actual result - std::vector m_result; + std::vector rectangles; ScissorRect Best() const; @@ -146,21 +148,31 @@ struct ScissorResult } private: - ScissorResult(const BPMemory& bpmem, std::pair viewport_x, + ScissorResult(ScissorPos scissor_top_left, ScissorPos scissor_bottom_right, + ScissorOffset scissor_offset, std::pair viewport_x, std::pair viewport_y); int GetViewportArea(const ScissorRect& rect) const; bool IsWorse(const ScissorRect& lhs, const ScissorRect& rhs) const; }; -ScissorResult ComputeScissorRects(); +ScissorResult ComputeScissorRects(ScissorPos scissor_top_left, ScissorPos scissor_bottom_right, + ScissorOffset scissor_offset, const Viewport& viewport); void FlushPipeline(); void SetGenerationMode(); -void SetScissorAndViewport(); +void SetScissorAndViewport(FramebufferManager* frame_buffer_manager, ScissorPos scissor_top_left, + ScissorPos scissor_bottom_right, ScissorOffset scissor_offset, + Viewport viewport); void SetDepthMode(); void SetBlendMode(); -void ClearScreen(const MathUtil::Rectangle& rc); -void OnPixelFormatChange(); + +// Returns true if the EFB was triggered to clear +bool ClearScreen(FramebufferManager* frame_buffer_manager, const MathUtil::Rectangle& rc, + bool color_enable, bool alpha_enable, bool z_enable, PixelFormat pixel_format, + u32 clear_color_ar, u32 clear_color_gb, u32 clear_z_value); + +void OnPixelFormatChange(FramebufferManager* frame_buffer_manager, PixelFormat pixel_format, + DepthFormat z_format); void SetInterlacingMode(const BPCmd& bp); } // namespace BPFunctions diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 9679ed62375..dd0cd59570d 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -381,7 +381,19 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, XFStateManager& // Clear the rectangular region after copying it. if (PE_copy.clear) { - ClearScreen(srcRect); + const bool color_enable = bpmem.blendmode.color_update != 0; + const bool alpha_enable = bpmem.blendmode.alpha_update != 0; + const bool z_enable = bpmem.zmode.update_enable != 0; + const auto pixel_format = bpmem.zcontrol.pixel_format; + const auto color_ar = bpmem.clearcolorAR; + const auto color_gb = bpmem.clearcolorGB; + const auto z_value = bpmem.clearZValue; + ClearScreen(g_framebuffer_manager.get(), srcRect, color_enable, alpha_enable, z_enable, + pixel_format, color_ar, color_gb, z_value); + + // Scissor rect must be restored. + BPFunctions::SetScissorAndViewport(g_framebuffer_manager.get(), bpmem.scissorTL, + bpmem.scissorBR, bpmem.scissorOffset, xfmem.viewport); } return; @@ -523,7 +535,8 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, XFStateManager& return; case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format - OnPixelFormatChange(); + OnPixelFormatChange(g_framebuffer_manager.get(), bpmem.zcontrol.pixel_format, + bpmem.zcontrol.zformat); if (bp.changes & 7) SetBlendMode(); // dual source could be activated by changing to PIXELFMT_RGBA6_Z24 pixel_shader_manager.SetZModeControl(); @@ -1355,8 +1368,10 @@ void BPReload() // let's not risk actually replaying any writes. // note that PixelShaderManager is already covered since it has its own DoState. SetGenerationMode(); - SetScissorAndViewport(); + BPFunctions::SetScissorAndViewport(g_framebuffer_manager.get(), bpmem.scissorTL, bpmem.scissorBR, + bpmem.scissorOffset, xfmem.viewport); SetDepthMode(); SetBlendMode(); - OnPixelFormatChange(); + OnPixelFormatChange(g_framebuffer_manager.get(), bpmem.zcontrol.pixel_format, + bpmem.zcontrol.zformat); } diff --git a/Source/Core/VideoCommon/FramebufferManager.cpp b/Source/Core/VideoCommon/FramebufferManager.cpp index 9d2382c190c..5a3c768311b 100644 --- a/Source/Core/VideoCommon/FramebufferManager.cpp +++ b/Source/Core/VideoCommon/FramebufferManager.cpp @@ -856,7 +856,8 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async } void FramebufferManager::ClearEFB(const MathUtil::Rectangle& rc, bool color_enable, - bool alpha_enable, bool z_enable, u32 color, u32 z) + bool alpha_enable, bool z_enable, u32 color, u32 z, + PixelFormat pixel_format) { FlushEFBPokes(); FlagPeekCacheAsOutOfDate(); @@ -870,9 +871,8 @@ void FramebufferManager::ClearEFB(const MathUtil::Rectangle& rc, bool color // channel to 0xFF. // On backends that don't allow masking Alpha clears, this allows us to use the fast path // almost all the time - if (bpmem.zcontrol.pixel_format == PixelFormat::RGB565_Z16 || - bpmem.zcontrol.pixel_format == PixelFormat::RGB8_Z24 || - bpmem.zcontrol.pixel_format == PixelFormat::Z24) + if (pixel_format == PixelFormat::RGB565_Z16 || pixel_format == PixelFormat::RGB8_Z24 || + pixel_format == PixelFormat::Z24) { // Force alpha writes, and clear the alpha channel. alpha_enable = true; @@ -880,9 +880,6 @@ void FramebufferManager::ClearEFB(const MathUtil::Rectangle& rc, bool color } g_gfx->ClearRegion(target_rc, color_enable, alpha_enable, z_enable, color, z); - - // Scissor rect must be restored. - BPFunctions::SetScissorAndViewport(); } bool FramebufferManager::CompileClearPipelines() diff --git a/Source/Core/VideoCommon/FramebufferManager.h b/Source/Core/VideoCommon/FramebufferManager.h index e6e7cdc920e..62c8c177fc2 100644 --- a/Source/Core/VideoCommon/FramebufferManager.h +++ b/Source/Core/VideoCommon/FramebufferManager.h @@ -110,7 +110,7 @@ public: // Clears the EFB using shaders. void ClearEFB(const MathUtil::Rectangle& rc, bool clear_color, bool clear_alpha, - bool clear_z, u32 color, u32 z); + bool clear_z, u32 color, u32 z, PixelFormat pixel_format); AbstractPipeline* GetClearPipeline(bool clear_color, bool clear_alpha, bool clear_z) const; diff --git a/Source/Core/VideoCommon/Statistics.cpp b/Source/Core/VideoCommon/Statistics.cpp index 6c35ed09fda..db098db5c7f 100644 --- a/Source/Core/VideoCommon/Statistics.cpp +++ b/Source/Core/VideoCommon/Statistics.cpp @@ -16,6 +16,7 @@ #include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoEvents.h" +#include "VideoCommon/XFMemory.h" Statistics g_stats; @@ -161,7 +162,8 @@ void Statistics::AddScissorRect() clear_scissors = false; } - BPFunctions::ScissorResult scissor = BPFunctions::ComputeScissorRects(); + BPFunctions::ScissorResult scissor = BPFunctions::ComputeScissorRects( + bpmem.scissorTL, bpmem.scissorBR, bpmem.scissorOffset, xfmem.viewport); bool add; if (scissors.empty()) { @@ -311,13 +313,13 @@ void Statistics::DisplayScissor() draw_rect(info.viewport_left, info.viewport_top, info.viewport_right, info.viewport_bottom, col); } - for (size_t i = 0; i < info.m_result.size(); i++) + for (size_t i = 0; i < info.rectangles.size(); i++) { // The last entry in the sorted list of results is the one that is used by hardware backends - const u8 new_alpha = (i == info.m_result.size() - 1) ? 0x40 : 0x80; + const u8 new_alpha = (i == info.rectangles.size() - 1) ? 0x40 : 0x80; const ImU32 new_col = (col & ~IM_COL32_A_MASK) | (new_alpha << IM_COL32_A_SHIFT); - const auto& r = info.m_result[i]; + const auto& r = info.rectangles[i]; draw_list->AddRectFilled(vec(r.rect.left + r.x_off, r.rect.top + r.y_off), vec(r.rect.right + r.x_off, r.rect.bottom + r.y_off), new_col); } @@ -365,14 +367,14 @@ void Statistics::DisplayScissor() ImVec2 p2 = ImGui::GetCursorScreenPos(); // Use a height of 1 since we want this to span two table rows (if possible) ImGui::Dummy(ImVec2(EFB_WIDTH * scale_height, 1)); - for (size_t i = 0; i < info.m_result.size(); i++) + for (size_t i = 0; i < info.rectangles.size(); i++) { // The last entry in the sorted list of results is the one that is used by hardware backends - const u8 new_alpha = (i == info.m_result.size() - 1) ? 0x80 : 0x40; + const u8 new_alpha = (i == info.rectangles.size() - 1) ? 0x80 : 0x40; const ImU32 col = ImGui::GetColorU32(COLORS[index % COLORS.size()]); const ImU32 new_col = (col & ~IM_COL32_A_MASK) | (new_alpha << IM_COL32_A_SHIFT); - const auto& r = info.m_result[i]; + const auto& r = info.rectangles[i]; draw_list->AddRectFilled( ImVec2(p2.x + r.rect.left * scale_height, p2.y + r.rect.top * scale_height), ImVec2(p2.x + r.rect.right * scale_height, p2.y + r.rect.bottom * scale_height), new_col); @@ -380,7 +382,7 @@ void Statistics::DisplayScissor() draw_list->AddRect( p2, ImVec2(p2.x + EFB_WIDTH * scale_height, p2.y + EFB_HEIGHT * scale_height), light_grey); ImGui::SameLine(); - ImGui::Text("%d", int(info.m_result.size())); + ImGui::Text("%d", int(info.rectangles.size())); if (show_raw_scissors) { diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 4dba5432bc4..973b944d98b 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -388,7 +388,8 @@ void VertexShaderManager::SetConstants(const std::vector& textures, } dirty = true; - BPFunctions::SetScissorAndViewport(); + BPFunctions::SetScissorAndViewport(g_framebuffer_manager.get(), bpmem.scissorTL, + bpmem.scissorBR, bpmem.scissorOffset, xfmem.viewport); g_stats.AddScissorRect(); } diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 60668f9f2d7..0214dab9dde 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -20,6 +20,7 @@ #include "VideoCommon/AbstractGfx.h" #include "VideoCommon/BPFunctions.h" +#include "VideoCommon/BPMemory.h" #include "VideoCommon/DriverDetails.h" #include "VideoCommon/Fifo.h" #include "VideoCommon/FramebufferManager.h" @@ -30,6 +31,7 @@ #include "VideoCommon/ShaderGenCommon.h" #include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/VertexManagerBase.h" +#include "VideoCommon/XFMemory.h" VideoConfig g_Config; VideoConfig g_ActiveConfig; @@ -383,7 +385,8 @@ void CheckForConfigChanges() // Viewport and scissor rect have to be reset since they will be scaled differently. if (changed_bits & CONFIG_CHANGE_BIT_TARGET_SIZE) { - BPFunctions::SetScissorAndViewport(); + BPFunctions::SetScissorAndViewport(g_framebuffer_manager.get(), bpmem.scissorTL, + bpmem.scissorBR, bpmem.scissorOffset, xfmem.viewport); } // Notify all listeners