GSdx: Renamed the sw thread setting to "extra threads".

- 0: no multi-threading
- 1: gif packet processing and texture uploads run parallel with rendering, the slowest decides the fps, dual-cores can still suffer by the spin loops, I'll check that when I compile pcsx2 on my notebook
- 2: two rendering threads, on a decent cpu packet processing is going to be slower now, this is probably going to increase fps the most on quads
- 3: small fps increase
- 4+: even smaller. 

If you have a quad cpu with HT, 6 is the max, 1 + 1 is needed for pcsx2 and gsdx's basic tasks.

Also hacked palette writes to not force a read-back in hw mode (added in previous rev), it hit render targets in a surprising large number of games.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4998 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2011-12-20 14:33:28 +00:00
parent 2f401da58c
commit 0b62c17d9c
20 changed files with 387 additions and 263 deletions

View File

@ -109,7 +109,7 @@ EXPORT_C_(int32) GPUopen(void* hWnd)
#endif
int renderer = theApp.GetConfig("Renderer", 1);
int threads = theApp.GetConfig("swthreads", 1);
int threads = theApp.GetConfig("extrathreads", 0);
switch(renderer)
{

View File

@ -49,7 +49,7 @@ class GPURendererSW : public GPURendererT<GSVertexSW>
};
protected:
GSRasterizerList* m_rl;
IRasterizer* m_rl;
GSTexture* m_texture;
uint32* m_output;

View File

@ -73,8 +73,8 @@ void GPUSettingsDlg::OnInit()
CheckDlgButton(m_hWnd, IDC_WINDOWED, theApp.GetConfig("windowed", 1));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 1));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("swthreads", 1), 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("extrathreads", 0), 0));
UpdateControls();
}
@ -124,7 +124,7 @@ bool GPUSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code)
theApp.SetConfig("scale_y", (data >> 2) & 3);
}
theApp.SetConfig("swthreads", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_GETPOS, 0, 0));
theApp.SetConfig("extrathreads", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_GETPOS, 0, 0));
theApp.SetConfig("windowed", (int)IsDlgButtonChecked(m_hWnd, IDC_WINDOWED));
}

View File

@ -190,7 +190,7 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
if(threads == -1)
{
threads = theApp.GetConfig("swthreads", 1);
threads = theApp.GetConfig("extrathreads", 0);
}
try
@ -769,6 +769,8 @@ EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
GSvsync(1);
Sleep(100);
bool exit = false;
while(!exit)

View File

@ -102,10 +102,10 @@ bool RunLinuxDialog()
gtk_container_add(GTK_CONTAINER(main_box), interlace_label);
gtk_container_add(GTK_CONTAINER(main_box), interlace_combo_box);
swthreads_label = gtk_label_new("Software renderer threads:");
swthreads_label = gtk_label_new("Extra sw renderer threads:");
swthreads_text = gtk_entry_new();
char buf[5];
sprintf(buf, "%d", theApp.GetConfig("swthreads", 1));
sprintf(buf, "%d", theApp.GetConfig("extrathreads", 0));
gtk_entry_set_text(GTK_ENTRY(swthreads_text), buf);
gtk_container_add(GTK_CONTAINER(main_box), swthreads_label);

View File

@ -547,6 +547,8 @@ GSPixelOffset4* GSLocalMemory::GetPixelOffset4(const GIFRegFRAME& FRAME, const G
return o;
}
static bool cmp_vec2x(const GSVector2i& a, const GSVector2i& b) {return a.x < b.x;}
list<GSVector2i>* GSLocalMemory::GetPage2TileMap(const GIFRegTEX0& TEX0)
{
uint32 hash = TEX0.TBP0 | (TEX0.TBW << 14) | (TEX0.PSM << 20) | (TEX0.TW << 26);
@ -613,10 +615,18 @@ list<GSVector2i>* GSLocalMemory::GetPage2TileMap(const GIFRegTEX0& TEX0)
}
}
// sort by x and flip the mask (it will be used to erase a lot of bits in a loop, [x] &= ~y)
vector<GSVector2i> tmp;
for(hash_map<uint32, uint32>::iterator j = m.begin(); j != m.end(); j++)
{
p2t[page].push_back(GSVector2i(j->first, j->second));
tmp.push_back(GSVector2i(j->first, ~j->second));
}
std::sort(tmp.begin(), tmp.end(), cmp_vec2x);
p2t[page].insert(p2t[page].end(), tmp.begin(), tmp.end());
}
m_p2tmap[hash] = p2t;

View File

