diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 2a71ab758b..f1030ee321 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -26,6 +26,7 @@ GSRenderer::GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev) : GSState(base, mt, irq) , m_dev(dev) , m_shader(0) + , m_vt(this) { m_interlace = theApp.GetConfig("interlace", 0); m_aspectratio = theApp.GetConfig("aspectratio", 1); diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index 0ee1427fd0..d671bdc7ea 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -115,7 +115,7 @@ protected: if(!m_dev->IsLost()) { - m_vt.Update(m_vertices, m_count, PRIM, m_context); + m_vt.Update(m_vertices, m_count, GSUtil::GetPrimClass(PRIM->PRIM)); Draw(); } diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index a0e5ee3a1a..9e8459c500 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -37,68 +37,86 @@ class GSRendererHW : public GSRendererT #pragma region hacks - typedef bool (GSRendererHW::*OI_Ptr)(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); + typedef bool (GSRendererHW::*OI_Ptr)(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); typedef void (GSRendererHW::*OO_Ptr)(); typedef bool (GSRendererHW::*CU_Ptr)(); - bool OI_FFXII(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + bool OI_FFXII(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { static uint32* video = NULL; - static bool ok = false; + static int lines = 0; - if(prim == GS_POINTLIST && m_count >= 448 * 448 && m_count <= 448 * 512) + if(lines == 0) { - // incoming pixels are stored in columns, one column is 16x512, total res 448x512 or 448x454 - - if(!video) video = new uint32[512 * 512]; - - for(int x = 0, i = 0, rows = m_count / 448; x < 448; x += 16) + if(m_vt.m_primclass == GS_LINE_CLASS && (m_count == 448 * 2 || m_count == 512 * 2)) { - uint32* dst = &video[x]; - - for(int y = 0; y < rows; y++, dst += 512) + lines = m_count / 2; + } + } + else + { + if(m_vt.m_primclass == GS_POINT_CLASS) + { + if(m_count >= 16 * 512) { - for(int j = 0; j < 16; j++, i++) + // incoming pixels are stored in columns, one column is 16x512, total res 448x512 or 448x454 + + if(!video) video = new uint32[512 * 512]; + + int ox = m_context->XYOFFSET.OFX; + int oy = m_context->XYOFFSET.OFY; + + for(int i = 0; i < m_count; i++) { - dst[j] = m_vertices[i].c0; + int x = ((int)m_vertices[i].p.x - ox) >> 4; + int y = ((int)m_vertices[i].p.y - oy) >> 4; + + // video[y * 448 + x] = m_vertices[i].c0; + video[(y << 8) + (y << 7) + (y << 6) + x] = m_vertices[i].c0; } + + return false; + } + else + { + lines = 0; } } + else if(m_vt.m_primclass == GS_LINE_CLASS) + { + if(m_count == lines * 2) + { + // normally, this step would copy the video onto screen with 512 texture mapped horizontal lines, + // but we use the stored video data to create a new texture, and replace the lines with two triangles - ok = true; + m_dev->Recycle(t->m_texture); - return false; - } - else if(prim == GS_LINELIST && m_count == 512 * 2 && ok) - { - // normally, this step would copy the video onto screen with 512 texture mapped horizontal lines, - // but we use the stored video data to create a new texture, and replace the lines with two triangles + t->m_texture = m_dev->CreateTexture(512, 512); - ok = false; + t->m_texture->Update(GSVector4i(0, 0, 448, lines), video, 448 * 4); - m_dev->Recycle(t->m_texture); + m_vertices[0] = m_vertices[0]; + m_vertices[1] = m_vertices[1]; + m_vertices[2] = m_vertices[m_count - 2]; + m_vertices[3] = m_vertices[1]; + m_vertices[4] = m_vertices[2]; + m_vertices[5] = m_vertices[m_count - 1]; - t->m_texture = m_dev->CreateTexture(512, 512); + m_count = 6; - t->m_texture->Update(GSVector4i(0, 0, 448, 512), video, 512 * 4); - - m_vertices[0] = m_vertices[0]; - m_vertices[1] = m_vertices[1]; - m_vertices[2] = m_vertices[m_count - 2]; - m_vertices[3] = m_vertices[1]; - m_vertices[4] = m_vertices[2]; - m_vertices[5] = m_vertices[m_count - 1]; - - prim = GS_TRIANGLELIST; - m_count = 6; - - return true; + m_vt.Update(m_vertices, m_count, GS_TRIANGLE_CLASS); + } + else + { + lines = 0; + } + } } return true; } - bool OI_FFX(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + bool OI_FFX(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { uint32 FBP = m_context->FRAME.Block(); uint32 ZBP = m_context->ZBUF.Block(); @@ -114,7 +132,7 @@ class GSRendererHW : public GSRendererT return true; } - bool OI_MetalSlug6(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + bool OI_MetalSlug6(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { // missing red channel fix @@ -126,10 +144,12 @@ class GSRendererHW : public GSRendererT } } + m_vt.Update(m_vertices, m_count, m_vt.m_primclass); + return true; } - bool OI_GodOfWar2(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + bool OI_GodOfWar2(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { uint32 FBP = m_context->FRAME.Block(); uint32 FBW = m_context->FRAME.FBW; @@ -156,7 +176,7 @@ class GSRendererHW : public GSRendererT return true; } - bool OI_SimpsonsGame(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + bool OI_SimpsonsGame(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { uint32 FBP = m_context->FRAME.Block(); uint32 FBW = m_context->FRAME.FBW; @@ -176,7 +196,7 @@ class GSRendererHW : public GSRendererT return true; } - bool OI_RozenMaidenGebetGarden(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + bool OI_RozenMaidenGebetGarden(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { if(!PRIM->TME) { @@ -222,9 +242,9 @@ class GSRendererHW : public GSRendererT return true; } - bool OI_PointListPalette(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + bool OI_PointListPalette(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { - if(prim == GS_POINTLIST && !PRIM->TME) + if(m_vt.m_primclass == GS_POINT_CLASS && !PRIM->TME) { uint32 FBP = m_context->FRAME.Block(); uint32 FBW = m_context->FRAME.FBW; @@ -586,9 +606,7 @@ protected: s_n++; } - int prim = PRIM->PRIM; - - if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(prim, rt->m_texture, ds->m_texture, tex)) + if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt->m_texture, ds->m_texture, tex)) { return; } diff --git a/plugins/GSdx/GSVertexTrace.cpp b/plugins/GSdx/GSVertexTrace.cpp index 6fe7330d5f..deb44bdc2d 100644 --- a/plugins/GSdx/GSVertexTrace.cpp +++ b/plugins/GSdx/GSVertexTrace.cpp @@ -24,14 +24,20 @@ #include "stdafx.h" #include "GSVertexTrace.h" #include "GSUtil.h" +#include "GSState.h" -uint32 GSVertexTrace::Hash(const GIFRegPRIM* PRIM, const GSDrawingContext* context) +GSVertexTrace::GSVertexTrace(const GSState* state) + : m_state(state) { - m_primclass = GSUtil::GetPrimClass(PRIM->PRIM); +} - uint32 hash = m_primclass | (PRIM->IIP << 2) | (PRIM->TME << 3) | (PRIM->FST << 4); +uint32 GSVertexTrace::Hash(GS_PRIM_CLASS primclass) +{ + m_primclass = primclass; - if(!(PRIM->TME && context->TEX0.TFX == TFX_DECAL && context->TEX0.TCC)) + uint32 hash = m_primclass | (m_state->PRIM->IIP << 2) | (m_state->PRIM->TME << 3) | (m_state->PRIM->FST << 4); + + if(!(m_state->PRIM->TME && m_state->m_context->TEX0.TFX == TFX_DECAL && m_state->m_context->TEX0.TCC)) { hash |= 1 << 5; } @@ -39,18 +45,20 @@ uint32 GSVertexTrace::Hash(const GIFRegPRIM* PRIM, const GSDrawingContext* conte return hash; } -void GSVertexTrace::Update(const GSVertexSW* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context) +void GSVertexTrace::Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass) { - m_map_sw[Hash(PRIM, context)](v, count, m_min, m_max); + m_map_sw[Hash(primclass)](v, count, m_min, m_max); m_eq.value = (m_min.c == m_max.c).mask() | ((m_min.p == m_max.p).mask() << 16) | ((m_min.t == m_max.t).mask() << 20); m_alpha.valid = false; } -void GSVertexTrace::Update(const GSVertexHW9* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context) -{ - m_map_hw9[Hash(PRIM, context)](v, count, m_min, m_max); +void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass) +{ + m_map_hw9[Hash(primclass)](v, count, m_min, m_max); + + const GSDrawingContext* context = m_state->m_context; GSVector4 o(context->XYOFFSET); GSVector4 s(1.0f / 16, 1.0f / 16, 1.0f, 1.0f); @@ -58,9 +66,9 @@ void GSVertexTrace::Update(const GSVertexHW9* v, int count, const GIFRegPRIM* PR m_min.p = (m_min.p - o) * s; m_max.p = (m_max.p - o) * s; - if(PRIM->TME) + if(m_state->PRIM->TME) { - if(PRIM->FST) + if(m_state->PRIM->FST) { s = GSVector4(1 << (16 - 4), 1).xxyy(); } @@ -78,9 +86,11 @@ void GSVertexTrace::Update(const GSVertexHW9* v, int count, const GIFRegPRIM* PR m_alpha.valid = false; } -void GSVertexTrace::Update(const GSVertexHW10* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context) +void GSVertexTrace::Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass) { - m_map_hw10[Hash(PRIM, context)](v, count, m_min, m_max); + m_map_hw10[Hash(primclass)](v, count, m_min, m_max); + + const GSDrawingContext* context = m_state->m_context; GSVector4 o(context->XYOFFSET); GSVector4 s(1.0f / 16, 1.0f / 16, 2.0f, 1.0f); @@ -88,9 +98,9 @@ void GSVertexTrace::Update(const GSVertexHW10* v, int count, const GIFRegPRIM* P m_min.p = (m_min.p - o) * s; m_max.p = (m_max.p - o) * s; - if(PRIM->TME) + if(m_state->PRIM->TME) { - if(PRIM->FST) + if(m_state->PRIM->FST) { s = GSVector4(1 << (16 - 4), 1).xxyy(); } diff --git a/plugins/GSdx/GSVertexTrace.h b/plugins/GSdx/GSVertexTrace.h index e8e176a4d8..eaed4bf267 100644 --- a/plugins/GSdx/GSVertexTrace.h +++ b/plugins/GSdx/GSVertexTrace.h @@ -29,6 +29,8 @@ #include "xbyak/xbyak.h" #include "xbyak/xbyak_util.h" +class GSState; + __declspec(align(16)) class GSVertexTrace { struct Vertex {GSVector4i c; GSVector4 p, t;}; @@ -83,7 +85,9 @@ __declspec(align(16)) class GSVertexTrace GSVertexTraceMapHW9 m_map_hw9; GSVertexTraceMapHW10 m_map_hw10; - uint32 Hash(const GIFRegPRIM* PRIM, const GSDrawingContext* context); + uint32 Hash(GS_PRIM_CLASS primclass); + + const GSState* m_state; public: GS_PRIM_CLASS m_primclass; @@ -97,8 +101,10 @@ public: struct {uint32 rgba:16, xyzf:4, stq:4;}; } m_eq; - void Update(const GSVertexSW* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context); - void Update(const GSVertexHW9* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context); - void Update(const GSVertexHW10* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context); - void Update(const GSVertexNull* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context) {} + GSVertexTrace(const GSState* state); + + void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass); + void Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass); + void Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass); + void Update(const GSVertexNull* v, int count, GS_PRIM_CLASS primclass) {} };