diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp index 9fbf560ecf..903b430aff 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp @@ -18,6 +18,7 @@ #include "VideoBackends/Software/Tev.h" #include "VideoBackends/Software/TransformUnit.h" +#include "VideoCommon/BoundingBox.h" #include "VideoCommon/CPMemory.h" #include "VideoCommon/DataReader.h" #include "VideoCommon/IndexGenerator.h" @@ -62,8 +63,8 @@ void SWVertexLoader::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_ } // Flush bounding box here because software overrides the base function - if (g_renderer->IsBBoxEnabled()) - g_renderer->BBoxFlush(); + if (g_bounding_box->IsEnabled()) + g_bounding_box->Flush(); m_setup_unit.Init(primitive_type); Rasterizer::SetTevKonstColors(); diff --git a/Source/Core/VideoCommon/AsyncRequests.cpp b/Source/Core/VideoCommon/AsyncRequests.cpp index aca5be57a4..4ab52845f9 100644 --- a/Source/Core/VideoCommon/AsyncRequests.cpp +++ b/Source/Core/VideoCommon/AsyncRequests.cpp @@ -6,6 +6,8 @@ #include #include "Core/System.h" + +#include "VideoCommon/BoundingBox.h" #include "VideoCommon/Fifo.h" #include "VideoCommon/RenderBase.h" #include "VideoCommon/Statistics.h" @@ -157,7 +159,7 @@ void AsyncRequests::HandleEvent(const AsyncRequests::Event& e) break; case Event::BBOX_READ: - *e.bbox.data = g_renderer->BBoxRead(e.bbox.index); + *e.bbox.data = g_bounding_box->Get(e.bbox.index); break; case Event::FIFO_RESET: diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 4e1114e87d..8979031d3d 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -285,7 +285,7 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, if (PE_copy.copy_to_xfb == 1) { // Make sure we disable Bounding box to match the side effects of the non-failure path - g_renderer->BBoxDisable(pixel_shader_manager); + g_bounding_box->Disable(pixel_shader_manager); } return; @@ -316,7 +316,7 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, // We should be able to get away with deactivating the current bbox tracking // here. Not sure if there's a better spot to put this. // the number of lines copied is determined by the y scale * source efb height - g_renderer->BBoxDisable(pixel_shader_manager); + g_bounding_box->Disable(pixel_shader_manager); float yScale; if (PE_copy.scale_invert) @@ -484,10 +484,10 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, case BPMEM_CLEARBBOX2: { const u8 offset = bp.address & 2; - g_renderer->BBoxEnable(pixel_shader_manager); + g_bounding_box->Enable(pixel_shader_manager); - g_renderer->BBoxWrite(offset, bp.newvalue & 0x3ff); - g_renderer->BBoxWrite(offset + 1, bp.newvalue >> 10); + g_bounding_box->Set(offset, bp.newvalue & 0x3ff); + g_bounding_box->Set(offset + 1, bp.newvalue >> 10); } return; case BPMEM_TEXINVALIDATE: diff --git a/Source/Core/VideoCommon/BoundingBox.cpp b/Source/Core/VideoCommon/BoundingBox.cpp index 0429559846..ffc85d824c 100644 --- a/Source/Core/VideoCommon/BoundingBox.cpp +++ b/Source/Core/VideoCommon/BoundingBox.cpp @@ -29,7 +29,7 @@ void BoundingBox::Disable(PixelShaderManager& pixel_shader_manager) void BoundingBox::Flush() { - if (!g_ActiveConfig.backend_info.bSupportsBBox) + if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) return; m_is_valid = false; @@ -76,6 +76,9 @@ u16 BoundingBox::Get(u32 index) { ASSERT(index < NUM_BBOX_VALUES); + if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) + return m_bounding_box_fallback[index]; + if (!m_is_valid) Readback(); @@ -86,6 +89,12 @@ void BoundingBox::Set(u32 index, u16 value) { ASSERT(index < NUM_BBOX_VALUES); + if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) + { + m_bounding_box_fallback[index] = value; + return; + } + if (m_is_valid && m_values[index] == value) return; @@ -98,6 +107,7 @@ void BoundingBox::Set(u32 index, u16 value) // Nonetheless, it has been designed to be as safe as possible. void BoundingBox::DoState(PointerWrap& p) { + p.DoArray(m_bounding_box_fallback); p.Do(m_is_active); p.DoArray(m_values); p.DoArray(m_dirty); diff --git a/Source/Core/VideoCommon/BoundingBox.h b/Source/Core/VideoCommon/BoundingBox.h index d8d2508716..ed4861d6ad 100644 --- a/Source/Core/VideoCommon/BoundingBox.h +++ b/Source/Core/VideoCommon/BoundingBox.h @@ -49,6 +49,18 @@ private: std::array m_values = {}; std::array m_dirty = {}; bool m_is_valid = true; + + // Nintendo's SDK seems to write "default" bounding box values before every draw (1023 0 1023 0 + // are the only values encountered so far, which happen to be the extents allowed by the BP + // registers) to reset the registers for comparison in the pixel engine, and presumably to detect + // whether GX has updated the registers with real values. + // + // We can store these values when Bounding Box emulation is disabled and return them on read, + // which the game will interpret as "no pixels have been drawn" + // + // This produces much better results than just returning garbage, which can cause games like + // Ultimate Spider-Man to crash + std::array m_bounding_box_fallback = {}; }; extern std::unique_ptr g_bounding_box; diff --git a/Source/Core/VideoCommon/PixelEngine.cpp b/Source/Core/VideoCommon/PixelEngine.cpp index 82464339e4..9817e38c07 100644 --- a/Source/Core/VideoCommon/PixelEngine.cpp +++ b/Source/Core/VideoCommon/PixelEngine.cpp @@ -20,7 +20,6 @@ #include "VideoCommon/BoundingBox.h" #include "VideoCommon/Fifo.h" #include "VideoCommon/PerfQueryBase.h" -#include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoBackendBase.h" namespace PixelEngine @@ -148,7 +147,7 @@ void PixelEngineManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base) { mmio->Register(base | (PE_BBOX_LEFT + 2 * i), MMIO::ComplexRead([i](Core::System& system, u32) { - g_renderer->BBoxDisable(system.GetPixelShaderManager()); + g_bounding_box->Disable(system.GetPixelShaderManager()); return g_video_backend->Video_GetBoundingBox(i); }), MMIO::InvalidWrite()); diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 1d7cc375d6..aa81601362 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -16,7 +16,6 @@ #include "VideoCommon/DriverDetails.h" #include "VideoCommon/LightingShaderGen.h" #include "VideoCommon/NativeVertexFormat.h" -#include "VideoCommon/RenderBase.h" #include "VideoCommon/RenderState.h" #include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VideoCommon.h" @@ -180,7 +179,7 @@ PixelShaderUid GetPixelShaderUid() uid_data->genMode_numindstages = bpmem.genMode.numindstages; uid_data->genMode_numtevstages = bpmem.genMode.numtevstages; uid_data->genMode_numtexgens = bpmem.genMode.numtexgens; - uid_data->bounding_box = g_ActiveConfig.bBBoxEnable && g_renderer->IsBBoxEnabled(); + uid_data->bounding_box = g_ActiveConfig.bBBoxEnable && g_bounding_box->IsEnabled(); uid_data->rgba6_format = bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24 && !g_ActiveConfig.bForceTrueColor; uid_data->dither = bpmem.blendmode.dither && uid_data->rgba6_format; diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 159dd6baaf..1bd0420a48 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -95,11 +95,6 @@ bool Renderer::Initialize() return true; } -void Renderer::Shutdown() -{ - g_bounding_box.reset(); -} - void Renderer::BeginUtilityDrawing() { g_vertex_manager->Flush(); @@ -151,48 +146,6 @@ void Renderer::ReinterpretPixelData(EFBReinterpretType convtype) g_framebuffer_manager->ReinterpretPixelData(convtype); } -bool Renderer::IsBBoxEnabled() const -{ - return g_bounding_box->IsEnabled(); -} - -void Renderer::BBoxEnable(PixelShaderManager& pixel_shader_manager) -{ - g_bounding_box->Enable(pixel_shader_manager); -} - -void Renderer::BBoxDisable(PixelShaderManager& pixel_shader_manager) -{ - g_bounding_box->Disable(pixel_shader_manager); -} - -u16 Renderer::BBoxRead(u32 index) -{ - if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) - return m_bounding_box_fallback[index]; - - return g_bounding_box->Get(index); -} - -void Renderer::BBoxWrite(u32 index, u16 value) -{ - if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) - { - m_bounding_box_fallback[index] = value; - return; - } - - g_bounding_box->Set(index, value); -} - -void Renderer::BBoxFlush() -{ - if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) - return; - - g_bounding_box->Flush(); -} - u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) { if (type == EFBAccessType::PeekColor) @@ -716,7 +669,6 @@ void Renderer::DoState(PointerWrap& p) p.Do(m_last_xfb_width); p.Do(m_last_xfb_stride); p.Do(m_last_xfb_height); - p.DoArray(m_bounding_box_fallback); g_bounding_box->DoState(p); diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 6a9d86387c..6776110492 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -33,7 +33,6 @@ class AbstractPipeline; class AbstractShader; class AbstractTexture; class AbstractStagingTexture; -class BoundingBox; class NativeVertexFormat; class PixelShaderManager; class PointerWrap; @@ -68,7 +67,6 @@ public: virtual ~Renderer(); virtual bool Initialize(); - virtual void Shutdown(); void BeginUtilityDrawing(); void EndUtilityDrawing(); @@ -99,13 +97,6 @@ public: virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); virtual void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points); - bool IsBBoxEnabled() const; - void BBoxEnable(PixelShaderManager& pixel_shader_manager); - void BBoxDisable(PixelShaderManager& pixel_shader_manager); - u16 BBoxRead(u32 index); - void BBoxWrite(u32 index, u16 value); - void BBoxFlush(); - // Finish up the current frame, print some stats void Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks); @@ -152,20 +143,6 @@ private: u32 m_last_xfb_stride = 0; u32 m_last_xfb_height = 0; - std::unique_ptr m_bounding_box; - - // Nintendo's SDK seems to write "default" bounding box values before every draw (1023 0 1023 0 - // are the only values encountered so far, which happen to be the extents allowed by the BP - // registers) to reset the registers for comparison in the pixel engine, and presumably to detect - // whether GX has updated the registers with real values. - // - // We can store these values when Bounding Box emulation is disabled and return them on read, - // which the game will interpret as "no pixels have been drawn" - // - // This produces much better results than just returning garbage, which can cause games like - // Ultimate Spider-Man to crash - std::array m_bounding_box_fallback = {}; - Common::Flag m_force_reload_textures; GraphicsModManager m_graphics_mod_manager; diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 5f6b8a310e..71e766c000 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -324,10 +324,10 @@ void VertexManagerBase::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 nu void VertexManagerBase::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex) { // If bounding box is enabled, we need to flush any changes first, then invalidate what we have. - if (g_renderer->IsBBoxEnabled() && g_ActiveConfig.bBBoxEnable && + if (g_bounding_box->IsEnabled() && g_ActiveConfig.bBBoxEnable && g_ActiveConfig.backend_info.bSupportsBBox) { - g_renderer->BBoxFlush(); + g_bounding_box->Flush(); } g_gfx->DrawIndexed(base_index, num_indices, base_vertex); diff --git a/Source/Core/VideoCommon/VideoBackendBase.cpp b/Source/Core/VideoCommon/VideoBackendBase.cpp index 5119ba5ed1..144c215ad9 100644 --- a/Source/Core/VideoCommon/VideoBackendBase.cpp +++ b/Source/Core/VideoCommon/VideoBackendBase.cpp @@ -395,8 +395,6 @@ void VideoBackendBase::ShutdownShared() if (g_shader_cache) g_shader_cache->Shutdown(); - if (g_renderer) - g_renderer->Shutdown(); if (g_texture_cache) g_texture_cache->Shutdown();