@ -24,8 +24,11 @@
#include "stdafx.h"
#include "GSRasterizer.h"
#define THREAD_HEIGHT 5
//#define THREAD_HEIGHT 1
// - for more threads screen segments should be smaller to better distribute the pixels
// - but not too small to keep the threading overhead low
// - ideal value between 3 and 5, or log2(64 / number of threads)
#define THREAD_HEIGHT 4
GSRasterizer::GSRasterizer(IDrawScanline* ds, int id, int threads)
: m_ds(ds)
@ -764,7 +767,6 @@ GSRasterizerMT::GSRasterizerMT(IDrawScanline* ds, int id, int threads)
: GSRasterizer(ds, id, threads)
, m_exit(false)
, m_break(true)
, m_ready(true)
{
CreateThread();
}
@ -790,8 +792,6 @@ void GSRasterizerMT::Queue(shared_ptr<GSRasterizerData> data)
{
m_break = false;
m_ready = false;
m_draw.Set();
}
}
@ -801,8 +801,6 @@ void GSRasterizerMT::Sync()
while(!m_queue.empty()) _mm_pause();
m_break = true;
while(!m_ready) _mm_pause();
}
void GSRasterizerMT::ThreadProc()
@ -815,35 +813,30 @@ void GSRasterizerMT::ThreadProc()
{
if(!m_queue.empty())
{
queue<shared_ptr<GSRasterizerData> > queue;
while(!m_queue.empty())
{
shared_ptr<GSRasterizerData> data;
{
GSAutoLock l(&m_lock);
// TODO: queue.swap(m_queue); // GCC
data = m_queue.front();
}
Draw(data);
while(!m_queue.empty())
{
queue.push(m_queue.front());
GSAutoLock l(&m_lock);
m_queue.pop();
}
}
while(!queue.empty())
{
Draw(queue.front());
queue.pop();
}
}
else
{
_mm_pause();
}
}
m_ready = true;
}
}
@ -864,20 +857,15 @@ GSRasterizerList::~GSRasterizerList()
}
}
void GSRasterizerList::Draw(shared_ptr<GSRasterizerData> data)
{
Sync();
front()->Draw(data);
}
void GSRasterizerList::Queue(shared_ptr<GSRasterizerData> data)
{
if(size() > 1)
if(size() > 1 && data->solidrect) // TODO: clip to thread area and dispatch?
{
ASSERT(!data->solidrect); // should call Draw instead, but it will work anyway
Sync(); // complete previous drawings
data->solidrect = false;
front()->Draw(data);
return;
}
GSVector4i bbox = data->bbox.rintersect(data->scissor);

View File

@ -142,6 +142,7 @@ public:
// IRasterizer
void Queue(shared_ptr<GSRasterizerData> data);
void Sync() {}
};
class GSRasterizerMT : public GSRasterizer, private GSThread
@ -149,8 +150,7 @@ class GSRasterizerMT : public GSRasterizer, private GSThread
protected:
volatile bool m_exit;
volatile bool m_break;
volatile bool m_ready;
GSAutoResetEvent m_draw;
GSEvent m_draw;
queue<shared_ptr<GSRasterizerData> > m_queue;
GSCritSec m_lock;
@ -177,12 +177,18 @@ protected:
public:
virtual ~GSRasterizerList();
template<class DS> static GSRasterizerList* Create(int threads)
template<class DS> static IRasterizer* Create(int threads)
{
threads = std::max<int>(threads, 0);
if(threads == 0)
{
return new GSRasterizer(new DS(), 0, 1);
}
else
{
GSRasterizerList* rl = new GSRasterizerList();
threads = std::max<int>(threads, 1); // TODO: min(threads, number of cpu cores)
for(int i = 0; i < threads; i++)
{
rl->push_back(new GSRasterizerMT(new DS(), i, threads));
@ -190,10 +196,7 @@ public:
return rl;
}
bool IsMultiThreaded() const {return size() > 1;}
void Draw(shared_ptr<GSRasterizerData> data);
}
// IRasterizer

View File

@ -747,10 +747,12 @@ protected:
m_tc->InvalidateVideoMem(m_mem.GetOffset(BITBLTBUF.DBP, BITBLTBUF.DBW, BITBLTBUF.DPSM), r);
}
void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r)
void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false)
{
// printf("[%d] InvalidateLocalMem %d,%d - %d,%d %05x (%d)\n", (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.SBP, (int)BITBLTBUF.SPSM);
if(clut) return; // FIXME
m_tc->InvalidateLocalMem(m_mem.GetOffset(BITBLTBUF.SBP, BITBLTBUF.SBW, BITBLTBUF.SPSM), r);
}

View File

@ -71,7 +71,7 @@ void GSRendererSW::VSync(int field)
Sync(); // IncAge might delete a cached texture in use
//printf("m_sync_count = %d\n", m_rl->m_sync_count); m_rl->m_sync_count = 0;
//printf("m_sync_count = %d\n", ((GSRasterizerList*)m_rl)->m_sync_count); ((GSRasterizerList*)m_rl)->m_sync_count = 0;
m_tc->IncAge();
@ -178,10 +178,10 @@ void GSRendererSW::Draw()
m_tc->InvalidateVideoMem(m_context->offset.zb, r);
}
if(!m_rl->IsMultiThreaded() || data->solidrect || s_dump)
{
if(s_dump)
{
Sync();
uint64 frame = m_perfmon.GetFrame();
string s;
@ -210,18 +210,11 @@ void GSRendererSW::Draw()
}
s_n++;
}
m_rl->Draw(data);
m_rl->Queue(data);
Sync();
if(s_dump)
{
uint64 frame = m_perfmon.GetFrame();
string s;
if(s_save && s_n >= s_saven)
{
s = format("c:\\temp1\\_%05d_f%lld_rt1_%05x_%d.bmp", s_n, frame, m_context->FRAME.Block(), m_context->FRAME.PSM);
@ -238,7 +231,6 @@ void GSRendererSW::Draw()
s_n++;
}
}
else
{
m_rl->Queue(data);
@ -252,8 +244,6 @@ void GSRendererSW::Draw()
{
InvalidatePages(m_context->offset.zb, r);
}
// Sync();
}
// TODO: m_perfmon.Put(GSPerfMon::Prim, stats.prims);
@ -295,7 +285,7 @@ void GSRendererSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS
}
}
void GSRendererSW::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r)
void GSRendererSW::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut)
{
//printf("ilm %05x %d %d\n", BITBLTBUF.DBP, BITBLTBUF.DBW, BITBLTBUF.DPSM);

View File

@ -52,7 +52,7 @@ class GSRendererSW : public GSRendererT<GSVertexSW>
};
protected:
GSRasterizerList* m_rl;
IRasterizer* m_rl;
GSTextureCacheSW* m_tc;
GSTexture* m_texture[2];
uint8* m_output;
@ -69,7 +69,7 @@ protected:
void Draw();
void Sync();
void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r);
void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r);
void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false);
void InvalidatePages(const GSOffset* o, const GSVector4i& rect);
void InvalidatePages(const GSTextureCacheSW::Texture* t);

View File

@ -130,8 +130,8 @@ void GSSettingsDlg::OnInit()
SendMessage(GetDlgItem(m_hWnd, IDC_MSAA), UDM_SETRANGE, 0, MAKELPARAM(16, 0));
SendMessage(GetDlgItem(m_hWnd, IDC_MSAA), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("msaa", 0), 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 1));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("swthreads", 1), 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("extrathreads", 0), 0));
UpdateControls();
}
@ -270,7 +270,7 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code)
theApp.SetConfig("nativeres", (int)IsDlgButtonChecked(m_hWnd, IDC_NATIVERES));
theApp.SetConfig("resx", (int)SendMessage(GetDlgItem(m_hWnd, IDC_RESX), UDM_GETPOS, 0, 0));
theApp.SetConfig("resy", (int)SendMessage(GetDlgItem(m_hWnd, IDC_RESY), UDM_GETPOS, 0, 0));
theApp.SetConfig("swthreads", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_GETPOS, 0, 0));
theApp.SetConfig("extrathreads", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_GETPOS, 0, 0));
theApp.SetConfig("msaa", (int)SendMessage(GetDlgItem(m_hWnd, IDC_MSAA), UDM_GETPOS, 0, 0));
// Hacks
theApp.SetConfig("UserHacks_AlphaHack", (int)IsDlgButtonChecked(m_hWnd, IDC_ALPHAHACK));

