From 609a44aaf2f70fb253c93bf84952bd14bfe1b91b Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 25 Jan 2023 20:51:23 +1000 Subject: [PATCH] GS/SW: Move code buffer into main memory map --- pcsx2/CMakeLists.txt | 7 - pcsx2/GS/GSCodeBuffer.cpp | 71 --- pcsx2/GS/GSCodeBuffer.h | 31 -- pcsx2/GS/Renderers/Common/GSFunctionMap.h | 40 +- pcsx2/GS/Renderers/HW/GSRendererHW.h | 1 - .../GS/Renderers/HW/GSRendererHWMultiISA.cpp | 12 +- pcsx2/GS/Renderers/SW/GSDrawScanline.cpp | 522 ++++++++++-------- pcsx2/GS/Renderers/SW/GSDrawScanline.h | 141 +---- .../SW/GSDrawScanlineCodeGenerator.cpp | 3 +- pcsx2/GS/Renderers/SW/GSRasterizer.cpp | 167 +++--- pcsx2/GS/Renderers/SW/GSRasterizer.h | 44 +- pcsx2/GS/Renderers/SW/GSRendererSW.h | 6 +- pcsx2/System.cpp | 43 +- pcsx2/System.h | 66 ++- pcsx2/System/RecTypes.h | 50 -- pcsx2/VMManager.cpp | 2 +- pcsx2/pcsx2core.vcxproj | 3 - pcsx2/pcsx2core.vcxproj.filters | 9 - pcsx2/x86/iR3000A.cpp | 2 +- pcsx2/x86/ix86-32/iR5900-32.cpp | 2 +- pcsx2/x86/microVU.h | 2 +- pcsx2/x86/newVif.h | 2 +- 22 files changed, 557 insertions(+), 669 deletions(-) delete mode 100644 pcsx2/GS/GSCodeBuffer.cpp delete mode 100644 pcsx2/GS/GSCodeBuffer.h delete mode 100644 pcsx2/System/RecTypes.h diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index f1eade721a..aabe691ce5 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -494,7 +494,6 @@ set(pcsx2GSSources GS/GSAlignedClass.cpp GS/GSCapture.cpp GS/GSClut.cpp - GS/GSCodeBuffer.cpp GS/GSCrc.cpp GS/GSDrawingContext.cpp GS/GSDump.cpp @@ -534,7 +533,6 @@ set(pcsx2GSHeaders GS/GSBlock.h GS/GSCapture.h GS/GSClut.h - GS/GSCodeBuffer.h GS/GSCrc.h GS/GSDrawingContext.h GS/GSDrawingEnvironment.h @@ -985,10 +983,6 @@ set(pcsx2RecordingHeaders ${rec_src}/Utilities/InputRecordingLogger.h ) -# System headers -set(pcsx2SystemHeaders - System/RecTypes.h) - # Windows sources set(pcsx2WindowsSources CDVD/Windows/DriveUtility.cpp @@ -1114,7 +1108,6 @@ target_sources(PCSX2 PRIVATE ${pcsx2FrontendHeaders} ${pcsx2ps2Sources} ${pcsx2ps2Headers} - ${pcsx2SystemHeaders} ) # platform sources diff --git a/pcsx2/GS/GSCodeBuffer.cpp b/pcsx2/GS/GSCodeBuffer.cpp deleted file mode 100644 index 8a69e9cf6f..0000000000 --- a/pcsx2/GS/GSCodeBuffer.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2021 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "PrecompiledHeader.h" -#include "GSCodeBuffer.h" -#include "GSExtra.h" -#include "common/General.h" - -GSCodeBuffer::GSCodeBuffer(size_t blocksize) - : m_blocksize(blocksize) - , m_pos(0) - , m_reserved(0) - , m_ptr(NULL) -{ -} - -GSCodeBuffer::~GSCodeBuffer() -{ - for (auto buffer : m_buffers) - { - HostSys::Munmap(buffer, m_blocksize); - } -} - -void* GSCodeBuffer::GetBuffer(size_t size) -{ - pxAssert(size < m_blocksize); - pxAssert(m_reserved == 0); - - size = (size + 15) & ~15; - - if (m_ptr == NULL || m_pos + size > m_blocksize) - { - m_ptr = (u8*)HostSys::Mmap(nullptr, m_blocksize, PageProtectionMode().All()); - if (!m_ptr) - pxFailRel("Failed to allocate GS code buffer"); - - m_pos = 0; - - m_buffers.push_back(m_ptr); - } - - u8* ptr = &m_ptr[m_pos]; - - m_reserved = size; - - return ptr; -} - -void GSCodeBuffer::ReleaseBuffer(size_t size) -{ - pxAssert(size <= m_reserved); - - m_pos = ((m_pos + size) + 15) & ~15; - - pxAssert(m_pos < m_blocksize); - - m_reserved = 0; -} diff --git a/pcsx2/GS/GSCodeBuffer.h b/pcsx2/GS/GSCodeBuffer.h deleted file mode 100644 index 50b345a7b8..0000000000 --- a/pcsx2/GS/GSCodeBuffer.h +++ /dev/null @@ -1,31 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2021 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#pragma once - -class GSCodeBuffer -{ - std::vector m_buffers; - size_t m_blocksize; - size_t m_pos, m_reserved; - u8* m_ptr; - -public: - GSCodeBuffer(size_t blocksize = 4096 * 64); // 256k - virtual ~GSCodeBuffer(); - - void* GetBuffer(size_t size); - void ReleaseBuffer(size_t size); -}; diff --git a/pcsx2/GS/Renderers/Common/GSFunctionMap.h b/pcsx2/GS/Renderers/Common/GSFunctionMap.h index 63a593fbd3..4496ad02c2 100644 --- a/pcsx2/GS/Renderers/Common/GSFunctionMap.h +++ b/pcsx2/GS/Renderers/Common/GSFunctionMap.h @@ -15,9 +15,9 @@ #pragma once -#include "GS/GSCodeBuffer.h" #include "GS/GSExtra.h" #include "GS/Renderers/SW/GSScanlineEnvironment.h" +#include "System.h" #include "common/emitter/tools.h" template @@ -147,28 +147,25 @@ class GSCodeGeneratorFunctionMap : public GSFunctionMap { std::string m_name; std::unordered_map m_cgmap; - GSCodeBuffer m_cb; - size_t m_total_code_size; enum { MAX_SIZE = 8192 }; public: - GSCodeGeneratorFunctionMap(const char* name) + GSCodeGeneratorFunctionMap(std::string name) : m_name(name) - , m_total_code_size(0) { } - ~GSCodeGeneratorFunctionMap() + ~GSCodeGeneratorFunctionMap() = default; + + void Clear() { -#ifdef _DEBUG - fprintf(stderr, "%s generated %zu bytes of instruction\n", m_name.c_str(), m_total_code_size); -#endif + m_cgmap.clear(); } VALUE GetDefaultFunction(KEY key) { - VALUE ret = NULL; + VALUE ret = nullptr; auto i = m_cgmap.find(key); @@ -178,22 +175,19 @@ public: } else { - void* code_ptr = m_cb.GetBuffer(MAX_SIZE); - - CG* cg = new CG(key, code_ptr, MAX_SIZE); - ASSERT(cg->getSize() < MAX_SIZE); + u8* code_ptr = GetVmMemory().GSCode().Reserve(MAX_SIZE); + CG cg(key, code_ptr, MAX_SIZE); + ASSERT(cg.getSize() < MAX_SIZE); #if 0 - fprintf(stderr, "%s Location:%p Size:%zu Key:%llx\n", m_name.c_str(), code_ptr, cg->getSize(), (u64)key); + fprintf(stderr, "%s Location:%p Size:%zu Key:%llx\n", m_name.c_str(), code_ptr, cg.getSize(), (u64)key); GSScanlineSelector sel(key); sel.Print(); #endif - m_total_code_size += cg->getSize(); + GetVmMemory().GSCode().Commit(cg.getSize()); - m_cb.ReleaseBuffer(cg->getSize()); - - ret = (VALUE)cg->getCode(); + ret = (VALUE)cg.getCode(); m_cgmap[key] = ret; @@ -211,8 +205,8 @@ public: ml.method_id = iJIT_GetNewMethodID(); ml.method_name = (char*)name.c_str(); - ml.method_load_address = (void*)cg->getCode(); - ml.method_size = (unsigned int)cg->getSize(); + ml.method_load_address = (void*)cg.getCode(); + ml.method_size = (unsigned int)cg.getSize(); iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &ml); /* @@ -224,7 +218,7 @@ public: fputc(0xBB, fp); fputc(0x6F, fp); fputc(0x00, fp); fputc(0x00, fp); fputc(0x00, fp); fputc(0x64, fp); fputc(0x67, fp); fputc(0x90, fp); - fwrite(cg->getCode(), cg->getSize(), 1, fp); + fwrite(cg.getCode(), cg.getSize(), 1, fp); fputc(0xBB, fp); fputc(0xDE, fp); fputc(0x00, fp); fputc(0x00, fp); fputc(0x00, fp); fputc(0x64, fp); fputc(0x67, fp); fputc(0x90, fp); @@ -236,8 +230,6 @@ public: } #endif - - delete cg; } return ret; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.h b/pcsx2/GS/Renderers/HW/GSRendererHW.h index 49061582fc..b34fffb5a3 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.h +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.h @@ -120,7 +120,6 @@ private: // software sprite renderer state std::vector m_sw_vertex_buffer; std::unique_ptr m_sw_texture[7 + 1]; - std::unique_ptr> m_sw_draw_scanline; std::unique_ptr> m_sw_rasterizer; public: diff --git a/pcsx2/GS/Renderers/HW/GSRendererHWMultiISA.cpp b/pcsx2/GS/Renderers/HW/GSRendererHWMultiISA.cpp index 0b89c8917e..2bc99270ae 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHWMultiISA.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHWMultiISA.cpp @@ -16,7 +16,7 @@ #include "GSRendererHW.h" #include "GS/Renderers/SW/GSTextureCacheSW.h" -#include "GS/Renderers/SW/GSDrawScanline.h" +#include "GS/Renderers/SW/GSRasterizer.h" class CURRENT_ISA::GSRendererHWFunctions { @@ -44,7 +44,7 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc) const GSDrawingEnvironment& env = hw.m_env; const GS_PRIM_CLASS primclass = vt.m_primclass; - GSDrawScanline::SharedData data; + GSRasterizerData data; GSScanlineGlobalData& gd = data.global; u32 clut_storage[256]; @@ -549,13 +549,9 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc) } if (!hw.m_sw_rasterizer) - { - hw.m_sw_draw_scanline = std::make_unique(); - hw.m_sw_rasterizer = std::make_unique(static_cast(hw.m_sw_draw_scanline.get()), 0, 1); - } + hw.m_sw_rasterizer = std::make_unique(); - static_cast(hw.m_sw_draw_scanline.get())->SetupDraw(data); - static_cast(hw.m_sw_rasterizer.get())->Draw(data); + static_cast(hw.m_sw_rasterizer.get())->Draw(data); if (invalidate_tc) hw.m_tc->InvalidateVideoMem(context->offset.fb, bbox); diff --git a/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp b/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp index 5910d2a190..aca9d9cb81 100644 --- a/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp +++ b/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp @@ -14,8 +14,11 @@ */ #include "PrecompiledHeader.h" -#include "GSDrawScanline.h" -#include "GSTextureCacheSW.h" +#include "GS/Renderers/SW/GSDrawScanline.h" +#include "GS/Renderers/SW/GSTextureCacheSW.h" +#include "GS/Renderers/SW/GSScanlineEnvironment.h" +#include "GS/Renderers/SW/GSRasterizer.h" +#include "GS/config.h" #if MULTI_ISA_COMPILE_ONCE // Lack of a better home @@ -33,13 +36,21 @@ GSDrawScanline::GSDrawScanline() : m_sp_map("GSSetupPrim") , m_ds_map("GSDrawScanline") { + GetVmMemory().GSCode().AllowModification(); + GetVmMemory().GSCode().Reset(); } -GSDrawScanline::~GSDrawScanline() = default; +GSDrawScanline::~GSDrawScanline() +{ + if (const size_t used = GetVmMemory().GSCode().GetMemoryUsed(); used > 0) + DevCon.WriteLn("SW JIT generated %zu bytes of code", used); + + GetVmMemory().GSCode().ForbidModification(); +} void GSDrawScanline::BeginDraw(const GSRasterizerData& data, GSScanlineLocalData& local) { - const GSScanlineGlobalData& global = static_cast(data).global; + const GSScanlineGlobalData& global = data.global; local.gd = &global; if (global.sel.mmin && global.sel.lcm) @@ -67,12 +78,22 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData& data, GSScanlineLocalData } } -void GSDrawScanline::SetupDraw(GSRasterizerData& data) +void GSDrawScanline::ResetCodeCache() { + Console.Warning("GS Software JIT cache overflow, resetting."); + m_sp_map.Clear(); + m_ds_map.Clear(); + GetVmMemory().GSCode().Reset(); +} + +bool GSDrawScanline::SetupDraw(GSRasterizerData& data) +{ + const GSScanlineGlobalData& global = data.global; + #ifdef ENABLE_JIT_RASTERIZER - SharedData& sdata = static_cast(data); - const GSScanlineGlobalData& global = sdata.global; - sdata.ds = m_ds_map[global.sel]; + data.draw_scanline = m_ds_map[global.sel]; + if (!unlikely(data.draw_scanline)) + return false; if (global.sel.aa1) { @@ -82,11 +103,13 @@ void GSDrawScanline::SetupDraw(GSRasterizerData& data) sel.zwrite = 0; sel.edge = 1; - sdata.de = m_ds_map[sel]; + data.draw_edge = m_ds_map[sel]; + if (unlikely(!data.draw_edge)) + return false; } else { - sdata.de = nullptr; + data.draw_edge = nullptr; } // doesn't need all bits => less functions generated @@ -107,7 +130,12 @@ void GSDrawScanline::SetupDraw(GSRasterizerData& data) sel.zequal = global.sel.zequal; sel.notest = global.sel.notest; - sdata.sp = m_sp_map[sel]; + return (data.setup_prim = m_sp_map[sel]) != nullptr; +#else + data.setup_prim = &GSDrawScanline::CSetupPrim; + data.draw_scanline = &GSDrawScanline::CDrawScanline; + data.draw_edge = global.sel.aa1 ? &GSDrawScanline::CDrawEdge : nullptr; + return true; #endif } @@ -116,6 +144,11 @@ void GSDrawScanline::UpdateDrawStats(u64 frame, u64 ticks, int actual, int total m_ds_map.UpdateStats(frame, ticks, actual, total, prims); } +void GSDrawScanline::PrintStats() +{ + m_ds_map.PrintStats(); +} + #if _M_SSE >= 0x501 typedef GSVector8i VectorI; typedef GSVector8 VectorF; @@ -310,6 +343,111 @@ void GSDrawScanline::CSetupPrim(const GSVertexSW* vertex, const u32* index, cons } } +template +__ri static bool TestAlpha(T& test, T& fm, T& zm, const T& ga, const GSScanlineGlobalData& global) +{ + GSScanlineSelector sel = global.sel; + + switch (sel.afail) + { + case AFAIL_FB_ONLY: + if (!sel.zwrite) + return true; + break; + + case AFAIL_ZB_ONLY: + if (!sel.fwrite) + return true; + break; + + case AFAIL_RGB_ONLY: + if (!sel.zwrite && sel.fpsm == 1) + return true; + break; + } + + T t; + + switch (sel.atst) + { + case ATST_NEVER: + t = GSVector4i::xffffffff(); + break; + + case ATST_ALWAYS: + return true; + + case ATST_LESS: + case ATST_LEQUAL: + t = (ga >> 16) > T(global.aref); + break; + + case ATST_EQUAL: + t = (ga >> 16) != T(global.aref); + break; + + case ATST_GEQUAL: + case ATST_GREATER: + t = (ga >> 16) < T(global.aref); + break; + + case ATST_NOTEQUAL: + t = (ga >> 16) == T(global.aref); + break; + + default: + __assume(0); + } + + switch (sel.afail) + { + case AFAIL_KEEP: + test |= t; + if (test.alltrue()) + return false; + break; + + case AFAIL_FB_ONLY: + zm |= t; + break; + + case AFAIL_ZB_ONLY: + fm |= t; + break; + + case AFAIL_RGB_ONLY: + zm |= t; + fm |= t & T::xff000000(); // fpsm 16 bit => & 0xffff8000? + break; + + default: + __assume(0); + } + + return true; +} + +static const int s_offsets[] = {0, 2, 8, 10, 16, 18, 24, 26}; // columnTable16[0] + +template +__ri static void WritePixel(const T& src, int addr, int i, u32 psm, const GSScanlineGlobalData& global) +{ + u8* dst = (u8*)global.vm + addr * 2 + s_offsets[i] * 2; + + switch (psm) + { + case 0: + *(u32*)dst = src.U32[i]; + break; + case 1: + *(u32*)dst = (src.U32[i] & 0xffffff) | (*(u32*)dst & 0xff000000); + break; + case 2: + *(u16*)dst = src.U16[i * 2]; + break; + } +} + void GSDrawScanline::CDrawScanline(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local) { const GSScanlineGlobalData& global = GlobalFromLocal(local); @@ -1587,108 +1725,150 @@ void GSDrawScanline::CDrawScanline(int pixels, int left, int top, const GSVertex } } -template -bool GSDrawScanline::TestAlpha(T& test, T& fm, T& zm, const T& ga, const GSScanlineGlobalData& global) +void GSDrawScanline::CDrawEdge(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local) { - GSScanlineSelector sel = global.sel; + // This sucks. But so does not jitting! + const GSScanlineGlobalData* old_gd = local.gd; + GSScanlineGlobalData gd; + std::memcpy(&gd, &local.gd, sizeof(gd)); + gd.sel.zwrite = 0; + gd.sel.edge = 1; + local.gd = &gd; - switch (sel.afail) - { - case AFAIL_FB_ONLY: - if (!sel.zwrite) - return true; - break; + CDrawScanline(pixels, left, top, scan, local); - case AFAIL_ZB_ONLY: - if (!sel.fwrite) - return true; - break; - - case AFAIL_RGB_ONLY: - if (!sel.zwrite && sel.fpsm == 1) - return true; - break; - } - - T t; - - switch (sel.atst) - { - case ATST_NEVER: - t = GSVector4i::xffffffff(); - break; - - case ATST_ALWAYS: - return true; - - case ATST_LESS: - case ATST_LEQUAL: - t = (ga >> 16) > T(global.aref); - break; - - case ATST_EQUAL: - t = (ga >> 16) != T(global.aref); - break; - - case ATST_GEQUAL: - case ATST_GREATER: - t = (ga >> 16) < T(global.aref); - break; - - case ATST_NOTEQUAL: - t = (ga >> 16) == T(global.aref); - break; - - default: - __assume(0); - } - - switch (sel.afail) - { - case AFAIL_KEEP: - test |= t; - if (test.alltrue()) - return false; - break; - - case AFAIL_FB_ONLY: - zm |= t; - break; - - case AFAIL_ZB_ONLY: - fm |= t; - break; - - case AFAIL_RGB_ONLY: - zm |= t; - fm |= t & T::xff000000(); // fpsm 16 bit => & 0xffff8000? - break; - - default: - __assume(0); - } - - return true; + local.gd = old_gd; } -static const int s_offsets[] = {0, 2, 8, 10, 16, 18, 24, 26}; // columnTable16[0] - -template -void GSDrawScanline::WritePixel(const T& src, int addr, int i, u32 psm, const GSScanlineGlobalData& global) +template +__ri static void FillRect(const GSOffset& off, const GSVector4i& r, u32 c, u32 m, GSScanlineLocalData& local) { - u8* dst = (u8*)global.vm + addr * 2 + s_offsets[i] * 2; + if (r.x >= r.z) + return; - switch (psm) + T* vm = (T*)GlobalFromLocal(local).vm; + + for (int y = r.y; y < r.w; y++) { - case 0: - *(u32*)dst = src.U32[i]; - break; - case 1: - *(u32*)dst = (src.U32[i] & 0xffffff) | (*(u32*)dst & 0xff000000); - break; - case 2: - *(u16*)dst = src.U16[i * 2]; - break; + auto pa = off.paMulti(vm, 0, y); + + for (int x = r.x; x < r.z; x++) + { + T& d = *pa.value(x); + d = (T)(!masked ? c : (c | (d & m))); + } + } +} + +#if _M_SSE >= 0x501 + +template +__ri static void FillBlock(const GSOffset& off, const GSVector4i& r, const GSVector8i& c, const GSVector8i& m, GSScanlineLocalData& local) +{ + if (r.x >= r.z) + return; + + T* vm = (T*)GlobalFromLocal(local).vm; + + for (int y = r.y; y < r.w; y += 8) + { + for (int x = r.x; x < r.z; x += 8 * 4 / sizeof(T)) + { + GSVector8i* RESTRICT p = (GSVector8i*)&vm[off.pa(x, y)]; + + p[0] = !masked ? c : (c | (p[0] & m)); + p[1] = !masked ? c : (c | (p[1] & m)); + p[2] = !masked ? c : (c | (p[2] & m)); + p[3] = !masked ? c : (c | (p[3] & m)); + p[4] = !masked ? c : (c | (p[4] & m)); + p[5] = !masked ? c : (c | (p[5] & m)); + p[6] = !masked ? c : (c | (p[6] & m)); + p[7] = !masked ? c : (c | (p[7] & m)); + } + } +} + +#else + +template +__ri static void FillBlock(const GSOffset& off, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m, GSScanlineLocalData& local) +{ + if (r.x >= r.z) + return; + + T* vm = (T*)GlobalFromLocal(local).vm; + + for (int y = r.y; y < r.w; y += 8) + { + auto pa = off.paMulti(vm, 0, y); + + for (int x = r.x; x < r.z; x += 8 * 4 / sizeof(T)) + { + GSVector4i* RESTRICT p = (GSVector4i*)pa.value(x); + + for (int i = 0; i < 16; i += 4) + { + p[i + 0] = !masked ? c : (c | (p[i + 0] & m)); + p[i + 1] = !masked ? c : (c | (p[i + 1] & m)); + p[i + 2] = !masked ? c : (c | (p[i + 2] & m)); + p[i + 3] = !masked ? c : (c | (p[i + 3] & m)); + } + } + } +} + +#endif + +template +__ri static void DrawRectT(const GSOffset& off, const GSVector4i& r, u32 c, u32 m, GSScanlineLocalData& local) +{ + if (m == 0xffffffff) + return; + +#if _M_SSE >= 0x501 + + GSVector8i color((int)c); + GSVector8i mask((int)m); + +#else + + GSVector4i color((int)c); + GSVector4i mask((int)m); + +#endif + + if (sizeof(T) == sizeof(u16)) + { + color = color.xxzzlh(); + mask = mask.xxzzlh(); + c = (c & 0xffff) | (c << 16); + m = (m & 0xffff) | (m << 16); + } + + color = color.andnot(mask); + c = c & (~m); + + if (masked) + ASSERT(mask.U32[0] != 0); + + GSVector4i br = r.ralign(GSVector2i(8 * 4 / sizeof(T), 8)); + + if (!br.rempty()) + { + FillRect(off, GSVector4i(r.x, r.y, r.z, br.y), c, m, local); + FillRect(off, GSVector4i(r.x, br.w, r.z, r.w), c, m, local); + + if (r.x < br.x || br.z < r.z) + { + FillRect(off, GSVector4i(r.x, br.y, br.x, br.w), c, m, local); + FillRect(off, GSVector4i(br.z, br.y, r.z, br.w), c, m, local); + } + + FillBlock(off, br, color, mask, local); + } + else + { + FillRect(off, r, c, m, local); } } @@ -1777,135 +1957,3 @@ void GSDrawScanline::DrawRect(const GSVector4i& r, const GSVertexSW& v, GSScanli } } } - -template -void GSDrawScanline::DrawRectT(const GSOffset& off, const GSVector4i& r, u32 c, u32 m, GSScanlineLocalData& local) -{ - if (m == 0xffffffff) - return; - -#if _M_SSE >= 0x501 - - GSVector8i color((int)c); - GSVector8i mask((int)m); - -#else - - GSVector4i color((int)c); - GSVector4i mask((int)m); - -#endif - - if (sizeof(T) == sizeof(u16)) - { - color = color.xxzzlh(); - mask = mask.xxzzlh(); - c = (c & 0xffff) | (c << 16); - m = (m & 0xffff) | (m << 16); - } - - color = color.andnot(mask); - c = c & (~m); - - if (masked) - ASSERT(mask.U32[0] != 0); - - GSVector4i br = r.ralign(GSVector2i(8 * 4 / sizeof(T), 8)); - - if (!br.rempty()) - { - FillRect(off, GSVector4i(r.x, r.y, r.z, br.y), c, m, local); - FillRect(off, GSVector4i(r.x, br.w, r.z, r.w), c, m, local); - - if (r.x < br.x || br.z < r.z) - { - FillRect(off, GSVector4i(r.x, br.y, br.x, br.w), c, m, local); - FillRect(off, GSVector4i(br.z, br.y, r.z, br.w), c, m, local); - } - - FillBlock(off, br, color, mask, local); - } - else - { - FillRect(off, r, c, m, local); - } -} - -template -void GSDrawScanline::FillRect(const GSOffset& off, const GSVector4i& r, u32 c, u32 m, GSScanlineLocalData& local) -{ - if (r.x >= r.z) - return; - - T* vm = (T*)GlobalFromLocal(local).vm; - - for (int y = r.y; y < r.w; y++) - { - auto pa = off.paMulti(vm, 0, y); - - for (int x = r.x; x < r.z; x++) - { - T& d = *pa.value(x); - d = (T)(!masked ? c : (c | (d & m))); - } - } -} - -#if _M_SSE >= 0x501 - -template -void GSDrawScanline::FillBlock(const GSOffset& off, const GSVector4i& r, const GSVector8i& c, const GSVector8i& m, GSScanlineLocalData& local) -{ - if (r.x >= r.z) - return; - - T* vm = (T*)GlobalFromLocal(local).vm; - - for (int y = r.y; y < r.w; y += 8) - { - for (int x = r.x; x < r.z; x += 8 * 4 / sizeof(T)) - { - GSVector8i* RESTRICT p = (GSVector8i*)&vm[off.pa(x, y)]; - - p[0] = !masked ? c : (c | (p[0] & m)); - p[1] = !masked ? c : (c | (p[1] & m)); - p[2] = !masked ? c : (c | (p[2] & m)); - p[3] = !masked ? c : (c | (p[3] & m)); - p[4] = !masked ? c : (c | (p[4] & m)); - p[5] = !masked ? c : (c | (p[5] & m)); - p[6] = !masked ? c : (c | (p[6] & m)); - p[7] = !masked ? c : (c | (p[7] & m)); - } - } -} - -#else - -template -void GSDrawScanline::FillBlock(const GSOffset& off, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m, GSScanlineLocalData& local) -{ - if (r.x >= r.z) - return; - - T* vm = (T*)GlobalFromLocal(local).vm; - - for (int y = r.y; y < r.w; y += 8) - { - auto pa = off.paMulti(vm, 0, y); - - for (int x = r.x; x < r.z; x += 8 * 4 / sizeof(T)) - { - GSVector4i* RESTRICT p = (GSVector4i*)pa.value(x); - - for (int i = 0; i < 16; i += 4) - { - p[i + 0] = !masked ? c : (c | (p[i + 0] & m)); - p[i + 1] = !masked ? c : (c | (p[i + 1] & m)); - p[i + 2] = !masked ? c : (c | (p[i + 2] & m)); - p[i + 3] = !masked ? c : (c | (p[i + 3] & m)); - } - } - } -} - -#endif diff --git a/pcsx2/GS/Renderers/SW/GSDrawScanline.h b/pcsx2/GS/Renderers/SW/GSDrawScanline.h index a62291f9cc..cd2921979e 100644 --- a/pcsx2/GS/Renderers/SW/GSDrawScanline.h +++ b/pcsx2/GS/Renderers/SW/GSDrawScanline.h @@ -16,136 +16,53 @@ #pragma once #include "GS/GSState.h" -#include "GS/Renderers/SW/GSRasterizer.h" -#include "GS/Renderers/SW/GSScanlineEnvironment.h" #include "GS/Renderers/SW/GSSetupPrimCodeGenerator.h" #include "GS/Renderers/SW/GSDrawScanlineCodeGenerator.h" -#include "GS/config.h" -#include +struct GSScanlineLocalData; MULTI_ISA_UNSHARED_START +class GSRasterizerData; + +class GSSetupPrimCodeGenerator; +class GSDrawScanlineCodeGenerator; + class GSDrawScanline : public GSVirtualAlignedClass<32> { -public: - using SetupPrimPtr = void(*)(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, GSScanlineLocalData& local); - using DrawScanlinePtr = void(*)(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local); - - class SharedData : public GSRasterizerData - { - public: - GSScanlineGlobalData global; - -#ifdef ENABLE_JIT_RASTERIZER - SetupPrimPtr sp; - DrawScanlinePtr ds; - DrawScanlinePtr de; -#endif - }; - -protected: - GSCodeGeneratorFunctionMap m_sp_map; - GSCodeGeneratorFunctionMap m_ds_map; - - template - static void DrawRectT(const GSOffset& off, const GSVector4i& r, u32 c, u32 m, GSScanlineLocalData& local); - - template - static __forceinline void FillRect(const GSOffset& off, const GSVector4i& r, u32 c, u32 m, GSScanlineLocalData& local); - -#if _M_SSE >= 0x501 - - template - static __forceinline void FillBlock(const GSOffset& off, const GSVector4i& r, const GSVector8i& c, const GSVector8i& m, GSScanlineLocalData& local); - -#else - - template - static __forceinline void FillBlock(const GSOffset& off, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m, GSScanlineLocalData& local); - -#endif + friend GSSetupPrimCodeGenerator; + friend GSDrawScanlineCodeGenerator; public: GSDrawScanline(); ~GSDrawScanline() override; - void SetupDraw(GSRasterizerData& data); - void UpdateDrawStats(u64 frame, u64 ticks, int actual, int total, int prims); + /// Function pointer types which we call back into. + using SetupPrimPtr = void(*)(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, GSScanlineLocalData& local); + using DrawScanlinePtr = void(*)(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local); + /// Flushes the code cache, forcing everything to be recompiled. + void ResetCodeCache(); + + /// Populates function pointers. If this returns false, we ran out of code space. + bool SetupDraw(GSRasterizerData& data); + + /// Draw pre-calculations, computed per-thread. static void BeginDraw(const GSRasterizerData& data, GSScanlineLocalData& local); + /// Not currently jitted. + static void DrawRect(const GSVector4i& r, const GSVertexSW& v, GSScanlineLocalData& local); + + void UpdateDrawStats(u64 frame, u64 ticks, int actual, int total, int prims); + void PrintStats(); + +private: + GSCodeGeneratorFunctionMap m_sp_map; + GSCodeGeneratorFunctionMap m_ds_map; + static void CSetupPrim(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, GSScanlineLocalData& local); static void CDrawScanline(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local); - - template static bool TestAlpha(T& test, T& fm, T& zm, const T& ga, const GSScanlineGlobalData& global); - template static void WritePixel(const T& src, int addr, int i, u32 psm, const GSScanlineGlobalData& global); - -#ifdef ENABLE_JIT_RASTERIZER - - __forceinline static void SetupPrim(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index, - const GSVertexSW& dscan, GSScanlineLocalData& local) - { - static_cast(data).sp(vertex, index, dscan, local); - } - __forceinline static void DrawScanline( - const GSRasterizerData& data, int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local) - { - static_cast(data).ds(pixels, left, top, scan, local); - } - __forceinline static void DrawEdge( - const GSRasterizerData& data, int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local) - { - static_cast(data).de(pixels, left, top, scan, local); - } - - __forceinline static bool HasEdge(const GSRasterizerData& data) - { - return static_cast(data).de != nullptr; - } - -#else - - __forceinline static void SetupPrim(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index, - const GSVertexSW& dscan, GSScanlineLocalData& local) - { - CSetupPrim(vertex, index, dscan, local); - } - __forceinline static void DrawScanline( - const GSRasterizerData& data, int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local) - { - CDrawScanline(pixels, left, top, scan, local); - } - __forceinline static void DrawEdge( - const GSRasterizerData& data, int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local) - { - // This sucks. But so does not jitting! - const GSScanlineGlobalData* old_gd = local.gd; - GSScanlineGlobalData gd; - std::memcpy(&gd, &local.gd, sizeof(gd)); - gd.sel.zwrite = 0; - gd.sel.edge = 1; - local.gd = &gd; - - CDrawScanline(pixels, left, top, scan, local); - - local.gd = old_gd; - } - - __forceinline static bool HasEdge(const SharedData& data) - { - return static_cast(data).global.sel.aa1; - } - -#endif - - // Not currently jitted. - void DrawRect(const GSVector4i& r, const GSVertexSW& v, GSScanlineLocalData& local); - - void PrintStats() - { - m_ds_map.PrintStats(); - } + static void CDrawEdge(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local); }; MULTI_ISA_UNSHARED_END diff --git a/pcsx2/GS/Renderers/SW/GSDrawScanlineCodeGenerator.cpp b/pcsx2/GS/Renderers/SW/GSDrawScanlineCodeGenerator.cpp index b25f76435b..212b61131b 100644 --- a/pcsx2/GS/Renderers/SW/GSDrawScanlineCodeGenerator.cpp +++ b/pcsx2/GS/Renderers/SW/GSDrawScanlineCodeGenerator.cpp @@ -91,8 +91,7 @@ GSDrawScanlineCodeGenerator::GSDrawScanlineCodeGenerator(u64 key, void* code, si if (shouldUseCDrawScanline(key)) { - mov(rax, reinterpret_cast(GSDrawScanline::CDrawScanline)); // TODO: Get rid of once we move to memory map - jmp(rax); + jmp(reinterpret_cast(&GSDrawScanline::CDrawScanline)); return; } diff --git a/pcsx2/GS/Renderers/SW/GSRasterizer.cpp b/pcsx2/GS/Renderers/SW/GSRasterizer.cpp index 82705f56f0..34af6bc4ff 100644 --- a/pcsx2/GS/Renderers/SW/GSRasterizer.cpp +++ b/pcsx2/GS/Renderers/SW/GSRasterizer.cpp @@ -146,7 +146,10 @@ void GSRasterizer::Draw(GSRasterizerData& data) if constexpr (ENABLE_DRAW_STATS) data.start = __rdtsc(); - GSDrawScanline::BeginDraw(static_cast(data), m_local); + m_setup_prim = data.setup_prim; + m_draw_scanline = data.draw_scanline; + m_draw_edge = data.draw_edge; + GSDrawScanline::BeginDraw(data, m_local); const GSVertexSW* vertex = data.vertex; const GSVertexSW* vertex_end = data.vertex + data.vertex_count; @@ -169,11 +172,11 @@ void GSRasterizer::Draw(GSRasterizerData& data) if (scissor_test) { - DrawPoint(data, vertex, index); + DrawPoint(vertex, data.vertex_count, index, data.index_count); } else { - DrawPoint(data, vertex, index); + DrawPoint(vertex, data.vertex_count, index, data.index_count); } break; @@ -184,7 +187,7 @@ void GSRasterizer::Draw(GSRasterizerData& data) { do { - DrawLine(data, vertex, index); + DrawLine(vertex, index); index += 2; } while (index < index_end); } @@ -192,7 +195,7 @@ void GSRasterizer::Draw(GSRasterizerData& data) { do { - DrawLine(data, vertex, tmp_index); + DrawLine(vertex, tmp_index); vertex += 2; } while (vertex < vertex_end); } @@ -205,7 +208,7 @@ void GSRasterizer::Draw(GSRasterizerData& data) { do { - DrawTriangle(data, vertex, index); + DrawTriangle(vertex, index); index += 3; } while (index < index_end); } @@ -213,7 +216,7 @@ void GSRasterizer::Draw(GSRasterizerData& data) { do { - DrawTriangle(data, vertex, tmp_index); + DrawTriangle(vertex, tmp_index); vertex += 3; } while (vertex < vertex_end); } @@ -226,7 +229,7 @@ void GSRasterizer::Draw(GSRasterizerData& data) { do { - DrawSprite(data, vertex, index); + DrawSprite(vertex, index); index += 2; } while (index < index_end); } @@ -234,7 +237,7 @@ void GSRasterizer::Draw(GSRasterizerData& data) { do { - DrawSprite(data, vertex, tmp_index); + DrawSprite(vertex, tmp_index); vertex += 2; } while (vertex < vertex_end); } @@ -258,13 +261,10 @@ void GSRasterizer::Draw(GSRasterizerData& data) } template -void GSRasterizer::DrawPoint(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index) +void GSRasterizer::DrawPoint(const GSVertexSW* vertex, int vertex_count, const u32* index, int index_count) { m_primcount++; - const int vertex_count = data.vertex_count; - const int index_count = data.index_count; - if (index) { for (int i = 0; i < index_count; i++, index++) @@ -277,9 +277,9 @@ void GSRasterizer::DrawPoint(const GSRasterizerData& data, const GSVertexSW* ver { if (IsOneOfMyScanlines(p.y)) { - GSDrawScanline::SetupPrim(data, vertex, index, GSVertexSW::zero(), m_local); + m_setup_prim(vertex, index, GSVertexSW::zero(), m_local); - DrawScanline(data, 1, p.x, p.y, v); + DrawScanline(1, p.x, p.y, v); } } } @@ -298,16 +298,16 @@ void GSRasterizer::DrawPoint(const GSRasterizerData& data, const GSVertexSW* ver { if (IsOneOfMyScanlines(p.y)) { - GSDrawScanline::SetupPrim(data, vertex, tmp_index, GSVertexSW::zero(), m_local); + m_setup_prim(vertex, tmp_index, GSVertexSW::zero(), m_local); - DrawScanline(data, 1, p.x, p.y, v); + DrawScanline(1, p.x, p.y, v); } } } } } -void GSRasterizer::DrawLine(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index) +void GSRasterizer::DrawLine(const GSVertexSW* vertex, const u32* index) { m_primcount++; @@ -320,12 +320,12 @@ void GSRasterizer::DrawLine(const GSRasterizerData& data, const GSVertexSW* vert int i = (dp < dp.yxwz()).mask() & 1; // |dx| <= |dy| - if (GSDrawScanline::HasEdge(data)) + if (HasEdge()) { - DrawEdge(data, v0, v1, dv, i, 0); - DrawEdge(data, v0, v1, dv, i, 1); + DrawEdge(v0, v1, dv, i, 0); + DrawEdge(v0, v1, dv, i, 1); - Flush(data, vertex, index, GSVertexSW::zero(), true); + Flush(vertex, index, GSVertexSW::zero(), true); return; } @@ -366,9 +366,9 @@ void GSRasterizer::DrawLine(const GSRasterizerData& data, const GSVertexSW* vert scan += dscan * (l - scan.p).xxxx(); - GSDrawScanline::SetupPrim(data, vertex, index, dscan, m_local); + m_setup_prim(vertex, index, dscan, m_local); - DrawScanline(data, pixels, left, p.y, scan); + DrawScanline(pixels, left, p.y, scan); } } } @@ -407,7 +407,7 @@ void GSRasterizer::DrawLine(const GSRasterizerData& data, const GSVertexSW* vert m_edge.count = e - m_edge.buff; - Flush(data, vertex, index, GSVertexSW::zero()); + Flush(vertex, index, GSVertexSW::zero()); } } @@ -425,7 +425,7 @@ static const u8 s_ysort[8][4] = #if _M_SSE >= 0x501 -void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index) +void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u32* index) { m_primcount++; @@ -509,7 +509,7 @@ void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* edge.p.y = vertex[i[m2]].p.x; dedge.p = ddx[!m2 << 1].yzzw(dedge.p); - DrawTriangleSection(data, tb.x, tb.w, edge, dedge, dscan, vertex[i[1 - m2]].p); + DrawTriangleSection(tb.x, tb.w, edge, dedge, dscan, vertex[i[1 - m2]].p); } } else @@ -521,7 +521,7 @@ void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* edge.p.y = edge.p.x; dedge.p = ddx[m2].xyzw(dedge.p); - DrawTriangleSection(data, tb.x, tb.z, edge, dedge, dscan, v0.p); + DrawTriangleSection(tb.x, tb.z, edge, dedge, dscan, v0.p); } if (tb.y < tb.w) @@ -531,13 +531,13 @@ void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* edge.p = (v0.p.xxxx() + ddx[m2] * dv0.p.yyyy()).xyzw(edge.p); dedge.p = ddx[!m2 << 1].yzzw(dedge.p); - DrawTriangleSection(data, tb.y, tb.w, edge, dedge, dscan, v1.p); + DrawTriangleSection(tb.y, tb.w, edge, dedge, dscan, v1.p); } } - Flush(data, vertex, index, (GSVertexSW&)dscan); + Flush(vertex, index, (GSVertexSW&)dscan); - if (GSDrawScanline::HasEdge(data)) + if (HasEdge()) { GSVector4 a = dx.abs() < dy.abs(); // |dx| <= |dy| GSVector4 b = dx < GSVector4::zero(); // dx < 0 @@ -546,15 +546,15 @@ void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* int orientation = a.mask(); int side = ((a | b) ^ c).mask() ^ 2; // evil - DrawEdge(data, (GSVertexSW&)v0, (GSVertexSW&)v1, (GSVertexSW&)dv0, orientation & 1, side & 1); - DrawEdge(data, (GSVertexSW&)v0, (GSVertexSW&)v2, (GSVertexSW&)dv1, orientation & 2, side & 2); - DrawEdge(data, (GSVertexSW&)v1, (GSVertexSW&)v2, (GSVertexSW&)dv2, orientation & 4, side & 4); + DrawEdge((GSVertexSW&)v0, (GSVertexSW&)v1, (GSVertexSW&)dv0, orientation & 1, side & 1); + DrawEdge((GSVertexSW&)v0, (GSVertexSW&)v2, (GSVertexSW&)dv1, orientation & 2, side & 2); + DrawEdge((GSVertexSW&)v1, (GSVertexSW&)v2, (GSVertexSW&)dv2, orientation & 4, side & 4); - Flush(data, vertex, index, GSVertexSW::zero(), true); + Flush(vertex, index, GSVertexSW::zero(), true); } } -void GSRasterizer::DrawTriangleSection(const GSRasterizerData& data, int top, int bottom, GSVertexSW2& RESTRICT edge, const GSVertexSW2& RESTRICT dedge, const GSVertexSW2& RESTRICT dscan, const GSVector4& RESTRICT p0) +void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW2& RESTRICT edge, const GSVertexSW2& RESTRICT dedge, const GSVertexSW2& RESTRICT dscan, const GSVector4& RESTRICT p0) { ASSERT(top < bottom); ASSERT(edge.p.x <= edge.p.y); @@ -606,7 +606,7 @@ void GSRasterizer::DrawTriangleSection(const GSRasterizerData& data, int top, in #else -void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index) +void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u32* index) { m_primcount++; @@ -688,7 +688,7 @@ void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* edge.p.y = vertex[i[m2]].p.x; dedge.p = ddx[!m2 << 1].yzzw(dedge.p); - DrawTriangleSection(data, tb.x, tb.w, edge, dedge, dscan, vertex[i[1 - m2]].p); + DrawTriangleSection(tb.x, tb.w, edge, dedge, dscan, vertex[i[1 - m2]].p); } } else @@ -700,7 +700,7 @@ void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* edge.p.y = edge.p.x; dedge.p = ddx[m2].xyzw(dedge.p); - DrawTriangleSection(data, tb.x, tb.z, edge, dedge, dscan, v0.p); + DrawTriangleSection(tb.x, tb.z, edge, dedge, dscan, v0.p); } if (tb.y < tb.w) @@ -710,13 +710,13 @@ void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* edge.p = (v0.p.xxxx() + ddx[m2] * dv0.p.yyyy()).xyzw(edge.p); dedge.p = ddx[!m2 << 1].yzzw(dedge.p); - DrawTriangleSection(data, tb.y, tb.w, edge, dedge, dscan, v1.p); + DrawTriangleSection(tb.y, tb.w, edge, dedge, dscan, v1.p); } } - Flush(data, vertex, index, dscan); + Flush(vertex, index, dscan); - if (GSDrawScanline::HasEdge(data)) + if (HasEdge()) { GSVector4 a = dx.abs() < dy.abs(); // |dx| <= |dy| GSVector4 b = dx < GSVector4::zero(); // dx < 0 @@ -725,15 +725,15 @@ void GSRasterizer::DrawTriangle(const GSRasterizerData& data, const GSVertexSW* int orientation = a.mask(); int side = ((a | b) ^ c).mask() ^ 2; // evil - DrawEdge(data, v0, v1, dv0, orientation & 1, side & 1); - DrawEdge(data, v0, v2, dv1, orientation & 2, side & 2); - DrawEdge(data, v1, v2, dv2, orientation & 4, side & 4); + DrawEdge(v0, v1, dv0, orientation & 1, side & 1); + DrawEdge(v0, v2, dv1, orientation & 2, side & 2); + DrawEdge(v1, v2, dv2, orientation & 4, side & 4); - Flush(data, vertex, index, GSVertexSW::zero(), true); + Flush(vertex, index, GSVertexSW::zero(), true); } } -void GSRasterizer::DrawTriangleSection(const GSRasterizerData& data, int top, int bottom, GSVertexSW& RESTRICT edge, const GSVertexSW& RESTRICT dedge, const GSVertexSW& RESTRICT dscan, const GSVector4& RESTRICT p0) +void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& RESTRICT edge, const GSVertexSW& RESTRICT dedge, const GSVertexSW& RESTRICT dscan, const GSVector4& RESTRICT p0) { ASSERT(top < bottom); ASSERT(edge.p.x <= edge.p.y); @@ -784,7 +784,7 @@ void GSRasterizer::DrawTriangleSection(const GSRasterizerData& data, int top, in #endif -void GSRasterizer::DrawSprite(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index) +void GSRasterizer::DrawSprite(const GSVertexSW* vertex, const u32* index) { m_primcount++; @@ -811,12 +811,11 @@ void GSRasterizer::DrawSprite(const GSRasterizerData& data, const GSVertexSW* ve GSVertexSW scan = v[0]; - // TODO: Double check IsSolidRect() works. if ((m_scanmsk_value & 2) == 0 && m_local.gd->sel.IsSolidRect()) { if (m_threads == 1) { - m_ds->DrawRect(r, scan, m_local); + GSDrawScanline::DrawRect(r, scan, m_local); int pixels = r.width() * r.height(); @@ -833,7 +832,7 @@ void GSRasterizer::DrawSprite(const GSRasterizerData& data, const GSVertexSW* ve r.top = top; r.bottom = std::min((top + (1 << m_thread_height)) & ~((1 << m_thread_height) - 1), bottom); - m_ds->DrawRect(r, scan, m_local); + GSDrawScanline::DrawRect(r, scan, m_local); int pixels = r.width() * r.height(); @@ -862,13 +861,13 @@ void GSRasterizer::DrawSprite(const GSRasterizerData& data, const GSVertexSW* ve scan.t = (scan.t + dt * prestep).xyzw(scan.t); - GSDrawScanline::SetupPrim(data, vertex, index, dscan, m_local); + m_setup_prim(vertex, index, dscan, m_local); while (1) { if (IsOneOfMyScanlines(r.top)) { - DrawScanline(data, r.width(), r.left, r.top, scan); + DrawScanline(r.width(), r.left, r.top, scan); } if (++r.top >= r.bottom) @@ -878,7 +877,7 @@ void GSRasterizer::DrawSprite(const GSRasterizerData& data, const GSVertexSW* ve } } -void GSRasterizer::DrawEdge(const GSRasterizerData& data, const GSVertexSW& v0, const GSVertexSW& v1, const GSVertexSW& dv, int orientation, int side) +void GSRasterizer::DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GSVertexSW& dv, int orientation, int side) { // orientation: // - true: |dv.p.y| > |dv.p.x| @@ -1083,7 +1082,7 @@ void GSRasterizer::AddScanline(GSVertexSW* e, int pixels, int left, int top, con AddScanlineInfo(e, pixels, left, top); } -void GSRasterizer::Flush(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, bool edge /* = false */) +void GSRasterizer::Flush(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, bool edge /* = false */) { // TODO: on win64 this could be the place where xmm6-15 are preserved (not by each DrawScanline) @@ -1091,7 +1090,7 @@ void GSRasterizer::Flush(const GSRasterizerData& data, const GSVertexSW* vertex, if (count > 0) { - m_ds->SetupPrim(data, vertex, index, dscan, m_local); + m_setup_prim(vertex, index, dscan, m_local); const GSVertexSW* RESTRICT e = m_edge.buff; const GSVertexSW* RESTRICT ee = e + count; @@ -1104,7 +1103,7 @@ void GSRasterizer::Flush(const GSRasterizerData& data, const GSVertexSW* vertex, int left = e->_pad.I32[1]; int top = e->_pad.I32[2]; - DrawScanline(data, pixels, left, top, *e++); + DrawScanline(pixels, left, top, *e++); } while (e < ee); } else @@ -1115,7 +1114,7 @@ void GSRasterizer::Flush(const GSRasterizerData& data, const GSVertexSW* vertex, int left = e->_pad.I32[1]; int top = e->_pad.I32[2]; - DrawEdge(data, pixels, left, top, *e++); + DrawEdge(pixels, left, top, *e++); } while (e < ee); } @@ -1129,7 +1128,7 @@ void GSRasterizer::Flush(const GSRasterizerData& data, const GSVertexSW* vertex, #define PIXELS_PER_LOOP 4 #endif -void GSRasterizer::DrawScanline(const GSRasterizerData& data, int pixels, int left, int top, const GSVertexSW& scan) +void GSRasterizer::DrawScanline(int pixels, int left, int top, const GSVertexSW& scan) { if ((m_scanmsk_value & 2) && (m_scanmsk_value & 1) == (top & 1)) return; m_pixels.actual += pixels; @@ -1138,10 +1137,10 @@ void GSRasterizer::DrawScanline(const GSRasterizerData& data, int pixels, int le ASSERT(m_pixels.actual <= m_pixels.total); - GSDrawScanline::DrawScanline(data, pixels, left, top, scan, m_local); + m_draw_scanline(pixels, left, top, scan, m_local); } -void GSRasterizer::DrawEdge(const GSRasterizerData& data, int pixels, int left, int top, const GSVertexSW& scan) +void GSRasterizer::DrawEdge(int pixels, int left, int top, const GSVertexSW& scan) { if ((m_scanmsk_value & 2) && (m_scanmsk_value & 1) == (top & 1)) return; m_pixels.actual += 1; @@ -1149,27 +1148,32 @@ void GSRasterizer::DrawEdge(const GSRasterizerData& data, int pixels, int left, ASSERT(m_pixels.actual <= m_pixels.total); - GSDrawScanline::DrawEdge(data, pixels, left, top, scan, m_local); + m_draw_edge(pixels, left, top, scan, m_local); } // GSSingleRasterizer::GSSingleRasterizer() + : m_r(&m_ds, 0, 1) { - m_ds = std::make_unique(); - m_r = std::make_unique(m_ds.get(), 0, 1); } -GSSingleRasterizer::~GSSingleRasterizer() -{ - m_r.reset(); - m_ds.reset(); -} +GSSingleRasterizer::~GSSingleRasterizer() = default; void GSSingleRasterizer::Queue(const GSRingHeap::SharedPtr& data) { - m_ds->SetupDraw(*data.get()); - m_r->Draw(*data.get()); + Draw(*data.get()); +} + +void GSSingleRasterizer::Draw(GSRasterizerData& data) +{ + if (!unlikely(m_ds.SetupDraw(data))) + { + m_ds.ResetCodeCache(); + m_ds.SetupDraw(data); + } + + m_r.Draw(data); } void GSSingleRasterizer::Sync() @@ -1183,20 +1187,18 @@ bool GSSingleRasterizer::IsSynced() const int GSSingleRasterizer::GetPixels(bool reset /*= true*/) { - return m_r->GetPixels(reset); + return m_r.GetPixels(reset); } void GSSingleRasterizer::PrintStats() { - m_ds->PrintStats(); + m_ds.PrintStats(); } // GSRasterizerList::GSRasterizerList(int threads) { - m_ds = std::make_unique(); - m_thread_height = compute_best_thread_height(threads); const int rows = (2048 >> m_thread_height) + 16; @@ -1213,12 +1215,6 @@ GSRasterizerList::GSRasterizerList(int threads) GSRasterizerList::~GSRasterizerList() { PerformanceMetrics::SetGSSWThreadCount(0); - - // Destruct draw scanline last. - m_workers.clear(); - m_r.clear(); - m_ds.reset(); - _aligned_free(m_scanline); } @@ -1252,7 +1248,12 @@ void GSRasterizerList::Queue(const GSRingHeap::SharedPtr& data { GSVector4i r = data->bbox.rintersect(data->scissor); - m_ds->SetupDraw(*data.get()); + if (unlikely(!m_ds.SetupDraw(*data.get()))) + { + Sync(); + m_ds.ResetCodeCache(); + m_ds.SetupDraw(*data.get()); + } ASSERT(r.top >= 0 && r.top < 2048 && r.bottom >= 0 && r.bottom < 2048); @@ -1316,7 +1317,7 @@ std::unique_ptr GSRasterizerList::Create(int threads) for (int i = 0; i < threads; i++) { - rl->m_r.push_back(std::unique_ptr(new GSRasterizer(rl->m_ds.get(), i, threads))); + rl->m_r.push_back(std::unique_ptr(new GSRasterizer(&rl->m_ds, i, threads))); auto& r = *rl->m_r[i]; rl->m_workers.push_back(std::unique_ptr(new GSWorker([i]() { GSRasterizerList::OnWorkerStartup(i); }, [&r](GSRingHeap::SharedPtr& item) { r.Draw(*item.get()); }, diff --git a/pcsx2/GS/Renderers/SW/GSRasterizer.h b/pcsx2/GS/Renderers/SW/GSRasterizer.h index b9a466aee7..d9492fd4a9 100644 --- a/pcsx2/GS/Renderers/SW/GSRasterizer.h +++ b/pcsx2/GS/Renderers/SW/GSRasterizer.h @@ -16,7 +16,7 @@ #pragma once #include "GS/Renderers/SW/GSVertexSW.h" -#include "GS/Renderers/Common/GSFunctionMap.h" +#include "GS/Renderers/SW/GSDrawScanline.h" #include "GS/GSAlignedClass.h" #include "GS/GSPerfMon.h" #include "GS/GSThread_CXX11.h" @@ -47,6 +47,12 @@ public: int counter; u8 scanmsk_value; + GSScanlineGlobalData global; + + GSDrawScanline::SetupPrimPtr setup_prim; + GSDrawScanline::DrawScanlinePtr draw_scanline; + GSDrawScanline::DrawScanlinePtr draw_edge; + GSRasterizerData() : scissor(GSVector4i::zero()) , bbox(GSVector4i::zero()) @@ -87,30 +93,33 @@ protected: struct { int sum, actual, total; } m_pixels; int m_primcount; + // For the current draw. GSScanlineLocalData m_local = {}; + GSDrawScanline::SetupPrimPtr m_setup_prim = nullptr; + GSDrawScanline::DrawScanlinePtr m_draw_scanline = nullptr; + GSDrawScanline::DrawScanlinePtr m_draw_edge = nullptr; - // TODO: Make data pointer a class member? - // Or, at the very least, pull the function pointers out. + __forceinline bool HasEdge() const { return (m_draw_edge != nullptr); } template - void DrawPoint(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index); - void DrawLine(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index); - void DrawTriangle(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index); - void DrawSprite(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index); + void DrawPoint(const GSVertexSW* vertex, int vertex_count, const u32* index, int index_count); + void DrawLine(const GSVertexSW* vertex, const u32* index); + void DrawTriangle(const GSVertexSW* vertex, const u32* index); + void DrawSprite(const GSVertexSW* vertex, const u32* index); #if _M_SSE >= 0x501 - __forceinline void DrawTriangleSection(const GSRasterizerData& data, int top, int bottom, GSVertexSW2& RESTRICT edge, const GSVertexSW2& RESTRICT dedge, const GSVertexSW2& RESTRICT dscan, const GSVector4& RESTRICT p0); + __forceinline void DrawTriangleSection(int top, int bottom, GSVertexSW2& RESTRICT edge, const GSVertexSW2& RESTRICT dedge, const GSVertexSW2& RESTRICT dscan, const GSVector4& RESTRICT p0); #else - __forceinline void DrawTriangleSection(const GSRasterizerData& data, int top, int bottom, GSVertexSW& RESTRICT edge, const GSVertexSW& RESTRICT dedge, const GSVertexSW& RESTRICT dscan, const GSVector4& RESTRICT p0); + __forceinline void DrawTriangleSection(int top, int bottom, GSVertexSW& RESTRICT edge, const GSVertexSW& RESTRICT dedge, const GSVertexSW& RESTRICT dscan, const GSVector4& RESTRICT p0); #endif - void DrawEdge(const GSRasterizerData& data, const GSVertexSW& v0, const GSVertexSW& v1, const GSVertexSW& dv, int orientation, int side); + void DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GSVertexSW& dv, int orientation, int side); __forceinline void AddScanline(GSVertexSW* e, int pixels, int left, int top, const GSVertexSW& scan); - __forceinline void Flush(const GSRasterizerData& data, const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, bool edge = false); + __forceinline void Flush(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, bool edge = false); - __forceinline void DrawScanline(const GSRasterizerData& data, int pixels, int left, int top, const GSVertexSW& scan); - __forceinline void DrawEdge(const GSRasterizerData& data, int pixels, int left, int top, const GSVertexSW& scan); + __forceinline void DrawScanline(int pixels, int left, int top, const GSVertexSW& scan); + __forceinline void DrawEdge(int pixels, int left, int top, const GSVertexSW& scan); public: GSRasterizer(GSDrawScanline* ds, int id, int threads); @@ -148,10 +157,11 @@ public: int GetPixels(bool reset = true) override; void PrintStats() override; + void Draw(GSRasterizerData& data); + private: - // TODO: Get rid of indirection here - std::unique_ptr m_ds; - std::unique_ptr m_r; + GSDrawScanline m_ds; + GSRasterizer m_r; }; class GSRasterizerList final : public IRasterizer @@ -159,7 +169,7 @@ class GSRasterizerList final : public IRasterizer protected: using GSWorker = GSJobQueue, 65536>; - std::unique_ptr m_ds; + GSDrawScanline m_ds; // Worker threads depend on the rasterizers, so don't change the order. std::vector> m_r; diff --git a/pcsx2/GS/Renderers/SW/GSRendererSW.h b/pcsx2/GS/Renderers/SW/GSRendererSW.h index 321bfa7c14..d132ae7d4e 100644 --- a/pcsx2/GS/Renderers/SW/GSRendererSW.h +++ b/pcsx2/GS/Renderers/SW/GSRendererSW.h @@ -15,8 +15,8 @@ #pragma once -#include "GSTextureCacheSW.h" -#include "GSDrawScanline.h" +#include "GS/Renderers/SW/GSTextureCacheSW.h" +#include "GS/Renderers/SW/GSRasterizer.h" #include "GS/GSRingHeap.h" #include "GS/MultiISA.h" @@ -25,7 +25,7 @@ MULTI_ISA_UNSHARED_START class GSRendererSW final : public GSRenderer { public: - class SharedData : public GSDrawScanline::SharedData + class SharedData : public GSRasterizerData { struct alignas(16) TextureLevel { diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index 039296143c..850dbbbcad 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -22,8 +22,6 @@ #include "Elfheader.h" -#include "System/RecTypes.h" - #include "common/Align.h" #include "common/MemsetFast.inl" #include "common/Perf.h" @@ -133,6 +131,36 @@ RecompiledCodeReserve& RecompiledCodeReserve::SetProfilerName(std::string name) return *this; } +GSCodeReserve::GSCodeReserve() + : RecompiledCodeReserve("GS Software Renderer") +{ +} + +GSCodeReserve::~GSCodeReserve() = default; + +void GSCodeReserve::Assign(VirtualMemoryManagerPtr allocator) +{ + RecompiledCodeReserve::Assign(std::move(allocator), HostMemoryMap::SWrecOffset, HostMemoryMap::SWrecSize); +} + +void GSCodeReserve::Reset() +{ + RecompiledCodeReserve::Reset(); + m_memory_used = 0; +} + +u8* GSCodeReserve::Reserve(size_t size) +{ + pxAssert((m_memory_used + size) <= m_size); + return m_baseptr + m_memory_used; +} + +void GSCodeReserve::Commit(size_t size) +{ + pxAssert((m_memory_used + size) <= m_size); + m_memory_used += size; +} + #include "svnrev.h" Pcsx2Config EmuConfig; @@ -221,9 +249,9 @@ namespace HostMemoryMap // For debuggers extern "C" { #ifdef _WIN32 - _declspec(dllexport) uptr EEmem, IOPmem, VUmem, EErec, IOPrec, VIF0rec, VIF1rec, mVU0rec, mVU1rec, bumpAllocator; + _declspec(dllexport) uptr EEmem, IOPmem, VUmem, EErec, IOPrec, VIF0rec, VIF1rec, mVU0rec, mVU1rec, SWjit, bumpAllocator; #else - __attribute__((visibility("default"), used)) uptr EEmem, IOPmem, VUmem, EErec, IOPrec, VIF0rec, VIF1rec, mVU0rec, mVU1rec, bumpAllocator; + __attribute__((visibility("default"), used)) uptr EEmem, IOPmem, VUmem, EErec, IOPrec, VIF0rec, VIF1rec, mVU0rec, mVU1rec, SWjit, bumpAllocator; #endif } } // namespace HostMemoryMap @@ -301,7 +329,9 @@ bool SysMainMemory::Allocate() m_ee.Assign(MainMemory()); m_iop.Assign(MainMemory()); m_vu.Assign(MainMemory()); + vtlb_Core_Alloc(); + return true; } @@ -315,6 +345,7 @@ void SysMainMemory::Reset() m_vu.Reset(); // Note: newVif is reset as part of other VIF structures. + // Software is reset on the GS thread. } void SysMainMemory::Release() @@ -356,10 +387,14 @@ SysCpuProviderPack::SysCpuProviderPack() dVifReserve(0); dVifReserve(1); } + + GetVmMemory().GSCode().Assign(GetVmMemory().CodeMemory()); } SysCpuProviderPack::~SysCpuProviderPack() { + GetVmMemory().GSCode().Release(); + if (newVifDynaRec) { dVifRelease(1); diff --git a/pcsx2/System.h b/pcsx2/System.h index 424b6dc074..83d73239b9 100644 --- a/pcsx2/System.h +++ b/pcsx2/System.h @@ -28,7 +28,6 @@ typedef SafeArray VmStateBuffer; class BaseVUmicroCPU; -class RecompiledCodeReserve; // This is a table of default virtual map addresses for ps2vm components. These locations // are provided and used to assist in debugging and possibly hacking; as it makes it possible @@ -64,7 +63,7 @@ namespace HostMemoryMap ////////////////////////////////////////////////////////////////////////// // Code ////////////////////////////////////////////////////////////////////////// - static const u32 CodeSize = 0x0F100000; // 241 mb + static const u32 CodeSize = 0x13100000; // 305 mb // EE recompiler code cache area (64mb) static const u32 EErecOffset = 0x00000000; @@ -86,8 +85,67 @@ namespace HostMemoryMap // SSE-optimized VIF unpack functions (1mb) static const u32 VIFUnpackRecOffset = 0x0F000000; + + // Software Renderer JIT buffer (64mb) + static const u32 SWrecOffset = 0x0F100000; + static const u32 SWrecSize = 0x04000000; } +// -------------------------------------------------------------------------------------- +// RecompiledCodeReserve +// -------------------------------------------------------------------------------------- +// A recompiled code reserve is a simple sequential-growth block of memory which is auto- +// cleared to INT 3 (0xcc) as needed. +// +class RecompiledCodeReserve : public VirtualMemoryReserve +{ + typedef VirtualMemoryReserve _parent; + +protected: + std::string m_profiler_name; + +public: + RecompiledCodeReserve(std::string name); + ~RecompiledCodeReserve(); + + void Assign(VirtualMemoryManagerPtr allocator, size_t offset, size_t size); + void Reset(); + + RecompiledCodeReserve& SetProfilerName(std::string name); + + void ForbidModification(); + void AllowModification(); + + operator u8*() { return m_baseptr; } + operator const u8*() const { return m_baseptr; } + +protected: + void _registerProfiler(); +}; + +// -------------------------------------------------------------------------------------- +// GSCodeReserve +// -------------------------------------------------------------------------------------- +// Stores code buffers for the GS software JIT. +class GSCodeReserve : public RecompiledCodeReserve +{ +public: + GSCodeReserve(); + ~GSCodeReserve(); + + size_t GetMemoryUsed() const { return m_memory_used; } + + void Assign(VirtualMemoryManagerPtr allocator); + void Reset(); + + u8* Reserve(size_t size); + void Commit(size_t size); + +private: + size_t m_memory_used = 0; +}; + + // -------------------------------------------------------------------------------------- // SysMainMemory // -------------------------------------------------------------------------------------- @@ -104,6 +162,8 @@ protected: iopMemoryReserve m_iop; vuMemoryReserve m_vu; + GSCodeReserve m_gs_code; + public: SysMainMemory(); ~SysMainMemory(); @@ -117,6 +177,8 @@ public: const iopMemoryReserve& IOPMemory() const { return m_iop; } const vuMemoryReserve& VUMemory() const { return m_vu; } + GSCodeReserve& GSCode() { return m_gs_code; } + bool Allocate(); void Reset(); void Release(); diff --git a/pcsx2/System/RecTypes.h b/pcsx2/System/RecTypes.h deleted file mode 100644 index 63a04a6711..0000000000 --- a/pcsx2/System/RecTypes.h +++ /dev/null @@ -1,50 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#pragma once - -#include "common/PageFaultSource.h" - -// -------------------------------------------------------------------------------------- -// RecompiledCodeReserve -// -------------------------------------------------------------------------------------- -// A recompiled code reserve is a simple sequential-growth block of memory which is auto- -// cleared to INT 3 (0xcc) as needed. -// -class RecompiledCodeReserve : public VirtualMemoryReserve -{ - typedef VirtualMemoryReserve _parent; - -protected: - std::string m_profiler_name; - -public: - RecompiledCodeReserve(std::string name); - ~RecompiledCodeReserve(); - - void Assign(VirtualMemoryManagerPtr allocator, size_t offset, size_t size); - void Reset(); - - RecompiledCodeReserve& SetProfilerName(std::string name); - - void ForbidModification(); - void AllowModification(); - - operator u8*() { return m_baseptr; } - operator const u8*() const { return m_baseptr; } - -protected: - void _registerProfiler(); -}; diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp index 3aa9d4169b..5f7e49b0a5 100644 --- a/pcsx2/VMManager.cpp +++ b/pcsx2/VMManager.cpp @@ -310,8 +310,8 @@ void VMManager::Internal::ReleaseMemory() std::vector().swap(s_no_interlacing_cheats_data); s_no_interlacing_cheats_loaded = false; - s_vm_memory.reset(); s_cpu_provider_pack.reset(); + s_vm_memory.reset(); } SysMainMemory& GetVmMemory() diff --git a/pcsx2/pcsx2core.vcxproj b/pcsx2/pcsx2core.vcxproj index 3f63f88be4..3b4d4dcdc9 100644 --- a/pcsx2/pcsx2core.vcxproj +++ b/pcsx2/pcsx2core.vcxproj @@ -280,7 +280,6 @@ - @@ -618,7 +617,6 @@ - @@ -715,7 +713,6 @@ - diff --git a/pcsx2/pcsx2core.vcxproj.filters b/pcsx2/pcsx2core.vcxproj.filters index 15686ccdee..3267264c50 100644 --- a/pcsx2/pcsx2core.vcxproj.filters +++ b/pcsx2/pcsx2core.vcxproj.filters @@ -992,9 +992,6 @@ System\Ps2\GS - - System\Ps2\GS - System\Ps2\GS @@ -1426,9 +1423,6 @@ System\Include - - System\Include - System\Ps2\EmotionEngine @@ -1903,9 +1897,6 @@ System\Ps2\GS - - System\Ps2\GS - System\Ps2\GS diff --git a/pcsx2/x86/iR3000A.cpp b/pcsx2/x86/iR3000A.cpp index 657e9d5c17..b49b27d687 100644 --- a/pcsx2/x86/iR3000A.cpp +++ b/pcsx2/x86/iR3000A.cpp @@ -23,7 +23,7 @@ #include "iR3000A.h" #include "R3000A.h" #include "BaseblockEx.h" -#include "System/RecTypes.h" +#include "System.h" #include "R5900OpcodeTables.h" #include "IopBios.h" #include "IopHw.h" diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index caba61b3dc..4a6af68d2a 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -24,7 +24,7 @@ #include "iR5900.h" #include "iR5900Analysis.h" #include "BaseblockEx.h" -#include "System/RecTypes.h" +#include "System.h" #include "vtlb.h" diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h index e2b779b795..7d3b04cf91 100644 --- a/pcsx2/x86/microVU.h +++ b/pcsx2/x86/microVU.h @@ -30,7 +30,7 @@ using namespace x86Emitter; #include "Gif_Unit.h" #include "iR5900.h" #include "R5900OpcodeTables.h" -#include "System/RecTypes.h" +#include "System.h" #include "common/emitter/x86emitter.h" #include "microVU_Misc.h" #include "microVU_IR.h" diff --git a/pcsx2/x86/newVif.h b/pcsx2/x86/newVif.h index 17157d8648..e915e5de27 100644 --- a/pcsx2/x86/newVif.h +++ b/pcsx2/x86/newVif.h @@ -19,7 +19,7 @@ #include "VU.h" #include "common/emitter/x86emitter.h" -#include "System/RecTypes.h" +#include "System.h" using namespace x86Emitter;