GS/SW: Combine IDrawScanline and GSDrawScanline

This commit is contained in:
Stenzek 2023-01-25 20:51:09 +10:00 committed by refractionpcsx2
parent c9d229e336
commit c8416b820b
5 changed files with 88 additions and 107 deletions

View File

@ -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

View File

@ -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<GSSetupPrimCodeGenerator, u64, SetupPrimPtr> m_sp_map;
GSCodeGeneratorFunctionMap<GSDrawScanlineCodeGenerator, u64, DrawScanlinePtr> 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<class T> static bool TestAlpha(T& test, T& fm, T& zm, const T& ga, const GSScanlineGlobalData& global);
template<class T> 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();

View File

@ -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<IRasterizer> GSRasterizerList::Create(int threads)
{
threads = std::max<int>(threads, 0);
if (threads == 0)
{
return std::make_unique<GSRasterizer>(new GSDrawScanline(), 0, 1);
}
std::unique_ptr<GSRasterizerList> rl(new GSRasterizerList(threads));
for (int i = 0; i < threads; i++)
{
rl->m_r.push_back(std::unique_ptr<GSRasterizer>(new GSRasterizer(new GSDrawScanline(), i, threads)));
auto& r = *rl->m_r[i];
rl->m_workers.push_back(std::unique_ptr<GSWorker>(new GSWorker([i]() { GSRasterizerList::OnWorkerStartup(i); },
[&r](GSRingHeap::SharedPtr<GSRasterizerData>& item) { r.Draw(item.get()); },
[i]() { GSRasterizerList::OnWorkerShutdown(i); })));
}
return rl;
}
void GSRasterizerList::PrintStats()
{
}

View File

@ -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<GSRasterizerData>& data);
void Sync() {}
bool IsSynced() const { return true; }
int GetPixels(bool reset);
void PrintStats() { m_ds->PrintStats(); }
void Queue(const GSRingHeap::SharedPtr<GSRasterizerData>& 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<GSRingHeap::SharedPtr<GSRasterizerData>, 65536>;
@ -203,40 +157,17 @@ protected:
static void OnWorkerShutdown(int i);
public:
virtual ~GSRasterizerList();
~GSRasterizerList() override;
template <class DS>
static std::unique_ptr<IRasterizer> Create(int threads)
{
threads = std::max<int>(threads, 0);
if (threads == 0)
{
return std::make_unique<GSRasterizer>(new DS(), 0, 1);
}
std::unique_ptr<GSRasterizerList> rl(new GSRasterizerList(threads));
for (int i = 0; i < threads; i++)
{
rl->m_r.push_back(std::unique_ptr<GSRasterizer>(new GSRasterizer(new DS(), i, threads)));
auto& r = *rl->m_r[i];
rl->m_workers.push_back(std::unique_ptr<GSWorker>(new GSWorker(
[i]() { GSRasterizerList::OnWorkerStartup(i); },
[&r](GSRingHeap::SharedPtr<GSRasterizerData>& item) { r.Draw(item.get()); },
[i]() { GSRasterizerList::OnWorkerShutdown(i); })));
}
return rl;
}
static std::unique_ptr<IRasterizer> Create(int threads);
// IRasterizer
void Queue(const GSRingHeap::SharedPtr<GSRasterizerData>& data);
void Sync();
bool IsSynced() const;
int GetPixels(bool reset);
void PrintStats() {}
void Queue(const GSRingHeap::SharedPtr<GSRasterizerData>& data) override;
void Sync() override;
bool IsSynced() const override;
int GetPixels(bool reset) override;
void PrintStats() override;
};
MULTI_ISA_UNSHARED_END

View File

@ -37,7 +37,7 @@ GSRendererSW::GSRendererSW(int threads)
m_nativeres = true; // ignore ini, sw is always native
m_tc = std::make_unique<GSTextureCacheSW>();
m_rl = GSRasterizerList::Create<GSDrawScanline>(threads);
m_rl = GSRasterizerList::Create(threads);
m_output = (u8*)_aligned_malloc(1024 * 1024 * sizeof(u32), 32);