diff options
Diffstat (limited to 'Source/Core/VideoCommon/BPFunctions.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/BPFunctions.cpp | 92 |
1 files changed, 49 insertions, 43 deletions
diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp index 7d1bd05482..1018af0142 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<float, float> viewport_x, +ScissorResult::ScissorResult(ScissorPos scissor_top_left, ScissorPos scissor_bottom_right, + ScissorOffset scissor_offset, std::pair<float, float> viewport_x, std::pair<float, float> 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) { @@ -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<int>& rc) +bool ClearScreen(FramebufferManager* frame_buffer_manager, const MathUtil::Rectangle<int>& 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<int>& 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) |
