diff --git a/plugins/GSdx/GPU.cpp b/plugins/GSdx/GPU.cpp index 77beb3d5e5..0ca5afceb4 100644 --- a/plugins/GSdx/GPU.cpp +++ b/plugins/GSdx/GPU.cpp @@ -93,12 +93,13 @@ EXPORT_C_(int32) GPUopen(HWND hWnd) } int renderer = theApp.GetConfig("Renderer", 1); + int threads = theApp.GetConfig("swthreads", 1); switch(renderer) { default: - case 0: s_gpu = new GPURendererSW(new GSDevice9()); break; - case 1: s_gpu = new GPURendererSW(new GSDevice11()); break; + case 0: s_gpu = new GPURendererSW(new GSDevice9(), threads); break; + case 1: s_gpu = new GPURendererSW(new GSDevice11(), threads); break; // TODO: case 3: s_gpu = new GPURendererNull(new GSDeviceNull()); break; } diff --git a/plugins/GSdx/GPUDrawScanline.cpp b/plugins/GSdx/GPUDrawScanline.cpp index 0c8b09944d..d7b1f5653d 100644 --- a/plugins/GSdx/GPUDrawScanline.cpp +++ b/plugins/GSdx/GPUDrawScanline.cpp @@ -22,12 +22,13 @@ #include "StdAfx.h" #include "GPUDrawScanline.h" -GPUDrawScanline::GPUDrawScanline(GPUState* state, int id) - : m_state(state) - , m_id(id) - , m_sp_map("GPUSetupPrim", &m_env) - , m_ds_map("GPUDrawScanline", &m_env) +GPUDrawScanline::GPUDrawScanline(const GPUScanlineGlobalData* gd) + : m_sp_map("GPUSetupPrim", &m_local) + , m_ds_map("GPUDrawScanline", &m_local) { + memset(&m_local, 0, sizeof(m_local)); + + m_local.gd = gd; } GPUDrawScanline::~GPUDrawScanline() @@ -36,40 +37,24 @@ GPUDrawScanline::~GPUDrawScanline() void GPUDrawScanline::BeginDraw(const GSRasterizerData* data) { - GPUDrawingEnvironment& env = m_state->m_env; - - const GPUScanlineParam* p = (const GPUScanlineParam*)data->param; - - m_env.sel = p->sel; - - m_env.vm = m_state->m_mem.GetPixelAddress(0, 0); - - if(m_env.sel.tme) + if(m_local.gd->sel.twin) { - m_env.tex = p->tex; - m_env.clut = p->clut; + uint32 u, v; - if(m_env.sel.twin) - { - uint32 u, v; + u = ~(m_local.gd->twin.x << 3) & 0xff; // TWW + v = ~(m_local.gd->twin.y << 3) & 0xff; // TWH - u = ~(env.TWIN.TWW << 3) & 0xff; - v = ~(env.TWIN.TWH << 3) & 0xff; + m_local.twin[0].u = GSVector4i((u << 16) | u); + m_local.twin[0].v = GSVector4i((v << 16) | v); - m_env.twin[0].u = GSVector4i((u << 16) | u); - m_env.twin[0].v = GSVector4i((v << 16) | v); - - u = env.TWIN.TWX << 3; - v = env.TWIN.TWY << 3; + u = m_local.gd->twin.z << 3; // TWX + v = m_local.gd->twin.y << 3; // TWY - m_env.twin[1].u = GSVector4i((u << 16) | u) & ~m_env.twin[0].u; - m_env.twin[1].v = GSVector4i((v << 16) | v) & ~m_env.twin[0].v; - } + m_local.twin[1].u = GSVector4i((u << 16) | u) & ~m_local.twin[0].u; + m_local.twin[1].v = GSVector4i((v << 16) | v) & ~m_local.twin[0].v; } - // - - m_ds = m_ds_map[m_env.sel]; + m_ds = m_ds_map[m_local.gd->sel]; m_de = NULL; @@ -81,15 +66,15 @@ void GPUDrawScanline::BeginDraw(const GSRasterizerData* data) sel.key = 0; - sel.iip = m_env.sel.iip; - sel.tfx = m_env.sel.tfx; - sel.twin = m_env.sel.twin; - sel.sprite = m_env.sel.sprite; + sel.iip = m_local.gd->sel.iip; + sel.tfx = m_local.gd->sel.tfx; + sel.twin = m_local.gd->sel.twin; + sel.sprite = m_local.gd->sel.sprite; m_sp = m_sp_map[sel]; } -void GPUDrawScanline::EndDraw(const GSRasterizerStats& stats) +void GPUDrawScanline::EndDraw(const GSRasterizerStats& stats, uint64 frame) { - m_ds_map.UpdateStats(stats, m_state->m_perfmon.GetFrame()); + m_ds_map.UpdateStats(stats, frame); } diff --git a/plugins/GSdx/GPUDrawScanline.h b/plugins/GSdx/GPUDrawScanline.h index 1fb0292514..54bc294383 100644 --- a/plugins/GSdx/GPUDrawScanline.h +++ b/plugins/GSdx/GPUDrawScanline.h @@ -29,24 +29,18 @@ class GPUDrawScanline : public IDrawScanline { - GPUScanlineEnvironment m_env; - - // + GPUScanlineLocalData m_local; GSCodeGeneratorFunctionMap m_sp_map; GSCodeGeneratorFunctionMap m_ds_map; -protected: - GPUState* m_state; - int m_id; - public: - GPUDrawScanline(GPUState* state, int id); + GPUDrawScanline(const GPUScanlineGlobalData* gd); virtual ~GPUDrawScanline(); // IDrawScanline void BeginDraw(const GSRasterizerData* data); - void EndDraw(const GSRasterizerStats& stats); + void EndDraw(const GSRasterizerStats& stats, uint64 frame); void PrintStats() {m_ds_map.PrintStats();} }; diff --git a/plugins/GSdx/GPUDrawScanlineCodeGenerator.cpp b/plugins/GSdx/GPUDrawScanlineCodeGenerator.cpp index f6cb728931..31b504fe25 100644 --- a/plugins/GSdx/GPUDrawScanlineCodeGenerator.cpp +++ b/plugins/GSdx/GPUDrawScanlineCodeGenerator.cpp @@ -24,14 +24,20 @@ #include "StdAfx.h" #include "GPUDrawScanlineCodeGenerator.h" +static const int _args = 8; +static const int _top = _args + 4; +static const int _v = _args + 8; + GPUDrawScanlineCodeGenerator::GPUDrawScanlineCodeGenerator(void* param, uint32 key, void* code, size_t maxsize) : GSCodeGenerator(code, maxsize) - , m_env(*(GPUScanlineEnvironment*)param) + , m_local(*(GPUScanlineLocalData*)param) { #if _M_AMD64 #error TODO #endif + m_sel.key = key; + Generate(); } @@ -40,9 +46,7 @@ void GPUDrawScanlineCodeGenerator::Generate() push(esi); push(edi); - const int params = 8; - - Init(params); + Init(); align(16); @@ -112,26 +116,23 @@ L("exit"); ret(8); } -void GPUDrawScanlineCodeGenerator::Init(int params) +void GPUDrawScanlineCodeGenerator::Init() { - const int _top = params + 4; - const int _v = params + 8; - mov(eax, dword[esp + _top]); - // uint16* fb = &m_env.vm[(top << (10 + m_env.sel.scalex)) + left]; + // uint16* fb = &m_local.vm[(top << (10 + m_sel.scalex)) + left]; mov(edi, eax); - shl(edi, 10 + m_env.sel.scalex); + shl(edi, 10 + m_sel.scalex); add(edi, edx); - lea(edi, ptr[edi * 2 + (size_t)m_env.vm]); + lea(edi, ptr[edi * 2 + (size_t)m_local.gd->vm]); // int steps = right - left - 8; sub(ecx, edx); sub(ecx, 8); - if(m_env.sel.dtd) + if(m_sel.dtd) { // dither = GSVector4i::load(&s_dither[top & 3][left & 3]); @@ -140,48 +141,48 @@ void GPUDrawScanlineCodeGenerator::Init(int params) and(edx, 3); shl(edx, 1); movdqu(xmm0, ptr[eax + edx + (size_t)m_dither]); - movdqa(ptr[&m_env.temp.dither], xmm0); + movdqa(ptr[&m_local.temp.dither], xmm0); } mov(edx, dword[esp + _v]); - if(m_env.sel.tme) + if(m_sel.tme) { - mov(esi, dword[&m_env.tex]); + mov(esi, dword[&m_local.gd->tex]); // GSVector4i vt = GSVector4i(v.t).xxzzl(); cvttps2dq(xmm4, ptr[edx + 32]); pshuflw(xmm4, xmm4, _MM_SHUFFLE(2, 2, 0, 0)); - // s = vt.xxxx().add16(m_env.d.s); - // t = vt.yyyy().add16(m_env.d.t); + // s = vt.xxxx().add16(m_local.d.s); + // t = vt.yyyy().add16(m_local.d.t); pshufd(xmm2, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm3, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); - paddw(xmm2, ptr[&m_env.d.s]); + paddw(xmm2, ptr[&m_local.d.s]); - if(!m_env.sel.sprite) + if(!m_sel.sprite) { - paddw(xmm3, ptr[&m_env.d.t]); + paddw(xmm3, ptr[&m_local.d.t]); } else { - if(m_env.sel.ltf) + if(m_sel.ltf) { movdqa(xmm0, xmm3); psllw(xmm0, 8); psrlw(xmm0, 1); - movdqa(ptr[&m_env.temp.vf], xmm0); + movdqa(ptr[&m_local.temp.vf], xmm0); } } - movdqa(ptr[&m_env.temp.s], xmm2); - movdqa(ptr[&m_env.temp.t], xmm3); + movdqa(ptr[&m_local.temp.s], xmm2); + movdqa(ptr[&m_local.temp.t], xmm3); } - if(m_env.sel.tfx != 3) // != decal + if(m_sel.tfx != 3) // != decal { // GSVector4i vc = GSVector4i(v.c).xxzzlh(); @@ -197,20 +198,20 @@ void GPUDrawScanlineCodeGenerator::Init(int params) pshufd(xmm5, xmm6, _MM_SHUFFLE(1, 1, 1, 1)); pshufd(xmm6, xmm6, _MM_SHUFFLE(2, 2, 2, 2)); - if(m_env.sel.iip) + if(m_sel.iip) { - // r = r.add16(m_env.d.r); - // g = g.add16(m_env.d.g); - // b = b.add16(m_env.d.b); + // r = r.add16(m_local.d.r); + // g = g.add16(m_local.d.g); + // b = b.add16(m_local.d.b); - paddw(xmm4, ptr[&m_env.d.r]); - paddw(xmm5, ptr[&m_env.d.g]); - paddw(xmm6, ptr[&m_env.d.b]); + paddw(xmm4, ptr[&m_local.d.r]); + paddw(xmm5, ptr[&m_local.d.g]); + paddw(xmm6, ptr[&m_local.d.b]); } - movdqa(ptr[&m_env.temp.r], xmm4); - movdqa(ptr[&m_env.temp.g], xmm5); - movdqa(ptr[&m_env.temp.b], xmm6); + movdqa(ptr[&m_local.temp.r], xmm4); + movdqa(ptr[&m_local.temp.g], xmm5); + movdqa(ptr[&m_local.temp.b], xmm6); } } @@ -224,62 +225,62 @@ void GPUDrawScanlineCodeGenerator::Step() add(edi, 8 * sizeof(uint16)); - if(m_env.sel.tme) + if(m_sel.tme) { - // GSVector4i st = m_env.d8.st; + // GSVector4i st = m_local.d8.st; - movdqa(xmm4, ptr[&m_env.d8.st]); + movdqa(xmm4, ptr[&m_local.d8.st]); // s = s.add16(st.xxxx()); // t = t.add16(st.yyyy()); pshufd(xmm2, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); - paddw(xmm2, ptr[&m_env.temp.s]); - movdqa(ptr[&m_env.temp.s], xmm2); + paddw(xmm2, ptr[&m_local.temp.s]); + movdqa(ptr[&m_local.temp.s], xmm2); // TODO: if(!sprite) ... else reload t pshufd(xmm3, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); - paddw(xmm3, ptr[&m_env.temp.t]); - movdqa(ptr[&m_env.temp.t], xmm3); + paddw(xmm3, ptr[&m_local.temp.t]); + movdqa(ptr[&m_local.temp.t], xmm3); } - if(m_env.sel.tfx != 3) // != decal + if(m_sel.tfx != 3) // != decal { - if(m_env.sel.iip) + if(m_sel.iip) { - // GSVector4i c = m_env.d8.c; + // GSVector4i c = m_local.d8.c; // r = r.add16(c.xxxx()); // g = g.add16(c.yyyy()); // b = b.add16(c.zzzz()); - movdqa(xmm6, ptr[&m_env.d8.c]); + movdqa(xmm6, ptr[&m_local.d8.c]); pshufd(xmm4, xmm6, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm5, xmm6, _MM_SHUFFLE(1, 1, 1, 1)); pshufd(xmm6, xmm6, _MM_SHUFFLE(2, 2, 2, 2)); - paddw(xmm4, ptr[&m_env.temp.r]); - paddw(xmm5, ptr[&m_env.temp.g]); - paddw(xmm6, ptr[&m_env.temp.b]); + paddw(xmm4, ptr[&m_local.temp.r]); + paddw(xmm5, ptr[&m_local.temp.g]); + paddw(xmm6, ptr[&m_local.temp.b]); - movdqa(ptr[&m_env.temp.r], xmm4); - movdqa(ptr[&m_env.temp.g], xmm5); - movdqa(ptr[&m_env.temp.b], xmm6); + movdqa(ptr[&m_local.temp.r], xmm4); + movdqa(ptr[&m_local.temp.g], xmm5); + movdqa(ptr[&m_local.temp.b], xmm6); } else { - movdqa(xmm4, ptr[&m_env.temp.r]); - movdqa(xmm5, ptr[&m_env.temp.g]); - movdqa(xmm6, ptr[&m_env.temp.b]); + movdqa(xmm4, ptr[&m_local.temp.r]); + movdqa(xmm5, ptr[&m_local.temp.g]); + movdqa(xmm6, ptr[&m_local.temp.b]); } } } void GPUDrawScanlineCodeGenerator::TestMask() { - if(!m_env.sel.me) + if(!m_sel.me) { return; } @@ -295,7 +296,7 @@ void GPUDrawScanlineCodeGenerator::TestMask() void GPUDrawScanlineCodeGenerator::SampleTexture() { - if(!m_env.sel.tme) + if(!m_sel.tme) { return; } @@ -306,7 +307,7 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() // xmm0, xmm4, xmm5, xmm6 = free // xmm1 = used - if(m_env.sel.ltf) + if(m_sel.ltf) { // GSVector4i u = s.sub16(GSVector4i(0x00200020)); // - 0.125f // GSVector4i v = t.sub16(GSVector4i(0x00200020)); // - 0.125f @@ -324,14 +325,14 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() movdqa(xmm0, xmm2); psllw(xmm0, 8); psrlw(xmm0, 1); - movdqa(ptr[&m_env.temp.uf], xmm0); + movdqa(ptr[&m_local.temp.uf], xmm0); - if(!m_env.sel.sprite) + if(!m_sel.sprite) { movdqa(xmm0, xmm3); psllw(xmm0, 8); psrlw(xmm0, 1); - movdqa(ptr[&m_env.temp.vf], xmm0); + movdqa(ptr[&m_local.temp.vf], xmm0); } } @@ -347,7 +348,7 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() // xmm0, xmm4, xmm5, xmm6 = free // xmm1 = used - if(m_env.sel.ltf) + if(m_sel.ltf) { // GSVector4i u1 = u0.add16(GSVector4i::x0001()); // GSVector4i v1 = v0.add16(GSVector4i::x0001()); @@ -360,23 +361,23 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() paddw(xmm4, xmm0); paddw(xmm5, xmm0); - if(m_env.sel.twin) + if(m_sel.twin) { - // u0 = (u0 & m_env.twin[0].u).add16(m_env.twin[1].u); - // v0 = (v0 & m_env.twin[0].v).add16(m_env.twin[1].v); - // u1 = (u1 & m_env.twin[0].u).add16(m_env.twin[1].u); - // v1 = (v1 & m_env.twin[0].v).add16(m_env.twin[1].v); + // u0 = (u0 & m_local.twin[0].u).add16(m_local.twin[1].u); + // v0 = (v0 & m_local.twin[0].v).add16(m_local.twin[1].v); + // u1 = (u1 & m_local.twin[0].u).add16(m_local.twin[1].u); + // v1 = (v1 & m_local.twin[0].v).add16(m_local.twin[1].v); - movdqa(xmm0, ptr[&m_env.twin[0].u]); - movdqa(xmm6, ptr[&m_env.twin[1].u]); + movdqa(xmm0, ptr[&m_local.twin[0].u]); + movdqa(xmm6, ptr[&m_local.twin[1].u]); pand(xmm2, xmm0); paddw(xmm2, xmm6); pand(xmm4, xmm0); paddw(xmm4, xmm6); - movdqa(xmm0, ptr[&m_env.twin[0].v]); - movdqa(xmm6, ptr[&m_env.twin[1].v]); + movdqa(xmm0, ptr[&m_local.twin[0].v]); + movdqa(xmm6, ptr[&m_local.twin[1].v]); pand(xmm3, xmm0); paddw(xmm3, xmm6); @@ -385,15 +386,15 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() } else { - // u0 = u0.min_i16(m_env.twin[2].u); - // v0 = v0.min_i16(m_env.twin[2].v); - // u1 = u1.min_i16(m_env.twin[2].u); - // v1 = v1.min_i16(m_env.twin[2].v); + // u0 = u0.min_i16(m_local.twin[2].u); + // v0 = v0.min_i16(m_local.twin[2].v); + // u1 = u1.min_i16(m_local.twin[2].u); + // v1 = v1.min_i16(m_local.twin[2].v); // TODO: if(!sprite) clamp16 else: - movdqa(xmm0, ptr[&m_env.twin[2].u]); - movdqa(xmm6, ptr[&m_env.twin[2].v]); + movdqa(xmm0, ptr[&m_local.twin[2].u]); + movdqa(xmm6, ptr[&m_local.twin[2].v]); pminsw(xmm2, xmm0); pminsw(xmm3, xmm6); @@ -447,8 +448,8 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() // spill (TODO) - movdqa(ptr[&m_env.temp.fd], xmm1); - movdqa(ptr[&m_env.temp.test], xmm7); + movdqa(ptr[&m_local.temp.fd], xmm1); + movdqa(ptr[&m_local.temp.test], xmm7); // xmm2 = c00 // xmm4 = c01 @@ -464,7 +465,7 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() psllw(xmm0, 11); psrlw(xmm0, 8); - lerp16<0>(xmm0, xmm1, ptr[&m_env.temp.uf]); + lerp16<0>(xmm0, xmm1, ptr[&m_local.temp.uf]); movdqa(xmm6, xmm2); psllw(xmm6, 6); @@ -476,7 +477,7 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() psrlw(xmm1, 11); psllw(xmm1, 3); - lerp16<0>(xmm1, xmm6, ptr[&m_env.temp.uf]); + lerp16<0>(xmm1, xmm6, ptr[&m_local.temp.uf]); movdqa(xmm7, xmm2); psllw(xmm7, 1); @@ -488,14 +489,14 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() psrlw(xmm6, 11); psllw(xmm6, 3); - lerp16<0>(xmm6, xmm7, ptr[&m_env.temp.uf]); + lerp16<0>(xmm6, xmm7, ptr[&m_local.temp.uf]); psraw(xmm2, 15); psrlw(xmm2, 8); psraw(xmm4, 15); psrlw(xmm4, 8); - lerp16<0>(xmm4, xmm2, ptr[&m_env.temp.uf]); + lerp16<0>(xmm4, xmm2, ptr[&m_local.temp.uf]); // xmm0 = r00 // xmm1 = g00 @@ -513,8 +514,8 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() psllw(xmm2, 11); psrlw(xmm2, 8); - lerp16<0>(xmm2, xmm7, ptr[&m_env.temp.uf]); - lerp16<0>(xmm2, xmm0, ptr[&m_env.temp.vf]); + lerp16<0>(xmm2, xmm7, ptr[&m_local.temp.uf]); + lerp16<0>(xmm2, xmm0, ptr[&m_local.temp.vf]); // xmm2 = r // xmm1 = g00 @@ -534,8 +535,8 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() psrlw(xmm0, 11); psllw(xmm0, 3); - lerp16<0>(xmm0, xmm7, ptr[&m_env.temp.uf]); - lerp16<0>(xmm0, xmm1, ptr[&m_env.temp.vf]); + lerp16<0>(xmm0, xmm7, ptr[&m_local.temp.uf]); + lerp16<0>(xmm0, xmm1, ptr[&m_local.temp.vf]); // xmm2 = r // xmm0 = g @@ -555,8 +556,8 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() psrlw(xmm1, 11); psllw(xmm1, 3); - lerp16<0>(xmm1, xmm7, ptr[&m_env.temp.uf]); - lerp16<0>(xmm1, xmm6, ptr[&m_env.temp.vf]); + lerp16<0>(xmm1, xmm7, ptr[&m_local.temp.uf]); + lerp16<0>(xmm1, xmm6, ptr[&m_local.temp.vf]); // xmm2 = r // xmm0 = g @@ -571,8 +572,8 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() psraw(xmm5, 15); psrlw(xmm5, 8); - lerp16<0>(xmm5, xmm3, ptr[&m_env.temp.uf]); - lerp16<0>(xmm5, xmm4, ptr[&m_env.temp.vf]); + lerp16<0>(xmm5, xmm3, ptr[&m_local.temp.uf]); + lerp16<0>(xmm5, xmm4, ptr[&m_local.temp.vf]); // xmm2 = r // xmm0 = g @@ -588,7 +589,7 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() // reload test - movdqa(xmm7, ptr[&m_env.temp.test]); + movdqa(xmm7, ptr[&m_local.temp.test]); // xmm4 = r // xmm5 = g @@ -615,29 +616,29 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() // reload fd - movdqa(xmm1, ptr[&m_env.temp.fd]); + movdqa(xmm1, ptr[&m_local.temp.fd]); } else { - if(m_env.sel.twin) + if(m_sel.twin) { - // u = (u & m_env.twin[0].u).add16(m_env.twin[1].u); - // v = (v & m_env.twin[0].v).add16(m_env.twin[1].v); + // u = (u & m_local.twin[0].u).add16(m_local.twin[1].u); + // v = (v & m_local.twin[0].v).add16(m_local.twin[1].v); - pand(xmm2, ptr[&m_env.twin[0].u]); - paddw(xmm2, ptr[&m_env.twin[1].u]); - pand(xmm3, ptr[&m_env.twin[0].v]); - paddw(xmm3, ptr[&m_env.twin[1].v]); + pand(xmm2, ptr[&m_local.twin[0].u]); + paddw(xmm2, ptr[&m_local.twin[1].u]); + pand(xmm3, ptr[&m_local.twin[0].v]); + paddw(xmm3, ptr[&m_local.twin[1].v]); } else { - // u = u.min_i16(m_env.twin[2].u); - // v = v.min_i16(m_env.twin[2].v); + // u = u.min_i16(m_local.twin[2].u); + // v = v.min_i16(m_local.twin[2].v); // TODO: if(!sprite) clamp16 else: - pminsw(xmm2, ptr[&m_env.twin[2].u]); - pminsw(xmm3, ptr[&m_env.twin[2].v]); + pminsw(xmm2, ptr[&m_local.twin[2].u]); + pminsw(xmm3, ptr[&m_local.twin[2].v]); } // xmm2 = u @@ -696,7 +697,7 @@ void GPUDrawScanlineCodeGenerator::SampleTexture() void GPUDrawScanlineCodeGenerator::ColorTFX() { - switch(m_env.sel.tfx) + switch(m_sel.tfx) { case 0: // none (tfx = 0) case 1: // none (tfx = tge) @@ -713,11 +714,11 @@ void GPUDrawScanlineCodeGenerator::ColorTFX() // c[2] = c[2].modulate16<1>(b).clamp8(); pcmpeqd(xmm0, xmm0); psrlw(xmm0, 8); - modulate16<1>(xmm4, ptr[&m_env.temp.r]); + modulate16<1>(xmm4, ptr[&m_local.temp.r]); pminsw(xmm4, xmm0); - modulate16<1>(xmm5, ptr[&m_env.temp.g]); + modulate16<1>(xmm5, ptr[&m_local.temp.g]); pminsw(xmm5, xmm0); - modulate16<1>(xmm6, ptr[&m_env.temp.b]); + modulate16<1>(xmm6, ptr[&m_local.temp.b]); pminsw(xmm6, xmm0); break; case 3: // decal (tfx = tme) @@ -727,7 +728,7 @@ void GPUDrawScanlineCodeGenerator::ColorTFX() void GPUDrawScanlineCodeGenerator::AlphaBlend() { - if(!m_env.sel.abe) + if(!m_sel.abe) { return; } @@ -748,7 +749,7 @@ void GPUDrawScanlineCodeGenerator::AlphaBlend() pand(xmm2, xmm0); psllw(xmm2, 3); - switch(m_env.sel.abr) + switch(m_sel.abr) { case 0: // r = r.avg8(c[0]); @@ -770,7 +771,7 @@ void GPUDrawScanlineCodeGenerator::AlphaBlend() break; } - if(m_env.sel.tme) + if(m_sel.tme) { movdqa(xmm0, xmm3); blend8(xmm4, xmm2); @@ -789,7 +790,7 @@ void GPUDrawScanlineCodeGenerator::AlphaBlend() pand(xmm2, xmm0); psrlw(xmm2, 2); - switch(m_env.sel.abr) + switch(m_sel.abr) { case 0: // g = g.avg8(c[2]); @@ -811,7 +812,7 @@ void GPUDrawScanlineCodeGenerator::AlphaBlend() break; } - if(m_env.sel.tme) + if(m_sel.tme) { movdqa(xmm0, xmm3); blend8(xmm5, xmm2); @@ -830,7 +831,7 @@ void GPUDrawScanlineCodeGenerator::AlphaBlend() pand(xmm2, xmm0); psrlw(xmm2, 7); - switch(m_env.sel.abr) + switch(m_sel.abr) { case 0: // b = b.avg8(c[2]); @@ -852,7 +853,7 @@ void GPUDrawScanlineCodeGenerator::AlphaBlend() break; } - if(m_env.sel.tme) + if(m_sel.tme) { movdqa(xmm0, xmm3); blend8(xmm6, xmm2); @@ -865,7 +866,7 @@ void GPUDrawScanlineCodeGenerator::AlphaBlend() void GPUDrawScanlineCodeGenerator::Dither() { - if(!m_env.sel.dtd) + if(!m_sel.dtd) { return; } @@ -874,7 +875,7 @@ void GPUDrawScanlineCodeGenerator::Dither() // c[1] = c[1].addus8(dither); // c[2] = c[2].addus8(dither); - movdqa(xmm0, ptr[&m_env.temp.dither]); + movdqa(xmm0, ptr[&m_local.temp.dither]); paddusb(xmm4, xmm0); paddusb(xmm5, xmm0); @@ -883,11 +884,11 @@ void GPUDrawScanlineCodeGenerator::Dither() void GPUDrawScanlineCodeGenerator::WriteFrame() { - // GSVector4i fs = r | g | b | (m_env.sel.md ? GSVector4i(0x80008000) : m_env.sel.tme ? a : 0); + // GSVector4i fs = r | g | b | (m_sel.md ? GSVector4i(0x80008000) : m_sel.tme ? a : 0); pcmpeqd(xmm0, xmm0); - if(m_env.sel.md || m_env.sel.tme) + if(m_sel.md || m_sel.tme) { movdqa(xmm2, xmm0); psllw(xmm2, 15); @@ -916,13 +917,13 @@ void GPUDrawScanlineCodeGenerator::WriteFrame() psllw(xmm6, 7); por(xmm4, xmm6); - if(m_env.sel.md) + if(m_sel.md) { // GSVector4i a = GSVector4i(0x80008000); por(xmm4, xmm2); } - else if(m_env.sel.tme) + else if(m_sel.tme) { // GSVector4i a = (c[3] << 8) & 0x80008000; @@ -950,9 +951,9 @@ void GPUDrawScanlineCodeGenerator::ReadTexel(const Xmm& dst, const Xmm& addr) { pextrw(eax, addr, (uint8)i); - if(m_env.sel.tlu) movzx(eax, byte[esi + eax]); + if(m_sel.tlu) movzx(eax, byte[esi + eax]); - const Address& src = m_env.sel.tlu ? ptr[eax * 2 + (size_t)m_env.clut] : ptr[esi + eax * 2]; + const Address& src = m_sel.tlu ? ptr[eax * 2 + (size_t)m_local.gd->clut] : ptr[esi + eax * 2]; if(i == 0) movd(dst, src); else pinsrw(dst, src, (uint8)i); diff --git a/plugins/GSdx/GPUDrawScanlineCodeGenerator.h b/plugins/GSdx/GPUDrawScanlineCodeGenerator.h index 81761d5506..2cc38de374 100644 --- a/plugins/GSdx/GPUDrawScanlineCodeGenerator.h +++ b/plugins/GSdx/GPUDrawScanlineCodeGenerator.h @@ -33,11 +33,12 @@ class GPUDrawScanlineCodeGenerator : public GSCodeGenerator static const GSVector4i m_test[8]; static const uint16 m_dither[4][16]; - GPUScanlineEnvironment& m_env; + GPUScanlineSelector m_sel; + GPUScanlineLocalData& m_local; void Generate(); - void Init(int params); + void Init(); void Step(); void TestMask(); void SampleTexture(); diff --git a/plugins/GSdx/GPUDrawingEnvironment.h b/plugins/GSdx/GPUDrawingEnvironment.h index a4b50f47ee..2c26b56f3e 100644 --- a/plugins/GSdx/GPUDrawingEnvironment.h +++ b/plugins/GSdx/GPUDrawingEnvironment.h @@ -25,7 +25,7 @@ #pragma pack(push, 1) -__declspec(align(16)) class GPUDrawingEnvironment +__aligned32 class GPUDrawingEnvironment { public: GPURegSTATUS STATUS; diff --git a/plugins/GSdx/GPURendererSW.cpp b/plugins/GSdx/GPURendererSW.cpp index 13c0a25d7a..18b0977d3c 100644 --- a/plugins/GSdx/GPURendererSW.cpp +++ b/plugins/GSdx/GPURendererSW.cpp @@ -23,11 +23,11 @@ #include "GPURendererSW.h" #include "GSdx.h" -GPURendererSW::GPURendererSW(GSDevice* dev) +GPURendererSW::GPURendererSW(GSDevice* dev, int threads) : GPURendererT(dev) , m_texture(NULL) { - m_rl.Create(this, theApp.GetConfig("swthreads", 1)); + m_rl.Create(threads); } GPURendererSW::~GPURendererSW() @@ -70,39 +70,42 @@ void GPURendererSW::Draw() // - GPUScanlineParam p; + GPUScanlineGlobalData gd; - p.sel.key = 0; - p.sel.iip = env.PRIM.IIP; - p.sel.me = env.STATUS.ME; + gd.sel.key = 0; + gd.sel.iip = env.PRIM.IIP; + gd.sel.me = env.STATUS.ME; if(env.PRIM.ABE) { - p.sel.abe = env.PRIM.ABE; - p.sel.abr = env.STATUS.ABR; + gd.sel.abe = env.PRIM.ABE; + gd.sel.abr = env.STATUS.ABR; } - p.sel.tge = env.PRIM.TGE; + gd.sel.tge = env.PRIM.TGE; if(env.PRIM.TME) { - p.sel.tme = env.PRIM.TME; - p.sel.tlu = env.STATUS.TP < 2; - p.sel.twin = (env.TWIN.u32 & 0xfffff) != 0; - p.sel.ltf = m_filter == 1 && env.PRIM.TYPE == GPU_POLYGON || m_filter == 2 ? 1 : 0; + gd.sel.tme = env.PRIM.TME; + gd.sel.tlu = env.STATUS.TP < 2; + gd.sel.twin = (env.TWIN.u32 & 0xfffff) != 0; + gd.sel.ltf = m_filter == 1 && env.PRIM.TYPE == GPU_POLYGON || m_filter == 2 ? 1 : 0; const void* t = m_mem.GetTexture(env.STATUS.TP, env.STATUS.TX, env.STATUS.TY); if(!t) {ASSERT(0); return;} - p.tex = t; - p.clut = m_mem.GetCLUT(env.STATUS.TP, env.CLUT.X, env.CLUT.Y); + gd.tex = t; + gd.clut = m_mem.GetCLUT(env.STATUS.TP, env.CLUT.X, env.CLUT.Y); + gd.twin = GSVector4i(env.TWIN.TWW, env.TWIN.TWH, env.TWIN.TWX, env.TWIN.TWY); } - p.sel.dtd = m_dither ? env.STATUS.DTD : 0; - p.sel.md = env.STATUS.MD; - p.sel.sprite = env.PRIM.TYPE == GPU_SPRITE; - p.sel.scalex = m_mem.GetScale().x; + gd.sel.dtd = m_dither ? env.STATUS.DTD : 0; + gd.sel.md = env.STATUS.MD; + gd.sel.sprite = env.PRIM.TYPE == GPU_SPRITE; + gd.sel.scalex = m_mem.GetScale().x; + + gd.vm = m_mem.GetPixelAddress(0, 0); // @@ -110,7 +113,8 @@ void GPURendererSW::Draw() data.vertices = m_vertices; data.count = m_count; - data.param = &p; + data.frame = m_perfmon.GetFrame(); + data.param = &gd; data.scissor.left = (int)m_env.DRAREATL.X << m_scale.x; data.scissor.top = (int)m_env.DRAREATL.Y << m_scale.y; @@ -127,14 +131,6 @@ void GPURendererSW::Draw() m_rl.Draw(&data); - GSRasterizerStats stats; - - m_rl.GetStats(stats); - - m_perfmon.Put(GSPerfMon::Draw, 1); - m_perfmon.Put(GSPerfMon::Prim, stats.prims); - m_perfmon.Put(GSPerfMon::Fillrate, stats.pixels); - // TODO { @@ -158,6 +154,16 @@ void GPURendererSW::Draw() Invalidate(r); } + + m_rl.Sync(); + + GSRasterizerStats stats; + + m_rl.GetStats(stats); + + m_perfmon.Put(GSPerfMon::Draw, 1); + m_perfmon.Put(GSPerfMon::Prim, stats.prims); + m_perfmon.Put(GSPerfMon::Fillrate, stats.pixels); } void GPURendererSW::VertexKick() diff --git a/plugins/GSdx/GPURendererSW.h b/plugins/GSdx/GPURendererSW.h index 0e7fc4c749..253944b3aa 100644 --- a/plugins/GSdx/GPURendererSW.h +++ b/plugins/GSdx/GPURendererSW.h @@ -36,6 +36,6 @@ protected: void Draw(); public: - GPURendererSW(GSDevice* dev); + GPURendererSW(GSDevice* dev, int threads); virtual ~GPURendererSW(); }; diff --git a/plugins/GSdx/GPUScanlineEnvironment.h b/plugins/GSdx/GPUScanlineEnvironment.h index 189341e7f8..f96043270c 100644 --- a/plugins/GSdx/GPUScanlineEnvironment.h +++ b/plugins/GSdx/GPUScanlineEnvironment.h @@ -53,29 +53,26 @@ union GPUScanlineSelector uint32 key; - operator uint32() {return key;} + operator uint32() const {return key;} }; -__declspec(align(16)) struct GPUScanlineParam -{ - GPUScanlineSelector sel; - - const void* tex; - const uint16* clut; -}; - -__declspec(align(16)) struct GPUScanlineEnvironment +__aligned32 struct GPUScanlineGlobalData { GPUScanlineSelector sel; void* vm; const void* tex; const uint16* clut; + GSVector4i twin; // TWW, TWH, TWX, TWY +}; - // GSVector4i md; // similar to gs fba +__aligned32 struct GPUScanlineLocalData +{ + const GPUScanlineGlobalData* gd; struct {GSVector4i u, v;} twin[3]; struct {GSVector4i s, t, r, g, b, _pad[3];} d; struct {GSVector4i st, c;} d8; + struct {GSVector4i s, t, r, b, g, uf, vf, dither, fd, test;} temp; }; diff --git a/plugins/GSdx/GPUSetupPrimCodeGenerator.cpp b/plugins/GSdx/GPUSetupPrimCodeGenerator.cpp index b28bffe9d1..e245152a77 100644 --- a/plugins/GSdx/GPUSetupPrimCodeGenerator.cpp +++ b/plugins/GSdx/GPUSetupPrimCodeGenerator.cpp @@ -29,22 +29,24 @@ using namespace Xbyak; GPUSetupPrimCodeGenerator::GPUSetupPrimCodeGenerator(void* param, uint32 key, void* code, size_t maxsize) : GSCodeGenerator(code, maxsize) - , m_env(*(GPUScanlineEnvironment*)param) + , m_local(*(GPUScanlineLocalData*)param) { #if _M_AMD64 #error TODO #endif + m_sel.key = key; + Generate(); } void GPUSetupPrimCodeGenerator::Generate() { - if(m_env.sel.tme && !m_env.sel.twin) + if(m_sel.tme && !m_sel.twin) { pcmpeqd(xmm0, xmm0); - if(m_env.sel.sprite) + if(m_sel.sprite) { // t = (GSVector4i(vertices[1].t) >> 8) - GSVector4i::x00000001(); @@ -59,30 +61,30 @@ void GPUSetupPrimCodeGenerator::Generate() packssdw(xmm1, xmm1); punpcklwd(xmm1, xmm1); - // m_env.twin[2].u = t.xxxx(); - // m_env.twin[2].v = t.yyyy(); + // m_local.twin[2].u = t.xxxx(); + // m_local.twin[2].v = t.yyyy(); pshufd(xmm2, xmm1, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm3, xmm1, _MM_SHUFFLE(1, 1, 1, 1)); - movdqa(ptr[&m_env.twin[2].u], xmm2); - movdqa(ptr[&m_env.twin[2].v], xmm3); + movdqa(ptr[&m_local.twin[2].u], xmm2); + movdqa(ptr[&m_local.twin[2].v], xmm3); } else { // TODO: not really needed - // m_env.twin[2].u = GSVector4i::x00ff(); - // m_env.twin[2].v = GSVector4i::x00ff(); + // m_local.twin[2].u = GSVector4i::x00ff(); + // m_local.twin[2].v = GSVector4i::x00ff(); psrlw(xmm0, 8); - movdqa(ptr[&m_env.twin[2].u], xmm0); - movdqa(ptr[&m_env.twin[2].v], xmm0); + movdqa(ptr[&m_local.twin[2].u], xmm0); + movdqa(ptr[&m_local.twin[2].v], xmm0); } } - if(m_env.sel.tme || m_env.sel.iip && m_env.sel.tfx != 3) + if(m_sel.tme || m_sel.iip && m_sel.tfx != 3) { for(int i = 0; i < 3; i++) { @@ -105,21 +107,21 @@ void GPUSetupPrimCodeGenerator::Generate() cvttps2dq(xmm2, xmm2); packssdw(xmm1, xmm2); - if(m_env.sel.tme) + if(m_sel.tme) { - // m_env.d8.st = dtc8.upl16(dtc8); + // m_local.d8.st = dtc8.upl16(dtc8); movdqa(xmm0, xmm1); punpcklwd(xmm0, xmm0); - movdqa(ptr[&m_env.d8.st], xmm0); + movdqa(ptr[&m_local.d8.st], xmm0); } - if(m_env.sel.iip && m_env.sel.tfx != 3) + if(m_sel.iip && m_sel.tfx != 3) { - // m_env.d8.c = dtc8.uph16(dtc8); + // m_local.d8.c = dtc8.uph16(dtc8); punpckhwd(xmm1, xmm1); - movdqa(ptr[&m_env.d8.c], xmm1); + movdqa(ptr[&m_local.d8.c], xmm1); } // xmm3 = dt @@ -128,7 +130,7 @@ void GPUSetupPrimCodeGenerator::Generate() // xmm7 = ps4567 // xmm0, xmm1, xmm2, xmm5 = free - if(m_env.sel.tme) + if(m_sel.tme) { // GSVector4 dtx = dt.xxxx(); // GSVector4 dty = dt.yyyy(); @@ -137,7 +139,7 @@ void GPUSetupPrimCodeGenerator::Generate() shufps(xmm3, xmm3, _MM_SHUFFLE(0, 0, 0, 0)); shufps(xmm0, xmm0, _MM_SHUFFLE(1, 1, 1, 1)); - // m_env.d.s = GSVector4i(dtx * ps0123).ps32(GSVector4i(dtx * ps4567)); + // m_local.d.s = GSVector4i(dtx * ps0123).ps32(GSVector4i(dtx * ps4567)); movaps(xmm1, xmm3); mulps(xmm3, xmm6); @@ -145,9 +147,9 @@ void GPUSetupPrimCodeGenerator::Generate() cvttps2dq(xmm3, xmm3); cvttps2dq(xmm1, xmm1); packssdw(xmm3, xmm1); - movdqa(ptr[&m_env.d.s], xmm3); + movdqa(ptr[&m_local.d.s], xmm3); - // m_env.d.t = GSVector4i(dty * ps0123).ps32(GSVector4i(dty * ps4567)); + // m_local.d.t = GSVector4i(dty * ps0123).ps32(GSVector4i(dty * ps4567)); movaps(xmm1, xmm0); mulps(xmm0, xmm6); @@ -155,7 +157,7 @@ void GPUSetupPrimCodeGenerator::Generate() cvttps2dq(xmm0, xmm0); cvttps2dq(xmm1, xmm1); packssdw(xmm0, xmm1); - movdqa(ptr[&m_env.d.t], xmm0); + movdqa(ptr[&m_local.d.t], xmm0); } // xmm4 = dc @@ -163,7 +165,7 @@ void GPUSetupPrimCodeGenerator::Generate() // xmm7 = ps4567 // xmm0, xmm1, zmm2, xmm3, xmm5 = free - if(m_env.sel.iip && m_env.sel.tfx != 3) + if(m_sel.iip && m_sel.tfx != 3) { // GSVector4 dcx = dc.xxxx(); // GSVector4 dcy = dc.yyyy(); @@ -175,7 +177,7 @@ void GPUSetupPrimCodeGenerator::Generate() shufps(xmm0, xmm0, _MM_SHUFFLE(1, 1, 1, 1)); shufps(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); - // m_env.d.r = GSVector4i(dcx * ps0123).ps32(GSVector4i(dcx * ps4567)); + // m_local.d.r = GSVector4i(dcx * ps0123).ps32(GSVector4i(dcx * ps4567)); movaps(xmm2, xmm4); mulps(xmm4, xmm6); @@ -183,9 +185,9 @@ void GPUSetupPrimCodeGenerator::Generate() cvttps2dq(xmm4, xmm4); cvttps2dq(xmm2, xmm2); packssdw(xmm4, xmm2); - movdqa(ptr[&m_env.d.r], xmm4); + movdqa(ptr[&m_local.d.r], xmm4); - // m_env.d.g = GSVector4i(dcy * ps0123).ps32(GSVector4i(dcy * ps4567)); + // m_local.d.g = GSVector4i(dcy * ps0123).ps32(GSVector4i(dcy * ps4567)); movaps(xmm2, xmm0); mulps(xmm0, xmm6); @@ -193,9 +195,9 @@ void GPUSetupPrimCodeGenerator::Generate() cvttps2dq(xmm0, xmm0); cvttps2dq(xmm2, xmm2); packssdw(xmm0, xmm2); - movdqa(ptr[&m_env.d.g], xmm0); + movdqa(ptr[&m_local.d.g], xmm0); - // m_env.d.b = GSVector4i(dcz * ps0123).ps32(GSVector4i(dcz * ps4567)); + // m_local.d.b = GSVector4i(dcz * ps0123).ps32(GSVector4i(dcz * ps4567)); movaps(xmm2, xmm1); mulps(xmm1, xmm6); @@ -203,7 +205,7 @@ void GPUSetupPrimCodeGenerator::Generate() cvttps2dq(xmm1, xmm1); cvttps2dq(xmm2, xmm2); packssdw(xmm1, xmm2); - movdqa(ptr[&m_env.d.b], xmm1); + movdqa(ptr[&m_local.d.b], xmm1); } } diff --git a/plugins/GSdx/GPUSetupPrimCodeGenerator.h b/plugins/GSdx/GPUSetupPrimCodeGenerator.h index e6e06452a6..2d0010bb87 100644 --- a/plugins/GSdx/GPUSetupPrimCodeGenerator.h +++ b/plugins/GSdx/GPUSetupPrimCodeGenerator.h @@ -30,7 +30,8 @@ class GPUSetupPrimCodeGenerator : public GSCodeGenerator static const GSVector4 m_shift[3]; - GPUScanlineEnvironment& m_env; + GPUScanlineSelector m_sel; + GPUScanlineLocalData& m_local; void Generate(); diff --git a/plugins/GSdx/GPUState.h b/plugins/GSdx/GPUState.h index ad84aac2e8..7e6722cf5a 100644 --- a/plugins/GSdx/GPUState.h +++ b/plugins/GSdx/GPUState.h @@ -29,7 +29,7 @@ #include "GSUtil.h" #include "GSPerfMon.h" -class GPUState : public GSAlignedClass<16> +class GPUState : public GSAlignedClass<32> { typedef void (GPUState::*GPUStatusCommandHandler)(GPUReg* r); diff --git a/plugins/GSdx/GPUVertex.h b/plugins/GSdx/GPUVertex.h index 7ae86ca426..fe9937f02a 100644 --- a/plugins/GSdx/GPUVertex.h +++ b/plugins/GSdx/GPUVertex.h @@ -26,7 +26,7 @@ #pragma pack(push, 1) -__declspec(align(16)) struct GPUVertex +__aligned32 struct GPUVertex { union { diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index 08926ed164..c652faca63 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -149,7 +149,7 @@ EXPORT_C GSclose() s_gs->m_wnd.Detach(); } -static INT32 _GSopen(void* dsp, char* title, int renderer) +static INT32 _GSopen(void* dsp, char* title, int renderer, int threads = -1) { GSDevice* dev = NULL; @@ -158,6 +158,11 @@ static INT32 _GSopen(void* dsp, char* title, int renderer) renderer = theApp.GetConfig("renderer", 0); } + if(threads == -1) + { + threads = theApp.GetConfig("swthreads", 1); + } + try { if (s_renderer != renderer) @@ -196,20 +201,21 @@ static INT32 _GSopen(void* dsp, char* title, int renderer) s_gs = new GSRendererNull(); break; case 1: case 4: case 7: case 10: case 12: - s_gs = new GSRendererSW(); + s_gs = new GSRendererSW(threads); break; } s_renderer = renderer; } } - catch( std::exception& ex ) + catch(std::exception& ex) { // Allowing std exceptions to escape the scope of the plugin callstack could // be problematic, because of differing typeids between DLL and EXE compilations. // ('new' could throw std::alloc) - printf( "GSdx error: Exception caught in GSopen: %s", ex.what() ); + printf("GSdx error: Exception caught in GSopen: %s", ex.what()); + return -1; } @@ -218,7 +224,7 @@ static INT32 _GSopen(void* dsp, char* title, int renderer) s_gs->SetVsync(s_vsync); s_gs->SetFrameLimit(s_framelimit); - if( *(HWND*)dsp == NULL ) + if(*(HWND*)dsp == NULL) { // old-style API expects us to create and manage our own window: @@ -232,21 +238,23 @@ static INT32 _GSopen(void* dsp, char* title, int renderer) } s_gs->m_wnd.Show(); + *(HWND*)dsp = (HWND)s_gs->m_wnd.GetHandle(); } else { - s_gs->SetMultithreaded( true ); - s_gs->m_wnd.Attach( *(HWND*)dsp, false ); + s_gs->SetMultithreaded(true); + s_gs->m_wnd.Attach(*(HWND*)dsp, false); } - if( !s_gs->CreateDevice(dev) ) + if(!s_gs->CreateDevice(dev)) { // This probably means the user has DX11 configured with a video card that is only DX9 // compliant. Cound mean drivr issues of some sort also, but to be sure, that's the most // common cause of device creation errors. :) --air GSclose(); + return -1; } @@ -255,17 +263,18 @@ static INT32 _GSopen(void* dsp, char* title, int renderer) return 0; } -EXPORT_C_(INT32) GSopen2( void* dsp, INT32 flags ) +EXPORT_C_(INT32) GSopen2(void* dsp, INT32 flags) { int renderer = theApp.GetConfig("renderer", 0); - if( flags & 4 ) + + if(flags & 4) { - if (isdx11avail) renderer = 4; //dx11 sw - else renderer = 1; //dx9 sw + renderer = isdx11avail ? 4 : 1; // dx11 / dx9 sw } - INT32 retval = _GSopen( dsp, NULL, renderer ); - s_gs->SetAspectRatio(0); // PCSX2 manages the aspect ratios + INT32 retval = _GSopen(dsp, NULL, renderer); + + s_gs->SetAspectRatio(0); // PCSX2 manages the aspect ratios return retval; } @@ -275,18 +284,21 @@ EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt) int renderer; // Legacy GUI expects to acquire vsync from the configuration files. + s_vsync = !!theApp.GetConfig("vsync", 0); if(mt == 2) { // pcsx2 sent a switch renderer request - if (isdx11avail) renderer = 4; //dx11 sw - else renderer = 1; //dx9 sw + + renderer = isdx11avail ? 4 : 1; // dx11 / dx9 sw + mt = 1; } else { // normal init + renderer = theApp.GetConfig("renderer", 0); } @@ -294,9 +306,9 @@ EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt) int retval = _GSopen(dsp, title, renderer); - if( retval == 0 && s_gs ) + if(retval == 0 && s_gs) { - s_gs->SetMultithreaded( !!mt ); + s_gs->SetMultithreaded(!!mt); } return retval; @@ -370,10 +382,14 @@ EXPORT_C GSvsync(int field) EXPORT_C_(uint32) GSmakeSnapshot(char* path) { - string str = string(path); - if (str[str.length() - 1] != '\\') - str = str + "\\"; - return s_gs->MakeSnapshot(str + "gsdx"); + string s(path); + + if(s.back() != '\\') + { + s = s + "\\"; + } + + return s_gs->MakeSnapshot(s + "gsdx"); } EXPORT_C GSkeyEvent(GSKeyEventData* e) @@ -401,13 +417,14 @@ EXPORT_C_(int) GSfreeze(int mode, GSFreezeData* data) EXPORT_C GSconfigure() { - if( !GSUtil::CheckSSE() ) return; + if(!GSUtil::CheckSSE()) return; - if( GSSettingsDlg( s_IsGsOpen2 ).DoModal() == IDOK ) + if(GSSettingsDlg(s_IsGsOpen2).DoModal() == IDOK) { - if( s_gs != NULL && s_gs->m_wnd.IsManaged() ) + if(s_gs != NULL && s_gs->m_wnd.IsManaged()) { // Legacy apps like gsdxgui expect this... + GSshutdown(); } } @@ -427,7 +444,9 @@ EXPORT_C_(INT32) GStest() if(!GSUtil::CheckDirectX()) { if(SUCCEEDED(s_hr)) + { ::CoUninitialize(); + } s_hr = E_FAIL; @@ -435,7 +454,9 @@ EXPORT_C_(INT32) GStest() } if(SUCCEEDED(s_hr)) + { ::CoUninitialize(); + } s_hr = E_FAIL; @@ -451,7 +472,8 @@ EXPORT_C GSabout() EXPORT_C GSirqCallback(void (*irq)()) { s_irq = irq; - if( s_gs ) + + if(s_gs) { s_gs->SetIrqCallback(s_irq); } @@ -462,9 +484,13 @@ EXPORT_C_(int) GSsetupRecording(int start, void* data) if(!s_gs) return 0; if(start & 1) + { s_gs->BeginCapture(); + } else + { s_gs->EndCapture(); + } return 1; } @@ -486,13 +512,15 @@ EXPORT_C GSgetLastTag(uint32* tag) EXPORT_C GSgetTitleInfo2(char* dest, size_t length) { - if (!s_gs->m_GStitleInfoBuffer[0]) + if(!s_gs->m_GStitleInfoBuffer[0]) + { strcpy(dest, "GSdx"); + } else { EnterCriticalSection(&s_gs->m_pGSsetTitle_Crit); - snprintf(dest, length-1, "GSdx | %s", s_gs->m_GStitleInfoBuffer); - dest[length-1] = 0; // just in case! + snprintf(dest, length - 1, "GSdx | %s", s_gs->m_GStitleInfoBuffer); + dest[length - 1] = 0; // just in case! LeaveCriticalSection(&s_gs->m_pGSsetTitle_Crit); } } @@ -505,22 +533,31 @@ EXPORT_C GSsetFrameSkip(int frameskip) EXPORT_C GSsetVsync(int enabled) { s_vsync = !!enabled; - if( s_gs ) + + if(s_gs) + { s_gs->SetVsync(s_vsync); + } } EXPORT_C GSsetExclusive(int enabled) { s_exclusive = !!enabled; - if( s_gs ) + + if(s_gs) + { s_gs->SetVsync(s_vsync); + } } EXPORT_C GSsetFrameLimit(int limit) { s_framelimit = !!limit; - if( s_gs ) + + if(s_gs) + { s_gs->SetFrameLimit(s_framelimit); + } } #ifdef _WINDOWS @@ -595,6 +632,7 @@ public: // lpszCmdLine: // First parameter is the renderer. // Second parameter is the gs file to load and run. + EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { int renderer = -1; diff --git a/plugins/GSdx/GSDrawScanline.cpp b/plugins/GSdx/GSDrawScanline.cpp index ffd1a2b344..8c9db5113f 100644 --- a/plugins/GSdx/GSDrawScanline.cpp +++ b/plugins/GSdx/GSDrawScanline.cpp @@ -23,13 +23,13 @@ #include "GSDrawScanline.h" #include "GSTextureCacheSW.h" -GSDrawScanline::GSDrawScanline(GSState* state, int id) - : m_state(state) - , m_id(id) - , m_sp_map("GSSetupPrim", &m_env) - , m_ds_map("GSDrawScanline", &m_env) +GSDrawScanline::GSDrawScanline(GSScanlineGlobalData* gd) + : m_sp_map("GSSetupPrim", &m_local) + , m_ds_map("GSDrawScanline", &m_local) { - memset(&m_env, 0, sizeof(m_env)); + memset(&m_local, 0, sizeof(m_local)); + + m_local.gd = gd; } GSDrawScanline::~GSDrawScanline() @@ -38,137 +38,13 @@ GSDrawScanline::~GSDrawScanline() void GSDrawScanline::BeginDraw(const GSRasterizerData* data) { - GSDrawingEnvironment& env = m_state->m_env; - GSDrawingContext* context = m_state->m_context; + m_ds = m_ds_map[m_local.gd->sel]; - const GSScanlineParam* p = (const GSScanlineParam*)data->param; - - m_sel = p->sel; - - m_env.vm = p->vm; - m_env.fbr = p->fbo->pixel.row; - m_env.zbr = p->zbo->pixel.row; - m_env.fbc = p->fbo->pixel.col[0]; - m_env.zbc = p->zbo->pixel.col[0]; - m_env.fzbr = p->fzbo->row; - m_env.fzbc = p->fzbo->col; - m_env.fm = GSVector4i(p->fm); - m_env.zm = GSVector4i(p->zm); - m_env.aref = GSVector4i((int)context->TEST.AREF); - m_env.afix = GSVector4i((int)context->ALPHA.FIX << 7).xxzzlh(); - m_env.frb = GSVector4i((int)env.FOGCOL.u32[0] & 0x00ff00ff); - m_env.fga = GSVector4i((int)(env.FOGCOL.u32[0] >> 8) & 0x00ff00ff); - m_env.dimx = env.dimx; - - if(m_sel.fpsm == 1) - { - m_env.fm |= GSVector4i::xff000000(); - } - else if(m_sel.fpsm == 2) - { - GSVector4i rb = m_env.fm & 0x00f800f8; - GSVector4i ga = m_env.fm & 0x8000f800; - - m_env.fm = (ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3) | GSVector4i::xffff0000(); - } - - if(m_sel.zpsm == 1) - { - m_env.zm |= GSVector4i::xff000000(); - } - else if(m_sel.zpsm == 2) - { - m_env.zm |= GSVector4i::xffff0000(); - } - - if(m_sel.atst == ATST_LESS) - { - m_sel.atst = ATST_LEQUAL; - - m_env.aref -= GSVector4i::x00000001(); - } - else if(m_sel.atst == ATST_GREATER) - { - m_sel.atst = ATST_GEQUAL; - - m_env.aref += GSVector4i::x00000001(); - } - - if(m_sel.tfx != TFX_NONE) - { - m_env.tex = p->tex; - m_env.clut = p->clut; - - unsigned short tw = (unsigned short)(1 << context->TEX0.TW); - unsigned short th = (unsigned short)(1 << context->TEX0.TH); - - switch(context->CLAMP.WMS) - { - case CLAMP_REPEAT: - m_env.t.min.u16[0] = tw - 1; - m_env.t.max.u16[0] = 0; - m_env.t.mask.u32[0] = 0xffffffff; - break; - case CLAMP_CLAMP: - m_env.t.min.u16[0] = 0; - m_env.t.max.u16[0] = tw - 1; - m_env.t.mask.u32[0] = 0; - break; - case CLAMP_REGION_CLAMP: - m_env.t.min.u16[0] = std::min(context->CLAMP.MINU, tw - 1); - m_env.t.max.u16[0] = std::min(context->CLAMP.MAXU, tw - 1); - m_env.t.mask.u32[0] = 0; - break; - case CLAMP_REGION_REPEAT: - m_env.t.min.u16[0] = context->CLAMP.MINU; - m_env.t.max.u16[0] = context->CLAMP.MAXU; - m_env.t.mask.u32[0] = 0xffffffff; - break; - default: - __assume(0); - } - - switch(context->CLAMP.WMT) - { - case CLAMP_REPEAT: - m_env.t.min.u16[4] = th - 1; - m_env.t.max.u16[4] = 0; - m_env.t.mask.u32[2] = 0xffffffff; - break; - case CLAMP_CLAMP: - m_env.t.min.u16[4] = 0; - m_env.t.max.u16[4] = th - 1; - m_env.t.mask.u32[2] = 0; - break; - case CLAMP_REGION_CLAMP: - m_env.t.min.u16[4] = std::min(context->CLAMP.MINV, th - 1); - m_env.t.max.u16[4] = std::min(context->CLAMP.MAXV, th - 1); // ffx anima summon scene, when the anchor appears (th = 256, maxv > 256) - m_env.t.mask.u32[2] = 0; - break; - case CLAMP_REGION_REPEAT: - m_env.t.min.u16[4] = context->CLAMP.MINV; - m_env.t.max.u16[4] = context->CLAMP.MAXV; - m_env.t.mask.u32[2] = 0xffffffff; - break; - default: - __assume(0); - } - - m_env.t.min = m_env.t.min.xxxxlh(); - m_env.t.max = m_env.t.max.xxxxlh(); - m_env.t.mask = m_env.t.mask.xxzz(); - m_env.t.invmask = ~m_env.t.mask; - } - - // - - m_ds = m_ds_map[m_sel]; - - if(m_sel.aa1)// && (m_state->m_perfmon.GetFrame() & 0x40)) + if(m_local.gd->sel.aa1)// && (m_state->m_perfmon.GetFrame() & 0x40)) { GSScanlineSelector sel; - sel.key = m_sel.key; + sel.key = m_local.gd->sel.key; sel.zwrite = 0; sel.edge = 1; @@ -179,7 +55,7 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data) m_de = NULL; } - if(m_sel.IsSolidRect()) + if(m_local.gd->sel.IsSolidRect()) { m_dr = (DrawRectPtr)&GSDrawScanline::DrawRect; } @@ -194,22 +70,22 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data) sel.key = 0; - sel.iip = m_sel.iip; - sel.tfx = m_sel.tfx; - sel.tcc = m_sel.tcc; - sel.fst = m_sel.fst; - sel.fge = m_sel.fge; - sel.sprite = m_sel.sprite; - sel.fb = m_sel.fb; - sel.zb = m_sel.zb; - sel.zoverflow = m_sel.zoverflow; + sel.iip = m_local.gd->sel.iip; + sel.tfx = m_local.gd->sel.tfx; + sel.tcc = m_local.gd->sel.tcc; + sel.fst = m_local.gd->sel.fst; + sel.fge = m_local.gd->sel.fge; + sel.sprite = m_local.gd->sel.sprite; + sel.fb = m_local.gd->sel.fb; + sel.zb = m_local.gd->sel.zb; + sel.zoverflow = m_local.gd->sel.zoverflow; m_sp = m_sp_map[sel]; } -void GSDrawScanline::EndDraw(const GSRasterizerStats& stats) +void GSDrawScanline::EndDraw(const GSRasterizerStats& stats, uint64 frame) { - m_ds_map.UpdateStats(stats, m_state->m_perfmon.GetFrame()); + m_ds_map.UpdateStats(stats, frame); } void GSDrawScanline::DrawRect(const GSVector4i& r, const GSVertexSW& v) @@ -221,56 +97,62 @@ void GSDrawScanline::DrawRect(const GSVector4i& r, const GSVertexSW& v) uint32 m; - m = m_env.zm.u32[0]; + m = m_local.gd->zm.u32[0]; if(m != 0xffffffff) { + const int* zbr = m_local.gd->zbr; + const int* zbc = m_local.gd->zbc; + uint32 z = (uint32)v.p.z; - if(m_sel.zpsm != 2) + if(m_local.gd->sel.zpsm != 2) { if(m == 0) { - DrawRectT(m_env.zbr, m_env.zbc, r, z, m); + DrawRectT(zbr, zbc, r, z, m); } else { - DrawRectT(m_env.zbr, m_env.zbc, r, z, m); + DrawRectT(zbr, zbc, r, z, m); } } else { if(m == 0) { - DrawRectT(m_env.zbr, m_env.zbc, r, z, m); + DrawRectT(zbr, zbc, r, z, m); } else { - DrawRectT(m_env.zbr, m_env.zbc, r, z, m); + DrawRectT(zbr, zbc, r, z, m); } } } - m = m_env.fm.u32[0]; + m = m_local.gd->fm.u32[0]; if(m != 0xffffffff) { + const int* fbr = m_local.gd->fbr; + const int* fbc = m_local.gd->fbc; + uint32 c = (GSVector4i(v.c) >> 7).rgba32(); - if(m_state->m_context->FBA.FBA) + if(m_local.gd->sel.fba) { c |= 0x80000000; } - if(m_sel.fpsm != 2) + if(m_local.gd->sel.fpsm != 2) { if(m == 0) { - DrawRectT(m_env.fbr, m_env.fbc, r, c, m); + DrawRectT(fbr, fbc, r, c, m); } else { - DrawRectT(m_env.fbr, m_env.fbc, r, c, m); + DrawRectT(fbr, fbc, r, c, m); } } else @@ -279,11 +161,11 @@ void GSDrawScanline::DrawRect(const GSVector4i& r, const GSVertexSW& v) if(m == 0) { - DrawRectT(m_env.fbr, m_env.fbc, r, c, m); + DrawRectT(fbr, fbc, r, c, m); } else { - DrawRectT(m_env.fbr, m_env.fbc, r, c, m); + DrawRectT(fbr, fbc, r, c, m); } } } @@ -331,9 +213,11 @@ void GSDrawScanline::FillRect(const int* RESTRICT row, const int* RESTRICT col, { if(r.x >= r.z) return; + T* vm = (T*)m_local.gd->vm; + for(int y = r.y; y < r.w; y++) { - T* RESTRICT d = &((T*)m_env.vm)[row[y]]; + T* RESTRICT d = &vm[row[y]]; for(int x = r.x; x < r.z; x++) { @@ -347,9 +231,11 @@ void GSDrawScanline::FillBlock(const int* RESTRICT row, const int* RESTRICT col, { if(r.x >= r.z) return; + T* vm = (T*)m_local.gd->vm; + for(int y = r.y; y < r.w; y += 8) { - T* RESTRICT d = &((T*)m_env.vm)[row[y]]; + T* RESTRICT d = &vm[row[y]]; for(int x = r.x; x < r.z; x += 8 * 4 / sizeof(T)) { diff --git a/plugins/GSdx/GSDrawScanline.h b/plugins/GSdx/GSDrawScanline.h index accacb1451..7a849198fe 100644 --- a/plugins/GSdx/GSDrawScanline.h +++ b/plugins/GSdx/GSDrawScanline.h @@ -29,8 +29,7 @@ class GSDrawScanline : public IDrawScanline { - GSScanlineEnvironment m_env; - GSScanlineSelector m_sel; + GSScanlineLocalData m_local; GSCodeGeneratorFunctionMap m_sp_map; GSCodeGeneratorFunctionMap m_ds_map; @@ -46,17 +45,13 @@ class GSDrawScanline : public IDrawScanline template __forceinline void FillBlock(const int* RESTRICT row, const int* RESTRICT col, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m); -protected: - GSState* m_state; - int m_id; - public: - GSDrawScanline(GSState* state, int id); + GSDrawScanline(GSScanlineGlobalData* gd); virtual ~GSDrawScanline(); // IDrawScanline void BeginDraw(const GSRasterizerData* data); - void EndDraw(const GSRasterizerStats& stats); + void EndDraw(const GSRasterizerStats& stats, uint64 frame); void PrintStats() {m_ds_map.PrintStats();} }; diff --git a/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp b/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp index 6711b78f55..4fcafea51e 100644 --- a/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp +++ b/plugins/GSdx/GSDrawScanlineCodeGenerator.cpp @@ -25,9 +25,13 @@ #include "StdAfx.h" #include "GSDrawScanlineCodeGenerator.h" +static const int _args = 16; +static const int _top = _args + 4; +static const int _v = _args + 8; + GSDrawScanlineCodeGenerator::GSDrawScanlineCodeGenerator(void* param, uint64 key, void* code, size_t maxsize) : GSCodeGenerator(code, maxsize) - , m_env(*(GSScanlineEnvironment*)param) + , m_local(*(GSScanlineLocalData*)param) { #if _M_AMD64 #error TODO @@ -47,9 +51,7 @@ void GSDrawScanlineCodeGenerator::Generate() push(edi); push(ebp); - const int params = 16; - - Init(params); + Init(); if(!m_sel.edge) { @@ -222,7 +224,7 @@ L("loop"); // xmm5 = rb // xmm6 = ga - WriteFrame(params); + WriteFrame(); L("step"); @@ -251,11 +253,8 @@ L("exit"); ret(8); } -void GSDrawScanlineCodeGenerator::Init(int params) +void GSDrawScanlineCodeGenerator::Init() { - const int _top = params + 4; - const int _v = params + 8; - // int skip = left & 3; mov(ebx, edx); @@ -285,23 +284,23 @@ void GSDrawScanlineCodeGenerator::Init(int params) vpor(xmm7, ptr[eax + (size_t)&m_test[7]]); - // GSVector2i* fza_base = &m_env.fzbr[top]; + // GSVector2i* fza_base = &m_local.gd->fzbr[top]; mov(esi, dword[esp + _top]); lea(esi, ptr[esi * 8]); - add(esi, dword[&m_env.fzbr]); + add(esi, dword[&m_local.gd->fzbr]); - // GSVector2i* fza_offset = &m_env.fzbc[left >> 2]; + // GSVector2i* fza_offset = &m_local.gd->fzbc[left >> 2]; lea(edi, ptr[ebx * 2]); - add(edi, dword[&m_env.fzbc]); + add(edi, dword[&m_local.gd->fzbc]); if(!m_sel.sprite && (m_sel.fwrite && m_sel.fge || m_sel.zb) || m_sel.fb && (m_sel.edge || m_sel.tfx != TFX_NONE || m_sel.iip)) { - // edx = &m_env.d[skip] + // edx = &m_local.d[skip] shl(edx, 4); - lea(edx, ptr[edx + (size_t)m_env.d]); + lea(edx, ptr[edx + (size_t)m_local.d]); // ebx = &v @@ -316,24 +315,24 @@ void GSDrawScanlineCodeGenerator::Init(int params) if(m_sel.fwrite && m_sel.fge) { - // f = GSVector4i(vp).zzzzh().zzzz().add16(m_env.d[skip].f); + // f = GSVector4i(vp).zzzzh().zzzz().add16(m_local.d[skip].f); vcvttps2dq(xmm1, xmm0); vpshufhw(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); vpshufd(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); vpaddw(xmm1, ptr[edx + 16 * 6]); - vmovdqa(ptr[&m_env.temp.f], xmm1); + vmovdqa(ptr[&m_local.temp.f], xmm1); } if(m_sel.zb) { - // z = vp.zzzz() + m_env.d[skip].z; + // z = vp.zzzz() + m_local.d[skip].z; vshufps(xmm0, xmm0, _MM_SHUFFLE(2, 2, 2, 2)); vaddps(xmm0, ptr[edx]); - vmovaps(ptr[&m_env.temp.z], xmm0); + vmovaps(ptr[&m_local.temp.z], xmm0); } } } @@ -341,7 +340,7 @@ void GSDrawScanlineCodeGenerator::Init(int params) { if(m_sel.ztest) { - vmovdqa(xmm0, ptr[&m_env.p.z]); + vmovdqa(xmm0, ptr[&m_local.p.z]); } } @@ -358,7 +357,7 @@ void GSDrawScanlineCodeGenerator::Init(int params) vpshufd(xmm3, xmm3, _MM_SHUFFLE(3, 3, 3, 3)); vpsrlw(xmm3, 9); - vmovdqa(ptr[&m_env.temp.cov], xmm3); + vmovdqa(ptr[&m_local.temp.cov], xmm3); } if(m_sel.tfx != TFX_NONE) @@ -369,8 +368,8 @@ void GSDrawScanlineCodeGenerator::Init(int params) vcvttps2dq(xmm4, xmm4); - // si = vti.xxxx() + m_env.d[skip].si; - // ti = vti.yyyy(); if(!sprite) ti += m_env.d[skip].ti; + // si = vti.xxxx() + m_local.d[skip].si; + // ti = vti.yyyy(); if(!sprite) ti += m_local.d[skip].ti; vpshufd(xmm2, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); vpshufd(xmm3, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); @@ -388,18 +387,18 @@ void GSDrawScanlineCodeGenerator::Init(int params) vpshuflw(xmm4, xmm3, _MM_SHUFFLE(2, 2, 0, 0)); vpshufhw(xmm4, xmm4, _MM_SHUFFLE(2, 2, 0, 0)); vpsrlw(xmm4, 1); - vmovdqa(ptr[&m_env.temp.vf], xmm4); + vmovdqa(ptr[&m_local.temp.vf], xmm4); } } - vmovdqa(ptr[&m_env.temp.s], xmm2); - vmovdqa(ptr[&m_env.temp.t], xmm3); + vmovdqa(ptr[&m_local.temp.s], xmm2); + vmovdqa(ptr[&m_local.temp.t], xmm3); } else { - // s = vt.xxxx() + m_env.d[skip].s; - // t = vt.yyyy() + m_env.d[skip].t; - // q = vt.zzzz() + m_env.d[skip].q; + // s = vt.xxxx() + m_local.d[skip].s; + // t = vt.yyyy() + m_local.d[skip].t; + // q = vt.zzzz() + m_local.d[skip].q; vshufps(xmm2, xmm4, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); vshufps(xmm3, xmm4, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); @@ -409,9 +408,9 @@ void GSDrawScanlineCodeGenerator::Init(int params) vaddps(xmm3, ptr[edx + 16 * 2]); vaddps(xmm4, ptr[edx + 16 * 3]); - vmovaps(ptr[&m_env.temp.s], xmm2); - vmovaps(ptr[&m_env.temp.t], xmm3); - vmovaps(ptr[&m_env.temp.q], xmm4); + vmovaps(ptr[&m_local.temp.s], xmm2); + vmovaps(ptr[&m_local.temp.t], xmm3); + vmovaps(ptr[&m_local.temp.q], xmm4); vrcpps(xmm4, xmm4); vmulps(xmm2, xmm4); @@ -432,8 +431,8 @@ void GSDrawScanlineCodeGenerator::Init(int params) vpshufd(xmm5, xmm6, _MM_SHUFFLE(1, 0, 3, 2)); vpunpcklwd(xmm6, xmm5); - // rb = vc.xxxx().add16(m_env.d[skip].rb); - // ga = vc.zzzz().add16(m_env.d[skip].ga); + // rb = vc.xxxx().add16(m_local.d[skip].rb); + // ga = vc.zzzz().add16(m_local.d[skip].ga); vpshufd(xmm5, xmm6, _MM_SHUFFLE(0, 0, 0, 0)); vpshufd(xmm6, xmm6, _MM_SHUFFLE(2, 2, 2, 2)); @@ -441,15 +440,15 @@ void GSDrawScanlineCodeGenerator::Init(int params) vpaddw(xmm5, ptr[edx + 16 * 4]); vpaddw(xmm6, ptr[edx + 16 * 5]); - vmovdqa(ptr[&m_env.temp.rb], xmm5); - vmovdqa(ptr[&m_env.temp.ga], xmm6); + vmovdqa(ptr[&m_local.temp.rb], xmm5); + vmovdqa(ptr[&m_local.temp.ga], xmm6); } else { if(m_sel.tfx == TFX_NONE) { - vmovdqa(xmm5, ptr[&m_env.c.rb]); - vmovdqa(xmm6, ptr[&m_env.c.ga]); + vmovdqa(xmm5, ptr[&m_local.c.rb]); + vmovdqa(xmm6, ptr[&m_local.c.ga]); } } } @@ -470,23 +469,23 @@ void GSDrawScanlineCodeGenerator::Init(int params) por(xmm7, ptr[eax + (size_t)&m_test[7]]); - // GSVector2i* fza_base = &m_env.fzbr[top]; + // GSVector2i* fza_base = &m_local.gd->fzbr[top]; mov(esi, dword[esp + _top]); lea(esi, ptr[esi * 8]); - add(esi, dword[&m_env.fzbr]); + add(esi, dword[&m_local.gd->fzbr]); - // GSVector2i* fza_offset = &m_env.fzbc[left >> 2]; + // GSVector2i* fza_offset = &m_local.gd->fzbc[left >> 2]; lea(edi, ptr[ebx * 2]); - add(edi, dword[&m_env.fzbc]); + add(edi, dword[&m_local.gd->fzbc]); if(!m_sel.sprite && (m_sel.fwrite && m_sel.fge || m_sel.zb) || m_sel.fb && (m_sel.edge || m_sel.tfx != TFX_NONE || m_sel.iip)) { - // edx = &m_env.d[skip] + // edx = &m_local.d[skip] shl(edx, 4); - lea(edx, ptr[edx + (size_t)m_env.d]); + lea(edx, ptr[edx + (size_t)m_local.d]); // ebx = &v @@ -501,24 +500,24 @@ void GSDrawScanlineCodeGenerator::Init(int params) if(m_sel.fwrite && m_sel.fge) { - // f = GSVector4i(vp).zzzzh().zzzz().add16(m_env.d[skip].f); + // f = GSVector4i(vp).zzzzh().zzzz().add16(m_local.d[skip].f); cvttps2dq(xmm1, xmm0); pshufhw(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); pshufd(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); paddw(xmm1, ptr[edx + 16 * 6]); - movdqa(ptr[&m_env.temp.f], xmm1); + movdqa(ptr[&m_local.temp.f], xmm1); } if(m_sel.zb) { - // z = vp.zzzz() + m_env.d[skip].z; + // z = vp.zzzz() + m_local.d[skip].z; shufps(xmm0, xmm0, _MM_SHUFFLE(2, 2, 2, 2)); addps(xmm0, ptr[edx]); - movaps(ptr[&m_env.temp.z], xmm0); + movaps(ptr[&m_local.temp.z], xmm0); } } } @@ -526,7 +525,7 @@ void GSDrawScanlineCodeGenerator::Init(int params) { if(m_sel.ztest) { - movdqa(xmm0, ptr[&m_env.p.z]); + movdqa(xmm0, ptr[&m_local.p.z]); } } @@ -543,7 +542,7 @@ void GSDrawScanlineCodeGenerator::Init(int params) pshufd(xmm3, xmm3, _MM_SHUFFLE(3, 3, 3, 3)); psrlw(xmm3, 9); - movdqa(ptr[&m_env.temp.cov], xmm3); + movdqa(ptr[&m_local.temp.cov], xmm3); } if(m_sel.tfx != TFX_NONE) @@ -554,8 +553,8 @@ void GSDrawScanlineCodeGenerator::Init(int params) cvttps2dq(xmm4, xmm4); - // si = vti.xxxx() + m_env.d[skip].si; - // ti = vti.yyyy(); if(!sprite) ti += m_env.d[skip].ti; + // si = vti.xxxx() + m_local.d[skip].si; + // ti = vti.yyyy(); if(!sprite) ti += m_local.d[skip].ti; pshufd(xmm2, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm3, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); @@ -574,18 +573,18 @@ void GSDrawScanlineCodeGenerator::Init(int params) pshuflw(xmm4, xmm4, _MM_SHUFFLE(2, 2, 0, 0)); pshufhw(xmm4, xmm4, _MM_SHUFFLE(2, 2, 0, 0)); psrlw(xmm4, 1); - movdqa(ptr[&m_env.temp.vf], xmm4); + movdqa(ptr[&m_local.temp.vf], xmm4); } } - movdqa(ptr[&m_env.temp.s], xmm2); - movdqa(ptr[&m_env.temp.t], xmm3); + movdqa(ptr[&m_local.temp.s], xmm2); + movdqa(ptr[&m_local.temp.t], xmm3); } else { - // s = vt.xxxx() + m_env.d[skip].s; - // t = vt.yyyy() + m_env.d[skip].t; - // q = vt.zzzz() + m_env.d[skip].q; + // s = vt.xxxx() + m_local.d[skip].s; + // t = vt.yyyy() + m_local.d[skip].t; + // q = vt.zzzz() + m_local.d[skip].q; movaps(xmm2, xmm4); movaps(xmm3, xmm4); @@ -598,9 +597,9 @@ void GSDrawScanlineCodeGenerator::Init(int params) addps(xmm3, ptr[edx + 16 * 2]); addps(xmm4, ptr[edx + 16 * 3]); - movaps(ptr[&m_env.temp.s], xmm2); - movaps(ptr[&m_env.temp.t], xmm3); - movaps(ptr[&m_env.temp.q], xmm4); + movaps(ptr[&m_local.temp.s], xmm2); + movaps(ptr[&m_local.temp.t], xmm3); + movaps(ptr[&m_local.temp.q], xmm4); rcpps(xmm4, xmm4); mulps(xmm2, xmm4); @@ -621,8 +620,8 @@ void GSDrawScanlineCodeGenerator::Init(int params) pshufd(xmm5, xmm6, _MM_SHUFFLE(1, 0, 3, 2)); punpcklwd(xmm6, xmm5); - // rb = vc.xxxx().add16(m_env.d[skip].rb); - // ga = vc.zzzz().add16(m_env.d[skip].ga); + // rb = vc.xxxx().add16(m_local.d[skip].rb); + // ga = vc.zzzz().add16(m_local.d[skip].ga); pshufd(xmm5, xmm6, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm6, xmm6, _MM_SHUFFLE(2, 2, 2, 2)); @@ -630,15 +629,15 @@ void GSDrawScanlineCodeGenerator::Init(int params) paddw(xmm5, ptr[edx + 16 * 4]); paddw(xmm6, ptr[edx + 16 * 5]); - movdqa(ptr[&m_env.temp.rb], xmm5); - movdqa(ptr[&m_env.temp.ga], xmm6); + movdqa(ptr[&m_local.temp.rb], xmm5); + movdqa(ptr[&m_local.temp.ga], xmm6); } else { if(m_sel.tfx == TFX_NONE) { - movdqa(xmm5, ptr[&m_env.c.rb]); - movdqa(xmm6, ptr[&m_env.c.ga]); + movdqa(xmm5, ptr[&m_local.c.rb]); + movdqa(xmm6, ptr[&m_local.c.ga]); } } } @@ -660,29 +659,29 @@ void GSDrawScanlineCodeGenerator::Step() { if(!m_sel.sprite) { - // z += m_env.d4.z; + // z += m_local.d4.z; if(m_sel.zb) { - vmovaps(xmm0, ptr[&m_env.temp.z]); - vaddps(xmm0, ptr[&m_env.d4.z]); - vmovaps(ptr[&m_env.temp.z], xmm0); + vmovaps(xmm0, ptr[&m_local.temp.z]); + vaddps(xmm0, ptr[&m_local.d4.z]); + vmovaps(ptr[&m_local.temp.z], xmm0); } - // f = f.add16(m_env.d4.f); + // f = f.add16(m_local.d4.f); if(m_sel.fwrite && m_sel.fge) { - vmovdqa(xmm1, ptr[&m_env.temp.f]); - vpaddw(xmm1, ptr[&m_env.d4.f]); - vmovdqa(ptr[&m_env.temp.f], xmm1); + vmovdqa(xmm1, ptr[&m_local.temp.f]); + vpaddw(xmm1, ptr[&m_local.d4.f]); + vmovdqa(ptr[&m_local.temp.f], xmm1); } } else { if(m_sel.ztest) { - vmovdqa(xmm0, ptr[&m_env.p.z]); + vmovdqa(xmm0, ptr[&m_local.p.z]); } } @@ -692,49 +691,49 @@ void GSDrawScanlineCodeGenerator::Step() { if(m_sel.fst) { - // GSVector4i st = m_env.d4.st; + // GSVector4i st = m_local.d4.st; // si += st.xxxx(); // if(!sprite) ti += st.yyyy(); - vmovdqa(xmm4, ptr[&m_env.d4.st]); + vmovdqa(xmm4, ptr[&m_local.d4.st]); vpshufd(xmm2, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); - vpaddd(xmm2, ptr[&m_env.temp.s]); - vmovdqa(ptr[&m_env.temp.s], xmm2); + vpaddd(xmm2, ptr[&m_local.temp.s]); + vmovdqa(ptr[&m_local.temp.s], xmm2); if(!m_sel.sprite) { vpshufd(xmm3, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); - vpaddd(xmm3, ptr[&m_env.temp.t]); - vmovdqa(ptr[&m_env.temp.t], xmm3); + vpaddd(xmm3, ptr[&m_local.temp.t]); + vmovdqa(ptr[&m_local.temp.t], xmm3); } else { - vmovdqa(xmm3, ptr[&m_env.temp.t]); + vmovdqa(xmm3, ptr[&m_local.temp.t]); } } else { - // GSVector4 stq = m_env.d4.stq; + // GSVector4 stq = m_local.d4.stq; // s += stq.xxxx(); // t += stq.yyyy(); // q += stq.zzzz(); - vmovaps(xmm4, ptr[&m_env.d4.stq]); + vmovaps(xmm4, ptr[&m_local.d4.stq]); vshufps(xmm2, xmm4, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); vshufps(xmm3, xmm4, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); vshufps(xmm4, xmm4, xmm4, _MM_SHUFFLE(2, 2, 2, 2)); - vaddps(xmm2, ptr[&m_env.temp.s]); - vaddps(xmm3, ptr[&m_env.temp.t]); - vaddps(xmm4, ptr[&m_env.temp.q]); + vaddps(xmm2, ptr[&m_local.temp.s]); + vaddps(xmm3, ptr[&m_local.temp.t]); + vaddps(xmm4, ptr[&m_local.temp.q]); - vmovaps(ptr[&m_env.temp.s], xmm2); - vmovaps(ptr[&m_env.temp.t], xmm3); - vmovaps(ptr[&m_env.temp.q], xmm4); + vmovaps(ptr[&m_local.temp.s], xmm2); + vmovaps(ptr[&m_local.temp.t], xmm3); + vmovaps(ptr[&m_local.temp.q], xmm4); vrcpps(xmm4, xmm4); vmulps(xmm2, xmm4); @@ -746,28 +745,28 @@ void GSDrawScanlineCodeGenerator::Step() { if(m_sel.iip) { - // GSVector4i c = m_env.d4.c; + // GSVector4i c = m_local.d4.c; // rb = rb.add16(c.xxxx()); // ga = ga.add16(c.yyyy()); - vmovdqa(xmm7, ptr[&m_env.d4.c]); + vmovdqa(xmm7, ptr[&m_local.d4.c]); vpshufd(xmm5, xmm7, _MM_SHUFFLE(0, 0, 0, 0)); vpshufd(xmm6, xmm7, _MM_SHUFFLE(1, 1, 1, 1)); - vpaddw(xmm5, ptr[&m_env.temp.rb]); - vpaddw(xmm6, ptr[&m_env.temp.ga]); + vpaddw(xmm5, ptr[&m_local.temp.rb]); + vpaddw(xmm6, ptr[&m_local.temp.ga]); - vmovdqa(ptr[&m_env.temp.rb], xmm5); - vmovdqa(ptr[&m_env.temp.ga], xmm6); + vmovdqa(ptr[&m_local.temp.rb], xmm5); + vmovdqa(ptr[&m_local.temp.ga], xmm6); } else { if(m_sel.tfx == TFX_NONE) { - vmovdqa(xmm5, ptr[&m_env.c.rb]); - vmovdqa(xmm6, ptr[&m_env.c.ga]); + vmovdqa(xmm5, ptr[&m_local.c.rb]); + vmovdqa(xmm6, ptr[&m_local.c.ga]); } } } @@ -786,29 +785,29 @@ void GSDrawScanlineCodeGenerator::Step() { if(!m_sel.sprite) { - // z += m_env.d4.z; + // z += m_local.d4.z; if(m_sel.zb) { - movaps(xmm0, ptr[&m_env.temp.z]); - addps(xmm0, ptr[&m_env.d4.z]); - movaps(ptr[&m_env.temp.z], xmm0); + movaps(xmm0, ptr[&m_local.temp.z]); + addps(xmm0, ptr[&m_local.d4.z]); + movaps(ptr[&m_local.temp.z], xmm0); } - // f = f.add16(m_env.d4.f); + // f = f.add16(m_local.d4.f); if(m_sel.fwrite && m_sel.fge) { - movdqa(xmm1, ptr[&m_env.temp.f]); - paddw(xmm1, ptr[&m_env.d4.f]); - movdqa(ptr[&m_env.temp.f], xmm1); + movdqa(xmm1, ptr[&m_local.temp.f]); + paddw(xmm1, ptr[&m_local.d4.f]); + movdqa(ptr[&m_local.temp.f], xmm1); } } else { if(m_sel.ztest) { - movdqa(xmm0, ptr[&m_env.p.z]); + movdqa(xmm0, ptr[&m_local.p.z]); } } @@ -818,37 +817,37 @@ void GSDrawScanlineCodeGenerator::Step() { if(m_sel.fst) { - // GSVector4i st = m_env.d4.st; + // GSVector4i st = m_local.d4.st; // si += st.xxxx(); // if(!sprite) ti += st.yyyy(); - movdqa(xmm4, ptr[&m_env.d4.st]); + movdqa(xmm4, ptr[&m_local.d4.st]); pshufd(xmm2, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); - paddd(xmm2, ptr[&m_env.temp.s]); - movdqa(ptr[&m_env.temp.s], xmm2); + paddd(xmm2, ptr[&m_local.temp.s]); + movdqa(ptr[&m_local.temp.s], xmm2); if(!m_sel.sprite) { pshufd(xmm3, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); - paddd(xmm3, ptr[&m_env.temp.t]); - movdqa(ptr[&m_env.temp.t], xmm3); + paddd(xmm3, ptr[&m_local.temp.t]); + movdqa(ptr[&m_local.temp.t], xmm3); } else { - movdqa(xmm3, ptr[&m_env.temp.t]); + movdqa(xmm3, ptr[&m_local.temp.t]); } } else { - // GSVector4 stq = m_env.d4.stq; + // GSVector4 stq = m_local.d4.stq; // s += stq.xxxx(); // t += stq.yyyy(); // q += stq.zzzz(); - movaps(xmm2, ptr[&m_env.d4.stq]); + movaps(xmm2, ptr[&m_local.d4.stq]); movaps(xmm3, xmm2); movaps(xmm4, xmm2); @@ -856,13 +855,13 @@ void GSDrawScanlineCodeGenerator::Step() shufps(xmm3, xmm3, _MM_SHUFFLE(1, 1, 1, 1)); shufps(xmm4, xmm4, _MM_SHUFFLE(2, 2, 2, 2)); - addps(xmm2, ptr[&m_env.temp.s]); - addps(xmm3, ptr[&m_env.temp.t]); - addps(xmm4, ptr[&m_env.temp.q]); + addps(xmm2, ptr[&m_local.temp.s]); + addps(xmm3, ptr[&m_local.temp.t]); + addps(xmm4, ptr[&m_local.temp.q]); - movaps(ptr[&m_env.temp.s], xmm2); - movaps(ptr[&m_env.temp.t], xmm3); - movaps(ptr[&m_env.temp.q], xmm4); + movaps(ptr[&m_local.temp.s], xmm2); + movaps(ptr[&m_local.temp.t], xmm3); + movaps(ptr[&m_local.temp.q], xmm4); rcpps(xmm4, xmm4); mulps(xmm2, xmm4); @@ -874,28 +873,28 @@ void GSDrawScanlineCodeGenerator::Step() { if(m_sel.iip) { - // GSVector4i c = m_env.d4.c; + // GSVector4i c = m_local.d4.c; // rb = rb.add16(c.xxxx()); // ga = ga.add16(c.yyyy()); - movdqa(xmm7, ptr[&m_env.d4.c]); + movdqa(xmm7, ptr[&m_local.d4.c]); pshufd(xmm5, xmm7, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm6, xmm7, _MM_SHUFFLE(1, 1, 1, 1)); - paddw(xmm5, ptr[&m_env.temp.rb]); - paddw(xmm6, ptr[&m_env.temp.ga]); + paddw(xmm5, ptr[&m_local.temp.rb]); + paddw(xmm6, ptr[&m_local.temp.ga]); - movdqa(ptr[&m_env.temp.rb], xmm5); - movdqa(ptr[&m_env.temp.ga], xmm6); + movdqa(ptr[&m_local.temp.rb], xmm5); + movdqa(ptr[&m_local.temp.ga], xmm6); } else { if(m_sel.tfx == TFX_NONE) { - movdqa(xmm5, ptr[&m_env.c.rb]); - movdqa(xmm6, ptr[&m_env.c.ga]); + movdqa(xmm5, ptr[&m_local.c.rb]); + movdqa(xmm6, ptr[&m_local.c.ga]); } } } @@ -957,7 +956,7 @@ void GSDrawScanlineCodeGenerator::TestZ(const Xmm& temp1, const Xmm& temp2) if(m_sel.zwrite) { - vmovdqa(ptr[&m_env.temp.zs], xmm0); + vmovdqa(ptr[&m_local.temp.zs], xmm0); } } @@ -967,7 +966,7 @@ void GSDrawScanlineCodeGenerator::TestZ(const Xmm& temp1, const Xmm& temp2) if(m_sel.zwrite && m_sel.zpsm < 2) { - vmovdqa(ptr[&m_env.temp.zd], xmm1); + vmovdqa(ptr[&m_local.temp.zd], xmm1); } // zd &= 0xffffffff >> m_sel.zpsm * 8; @@ -1048,7 +1047,7 @@ void GSDrawScanlineCodeGenerator::TestZ(const Xmm& temp1, const Xmm& temp2) if(m_sel.zwrite) { - movdqa(ptr[&m_env.temp.zs], xmm0); + movdqa(ptr[&m_local.temp.zs], xmm0); } } @@ -1058,7 +1057,7 @@ void GSDrawScanlineCodeGenerator::TestZ(const Xmm& temp1, const Xmm& temp2) if(m_sel.zwrite && m_sel.zpsm < 2) { - movdqa(ptr[&m_env.temp.zd], xmm1); + movdqa(ptr[&m_local.temp.zd], xmm1); } // zd &= 0xffffffff >> m_sel.zpsm * 8; @@ -1114,7 +1113,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() return; } - mov(ebx, dword[&m_env.tex]); + mov(ebx, dword[&m_local.gd->tex]); // ebx = tex @@ -1151,7 +1150,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() vpshuflw(xmm0, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); vpshufhw(xmm0, xmm0, _MM_SHUFFLE(2, 2, 0, 0)); vpsrlw(xmm0, 1); - vmovdqa(ptr[&m_env.temp.uf], xmm0); + vmovdqa(ptr[&m_local.temp.uf], xmm0); if(!m_sel.sprite) { @@ -1160,7 +1159,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() vpshuflw(xmm1, xmm3, _MM_SHUFFLE(2, 2, 0, 0)); vpshufhw(xmm1, xmm1, _MM_SHUFFLE(2, 2, 0, 0)); vpsrlw(xmm1, 1); - vmovdqa(ptr[&m_env.temp.vf], xmm1); + vmovdqa(ptr[&m_local.temp.vf], xmm1); } } @@ -1270,7 +1269,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() // xmm0, xmm2, xmm3 = free // xmm7 = used - vmovdqa(xmm0, ptr[&m_env.temp.uf]); + vmovdqa(xmm0, ptr[&m_local.temp.uf]); // GSVector4i rb00 = c00 & mask; // GSVector4i ga00 = (c00 >> 8) & mask; @@ -1348,7 +1347,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() // rb00 = rb00.lerp16<0>(rb10, vf); // ga00 = ga00.lerp16<0>(ga10, vf); - vmovdqa(xmm0, ptr[&m_env.temp.vf]); + vmovdqa(xmm0, ptr[&m_local.temp.vf]); lerp16<0>(xmm5, xmm3, xmm0); lerp16<0>(xmm6, xmm4, xmm0); @@ -1407,7 +1406,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() pshuflw(xmm0, xmm0, _MM_SHUFFLE(2, 2, 0, 0)); pshufhw(xmm0, xmm0, _MM_SHUFFLE(2, 2, 0, 0)); psrlw(xmm0, 1); - movdqa(ptr[&m_env.temp.uf], xmm0); + movdqa(ptr[&m_local.temp.uf], xmm0); if(!m_sel.sprite) { @@ -1417,7 +1416,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() pshuflw(xmm1, xmm1, _MM_SHUFFLE(2, 2, 0, 0)); pshufhw(xmm1, xmm1, _MM_SHUFFLE(2, 2, 0, 0)); psrlw(xmm1, 1); - movdqa(ptr[&m_env.temp.vf], xmm1); + movdqa(ptr[&m_local.temp.vf], xmm1); } } @@ -1533,7 +1532,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() // xmm0, xmm2, xmm3 = free // xmm7 = used - movdqa(xmm0, ptr[&m_env.temp.uf]); + movdqa(xmm0, ptr[&m_local.temp.uf]); // GSVector4i rb00 = c00 & mask; // GSVector4i ga00 = (c00 >> 8) & mask; @@ -1615,7 +1614,7 @@ void GSDrawScanlineCodeGenerator::SampleTexture() // rb00 = rb00.lerp16<0>(rb10, vf); // ga00 = ga00.lerp16<0>(ga10, vf); - movdqa(xmm0, ptr[&m_env.temp.vf]); + movdqa(xmm0, ptr[&m_local.temp.vf]); lerp16<0>(xmm5, xmm3, xmm0); lerp16<0>(xmm6, xmm4, xmm0); @@ -1661,7 +1660,7 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv) { if(region) { - vpmaxsw(uv, ptr[&m_env.t.min]); + vpmaxsw(uv, ptr[&m_local.gd->t.min]); } else { @@ -1669,15 +1668,15 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv) vpmaxsw(uv, xmm0); } - vpminsw(uv, ptr[&m_env.t.max]); + vpminsw(uv, ptr[&m_local.gd->t.max]); } else { - vpand(uv, ptr[&m_env.t.min]); + vpand(uv, ptr[&m_local.gd->t.min]); if(region) { - vpor(uv, ptr[&m_env.t.max]); + vpor(uv, ptr[&m_local.gd->t.max]); } } } @@ -1685,15 +1684,15 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv) { vmovdqa(xmm1, uv); - vmovdqa(xmm4, ptr[&m_env.t.min]); - vmovdqa(xmm5, ptr[&m_env.t.max]); + vmovdqa(xmm4, ptr[&m_local.gd->t.min]); + vmovdqa(xmm5, ptr[&m_local.gd->t.max]); - // GSVector4i clamp = t.sat_i16(m_env.t.min, m_env.t.max); + // GSVector4i clamp = t.sat_i16(m_local.gd->t.min, m_local.gd->t.max); vpmaxsw(uv, xmm4); vpminsw(uv, xmm5); - // GSVector4i repeat = (t & m_env.t.min) | m_env.t.max; + // GSVector4i repeat = (t & m_local.gd->t.min) | m_local.gd->t.max; vpand(xmm1, xmm4); @@ -1702,9 +1701,9 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv) vpor(xmm1, xmm5); } - // clamp.blend8(repeat, m_env.t.mask); + // clamp.blend8(repeat, m_local.gd->t.mask); - vmovdqa(xmm0, ptr[&m_env.t.mask]); + vmovdqa(xmm0, ptr[&m_local.gd->t.mask]); vpblendvb(uv, xmm1, xmm0); } @@ -1717,7 +1716,7 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv) { if(region) { - pmaxsw(uv, ptr[&m_env.t.min]); + pmaxsw(uv, ptr[&m_local.gd->t.min]); } else { @@ -1725,15 +1724,15 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv) pmaxsw(uv, xmm0); } - pminsw(uv, ptr[&m_env.t.max]); + pminsw(uv, ptr[&m_local.gd->t.max]); } else { - pand(uv, ptr[&m_env.t.min]); + pand(uv, ptr[&m_local.gd->t.min]); if(region) { - por(uv, ptr[&m_env.t.max]); + por(uv, ptr[&m_local.gd->t.max]); } } } @@ -1741,15 +1740,15 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv) { movdqa(xmm1, uv); - movdqa(xmm4, ptr[&m_env.t.min]); - movdqa(xmm5, ptr[&m_env.t.max]); + movdqa(xmm4, ptr[&m_local.gd->t.min]); + movdqa(xmm5, ptr[&m_local.gd->t.max]); - // GSVector4i clamp = t.sat_i16(m_env.t.min, m_env.t.max); + // GSVector4i clamp = t.sat_i16(m_local.gd->t.min, m_local.gd->t.max); pmaxsw(uv, xmm4); pminsw(uv, xmm5); - // GSVector4i repeat = (t & m_env.t.min) | m_env.t.max; + // GSVector4i repeat = (t & m_local.gd->t.min) | m_local.gd->t.max; pand(xmm1, xmm4); @@ -1758,9 +1757,9 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv) por(xmm1, xmm5); } - // clamp.blend8(repeat, m_env.t.mask); + // clamp.blend8(repeat, m_local.gd->t.mask); - movdqa(xmm0, ptr[&m_env.t.mask]); + movdqa(xmm0, ptr[&m_local.gd->t.mask]); blend8(uv, xmm1); } } @@ -1783,7 +1782,7 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv0, const Xmm& uv1) { if(region) { - vmovdqa(xmm4, ptr[&m_env.t.min]); + vmovdqa(xmm4, ptr[&m_local.gd->t.min]); vpmaxsw(uv0, xmm4); vpmaxsw(uv1, xmm4); @@ -1796,21 +1795,21 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv0, const Xmm& uv1) vpmaxsw(uv1, xmm0); } - vmovdqa(xmm5, ptr[&m_env.t.max]); + vmovdqa(xmm5, ptr[&m_local.gd->t.max]); vpminsw(uv0, xmm5); vpminsw(uv1, xmm5); } else { - vmovdqa(xmm4, ptr[&m_env.t.min]); + vmovdqa(xmm4, ptr[&m_local.gd->t.min]); vpand(uv0, xmm4); vpand(uv1, xmm4); if(region) { - vmovdqa(xmm5, ptr[&m_env.t.max]); + vmovdqa(xmm5, ptr[&m_local.gd->t.max]); vpor(uv0, xmm5); vpor(uv1, xmm5); @@ -1822,17 +1821,17 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv0, const Xmm& uv1) vmovdqa(xmm1, uv0); vmovdqa(xmm6, uv1); - vmovdqa(xmm4, ptr[&m_env.t.min]); - vmovdqa(xmm5, ptr[&m_env.t.max]); + vmovdqa(xmm4, ptr[&m_local.gd->t.min]); + vmovdqa(xmm5, ptr[&m_local.gd->t.max]); - // GSVector4i clamp = t.sat_i16(m_env.t.min, m_env.t.max); + // GSVector4i clamp = t.sat_i16(m_local.gd->t.min, m_local.gd->t.max); vpmaxsw(uv0, xmm4); vpmaxsw(uv1, xmm4); vpminsw(uv0, xmm5); vpminsw(uv1, xmm5); - // GSVector4i repeat = (t & m_env.t.min) | m_env.t.max; + // GSVector4i repeat = (t & m_local.gd->t.min) | m_local.gd->t.max; vpand(xmm1, xmm4); vpand(xmm6, xmm4); @@ -1843,18 +1842,18 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv0, const Xmm& uv1) vpor(xmm6, xmm5); } - // clamp.blend8(repeat, m_env.t.mask); + // clamp.blend8(repeat, m_local.gd->t.mask); if(m_cpu.has(util::Cpu::tSSE41)) { - vmovdqa(xmm0, ptr[&m_env.t.mask]); + vmovdqa(xmm0, ptr[&m_local.gd->t.mask]); vpblendvb(uv0, xmm1, xmm0); vpblendvb(uv1, xmm6, xmm0); } else { - vmovdqa(xmm0, ptr[&m_env.t.invmask]); + vmovdqa(xmm0, ptr[&m_local.gd->t.invmask]); vmovdqa(xmm4, xmm0); vpand(uv0, xmm0); @@ -1875,7 +1874,7 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv0, const Xmm& uv1) { if(region) { - movdqa(xmm4, ptr[&m_env.t.min]); + movdqa(xmm4, ptr[&m_local.gd->t.min]); pmaxsw(uv0, xmm4); pmaxsw(uv1, xmm4); @@ -1887,21 +1886,21 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv0, const Xmm& uv1) pmaxsw(uv1, xmm0); } - movdqa(xmm5, ptr[&m_env.t.max]); + movdqa(xmm5, ptr[&m_local.gd->t.max]); pminsw(uv0, xmm5); pminsw(uv1, xmm5); } else { - movdqa(xmm4, ptr[&m_env.t.min]); + movdqa(xmm4, ptr[&m_local.gd->t.min]); pand(uv0, xmm4); pand(uv1, xmm4); if(region) { - movdqa(xmm5, ptr[&m_env.t.max]); + movdqa(xmm5, ptr[&m_local.gd->t.max]); por(uv0, xmm5); por(uv1, xmm5); @@ -1913,17 +1912,17 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv0, const Xmm& uv1) movdqa(xmm1, uv0); movdqa(xmm6, uv1); - movdqa(xmm4, ptr[&m_env.t.min]); - movdqa(xmm5, ptr[&m_env.t.max]); + movdqa(xmm4, ptr[&m_local.gd->t.min]); + movdqa(xmm5, ptr[&m_local.gd->t.max]); - // GSVector4i clamp = t.sat_i16(m_env.t.min, m_env.t.max); + // GSVector4i clamp = t.sat_i16(m_local.gd->t.min, m_local.gd->t.max); pmaxsw(uv0, xmm4); pmaxsw(uv1, xmm4); pminsw(uv0, xmm5); pminsw(uv1, xmm5); - // GSVector4i repeat = (t & m_env.t.min) | m_env.t.max; + // GSVector4i repeat = (t & m_local.gd->t.min) | m_local.gd->t.max; pand(xmm1, xmm4); pand(xmm6, xmm4); @@ -1934,18 +1933,18 @@ void GSDrawScanlineCodeGenerator::Wrap(const Xmm& uv0, const Xmm& uv1) por(xmm6, xmm5); } - // clamp.blend8(repeat, m_env.t.mask); + // clamp.blend8(repeat, m_local.gd->t.mask); if(m_cpu.has(util::Cpu::tSSE41)) { - movdqa(xmm0, ptr[&m_env.t.mask]); + movdqa(xmm0, ptr[&m_local.gd->t.mask]); pblendvb(uv0, xmm1); pblendvb(uv1, xmm6); } else { - movdqa(xmm0, ptr[&m_env.t.invmask]); + movdqa(xmm0, ptr[&m_local.gd->t.invmask]); movdqa(xmm4, xmm0); pand(uv0, xmm0); @@ -1973,9 +1972,9 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() { case TFX_MODULATE: - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - vmovdqa(xmm4, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + vmovdqa(xmm4, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); // gat = gat.modulate16<1>(ga).clamp8(); @@ -2000,9 +1999,9 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() if(!m_sel.tcc) { - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - vmovdqa(xmm4, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + vmovdqa(xmm4, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); vpsrlw(xmm4, 7); @@ -2013,9 +2012,9 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() case TFX_HIGHLIGHT: - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - vmovdqa(xmm4, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + vmovdqa(xmm4, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); vmovdqa(xmm2, xmm4); // gat = gat.mix16(!tcc ? ga.srl16(7) : gat.addus8(ga.srl16(7))); @@ -2037,9 +2036,9 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() if(!m_sel.tcc) { - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - vmovdqa(xmm4, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + vmovdqa(xmm4, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); vmovdqa(xmm2, xmm4); vpsrlw(xmm4, 7); @@ -2073,7 +2072,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() if(m_sel.edge) { - vmovdqa(xmm0, ptr[&m_env.temp.cov]); + vmovdqa(xmm0, ptr[&m_local.temp.cov]); } else { @@ -2094,7 +2093,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() if(m_sel.edge) { - vmovdqa(xmm1, ptr[&m_env.temp.cov]); + vmovdqa(xmm1, ptr[&m_local.temp.cov]); } else { @@ -2115,9 +2114,9 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() { case TFX_MODULATE: - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - movdqa(xmm4, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + movdqa(xmm4, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); // gat = gat.modulate16<1>(ga).clamp8(); @@ -2142,9 +2141,9 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() if(!m_sel.tcc) { - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - movdqa(xmm4, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + movdqa(xmm4, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); psrlw(xmm4, 7); @@ -2155,9 +2154,9 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() case TFX_HIGHLIGHT: - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - movdqa(xmm4, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + movdqa(xmm4, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); movdqa(xmm2, xmm4); // gat = gat.mix16(!tcc ? ga.srl16(7) : gat.addus8(ga.srl16(7))); @@ -2179,9 +2178,9 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() if(!m_sel.tcc) { - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - movdqa(xmm4, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + movdqa(xmm4, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); movdqa(xmm2, xmm4); psrlw(xmm4, 7); @@ -2215,7 +2214,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() if(m_sel.edge) { - movdqa(xmm0, ptr[&m_env.temp.cov]); + movdqa(xmm0, ptr[&m_local.temp.cov]); } else { @@ -2236,7 +2235,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX() if(m_sel.edge) { - movdqa(xmm1, ptr[&m_env.temp.cov]); + movdqa(xmm1, ptr[&m_local.temp.cov]); } else { @@ -2259,24 +2258,24 @@ void GSDrawScanlineCodeGenerator::ReadMask() { if(m_sel.fwrite) { - vmovdqa(xmm3, ptr[&m_env.fm]); + vmovdqa(xmm3, ptr[&m_local.gd->fm]); } if(m_sel.zwrite) { - vmovdqa(xmm4, ptr[&m_env.zm]); + vmovdqa(xmm4, ptr[&m_local.gd->zm]); } } else { if(m_sel.fwrite) { - movdqa(xmm3, ptr[&m_env.fm]); + movdqa(xmm3, ptr[&m_local.gd->fm]); } if(m_sel.zwrite) { - movdqa(xmm4, ptr[&m_env.zm]); + movdqa(xmm4, ptr[&m_local.gd->zm]); } } } @@ -2312,31 +2311,31 @@ void GSDrawScanlineCodeGenerator::TestAlpha() case ATST_LESS: case ATST_LEQUAL: - // t = (ga >> 16) > m_env.aref; + // t = (ga >> 16) > m_local.gd->aref; vpsrld(xmm1, xmm6, 16); - vpcmpgtd(xmm1, ptr[&m_env.aref]); + vpcmpgtd(xmm1, ptr[&m_local.gd->aref]); break; case ATST_EQUAL: - // t = (ga >> 16) != m_env.aref; + // t = (ga >> 16) != m_local.gd->aref; vpsrld(xmm1, xmm6, 16); - vpcmpeqd(xmm1, ptr[&m_env.aref]); + vpcmpeqd(xmm1, ptr[&m_local.gd->aref]); vpcmpeqd(xmm0, xmm0); vpxor(xmm1, xmm0); break; case ATST_GEQUAL: case ATST_GREATER: - // t = (ga >> 16) < m_env.aref; + // t = (ga >> 16) < m_local.gd->aref; vpsrld(xmm0, xmm6, 16); - vmovdqa(xmm1, ptr[&m_env.aref]); + vmovdqa(xmm1, ptr[&m_local.gd->aref]); vpcmpgtd(xmm1, xmm0); break; case ATST_NOTEQUAL: - // t = (ga >> 16) == m_env.aref; + // t = (ga >> 16) == m_local.gd->aref; vpsrld(xmm1, xmm6, 16); - vpcmpeqd(xmm1, ptr[&m_env.aref]); + vpcmpeqd(xmm1, ptr[&m_local.gd->aref]); break; } @@ -2382,35 +2381,35 @@ void GSDrawScanlineCodeGenerator::TestAlpha() case ATST_LESS: case ATST_LEQUAL: - // t = (ga >> 16) > m_env.aref; + // t = (ga >> 16) > m_local.gd->aref; movdqa(xmm1, xmm6); psrld(xmm1, 16); - pcmpgtd(xmm1, ptr[&m_env.aref]); + pcmpgtd(xmm1, ptr[&m_local.gd->aref]); break; case ATST_EQUAL: - // t = (ga >> 16) != m_env.aref; + // t = (ga >> 16) != m_local.gd->aref; movdqa(xmm1, xmm6); psrld(xmm1, 16); - pcmpeqd(xmm1, ptr[&m_env.aref]); + pcmpeqd(xmm1, ptr[&m_local.gd->aref]); pcmpeqd(xmm0, xmm0); pxor(xmm1, xmm0); break; case ATST_GEQUAL: case ATST_GREATER: - // t = (ga >> 16) < m_env.aref; + // t = (ga >> 16) < m_local.gd->aref; movdqa(xmm0, xmm6); psrld(xmm0, 16); - movdqa(xmm1, ptr[&m_env.aref]); + movdqa(xmm1, ptr[&m_local.gd->aref]); pcmpgtd(xmm1, xmm0); break; case ATST_NOTEQUAL: - // t = (ga >> 16) == m_env.aref; + // t = (ga >> 16) == m_local.gd->aref; movdqa(xmm1, xmm6); psrld(xmm1, 16); - pcmpeqd(xmm1, ptr[&m_env.aref]); + pcmpeqd(xmm1, ptr[&m_local.gd->aref]); break; } @@ -2457,11 +2456,11 @@ void GSDrawScanlineCodeGenerator::ColorTFX() { case TFX_MODULATE: - // GSVector4i rb = iip ? rbf : m_env.c.rb; + // GSVector4i rb = iip ? rbf : m_local.c.rb; // rbt = rbt.modulate16<1>(rb).clamp8(); - modulate16<1>(xmm5, ptr[m_sel.iip ? &m_env.temp.rb : &m_env.c.rb]); + modulate16<1>(xmm5, ptr[m_sel.iip ? &m_local.temp.rb : &m_local.c.rb]); clamp16(xmm5, xmm1); @@ -2476,9 +2475,9 @@ void GSDrawScanlineCodeGenerator::ColorTFX() if(m_sel.tfx == TFX_HIGHLIGHT2 && m_sel.tcc) { - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - vmovdqa(xmm2, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + vmovdqa(xmm2, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); } // gat = gat.modulate16<1>(ga).add16(af).clamp8().mix16(gat); @@ -2497,11 +2496,11 @@ void GSDrawScanlineCodeGenerator::ColorTFX() mix16(xmm6, xmm1, xmm0); - // GSVector4i rb = iip ? rbf : m_env.c.rb; + // GSVector4i rb = iip ? rbf : m_local.c.rb; // rbt = rbt.modulate16<1>(rb).add16(af).clamp8(); - modulate16<1>(xmm5, ptr[m_sel.iip ? &m_env.temp.rb : &m_env.c.rb]); + modulate16<1>(xmm5, ptr[m_sel.iip ? &m_local.temp.rb : &m_local.c.rb]); vpaddw(xmm5, xmm2); @@ -2527,11 +2526,11 @@ void GSDrawScanlineCodeGenerator::ColorTFX() { case TFX_MODULATE: - // GSVector4i rb = iip ? rbf : m_env.c.rb; + // GSVector4i rb = iip ? rbf : m_local.c.rb; // rbt = rbt.modulate16<1>(rb).clamp8(); - modulate16<1>(xmm5, ptr[m_sel.iip ? &m_env.temp.rb : &m_env.c.rb]); + modulate16<1>(xmm5, ptr[m_sel.iip ? &m_local.temp.rb : &m_local.c.rb]); clamp16(xmm5, xmm1); @@ -2546,9 +2545,9 @@ void GSDrawScanlineCodeGenerator::ColorTFX() if(m_sel.tfx == TFX_HIGHLIGHT2 && m_sel.tcc) { - // GSVector4i ga = iip ? gaf : m_env.c.ga; + // GSVector4i ga = iip ? gaf : m_local.c.ga; - movdqa(xmm2, ptr[m_sel.iip ? &m_env.temp.ga : &m_env.c.ga]); + movdqa(xmm2, ptr[m_sel.iip ? &m_local.temp.ga : &m_local.c.ga]); } // gat = gat.modulate16<1>(ga).add16(af).clamp8().mix16(gat); @@ -2567,11 +2566,11 @@ void GSDrawScanlineCodeGenerator::ColorTFX() mix16(xmm6, xmm1, xmm0); - // GSVector4i rb = iip ? rbf : m_env.c.rb; + // GSVector4i rb = iip ? rbf : m_local.c.rb; // rbt = rbt.modulate16<1>(rb).add16(af).clamp8(); - modulate16<1>(xmm5, ptr[m_sel.iip ? &m_env.temp.rb : &m_env.c.rb]); + modulate16<1>(xmm5, ptr[m_sel.iip ? &m_local.temp.rb : &m_local.c.rb]); paddw(xmm5, xmm2); @@ -2602,31 +2601,31 @@ void GSDrawScanlineCodeGenerator::Fog() if(m_cpu.has(util::Cpu::tAVX)) { - // rb = m_env.frb.lerp16<0>(rb, f); - // ga = m_env.fga.lerp16<0>(ga, f).mix16(ga); + // rb = m_local.gd->frb.lerp16<0>(rb, f); + // ga = m_local.gd->fga.lerp16<0>(ga, f).mix16(ga); - vmovdqa(xmm0, ptr[!m_sel.sprite ? &m_env.temp.f : &m_env.p.f]); + vmovdqa(xmm0, ptr[!m_sel.sprite ? &m_local.temp.f : &m_local.p.f]); vmovdqa(xmm1, xmm6); - vmovdqa(xmm2, ptr[&m_env.frb]); + vmovdqa(xmm2, ptr[&m_local.gd->frb]); lerp16<0>(xmm5, xmm2, xmm0); - vmovdqa(xmm2, ptr[&m_env.fga]); + vmovdqa(xmm2, ptr[&m_local.gd->fga]); lerp16<0>(xmm6, xmm2, xmm0); mix16(xmm6, xmm1, xmm0); } else { - // rb = m_env.frb.lerp16<0>(rb, f); - // ga = m_env.fga.lerp16<0>(ga, f).mix16(ga); + // rb = m_local.gd->frb.lerp16<0>(rb, f); + // ga = m_local.gd->fga.lerp16<0>(ga, f).mix16(ga); - movdqa(xmm0, ptr[!m_sel.sprite ? &m_env.temp.f : &m_env.p.f]); + movdqa(xmm0, ptr[!m_sel.sprite ? &m_local.temp.f : &m_local.p.f]); movdqa(xmm1, xmm6); - movdqa(xmm2, ptr[&m_env.frb]); + movdqa(xmm2, ptr[&m_local.gd->frb]); lerp16<0>(xmm5, xmm2, xmm0); - movdqa(xmm2, ptr[&m_env.fga]); + movdqa(xmm2, ptr[&m_local.gd->fga]); lerp16<0>(xmm6, xmm2, xmm0); mix16(xmm6, xmm1, xmm0); } @@ -2661,7 +2660,7 @@ void GSDrawScanlineCodeGenerator::TestDestAlpha() if(m_cpu.has(util::Cpu::tAVX)) { - // test |= ((fd [<< 16]) ^ m_env.datm).sra32(31); + // test |= ((fd [<< 16]) ^ m_local.gd->datm).sra32(31); if(m_sel.datm) { @@ -2695,7 +2694,7 @@ void GSDrawScanlineCodeGenerator::TestDestAlpha() } else { - // test |= ((fd [<< 16]) ^ m_env.datm).sra32(31); + // test |= ((fd [<< 16]) ^ m_local.gd->datm).sra32(31); movdqa(xmm1, xmm2); @@ -2826,25 +2825,25 @@ void GSDrawScanlineCodeGenerator::WriteZBuf() if(m_cpu.has(util::Cpu::tAVX)) { - vmovdqa(xmm1, ptr[!m_sel.sprite ? &m_env.temp.zs : &m_env.p.z]); + vmovdqa(xmm1, ptr[!m_sel.sprite ? &m_local.temp.zs : &m_local.p.z]); if(fast) { // zs = zs.blend8(zd, zm); - vpblendvb(xmm1, ptr[&m_env.temp.zd], xmm4); + vpblendvb(xmm1, ptr[&m_local.temp.zd], xmm4); } } else { - movdqa(xmm1, ptr[!m_sel.sprite ? &m_env.temp.zs : &m_env.p.z]); + movdqa(xmm1, ptr[!m_sel.sprite ? &m_local.temp.zs : &m_local.p.z]); if(fast) { // zs = zs.blend8(zd, zm); movdqa(xmm0, xmm4); - movdqa(xmm7, ptr[&m_env.temp.zd]); + movdqa(xmm7, ptr[&m_local.temp.zd]); blend8(xmm1, xmm7); } } @@ -2945,7 +2944,7 @@ void GSDrawScanlineCodeGenerator::AlphaBlend() if(!(m_sel.fpsm == 1 && m_sel.abc == 1)) { - // GSVector4i a = abc < 2 ? c[abc * 2 + 1].yywwlh().sll16(7) : m_env.afix; + // GSVector4i a = abc < 2 ? c[abc * 2 + 1].yywwlh().sll16(7) : m_local.gd->afix; switch(m_sel.abc) { @@ -2956,7 +2955,7 @@ void GSDrawScanlineCodeGenerator::AlphaBlend() vpsllw(xmm7, 7); break; case 2: - vmovdqa(xmm7, ptr[&m_env.afix]); + vmovdqa(xmm7, ptr[&m_local.gd->afix]); break; } @@ -3166,7 +3165,7 @@ void GSDrawScanlineCodeGenerator::AlphaBlend() if(!(m_sel.fpsm == 1 && m_sel.abc == 1)) { - // GSVector4i a = abc < 2 ? c[abc * 2 + 1].yywwlh().sll16(7) : m_env.afix; + // GSVector4i a = abc < 2 ? c[abc * 2 + 1].yywwlh().sll16(7) : m_local.gd->afix; switch(m_sel.abc) { @@ -3178,7 +3177,7 @@ void GSDrawScanlineCodeGenerator::AlphaBlend() psllw(xmm7, 7); break; case 2: - movdqa(xmm7, ptr[&m_env.afix]); + movdqa(xmm7, ptr[&m_local.gd->afix]); break; } @@ -3311,10 +3310,8 @@ void GSDrawScanlineCodeGenerator::AlphaBlend() } } -void GSDrawScanlineCodeGenerator::WriteFrame(int params) +void GSDrawScanlineCodeGenerator::WriteFrame() { - const int _top = params + 4; - if(!m_sel.fwrite) { return; @@ -3338,8 +3335,8 @@ void GSDrawScanlineCodeGenerator::WriteFrame(int params) mov(eax, dword[esp + _top]); and(eax, 3); shl(eax, 5); - vpaddw(xmm5, ptr[eax + (size_t)&m_env.dimx[0]]); - vpaddw(xmm6, ptr[eax + (size_t)&m_env.dimx[1]]); + vpaddw(xmm5, ptr[eax + (size_t)&m_local.gd->dimx[0]]); + vpaddw(xmm6, ptr[eax + (size_t)&m_local.gd->dimx[1]]); } // GSVector4i fs = c[0].upl16(c[1]).pu16(c[0].uph16(c[1])); @@ -3403,8 +3400,8 @@ void GSDrawScanlineCodeGenerator::WriteFrame(int params) mov(eax, dword[esp + _top]); and(eax, 3); shl(eax, 5); - paddw(xmm5, ptr[eax + (size_t)&m_env.dimx[0]]); - paddw(xmm6, ptr[eax + (size_t)&m_env.dimx[1]]); + paddw(xmm5, ptr[eax + (size_t)&m_local.gd->dimx[0]]); + paddw(xmm6, ptr[eax + (size_t)&m_local.gd->dimx[1]]); } // GSVector4i fs = c[0].upl16(c[1]).pu16(c[0].uph16(c[1])); @@ -3472,13 +3469,13 @@ void GSDrawScanlineCodeGenerator::ReadPixel(const Xmm& dst, const Reg32& addr) { if(m_cpu.has(util::Cpu::tAVX)) { - vmovq(dst, qword[addr * 2 + (size_t)m_env.vm]); - vmovhps(dst, qword[addr * 2 + (size_t)m_env.vm + 8 * 2]); + vmovq(dst, qword[addr * 2 + (size_t)m_local.gd->vm]); + vmovhps(dst, qword[addr * 2 + (size_t)m_local.gd->vm + 8 * 2]); } else { - movq(dst, qword[addr * 2 + (size_t)m_env.vm]); - movhps(dst, qword[addr * 2 + (size_t)m_env.vm + 8 * 2]); + movq(dst, qword[addr * 2 + (size_t)m_local.gd->vm]); + movhps(dst, qword[addr * 2 + (size_t)m_local.gd->vm + 8 * 2]); } } @@ -3493,12 +3490,12 @@ void GSDrawScanlineCodeGenerator::WritePixel(const Xmm& src, const Reg32& addr, { test(mask, 0x0f); je("@f"); - vmovq(qword[addr * 2 + (size_t)m_env.vm], src); + vmovq(qword[addr * 2 + (size_t)m_local.gd->vm], src); L("@@"); test(mask, 0xf0); je("@f"); - vmovhps(qword[addr * 2 + (size_t)m_env.vm + 8 * 2], src); + vmovhps(qword[addr * 2 + (size_t)m_local.gd->vm + 8 * 2], src); L("@@"); // vmaskmovps? @@ -3507,12 +3504,12 @@ void GSDrawScanlineCodeGenerator::WritePixel(const Xmm& src, const Reg32& addr, { test(mask, 0x0f); je("@f"); - movq(qword[addr * 2 + (size_t)m_env.vm], src); + movq(qword[addr * 2 + (size_t)m_local.gd->vm], src); L("@@"); test(mask, 0xf0); je("@f"); - movhps(qword[addr * 2 + (size_t)m_env.vm + 8 * 2], src); + movhps(qword[addr * 2 + (size_t)m_local.gd->vm + 8 * 2], src); L("@@"); } } @@ -3549,7 +3546,7 @@ static const int s_offsets[4] = {0, 2, 8, 10}; void GSDrawScanlineCodeGenerator::WritePixel(const Xmm& src, const Reg32& addr, uint8 i, int psm) { - Address dst = ptr[addr * 2 + (size_t)m_env.vm + s_offsets[i] * 2]; + Address dst = ptr[addr * 2 + (size_t)m_local.gd->vm + s_offsets[i] * 2]; if(m_cpu.has(util::Cpu::tAVX)) { @@ -3645,7 +3642,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(const Xmm& dst, const Xmm& addr, con void GSDrawScanlineCodeGenerator::ReadTexel(const Xmm& dst, const Xmm& addr, uint8 i) { - const Address& src = m_sel.tlu ? ptr[eax * 4 + (size_t)m_env.clut] : ptr[ebx + eax * 4]; + const Address& src = m_sel.tlu ? ptr[eax * 4 + (size_t)m_local.gd->clut] : ptr[ebx + eax * 4]; if(m_cpu.has(util::Cpu::tAVX)) { diff --git a/plugins/GSdx/GSDrawScanlineCodeGenerator.h b/plugins/GSdx/GSDrawScanlineCodeGenerator.h index e2d1389ecb..eb4cb48b63 100644 --- a/plugins/GSdx/GSDrawScanlineCodeGenerator.h +++ b/plugins/GSdx/GSDrawScanlineCodeGenerator.h @@ -32,12 +32,12 @@ class GSDrawScanlineCodeGenerator : public GSCodeGenerator static const GSVector4i m_test[8]; - GSScanlineEnvironment& m_env; GSScanlineSelector m_sel; + GSScanlineLocalData& m_local; void Generate(); - void Init(int params); + void Init(); void Step(); void TestZ(const Xmm& temp1, const Xmm& temp2); void SampleTexture(); @@ -53,7 +53,7 @@ class GSDrawScanlineCodeGenerator : public GSCodeGenerator void WriteMask(); void WriteZBuf(); void AlphaBlend(); - void WriteFrame(int params); + void WriteFrame(); void ReadPixel(const Xmm& dst, const Reg32& addr); void WritePixel(const Xmm& src, const Reg32& addr, const Reg8& mask, bool fast, int psm, int fz); diff --git a/plugins/GSdx/GSRasterizer.cpp b/plugins/GSdx/GSRasterizer.cpp index 074637c360..5afc0a383a 100644 --- a/plugins/GSdx/GSRasterizer.cpp +++ b/plugins/GSdx/GSRasterizer.cpp @@ -110,7 +110,7 @@ void GSRasterizer::Draw(const GSRasterizerData* data) m_stats.ticks = __rdtsc() - start; - m_ds->EndDraw(m_stats); + m_ds->EndDraw(m_stats, data->frame); } void GSRasterizer::GetStats(GSRasterizerStats& stats) @@ -908,23 +908,19 @@ void GSRasterizerMT::ThreadProc() // GSRasterizerList::GSRasterizerList() + : m_sync(0) + , m_syncstart(0) + , m_param(NULL) { } GSRasterizerList::~GSRasterizerList() -{ - FreeRasterizers(); -} - -void GSRasterizerList::FreeRasterizers() { for(size_t i = 0; i < size(); i++) delete (*this)[i]; - clear(); - for(size_t i = 0; i < m_ready.size(); i++) CloseHandle(m_ready[i]); - m_ready.clear(); + if(m_param) _aligned_free(m_param); } void GSRasterizerList::Sync() @@ -956,6 +952,8 @@ void GSRasterizerList::Draw(const GSRasterizerData* data) { m_stats.Reset(); + memcpy(m_param, data->param, m_param_size); + m_start = __rdtsc(); m_sync = m_syncstart; diff --git a/plugins/GSdx/GSRasterizer.h b/plugins/GSdx/GSRasterizer.h index c45b7892bf..7c9b6b61d5 100644 --- a/plugins/GSdx/GSRasterizer.h +++ b/plugins/GSdx/GSRasterizer.h @@ -34,6 +34,7 @@ public: GS_PRIM_CLASS primclass; const GSVertexSW* vertices; int count; + uint64 frame; const void* param; }; @@ -55,7 +56,7 @@ public: virtual ~IDrawScanline() {} virtual void BeginDraw(const GSRasterizerData* data) = 0; - virtual void EndDraw(const GSRasterizerStats& stats) = 0; + virtual void EndDraw(const GSRasterizerStats& stats, uint64 frame) = 0; virtual void PrintStats() = 0; __forceinline void SetupPrim(const GSVertexSW* v, const GSVertexSW& dscan) {m_sp(v, dscan);} @@ -141,28 +142,29 @@ protected: long m_syncstart; GSRasterizerStats m_stats; int64 m_start; - - void FreeRasterizers(); + void* m_param; + size_t m_param_size; public: GSRasterizerList(); virtual ~GSRasterizerList(); - template void Create(T* parent, int threads) + template void Create(int threads) { - FreeRasterizers(); - threads = std::max(threads, 1); // TODO: min(threads, number of cpu cores) + m_param = _aligned_malloc(sizeof(PARAM), 32); + m_param_size = sizeof(PARAM); + m_syncstart = 0; - push_back(new GSRasterizer(new DS(parent, 0), 0, threads)); + push_back(new GSRasterizer(new DS((PARAM*)m_param), 0, threads)); for(int i = 1; i < threads; i++) { - HANDLE ready = CreateEvent(NULL, FALSE, FALSE, NULL); + HANDLE ready = CreateEvent(NULL, FALSE, TRUE, NULL); - push_back(new GSRasterizerMT(new DS(parent, i), i, threads, ready, m_sync)); + push_back(new GSRasterizerMT(new DS((PARAM*)m_param), i, threads, ready, m_sync)); m_ready.push_back(ready); diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 510c50e8a0..fca5d19822 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -24,14 +24,14 @@ const GSVector4 g_pos_scale(1.0f / 16, 1.0f / 16, 1.0f, 128.0f); -GSRendererSW::GSRendererSW() +GSRendererSW::GSRendererSW(int threads) : GSRendererT() { m_tc = new GSTextureCacheSW(this); memset(m_texture, 0, sizeof(m_texture)); - m_rl.Create(this, theApp.GetConfig("swthreads", 1)); + m_rl.Create(threads); InitVertexKick(); } @@ -128,11 +128,11 @@ void GSRendererSW::Draw() m_dump.Object(m_vertices, m_count, m_vt.m_primclass); } - GSScanlineParam p; + GSScanlineGlobalData gd; - GetScanlineParam(p, m_vt.m_primclass); + GetScanlineGlobalData(gd); - if((p.fm & p.zm) == 0xffffffff) + if(!gd.sel.fwrite && !gd.sel.zwrite) { return; } @@ -176,18 +176,19 @@ void GSRendererSW::Draw() data.primclass = m_vt.m_primclass; data.vertices = m_vertices; data.count = m_count; - data.param = &p; + data.frame = m_perfmon.GetFrame(); + data.param = &gd; m_rl.Draw(&data); GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(data.scissor); - if(p.fm != 0xffffffff) + if(gd.sel.fwrite) { m_tc->InvalidateVideoMem(m_context->offset.fb, r); } - if(p.zm != 0xffffffff) + if(gd.sel.zwrite) { m_tc->InvalidateVideoMem(m_context->offset.zb, r); } @@ -230,7 +231,7 @@ void GSRendererSW::Draw() if(0)//stats.ticks > 5000000) { printf("* [%I64d | %012I64x] ticks %I64d prims %d (%d) pixels %d (%d)\n", - m_perfmon.GetFrame(), p.sel.key, + m_perfmon.GetFrame(), gd.sel.key, stats.ticks, stats.prims, stats.prims > 0 ? (int)(stats.ticks / stats.prims) : -1, stats.pixels, stats.pixels > 0 ? (int)(stats.ticks / stats.pixels) : -1); @@ -242,33 +243,38 @@ void GSRendererSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS m_tc->InvalidateVideoMem(m_mem.GetOffset(BITBLTBUF.DBP, BITBLTBUF.DBW, BITBLTBUF.DPSM), r); } -void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) +void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd) { const GSDrawingEnvironment& env = m_env; const GSDrawingContext* context = m_context; + const GS_PRIM_CLASS primclass = m_vt.m_primclass; - p.vm = m_mem.m_vm8; + gd.vm = m_mem.m_vm8; + gd.dimx = env.dimx; - p.fbo = context->offset.fb; - p.zbo = context->offset.zb; - p.fzbo = context->offset.fzb; + gd.fbr = context->offset.fb->pixel.row; + gd.zbr = context->offset.zb->pixel.row; + gd.fbc = context->offset.fb->pixel.col[0]; + gd.zbc = context->offset.zb->pixel.col[0]; + gd.fzbr = context->offset.fzb->row; + gd.fzbc = context->offset.fzb->col; - p.sel.key = 0; + gd.sel.key = 0; - p.sel.fpsm = 3; - p.sel.zpsm = 3; - p.sel.atst = ATST_ALWAYS; - p.sel.tfx = TFX_NONE; - p.sel.ababcd = 255; - p.sel.sprite = primclass == GS_SPRITE_CLASS ? 1 : 0; + gd.sel.fpsm = 3; + gd.sel.zpsm = 3; + gd.sel.atst = ATST_ALWAYS; + gd.sel.tfx = TFX_NONE; + gd.sel.ababcd = 255; + gd.sel.sprite = primclass == GS_SPRITE_CLASS ? 1 : 0; - p.fm = context->FRAME.FBMSK; - p.zm = context->ZBUF.ZMSK || context->TEST.ZTE == 0 ? 0xffffffff : 0; + uint32 fm = context->FRAME.FBMSK; + uint32 zm = context->ZBUF.ZMSK || context->TEST.ZTE == 0 ? 0xffffffff : 0; if(context->TEST.ZTE && context->TEST.ZTST == ZTST_NEVER) { - p.fm = 0xffffffff; - p.zm = 0xffffffff; + fm = 0xffffffff; + zm = 0xffffffff; } if(PRIM->TME) @@ -278,46 +284,60 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) if(context->TEST.ATE) { - if(!TryAlphaTest(p.fm, p.zm)) + if(!TryAlphaTest(fm, zm)) { - p.sel.atst = context->TEST.ATST; - p.sel.afail = context->TEST.AFAIL; + gd.sel.atst = context->TEST.ATST; + gd.sel.afail = context->TEST.AFAIL; + + gd.aref = GSVector4i((int)context->TEST.AREF); + + switch(gd.sel.atst) + { + case ATST_LESS: + gd.sel.atst = ATST_LEQUAL; + gd.aref -= GSVector4i::x00000001(); + break; + case ATST_GREATER: + gd.sel.atst = ATST_GEQUAL; + gd.aref += GSVector4i::x00000001(); + break; + } } } - bool fwrite = p.fm != 0xffffffff; - bool ftest = p.sel.atst != ATST_ALWAYS || context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24; + bool fwrite = fm != 0xffffffff; + bool ftest = gd.sel.atst != ATST_ALWAYS || context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24; - p.sel.fwrite = fwrite; - p.sel.ftest = ftest; + gd.sel.fwrite = fwrite; + gd.sel.ftest = ftest; if(fwrite || ftest) { - p.sel.fpsm = GSLocalMemory::m_psm[context->FRAME.PSM].fmt; + gd.sel.fpsm = GSLocalMemory::m_psm[context->FRAME.PSM].fmt; if((primclass == GS_LINE_CLASS || primclass == GS_TRIANGLE_CLASS) && m_vt.m_eq.rgba != 0xffff) { - p.sel.iip = PRIM->IIP; + gd.sel.iip = PRIM->IIP; } if(PRIM->TME) { - p.sel.tfx = context->TEX0.TFX; - p.sel.tcc = context->TEX0.TCC; - p.sel.fst = PRIM->FST; - p.sel.ltf = IsLinear(); - p.sel.tlu = GSLocalMemory::m_psm[context->TEX0.PSM].pal > 0; - p.sel.wms = context->CLAMP.WMS; - p.sel.wmt = context->CLAMP.WMT; + gd.sel.tfx = context->TEX0.TFX; + gd.sel.tcc = context->TEX0.TCC; + gd.sel.fst = PRIM->FST; + gd.sel.ltf = IsLinear(); + gd.sel.tlu = GSLocalMemory::m_psm[context->TEX0.PSM].pal > 0; + gd.sel.wms = context->CLAMP.WMS; + gd.sel.wmt = context->CLAMP.WMT; - if(p.sel.tfx == TFX_MODULATE && p.sel.tcc && m_vt.m_eq.rgba == 0xffff && m_vt.m_min.c.eq(GSVector4i(128))) + if(gd.sel.tfx == TFX_MODULATE && gd.sel.tcc && m_vt.m_eq.rgba == 0xffff && m_vt.m_min.c.eq(GSVector4i(128))) { // modulate does not do anything when vertex color is 0x80 - p.sel.tfx = TFX_DECAL; + gd.sel.tfx = TFX_DECAL; } - if(p.sel.fst == 0) + if(gd.sel.fst == 0) { // skip per pixel division if q is constant @@ -325,7 +345,7 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) if(m_vt.m_eq.q) { - p.sel.fst = 1; + gd.sel.fst = 1; if(v[0].t.z != 1.0f) { @@ -339,7 +359,7 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) } else if(primclass == GS_SPRITE_CLASS) { - p.sel.fst = 1; + gd.sel.fst = 1; for(int i = 0, j = m_count; i < j; i += 2) { @@ -351,11 +371,11 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) } } - if(p.sel.ltf) + if(gd.sel.ltf) { GSVector4 half(0x8000, 0x8000); - if(p.sel.fst) + if(gd.sel.fst) { // if q is constant we can do the half pel shift for bilinear sampling on the vertices @@ -370,68 +390,160 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) GSVector4i r; - GetTextureMinMax(r, p.sel.ltf); + GetTextureMinMax(r, gd.sel.ltf); const GSTextureCacheSW::GSTexture* t = m_tc->Lookup(context->TEX0, env.TEXA, r); if(!t) {ASSERT(0); return;} - p.tex = t->m_buff; - p.clut = m_mem.m_clut; + gd.tex = t->m_buff; + gd.clut = m_mem.m_clut; - p.sel.tw = t->m_tw - 3; + gd.sel.tw = t->m_tw - 3; + + uint16 tw = (uint16)(1 << context->TEX0.TW); + uint16 th = (uint16)(1 << context->TEX0.TH); + + switch(context->CLAMP.WMS) + { + case CLAMP_REPEAT: + gd.t.min.u16[0] = tw - 1; + gd.t.max.u16[0] = 0; + gd.t.mask.u32[0] = 0xffffffff; + break; + case CLAMP_CLAMP: + gd.t.min.u16[0] = 0; + gd.t.max.u16[0] = tw - 1; + gd.t.mask.u32[0] = 0; + break; + case CLAMP_REGION_CLAMP: + gd.t.min.u16[0] = std::min(context->CLAMP.MINU, tw - 1); + gd.t.max.u16[0] = std::min(context->CLAMP.MAXU, tw - 1); + gd.t.mask.u32[0] = 0; + break; + case CLAMP_REGION_REPEAT: + gd.t.min.u16[0] = context->CLAMP.MINU; + gd.t.max.u16[0] = context->CLAMP.MAXU; + gd.t.mask.u32[0] = 0xffffffff; + break; + default: + __assume(0); + } + + switch(context->CLAMP.WMT) + { + case CLAMP_REPEAT: + gd.t.min.u16[4] = th - 1; + gd.t.max.u16[4] = 0; + gd.t.mask.u32[2] = 0xffffffff; + break; + case CLAMP_CLAMP: + gd.t.min.u16[4] = 0; + gd.t.max.u16[4] = th - 1; + gd.t.mask.u32[2] = 0; + break; + case CLAMP_REGION_CLAMP: + gd.t.min.u16[4] = std::min(context->CLAMP.MINV, th - 1); + gd.t.max.u16[4] = std::min(context->CLAMP.MAXV, th - 1); // ffx anima summon scene, when the anchor appears (th = 256, maxv > 256) + gd.t.mask.u32[2] = 0; + break; + case CLAMP_REGION_REPEAT: + gd.t.min.u16[4] = context->CLAMP.MINV; + gd.t.max.u16[4] = context->CLAMP.MAXV; + gd.t.mask.u32[2] = 0xffffffff; + break; + default: + __assume(0); + } + + gd.t.min = gd.t.min.xxxxlh(); + gd.t.max = gd.t.max.xxxxlh(); + gd.t.mask = gd.t.mask.xxzz(); + gd.t.invmask = ~gd.t.mask; } - p.sel.fge = PRIM->FGE; + if(PRIM->FGE) + { + gd.sel.fge = 1; + + gd.frb = GSVector4i((int)env.FOGCOL.u32[0] & 0x00ff00ff); + gd.fga = GSVector4i((int)(env.FOGCOL.u32[0] >> 8) & 0x00ff00ff); + } if(context->FRAME.PSM != PSM_PSMCT24) { - p.sel.date = context->TEST.DATE; - p.sel.datm = context->TEST.DATM; + gd.sel.date = context->TEST.DATE; + gd.sel.datm = context->TEST.DATM; } if(!IsOpaque()) { - p.sel.abe = PRIM->ABE; - p.sel.ababcd = context->ALPHA.u32[0]; + gd.sel.abe = PRIM->ABE; + gd.sel.ababcd = context->ALPHA.u32[0]; if(env.PABE.PABE) { - p.sel.pabe = 1; + gd.sel.pabe = 1; } if(m_aa1 && PRIM->AA1 && (primclass == GS_LINE_CLASS || primclass == GS_TRIANGLE_CLASS)) { - p.sel.aa1 = 1; + gd.sel.aa1 = 1; } + + gd.afix = GSVector4i((int)context->ALPHA.FIX << 7).xxzzlh(); } - if(p.sel.date - || p.sel.aba == 1 || p.sel.abb == 1 || p.sel.abc == 1 || p.sel.abd == 1 - || p.sel.atst != ATST_ALWAYS && p.sel.afail == AFAIL_RGB_ONLY - || p.sel.fpsm == 0 && p.fm != 0 && p.fm != 0xffffffff - || p.sel.fpsm == 1 && (p.fm & 0x00ffffff) != 0 && (p.fm & 0x00ffffff) != 0x00ffffff - || p.sel.fpsm == 2 && (p.fm & 0x80f8f8f8) != 0 && (p.fm & 0x80f8f8f8) != 0x80f8f8f8) + if(gd.sel.date + || gd.sel.aba == 1 || gd.sel.abb == 1 || gd.sel.abc == 1 || gd.sel.abd == 1 + || gd.sel.atst != ATST_ALWAYS && gd.sel.afail == AFAIL_RGB_ONLY + || gd.sel.fpsm == 0 && fm != 0 && fm != 0xffffffff + || gd.sel.fpsm == 1 && (fm & 0x00ffffff) != 0 && (fm & 0x00ffffff) != 0x00ffffff + || gd.sel.fpsm == 2 && (fm & 0x80f8f8f8) != 0 && (fm & 0x80f8f8f8) != 0x80f8f8f8) { - p.sel.rfb = 1; + gd.sel.rfb = 1; } - p.sel.colclamp = env.COLCLAMP.CLAMP; - p.sel.fba = context->FBA.FBA; - p.sel.dthe = env.DTHE.DTHE; + gd.sel.colclamp = env.COLCLAMP.CLAMP; + gd.sel.fba = context->FBA.FBA; + gd.sel.dthe = env.DTHE.DTHE; } - bool zwrite = p.zm != 0xffffffff; + bool zwrite = zm != 0xffffffff; bool ztest = context->TEST.ZTE && context->TEST.ZTST > ZTST_ALWAYS; - p.sel.zwrite = zwrite; - p.sel.ztest = ztest; + gd.sel.zwrite = zwrite; + gd.sel.ztest = ztest; if(zwrite || ztest) { - p.sel.zpsm = GSLocalMemory::m_psm[context->ZBUF.PSM].fmt; - p.sel.ztst = ztest ? context->TEST.ZTST : ZTST_ALWAYS; - p.sel.zoverflow = GSVector4i(m_vt.m_max.p).z == 0x80000000; + gd.sel.zpsm = GSLocalMemory::m_psm[context->ZBUF.PSM].fmt; + gd.sel.ztst = ztest ? context->TEST.ZTST : ZTST_ALWAYS; + gd.sel.zoverflow = GSVector4i(m_vt.m_max.p).z == 0x80000000; + } + + gd.fm = GSVector4i(fm); + gd.zm = GSVector4i(zm); + + if(gd.sel.fpsm == 1) + { + gd.fm |= GSVector4i::xff000000(); + } + else if(gd.sel.fpsm == 2) + { + GSVector4i rb = gd.fm & 0x00f800f8; + GSVector4i ga = gd.fm & 0x8000f800; + + gd.fm = (ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3) | GSVector4i::xffff0000(); + } + + if(gd.sel.zpsm == 1) + { + gd.zm |= GSVector4i::xff000000(); + } + else if(gd.sel.zpsm == 2) + { + gd.zm |= GSVector4i::xffff0000(); } } diff --git a/plugins/GSdx/GSRendererSW.h b/plugins/GSdx/GSRendererSW.h index abe8b60ee0..89112fdbc0 100644 --- a/plugins/GSdx/GSRendererSW.h +++ b/plugins/GSdx/GSRendererSW.h @@ -41,10 +41,10 @@ protected: void Draw(); void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); - void GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass); + void GetScanlineGlobalData(GSScanlineGlobalData& gd); public: - GSRendererSW(); + GSRendererSW(int threads); virtual ~GSRendererSW(); template diff --git a/plugins/GSdx/GSScanlineEnvironment.h b/plugins/GSdx/GSScanlineEnvironment.h index afeed0beec..f2a03bf7b2 100644 --- a/plugins/GSdx/GSScanlineEnvironment.h +++ b/plugins/GSdx/GSScanlineEnvironment.h @@ -85,10 +85,10 @@ union GSScanlineSelector uint64 key; - operator uint32() {return lo;} - operator uint64() {return key;} + operator uint32() const {return lo;} + operator uint64() const {return key;} - bool IsSolidRect() + bool IsSolidRect() const { return sprite && iip == 0 @@ -101,45 +101,44 @@ union GSScanlineSelector } }; -__aligned32 struct GSScanlineParam +__aligned32 struct GSScanlineGlobalData // per batch variables, this is like a pixel shader constant buffer { GSScanlineSelector sel; + // - the data of vm, tex, clut, dimx may change, multi-threaded drawing must be finished before that happens (an idea: remember which pages are used, sync when something needs to read or write them) + // - tex is a cached texture, it may be recycled to free up memory, its absolute address cannot be compiled into code + // - row and column pointers are allocated once and never change or freed, thier address can be used directly + // - if in the future drawing does not have to be synchronized per batch, the rest of GSRasterizerData should be copied here, too (scissor, prim type, vertices) + void* vm; const void* tex; const uint32* clut; + const GSVector4i* dimx; - GSOffset* fbo; - GSOffset* zbo; - GSPixelOffset4* fzbo; - - uint32 fm, zm; -}; - -__aligned32 struct GSScanlineEnvironment -{ - void* vm; - const void* tex; - const uint32* clut; - - int* fbr; - int* zbr; - int* fbc; - int* zbc; - GSVector2i* fzbr; - GSVector2i* fzbc; - - GSVector4i* dimx; + const int* fbr; + const int* zbr; + const int* fbc; + const int* zbc; + const GSVector2i* fzbr; + const GSVector2i* fzbc; GSVector4i fm, zm; struct {GSVector4i min, max, mask, invmask;} t; // [u] x 4 [v] x 4 GSVector4i aref; GSVector4i afix; GSVector4i frb, fga; +}; + +__aligned32 struct GSScanlineLocalData // per prim variables, each thread has its own +{ + const GSScanlineGlobalData* gd; struct {GSVector4 z, s, t, q; GSVector4i rb, ga, f, si, ti, _pad[7];} d[4]; struct {GSVector4 z, stq; GSVector4i c, f, st;} d4; struct {GSVector4i rb, ga;} c; struct {GSVector4i z, f;} p; - struct {GSVector4i z, f, s, t, q, rb, ga, zs, zd, uf, vf, cov;} temp; + + // these should be stored on stack as normal local variables (no free regs to use, esp cannot be saved to anywhere, and we need an aligned stack) + + struct {GSVector4i z, f, s, t, q, rb, ga, zs, zd, uf, vf, cov;} temp; }; diff --git a/plugins/GSdx/GSSetupPrimCodeGenerator.cpp b/plugins/GSdx/GSSetupPrimCodeGenerator.cpp index fc2aae2e92..1443efda35 100644 --- a/plugins/GSdx/GSSetupPrimCodeGenerator.cpp +++ b/plugins/GSdx/GSSetupPrimCodeGenerator.cpp @@ -28,8 +28,12 @@ using namespace Xbyak; GSSetupPrimCodeGenerator::GSSetupPrimCodeGenerator(void* param, uint64 key, void* code, size_t maxsize) : GSCodeGenerator(code, maxsize) - , m_env(*(GSScanlineEnvironment*)param) + , m_local(*(GSScanlineLocalData*)param) { + #if _M_AMD64 + #error TODO + #endif + m_sel.key = key; m_en.z = m_sel.zb ? 1 : 0; @@ -37,10 +41,6 @@ GSSetupPrimCodeGenerator::GSSetupPrimCodeGenerator(void* param, uint64 key, void m_en.t = m_sel.fb && m_sel.tfx != TFX_NONE ? 1 : 0; m_en.c = m_sel.fb && !(m_sel.tfx == TFX_DECAL && m_sel.tcc) ? 1 : 0; - #if _M_AMD64 - #error TODO - #endif - Generate(); } @@ -91,23 +91,23 @@ void GSSetupPrimCodeGenerator::Depth() vshufps(xmm1, xmm0, xmm0, _MM_SHUFFLE(3, 3, 3, 3)); - // m_env.d4.f = GSVector4i(df * 4.0f).xxzzlh(); + // m_local.d4.f = GSVector4i(df * 4.0f).xxzzlh(); vmulps(xmm2, xmm1, xmm3); vcvttps2dq(xmm2, xmm2); vpshuflw(xmm2, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); vpshufhw(xmm2, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); - vmovdqa(ptr[&m_env.d4.f], xmm2); + vmovdqa(ptr[&m_local.d4.f], xmm2); for(int i = 0; i < 4; i++) { - // m_env.d[i].f = GSVector4i(df * m_shift[i]).xxzzlh(); + // m_local.d[i].f = GSVector4i(df * m_shift[i]).xxzzlh(); vmulps(xmm2, xmm1, Xmm(4 + i)); vcvttps2dq(xmm2, xmm2); vpshuflw(xmm2, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); vpshufhw(xmm2, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); - vmovdqa(ptr[&m_env.d[i].f], xmm2); + vmovdqa(ptr[&m_local.d[i].f], xmm2); } } @@ -117,17 +117,17 @@ void GSSetupPrimCodeGenerator::Depth() vshufps(xmm0, xmm0, _MM_SHUFFLE(2, 2, 2, 2)); - // m_env.d4.z = dz * 4.0f; + // m_local.d4.z = dz * 4.0f; vmulps(xmm1, xmm0, xmm3); - vmovdqa(ptr[&m_env.d4.z], xmm1); + vmovdqa(ptr[&m_local.d4.z], xmm1); for(int i = 0; i < 4; i++) { - // m_env.d[i].z = dz * m_shift[i]; + // m_local.d[i].z = dz * m_shift[i]; vmulps(xmm1, xmm0, Xmm(4 + i)); - vmovdqa(ptr[&m_env.d[i].z], xmm1); + vmovdqa(ptr[&m_local.d[i].z], xmm1); } } } @@ -139,12 +139,12 @@ void GSSetupPrimCodeGenerator::Depth() if(m_en.f) { - // m_env.p.f = GSVector4i(p).zzzzh().zzzz(); + // m_local.p.f = GSVector4i(p).zzzzh().zzzz(); vcvttps2dq(xmm1, xmm0); vpshufhw(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); vpshufd(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); - vmovdqa(ptr[&m_env.p.f], xmm1); + vmovdqa(ptr[&m_local.p.f], xmm1); } if(m_en.z) @@ -155,7 +155,7 @@ void GSSetupPrimCodeGenerator::Depth() if(m_sel.zoverflow) { - // m_env.p.z = (GSVector4i(z * 0.5f) << 1) | (GSVector4i(z) & GSVector4i::x00000001()); + // m_local.p.z = (GSVector4i(z * 0.5f) << 1) | (GSVector4i(z) & GSVector4i::x00000001()); static const float half = 0.5f; @@ -173,12 +173,12 @@ void GSSetupPrimCodeGenerator::Depth() } else { - // m_env.p.z = GSVector4i(z); + // m_local.p.z = GSVector4i(z); vcvttps2dq(xmm0, xmm0); } - vmovdqa(ptr[&m_env.p.z], xmm0); + vmovdqa(ptr[&m_local.p.z], xmm0); } } } @@ -197,25 +197,25 @@ void GSSetupPrimCodeGenerator::Depth() movaps(xmm1, xmm0); shufps(xmm1, xmm1, _MM_SHUFFLE(3, 3, 3, 3)); - // m_env.d4.f = GSVector4i(df * 4.0f).xxzzlh(); + // m_local.d4.f = GSVector4i(df * 4.0f).xxzzlh(); movaps(xmm2, xmm1); mulps(xmm2, xmm3); cvttps2dq(xmm2, xmm2); pshuflw(xmm2, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); pshufhw(xmm2, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); - movdqa(ptr[&m_env.d4.f], xmm2); + movdqa(ptr[&m_local.d4.f], xmm2); for(int i = 0; i < 4; i++) { - // m_env.d[i].f = GSVector4i(df * m_shift[i]).xxzzlh(); + // m_local.d[i].f = GSVector4i(df * m_shift[i]).xxzzlh(); movaps(xmm2, xmm1); mulps(xmm2, Xmm(4 + i)); cvttps2dq(xmm2, xmm2); pshuflw(xmm2, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); pshufhw(xmm2, xmm2, _MM_SHUFFLE(2, 2, 0, 0)); - movdqa(ptr[&m_env.d[i].f], xmm2); + movdqa(ptr[&m_local.d[i].f], xmm2); } } @@ -225,19 +225,19 @@ void GSSetupPrimCodeGenerator::Depth() shufps(xmm0, xmm0, _MM_SHUFFLE(2, 2, 2, 2)); - // m_env.d4.z = dz * 4.0f; + // m_local.d4.z = dz * 4.0f; movaps(xmm1, xmm0); mulps(xmm1, xmm3); - movdqa(ptr[&m_env.d4.z], xmm1); + movdqa(ptr[&m_local.d4.z], xmm1); for(int i = 0; i < 4; i++) { - // m_env.d[i].z = dz * m_shift[i]; + // m_local.d[i].z = dz * m_shift[i]; movaps(xmm1, xmm0); mulps(xmm1, Xmm(4 + i)); - movdqa(ptr[&m_env.d[i].z], xmm1); + movdqa(ptr[&m_local.d[i].z], xmm1); } } } @@ -249,12 +249,12 @@ void GSSetupPrimCodeGenerator::Depth() if(m_en.f) { - // m_env.p.f = GSVector4i(p).zzzzh().zzzz(); + // m_local.p.f = GSVector4i(p).zzzzh().zzzz(); cvttps2dq(xmm1, xmm0); pshufhw(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); pshufd(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2)); - movdqa(ptr[&m_env.p.f], xmm1); + movdqa(ptr[&m_local.p.f], xmm1); } if(m_en.z) @@ -265,7 +265,7 @@ void GSSetupPrimCodeGenerator::Depth() if(m_sel.zoverflow) { - // m_env.p.z = (GSVector4i(z * 0.5f) << 1) | (GSVector4i(z) & GSVector4i::x00000001()); + // m_local.p.z = (GSVector4i(z * 0.5f) << 1) | (GSVector4i(z) & GSVector4i::x00000001()); static const float half = 0.5f; @@ -284,12 +284,12 @@ void GSSetupPrimCodeGenerator::Depth() } else { - // m_env.p.z = GSVector4i(z); + // m_local.p.z = GSVector4i(z); cvttps2dq(xmm0, xmm0); } - movdqa(ptr[&m_env.p.z], xmm0); + movdqa(ptr[&m_local.p.z], xmm0); } } } @@ -312,16 +312,16 @@ void GSSetupPrimCodeGenerator::Texture() if(m_sel.fst) { - // m_env.d4.st = GSVector4i(t * 4.0f); + // m_local.d4.st = GSVector4i(t * 4.0f); vcvttps2dq(xmm1, xmm1); - vmovdqa(ptr[&m_env.d4.st], xmm1); + vmovdqa(ptr[&m_local.d4.st], xmm1); } else { - // m_env.d4.stq = t * 4.0f; + // m_local.d4.stq = t * 4.0f; - vmovaps(ptr[&m_env.d4.stq], xmm1); + vmovaps(ptr[&m_local.d4.stq], xmm1); } for(int j = 0, k = m_sel.fst ? 2 : 3; j < k; j++) @@ -340,25 +340,25 @@ void GSSetupPrimCodeGenerator::Texture() if(m_sel.fst) { - // m_env.d[i].si/ti = GSVector4i(v); + // m_local.d[i].si/ti = GSVector4i(v); vcvttps2dq(xmm2, xmm2); switch(j) { - case 0: vmovdqa(ptr[&m_env.d[i].si], xmm2); break; - case 1: vmovdqa(ptr[&m_env.d[i].ti], xmm2); break; + case 0: vmovdqa(ptr[&m_local.d[i].si], xmm2); break; + case 1: vmovdqa(ptr[&m_local.d[i].ti], xmm2); break; } } else { - // m_env.d[i].s/t/q = v; + // m_local.d[i].s/t/q = v; switch(j) { - case 0: vmovaps(ptr[&m_env.d[i].s], xmm2); break; - case 1: vmovaps(ptr[&m_env.d[i].t], xmm2); break; - case 2: vmovaps(ptr[&m_env.d[i].q], xmm2); break; + case 0: vmovaps(ptr[&m_local.d[i].s], xmm2); break; + case 1: vmovaps(ptr[&m_local.d[i].t], xmm2); break; + case 2: vmovaps(ptr[&m_local.d[i].q], xmm2); break; } } } @@ -375,16 +375,16 @@ void GSSetupPrimCodeGenerator::Texture() if(m_sel.fst) { - // m_env.d4.st = GSVector4i(t * 4.0f); + // m_local.d4.st = GSVector4i(t * 4.0f); cvttps2dq(xmm1, xmm1); - movdqa(ptr[&m_env.d4.st], xmm1); + movdqa(ptr[&m_local.d4.st], xmm1); } else { - // m_env.d4.stq = t * 4.0f; + // m_local.d4.stq = t * 4.0f; - movaps(ptr[&m_env.d4.stq], xmm1); + movaps(ptr[&m_local.d4.stq], xmm1); } for(int j = 0, k = m_sel.fst ? 2 : 3; j < k; j++) @@ -405,25 +405,25 @@ void GSSetupPrimCodeGenerator::Texture() if(m_sel.fst) { - // m_env.d[i].si/ti = GSVector4i(v); + // m_local.d[i].si/ti = GSVector4i(v); cvttps2dq(xmm2, xmm2); switch(j) { - case 0: movdqa(ptr[&m_env.d[i].si], xmm2); break; - case 1: movdqa(ptr[&m_env.d[i].ti], xmm2); break; + case 0: movdqa(ptr[&m_local.d[i].si], xmm2); break; + case 1: movdqa(ptr[&m_local.d[i].ti], xmm2); break; } } else { - // m_env.d[i].s/t/q = v; + // m_local.d[i].s/t/q = v; switch(j) { - case 0: movaps(ptr[&m_env.d[i].s], xmm2); break; - case 1: movaps(ptr[&m_env.d[i].t], xmm2); break; - case 2: movaps(ptr[&m_env.d[i].q], xmm2); break; + case 0: movaps(ptr[&m_local.d[i].s], xmm2); break; + case 1: movaps(ptr[&m_local.d[i].t], xmm2); break; + case 2: movaps(ptr[&m_local.d[i].q], xmm2); break; } } } @@ -446,13 +446,13 @@ void GSSetupPrimCodeGenerator::Color() vmovaps(xmm0, ptr[edx]); - // m_env.d4.c = GSVector4i(c * 4.0f).xzyw().ps32(); + // m_local.d4.c = GSVector4i(c * 4.0f).xzyw().ps32(); vmulps(xmm1, xmm0, xmm3); vcvttps2dq(xmm1, xmm1); vpshufd(xmm1, xmm1, _MM_SHUFFLE(3, 1, 2, 0)); vpackssdw(xmm1, xmm1); - vmovdqa(ptr[&m_env.d4.c], xmm1); + vmovdqa(ptr[&m_local.d4.c], xmm1); // xmm3 is not needed anymore @@ -476,10 +476,10 @@ void GSSetupPrimCodeGenerator::Color() vcvttps2dq(xmm1, xmm1); vpackssdw(xmm1, xmm1); - // m_env.d[i].rb = r.upl16(b); + // m_local.d[i].rb = r.upl16(b); vpunpcklwd(xmm0, xmm1); - vmovdqa(ptr[&m_env.d[i].rb], xmm0); + vmovdqa(ptr[&m_local.d[i].rb], xmm0); } // GSVector4 c = dscan.c; @@ -506,10 +506,10 @@ void GSSetupPrimCodeGenerator::Color() vcvttps2dq(xmm1, xmm1); vpackssdw(xmm1, xmm1); - // m_env.d[i].ga = g.upl16(a); + // m_local.d[i].ga = g.upl16(a); vpunpcklwd(xmm0, xmm1); - vmovdqa(ptr[&m_env.d[i].ga], xmm0); + vmovdqa(ptr[&m_local.d[i].ga], xmm0); } } else @@ -530,14 +530,14 @@ void GSSetupPrimCodeGenerator::Color() vpsrlw(xmm0, 7); } - // m_env.c.rb = c.xxxx(); - // m_env.c.ga = c.zzzz(); + // m_local.c.rb = c.xxxx(); + // m_local.c.ga = c.zzzz(); vpshufd(xmm1, xmm0, _MM_SHUFFLE(0, 0, 0, 0)); vpshufd(xmm2, xmm0, _MM_SHUFFLE(2, 2, 2, 2)); - vmovdqa(ptr[&m_env.c.rb], xmm1); - vmovdqa(ptr[&m_env.c.ga], xmm2); + vmovdqa(ptr[&m_local.c.rb], xmm1); + vmovdqa(ptr[&m_local.c.ga], xmm2); } } else @@ -549,14 +549,14 @@ void GSSetupPrimCodeGenerator::Color() movaps(xmm0, ptr[edx]); movaps(xmm1, xmm0); - // m_env.d4.c = GSVector4i(c * 4.0f).xzyw().ps32(); + // m_local.d4.c = GSVector4i(c * 4.0f).xzyw().ps32(); movaps(xmm2, xmm0); mulps(xmm2, xmm3); cvttps2dq(xmm2, xmm2); pshufd(xmm2, xmm2, _MM_SHUFFLE(3, 1, 2, 0)); packssdw(xmm2, xmm2); - movdqa(ptr[&m_env.d4.c], xmm2); + movdqa(ptr[&m_local.d4.c], xmm2); // xmm3 is not needed anymore @@ -582,10 +582,10 @@ void GSSetupPrimCodeGenerator::Color() cvttps2dq(xmm3, xmm3); packssdw(xmm3, xmm3); - // m_env.d[i].rb = r.upl16(b); + // m_local.d[i].rb = r.upl16(b); punpcklwd(xmm2, xmm3); - movdqa(ptr[&m_env.d[i].rb], xmm2); + movdqa(ptr[&m_local.d[i].rb], xmm2); } // GSVector4 c = dscan.c; @@ -615,10 +615,10 @@ void GSSetupPrimCodeGenerator::Color() cvttps2dq(xmm3, xmm3); packssdw(xmm3, xmm3); - // m_env.d[i].ga = g.upl16(a); + // m_local.d[i].ga = g.upl16(a); punpcklwd(xmm2, xmm3); - movdqa(ptr[&m_env.d[i].ga], xmm2); + movdqa(ptr[&m_local.d[i].ga], xmm2); } } else @@ -640,14 +640,14 @@ void GSSetupPrimCodeGenerator::Color() psrlw(xmm0, 7); } - // m_env.c.rb = c.xxxx(); - // m_env.c.ga = c.zzzz(); + // m_local.c.rb = c.xxxx(); + // m_local.c.ga = c.zzzz(); pshufd(xmm1, xmm0, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm2, xmm0, _MM_SHUFFLE(2, 2, 2, 2)); - movdqa(ptr[&m_env.c.rb], xmm1); - movdqa(ptr[&m_env.c.ga], xmm2); + movdqa(ptr[&m_local.c.rb], xmm1); + movdqa(ptr[&m_local.c.ga], xmm2); } } } diff --git a/plugins/GSdx/GSSetupPrimCodeGenerator.h b/plugins/GSdx/GSSetupPrimCodeGenerator.h index a53b7a71f8..ba43dda5b7 100644 --- a/plugins/GSdx/GSSetupPrimCodeGenerator.h +++ b/plugins/GSdx/GSSetupPrimCodeGenerator.h @@ -30,8 +30,8 @@ class GSSetupPrimCodeGenerator : public GSCodeGenerator static const GSVector4 m_shift[5]; - GSScanlineEnvironment& m_env; GSScanlineSelector m_sel; + GSScanlineLocalData& m_local; struct {uint32 z:1, f:1, t:1, c:1;} m_en; diff --git a/plugins/GSdx/GSVertexTrace.cpp b/plugins/GSdx/GSVertexTrace.cpp index 7629ec5d75..5e4c468e31 100644 --- a/plugins/GSdx/GSVertexTrace.cpp +++ b/plugins/GSdx/GSVertexTrace.cpp @@ -126,6 +126,12 @@ void GSVertexTrace::Update(const GSVertexHW11* v, int count, GS_PRIM_CLASS primc using namespace Xbyak; +static const int _args = 0; +static const int _v = _args + 4; +static const int _count = _args + 8; +static const int _min = _args + 12; +static const int _max = _args + 16; + GSVertexTrace::CGSW::CGSW(const void* param, uint32 key, void* code, size_t maxsize) : GSCodeGenerator(code, maxsize) { @@ -133,8 +139,6 @@ GSVertexTrace::CGSW::CGSW(const void* param, uint32 key, void* code, size_t maxs #error TODO #endif - const int params = 0; - uint32 primclass = (key >> 0) & 3; uint32 iip = (key >> 2) & 1; uint32 tme = (key >> 3) & 1; @@ -157,11 +161,6 @@ GSVertexTrace::CGSW::CGSW(const void* param, uint32 key, void* code, size_t maxs break; } - const int _v = params + 4; - const int _count = params + 8; - const int _min = params + 12; - const int _max = params + 16; - // if(m_cpu.has(util::Cpu::tAVX)) @@ -410,8 +409,6 @@ GSVertexTrace::CGHW9::CGHW9(const void* param, uint32 key, void* code, size_t ma #error TODO #endif - const int params = 0; - uint32 primclass = (key >> 0) & 3; uint32 iip = (key >> 2) & 1; uint32 tme = (key >> 3) & 1; @@ -436,11 +433,6 @@ GSVertexTrace::CGHW9::CGHW9(const void* param, uint32 key, void* code, size_t ma break; } - const int _v = params + 4; - const int _count = params + 8; - const int _min = params + 12; - const int _max = params + 16; - // if(m_cpu.has(util::Cpu::tAVX)) @@ -748,8 +740,6 @@ GSVertexTrace::CGHW11::CGHW11(const void* param, uint32 key, void* code, size_t #error TODO #endif - const int params = 0; - uint32 primclass = (key >> 0) & 3; uint32 iip = (key >> 2) & 1; uint32 tme = (key >> 3) & 1; @@ -772,11 +762,6 @@ GSVertexTrace::CGHW11::CGHW11(const void* param, uint32 key, void* code, size_t break; } - const int _v = params + 4; - const int _count = params + 8; - const int _min = params + 12; - const int _max = params + 16; - // if(m_cpu.has(util::Cpu::tAVX))