From efbe5bc4b651d1f7f726bb064255e0e2562f7490 Mon Sep 17 00:00:00 2001 From: degasus Date: Fri, 9 Oct 2015 20:50:36 +0200 Subject: [PATCH] VideoSW: Use more VideoCommon Now we require lots of empty functions, but this removes by far more duplicated code. --- Source/Core/DolphinWX/FrameTools.cpp | 2 - .../DolphinWX/SoftwareVideoConfigDialog.cpp | 23 +- .../DolphinWX/SoftwareVideoConfigDialog.h | 6 +- Source/Core/DolphinWX/VideoConfigDiag.h | 2 - .../VideoBackends/Software/BPMemLoader.cpp | 178 -------- .../Core/VideoBackends/Software/BPMemLoader.h | 13 - .../VideoBackends/Software/CMakeLists.txt | 11 +- .../VideoBackends/Software/CPMemLoader.cpp | 60 --- .../Core/VideoBackends/Software/CPMemLoader.h | 10 - .../Core/VideoBackends/Software/Clipper.cpp | 24 +- Source/Core/VideoBackends/Software/Clipper.h | 3 - .../Core/VideoBackends/Software/DebugUtil.cpp | 42 +- .../Core/VideoBackends/Software/DebugUtil.h | 2 - .../Core/VideoBackends/Software/EfbCopy.cpp | 39 +- Source/Core/VideoBackends/Software/EfbCopy.h | 3 +- .../VideoBackends/Software/EfbInterface.cpp | 7 +- .../VideoBackends/Software/EfbInterface.h | 2 - .../Software/NativeVertexFormat.h | 12 - .../VideoBackends/Software/OpcodeDecoder.cpp | 304 -------------- .../VideoBackends/Software/OpcodeDecoder.h | 52 --- .../VideoBackends/Software/Rasterizer.cpp | 37 +- .../Core/VideoBackends/Software/Rasterizer.h | 8 - .../Software/SWCommandProcessor.cpp | 354 ---------------- .../Software/SWCommandProcessor.h | 61 --- .../VideoBackends/Software/SWRenderer.cpp | 154 ++++--- .../Core/VideoBackends/Software/SWRenderer.h | 40 +- .../VideoBackends/Software/SWStatistics.cpp | 18 - .../VideoBackends/Software/SWStatistics.h | 47 --- .../VideoBackends/Software/SWVertexLoader.cpp | 172 +++++--- .../VideoBackends/Software/SWVertexLoader.h | 35 +- .../VideoBackends/Software/SWVideoConfig.cpp | 91 ---- .../VideoBackends/Software/SWVideoConfig.h | 43 -- Source/Core/VideoBackends/Software/SWmain.cpp | 397 +++++++----------- .../Core/VideoBackends/Software/SetupUnit.cpp | 21 +- .../Core/VideoBackends/Software/SetupUnit.h | 3 - .../VideoBackends/Software/Software.vcxproj | 14 - Source/Core/VideoBackends/Software/Tev.cpp | 49 +-- Source/Core/VideoBackends/Software/Tev.h | 6 +- .../VideoBackends/Software/TextureEncoder.cpp | 2 +- .../VideoBackends/Software/TextureSampler.cpp | 3 +- .../VideoBackends/Software/TransformUnit.cpp | 5 +- Source/Core/VideoBackends/Software/Vec3.h | 7 - .../VideoBackends/Software/VideoBackend.h | 34 +- .../VideoBackends/Software/XFMemLoader.cpp | 86 ---- .../Core/VideoBackends/Software/XFMemLoader.h | 17 - Source/Core/VideoCommon/CPMemory.h | 1 + Source/Core/VideoCommon/Statistics.cpp | 16 + Source/Core/VideoCommon/Statistics.h | 11 + .../Core/VideoCommon/VertexLoaderManager.cpp | 1 + Source/Core/VideoCommon/VideoConfig.cpp | 17 + Source/Core/VideoCommon/VideoConfig.h | 9 + 51 files changed, 529 insertions(+), 2025 deletions(-) delete mode 100644 Source/Core/VideoBackends/Software/BPMemLoader.cpp delete mode 100644 Source/Core/VideoBackends/Software/BPMemLoader.h delete mode 100644 Source/Core/VideoBackends/Software/CPMemLoader.cpp delete mode 100644 Source/Core/VideoBackends/Software/CPMemLoader.h delete mode 100644 Source/Core/VideoBackends/Software/OpcodeDecoder.cpp delete mode 100644 Source/Core/VideoBackends/Software/OpcodeDecoder.h delete mode 100644 Source/Core/VideoBackends/Software/SWCommandProcessor.cpp delete mode 100644 Source/Core/VideoBackends/Software/SWCommandProcessor.h delete mode 100644 Source/Core/VideoBackends/Software/SWStatistics.cpp delete mode 100644 Source/Core/VideoBackends/Software/SWStatistics.h delete mode 100644 Source/Core/VideoBackends/Software/SWVideoConfig.cpp delete mode 100644 Source/Core/VideoBackends/Software/SWVideoConfig.h delete mode 100644 Source/Core/VideoBackends/Software/XFMemLoader.cpp delete mode 100644 Source/Core/VideoBackends/Software/XFMemLoader.h diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index e960eda15d..db0acc7fe0 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -76,8 +76,6 @@ #include "InputCommon/ControllerInterface/ControllerInterface.h" -#include "VideoBackends/Software/SWVideoConfig.h" - #include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" diff --git a/Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp b/Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp index fb2fbddbcd..eba84552a2 100644 --- a/Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp +++ b/Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp @@ -31,13 +31,16 @@ IntegerSetting::IntegerSetting(wxWindow* parent, const wxString& label, T& se } -SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std::string& title, const std::string& _ininame) : +SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std::string& title, const std::string& ininame) : wxDialog(parent, wxID_ANY, - wxString(wxString::Format(_("Dolphin %s Graphics Configuration"), title))), - vconfig(g_SWVideoConfig), - ininame(_ininame) + wxString(wxString::Format(_("Dolphin %s Graphics Configuration"), title))) { - vconfig.Load((File::GetUserPath(D_CONFIG_IDX) + ininame + ".ini").c_str()); + VideoConfig& vconfig = g_ActiveConfig; + + if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + "GFX.ini")) + vconfig.Load(File::GetUserPath(D_CONFIG_IDX) + "GFX.ini"); + else + vconfig.Load(File::GetUserPath(D_CONFIG_IDX) + ininame + ".ini"); wxNotebook* const notebook = new wxNotebook(this, wxID_ANY); @@ -77,7 +80,7 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std } // xfb - szr_rendering->Add(new SettingCheckBox(page_general, _("Bypass XFB"), "", vconfig.bBypassXFB)); + szr_rendering->Add(new SettingCheckBox(page_general, _("Bypass XFB"), "", vconfig.bUseXFB, true)); } // - info @@ -87,7 +90,7 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std wxGridSizer* const szr_info = new wxGridSizer(2, 5, 5); group_info->Add(szr_info, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); - szr_info->Add(new SettingCheckBox(page_general, _("Various Statistics"), "", vconfig.bShowStats)); + szr_info->Add(new SettingCheckBox(page_general, _("Various Statistics"), "", vconfig.bOverlayStats)); } // - utility @@ -117,8 +120,8 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std wxFlexGridSizer* const szr_misc = new wxFlexGridSizer(2, 5, 5); group_misc->Add(szr_misc, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); - szr_misc->Add(new U32Setting(page_general, _("Start"), vconfig.drawStart, 0, 100000)); - szr_misc->Add(new U32Setting(page_general, _("End"), vconfig.drawEnd, 0, 100000)); + szr_misc->Add(new IntegerSetting(page_general, _("Start"), vconfig.drawStart, 0, 100000)); + szr_misc->Add(new IntegerSetting(page_general, _("End"), vconfig.drawEnd, 0, 100000)); } page_general->SetSizerAndFit(szr_general); @@ -136,5 +139,5 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std SoftwareVideoConfigDialog::~SoftwareVideoConfigDialog() { - g_SWVideoConfig.Save((File::GetUserPath(D_CONFIG_IDX) + ininame + ".ini").c_str()); + g_ActiveConfig.Save((File::GetUserPath(D_CONFIG_IDX) + "GFX.ini").c_str()); } diff --git a/Source/Core/DolphinWX/SoftwareVideoConfigDialog.h b/Source/Core/DolphinWX/SoftwareVideoConfigDialog.h index 7b23211476..221ec0f209 100644 --- a/Source/Core/DolphinWX/SoftwareVideoConfigDialog.h +++ b/Source/Core/DolphinWX/SoftwareVideoConfigDialog.h @@ -13,8 +13,8 @@ #include #include "Core/ConfigManager.h" -#include "VideoBackends/Software/SWVideoConfig.h" #include "VideoCommon/VideoBackendBase.h" +#include "VideoCommon/VideoConfig.h" class SoftwareVideoConfigDialog : public wxDialog { @@ -37,8 +37,4 @@ public: } ev.Skip(); } - -protected: - SWVideoConfig& vconfig; - std::string ininame; }; diff --git a/Source/Core/DolphinWX/VideoConfigDiag.h b/Source/Core/DolphinWX/VideoConfigDiag.h index a52960953a..24f91d87f0 100644 --- a/Source/Core/DolphinWX/VideoConfigDiag.h +++ b/Source/Core/DolphinWX/VideoConfigDiag.h @@ -65,8 +65,6 @@ private: T& m_setting; }; -typedef IntegerSetting U32Setting; - class SettingChoice : public wxChoice { public: diff --git a/Source/Core/VideoBackends/Software/BPMemLoader.cpp b/Source/Core/VideoBackends/Software/BPMemLoader.cpp deleted file mode 100644 index fefe028f64..0000000000 --- a/Source/Core/VideoBackends/Software/BPMemLoader.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "Core/ConfigManager.h" -#include "Core/Core.h" -#include "Core/HW/Memmap.h" - -#include "VideoBackends/Software/BPMemLoader.h" -#include "VideoBackends/Software/EfbCopy.h" -#include "VideoBackends/Software/EfbInterface.h" -#include "VideoBackends/Software/Rasterizer.h" -#include "VideoBackends/Software/Tev.h" - -#include "VideoCommon/BoundingBox.h" -#include "VideoCommon/PixelEngine.h" -#include "VideoCommon/TextureDecoder.h" -#include "VideoCommon/VideoCommon.h" - - -void InitBPMemory() -{ - memset(&bpmem, 0, sizeof(bpmem)); - bpmem.bpMask = 0xFFFFFF; -} - -void SWLoadBPReg(u32 value) -{ - //handle the mask register - int address = value >> 24; - int oldval = ((u32*)&bpmem)[address]; - int newval = (oldval & ~bpmem.bpMask) | (value & bpmem.bpMask); - - ((u32*)&bpmem)[address] = newval; - - //reset the mask register - if (address != 0xFE) - bpmem.bpMask = 0xFFFFFF; - - SWBPWritten(address, newval); -} - -void SWBPWritten(int address, int newvalue) -{ - switch (address) - { - case BPMEM_SCISSORTL: - case BPMEM_SCISSORBR: - case BPMEM_SCISSOROFFSET: - Rasterizer::SetScissor(); - break; - case BPMEM_SETDRAWDONE: // This is called when the game is done drawing (eg: like in DX: Begin(); Draw(); End();) - switch (bpmem.drawdone & 0xFF) - { - case 0x02: - PixelEngine::SetFinish(); // may generate interrupt - DEBUG_LOG(VIDEO, "GXSetDrawDone SetPEFinish (value: 0x%02X)", (bpmem.drawdone & 0xFFFF)); - break; - - default: - WARN_LOG(VIDEO, "GXSetDrawDone ??? (value 0x%02X)", (bpmem.drawdone & 0xFFFF)); - break; - } - break; - case BPMEM_PE_TOKEN_ID: // Pixel Engine Token ID - DEBUG_LOG(VIDEO, "SetPEToken 0x%04x", (bpmem.petoken & 0xFFFF)); - PixelEngine::SetToken(static_cast(bpmem.petokenint & 0xFFFF), false); - break; - case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID - DEBUG_LOG(VIDEO, "SetPEToken + INT 0x%04x", (bpmem.petokenint & 0xFFFF)); - PixelEngine::SetToken(static_cast(bpmem.petokenint & 0xFFFF), true); - break; - case BPMEM_TRIGGER_EFB_COPY: - EfbCopy::CopyEfb(); - break; - case BPMEM_CLEARBBOX1: - BoundingBox::coords[BoundingBox::LEFT] = newvalue >> 10; - BoundingBox::coords[BoundingBox::RIGHT] = newvalue & 0x3ff; - break; - case BPMEM_CLEARBBOX2: - BoundingBox::coords[BoundingBox::TOP] = newvalue >> 10; - BoundingBox::coords[BoundingBox::BOTTOM] = newvalue & 0x3ff; - break; - case BPMEM_CLEAR_PIXEL_PERF: - // TODO: I didn't test if the value written to this register affects the amount of cleared registers - memset(EfbInterface::perf_values, 0, sizeof(EfbInterface::perf_values)); - break; - case BPMEM_LOADTLUT0: // This one updates bpmem.tlutXferSrc, no need to do anything here. - break; - case BPMEM_LOADTLUT1: // Load a Texture Look Up Table - { - u32 tlutTMemAddr = (newvalue & 0x3FF) << 9; - u32 tlutXferCount = (newvalue & 0x1FFC00) >> 5; - u32 addr = bpmem.tmem_config.tlut_src << 5; - - // The GameCube ignores the upper bits of this address. Some games (WW, MKDD) set them. - if (!SConfig::GetInstance().bWii) - addr = addr & 0x01FFFFFF; - - Memory::CopyFromEmu(texMem + tlutTMemAddr, addr, tlutXferCount); - - break; - } - - case BPMEM_PRELOAD_MODE: - if (newvalue != 0) - { - // TODO: Not quite sure if this is completely correct (likely not) - // NOTE: libogc's implementation of GX_PreloadEntireTexture seems flawed, so it's not necessarily a good reference for RE'ing this feature. - - BPS_TmemConfig& tmem_cfg = bpmem.tmem_config; - u32 src_addr = tmem_cfg.preload_addr << 5; // TODO: Should we add mask here on GC? - u32 size = tmem_cfg.preload_tile_info.count * TMEM_LINE_SIZE; - u32 tmem_addr_even = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE; - - if (tmem_cfg.preload_tile_info.type != 3) - { - if (tmem_addr_even + size > TMEM_SIZE) - size = TMEM_SIZE - tmem_addr_even; - - Memory::CopyFromEmu(texMem + tmem_addr_even, src_addr, size); - } - else // RGBA8 tiles (and CI14, but that might just be stupid libogc!) - { - u8* src_ptr = Memory::GetPointer(src_addr); - - // AR and GB tiles are stored in separate TMEM banks => can't use a single memcpy for everything - u32 tmem_addr_odd = tmem_cfg.preload_tmem_odd * TMEM_LINE_SIZE; - - for (unsigned int i = 0; i < tmem_cfg.preload_tile_info.count; ++i) - { - if (tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE || - tmem_addr_odd + TMEM_LINE_SIZE > TMEM_SIZE) - break; - - memcpy(texMem + tmem_addr_even, src_ptr, TMEM_LINE_SIZE); - memcpy(texMem + tmem_addr_odd, src_ptr + TMEM_LINE_SIZE, TMEM_LINE_SIZE); - tmem_addr_even += TMEM_LINE_SIZE; - tmem_addr_odd += TMEM_LINE_SIZE; - src_ptr += TMEM_LINE_SIZE * 2; - } - } - } - break; - - case BPMEM_TEV_COLOR_RA: - case BPMEM_TEV_COLOR_RA + 2: - case BPMEM_TEV_COLOR_RA + 4: - case BPMEM_TEV_COLOR_RA + 6: - { - int regNum = (address >> 1 ) & 0x3; - TevReg& reg = bpmem.tevregs[regNum]; - bool is_konst = reg.type_ra != 0; - - Rasterizer::SetTevReg(regNum, Tev::ALP_C, is_konst, static_cast(reg.alpha)); - Rasterizer::SetTevReg(regNum, Tev::RED_C, is_konst, static_cast(reg.red)); - - break; - } - - case BPMEM_TEV_COLOR_BG: - case BPMEM_TEV_COLOR_BG + 2: - case BPMEM_TEV_COLOR_BG + 4: - case BPMEM_TEV_COLOR_BG + 6: - { - int regNum = (address >> 1 ) & 0x3; - TevReg& reg = bpmem.tevregs[regNum]; - bool is_konst = reg.type_bg != 0; - - Rasterizer::SetTevReg(regNum, Tev::GRN_C, is_konst, static_cast(reg.green)); - Rasterizer::SetTevReg(regNum, Tev::BLU_C, is_konst, static_cast(reg.blue)); - - break; - } - - } -} - diff --git a/Source/Core/VideoBackends/Software/BPMemLoader.h b/Source/Core/VideoBackends/Software/BPMemLoader.h deleted file mode 100644 index 71cd076d8e..0000000000 --- a/Source/Core/VideoBackends/Software/BPMemLoader.h +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - - -#include "Common/CommonTypes.h" -#include "VideoCommon/BPMemory.h" - -void InitBPMemory(); -void SWBPWritten(int address, int newvalue); -void SWLoadBPReg(u32 value); diff --git a/Source/Core/VideoBackends/Software/CMakeLists.txt b/Source/Core/VideoBackends/Software/CMakeLists.txt index 14bde663d1..5706726770 100644 --- a/Source/Core/VideoBackends/Software/CMakeLists.txt +++ b/Source/Core/VideoBackends/Software/CMakeLists.txt @@ -1,24 +1,17 @@ -set(SRCS BPMemLoader.cpp - CPMemLoader.cpp - Clipper.cpp +set(SRCS Clipper.cpp DebugUtil.cpp EfbCopy.cpp EfbInterface.cpp - OpcodeDecoder.cpp Rasterizer.cpp - SWCommandProcessor.cpp SWOGLWindow.cpp SWRenderer.cpp - SWStatistics.cpp SWVertexLoader.cpp - SWVideoConfig.cpp SWmain.cpp SetupUnit.cpp Tev.cpp TextureEncoder.cpp TextureSampler.cpp - TransformUnit.cpp - XFMemLoader.cpp) + TransformUnit.cpp) set(LIBS videocommon SOIL diff --git a/Source/Core/VideoBackends/Software/CPMemLoader.cpp b/Source/Core/VideoBackends/Software/CPMemLoader.cpp deleted file mode 100644 index c33cd2dd0e..0000000000 --- a/Source/Core/VideoBackends/Software/CPMemLoader.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "Common/CommonFuncs.h" -#include "Core/HW/Memmap.h" -#include "VideoBackends/Software/CPMemLoader.h" -#include "VideoCommon/VideoCommon.h" - - -void SWLoadCPReg(u32 sub_cmd, u32 value) -{ - switch (sub_cmd & 0xF0) - { - case 0x30: - g_main_cp_state.matrix_index_a.Hex = value; - break; - - case 0x40: - g_main_cp_state.matrix_index_b.Hex = value; - break; - - case 0x50: - g_main_cp_state.vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits - g_main_cp_state.vtx_desc.Hex |= value; - g_main_cp_state.bases_dirty = true; - break; - - case 0x60: - g_main_cp_state.vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits - g_main_cp_state.vtx_desc.Hex |= (u64)value << 17; - g_main_cp_state.bases_dirty = true; - break; - - case 0x70: - _assert_((sub_cmd & 0x0F) < 8); - g_main_cp_state.vtx_attr[sub_cmd & 7].g0.Hex = value; - break; - - case 0x80: - _assert_((sub_cmd & 0x0F) < 8); - g_main_cp_state.vtx_attr[sub_cmd & 7].g1.Hex = value; - break; - - case 0x90: - _assert_((sub_cmd & 0x0F) < 8); - g_main_cp_state.vtx_attr[sub_cmd & 7].g2.Hex = value; - break; - - // Pointers to vertex arrays in GC RAM - case 0xA0: - g_main_cp_state.array_bases[sub_cmd & 0xF] = value; - g_main_cp_state.bases_dirty = true; - break; - - case 0xB0: - g_main_cp_state.array_strides[sub_cmd & 0xF] = value & 0xFF; - break; - } -} diff --git a/Source/Core/VideoBackends/Software/CPMemLoader.h b/Source/Core/VideoBackends/Software/CPMemLoader.h deleted file mode 100644 index 5760505a41..0000000000 --- a/Source/Core/VideoBackends/Software/CPMemLoader.h +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include "Common/CommonTypes.h" -#include "VideoCommon/CPMemory.h" - -void SWLoadCPReg(u32 sub_cmd, u32 value); diff --git a/Source/Core/VideoBackends/Software/Clipper.cpp b/Source/Core/VideoBackends/Software/Clipper.cpp index d28b1517cb..7c360c65b0 100644 --- a/Source/Core/VideoBackends/Software/Clipper.cpp +++ b/Source/Core/VideoBackends/Software/Clipper.cpp @@ -36,12 +36,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Common/ChunkFile.h" -#include "VideoBackends/Software/BPMemLoader.h" #include "VideoBackends/Software/Clipper.h" #include "VideoBackends/Software/NativeVertexFormat.h" #include "VideoBackends/Software/Rasterizer.h" -#include "VideoBackends/Software/SWStatistics.h" -#include "VideoBackends/Software/XFMemLoader.h" + +#include "VideoCommon/BPMemory.h" +#include "VideoCommon/Statistics.h" +#include "VideoCommon/XFMemory.h" namespace Clipper { @@ -56,13 +57,6 @@ namespace Clipper static OutputVertexData ClippedVertices[NUM_CLIPPED_VERTICES]; static OutputVertexData *Vertices[NUM_INDICES]; - void DoState(PointerWrap &p) - { - p.DoArray(m_ViewOffset); - for (auto& ClippedVertice : ClippedVertices) - ClippedVertice.DoState(p); - } - void Init() { for (int i = 0; i < NUM_CLIPPED_VERTICES; ++i) @@ -220,7 +214,7 @@ namespace Clipper POLY_CLIP(CLIP_POS_Z_BIT, 0, 0, 0, 1); POLY_CLIP(CLIP_NEG_Z_BIT, 0, 0, 1, 1); - INCSTAT(swstats.thisFrame.numTrianglesClipped); + INCSTAT(stats.thisFrame.numTrianglesClipped); // transform the poly in inlist into triangles indices[0] = inlist[0]; @@ -287,7 +281,7 @@ namespace Clipper void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) { - INCSTAT(swstats.thisFrame.numTrianglesIn) + INCSTAT(stats.thisFrame.numTrianglesIn) bool backface; @@ -411,7 +405,7 @@ namespace Clipper if (mask) { - INCSTAT(swstats.thisFrame.numTrianglesRejected) + INCSTAT(stats.thisFrame.numTrianglesRejected) return false; } @@ -431,13 +425,13 @@ namespace Clipper if ((bpmem.genMode.cullmode & 1) && !backface) // cull frontfacing { - INCSTAT(swstats.thisFrame.numTrianglesCulled) + INCSTAT(stats.thisFrame.numTrianglesCulled) return false; } if ((bpmem.genMode.cullmode & 2) && backface) // cull backfacing { - INCSTAT(swstats.thisFrame.numTrianglesCulled) + INCSTAT(stats.thisFrame.numTrianglesCulled) return false; } diff --git a/Source/Core/VideoBackends/Software/Clipper.h b/Source/Core/VideoBackends/Software/Clipper.h index 263fbd0854..8cf82a0e31 100644 --- a/Source/Core/VideoBackends/Software/Clipper.h +++ b/Source/Core/VideoBackends/Software/Clipper.h @@ -5,7 +5,6 @@ #pragma once struct OutputVertexData; -class PointerWrap; namespace Clipper { @@ -20,6 +19,4 @@ namespace Clipper bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface); void PerspectiveDivide(OutputVertexData *vertex); - - void DoState(PointerWrap &p); } diff --git a/Source/Core/VideoBackends/Software/DebugUtil.cpp b/Source/Core/VideoBackends/Software/DebugUtil.cpp index 7be0692088..493fe51352 100644 --- a/Source/Core/VideoBackends/Software/DebugUtil.cpp +++ b/Source/Core/VideoBackends/Software/DebugUtil.cpp @@ -8,18 +8,16 @@ #include "Core/ConfigManager.h" -#include "VideoBackends/Software/BPMemLoader.h" #include "VideoBackends/Software/DebugUtil.h" #include "VideoBackends/Software/EfbInterface.h" -#include "VideoBackends/Software/SWCommandProcessor.h" #include "VideoBackends/Software/SWRenderer.h" -#include "VideoBackends/Software/SWStatistics.h" -#include "VideoBackends/Software/SWVideoConfig.h" #include "VideoBackends/Software/TextureSampler.h" +#include "VideoCommon/BPMemory.h" #include "VideoCommon/Fifo.h" #include "VideoCommon/ImageWrite.h" - +#include "VideoCommon/Statistics.h" +#include "VideoCommon/VideoConfig.h" namespace DebugUtil { @@ -109,7 +107,7 @@ void DumpActiveTextures() { SaveTexture(StringFromFormat("%star%i_ind%i_map%i_mip%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), - swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip), texmap, mip); + stats.thisFrame.numDrawnObjects, stageNum, texmap, mip), texmap, mip); } } @@ -126,7 +124,7 @@ void DumpActiveTextures() { SaveTexture(StringFromFormat("%star%i_stage%i_map%i_mip%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), - swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip), texmap, mip); + stats.thisFrame.numDrawnObjects, stageNum, texmap, mip), texmap, mip); } } } @@ -154,13 +152,6 @@ static void DumpEfb(const std::string& filename) delete[] data; } - - -static void DumpColorTexture(const std::string& filename, u32 width, u32 height) -{ - TextureToPng(SWRenderer::GetCurrentColorTexture(), width * 4, filename, width, height, true); -} - void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name) { int buffer = bufferBase + subBuffer; @@ -202,7 +193,7 @@ void OnObjectBegin() { if (!g_bSkipCurrentFrame) { - if (g_SWVideoConfig.bDumpTextures && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd) + if (g_ActiveConfig.bDumpTextures && stats.thisFrame.numDrawnObjects >= g_ActiveConfig.drawStart && stats.thisFrame.numDrawnObjects < g_ActiveConfig.drawEnd) DumpActiveTextures(); } } @@ -211,10 +202,10 @@ void OnObjectEnd() { if (!g_bSkipCurrentFrame) { - if (g_SWVideoConfig.bDumpObjects && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd) + if (g_ActiveConfig.bDumpObjects && stats.thisFrame.numDrawnObjects >= g_ActiveConfig.drawStart && stats.thisFrame.numDrawnObjects < g_ActiveConfig.drawEnd) DumpEfb(StringFromFormat("%sobject%i.png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), - swstats.thisFrame.numDrawnObjects)); + stats.thisFrame.numDrawnObjects)); for (int i = 0; i < NUM_OBJECT_BUFFERS; i++) { @@ -223,7 +214,7 @@ void OnObjectEnd() DrawnToBuffer[i] = false; std::string filename = StringFromFormat("%sobject%i_%s(%i).png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), - swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]); + stats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]); TextureToPng((u8*)ObjectBuffer[i], EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true); memset(ObjectBuffer[i], 0, EFB_WIDTH * EFB_HEIGHT * sizeof(u32)); @@ -231,20 +222,7 @@ void OnObjectEnd() } } - swstats.thisFrame.numDrawnObjects++; - } -} - -// If frame dumping is enabled, dump whatever is drawn to the screen. -void OnFrameEnd(u32 width, u32 height) -{ - if (!g_bSkipCurrentFrame) - { - if (SConfig::GetInstance().m_DumpFrames) - { - DumpColorTexture(StringFromFormat("%sframe%i_color.png", - File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount), width, height); - } + stats.thisFrame.numDrawnObjects++; } } diff --git a/Source/Core/VideoBackends/Software/DebugUtil.h b/Source/Core/VideoBackends/Software/DebugUtil.h index 8607a6e4c0..1d5b072500 100644 --- a/Source/Core/VideoBackends/Software/DebugUtil.h +++ b/Source/Core/VideoBackends/Software/DebugUtil.h @@ -18,8 +18,6 @@ namespace DebugUtil void OnObjectBegin(); void OnObjectEnd(); - void OnFrameEnd(u32 width, u32 height); - void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name); void DrawTempBuffer(u8 *color, int buffer); diff --git a/Source/Core/VideoBackends/Software/EfbCopy.cpp b/Source/Core/VideoBackends/Software/EfbCopy.cpp index 39dff99ad0..9637ef7af0 100644 --- a/Source/Core/VideoBackends/Software/EfbCopy.cpp +++ b/Source/Core/VideoBackends/Software/EfbCopy.cpp @@ -5,15 +5,13 @@ #include "Common/GL/GLInterfaceBase.h" #include "Core/Core.h" #include "Core/HW/Memmap.h" -#include "VideoBackends/Software/BPMemLoader.h" #include "VideoBackends/Software/DebugUtil.h" #include "VideoBackends/Software/EfbCopy.h" #include "VideoBackends/Software/EfbInterface.h" -#include "VideoBackends/Software/SWCommandProcessor.h" #include "VideoBackends/Software/SWRenderer.h" -#include "VideoBackends/Software/SWStatistics.h" -#include "VideoBackends/Software/SWVideoConfig.h" #include "VideoBackends/Software/TextureEncoder.h" + +#include "VideoCommon/BPMemory.h" #include "VideoCommon/Fifo.h" static const float s_gammaLUT[] = @@ -33,31 +31,9 @@ namespace EfbCopy INFO_LOG(VIDEO, "xfbaddr: %x, fbwidth: %i, fbheight: %i, source: (%i, %i, %i, %i), Gamma %f", xfbAddr, fbWidth, fbHeight, sourceRc.top, sourceRc.left, sourceRc.bottom, sourceRc.right, Gamma); - if (!g_SWVideoConfig.bBypassXFB) - { - EfbInterface::yuv422_packed* xfb_in_ram = (EfbInterface::yuv422_packed *) Memory::GetPointer(xfbAddr); + EfbInterface::yuv422_packed* xfb_in_ram = (EfbInterface::yuv422_packed*) Memory::GetPointer(xfbAddr); - EfbInterface::CopyToXFB(xfb_in_ram, fbWidth, fbHeight, sourceRc, Gamma); - } - else - { - // Ask SWRenderer for the next color texture - u8 *colorTexture = SWRenderer::GetNextColorTexture(); - - EfbInterface::BypassXFB(colorTexture, fbWidth, fbHeight, sourceRc, Gamma); - - // Tell SWRenderer we are now finished with it. - SWRenderer::SwapColorTexture(); - - // FifoPlayer is broken and never calls BeginFrame/EndFrame. - // Hence, we manually force a swap now. This emulates the behavior - // of hardware backends with XFB emulation disabled. - // TODO: Fix FifoPlayer by making proper use of VideoInterface! - // This requires careful synchronization since GPU commands - // are processed on a different thread than VI commands. - SWRenderer::Swap(fbWidth, fbHeight); - DebugUtil::OnFrameEnd(fbWidth, fbHeight); - } + EfbInterface::CopyToXFB(xfb_in_ram, fbWidth, fbHeight, sourceRc, Gamma); } static void CopyToRam() @@ -67,7 +43,7 @@ namespace EfbCopy TextureEncoder::Encode(dest_ptr); } - static void ClearEfb() + void ClearEfb() { u32 clearColor = (bpmem.clearcolorAR & 0xff) << 24 | bpmem.clearcolorGB << 8 | (bpmem.clearcolorAR & 0xff00) >> 8; @@ -128,11 +104,6 @@ namespace EfbCopy { CopyToRam(); // FIXME: should use the rectangle we have already created above } - - if (bpmem.triggerEFBCopy.clear) - { - ClearEfb(); - } } } } diff --git a/Source/Core/VideoBackends/Software/EfbCopy.h b/Source/Core/VideoBackends/Software/EfbCopy.h index 3d3b5939ad..97698d3c5f 100644 --- a/Source/Core/VideoBackends/Software/EfbCopy.h +++ b/Source/Core/VideoBackends/Software/EfbCopy.h @@ -9,6 +9,7 @@ namespace EfbCopy { // Copy the EFB to RAM as a texture format or XFB - // Clear the EFB if needed void CopyEfb(); + + void ClearEfb(); } diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index ca6221ef26..b6b55b7204 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -8,9 +8,9 @@ #include "Common/CommonTypes.h" #include "Core/HW/Memmap.h" -#include "VideoBackends/Software/BPMemLoader.h" #include "VideoBackends/Software/EfbInterface.h" +#include "VideoCommon/BPMemory.h" #include "VideoCommon/LookUpTables.h" #include "VideoCommon/PixelEngine.h" @@ -31,11 +31,6 @@ namespace EfbInterface return (x + y * EFB_WIDTH) * 3 + DEPTH_BUFFER_START; } - void DoState(PointerWrap &p) - { - p.DoArray(efb); - } - static void SetPixelAlphaOnly(u32 offset, u8 a) { switch (bpmem.zcontrol.pixel_format) diff --git a/Source/Core/VideoBackends/Software/EfbInterface.h b/Source/Core/VideoBackends/Software/EfbInterface.h index 999dfbf8c4..0f09000a33 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.h +++ b/Source/Core/VideoBackends/Software/EfbInterface.h @@ -58,8 +58,6 @@ namespace EfbInterface void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma); void BypassXFB(u8* texture, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma); - void DoState(PointerWrap &p); - extern u32 perf_values[PQ_NUM_MEMBERS]; inline void IncPerfCounterQuadCount(PerfQueryType type) { diff --git a/Source/Core/VideoBackends/Software/NativeVertexFormat.h b/Source/Core/VideoBackends/Software/NativeVertexFormat.h index 83f771b26b..6fb0f7c1ae 100644 --- a/Source/Core/VideoBackends/Software/NativeVertexFormat.h +++ b/Source/Core/VideoBackends/Software/NativeVertexFormat.h @@ -77,16 +77,4 @@ struct OutputVertexData #undef LINTERP #undef LINTERP_INT } - void DoState(PointerWrap &p) - { - mvPosition.DoState(p); - p.Do(projectedPosition); - screenPosition.DoState(p); - for (auto& vec : normal) - vec.DoState(p); - p.DoArray(color, sizeof color); - for (auto& vec : texCoords) - vec.DoState(p); - } - }; diff --git a/Source/Core/VideoBackends/Software/OpcodeDecoder.cpp b/Source/Core/VideoBackends/Software/OpcodeDecoder.cpp deleted file mode 100644 index 6a7279440d..0000000000 --- a/Source/Core/VideoBackends/Software/OpcodeDecoder.cpp +++ /dev/null @@ -1,304 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "Common/ChunkFile.h" -#include "Common/CommonTypes.h" -#include "Core/HW/Memmap.h" -#include "VideoBackends/Software/BPMemLoader.h" -#include "VideoBackends/Software/CPMemLoader.h" -#include "VideoBackends/Software/DebugUtil.h" -#include "VideoBackends/Software/OpcodeDecoder.h" -#include "VideoBackends/Software/SWCommandProcessor.h" -#include "VideoBackends/Software/SWStatistics.h" -#include "VideoBackends/Software/SWVertexLoader.h" -#include "VideoBackends/Software/SWVideoConfig.h" -#include "VideoBackends/Software/XFMemLoader.h" -#include "VideoCommon/Fifo.h" -#include "VideoCommon/VertexLoaderUtils.h" - -typedef void (*DecodingFunction)(u32); - -namespace OpcodeDecoder -{ -static DecodingFunction currentFunction = nullptr; -static u32 minCommandSize; -static u16 streamSize; -static u16 streamAddress; -static bool readOpcode; -static SWVertexLoader vertexLoader; -static bool inObjectStream; -static u8 lastPrimCmd; - - -void DoState(PointerWrap &p) -{ - p.Do(minCommandSize); - // Not sure what is wrong with this. Something(s) in here is causing Dolphin to crash/hang when loading states saved from another run of Dolphin. Doesn't seem too important anyway... - //vertexLoader.DoState(p); - p.Do(readOpcode); - p.Do(inObjectStream); - p.Do(lastPrimCmd); - p.Do(streamSize); - p.Do(streamAddress); - if (p.GetMode() == PointerWrap::MODE_READ) - ResetDecoding(); -} - -static void DecodePrimitiveStream(u32 iBufferSize) -{ - u32 vertexSize = vertexLoader.GetVertexSize(); - - bool skipPrimitives = g_bSkipCurrentFrame || - swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawStart || - swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawEnd; - - if (skipPrimitives) - { - while (streamSize > 0 && iBufferSize >= vertexSize) - { - g_video_buffer_read_ptr += vertexSize; - iBufferSize -= vertexSize; - streamSize--; - } - } - else - { - while (streamSize > 0 && iBufferSize >= vertexSize) - { - vertexLoader.LoadVertex(); - iBufferSize -= vertexSize; - streamSize--; - } - } - - if (streamSize == 0) - { - // return to normal command processing - ResetDecoding(); - } -} - -static void ReadXFData(u32 iBufferSize) -{ - _assert_msg_(VIDEO, iBufferSize >= (u32)(streamSize * 4), "Underflow during standard opcode decoding"); - - u32 pData[16]; - for (int i = 0; i < streamSize; i++) - pData[i] = DataRead(); - SWLoadXFReg(streamSize, streamAddress, pData); - - // return to normal command processing - ResetDecoding(); -} - -static void ExecuteDisplayList(u32 addr, u32 count) -{ - u8 *videoDataSave = g_video_buffer_read_ptr; - - u8 *dlStart = Memory::GetPointer(addr); - - g_video_buffer_read_ptr = dlStart; - - while (OpcodeDecoder::CommandRunnable(count)) - { - OpcodeDecoder::Run(count); - - // if data was read by the opcode decoder then the video data pointer changed - u32 readCount = (u32)(g_video_buffer_read_ptr - dlStart); - dlStart = g_video_buffer_read_ptr; - - _assert_msg_(VIDEO, count >= readCount, "Display list underrun"); - - count -= readCount; - } - - g_video_buffer_read_ptr = videoDataSave; -} - -static void DecodeStandard(u32 bufferSize) -{ - _assert_msg_(VIDEO, CommandRunnable(bufferSize), "Underflow during standard opcode decoding"); - - int Cmd = DataRead(); - - if (Cmd == GX_NOP) - return; - // Causes a SIGBUS error on Android - // XXX: Investigate -#ifndef ANDROID - // check if switching in or out of an object - // only used for debugging - if (inObjectStream && (Cmd & 0x87) != lastPrimCmd) - { - inObjectStream = false; - DebugUtil::OnObjectEnd(); - } - if (Cmd & 0x80 && !inObjectStream) - { - inObjectStream = true; - lastPrimCmd = Cmd & 0x87; - DebugUtil::OnObjectBegin(); - } -#endif - switch (Cmd) - { - case GX_NOP: - break; - - case GX_LOAD_CP_REG: //0x08 - { - u32 SubCmd = DataRead(); - u32 Value = DataRead(); - SWLoadCPReg(SubCmd, Value); - } - break; - - case GX_LOAD_XF_REG: - { - u32 Cmd2 = DataRead(); - streamSize = ((Cmd2 >> 16) & 15) + 1; - streamAddress = Cmd2 & 0xFFFF; - currentFunction = ReadXFData; - minCommandSize = streamSize * 4; - readOpcode = false; - } - break; - - case GX_LOAD_INDX_A: //used for position matrices - SWLoadIndexedXF(DataRead(), 0xC); - break; - case GX_LOAD_INDX_B: //used for normal matrices - SWLoadIndexedXF(DataRead(), 0xD); - break; - case GX_LOAD_INDX_C: //used for postmatrices - SWLoadIndexedXF(DataRead(), 0xE); - break; - case GX_LOAD_INDX_D: //used for lights - SWLoadIndexedXF(DataRead(), 0xF); - break; - - case GX_CMD_CALL_DL: - { - u32 dwAddr = DataRead(); - u32 dwCount = DataRead(); - ExecuteDisplayList(dwAddr, dwCount); - } - break; - - case 0x44: - // zelda 4 swords calls it and checks the metrics registers after that - break; - - case GX_CMD_INVL_VC:// Invalidate (vertex cache?) - DEBUG_LOG(VIDEO, "Invalidate (vertex cache?)"); - break; - - case GX_LOAD_BP_REG: //0x61 - { - u32 cmd = DataRead(); - SWLoadBPReg(cmd); - } - break; - - // draw primitives - default: - if ((Cmd & 0xC0) == 0x80) - { - u8 vatIndex = Cmd & GX_VAT_MASK; - u8 primitiveType = (Cmd & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT; - vertexLoader.SetFormat(vatIndex, primitiveType); - - // switch to primitive processing - streamSize = DataRead(); - currentFunction = DecodePrimitiveStream; - minCommandSize = vertexLoader.GetVertexSize(); - readOpcode = false; - - INCSTAT(swstats.thisFrame.numPrimatives); - DEBUG_LOG(VIDEO, "Draw begin"); - } - else - { - PanicAlert("GFX: Unknown Opcode (0x%x).\n", Cmd); - break; - } - break; - } -} - - -void Init() -{ - inObjectStream = false; - lastPrimCmd = 0; - ResetDecoding(); -} - -void ResetDecoding() -{ - currentFunction = DecodeStandard; - minCommandSize = 1; - readOpcode = true; -} - -bool CommandRunnable(u32 iBufferSize) -{ - if (iBufferSize < minCommandSize) - return false; - - if (readOpcode) - { - u8 Cmd = DataPeek(0); - u32 minSize = 1; - - switch (Cmd) - { - case GX_LOAD_CP_REG: //0x08 - minSize = 6; - break; - - case GX_LOAD_XF_REG: - minSize = 5; - break; - - case GX_LOAD_INDX_A: //used for position matrices - minSize = 5; - break; - case GX_LOAD_INDX_B: //used for normal matrices - minSize = 5; - break; - case GX_LOAD_INDX_C: //used for postmatrices - minSize = 5; - break; - case GX_LOAD_INDX_D: //used for lights - minSize = 5; - break; - - case GX_CMD_CALL_DL: - minSize = 9; - break; - - case GX_LOAD_BP_REG: //0x61 - minSize = 5; - break; - - // draw primitives - default: - if ((Cmd & 0xC0) == 0x80) - minSize = 3; - break; - } - - return (iBufferSize >= minSize); - } - - return true; -} - -void Run(u32 iBufferSize) -{ - currentFunction(iBufferSize); -} - -} diff --git a/Source/Core/VideoBackends/Software/OpcodeDecoder.h b/Source/Core/VideoBackends/Software/OpcodeDecoder.h deleted file mode 100644 index 83630fa202..0000000000 --- a/Source/Core/VideoBackends/Software/OpcodeDecoder.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include "Common/CommonTypes.h" - -class PointerWrap; - -namespace OpcodeDecoder -{ - - #define GX_NOP 0x00 - - #define GX_LOAD_BP_REG 0x61 - #define GX_LOAD_CP_REG 0x08 - #define GX_LOAD_XF_REG 0x10 - #define GX_LOAD_INDX_A 0x20 - #define GX_LOAD_INDX_B 0x28 - #define GX_LOAD_INDX_C 0x30 - #define GX_LOAD_INDX_D 0x38 - - #define GX_CMD_CALL_DL 0x40 - #define GX_CMD_INVL_VC 0x48 - - #define GX_PRIMITIVE_MASK 0x38 - #define GX_PRIMITIVE_SHIFT 3 - #define GX_VAT_MASK 0x07 - - // These values are the values extracted using GX_PRIMITIVE_MASK - // and GX_PRIMITIVE_SHIFT. - // GX_DRAW_QUADS_2 behaves the same way as GX_DRAW_QUADS. - #define GX_DRAW_QUADS 0x0 //0x80 - #define GX_DRAW_QUADS_2 0x1 //0x88 - #define GX_DRAW_TRIANGLES 0x2 //0x90 - #define GX_DRAW_TRIANGLE_STRIP 0x3 //0x98 - #define GX_DRAW_TRIANGLE_FAN 0x4 //0xA0 - #define GX_DRAW_LINES 0x5 //0xA8 - #define GX_DRAW_LINE_STRIP 0x6 //0xB0 - #define GX_DRAW_POINTS 0x7 //0xB8 - - void Init(); - - void ResetDecoding(); - - bool CommandRunnable(u32 iBufferSize); - - void Run(u32 iBufferSize); - - void DoState(PointerWrap &p); -} diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp index 79332b6cdb..03d352beb5 100644 --- a/Source/Core/VideoBackends/Software/Rasterizer.cpp +++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp @@ -6,15 +6,14 @@ #include #include "Common/CommonTypes.h" -#include "VideoBackends/Software/BPMemLoader.h" #include "VideoBackends/Software/EfbInterface.h" #include "VideoBackends/Software/NativeVertexFormat.h" #include "VideoBackends/Software/Rasterizer.h" -#include "VideoBackends/Software/SWStatistics.h" -#include "VideoBackends/Software/SWVideoConfig.h" #include "VideoBackends/Software/Tev.h" -#include "VideoBackends/Software/XFMemLoader.h" #include "VideoCommon/BoundingBox.h" +#include "VideoCommon/Statistics.h" +#include "VideoCommon/VideoConfig.h" +#include "VideoCommon/XFMemory.h" namespace Rasterizer { @@ -38,28 +37,6 @@ static s32 scissorBottom = 0; static Tev tev; static RasterBlock rasterBlock; -void DoState(PointerWrap &p) -{ - ZSlope.DoState(p); - WSlope.DoState(p); - for (auto& color_slopes_1d : ColorSlopes) - for (Slope& color_slope : color_slopes_1d) - color_slope.DoState(p); - for (auto& tex_slopes_1d : TexSlopes) - for (Slope& tex_slope : tex_slopes_1d) - tex_slope.DoState(p); - p.Do(vertex0X); - p.Do(vertex0Y); - p.Do(vertexOffsetX); - p.Do(vertexOffsetY); - p.Do(scissorLeft); - p.Do(scissorTop); - p.Do(scissorRight); - p.Do(scissorBottom); - tev.DoState(p); - p.Do(rasterBlock); -} - void Init() { tev.Init(); @@ -121,14 +98,14 @@ void SetTevReg(int reg, int comp, bool konst, s16 color) static void Draw(s32 x, s32 y, s32 xi, s32 yi) { - INCSTAT(swstats.thisFrame.rasterizedPixels); + INCSTAT(stats.thisFrame.rasterizedPixels); float dx = vertexOffsetX + (float)(x - vertex0X); float dy = vertexOffsetY + (float)(y - vertex0Y); s32 z = (s32)MathUtil::Clamp(ZSlope.GetValue(dx, dy), 0.0f, 16777215.0f); - if (bpmem.UseEarlyDepthTest() && g_SWVideoConfig.bZComploc) + if (bpmem.UseEarlyDepthTest() && g_ActiveConfig.bZComploc) { // TODO: Test if perf regs are incremented even if test is disabled EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT_ZCOMPLOC); @@ -314,7 +291,7 @@ static void BuildBlock(s32 blockX, s32 blockY) void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) { - INCSTAT(swstats.thisFrame.numTrianglesDrawn); + INCSTAT(stats.thisFrame.numTrianglesDrawn); // adapted from http://devmaster.net/posts/6145/advanced-rasterization @@ -378,7 +355,7 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer // Many things might prevent us from reaching this line (culling, clipping, scissoring). // However, the zslope is always guaranteed to be calculated unless all vertices are trivially rejected during clipping! // We're currently sloppy at this since we abort early if any of the culling/clipping/scissoring tests fail. - if (!bpmem.genMode.zfreeze || !g_SWVideoConfig.bZFreeze) + if (!bpmem.genMode.zfreeze || !g_ActiveConfig.bZFreeze) InitSlope(&ZSlope, v0->screenPosition[2], v1->screenPosition[2], v2->screenPosition[2], fltdx31, fltdx12, fltdy12, fltdy31); for (unsigned int i = 0; i < bpmem.genMode.numcolchans; i++) diff --git a/Source/Core/VideoBackends/Software/Rasterizer.h b/Source/Core/VideoBackends/Software/Rasterizer.h index 3a6a72852f..a80565647e 100644 --- a/Source/Core/VideoBackends/Software/Rasterizer.h +++ b/Source/Core/VideoBackends/Software/Rasterizer.h @@ -25,12 +25,6 @@ namespace Rasterizer float f0; float GetValue(float dx, float dy) { return f0 + (dfdx * dx) + (dfdy * dy); } - void DoState(PointerWrap &p) - { - p.Do(dfdx); - p.Do(dfdy); - p.Do(f0); - } }; struct RasterBlockPixel @@ -47,6 +41,4 @@ namespace Rasterizer s32 TextureLod[16]; bool TextureLinear[16]; }; - - void DoState(PointerWrap &p); } diff --git a/Source/Core/VideoBackends/Software/SWCommandProcessor.cpp b/Source/Core/VideoBackends/Software/SWCommandProcessor.cpp deleted file mode 100644 index 42528603a6..0000000000 --- a/Source/Core/VideoBackends/Software/SWCommandProcessor.cpp +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include "Common/Atomic.h" -#include "Common/ChunkFile.h" -#include "Common/CommonTypes.h" -#include "Common/FPURoundMode.h" -#include "Common/MathUtil.h" -#include "Common/Thread.h" - -#include "Core/ConfigManager.h" -#include "Core/Core.h" -#include "Core/CoreTiming.h" -#include "Core/HW/Memmap.h" -#include "Core/HW/MMIO.h" -#include "Core/HW/ProcessorInterface.h" - -#include "VideoBackends/Software/OpcodeDecoder.h" -#include "VideoBackends/Software/SWCommandProcessor.h" -#include "VideoBackends/Software/VideoBackend.h" - -#include "VideoCommon/Fifo.h" -#include "VideoCommon/VertexLoaderUtils.h" - -namespace SWCommandProcessor -{ - -enum -{ - GATHER_PIPE_SIZE = 32, - INT_CAUSE_CP = 0x800 -}; - -// STATE_TO_SAVE -// variables - -static const int commandBufferSize = 1024 * 1024; -static const int maxCommandBufferWrite = commandBufferSize - GATHER_PIPE_SIZE; -static u8 commandBuffer[commandBufferSize]; -static u32 readPos; -static u32 writePos; -static int et_UpdateInterrupts; -static std::atomic interruptSet; -static std::atomic interruptWaiting; - -static CPReg cpreg; // shared between gfx and emulator thread - -void DoState(PointerWrap &p) -{ - p.DoPOD(cpreg); - p.DoArray(commandBuffer, commandBufferSize); - p.Do(readPos); - p.Do(writePos); - p.Do(et_UpdateInterrupts); - p.Do(interruptSet); - p.Do(interruptWaiting); - - // Is this right? - p.DoArray(g_video_buffer_read_ptr, writePos); -} - -static void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate) -{ - UpdateInterrupts(userdata); -} - -static inline bool AtBreakpoint() -{ - return cpreg.ctrl.BPEnable && (cpreg.readptr == cpreg.breakpt); -} - -void Init() -{ - cpreg.status.Hex = 0; - cpreg.status.CommandIdle = 1; - cpreg.status.ReadIdle = 1; - - cpreg.ctrl.Hex = 0; - cpreg.clear.Hex = 0; - - cpreg.bboxleft = 0; - cpreg.bboxtop = 0; - cpreg.bboxright = 0; - cpreg.bboxbottom = 0; - - cpreg.token = 0; - - et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper); - - // internal buffer position - readPos = 0; - writePos = 0; - - interruptSet.store(false); - interruptWaiting.store(false); - - g_video_buffer_read_ptr = nullptr; - g_bSkipCurrentFrame = false; -} - -void Shutdown() -{ -} - -void RunGpu() -{ - if (!SConfig::GetInstance().bCPUThread) - { - // We are going to do FP math on the main thread so have to save the current state - FPURoundMode::SaveSIMDState(); - FPURoundMode::LoadDefaultSIMDState(); - - // run the opcode decoder - do - { - RunBuffer(); - } while (cpreg.ctrl.GPReadEnable && !AtBreakpoint() && cpreg.readptr != cpreg.writeptr); - - FPURoundMode::LoadSIMDState(); - } -} - -void RegisterMMIO(MMIO::Mapping* mmio, u32 base) -{ - // Directly map reads and writes to the cpreg structure. - for (u32 i = 0; i < sizeof (cpreg) / sizeof (u16); ++i) - { - u16* ptr = ((u16*)&cpreg) + i; - mmio->Register(base | (i * 2), - MMIO::DirectRead(ptr), - MMIO::DirectWrite(ptr) - ); - } - - // Bleh. Apparently SWCommandProcessor does not know about regs 0x40 to - // 0x64... - for (u32 i = 0x40; i < 0x64; ++i) - { - mmio->Register(base | i, - MMIO::Constant(0), - MMIO::Nop() - ); - } - - // The low part of MMIO regs for FIFO addresses needs to be aligned to 32 - // bytes. - u32 fifo_addr_lo_regs[] = { - CommandProcessor::FIFO_BASE_LO, - CommandProcessor::FIFO_END_LO, - CommandProcessor::FIFO_WRITE_POINTER_LO, - CommandProcessor::FIFO_READ_POINTER_LO, - CommandProcessor::FIFO_BP_LO, - CommandProcessor::FIFO_RW_DISTANCE_LO, - }; - for (u32 reg : fifo_addr_lo_regs) - { - mmio->RegisterWrite(base | reg, - MMIO::DirectWrite(((u16*)&cpreg) + (reg / 2), 0xFFE0) - ); - } - - // The clear register needs to perform some more complicated operations on - // writes. - mmio->RegisterWrite(base | CommandProcessor::CLEAR_REGISTER, - MMIO::ComplexWrite([](u32, u16 val) { - UCPClearReg tmpClear(val); - - if (tmpClear.ClearFifoOverflow) - cpreg.status.OverflowHiWatermark = 0; - if (tmpClear.ClearFifoUnderflow) - cpreg.status.UnderflowLoWatermark = 0; - }) - ); -} - -void GatherPipeBursted() -{ - if (cpreg.ctrl.GPLinkEnable) - { - DEBUG_LOG(COMMANDPROCESSOR,"\t WGP burst. write thru : %08x", cpreg.writeptr); - - if (cpreg.writeptr == cpreg.fifoend) - cpreg.writeptr = cpreg.fifobase; - else - cpreg.writeptr += GATHER_PIPE_SIZE; - - Common::AtomicAdd(cpreg.rwdistance, GATHER_PIPE_SIZE); - } - - RunGpu(); -} - -void UpdateInterrupts(u64 userdata) -{ - if (userdata) - { - interruptSet.store(true); - INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); - ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true); - } - else - { - interruptSet.store(false); - INFO_LOG(COMMANDPROCESSOR,"Interrupt cleared"); - ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false); - } - interruptWaiting.store(false); -} - -void UpdateInterruptsFromVideoBackend(u64 userdata) -{ - CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata); -} - -static void ReadFifo() -{ - bool canRead = cpreg.readptr != cpreg.writeptr && writePos < (int)maxCommandBufferWrite; - bool atBreakpoint = AtBreakpoint(); - - if (canRead && !atBreakpoint) - { - // read from fifo - u8 *ptr = Memory::GetPointer(cpreg.readptr); - int bytesRead = 0; - - do - { - // copy to buffer - memcpy(&commandBuffer[writePos], ptr, GATHER_PIPE_SIZE); - writePos += GATHER_PIPE_SIZE; - bytesRead += GATHER_PIPE_SIZE; - - if (cpreg.readptr == cpreg.fifoend) - { - cpreg.readptr = cpreg.fifobase; - ptr = Memory::GetPointer(cpreg.readptr); - } - else - { - cpreg.readptr += GATHER_PIPE_SIZE; - ptr += GATHER_PIPE_SIZE; - } - - canRead = cpreg.readptr != cpreg.writeptr && writePos < (int)maxCommandBufferWrite; - atBreakpoint = AtBreakpoint(); - } while (canRead && !atBreakpoint); - - Common::AtomicAdd(cpreg.rwdistance, -bytesRead); - } -} - -static void SetStatus() -{ - // overflow check - if (cpreg.rwdistance > cpreg.hiwatermark) - cpreg.status.OverflowHiWatermark = 1; - - // underflow check - if (cpreg.rwdistance < cpreg.lowatermark) - cpreg.status.UnderflowLoWatermark = 1; - - // breakpoint - if (cpreg.ctrl.BPEnable) - { - if (cpreg.breakpt == cpreg.readptr) - { - if (!cpreg.status.Breakpoint) - INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %x", cpreg.readptr); - cpreg.status.Breakpoint = 1; - } - } - else - { - if (cpreg.status.Breakpoint) - INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %x", cpreg.readptr); - cpreg.status.Breakpoint = 0; - } - - cpreg.status.ReadIdle = cpreg.readptr == cpreg.writeptr; - - bool bpInt = cpreg.status.Breakpoint && cpreg.ctrl.BPInt; - bool ovfInt = cpreg.status.OverflowHiWatermark && cpreg.ctrl.FifoOverflowIntEnable; - bool undfInt = cpreg.status.UnderflowLoWatermark && cpreg.ctrl.FifoUnderflowIntEnable; - - bool interrupt = bpInt || ovfInt || undfInt; - - if (interrupt != interruptSet.load() && !interruptWaiting.load()) - { - u64 userdata = interrupt?1:0; - if (SConfig::GetInstance().bCPUThread) - { - interruptWaiting.store(true); - SWCommandProcessor::UpdateInterruptsFromVideoBackend(userdata); - } - else - { - SWCommandProcessor::UpdateInterrupts(userdata); - } - } -} - -bool RunBuffer() -{ - // fifo is read 32 bytes at a time - // read fifo data to internal buffer - if (cpreg.ctrl.GPReadEnable) - ReadFifo(); - - SetStatus(); - - _dbg_assert_(COMMANDPROCESSOR, writePos >= readPos); - - g_video_buffer_read_ptr = &commandBuffer[readPos]; - - u32 availableBytes = writePos - readPos; - - while (OpcodeDecoder::CommandRunnable(availableBytes)) - { - cpreg.status.CommandIdle = 0; - - OpcodeDecoder::Run(availableBytes); - - // if data was read by the opcode decoder then the video data pointer changed - readPos = (u32)(g_video_buffer_read_ptr - &commandBuffer[0]); - _dbg_assert_(VIDEO, writePos >= readPos); - availableBytes = writePos - readPos; - } - - cpreg.status.CommandIdle = 1; - - bool ranDecoder = false; - - // move data remaining in the command buffer - if (readPos > 0) - { - memmove(&commandBuffer[0], &commandBuffer[readPos], availableBytes); - writePos -= readPos; - readPos = 0; - - ranDecoder = true; - } - - return ranDecoder; -} - -void SetRendering(bool enabled) -{ - g_bSkipCurrentFrame = !enabled; -} - -} // end of namespace SWCommandProcessor - diff --git a/Source/Core/VideoBackends/Software/SWCommandProcessor.h b/Source/Core/VideoBackends/Software/SWCommandProcessor.h deleted file mode 100644 index 539be4263f..0000000000 --- a/Source/Core/VideoBackends/Software/SWCommandProcessor.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include "Common/CommonTypes.h" - -#include "VideoCommon/CommandProcessor.h" - -class PointerWrap; -namespace MMIO { class Mapping; } - -namespace SWCommandProcessor -{ - using UCPStatusReg = CommandProcessor::UCPStatusReg; - using UCPCtrlReg = CommandProcessor::UCPCtrlReg; - using UCPClearReg = CommandProcessor::UCPClearReg; - - struct CPReg - { - UCPStatusReg status; // 0x00 - UCPCtrlReg ctrl; // 0x02 - UCPClearReg clear; // 0x04 - u32 unk0; // 0x08 - u16 unk1; // 0x0c - u16 token; // 0x0e - u16 bboxleft; // 0x10 - u16 bboxtop; // 0x12 - u16 bboxright; // 0x14 - u16 bboxbottom; // 0x16 - u32 unk2; // 0x18 - u32 unk3; // 0x1c - u32 fifobase; // 0x20 - u32 fifoend; // 0x24 - u32 hiwatermark; // 0x28 - u32 lowatermark; // 0x2c - u32 rwdistance; // 0x30 - u32 writeptr; // 0x34 - u32 readptr; // 0x38 - u32 breakpt; // 0x3c - }; - - // Init - void Init(); - void Shutdown(); - void DoState(PointerWrap &p); - - void RegisterMMIO(MMIO::Mapping* mmio, u32 base); - - bool RunBuffer(); - void RunGpu(); - - // for CGPFIFO - void GatherPipeBursted(); - void UpdateInterrupts(u64 userdata); - void UpdateInterruptsFromVideoBackend(u64 userdata); - - void SetRendering(bool enabled); - -} // end of namespace SWCommandProcessor diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp index 3eeed2958b..ba3f2a9fcc 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.cpp +++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp @@ -10,35 +10,30 @@ #include "Common/CommonTypes.h" #include "Common/StringUtil.h" +#include "Core/ConfigManager.h" #include "Core/Core.h" +#include "Core/HW/Memmap.h" -#include "VideoBackends/Software/SWCommandProcessor.h" +#include "VideoBackends/Software/EfbCopy.h" #include "VideoBackends/Software/SWOGLWindow.h" #include "VideoBackends/Software/SWRenderer.h" -#include "VideoBackends/Software/SWStatistics.h" +#include "VideoCommon/BoundingBox.h" +#include "VideoCommon/Fifo.h" #include "VideoCommon/ImageWrite.h" #include "VideoCommon/OnScreenDisplay.h" +#include "VideoCommon/VideoConfig.h" static u8 *s_xfbColorTexture[2]; static int s_currentColorTexture = 0; -static std::atomic s_bScreenshot; -static std::mutex s_criticalScreenshot; -static std::string s_sScreenshotName; - -void SWRenderer::Init() -{ - s_bScreenshot.store(false); -} - -void SWRenderer::Shutdown() +SWRenderer::~SWRenderer() { delete[] s_xfbColorTexture[0]; delete[] s_xfbColorTexture[1]; } -void SWRenderer::Prepare() +void SWRenderer::Init() { s_xfbColorTexture[0] = new u8[MAX_XFB_WIDTH * MAX_XFB_HEIGHT * 4]; s_xfbColorTexture[1] = new u8[MAX_XFB_WIDTH * MAX_XFB_HEIGHT * 4]; @@ -46,44 +41,17 @@ void SWRenderer::Prepare() s_currentColorTexture = 0; } -void SWRenderer::SetScreenshot(const char *_szFilename) +void SWRenderer::Shutdown() { - std::lock_guard lk(s_criticalScreenshot); - s_sScreenshotName = _szFilename; - s_bScreenshot.store(true); + g_Config.bRunning = false; + UpdateActiveConfig(); } -void SWRenderer::RenderText(const char* pstr, int left, int top, u32 color) +void SWRenderer::RenderText(const std::string& pstr, int left, int top, u32 color) { SWOGLWindow::s_instance->PrintText(pstr, left, top, color); } -void SWRenderer::DrawDebugText() -{ - std::string debugtext; - - if (g_SWVideoConfig.bShowStats) - { - debugtext += StringFromFormat("Objects: %i\n", swstats.thisFrame.numDrawnObjects); - debugtext += StringFromFormat("Primitives: %i\n", swstats.thisFrame.numPrimatives); - debugtext += StringFromFormat("Vertices Loaded: %i\n", swstats.thisFrame.numVerticesLoaded); - - debugtext += StringFromFormat("Triangles Input: %i\n", swstats.thisFrame.numTrianglesIn); - debugtext += StringFromFormat("Triangles Rejected: %i\n", swstats.thisFrame.numTrianglesRejected); - debugtext += StringFromFormat("Triangles Culled: %i\n", swstats.thisFrame.numTrianglesCulled); - debugtext += StringFromFormat("Triangles Clipped: %i\n", swstats.thisFrame.numTrianglesClipped); - debugtext += StringFromFormat("Triangles Drawn: %i\n", swstats.thisFrame.numTrianglesDrawn); - - debugtext += StringFromFormat("Rasterized Pix: %i\n", swstats.thisFrame.rasterizedPixels); - debugtext += StringFromFormat("TEV Pix In: %i\n", swstats.thisFrame.tevPixelsIn); - debugtext += StringFromFormat("TEV Pix Out: %i\n", swstats.thisFrame.tevPixelsOut); - } - - // Render a shadow, and then the text. - SWRenderer::RenderText(debugtext.c_str(), 21, 21, 0xDD000000); - SWRenderer::RenderText(debugtext.c_str(), 20, 20, 0xFFFFFF00); -} - u8* SWRenderer::GetNextColorTexture() { return s_xfbColorTexture[!s_currentColorTexture]; @@ -138,16 +106,42 @@ void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidt } // Called on the GPU thread -void SWRenderer::Swap(u32 fbWidth, u32 fbHeight) +void SWRenderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) { - // Save screenshot - if (s_bScreenshot.load()) + if (!g_bSkipCurrentFrame) { - std::lock_guard lk(s_criticalScreenshot); - TextureToPng(GetCurrentColorTexture(), fbWidth * 4, s_sScreenshotName, fbWidth, fbHeight, false); - // Reset settings - s_sScreenshotName.clear(); - s_bScreenshot.store(false); + + if (g_ActiveConfig.bUseXFB) + { + EfbInterface::yuv422_packed* xfb = (EfbInterface::yuv422_packed*) Memory::GetPointer(xfbAddr); + UpdateColorTexture(xfb, fbWidth, fbHeight); + } + else + { + EfbInterface::BypassXFB(GetCurrentColorTexture(), fbWidth, fbHeight, rc, Gamma); + } + + // Save screenshot + if (s_bScreenshot) + { + std::lock_guard lk(s_criticalScreenshot); + + if (TextureToPng(GetCurrentColorTexture(), fbWidth * 4, s_sScreenshotName, fbWidth, fbHeight, false)) + OSD::AddMessage("Screenshot saved to " + s_sScreenshotName); + + // Reset settings + s_sScreenshotName.clear(); + s_bScreenshot = false; + s_screenshotCompleted.Set(); + } + + if (SConfig::GetInstance().m_DumpFrames) + { + static int frame_index = 0; + TextureToPng(GetCurrentColorTexture(), fbWidth * 4, StringFromFormat("%sframe%i_color.png", + File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), frame_index), fbWidth, fbHeight, true); + frame_index++; + } } OSD::DoCallbacks(OSD::CallbackType::OnFrame); @@ -156,7 +150,57 @@ void SWRenderer::Swap(u32 fbWidth, u32 fbHeight) SWOGLWindow::s_instance->ShowImage(GetCurrentColorTexture(), fbWidth * 4, fbWidth, fbHeight, 1.0); - swstats.frameCount++; - swstats.ResetFrame(); - Core::Callback_VideoCopiedToXFB(true); // FIXME: should this function be called FrameRendered? + UpdateActiveConfig(); +} + +u32 SWRenderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) +{ + u32 value = 0; + + switch (type) + { + case PEEK_Z: + { + value = EfbInterface::GetDepth(x, y); + break; + } + case PEEK_COLOR: + { + u32 color = 0; + EfbInterface::GetColor(x, y, (u8*)&color); + + // rgba to argb + value = (color >> 8) | (color & 0xff) << 24; + break; + } + default: + break; + } + + return value; +} + +u16 SWRenderer::BBoxRead(int index) +{ + return BoundingBox::coords[index]; +} + +void SWRenderer::BBoxWrite(int index, u16 value) +{ + BoundingBox::coords[index] = value; +} + +TargetRectangle SWRenderer::ConvertEFBRectangle(const EFBRectangle& rc) +{ + TargetRectangle result; + result.left = rc.left; + result.top = rc.top; + result.right = rc.right; + result.bottom = rc.bottom; + return result; +} + +void SWRenderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) +{ + EfbCopy::ClearEfb(); } diff --git a/Source/Core/VideoBackends/Software/SWRenderer.h b/Source/Core/VideoBackends/Software/SWRenderer.h index c7cafe344a..3ce1cc4593 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.h +++ b/Source/Core/VideoBackends/Software/SWRenderer.h @@ -6,22 +6,40 @@ #include "Common/CommonTypes.h" #include "Common/Thread.h" + #include "VideoBackends/Software/EfbInterface.h" -namespace SWRenderer +#include "VideoCommon/RenderBase.h" + +class SWRenderer : public Renderer { - void Init(); - void Prepare(); - void Shutdown(); +public: + ~SWRenderer() override; - void SetScreenshot(const char *_szFilename); - void RenderText(const char* pstr, int left, int top, u32 color); - void DrawDebugText(); + static void Init(); + static void Shutdown(); - u8* GetNextColorTexture(); - u8* GetCurrentColorTexture(); + static u8* GetNextColorTexture(); + static u8* GetCurrentColorTexture(); void SwapColorTexture(); void UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight); - void Swap(u32 fbWidth, u32 fbHeight); -} + void RenderText(const std::string& pstr, int left, int top, u32 color) override; + u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; + void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {}; + + u16 BBoxRead(int index) override; + void BBoxWrite(int index, u16 value) override; + + int GetMaxTextureSize() override { return 16 * 1024; }; + + TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override; + + void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) override; + + void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) override; + + void ReinterpretPixelData(unsigned int convtype) override {} + + bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override { return true; }; +}; diff --git a/Source/Core/VideoBackends/Software/SWStatistics.cpp b/Source/Core/VideoBackends/Software/SWStatistics.cpp deleted file mode 100644 index 44892d6b94..0000000000 --- a/Source/Core/VideoBackends/Software/SWStatistics.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include "VideoBackends/Software/SWStatistics.h" - -SWStatistics swstats; - -SWStatistics::SWStatistics() -{ - frameCount = 0; -} - -void SWStatistics::ResetFrame() -{ - memset(&thisFrame, 0, sizeof(ThisFrame)); -} diff --git a/Source/Core/VideoBackends/Software/SWStatistics.h b/Source/Core/VideoBackends/Software/SWStatistics.h deleted file mode 100644 index 6b343ca44b..0000000000 --- a/Source/Core/VideoBackends/Software/SWStatistics.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "Common/CommonTypes.h" -#include "VideoBackends/Software/SWVideoConfig.h" - -#pragma once - -struct SWStatistics -{ - struct ThisFrame - { - u32 numDrawnObjects; - u32 numPrimatives; - u32 numVerticesLoaded; - u32 numVerticesOut; - - u32 numTrianglesIn; - u32 numTrianglesRejected; - u32 numTrianglesCulled; - u32 numTrianglesClipped; - u32 numTrianglesDrawn; - - u32 rasterizedPixels; - u32 tevPixelsIn; - u32 tevPixelsOut; - }; - - u32 frameCount; - SWStatistics(); - - ThisFrame thisFrame; - void ResetFrame(); -}; - -extern SWStatistics swstats; - -#if (STATISTICS) -#define INCSTAT(a) (a)++; -#define ADDSTAT(a,b) (a)+=(b); -#define SETSTAT(a,x) (a)=(int)(x); -#else -#define INCSTAT(a) ; -#define ADDSTAT(a,b) ; -#define SETSTAT(a,x) ; -#endif diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp index bda8714f00..86855db446 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp @@ -7,22 +7,40 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" -#include "VideoBackends/Software/CPMemLoader.h" +#include "VideoBackends/Software/Clipper.h" +#include "VideoBackends/Software/DebugUtil.h" #include "VideoBackends/Software/NativeVertexFormat.h" +#include "VideoBackends/Software/Rasterizer.h" #include "VideoBackends/Software/SetupUnit.h" -#include "VideoBackends/Software/SWStatistics.h" #include "VideoBackends/Software/SWVertexLoader.h" +#include "VideoBackends/Software/Tev.h" #include "VideoBackends/Software/TransformUnit.h" -#include "VideoBackends/Software/XFMemLoader.h" +#include "VideoCommon/IndexGenerator.h" +#include "VideoCommon/OpcodeDecoding.h" +#include "VideoCommon/PixelShaderManager.h" +#include "VideoCommon/Statistics.h" #include "VideoCommon/VertexLoaderBase.h" #include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexLoaderUtils.h" +#include "VideoCommon/XFMemory.h" - -SWVertexLoader::SWVertexLoader() : - m_VertexSize(0) +class NullNativeVertexFormat : public NativeVertexFormat { +public: + NullNativeVertexFormat(const PortableVertexDeclaration& _vtx_decl) { vtx_decl = _vtx_decl; } + void SetupVertexPointers() override {} +}; + +NativeVertexFormat* SWVertexLoader::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) +{ + return new NullNativeVertexFormat(vtx_decl); +} + +SWVertexLoader::SWVertexLoader() +{ + LocalVBuffer.resize(MAXVBUFFERSIZE); + LocalIBuffer.resize(MAXIBUFFERSIZE); m_SetupUnit = new SetupUnit; } @@ -32,25 +50,89 @@ SWVertexLoader::~SWVertexLoader() m_SetupUnit = nullptr; } -void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType) +void SWVertexLoader::ResetBuffer(u32 stride) { - memset(&m_Vertex, 0, sizeof(m_Vertex)); + s_pCurBufferPointer = s_pBaseBufferPointer = LocalVBuffer.data(); + s_pEndBufferPointer = s_pCurBufferPointer + LocalVBuffer.size(); + IndexGenerator::Start(GetIndexBuffer()); +} - m_attributeIndex = attributeIndex; +void SWVertexLoader::vFlush(bool useDstAlpha) +{ + DebugUtil::OnObjectBegin(); - VertexLoaderUID uid(g_main_cp_state.vtx_desc, g_main_cp_state.vtx_attr[m_attributeIndex]); - m_CurrentLoader = m_VertexLoaderMap[uid].get(); - - if (!m_CurrentLoader) + u8 primitiveType = 0; + switch (current_primitive_type) { - m_VertexLoaderMap[uid] = VertexLoaderBase::CreateVertexLoader(g_main_cp_state.vtx_desc, g_main_cp_state.vtx_attr[m_attributeIndex]); - m_CurrentLoader = m_VertexLoaderMap[uid].get(); + case PRIMITIVE_POINTS: + primitiveType = GX_DRAW_POINTS; + break; + case PRIMITIVE_LINES: + primitiveType = GX_DRAW_LINES; + break; + case PRIMITIVE_TRIANGLES: + primitiveType = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? GX_DRAW_TRIANGLE_STRIP : GX_DRAW_TRIANGLES; + break; } - m_VertexSize = m_CurrentLoader->m_VertexSize; - m_CurrentVat = &g_main_cp_state.vtx_attr[m_attributeIndex]; + m_SetupUnit->Init(primitiveType); + // set all states with are stored within video sw + Clipper::SetViewOffset(); + Rasterizer::SetScissor(); + for (int i = 0; i < 4; i++) + { + Rasterizer::SetTevReg(i, Tev::RED_C, false, PixelShaderManager::constants.colors[i][0]); + Rasterizer::SetTevReg(i, Tev::GRN_C, false, PixelShaderManager::constants.colors[i][1]); + Rasterizer::SetTevReg(i, Tev::BLU_C, false, PixelShaderManager::constants.colors[i][2]); + Rasterizer::SetTevReg(i, Tev::ALP_C, false, PixelShaderManager::constants.colors[i][3]); + Rasterizer::SetTevReg(i, Tev::RED_C, true, PixelShaderManager::constants.kcolors[i][0]); + Rasterizer::SetTevReg(i, Tev::GRN_C, true, PixelShaderManager::constants.kcolors[i][1]); + Rasterizer::SetTevReg(i, Tev::BLU_C, true, PixelShaderManager::constants.kcolors[i][2]); + Rasterizer::SetTevReg(i, Tev::ALP_C, true, PixelShaderManager::constants.kcolors[i][3]); + } + for (u32 i = 0; i < IndexGenerator::GetIndexLen(); i++) + { + u16 index = LocalIBuffer[i]; + + if (index == 0xffff) + { + // primitive restart + m_SetupUnit->Init(primitiveType); + continue; + } + memset(&m_Vertex, 0, sizeof(m_Vertex)); + + // Super Mario Sunshine requires those to be zero for those debug boxes. + memset(&m_Vertex.color, 0, sizeof(m_Vertex.color)); + + // parse the videocommon format to our own struct format (m_Vertex) + SetFormat(g_main_cp_state.last_id, primitiveType); + ParseVertex(VertexLoaderManager::GetCurrentVertexFormat()->GetVertexDeclaration(), index); + + // transform this vertex so that it can be used for rasterization (outVertex) + OutputVertexData* outVertex = m_SetupUnit->GetVertex(); + TransformUnit::TransformPosition(&m_Vertex, outVertex); + memset(&outVertex->normal, 0, sizeof(outVertex->normal)); + if (VertexLoaderManager::g_current_components & VB_HAS_NRM0) + { + TransformUnit::TransformNormal(&m_Vertex, (VertexLoaderManager::g_current_components & VB_HAS_NRM2) != 0, outVertex); + } + TransformUnit::TransformColor(&m_Vertex, outVertex); + TransformUnit::TransformTexCoord(&m_Vertex, outVertex, m_TexGenSpecialCase); + + // assemble and rasterize the primitive + m_SetupUnit->SetupVertex(); + + INCSTAT(stats.thisFrame.numVerticesLoaded) + } + + DebugUtil::OnObjectEnd(); +} + +void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType) +{ // matrix index from xf regs or cp memory? if (xfmem.MatrixIndexA.PosNormalMtxIdx != g_main_cp_state.matrix_index_a.PosNormalMtxIdx || xfmem.MatrixIndexA.Tex0MtxIdx != g_main_cp_state.matrix_index_a.Tex0MtxIdx || @@ -81,8 +163,6 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType) ((g_main_cp_state.vtx_desc.Hex & 0x60600L) == g_main_cp_state.vtx_desc.Hex) && // only pos and tex coord 0 (g_main_cp_state.vtx_desc.Tex0Coord != NOT_PRESENT) && (xfmem.texMtxInfo[0].projection == XF_TEXPROJ_ST); - - m_SetupUnit->Init(primitiveType); } template @@ -138,9 +218,10 @@ static void ReadVertexAttribute(T* dst, DataReader src, const AttributeFormat& f } } -void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec) +void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec, int index) { - DataReader src(m_LoadedVertices.data(), m_LoadedVertices.data() + m_LoadedVertices.size()); + DataReader src(LocalVBuffer.data(), LocalVBuffer.data() + LocalVBuffer.size()); + src.Skip(index * vdec.stride); ReadVertexAttribute(&m_Vertex.position[0], src, vdec.position, 0, 3, false); @@ -167,52 +248,3 @@ void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec) ReadVertexAttribute(&m_Vertex.posMtx, src, vdec.posmtx, 0, 1, false); } - -void SWVertexLoader::LoadVertex() -{ - const PortableVertexDeclaration& vdec = m_CurrentLoader->m_native_vtx_decl; - - // reserve memory for the destination of the vertex loader - m_LoadedVertices.resize(vdec.stride + 4); - - VertexLoaderManager::UpdateVertexArrayPointers(); - - // convert the vertex from the gc format to the videocommon (hardware optimized) format - u8* old = g_video_buffer_read_ptr; - int converted_vertices = m_CurrentLoader->RunVertices( - DataReader(g_video_buffer_read_ptr, nullptr), // src - DataReader(m_LoadedVertices.data(), m_LoadedVertices.data() + m_LoadedVertices.size()), // dst - 1 // vertices - ); - g_video_buffer_read_ptr = old + m_CurrentLoader->m_VertexSize; - - if (converted_vertices == 0) - return; - - // parse the videocommon format to our own struct format (m_Vertex) - ParseVertex(vdec); - - // transform this vertex so that it can be used for rasterization (outVertex) - OutputVertexData* outVertex = m_SetupUnit->GetVertex(); - TransformUnit::TransformPosition(&m_Vertex, outVertex); - memset(&outVertex->normal, 0, sizeof(outVertex->normal)); - if (g_main_cp_state.vtx_desc.Normal != NOT_PRESENT) - { - TransformUnit::TransformNormal(&m_Vertex, m_CurrentVat->g0.NormalElements, outVertex); - } - TransformUnit::TransformColor(&m_Vertex, outVertex); - TransformUnit::TransformTexCoord(&m_Vertex, outVertex, m_TexGenSpecialCase); - - // assemble and rasterize the primitive - m_SetupUnit->SetupVertex(); - - INCSTAT(swstats.thisFrame.numVerticesLoaded) -} - -void SWVertexLoader::DoState(PointerWrap &p) -{ - p.Do(m_VertexSize); - p.Do(*m_CurrentVat); - m_SetupUnit->DoState(p); - p.Do(m_TexGenSpecialCase); -} diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.h b/Source/Core/VideoBackends/Software/SWVertexLoader.h index 4972364c1b..7166ae6697 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.h +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.h @@ -6,45 +6,42 @@ #include #include +#include #include "Common/CommonTypes.h" -#include "VideoBackends/Software/CPMemLoader.h" #include "VideoBackends/Software/NativeVertexFormat.h" #include "VideoCommon/VertexLoaderBase.h" +#include "VideoCommon/VertexManagerBase.h" -class PointerWrap; class SetupUnit; -class SWVertexLoader +class SWVertexLoader : public VertexManagerBase { - u32 m_VertexSize; +public: + SWVertexLoader(); + ~SWVertexLoader(); - VAT* m_CurrentVat; + NativeVertexFormat* CreateNativeVertexFormat(const PortableVertexDeclaration& vdec) override; + +protected: + virtual void ResetBuffer(u32 stride); + u16* GetIndexBuffer() { return &LocalIBuffer[0]; } +private: + void vFlush(bool useDstAlpha) override; + std::vector LocalVBuffer; + std::vector LocalIBuffer; InputVertexData m_Vertex; - void ParseVertex(const PortableVertexDeclaration& vdec); + void ParseVertex(const PortableVertexDeclaration& vdec, int index); SetupUnit *m_SetupUnit; bool m_TexGenSpecialCase; - std::unordered_map> m_VertexLoaderMap; - std::vector m_LoadedVertices; - VertexLoaderBase* m_CurrentLoader; - - u8 m_attributeIndex; - public: - SWVertexLoader(); - ~SWVertexLoader(); void SetFormat(u8 attributeIndex, u8 primitiveType); - - u32 GetVertexSize() { return m_VertexSize; } - - void LoadVertex(); - void DoState(PointerWrap &p); }; diff --git a/Source/Core/VideoBackends/Software/SWVideoConfig.cpp b/Source/Core/VideoBackends/Software/SWVideoConfig.cpp deleted file mode 100644 index 4bd011e2df..0000000000 --- a/Source/Core/VideoBackends/Software/SWVideoConfig.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "Common/FileUtil.h" -#include "Common/IniFile.h" -#include "VideoBackends/Software/SWVideoConfig.h" - -SWVideoConfig g_SWVideoConfig; - -SWVideoConfig::SWVideoConfig() -{ - bFullscreen = false; - bHideCursor = false; - renderToMainframe = false; - - bBypassXFB = false; - - bShowStats = false; - - bDumpTextures = false; - bDumpObjects = false; - - bZComploc = true; - bZFreeze = true; - - bDumpTevStages = false; - bDumpTevTextureFetches = false; - - drawStart = 0; - drawEnd = 100000; -} - -void SWVideoConfig::Load(const char* ini_file) -{ - IniFile iniFile; - iniFile.Load(ini_file); - - IniFile::Section* hardware = iniFile.GetOrCreateSection("Hardware"); - hardware->Get("Fullscreen", &bFullscreen, 0); // Hardware - hardware->Get("RenderToMainframe", &renderToMainframe, false); - - IniFile::Section* rendering = iniFile.GetOrCreateSection("Rendering"); - rendering->Get("BypassXFB", &bBypassXFB, false); - rendering->Get("ZComploc", &bZComploc, true); - rendering->Get("ZFreeze", &bZFreeze, true); - - IniFile::Section* info = iniFile.GetOrCreateSection("Info"); - info->Get("ShowStats", &bShowStats, false); - - IniFile::Section* utility = iniFile.GetOrCreateSection("Utility"); - utility->Get("DumpTexture", &bDumpTextures, false); - utility->Get("DumpObjects", &bDumpObjects, false); - utility->Get("DumpTevStages", &bDumpTevStages, false); - utility->Get("DumpTevTexFetches", &bDumpTevTextureFetches, false); - - IniFile::Section* misc = iniFile.GetOrCreateSection("Misc"); - misc->Get("DrawStart", &drawStart, 0); - misc->Get("DrawEnd", &drawEnd, 100000); -} - -void SWVideoConfig::Save(const char* ini_file) -{ - IniFile iniFile; - iniFile.Load(ini_file); - - IniFile::Section* hardware = iniFile.GetOrCreateSection("Hardware"); - hardware->Set("Fullscreen", bFullscreen); - hardware->Set("RenderToMainframe", renderToMainframe); - - IniFile::Section* rendering = iniFile.GetOrCreateSection("Rendering"); - rendering->Set("BypassXFB", bBypassXFB); - rendering->Set("ZComploc", bZComploc); - rendering->Set("ZFreeze", bZFreeze); - - IniFile::Section* info = iniFile.GetOrCreateSection("Info"); - info->Set("ShowStats", bShowStats); - - IniFile::Section* utility = iniFile.GetOrCreateSection("Utility"); - utility->Set("DumpTexture", bDumpTextures); - utility->Set("DumpObjects", bDumpObjects); - utility->Set("DumpTevStages", bDumpTevStages); - utility->Set("DumpTevTexFetches", bDumpTevTextureFetches); - - IniFile::Section* misc = iniFile.GetOrCreateSection("Misc"); - misc->Set("DrawStart", drawStart); - misc->Set("DrawEnd", drawEnd); - - iniFile.Save(ini_file); -} - diff --git a/Source/Core/VideoBackends/Software/SWVideoConfig.h b/Source/Core/VideoBackends/Software/SWVideoConfig.h deleted file mode 100644 index 4dfa8ac87d..0000000000 --- a/Source/Core/VideoBackends/Software/SWVideoConfig.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include "Common/CommonTypes.h" -#include "Common/NonCopyable.h" - -#define STATISTICS 1 - -// NEVER inherit from this class. -struct SWVideoConfig : NonCopyable -{ - SWVideoConfig(); - void Load(const char* ini_file); - void Save(const char* ini_file); - - // General - bool bFullscreen; - bool bHideCursor; - bool renderToMainframe; - - bool bBypassXFB; - - // Emulation features - bool bZComploc; - bool bZFreeze; - - bool bShowStats; - - bool bDumpTextures; - bool bDumpObjects; - - // Debug only - bool bDumpTevStages; - bool bDumpTevTextureFetches; - - u32 drawStart; - u32 drawEnd; -}; - -extern SWVideoConfig g_SWVideoConfig; diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index b0f0af66f8..59162c2f06 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include "Common/CommonTypes.h" @@ -16,25 +17,29 @@ #include "Core/HW/Memmap.h" #include "Core/HW/VideoInterface.h" -#include "VideoBackends/Software/BPMemLoader.h" #include "VideoBackends/Software/Clipper.h" #include "VideoBackends/Software/DebugUtil.h" +#include "VideoBackends/Software/EfbCopy.h" #include "VideoBackends/Software/EfbInterface.h" -#include "VideoBackends/Software/OpcodeDecoder.h" #include "VideoBackends/Software/Rasterizer.h" -#include "VideoBackends/Software/SWCommandProcessor.h" #include "VideoBackends/Software/SWOGLWindow.h" #include "VideoBackends/Software/SWRenderer.h" -#include "VideoBackends/Software/SWStatistics.h" #include "VideoBackends/Software/SWVertexLoader.h" -#include "VideoBackends/Software/SWVideoConfig.h" #include "VideoBackends/Software/VideoBackend.h" -#include "VideoBackends/Software/XFMemLoader.h" -#include "VideoCommon/BoundingBox.h" +#include "VideoCommon/BPStructs.h" +#include "VideoCommon/CommandProcessor.h" #include "VideoCommon/Fifo.h" +#include "VideoCommon/Fifo.h" +#include "VideoCommon/IndexGenerator.h" #include "VideoCommon/OnScreenDisplay.h" +#include "VideoCommon/OpcodeDecoding.h" #include "VideoCommon/PixelEngine.h" +#include "VideoCommon/PixelShaderManager.h" +#include "VideoCommon/TextureCacheBase.h" +#include "VideoCommon/VertexLoaderManager.h" +#include "VideoCommon/VertexShaderManager.h" +#include "VideoCommon/VideoConfig.h" #include "VideoCommon/XFMemory.h" #define VSYNC_ENABLED 0 @@ -51,6 +56,86 @@ static volatile struct namespace SW { +class PerfQuery : public PerfQueryBase +{ +public: + PerfQuery() {} + ~PerfQuery() {} + + void EnableQuery(PerfQueryGroup type) override {} + void DisableQuery(PerfQueryGroup type) override {} + void ResetQuery() override + { + memset(EfbInterface::perf_values, 0, sizeof(EfbInterface::perf_values)); + } + u32 GetQueryResult(PerfQueryType type) override + { + return EfbInterface::perf_values[type]; + }; + void FlushResults() override {} + bool IsFlushed() const {return true;}; +}; + +class TextureCache : public TextureCacheBase +{ +public: + void CompileShaders() override {}; + void DeleteShaders() override {}; + void ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette, TlutFormat format) override {}; + void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride, + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, + bool isIntensity, bool scaleByHalf) override + { + EfbCopy::CopyEfb(); + } + +private: + struct TCacheEntry : TCacheEntryBase + { + TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {} + ~TCacheEntry() {} + + void Load(unsigned int width, unsigned int height, + unsigned int expanded_width, unsigned int level) override {} + + void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, + bool scaleByHalf, unsigned int cbufid, const float *colmat) override + { + EfbCopy::CopyEfb(); + } + + void CopyRectangleFromTexture( + const TCacheEntryBase* source, + const MathUtil::Rectangle& srcrect, + const MathUtil::Rectangle& dstrect) override {} + + void Bind(unsigned int stage) override {} + + bool Save(const std::string& filename, unsigned int level) override { return false; } + }; + + TCacheEntryBase* CreateTexture(const TCacheEntryConfig& config) override + { + return new TCacheEntry(config); + } +}; + +class XFBSource : public XFBSourceBase +{ + void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) override {} + void CopyEFB(float Gamma) override {} +}; + +class FramebufferManager : public FramebufferManagerBase +{ + std::unique_ptr CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) override { return std::make_unique(); } + void GetTargetSize(unsigned int* width, unsigned int* height) override {}; + void CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma = 1.0f) override + { + EfbCopy::CopyEfb(); + } +}; + static std::atomic fifoStateRun; static std::atomic emuRunningState; static std::mutex m_csSWVidOccupied; @@ -65,93 +150,57 @@ std::string VideoSoftware::GetDisplayName() const return "Software Renderer"; } +static void InitBackendInfo() +{ + g_Config.backend_info.APIType = API_NONE; + g_Config.backend_info.bSupports3DVision = false; + g_Config.backend_info.bSupportsDualSourceBlend = true; + g_Config.backend_info.bSupportsEarlyZ = true; + g_Config.backend_info.bSupportsOversizedViewports = true; + g_Config.backend_info.bSupportsPrimitiveRestart = false; + + // aamodes + g_Config.backend_info.AAModes = {1}; +} + void VideoSoftware::ShowConfig(void *hParent) { + if (!m_initialized) + InitBackendInfo(); Host_ShowVideoConfig(hParent, GetDisplayName(), "gfx_software"); } bool VideoSoftware::Initialize(void *window_handle) { - g_SWVideoConfig.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_software.ini").c_str()); + InitializeShared(); + InitBackendInfo(); + + g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_software.ini").c_str()); + g_Config.GameIniLoad(); + g_Config.UpdateProjectionHack(); + g_Config.VerifyValidity(); + UpdateActiveConfig(); SWOGLWindow::Init(window_handle); - InitBPMemory(); - InitXFMemory(); - SWCommandProcessor::Init(); PixelEngine::Init(); - OpcodeDecoder::Init(); Clipper::Init(); Rasterizer::Init(); SWRenderer::Init(); DebugUtil::Init(); + // Do our OSD callbacks + OSD::DoCallbacks(OSD::CallbackType::Initialization); + m_initialized = true; + return true; } -void VideoSoftware::DoState(PointerWrap& p) -{ - bool software = true; - p.Do(software); - if (p.GetMode() == PointerWrap::MODE_READ && software == false) - // change mode to abort load of incompatible save state. - p.SetMode(PointerWrap::MODE_VERIFY); - - // TODO: incomplete? - SWCommandProcessor::DoState(p); - PixelEngine::DoState(p); - EfbInterface::DoState(p); - OpcodeDecoder::DoState(p); - Clipper::DoState(p); - p.Do(xfmem); - p.Do(bpmem); - p.DoPOD(swstats); - - // CP Memory - DoCPState(p); -} - -void VideoSoftware::CheckInvalidState() -{ - // there is no state to invalidate -} - -void VideoSoftware::PauseAndLock(bool doLock, bool unpauseOnUnlock) -{ - if (doLock) - { - EmuStateChange(EMUSTATE_CHANGE_PAUSE); - if (!Core::IsGPUThread()) - m_csSWVidOccupied.lock(); - } - else - { - if (unpauseOnUnlock) - EmuStateChange(EMUSTATE_CHANGE_PLAY); - if (!Core::IsGPUThread()) - m_csSWVidOccupied.unlock(); - } -} - -void VideoSoftware::RunLoop(bool enable) -{ - emuRunningState.store(enable); -} - -void VideoSoftware::EmuStateChange(EMUSTATE_CHANGE newState) -{ - emuRunningState.store(newState == EMUSTATE_CHANGE_PLAY); -} - void VideoSoftware::Shutdown() { m_initialized = false; - // TODO: should be in Video_Cleanup - SWRenderer::Shutdown(); - DebugUtil::Shutdown(); - // Do our OSD callbacks OSD::DoCallbacks(OSD::CallbackType::Shutdown); @@ -160,186 +209,54 @@ void VideoSoftware::Shutdown() void VideoSoftware::Video_Cleanup() { + if (g_renderer) + { + Fifo_Shutdown(); + + SWRenderer::Shutdown(); + DebugUtil::Shutdown(); + // The following calls are NOT Thread Safe + // And need to be called from the video thread + SWRenderer::Shutdown(); + VertexLoaderManager::Shutdown(); + g_framebuffer_manager.reset(); + g_texture_cache.reset(); + VertexShaderManager::Shutdown(); + PixelShaderManager::Shutdown(); + g_perf_query.reset(); + g_vertex_manager.reset(); + OpcodeDecoder_Shutdown(); + g_renderer.reset(); + } } // This is called after Video_Initialize() from the Core void VideoSoftware::Video_Prepare() { - // Do our OSD callbacks - OSD::DoCallbacks(OSD::CallbackType::Initialization); + g_renderer = std::make_unique(); - SWRenderer::Prepare(); + CommandProcessor::Init(); + PixelEngine::Init(); + + BPInit(); + g_vertex_manager = std::make_unique(); + g_perf_query = std::make_unique(); + Fifo_Init(); // must be done before OpcodeDecoder_Init() + OpcodeDecoder_Init(); + IndexGenerator::Init(); + VertexShaderManager::Init(); + PixelShaderManager::Init(); + g_texture_cache = std::make_unique(); + SWRenderer::Init(); + VertexLoaderManager::Init(); + g_framebuffer_manager = std::make_unique(); + + // Notify the core that the video backend is ready + Host_Message(WM_USER_CREATE); INFO_LOG(VIDEO, "Video backend initialized."); } -// Run from the CPU thread (from VideoInterface.cpp) -void VideoSoftware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight) -{ - // XXX: fbStride should be implemented properly here - // If stride isn't implemented then there are problems with XFB - // Animal Crossing is a good example for this. - s_beginFieldArgs.xfbAddr = xfbAddr; - s_beginFieldArgs.fbWidth = fbWidth; - s_beginFieldArgs.fbHeight = fbHeight; -} - -// Run from the CPU thread (from VideoInterface.cpp) -void VideoSoftware::Video_EndField() -{ - // Techincally the XFB is continually rendered out scanline by scanline between - // BeginField and EndFeild, We could possibly get away with copying out the whole thing - // at BeginField for less lag, but for the safest emulation we run it here. - - if (g_bSkipCurrentFrame || s_beginFieldArgs.xfbAddr == 0) - { - swstats.frameCount++; - swstats.ResetFrame(); - Core::Callback_VideoCopiedToXFB(false); - return; - } - if (!g_SWVideoConfig.bBypassXFB) - { - EfbInterface::yuv422_packed *xfb = (EfbInterface::yuv422_packed *) Memory::GetPointer(s_beginFieldArgs.xfbAddr); - - SWRenderer::UpdateColorTexture(xfb, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight); - } - - // Ideally we would just move all the OpenGL context stuff to the CPU thread, - // but this gets messy when the hardware rasterizer is enabled. - // And neobrain loves his hardware rasterizer. - - // If BypassXFB has already done a swap (cf. EfbCopy::CopyToXfb), skip this. - if (!g_SWVideoConfig.bBypassXFB) - { - // Dump frame if needed - DebugUtil::OnFrameEnd(s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight); - - // If we are in dual core mode, notify the GPU thread about the new color texture. - if (SConfig::GetInstance().bCPUThread) - s_swapRequested.store(true); - else - SWRenderer::Swap(s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight); - } -} - -u32 VideoSoftware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) -{ - u32 value = 0; - - switch (type) - { - case PEEK_Z: - { - value = EfbInterface::GetDepth(x, y); - break; - } - - case POKE_Z: - break; - - case PEEK_COLOR: - { - u32 color = 0; - EfbInterface::GetColor(x, y, (u8*)&color); - - // rgba to argb - value = (color >> 8) | (color & 0xff) << 24; - break; - } - - case POKE_COLOR: - break; - } - - return value; -} - -u32 VideoSoftware::Video_GetQueryResult(PerfQueryType type) -{ - return EfbInterface::perf_values[type]; -} - -u16 VideoSoftware::Video_GetBoundingBox(int index) -{ - return BoundingBox::coords[index]; -} - -bool VideoSoftware::Video_Screenshot(const std::string& filename) -{ - SWRenderer::SetScreenshot(filename.c_str()); - return true; -} - -// Run from the graphics thread -static void VideoFifo_CheckSwapRequest() -{ - if (s_swapRequested.load()) - { - SWRenderer::Swap(s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight); - s_swapRequested.store(false); - } -} - -// ------------------------------- -// Enter and exit the video loop -// ------------------------------- -void VideoSoftware::Video_EnterLoop() -{ - std::lock_guard lk(m_csSWVidOccupied); - fifoStateRun.store(true); - - while (fifoStateRun.load()) - { - VideoFifo_CheckSwapRequest(); - g_video_backend->PeekMessages(); - - if (!SWCommandProcessor::RunBuffer()) - { - Common::YieldCPU(); - } - - while (!emuRunningState.load() && fifoStateRun.load()) - { - g_video_backend->PeekMessages(); - VideoFifo_CheckSwapRequest(); - m_csSWVidOccupied.unlock(); - Common::SleepCurrentThread(1); - m_csSWVidOccupied.lock(); - } - } -} - -void VideoSoftware::Video_ExitLoop() -{ - fifoStateRun.store(false); -} - -// TODO : could use the OSD class in video common, we would need to implement the Renderer class -// however most of it is useless for the SW backend so we could as well move it to its own class -void VideoSoftware::Video_AddMessage(const std::string& msg, u32 milliseconds) -{ -} -void VideoSoftware::Video_ClearMessages() -{ -} - -void VideoSoftware::Video_SetRendering(bool bEnabled) -{ - SWCommandProcessor::SetRendering(bEnabled); -} - -void VideoSoftware::Video_GatherPipeBursted() -{ - SWCommandProcessor::GatherPipeBursted(); -} - -void VideoSoftware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) -{ - SWCommandProcessor::RegisterMMIO(mmio, base); -} - -// Draw messages on top of the screen unsigned int VideoSoftware::PeekMessages() { return SWOGLWindow::s_instance->PeekMessages(); diff --git a/Source/Core/VideoBackends/Software/SetupUnit.cpp b/Source/Core/VideoBackends/Software/SetupUnit.cpp index e433ae17f0..a9ef985963 100644 --- a/Source/Core/VideoBackends/Software/SetupUnit.cpp +++ b/Source/Core/VideoBackends/Software/SetupUnit.cpp @@ -4,11 +4,9 @@ #include "Common/ChunkFile.h" #include "VideoBackends/Software/Clipper.h" -#include "VideoBackends/Software/CPMemLoader.h" -#include "VideoBackends/Software/OpcodeDecoder.h" #include "VideoBackends/Software/SetupUnit.h" -#include "VideoBackends/Software/SWStatistics.h" +#include "VideoCommon/OpcodeDecoding.h" void SetupUnit::Init(u8 primitiveType) { @@ -167,20 +165,3 @@ void SetupUnit::SetupLineStrip() void SetupUnit::SetupPoint() {} -void SetupUnit::DoState(PointerWrap &p) -{ - // TODO: some or all of this is making the save states stop working once Dolphin is closed...sometimes (usually) - // I have no idea what specifically is wrong, or if this is even important. Disabling it doesn't seem to make any noticible difference... -/* p.Do(m_PrimType); - p.Do(m_VertexCounter); - for (int i = 0; i < 3; ++i) - m_Vertices[i].DoState(p); - - if (p.GetMode() == PointerWrap::MODE_READ) - { - m_VertPointer[0] = &m_Vertices[0]; - m_VertPointer[1] = &m_Vertices[1]; - m_VertPointer[2] = &m_Vertices[2]; - m_VertWritePointer = m_VertPointer[0]; - }*/ -} diff --git a/Source/Core/VideoBackends/Software/SetupUnit.h b/Source/Core/VideoBackends/Software/SetupUnit.h index c68d6b9c73..a00fc29634 100644 --- a/Source/Core/VideoBackends/Software/SetupUnit.h +++ b/Source/Core/VideoBackends/Software/SetupUnit.h @@ -7,8 +7,6 @@ #include "Common/CommonTypes.h" #include "VideoBackends/Software/NativeVertexFormat.h" -class PointerWrap; - class SetupUnit { u8 m_PrimType; @@ -32,5 +30,4 @@ public: OutputVertexData* GetVertex(); void SetupVertex(); - void DoState(PointerWrap &p); }; diff --git a/Source/Core/VideoBackends/Software/Software.vcxproj b/Source/Core/VideoBackends/Software/Software.vcxproj index edf569db32..488a9609aa 100644 --- a/Source/Core/VideoBackends/Software/Software.vcxproj +++ b/Source/Core/VideoBackends/Software/Software.vcxproj @@ -35,52 +35,38 @@ - - - - - - - - - - - - - - diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index 7391dfefb3..939b9f98a4 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -8,12 +8,13 @@ #include "Common/CommonTypes.h" #include "VideoBackends/Software/DebugUtil.h" #include "VideoBackends/Software/EfbInterface.h" -#include "VideoBackends/Software/SWStatistics.h" -#include "VideoBackends/Software/SWVideoConfig.h" #include "VideoBackends/Software/Tev.h" #include "VideoBackends/Software/TextureSampler.h" -#include "VideoBackends/Software/XFMemLoader.h" + #include "VideoCommon/BoundingBox.h" +#include "VideoCommon/Statistics.h" +#include "VideoCommon/VideoConfig.h" +#include "VideoCommon/XFMemory.h" #ifdef _DEBUG #define ALLOW_TEV_DUMPS 1 @@ -509,7 +510,7 @@ void Tev::Draw() _assert_(Position[0] >= 0 && Position[0] < EFB_WIDTH); _assert_(Position[1] >= 0 && Position[1] < EFB_HEIGHT); - INCSTAT(swstats.thisFrame.tevPixelsIn); + INCSTAT(stats.thisFrame.tevPixelsIn); for (unsigned int stageNum = 0; stageNum < bpmem.genMode.numindstages; stageNum++) { @@ -527,7 +528,7 @@ void Tev::Draw() IndirectLod[stageNum], IndirectLinear[stageNum], texmap, IndirectTex[stageNum]); #if ALLOW_TEV_DUMPS - if (g_SWVideoConfig.bDumpTevStages) + if (g_ActiveConfig.bDumpTevStages) { u8 stage[4] = { IndirectTex[stageNum][TextureSampler::ALP_SMP], @@ -565,7 +566,7 @@ void Tev::Draw() TextureSampler::Sample(TexCoord.s, TexCoord.t, TextureLod[stageNum], TextureLinear[stageNum], texmap, texel); #if ALLOW_TEV_DUMPS - if (g_SWVideoConfig.bDumpTevTextureFetches) + if (g_ActiveConfig.bDumpTevTextureFetches) DebugUtil::DrawTempBuffer(texel, DIRECT_TFETCH + stageNum); #endif @@ -632,7 +633,7 @@ void Tev::Draw() Reg[ac.dest][ALP_C] = Clamp1024(Reg[ac.dest][ALP_C]); #if ALLOW_TEV_DUMPS - if (g_SWVideoConfig.bDumpTevStages) + if (g_ActiveConfig.bDumpTevStages) { u8 stage[4] = {(u8)Reg[0][RED_C], (u8)Reg[0][GRN_C], (u8)Reg[0][BLU_C], (u8)Reg[0][ALP_C]}; DebugUtil::DrawTempBuffer(stage, DIRECT + stageNum); @@ -754,7 +755,7 @@ void Tev::Draw() output[BLU_C] = (output[BLU_C] * invFog + fogInt * bpmem.fog.color.b) >> 8; } - bool late_ztest = !bpmem.zcontrol.early_ztest || !g_SWVideoConfig.bZComploc; + bool late_ztest = !bpmem.zcontrol.early_ztest || !g_ActiveConfig.bZComploc; if (late_ztest && bpmem.zmode.testenable) { // TODO: Check against hw if these values get incremented even if depth testing is disabled @@ -773,7 +774,7 @@ void Tev::Draw() BoundingBox::coords[BoundingBox::BOTTOM] = std::max((u16)Position[1], BoundingBox::coords[BoundingBox::BOTTOM]); #if ALLOW_TEV_DUMPS - if (g_SWVideoConfig.bDumpTevStages) + if (g_ActiveConfig.bDumpTevStages) { for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) DebugUtil::CopyTempBuffer(Position[0], Position[1], INDIRECT, i, "Indirect"); @@ -781,7 +782,7 @@ void Tev::Draw() DebugUtil::CopyTempBuffer(Position[0], Position[1], DIRECT, i, "Stage"); } - if (g_SWVideoConfig.bDumpTevTextureFetches) + if (g_ActiveConfig.bDumpTevTextureFetches) { for (u32 i = 0; i <= bpmem.genMode.numtevstages; ++i) { @@ -792,7 +793,7 @@ void Tev::Draw() } #endif - INCSTAT(swstats.thisFrame.tevPixelsOut); + INCSTAT(stats.thisFrame.tevPixelsOut); EfbInterface::IncPerfCounterQuadCount(PQ_BLEND_INPUT); EfbInterface::BlendTev(Position[0], Position[1], output); @@ -810,29 +811,3 @@ void Tev::SetRegColor(int reg, int comp, bool konst, s16 color) } } -void Tev::DoState(PointerWrap &p) -{ - p.DoArray(Reg); - - p.DoArray(KonstantColors); - p.DoArray(TexColor); - p.DoArray(RasColor); - p.DoArray(StageKonst); - - p.DoArray(FixedConstants); - p.Do(AlphaBump); - p.DoArray(IndirectTex); - p.Do(TexCoord); - - p.DoArray(m_BiasLUT); - p.DoArray(m_ScaleLShiftLUT); - p.DoArray(m_ScaleRShiftLUT); - - p.DoArray(Position); - p.DoArray(Color); - p.DoArray(Uv); - p.DoArray(IndirectLod); - p.DoArray(IndirectLinear); - p.DoArray(TextureLod); - p.DoArray(TextureLinear); -} diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h index 9da27acc52..64e195555b 100644 --- a/Source/Core/VideoBackends/Software/Tev.h +++ b/Source/Core/VideoBackends/Software/Tev.h @@ -4,9 +4,7 @@ #pragma once -#include "VideoBackends/Software/BPMemLoader.h" - -class PointerWrap; +#include "VideoCommon/BPMemory.h" class Tev { @@ -90,6 +88,4 @@ public: void Draw(); void SetRegColor(int reg, int comp, bool konst, s16 color); - - void DoState(PointerWrap &p); }; diff --git a/Source/Core/VideoBackends/Software/TextureEncoder.cpp b/Source/Core/VideoBackends/Software/TextureEncoder.cpp index 13c5973c95..4b38d1c19a 100644 --- a/Source/Core/VideoBackends/Software/TextureEncoder.cpp +++ b/Source/Core/VideoBackends/Software/TextureEncoder.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "VideoBackends/Software/BPMemLoader.h" #include "VideoBackends/Software/EfbInterface.h" #include "VideoBackends/Software/TextureEncoder.h" +#include "VideoCommon/BPMemory.h" #include "VideoCommon/LookUpTables.h" #include "VideoCommon/TextureDecoder.h" diff --git a/Source/Core/VideoBackends/Software/TextureSampler.cpp b/Source/Core/VideoBackends/Software/TextureSampler.cpp index 3490133942..6c1001a6c8 100644 --- a/Source/Core/VideoBackends/Software/TextureSampler.cpp +++ b/Source/Core/VideoBackends/Software/TextureSampler.cpp @@ -7,8 +7,9 @@ #include "Common/Common.h" #include "Core/HW/Memmap.h" -#include "VideoBackends/Software/BPMemLoader.h" #include "VideoBackends/Software/TextureSampler.h" + +#include "VideoCommon/BPMemory.h" #include "VideoCommon/TextureDecoder.h" #define ALLOW_MIPMAP 1 diff --git a/Source/Core/VideoBackends/Software/TransformUnit.cpp b/Source/Core/VideoBackends/Software/TransformUnit.cpp index b3cd45a8a3..ab75964c24 100644 --- a/Source/Core/VideoBackends/Software/TransformUnit.cpp +++ b/Source/Core/VideoBackends/Software/TransformUnit.cpp @@ -8,13 +8,12 @@ #include "Common/CommonTypes.h" #include "Common/MathUtil.h" -#include "VideoBackends/Software/BPMemLoader.h" -#include "VideoBackends/Software/CPMemLoader.h" #include "VideoBackends/Software/NativeVertexFormat.h" #include "VideoBackends/Software/TransformUnit.h" #include "VideoBackends/Software/Vec3.h" -#include "VideoBackends/Software/XFMemLoader.h" +#include "VideoCommon/BPMemory.h" +#include "VideoCommon/XFMemory.h" namespace TransformUnit { diff --git a/Source/Core/VideoBackends/Software/Vec3.h b/Source/Core/VideoBackends/Software/Vec3.h index da54327fe2..f6c806847e 100644 --- a/Source/Core/VideoBackends/Software/Vec3.h +++ b/Source/Core/VideoBackends/Software/Vec3.h @@ -159,11 +159,4 @@ public: y = 0.0f; z = 0.0f; } - - void DoState(PointerWrap &p) - { - p.Do(x); - p.Do(y); - p.Do(z); - } }; diff --git a/Source/Core/VideoBackends/Software/VideoBackend.h b/Source/Core/VideoBackends/Software/VideoBackend.h index e34ae07f9a..7d9d4437db 100644 --- a/Source/Core/VideoBackends/Software/VideoBackend.h +++ b/Source/Core/VideoBackends/Software/VideoBackend.h @@ -12,7 +12,7 @@ namespace MMIO { class Mapping; } namespace SW { -class VideoSoftware : public VideoBackend +class VideoSoftware : public VideoBackendHardware { bool Initialize(void *window_handle) override; void Shutdown() override; @@ -20,42 +20,12 @@ class VideoSoftware : public VideoBackend std::string GetName() const override; std::string GetDisplayName() const override; - void EmuStateChange(EMUSTATE_CHANGE newState) override; - - void RunLoop(bool enable) override; - - void ShowConfig(void* parent) override; - void Video_Prepare() override; void Video_Cleanup() override; - void Video_EnterLoop() override; - void Video_ExitLoop() override; - void Video_BeginField(u32, u32, u32, u32) override; - void Video_EndField() override; - - u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) override; - u32 Video_GetQueryResult(PerfQueryType type) override; - u16 Video_GetBoundingBox(int index) override; - - void Video_AddMessage(const std::string& msg, unsigned int milliseconds) override; - void Video_ClearMessages() override; - bool Video_Screenshot(const std::string& filename) override; - - void Video_SetRendering(bool bEnabled) override; - - void Video_GatherPipeBursted() override; - int Video_Sync(int ticks) override { return 0; } - - void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) override; + void ShowConfig(void* parent) override; unsigned int PeekMessages() override; - - void PauseAndLock(bool doLock, bool unpauseOnUnlock=true) override; - void DoState(PointerWrap &p) override; - -public: - void CheckInvalidState() override; }; } diff --git a/Source/Core/VideoBackends/Software/XFMemLoader.cpp b/Source/Core/VideoBackends/Software/XFMemLoader.cpp deleted file mode 100644 index 3aa86aea8e..0000000000 --- a/Source/Core/VideoBackends/Software/XFMemLoader.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2009 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "Common/Common.h" -#include "Common/CommonFuncs.h" -#include "Core/HW/Memmap.h" -#include "VideoBackends/Software/Clipper.h" -#include "VideoBackends/Software/CPMemLoader.h" -#include "VideoBackends/Software/XFMemLoader.h" -#include "VideoCommon/VideoCommon.h" - -void InitXFMemory() -{ - memset(&xfmem, 0, sizeof(xfmem)); -} - -void XFWritten(u32 transferSize, u32 baseAddress) -{ - u32 topAddress = baseAddress + transferSize; - - if (baseAddress <= 0x1026 && topAddress >= 0x1020) - Clipper::SetViewOffset(); - - // fix lights so invalid values don't trash the lighting computations - if (baseAddress <= 0x067f && topAddress >= 0x0604) - { - u32* x = (u32*)xfmem.lights; - - // go through all lights - for (int light = 0; light < 8; light++) - { - // skip to floating point values - x += 4; - - for (int i = 0; i < 12; i++) - { - u32 xVal = *x; - - // if the exponent is 255 then the number is inf or nan - if ((xVal & 0x7f800000) == 0x7f800000) - *x = 0; - - x++; - } - } - } -} - -void SWLoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData) -{ - // do not allow writes past registers - if (baseAddress + transferSize > 0x1058) - { - INFO_LOG(VIDEO, "XF load exceeds address space: %x %d bytes", baseAddress, transferSize); - - if (baseAddress >= 0x1058) - transferSize = 0; - else - transferSize = 0x1058 - baseAddress; - } - - // write to XF regs - if (transferSize > 0) - { - memcpy((u32*)(&xfmem) + baseAddress, pData, transferSize * 4); - XFWritten(transferSize, baseAddress); - } -} - -void SWLoadIndexedXF(u32 val, int array) -{ - int index = val >> 16; - int address = val & 0xFFF; //check mask - int size = ((val >> 12) & 0xF) + 1; - //load stuff from array to address in xf mem - - u32 *pData = (u32*)Memory::GetPointer(g_main_cp_state.array_bases[array] + g_main_cp_state.array_strides[array]*index); - - // byteswap data - u32 buffer[16]; - for (int i = 0; i < size; ++i) - buffer[i] = Common::swap32(*(pData + i)); - - SWLoadXFReg(size, address, buffer); -} diff --git a/Source/Core/VideoBackends/Software/XFMemLoader.h b/Source/Core/VideoBackends/Software/XFMemLoader.h deleted file mode 100644 index cfbaecfd1b..0000000000 --- a/Source/Core/VideoBackends/Software/XFMemLoader.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include "Common/CommonTypes.h" - -#include "VideoCommon/XFMemory.h" - -void InitXFMemory(); - -void XFWritten(u32 transferSize, u32 baseAddress); - -void SWLoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData); - -void SWLoadIndexedXF(u32 val, int array); diff --git a/Source/Core/VideoCommon/CPMemory.h b/Source/Core/VideoCommon/CPMemory.h index 491f818305..59183fe47f 100644 --- a/Source/Core/VideoCommon/CPMemory.h +++ b/Source/Core/VideoCommon/CPMemory.h @@ -257,6 +257,7 @@ struct CPState final BitSet32 attr_dirty; bool bases_dirty; VertexLoaderBase* vertex_loaders[8]; + int last_id; }; class PointerWrap; diff --git a/Source/Core/VideoCommon/Statistics.cpp b/Source/Core/VideoCommon/Statistics.cpp index 04164cdaed..53db2fcf50 100644 --- a/Source/Core/VideoCommon/Statistics.cpp +++ b/Source/Core/VideoCommon/Statistics.cpp @@ -8,6 +8,7 @@ #include "Common/StringUtil.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/VertexLoaderManager.h" +#include "VideoCommon/VideoConfig.h" Statistics stats; @@ -27,6 +28,21 @@ void Statistics::SwapDL() std::string Statistics::ToString() { std::string str; + + if (g_ActiveConfig.backend_info.APIType == API_TYPE::API_NONE) + { + str += StringFromFormat("Objects: %i\n", stats.thisFrame.numDrawnObjects); + str += StringFromFormat("Vertices Loaded: %i\n", stats.thisFrame.numVerticesLoaded); + str += StringFromFormat("Triangles Input: %i\n", stats.thisFrame.numTrianglesIn); + str += StringFromFormat("Triangles Rejected: %i\n", stats.thisFrame.numTrianglesRejected); + str += StringFromFormat("Triangles Culled: %i\n", stats.thisFrame.numTrianglesCulled); + str += StringFromFormat("Triangles Clipped: %i\n", stats.thisFrame.numTrianglesClipped); + str += StringFromFormat("Triangles Drawn: %i\n", stats.thisFrame.numTrianglesDrawn); + str += StringFromFormat("Rasterized Pix: %i\n", stats.thisFrame.rasterizedPixels); + str += StringFromFormat("TEV Pix In: %i\n", stats.thisFrame.tevPixelsIn); + str += StringFromFormat("TEV Pix Out: %i\n", stats.thisFrame.tevPixelsOut); + } + str += StringFromFormat("Textures created: %i\n", stats.numTexturesCreated); str += StringFromFormat("Textures uploaded: %i\n", stats.numTexturesUploaded); str += StringFromFormat("Textures alive: %i\n", stats.numTexturesAlive); diff --git a/Source/Core/VideoCommon/Statistics.h b/Source/Core/VideoCommon/Statistics.h index edd70bdf97..26c663a513 100644 --- a/Source/Core/VideoCommon/Statistics.h +++ b/Source/Core/VideoCommon/Statistics.h @@ -52,6 +52,17 @@ struct Statistics int bytesVertexStreamed; int bytesIndexStreamed; int bytesUniformStreamed; + + int numTrianglesClipped; + int numTrianglesIn; + int numTrianglesRejected; + int numTrianglesCulled; + int numDrawnObjects; + int rasterizedPixels; + int numTrianglesDrawn; + int numVerticesLoaded; + int tevPixelsIn; + int tevPixelsOut; }; ThisFrame thisFrame; void ResetFrame(); diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index baf04ba52a..5012dea9d8 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -124,6 +124,7 @@ void MarkAllDirty() static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = false) { CPState* state = preprocess ? &g_preprocess_cp_state : &g_main_cp_state; + state->last_id = vtx_attr_group; VertexLoaderBase* loader; if (state->attr_dirty[vtx_attr_group]) diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 626e1f0bd0..50486d716a 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -87,6 +87,15 @@ void VideoConfig::Load(const std::string& ini_file) settings->Get("EnableShaderDebugging", &bEnableShaderDebugging, false); settings->Get("BorderlessFullscreen", &bBorderlessFullscreen, false); + settings->Get("SWZComploc", &bZComploc, true); + settings->Get("SWZFreeze", &bZFreeze, true); + settings->Get("SWDumpObjects", &bDumpObjects, false); + settings->Get("SWDumpTevStages", &bDumpTevStages, false); + settings->Get("SWDumpTevTexFetches", &bDumpTevTextureFetches, false); + settings->Get("SWDrawStart", &drawStart, 0); + settings->Get("SWDrawEnd", &drawEnd, 100000); + + IniFile::Section* enhancements = iniFile.GetOrCreateSection("Enhancements"); enhancements->Get("ForceFiltering", &bForceFiltering, 0); enhancements->Get("MaxAnisotropy", &iMaxAnisotropy, 0); // NOTE - this is x in (1 << x) @@ -287,6 +296,14 @@ void VideoConfig::Save(const std::string& ini_file) settings->Set("EnableShaderDebugging", bEnableShaderDebugging); settings->Set("BorderlessFullscreen", bBorderlessFullscreen); + settings->Set("SWZComploc", bZComploc); + settings->Set("SWZFreeze", bZFreeze); + settings->Set("SWDumpObjects", bDumpObjects); + settings->Set("SWDumpTevStages", bDumpTevStages); + settings->Set("SWDumpTevTexFetches", bDumpTevTextureFetches); + settings->Set("SWDrawStart", drawStart); + settings->Set("SWDrawEnd", drawEnd); + IniFile::Section* enhancements = iniFile.GetOrCreateSection("Enhancements"); enhancements->Set("ForceFiltering", bForceFiltering); enhancements->Set("MaxAnisotropy", iMaxAnisotropy); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 5b88e64c2f..bc0250ab2f 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -136,6 +136,15 @@ struct VideoConfig final // Debugging bool bEnableShaderDebugging; + // VideoSW Debugging + int drawStart; + int drawEnd; + bool bZComploc; + bool bZFreeze; + bool bDumpObjects; + bool bDumpTevStages; + bool bDumpTevTextureFetches; + // Static config per API // TODO: Move this out of VideoConfig struct