diff --git a/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp b/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp index a34c5d25c7..981646f4b4 100644 --- a/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp +++ b/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp @@ -75,16 +75,7 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data) } else { - m_de = NULL; - } - - if (m_global.sel.IsSolidRect()) - { - m_dr = (DrawRectPtr)&GSDrawScanline::DrawRect; - } - else - { - m_dr = NULL; + m_de = nullptr; } // doesn't need all bits => less functions generated diff --git a/pcsx2/GS/Renderers/SW/GSDrawScanline.h b/pcsx2/GS/Renderers/SW/GSDrawScanline.h index 17909db0ad..6ab3417c63 100644 --- a/pcsx2/GS/Renderers/SW/GSDrawScanline.h +++ b/pcsx2/GS/Renderers/SW/GSDrawScanline.h @@ -24,7 +24,7 @@ MULTI_ISA_UNSHARED_START -class GSDrawScanline : public IDrawScanline +class GSDrawScanline : public GSAlignedClass<32> { public: class SharedData : public GSRasterizerData @@ -33,9 +33,16 @@ public: GSScanlineGlobalData global; }; + typedef void (*SetupPrimPtr)(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan); + typedef void (*DrawScanlinePtr)(int pixels, int left, int top, const GSVertexSW& scan); + protected: - GSScanlineGlobalData m_global; - GSScanlineLocalData m_local; + GSScanlineGlobalData m_global = {}; + GSScanlineLocalData m_local = {}; + + SetupPrimPtr m_sp = nullptr; + DrawScanlinePtr m_ds = nullptr; + DrawScanlinePtr m_de = nullptr; GSCodeGeneratorFunctionMap m_sp_map; GSCodeGeneratorFunctionMap m_ds_map; @@ -62,20 +69,27 @@ public: GSDrawScanline(); virtual ~GSDrawScanline() = default; + __forceinline bool HasEdge() const { return m_de != nullptr; } + __forceinline bool IsSolidRect() const { return m_global.sel.IsSolidRect(); } + // IDrawScanline void BeginDraw(const GSRasterizerData* data); void EndDraw(u64 frame, u64 ticks, int actual, int total, int prims); - void DrawRect(const GSVector4i& r, const GSVertexSW& v); - static void CSetupPrim(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, GSScanlineLocalData& local, const GSScanlineGlobalData& global); static void CDrawScanline(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local, const GSScanlineGlobalData& global); 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); -#ifndef ENABLE_JIT_RASTERIZER +#ifdef ENABLE_JIT_RASTERIZER + + __forceinline void SetupPrim(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan) { m_sp(vertex, index, dscan); } + __forceinline void DrawScanline(int pixels, int left, int top, const GSVertexSW& scan) { m_ds(pixels, left, top, scan); } + __forceinline void DrawEdge(int pixels, int left, int top, const GSVertexSW& scan) { m_de(pixels, left, top, scan); } + +#else void SetupPrim(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan); void DrawScanline(int pixels, int left, int top, const GSVertexSW& scan); @@ -83,6 +97,9 @@ public: #endif + // Not currently jitted. + void DrawRect(const GSVector4i& r, const GSVertexSW& v); + void PrintStats() { m_ds_map.PrintStats(); diff --git a/pcsx2/GS/Renderers/SW/GSRasterizer.cpp b/pcsx2/GS/Renderers/SW/GSRasterizer.cpp index 76bdc5440d..42c541745d 100644 --- a/pcsx2/GS/Renderers/SW/GSRasterizer.cpp +++ b/pcsx2/GS/Renderers/SW/GSRasterizer.cpp @@ -16,7 +16,8 @@ // TODO: JIT Draw* (flags: depth, texture, color (+iip), scissor) #include "PrecompiledHeader.h" -#include "GSRasterizer.h" +#include "GS/Renderers/SW/GSRasterizer.h" +#include "GS/Renderers/SW/GSDrawScanline.h" #include "GS/GSExtra.h" #include "PerformanceMetrics.h" #include "common/AlignedMalloc.h" @@ -43,7 +44,7 @@ static int compute_best_thread_height(int threads) return 4; } -GSRasterizer::GSRasterizer(IDrawScanline* ds, int id, int threads) +GSRasterizer::GSRasterizer(GSDrawScanline* ds, int id, int threads) : m_ds(ds) , m_id(id) , m_threads(threads) @@ -1153,6 +1154,20 @@ void GSRasterizer::DrawEdge(int pixels, int left, int top, const GSVertexSW& sca m_ds->DrawEdge(pixels, left, top, scan); } +void GSRasterizer::Sync() +{ +} + +bool GSRasterizer::IsSynced() const +{ + return true; +} + +void GSRasterizer::PrintStats() +{ + m_ds->PrintStats(); +} + // GSRasterizerList::GSRasterizerList(int threads) @@ -1254,3 +1269,30 @@ int GSRasterizerList::GetPixels(bool reset) return pixels; } + +std::unique_ptr GSRasterizerList::Create(int threads) +{ + threads = std::max(threads, 0); + + if (threads == 0) + { + return std::make_unique(new GSDrawScanline(), 0, 1); + } + + std::unique_ptr rl(new GSRasterizerList(threads)); + + for (int i = 0; i < threads; i++) + { + rl->m_r.push_back(std::unique_ptr(new GSRasterizer(new GSDrawScanline(), 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()); }, + [i]() { GSRasterizerList::OnWorkerShutdown(i); }))); + } + + return rl; +} + +void GSRasterizerList::PrintStats() +{ +} diff --git a/pcsx2/GS/Renderers/SW/GSRasterizer.h b/pcsx2/GS/Renderers/SW/GSRasterizer.h index 6074ae8c5f..f81d1b871f 100644 --- a/pcsx2/GS/Renderers/SW/GSRasterizer.h +++ b/pcsx2/GS/Renderers/SW/GSRasterizer.h @@ -26,6 +26,8 @@ MULTI_ISA_UNSHARED_START +class GSDrawScanline; + class alignas(32) GSRasterizerData : public GSAlignedClass<32> { static int s_counter; @@ -69,54 +71,6 @@ public: } }; -class IDrawScanline : public GSAlignedClass<32> -{ -public: - IDrawScanline() - : m_sp(NULL) - , m_ds(NULL) - , m_de(NULL) - , m_dr(NULL) - { - } - virtual ~IDrawScanline() {} - - typedef void (*SetupPrimPtr)(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan); - typedef void (*DrawScanlinePtr)(int pixels, int left, int top, const GSVertexSW& scan); - typedef void (IDrawScanline::*DrawRectPtr)(const GSVector4i& r, const GSVertexSW& v); // TODO: jit - -protected: - SetupPrimPtr m_sp; - DrawScanlinePtr m_ds; - DrawScanlinePtr m_de; - DrawRectPtr m_dr; - -public: - virtual void BeginDraw(const GSRasterizerData* data) = 0; - virtual void EndDraw(u64 frame, u64 ticks, int actual, int total, int prims) = 0; - -#ifdef ENABLE_JIT_RASTERIZER - - __forceinline void SetupPrim(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan) { m_sp(vertex, index, dscan); } - __forceinline void DrawScanline(int pixels, int left, int top, const GSVertexSW& scan) { m_ds(pixels, left, top, scan); } - __forceinline void DrawEdge(int pixels, int left, int top, const GSVertexSW& scan) { m_de(pixels, left, top, scan); } - __forceinline void DrawRect(const GSVector4i& r, const GSVertexSW& v) { (this->*m_dr)(r, v); } - -#else - - virtual void SetupPrim(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan) = 0; - virtual void DrawScanline(int pixels, int left, int top, const GSVertexSW& scan) = 0; - virtual void DrawEdge(int pixels, int left, int top, const GSVertexSW& scan) = 0; - virtual void DrawRect(const GSVector4i& r, const GSVertexSW& v) = 0; - -#endif - - virtual void PrintStats() = 0; - - __forceinline bool HasEdge() const { return m_de != NULL; } - __forceinline bool IsSolidRect() const { return m_dr != NULL; } -}; - class IRasterizer : public GSVirtualAlignedClass<32> { public: @@ -129,10 +83,10 @@ public: virtual void PrintStats() = 0; }; -class alignas(32) GSRasterizer : public IRasterizer +class alignas(32) GSRasterizer final : public IRasterizer { protected: - IDrawScanline* m_ds; + GSDrawScanline* m_ds; int m_id; int m_threads; int m_thread_height; @@ -168,8 +122,8 @@ protected: __forceinline void DrawEdge(int pixels, int left, int top, const GSVertexSW& scan); public: - GSRasterizer(IDrawScanline* ds, int id, int threads); - virtual ~GSRasterizer(); + GSRasterizer(GSDrawScanline* ds, int id, int threads); + ~GSRasterizer() override; __forceinline bool IsOneOfMyScanlines(int top) const; __forceinline bool IsOneOfMyScanlines(int top, int bottom) const; @@ -179,14 +133,14 @@ public: // IRasterizer - void Queue(const GSRingHeap::SharedPtr& data); - void Sync() {} - bool IsSynced() const { return true; } - int GetPixels(bool reset); - void PrintStats() { m_ds->PrintStats(); } + void Queue(const GSRingHeap::SharedPtr& data) override; + void Sync() override; + bool IsSynced() const override; + int GetPixels(bool reset) override; + void PrintStats() override; }; -class GSRasterizerList : public IRasterizer +class GSRasterizerList final : public IRasterizer { protected: using GSWorker = GSJobQueue, 65536>; @@ -203,40 +157,17 @@ protected: static void OnWorkerShutdown(int i); public: - virtual ~GSRasterizerList(); + ~GSRasterizerList() override; - template - static std::unique_ptr Create(int threads) - { - threads = std::max(threads, 0); - - if (threads == 0) - { - return std::make_unique(new DS(), 0, 1); - } - - std::unique_ptr rl(new GSRasterizerList(threads)); - - for (int i = 0; i < threads; i++) - { - rl->m_r.push_back(std::unique_ptr(new GSRasterizer(new 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()); }, - [i]() { GSRasterizerList::OnWorkerShutdown(i); }))); - } - - return rl; - } + static std::unique_ptr Create(int threads); // IRasterizer - void Queue(const GSRingHeap::SharedPtr& data); - void Sync(); - bool IsSynced() const; - int GetPixels(bool reset); - void PrintStats() {} + void Queue(const GSRingHeap::SharedPtr& data) override; + void Sync() override; + bool IsSynced() const override; + int GetPixels(bool reset) override; + void PrintStats() override; }; MULTI_ISA_UNSHARED_END diff --git a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp index 44152a3815..8c9f1edbc3 100644 --- a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp +++ b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp @@ -37,7 +37,7 @@ GSRendererSW::GSRendererSW(int threads) m_nativeres = true; // ignore ini, sw is always native m_tc = std::make_unique(); - m_rl = GSRasterizerList::Create(threads); + m_rl = GSRasterizerList::Create(threads); m_output = (u8*)_aligned_malloc(1024 * 1024 * sizeof(u32), 32);