View File

@ -386,12 +386,12 @@ float GSState::GetFPS()
// GIFPackedRegHandler*
__forceinline void GSState::GIFPackedRegHandlerNull(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerNull(const GIFPackedReg* RESTRICT r)
{
// ASSERT(0);
}
__forceinline void GSState::GIFPackedRegHandlerRGBA(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerRGBA(const GIFPackedReg* RESTRICT r)
{
#if _M_SSE >= 0x301
@ -418,7 +418,7 @@ __forceinline void GSState::GIFPackedRegHandlerRGBA(const GIFPackedReg* r)
m_v.RGBAQ.Q = m_q;
}
__forceinline void GSState::GIFPackedRegHandlerSTQ(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerSTQ(const GIFPackedReg* RESTRICT r)
{
#if defined(_M_AMD64)
@ -445,7 +445,7 @@ __forceinline void GSState::GIFPackedRegHandlerSTQ(const GIFPackedReg* r)
#endif
}
__forceinline void GSState::GIFPackedRegHandlerUV(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerUV(const GIFPackedReg* RESTRICT r)
{
#if _M_SSE >= 0x200
@ -465,7 +465,7 @@ __forceinline void GSState::GIFPackedRegHandlerUV(const GIFPackedReg* r)
#endif
}
__forceinline void GSState::GIFPackedRegHandlerXYZF2(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r)
{
m_v.XYZ.X = r->XYZF2.X;
m_v.XYZ.Y = r->XYZF2.Y;
@ -475,7 +475,7 @@ __forceinline void GSState::GIFPackedRegHandlerXYZF2(const GIFPackedReg* r)
VertexKick(r->XYZF2.ADC);
}
__forceinline void GSState::GIFPackedRegHandlerXYZ2(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r)
{
m_v.XYZ.X = r->XYZ2.X;
m_v.XYZ.Y = r->XYZ2.Y;
@ -484,23 +484,23 @@ __forceinline void GSState::GIFPackedRegHandlerXYZ2(const GIFPackedReg* r)
VertexKick(r->XYZ2.ADC);
}
__forceinline void GSState::GIFPackedRegHandlerFOG(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r)
{
m_v.FOG.F = r->FOG.F;
}
__forceinline void GSState::GIFPackedRegHandlerA_D(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerA_D(const GIFPackedReg* RESTRICT r)
{
(this->*m_fpGIFRegHandlers[r->A_D.ADDR])(&r->r);
}
__forceinline void GSState::GIFPackedRegHandlerNOP(const GIFPackedReg* r)
__forceinline void GSState::GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r)
{
}
// GIFRegHandler*
void GSState::GIFRegHandlerNull(const GIFReg* r)
void GSState::GIFRegHandlerNull(const GIFReg* RESTRICT r)
{
// ASSERT(0);
}
@ -531,19 +531,19 @@ __forceinline void GSState::ApplyPRIM(const GIFRegPRIM& prim)
ResetPrim();
}
void GSState::GIFRegHandlerPRIM(const GIFReg* r)
void GSState::GIFRegHandlerPRIM(const GIFReg* RESTRICT r)
{
ALIGN_STACK(32);
ApplyPRIM(r->PRIM);
}
__forceinline void GSState::GIFRegHandlerRGBAQ(const GIFReg* r)
__forceinline void GSState::GIFRegHandlerRGBAQ(const GIFReg* RESTRICT r)
{
m_v.RGBAQ = (GSVector4i)r->RGBAQ;
}
__forceinline void GSState::GIFRegHandlerST(const GIFReg* r)
__forceinline void GSState::GIFRegHandlerST(const GIFReg* RESTRICT r)
{
m_v.ST = (GSVector4i)r->ST;
@ -554,7 +554,7 @@ __forceinline void GSState::GIFRegHandlerST(const GIFReg* r)
#endif
}
__forceinline void GSState::GIFRegHandlerUV(const GIFReg* r)
__forceinline void GSState::GIFRegHandlerUV(const GIFReg* RESTRICT r)
{
m_v.UV.u32[0] = r->UV.u32[0] & 0x3fff3fff;
@ -564,7 +564,7 @@ __forceinline void GSState::GIFRegHandlerUV(const GIFReg* r)
#endif
}
void GSState::GIFRegHandlerXYZF2(const GIFReg* r)
void GSState::GIFRegHandlerXYZF2(const GIFReg* RESTRICT r)
{
/*
m_v.XYZ.X = r->XYZF.X;
@ -579,7 +579,7 @@ void GSState::GIFRegHandlerXYZF2(const GIFReg* r)
VertexKick(false);
}
void GSState::GIFRegHandlerXYZ2(const GIFReg* r)
void GSState::GIFRegHandlerXYZ2(const GIFReg* RESTRICT r)
{
m_v.XYZ = (GSVector4i)r->XYZ;
@ -624,13 +624,13 @@ void GSState::ApplyTEX0(int i, GIFRegTEX0& TEX0)
r.right = GSLocalMemory::m_psm[TEX0.CPSM].pgs.x;
r.bottom = GSLocalMemory::m_psm[TEX0.CPSM].pgs.y;
InvalidateLocalMem(BITBLTBUF, r);
InvalidateLocalMem(BITBLTBUF, r, true);
m_mem.m_clut.Write(m_env.CTXT[i].TEX0, m_env.TEXCLUT);
}
}
template<int i> void GSState::GIFRegHandlerTEX0(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
{
GIFRegTEX0 TEX0 = r->TEX0;
@ -681,7 +681,7 @@ template<int i> void GSState::GIFRegHandlerTEX0(const GIFReg* r)
}
}
template<int i> void GSState::GIFRegHandlerCLAMP(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerCLAMP(const GIFReg* RESTRICT r)
{
if(PRIM->CTXT == i && r->CLAMP != m_env.CTXT[i].CLAMP)
{
@ -691,12 +691,12 @@ template<int i> void GSState::GIFRegHandlerCLAMP(const GIFReg* r)
m_env.CTXT[i].CLAMP = (GSVector4i)r->CLAMP;
}
void GSState::GIFRegHandlerFOG(const GIFReg* r)
void GSState::GIFRegHandlerFOG(const GIFReg* RESTRICT r)
{
m_v.FOG = (GSVector4i)r->FOG;
}
void GSState::GIFRegHandlerXYZF3(const GIFReg* r)
void GSState::GIFRegHandlerXYZF3(const GIFReg* RESTRICT r)
{
/*
m_v.XYZ.X = r->XYZF.X;
@ -711,18 +711,18 @@ void GSState::GIFRegHandlerXYZF3(const GIFReg* r)
VertexKick(true);
}
void GSState::GIFRegHandlerXYZ3(const GIFReg* r)
void GSState::GIFRegHandlerXYZ3(const GIFReg* RESTRICT r)
{
m_v.XYZ = (GSVector4i)r->XYZ;
VertexKick(true);
}
void GSState::GIFRegHandlerNOP(const GIFReg* r)
void GSState::GIFRegHandlerNOP(const GIFReg* RESTRICT r)
{
}
template<int i> void GSState::GIFRegHandlerTEX1(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerTEX1(const GIFReg* RESTRICT r)
{
if(PRIM->CTXT == i && r->TEX1 != m_env.CTXT[i].TEX1)
{
@ -732,7 +732,7 @@ template<int i> void GSState::GIFRegHandlerTEX1(const GIFReg* r)
m_env.CTXT[i].TEX1 = (GSVector4i)r->TEX1;
}
template<int i> void GSState::GIFRegHandlerTEX2(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerTEX2(const GIFReg* RESTRICT r)
{
// m_env.CTXT[i].TEX2 = r->TEX2; // not used
@ -749,7 +749,7 @@ template<int i> void GSState::GIFRegHandlerTEX2(const GIFReg* r)
ApplyTEX0(i, TEX0);
}
template<int i> void GSState::GIFRegHandlerXYOFFSET(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerXYOFFSET(const GIFReg* RESTRICT r)
{
GSVector4i o = (GSVector4i)r->XYOFFSET & GSVector4i::x0000ffff();
@ -763,7 +763,7 @@ template<int i> void GSState::GIFRegHandlerXYOFFSET(const GIFReg* r)
m_env.CTXT[i].UpdateScissor();
}
void GSState::GIFRegHandlerPRMODECONT(const GIFReg* r)
void GSState::GIFRegHandlerPRMODECONT(const GIFReg* RESTRICT r)
{
if(r->PRMODECONT != m_env.PRMODECONT)
{
@ -781,7 +781,7 @@ void GSState::GIFRegHandlerPRMODECONT(const GIFReg* r)
UpdateVertexKick();
}
void GSState::GIFRegHandlerPRMODE(const GIFReg* r)
void GSState::GIFRegHandlerPRMODE(const GIFReg* RESTRICT r)
{
if(!m_env.PRMODECONT.AC)
{
@ -797,7 +797,7 @@ void GSState::GIFRegHandlerPRMODE(const GIFReg* r)
UpdateVertexKick();
}
void GSState::GIFRegHandlerTEXCLUT(const GIFReg* r)
void GSState::GIFRegHandlerTEXCLUT(const GIFReg* RESTRICT r)
{
if(r->TEXCLUT != m_env.TEXCLUT)
{
@ -807,7 +807,7 @@ void GSState::GIFRegHandlerTEXCLUT(const GIFReg* r)
m_env.TEXCLUT = (GSVector4i)r->TEXCLUT;
}
void GSState::GIFRegHandlerSCANMSK(const GIFReg* r)
void GSState::GIFRegHandlerSCANMSK(const GIFReg* RESTRICT r)
{
if(r->SCANMSK != m_env.SCANMSK)
{
@ -817,7 +817,7 @@ void GSState::GIFRegHandlerSCANMSK(const GIFReg* r)
m_env.SCANMSK = (GSVector4i)r->SCANMSK;
}
template<int i> void GSState::GIFRegHandlerMIPTBP1(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerMIPTBP1(const GIFReg* RESTRICT r)
{
if(PRIM->CTXT == i && r->MIPTBP1 != m_env.CTXT[i].MIPTBP1)
{
@ -827,7 +827,7 @@ template<int i> void GSState::GIFRegHandlerMIPTBP1(const GIFReg* r)
m_env.CTXT[i].MIPTBP1 = (GSVector4i)r->MIPTBP1;
}
template<int i> void GSState::GIFRegHandlerMIPTBP2(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerMIPTBP2(const GIFReg* RESTRICT r)
{
if(PRIM->CTXT == i && r->MIPTBP2 != m_env.CTXT[i].MIPTBP2)
{
@ -837,7 +837,7 @@ template<int i> void GSState::GIFRegHandlerMIPTBP2(const GIFReg* r)
m_env.CTXT[i].MIPTBP2 = (GSVector4i)r->MIPTBP2;
}
void GSState::GIFRegHandlerTEXA(const GIFReg* r)
void GSState::GIFRegHandlerTEXA(const GIFReg* RESTRICT r)
{
if(r->TEXA != m_env.TEXA)
{
@ -847,7 +847,7 @@ void GSState::GIFRegHandlerTEXA(const GIFReg* r)
m_env.TEXA = (GSVector4i)r->TEXA;
}
void GSState::GIFRegHandlerFOGCOL(const GIFReg* r)
void GSState::GIFRegHandlerFOGCOL(const GIFReg* RESTRICT r)
{
if(r->FOGCOL != m_env.FOGCOL)
{
@ -857,12 +857,12 @@ void GSState::GIFRegHandlerFOGCOL(const GIFReg* r)
m_env.FOGCOL = (GSVector4i)r->FOGCOL;
}
void GSState::GIFRegHandlerTEXFLUSH(const GIFReg* r)
void GSState::GIFRegHandlerTEXFLUSH(const GIFReg* RESTRICT r)
{
// TRACE(_T("TEXFLUSH\n"));
}
template<int i> void GSState::GIFRegHandlerSCISSOR(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerSCISSOR(const GIFReg* RESTRICT r)
{
if(PRIM->CTXT == i && r->SCISSOR != m_env.CTXT[i].SCISSOR)
{
@ -874,7 +874,7 @@ template<int i> void GSState::GIFRegHandlerSCISSOR(const GIFReg* r)
m_env.CTXT[i].UpdateScissor();
}
template<int i> void GSState::GIFRegHandlerALPHA(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerALPHA(const GIFReg* RESTRICT r)
{
ASSERT(r->ALPHA.A != 3);
ASSERT(r->ALPHA.B != 3);
@ -893,7 +893,7 @@ template<int i> void GSState::GIFRegHandlerALPHA(const GIFReg* r)
m_env.CTXT[i].ALPHA.u32[0] = ((~m_env.CTXT[i].ALPHA.u32[0] >> 1) | 0xAA) & m_env.CTXT[i].ALPHA.u32[0];
}
void GSState::GIFRegHandlerDIMX(const GIFReg* r)
void GSState::GIFRegHandlerDIMX(const GIFReg* RESTRICT r)
{
bool update = false;
@ -912,7 +912,7 @@ void GSState::GIFRegHandlerDIMX(const GIFReg* r)
}
}
void GSState::GIFRegHandlerDTHE(const GIFReg* r)
void GSState::GIFRegHandlerDTHE(const GIFReg* RESTRICT r)
{
if(r->DTHE != m_env.DTHE)
{
@ -922,7 +922,7 @@ void GSState::GIFRegHandlerDTHE(const GIFReg* r)
m_env.DTHE = (GSVector4i)r->DTHE;
}
void GSState::GIFRegHandlerCOLCLAMP(const GIFReg* r)
void GSState::GIFRegHandlerCOLCLAMP(const GIFReg* RESTRICT r)
{
if(r->COLCLAMP != m_env.COLCLAMP)
{
@ -935,7 +935,7 @@ void GSState::GIFRegHandlerCOLCLAMP(const GIFReg* r)
#endif
}
template<int i> void GSState::GIFRegHandlerTEST(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerTEST(const GIFReg* RESTRICT r)
{
if(PRIM->CTXT == i && r->TEST != m_env.CTXT[i].TEST)
{
@ -948,7 +948,7 @@ template<int i> void GSState::GIFRegHandlerTEST(const GIFReg* r)
#endif
}
void GSState::GIFRegHandlerPABE(const GIFReg* r)
void GSState::GIFRegHandlerPABE(const GIFReg* RESTRICT r)
{
if(r->PABE != m_env.PABE)
{
@ -958,7 +958,7 @@ void GSState::GIFRegHandlerPABE(const GIFReg* r)
m_env.PABE = (GSVector4i)r->PABE;
}
template<int i> void GSState::GIFRegHandlerFBA(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerFBA(const GIFReg* RESTRICT r)
{
if(PRIM->CTXT == i && r->FBA != m_env.CTXT[i].FBA)
{
@ -968,7 +968,7 @@ template<int i> void GSState::GIFRegHandlerFBA(const GIFReg* r)
m_env.CTXT[i].FBA = (GSVector4i)r->FBA;
}
template<int i> void GSState::GIFRegHandlerFRAME(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerFRAME(const GIFReg* RESTRICT r)
{
if(PRIM->CTXT == i && r->FRAME != m_env.CTXT[i].FRAME)
{
@ -988,7 +988,7 @@ template<int i> void GSState::GIFRegHandlerFRAME(const GIFReg* r)
#endif
}
template<int i> void GSState::GIFRegHandlerZBUF(const GIFReg* r)
template<int i> void GSState::GIFRegHandlerZBUF(const GIFReg* RESTRICT r)
{
GIFRegZBUF ZBUF = r->ZBUF;
@ -1023,7 +1023,7 @@ template<int i> void GSState::GIFRegHandlerZBUF(const GIFReg* r)
m_env.CTXT[i].ZBUF = (GSVector4i)ZBUF;
}
void GSState::GIFRegHandlerBITBLTBUF(const GIFReg* r)
void GSState::GIFRegHandlerBITBLTBUF(const GIFReg* RESTRICT r)
{
if(r->BITBLTBUF != m_env.BITBLTBUF)
{
@ -1043,7 +1043,7 @@ void GSState::GIFRegHandlerBITBLTBUF(const GIFReg* r)
}
}
void GSState::GIFRegHandlerTRXPOS(const GIFReg* r)
void GSState::GIFRegHandlerTRXPOS(const GIFReg* RESTRICT r)
{
if(r->TRXPOS != m_env.TRXPOS)
{
@ -1053,7 +1053,7 @@ void GSState::GIFRegHandlerTRXPOS(const GIFReg* r)
m_env.TRXPOS = (GSVector4i)r->TRXPOS;
}
void GSState::GIFRegHandlerTRXREG(const GIFReg* r)
void GSState::GIFRegHandlerTRXREG(const GIFReg* RESTRICT r)
{
if(r->TRXREG != m_env.TRXREG)
{
@ -1063,7 +1063,7 @@ void GSState::GIFRegHandlerTRXREG(const GIFReg* r)
m_env.TRXREG = (GSVector4i)r->TRXREG;
}
void GSState::GIFRegHandlerTRXDIR(const GIFReg* r)
void GSState::GIFRegHandlerTRXDIR(const GIFReg* RESTRICT r)
{
Flush();
@ -1083,17 +1083,19 @@ void GSState::GIFRegHandlerTRXDIR(const GIFReg* r)
case 3:
ASSERT(0);
break;
default:
__assume(0);
}
}
void GSState::GIFRegHandlerHWREG(const GIFReg* r)
void GSState::GIFRegHandlerHWREG(const GIFReg* RESTRICT r)
{
ASSERT(m_env.TRXDIR.XDIR == 0); // host => local
Write((uint8*)r, 8); // haunting ground
}
void GSState::GIFRegHandlerSIGNAL(const GIFReg* r)
void GSState::GIFRegHandlerSIGNAL(const GIFReg* RESTRICT r)
{
m_regs->SIGLBLID.SIGID = (m_regs->SIGLBLID.SIGID & ~r->SIGNAL.IDMSK) | (r->SIGNAL.ID & r->SIGNAL.IDMSK);
@ -1101,13 +1103,13 @@ void GSState::GIFRegHandlerSIGNAL(const GIFReg* r)
if(!m_regs->IMR.SIGMSK && m_irq) m_irq();
}
void GSState::GIFRegHandlerFINISH(const GIFReg* r)
void GSState::GIFRegHandlerFINISH(const GIFReg* RESTRICT r)
{
if(m_regs->CSR.wFINISH) m_regs->CSR.rFINISH = 1;
if(!m_regs->IMR.FINISHMSK && m_irq) m_irq();
}
void GSState::GIFRegHandlerLABEL(const GIFReg* r)
void GSState::GIFRegHandlerLABEL(const GIFReg* RESTRICT r)
{
m_regs->SIGLBLID.LBLID = (m_regs->SIGLBLID.LBLID & ~r->LABEL.IDMSK) | (r->LABEL.ID & r->LABEL.IDMSK);
}

View File

@ -37,70 +37,72 @@
class GSState : public GSAlignedClass<32>
{
typedef void (GSState::*GIFPackedRegHandler)(const GIFPackedReg* r);
// RESTRICT prevents multiple loads of the same part of the register when accessing its bitfields (the compiler is happy to know that memory writes in-between will not go there)
typedef void (GSState::*GIFPackedRegHandler)(const GIFPackedReg* RESTRICT r);
GIFPackedRegHandler m_fpGIFPackedRegHandlers[16];
void GIFPackedRegHandlerNull(const GIFPackedReg* r);
void GIFPackedRegHandlerRGBA(const GIFPackedReg* r);
void GIFPackedRegHandlerSTQ(const GIFPackedReg* r);
void GIFPackedRegHandlerUV(const GIFPackedReg* r);
void GIFPackedRegHandlerXYZF2(const GIFPackedReg* r);
void GIFPackedRegHandlerXYZ2(const GIFPackedReg* r);
void GIFPackedRegHandlerFOG(const GIFPackedReg* r);
void GIFPackedRegHandlerA_D(const GIFPackedReg* r);
void GIFPackedRegHandlerNOP(const GIFPackedReg* r);
void GIFPackedRegHandlerNull(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerRGBA(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerSTQ(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerUV(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerA_D(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r);
typedef void (GSState::*GIFRegHandler)(const GIFReg* r);
typedef void (GSState::*GIFRegHandler)(const GIFReg* RESTRICT r);
GIFRegHandler m_fpGIFRegHandlers[256];
void ApplyTEX0(int i, GIFRegTEX0& TEX0);
void ApplyPRIM(const GIFRegPRIM& PRIM);
void GIFRegHandlerNull(const GIFReg* r);
void GIFRegHandlerPRIM(const GIFReg* r);
void GIFRegHandlerRGBAQ(const GIFReg* r);
void GIFRegHandlerST(const GIFReg* r);
void GIFRegHandlerUV(const GIFReg* r);
void GIFRegHandlerXYZF2(const GIFReg* r);
void GIFRegHandlerXYZ2(const GIFReg* r);
template<int i> void GIFRegHandlerTEX0(const GIFReg* r);
template<int i> void GIFRegHandlerCLAMP(const GIFReg* r);
void GIFRegHandlerFOG(const GIFReg* r);
void GIFRegHandlerXYZF3(const GIFReg* r);
void GIFRegHandlerXYZ3(const GIFReg* r);
void GIFRegHandlerNOP(const GIFReg* r);
template<int i> void GIFRegHandlerTEX1(const GIFReg* r);
template<int i> void GIFRegHandlerTEX2(const GIFReg* r);
template<int i> void GIFRegHandlerXYOFFSET(const GIFReg* r);
void GIFRegHandlerPRMODECONT(const GIFReg* r);
void GIFRegHandlerPRMODE(const GIFReg* r);
void GIFRegHandlerTEXCLUT(const GIFReg* r);
void GIFRegHandlerSCANMSK(const GIFReg* r);
template<int i> void GIFRegHandlerMIPTBP1(const GIFReg* r);
template<int i> void GIFRegHandlerMIPTBP2(const GIFReg* r);
void GIFRegHandlerTEXA(const GIFReg* r);
void GIFRegHandlerFOGCOL(const GIFReg* r);
void GIFRegHandlerTEXFLUSH(const GIFReg* r);
template<int i> void GIFRegHandlerSCISSOR(const GIFReg* r);
template<int i> void GIFRegHandlerALPHA(const GIFReg* r);
void GIFRegHandlerDIMX(const GIFReg* r);
void GIFRegHandlerDTHE(const GIFReg* r);
void GIFRegHandlerCOLCLAMP(const GIFReg* r);
template<int i> void GIFRegHandlerTEST(const GIFReg* r);
void GIFRegHandlerPABE(const GIFReg* r);
template<int i> void GIFRegHandlerFBA(const GIFReg* r);
template<int i> void GIFRegHandlerFRAME(const GIFReg* r);
template<int i> void GIFRegHandlerZBUF(const GIFReg* r);
void GIFRegHandlerBITBLTBUF(const GIFReg* r);
void GIFRegHandlerTRXPOS(const GIFReg* r);
void GIFRegHandlerTRXREG(const GIFReg* r);
void GIFRegHandlerTRXDIR(const GIFReg* r);
void GIFRegHandlerHWREG(const GIFReg* r);
void GIFRegHandlerSIGNAL(const GIFReg* r);
void GIFRegHandlerFINISH(const GIFReg* r);
void GIFRegHandlerLABEL(const GIFReg* r);
void GIFRegHandlerNull(const GIFReg* RESTRICT r);
void GIFRegHandlerPRIM(const GIFReg* RESTRICT r);
void GIFRegHandlerRGBAQ(const GIFReg* RESTRICT r);
void GIFRegHandlerST(const GIFReg* RESTRICT r);
void GIFRegHandlerUV(const GIFReg* RESTRICT r);
void GIFRegHandlerXYZF2(const GIFReg* RESTRICT r);
void GIFRegHandlerXYZ2(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerTEX0(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerCLAMP(const GIFReg* RESTRICT r);
void GIFRegHandlerFOG(const GIFReg* RESTRICT r);
void GIFRegHandlerXYZF3(const GIFReg* RESTRICT r);
void GIFRegHandlerXYZ3(const GIFReg* RESTRICT r);
void GIFRegHandlerNOP(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerTEX1(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerTEX2(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerXYOFFSET(const GIFReg* RESTRICT r);
void GIFRegHandlerPRMODECONT(const GIFReg* RESTRICT r);
void GIFRegHandlerPRMODE(const GIFReg* RESTRICT r);
void GIFRegHandlerTEXCLUT(const GIFReg* RESTRICT r);
void GIFRegHandlerSCANMSK(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerMIPTBP1(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerMIPTBP2(const GIFReg* RESTRICT r);
void GIFRegHandlerTEXA(const GIFReg* RESTRICT r);
void GIFRegHandlerFOGCOL(const GIFReg* RESTRICT r);
void GIFRegHandlerTEXFLUSH(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerSCISSOR(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerALPHA(const GIFReg* RESTRICT r);
void GIFRegHandlerDIMX(const GIFReg* RESTRICT r);
void GIFRegHandlerDTHE(const GIFReg* RESTRICT r);
void GIFRegHandlerCOLCLAMP(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerTEST(const GIFReg* RESTRICT r);
void GIFRegHandlerPABE(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerFBA(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerFRAME(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerZBUF(const GIFReg* RESTRICT r);
void GIFRegHandlerBITBLTBUF(const GIFReg* RESTRICT r);
void GIFRegHandlerTRXPOS(const GIFReg* RESTRICT r);
void GIFRegHandlerTRXREG(const GIFReg* RESTRICT r);
void GIFRegHandlerTRXDIR(const GIFReg* RESTRICT r);
void GIFRegHandlerHWREG(const GIFReg* RESTRICT r);
void GIFRegHandlerSIGNAL(const GIFReg* RESTRICT r);
void GIFRegHandlerFINISH(const GIFReg* RESTRICT r);
void GIFRegHandlerLABEL(const GIFReg* RESTRICT r);
int m_version;
int m_sssize;
@ -206,7 +208,7 @@ public:
virtual void FlushPrim() = 0;
virtual void ResetPrim() = 0;
virtual void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {}
virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {}
virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false) {}
void Move();
void Write(const uint8* mem, int len);

View File

@ -351,7 +351,7 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset* o, const GSVector4i& rec
for(list<GSVector2i>::iterator k = l.begin(); k != l.end(); k++)
{
s->m_valid[k->x] &= ~k->y;
s->m_valid[k->x] &= k->y;
}
}
else

View File

@ -131,7 +131,7 @@ void GSTextureCacheSW::InvalidateVideoMem(const GSOffset* o, const GSVector4i& r
for(list<GSVector2i>::iterator j = l.begin(); j != l.end(); j++)
{
t->m_valid[j->x] &= ~j->y;
t->m_valid[j->x] &= j->y;
}
}
else

View File

@ -54,32 +54,123 @@ public:
void Unlock() {LeaveCriticalSection(&m_cs);}
};
class GSAutoResetEvent
class GSEvent
{
protected:
HANDLE m_hEvent;
public:
GSAutoResetEvent() {m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);}
~GSAutoResetEvent() {CloseHandle(m_hEvent);}
GSEvent(bool manual = false, bool initial = false) {m_hEvent = CreateEvent(NULL, manual, initial, NULL);}
~GSEvent() {CloseHandle(m_hEvent);}
void Set() {SetEvent(m_hEvent);}
void Reset() {ResetEvent(m_hEvent);}
bool Wait() {return WaitForSingleObject(m_hEvent, INFINITE) == WAIT_OBJECT_0;}
};
/*
class GSAutoResetEvent
// TODO: pthreads version (needs manual-reset event)
template<
class T,
class ENQUEUE_EVENT = GSEvent,
class DEQUEUE_EVENT = GSEvent>
class GSQueue : public GSCritSec
{
protected:
long m_sync;
std::list<T> m_queue;
HANDLE m_put;
HANDLE m_get;
ENQUEUE_EVENT m_enqueue;
DEQUEUE_EVENT m_dequeue;
long m_count;
public:
GSAutoResetEvent() {m_sync = 0;}
~GSAutoResetEvent() {}
GSQueue(long count)
: m_enqueue(true)
, m_dequeue(true)
, m_count(count)
{
m_put = CreateSemaphore(NULL, count, count, NULL);
m_get = CreateSemaphore(NULL, 0, count, NULL);
void Set() {_interlockedbittestandset(&m_sync, 0);}
bool Wait() {while(!_interlockedbittestandreset(&m_sync, 0)) _mm_pause(); return true;}
m_dequeue.Set();
}
virtual ~GSQueue()
{
CloseHandle(m_put);
CloseHandle(m_get);
}
size_t GetCount() const
{
// GSAutoLock cAutoLock(this);
return m_queue.size();
}
size_t GetMaxCount() const
{
// GSAutoLock cAutoLock(this);
return (size_t)m_count;
}
ENQUEUE_EVENT& GetEnqueueEvent()
{
return m_enqueue;
}
DEQUEUE_EVENT& GetDequeueEvent()
{
return m_dequeue;
}
void Enqueue(T item)
{
WaitForSingleObject(m_put, INFINITE);
{
GSAutoLock cAutoLock(this);
m_queue.push_back(item);
m_enqueue.Set();
m_dequeue.Reset();
}
ReleaseSemaphore(m_get, 1, NULL);
}
T Dequeue()
{
T item;
WaitForSingleObject(m_get, INFINITE);
{
GSAutoLock cAutoLock(this);
item = m_queue.front();
m_queue.pop_front();
if(m_queue.empty())
{
m_enqueue.Reset();
m_dequeue.Set();
}
}
ReleaseSemaphore(m_put, 1, NULL);
return item;
}
T Peek() // lock on "this"
{
return m_queue.front();
}
};
*/
#else
@ -128,14 +219,14 @@ public:
void Unlock() {pthread_mutex_unlock(&m_mutex);}
};
class GSAutoResetEvent
class GSEvent
{
protected:
sem_t m_sem;
public:
GSAutoResetEvent() {sem_init(&m_sem, 0, 0);}
~GSAutoResetEvent() {sem_destroy(&m_sem);}
GSEvent() {sem_init(&m_sem, 0, 0);}
~GSEvent() {sem_destroy(&m_sem);}
void Set() {sem_post(&m_sem);}
bool Wait() {return sem_wait(&m_sem) == 0;}
@ -152,3 +243,23 @@ public:
GSAutoLock(GSCritSec* cs) {m_cs = cs; m_cs->Lock();}
~GSAutoLock() {m_cs->Unlock();}
};
class GSEventSpin
{
protected:
volatile long m_sync;
volatile bool m_manual;
public:
GSEventSpin(bool manual = false, bool initial = false) {m_sync = initial ? 1 : 0; m_manual = manual;}
~GSEventSpin() {}
void Set() {_interlockedbittestandset(&m_sync, 0);}
void Reset() {_interlockedbittestandreset(&m_sync, 0);}
bool Wait()
{
if(m_manual) while(!m_sync) _mm_pause();
else while(!_interlockedbittestandreset(&m_sync, 0)) _mm_pause();
return true;
}
};

View File

@ -13,13 +13,11 @@
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@ -104,9 +102,9 @@ BEGIN
CONTROL "",IDC_MSAA,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,109,261,11,14
LTEXT "HW Anti Aliasing",IDC_STATIC_TEXT_HWAA,18,261,53,8
GROUPBOX "D3D Enhancements (can cause glitches)",IDC_STATIC,7,117,175,66
LTEXT "SW rend. threads:",IDC_STATIC,7,189,60,8
EDITTEXT IDC_SWTHREADS_EDIT,71,187,35,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,190,11,14
LTEXT "Extra rendering threads:",IDC_STATIC,7,189,80,8
EDITTEXT IDC_SWTHREADS_EDIT,89,187,35,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,117,190,11,14
CONTROL "Texture filtering",IDC_FILTER,"Button",BS_AUTO3STATE | WS_TABSTOP,7,203,67,10
CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,204,58,10
CONTROL "Allow 8-bit textures",IDC_PALTEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,217,82,10
@ -144,23 +142,23 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL 2021,IDC_LOGO9,"Static",SS_BITMAP,7,7,175,44
LTEXT "Resolution:",IDC_STATIC,7,59,37,8
COMBOBOX IDC_RESOLUTION,78,57,104,125,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_RESOLUTION,80,57,102,125,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Renderer:",IDC_STATIC,7,74,34,8
COMBOBOX IDC_RENDERER,78,72,104,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_RENDERER,80,72,102,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Texture Filter (Del):",IDC_STATIC,7,90,64,8
COMBOBOX IDC_FILTER,78,87,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_FILTER,80,87,102,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Dithering (End):",IDC_STATIC,7,105,52,8
COMBOBOX IDC_DITHERING,78,102,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_DITHERING,80,102,102,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Aspect Ratio (PgDn):",IDC_STATIC,7,120,68,8
COMBOBOX IDC_ASPECTRATIO,78,117,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Rendering Threads:",IDC_STATIC,7,157,64,8
EDITTEXT IDC_SWTHREADS_EDIT,78,155,35,13,ES_AUTOHSCROLL | ES_NUMBER
COMBOBOX IDC_ASPECTRATIO,80,117,102,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Extra Rend. Threads:",IDC_STATIC,7,157,70,8
EDITTEXT IDC_SWTHREADS_EDIT,80,155,35,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,161,11,14
DEFPUSHBUTTON "OK",IDOK,43,178,50,14
PUSHBUTTON "Cancel",IDCANCEL,96,178,50,14
CONTROL 2022,IDC_LOGO11,"Static",SS_BITMAP,7,7,173,42
LTEXT "Internal Resolution:",IDC_STATIC,7,135,64,8
COMBOBOX IDC_SCALE,78,132,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_SCALE,80,132,102,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Windowed",IDC_WINDOWED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,129,157,49,10
END
@ -181,9 +179,9 @@ BEGIN
EDITTEXT IDC_RESY_EDIT,130,132,35,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_RESY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,154,130,11,14
CONTROL "Native",IDC_NATIVERES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,92,105,33,10
LTEXT "Rendering threads:",IDC_STATIC,19,214,63,8
EDITTEXT IDC_SWTHREADS_EDIT,87,212,35,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,115,215,11,14
LTEXT "Extra rendering threads:",IDC_STATIC,19,214,80,8
EDITTEXT IDC_SWTHREADS_EDIT,102,212,35,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,135,215,11,14
COMBOBOX IDC_UPSCALE_MULTIPLIER,92,117,74,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Or use Scaling:",IDC_STATIC,38,120,49,8
LTEXT "Original PS2 resolution :",IDC_STATIC,10,105,80,8
@ -241,7 +239,7 @@ BEGIN
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 182
VERTGUIDE, 78
VERTGUIDE, 80
VERTGUIDE, 182
TOPMARGIN, 7
BOTTOMMARGIN, 192
@ -298,7 +296,7 @@ BEGIN
END
END
#endif // English (U.S.) resources
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
@ -312,7 +310,6 @@ END
#include "res/convert.fx"
#include "res/interlace.fx"
#include "res/merge.fx"
#include "res/fxaa.fx"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -317,6 +317,23 @@ typedef signed long long int64;
return retval;
}
__forceinline long _InterlockedExchangeAdd(volatile long* const Addend, const long Value)
{
long retval = Value;
__asm__("lock; xaddl %[retval], %[Addend]" : [retval] "+r" (retval) : [Addend] "m" (*Addend) : "memory");
return retval;
}
__forceinline long _InterlockedDecrement(volatile long* const lpAddend)
{
return _InterlockedExchangeAdd(lpAddend, -1) - 1;
}
__forceinline long _InterlockedIncrement(volatile long* const lpAddend)
{
return _InterlockedExchangeAdd(lpAddend, 1) + 1;
}
#ifdef __GNUC__
__forceinline unsigned long long __rdtsc()