From 7bb9a3cc2555d3bcaf4120d2c249e1a0448db3f3 Mon Sep 17 00:00:00 2001 From: gabest11 Date: Sat, 27 Jun 2009 03:32:33 +0000 Subject: [PATCH] GSdx: changed a lot of things, expect new bugs :P git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1439 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GPURenderer.cpp | 2 +- plugins/GSdx/GS.cpp | 12 +- plugins/GSdx/GS.h | 33 +- plugins/GSdx/GSCrc.cpp | 3 +- plugins/GSdx/GSCrc.h | 1 + plugins/GSdx/GSDrawingContext.h | 2 +- plugins/GSdx/GSFunctionMap.h | 16 +- plugins/GSdx/GSLocalMemory.cpp | 149 +-- plugins/GSdx/GSRenderer.cpp | 19 +- plugins/GSdx/GSRenderer.h | 7 +- plugins/GSdx/GSRendererDX.cpp | 23 + plugins/GSdx/GSRendererDX.h | 338 +++++ plugins/GSdx/GSRendererDX10.cpp | 266 ++++ .../{GSRendererHW10.h => GSRendererDX10.h} | 11 +- plugins/GSdx/GSRendererDX11.cpp | 266 ++++ .../{GSRendererHW11.h => GSRendererDX11.h} | 10 +- plugins/GSdx/GSRendererDX9.cpp | 322 +++++ .../GSdx/{GSRendererHW9.h => GSRendererDX9.h} | 13 +- plugins/GSdx/GSRendererHW.h | 46 +- plugins/GSdx/GSRendererHW10.cpp | 529 -------- plugins/GSdx/GSRendererHW11.cpp | 529 -------- plugins/GSdx/GSRendererHW9.cpp | 573 --------- plugins/GSdx/GSRendererOGL.cpp | 3 +- plugins/GSdx/GSRendererOGL.h | 2 +- plugins/GSdx/GSRendererSW.cpp | 4 +- plugins/GSdx/GSTextureCache.cpp | 1133 +++++++++-------- plugins/GSdx/GSTextureCache.h | 125 +- plugins/GSdx/GSTextureCache10.cpp | 464 +++---- plugins/GSdx/GSTextureCache10.h | 34 +- plugins/GSdx/GSTextureCache11.cpp | 381 +++--- plugins/GSdx/GSTextureCache11.h | 34 +- plugins/GSdx/GSTextureCache9.cpp | 378 +++--- plugins/GSdx/GSTextureCache9.h | 34 +- plugins/GSdx/GSTextureCacheOGL.cpp | 23 +- plugins/GSdx/GSTextureCacheOGL.h | 34 +- plugins/GSdx/GSTextureCacheSW.cpp | 47 +- plugins/GSdx/GSTextureCacheSW.h | 3 - plugins/GSdx/GSTextureFX.cpp | 13 + plugins/GSdx/GSTextureFX.h | 25 +- plugins/GSdx/GSTextureFX10.cpp | 92 +- plugins/GSdx/GSTextureFX10.h | 15 +- plugins/GSdx/GSTextureFX11.cpp | 94 +- plugins/GSdx/GSTextureFX11.h | 15 +- plugins/GSdx/GSTextureFX9.cpp | 75 +- plugins/GSdx/GSTextureFX9.h | 14 +- plugins/GSdx/GSVector.cpp | 12 +- plugins/GSdx/GSVector.h | 27 +- plugins/GSdx/GSVertexHW.h | 18 +- plugins/GSdx/GSdx_vs2008.vcproj | 120 +- plugins/GSdx/GSdx_vs2010.vcxproj | 12 +- plugins/GSdx/GSdx_vs2010.vcxproj.filters | 12 +- plugins/GSdx/res/tfx.fx | 28 +- 52 files changed, 3004 insertions(+), 3437 deletions(-) create mode 100644 plugins/GSdx/GSRendererDX.cpp create mode 100644 plugins/GSdx/GSRendererDX.h create mode 100644 plugins/GSdx/GSRendererDX10.cpp rename plugins/GSdx/{GSRendererHW10.h => GSRendererDX10.h} (86%) create mode 100644 plugins/GSdx/GSRendererDX11.cpp rename plugins/GSdx/{GSRendererHW11.h => GSRendererDX11.h} (83%) create mode 100644 plugins/GSdx/GSRendererDX9.cpp rename plugins/GSdx/{GSRendererHW9.h => GSRendererDX9.h} (85%) delete mode 100644 plugins/GSdx/GSRendererHW10.cpp delete mode 100644 plugins/GSdx/GSRendererHW11.cpp delete mode 100644 plugins/GSdx/GSRendererHW9.cpp diff --git a/plugins/GSdx/GPURenderer.cpp b/plugins/GSdx/GPURenderer.cpp index 944d5d791..4e2ba0d3a 100644 --- a/plugins/GSdx/GPURenderer.cpp +++ b/plugins/GSdx/GPURenderer.cpp @@ -185,7 +185,7 @@ LRESULT CALLBACK GPURenderer::WndProc(HWND hWnd, UINT message, WPARAM wParam, LP if(i != m_wnd2gpu.end()) { - return (*i).second->OnMessage(message, wParam, lParam); + return i->second->OnMessage(message, wParam, lParam); } ASSERT(0); diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index 67aeab825..f7751d5d3 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -21,9 +21,9 @@ #include "stdafx.h" #include "GSUtil.h" -#include "GSRendererHW9.h" -#include "GSRendererHW10.h" -#include "GSRendererHW11.h" +#include "GSRendererDX9.h" +#include "GSRendererDX10.h" +#include "GSRendererDX11.h" #include "GSRendererOGL.h" #include "GSRendererSW.h" #include "GSRendererNull.h" @@ -121,13 +121,13 @@ static INT32 GSopen(void* dsp, char* title, int mt, int renderer) switch(renderer) { default: - case 0: s_gs = new GSRendererHW9(s_basemem, !!mt, s_irq); break; + case 0: s_gs = new GSRendererDX9(s_basemem, !!mt, s_irq); break; case 1: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice9()); break; case 2: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice9()); break; - case 3: s_gs = new GSRendererHW10(s_basemem, !!mt, s_irq); break; + case 3: s_gs = new GSRendererDX10(s_basemem, !!mt, s_irq); break; case 4: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice10()); break; case 5: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice10()); break; - case 6: s_gs = new GSRendererHW11(s_basemem, !!mt, s_irq); break; + case 6: s_gs = new GSRendererDX11(s_basemem, !!mt, s_irq); break; case 7: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice11()); break; case 8: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice11()); break; #if 0 diff --git a/plugins/GSdx/GS.h b/plugins/GSdx/GS.h index 2e523d900..3ef534c9b 100644 --- a/plugins/GSdx/GS.h +++ b/plugins/GSdx/GS.h @@ -28,6 +28,9 @@ #define PLUGIN_VERSION 15 +#define MAX_PAGES 512 +#define MAX_BLOCKS 16384 + #include "GSVector.h" #pragma pack(push, 1) @@ -813,13 +816,39 @@ REG64_(GIFReg, TEX1) uint32 K:12; uint32 _PAD4:20; REG_END2 + + bool IsMinLinear() const {return (MMIN == 1) || (MMIN & 4);} + bool IsMagLinear() const {return MMAG;} + bool IsLinear() const { - bool mmag = (MMAG & 1); - bool mmin = (MMIN == 1) || (MMIN & 4); + bool mmin = IsMinLinear(); + bool mmag = IsMagLinear(); return !LCM ? mmag || mmin : K <= 0 ? mmag : mmin; } + + bool IsLinear(float qmin, float qmax) const + { + bool mmin = IsMinLinear(); + bool mmag = IsMagLinear(); + + if(mmag == mmin) return mmag; + + float LODmin = K; + float LODmax = K; + + if(!LCM) + { + float f = (float)(1 << L) / log(2.0f); + + LODmin += log(1.0f / abs(qmax)) * f; + LODmax += log(1.0f / abs(qmin)) * f; + } + + return LODmax <= 0 ? mmag : LODmin > 0 ? mmin : mmag || mmin; + } + REG_END2 REG64_(GIFReg, TEX2) diff --git a/plugins/GSdx/GSCrc.cpp b/plugins/GSdx/GSCrc.cpp index a5c6977c0..00fa94258 100644 --- a/plugins/GSdx/GSCrc.cpp +++ b/plugins/GSdx/GSCrc.cpp @@ -31,6 +31,7 @@ CRC::Game CRC::m_games[] = {0xA6167B59, Lamune, JP, PointListPalette}, {0xDDB59F46, KyuuketsuKitanMoonties, JP, PointListPalette}, {0xC8EE2562, PiaCarroteYoukosoGPGakuenPrincess, JP, PointListPalette}, + {0x6CF94A43, KazokuKeikakuKokoroNoKizuna, JP, PointListPalette}, {0xa39517ab, FFX, EU, 0}, {0xa39517ae, FFX, FR, 0}, {0x941bb7d9, FFX, DE, 0}, @@ -156,7 +157,7 @@ CRC::Game CRC::Lookup(uint32 crc) if(i != m_map.end()) { - return *(*i).second; + return *i->second; } return m_games[0]; diff --git a/plugins/GSdx/GSCrc.h b/plugins/GSdx/GSCrc.h index d5791c7b7..06f6698d5 100644 --- a/plugins/GSdx/GSCrc.h +++ b/plugins/GSdx/GSCrc.h @@ -33,6 +33,7 @@ public: Lamune, KyuuketsuKitanMoonties, PiaCarroteYoukosoGPGakuenPrincess, + KazokuKeikakuKokoroNoKizuna, FFX, FFX2, FFXII, diff --git a/plugins/GSdx/GSDrawingContext.h b/plugins/GSdx/GSDrawingContext.h index 0f72f2f93..75e4b73ce 100644 --- a/plugins/GSdx/GSDrawingContext.h +++ b/plugins/GSdx/GSDrawingContext.h @@ -89,7 +89,7 @@ public: (int)SCISSOR.SCAX1 + 1, (int)SCISSOR.SCAY1 + 1); - scissor.ex = GSVector4i( + scissor.ex = GSVector4( (int)SCISSOR.SCAX0, (int)SCISSOR.SCAY0, (int)SCISSOR.SCAX1, diff --git a/plugins/GSdx/GSFunctionMap.h b/plugins/GSdx/GSFunctionMap.h index b825e7ea5..050e49a92 100644 --- a/plugins/GSdx/GSFunctionMap.h +++ b/plugins/GSdx/GSFunctionMap.h @@ -68,7 +68,7 @@ public: { for(hash_map::iterator i = m_map_active.begin(); i != m_map_active.end(); i++) { - delete (*i).second; + delete i->second; } } @@ -80,7 +80,7 @@ public: if(i != m_map_active.end()) { - m_active = (*i).second; + m_active = i->second; } else { @@ -92,7 +92,7 @@ public: p->frame = (uint64)-1; - p->f = i != m_map.end() ? (*i).second : GetDefaultFunction(key); + p->f = i != m_map.end() ? i->second : GetDefaultFunction(key); m_map_active[key] = p; @@ -123,7 +123,7 @@ public: for(hash_map::iterator i = m_map_active.begin(); i != m_map_active.end(); i++) { - ActivePtr* p = (*i).second; + ActivePtr* p = i->second; if(p->frames) { @@ -133,8 +133,8 @@ public: for(hash_map::iterator i = m_map_active.begin(); i != m_map_active.end(); i++) { - KEY key = (*i).first; - ActivePtr* p = (*i).second; + KEY key = i->first; + ActivePtr* p = i->second; if(p->frames > 0) { @@ -179,7 +179,7 @@ public: { for(hash_map::iterator i = m_cgmap.begin(); i != m_cgmap.end(); i++) { - delete (*i).second; + delete i->second; } } @@ -191,7 +191,7 @@ public: if(i != m_cgmap.end()) { - cg = (*i).second; + cg = i->second; } else { diff --git a/plugins/GSdx/GSLocalMemory.cpp b/plugins/GSdx/GSLocalMemory.cpp index 8f3313dfe..7d5a78fbe 100644 --- a/plugins/GSdx/GSLocalMemory.cpp +++ b/plugins/GSdx/GSLocalMemory.cpp @@ -30,14 +30,17 @@ #define ASSERT_BLOCK(r, w, h) \ ASSERT((r).width() >= w && (r).height() >= h && !((r).left&(w-1)) && !((r).top&(h-1)) && !((r).right&(w-1)) && !((r).bottom&(h-1))); \ -#define FOREACH_BLOCK_START(w, h, bpp) \ +#define FOREACH_BLOCK_START(w, h, bpp, format) \ + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[format]; \ uint32 bp = TEX0.TBP0; \ uint32 bw = TEX0.TBW; \ int offset = dstpitch * h - r.width() * bpp / 8; \ for(int y = r.top, ye = r.bottom; y < ye; y += h, dst += offset) \ { ASSERT_BLOCK(r, w, h); \ + uint32 base = psm.bn(0, y, bp, bw); \ for(int x = r.left, xe = r.right; x < xe; x += w, dst += w * bpp / 8) \ { \ + const uint8* src = BlockPtr(base + psm.blockOffset[x >> 3]); \ #define FOREACH_BLOCK_END }} @@ -462,7 +465,7 @@ GSLocalMemory::~GSLocalMemory() for(hash_map::iterator i = m_omap.begin(); i != m_omap.end(); i++) { - Offset* o = (*i).second; + Offset* o = i->second; _aligned_free(o->col[0]); @@ -471,7 +474,7 @@ GSLocalMemory::~GSLocalMemory() for(hash_map::iterator i = m_o4map.begin(); i != m_o4map.end(); i++) { - _aligned_free((*i).second); + _aligned_free(i->second); } } @@ -487,7 +490,7 @@ GSLocalMemory::Offset* GSLocalMemory::GetOffset(uint32 bp, uint32 bw, uint32 psm if(i != m_omap.end()) { - return (*i).second; + return i->second; } Offset* o = (Offset*)_aligned_malloc(sizeof(Offset), 16); @@ -536,7 +539,7 @@ GSLocalMemory::Offset4* GSLocalMemory::GetOffset4(const GIFRegFRAME& FRAME, cons if(i != m_o4map.end()) { - return (*i).second; + return i->second; } Offset4* o = (Offset4*)_aligned_malloc(sizeof(Offset4), 16); @@ -1435,9 +1438,9 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB void GSLocalMemory::ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT32) { - ReadBlock32(BlockPtr32(x, y, bp, bw), dst, dstpitch); + ReadBlock32(src, dst, dstpitch); } FOREACH_BLOCK_END } @@ -1446,17 +1449,17 @@ void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, { if(TEXA.AEM) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT24) { - ReadAndExpandBlock24(BlockPtr32(x, y, bp, bw), dst, dstpitch, TEXA); + ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } else { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT24) { - ReadAndExpandBlock24(BlockPtr32(x, y, bp, bw), dst, dstpitch, TEXA); + ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } @@ -1466,9 +1469,9 @@ void GSLocalMemory::ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, { __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(16, 8, 32) + FOREACH_BLOCK_START(16, 8, 32, PSM_PSMCT16) { - ReadBlock16(BlockPtr16(x, y, bp, bw), (uint8*)block, sizeof(block) / 8); + ReadBlock16(src, (uint8*)block, sizeof(block) / 8); ExpandBlock16(block, dst, dstpitch, TEXA); } @@ -1479,9 +1482,9 @@ void GSLocalMemory::ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch { __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(16, 8, 32) + FOREACH_BLOCK_START(16, 8, 32, PSM_PSMCT16S) { - ReadBlock16(BlockPtr16S(x, y, bp, bw), (uint8*)block, sizeof(block) / 8); + ReadBlock16(src, (uint8*)block, sizeof(block) / 8); ExpandBlock16(block, dst, dstpitch, TEXA); } @@ -1492,9 +1495,9 @@ void GSLocalMemory::ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, { const uint32* pal = m_clut; - FOREACH_BLOCK_START(16, 16, 32) + FOREACH_BLOCK_START(16, 16, 32, PSM_PSMT8) { - ReadAndExpandBlock8_32(BlockPtr8(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock8_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1503,9 +1506,9 @@ void GSLocalMemory::ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, { const uint64* pal = m_clut; - FOREACH_BLOCK_START(32, 16, 32) + FOREACH_BLOCK_START(32, 16, 32, PSM_PSMT4) { - ReadAndExpandBlock4_32(BlockPtr4(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock4_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1514,9 +1517,9 @@ void GSLocalMemory::ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, { const uint32* pal = m_clut; - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT8H) { - ReadAndExpandBlock8H_32(BlockPtr32(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock8H_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1525,9 +1528,9 @@ void GSLocalMemory::ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch { const uint32* pal = m_clut; - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HL) { - ReadAndExpandBlock4HL_32(BlockPtr32(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock4HL_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1536,18 +1539,18 @@ void GSLocalMemory::ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch { const uint32* pal = m_clut; - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HH) { - ReadAndExpandBlock4HH_32(BlockPtr32(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock4HH_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } void GSLocalMemory::ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ32) { - ReadBlock32(BlockPtr32Z(x, y, bp, bw), dst, dstpitch); + ReadBlock32(src, dst, dstpitch); } FOREACH_BLOCK_END } @@ -1556,17 +1559,17 @@ void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch { if(TEXA.AEM) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ24) { - ReadAndExpandBlock24(BlockPtr32Z(x, y, bp, bw), dst, dstpitch, TEXA); + ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } else { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ24) { - ReadAndExpandBlock24(BlockPtr32Z(x, y, bp, bw), dst, dstpitch, TEXA); + ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } FOREACH_BLOCK_END } @@ -1576,9 +1579,9 @@ void GSLocalMemory::ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch { __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(16, 8, 32) + FOREACH_BLOCK_START(16, 8, 32, PSM_PSMZ16) { - ReadBlock16(BlockPtr16Z(x, y, bp, bw), (uint8*)block, sizeof(block) / 8); + ReadBlock16(src, (uint8*)block, sizeof(block) / 8); ExpandBlock16(block, dst, dstpitch, TEXA); } @@ -1589,9 +1592,9 @@ void GSLocalMemory::ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitc { __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(16, 8, 32) + FOREACH_BLOCK_START(16, 8, 32, PSM_PSMZ16S) { - ReadBlock16(BlockPtr16SZ(x, y, bp, bw), (uint8*)block, sizeof(block) / 8); + ReadBlock16(src, (uint8*)block, sizeof(block) / 8); ExpandBlock16(block, dst, dstpitch, TEXA); } @@ -1736,18 +1739,18 @@ void GSLocalMemory::ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, c void GSLocalMemory::ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 8, 16) + FOREACH_BLOCK_START(16, 8, 16, PSM_PSMCT16) { - ReadBlock16(BlockPtr16(x, y, bp, bw), dst, dstpitch); + ReadBlock16(src, dst, dstpitch); } FOREACH_BLOCK_END } void GSLocalMemory::ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 8, 16) + FOREACH_BLOCK_START(16, 8, 16, PSM_PSMCT16S) { - ReadBlock16(BlockPtr16S(x, y, bp, bw), dst, dstpitch); + ReadBlock16(src, dst, dstpitch); } FOREACH_BLOCK_END } @@ -1758,9 +1761,9 @@ void GSLocalMemory::ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(16, 16, 32) + FOREACH_BLOCK_START(16, 16, 32, PSM_PSMT8) { - ReadAndExpandBlock8_32(BlockPtr8(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock8_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1770,9 +1773,9 @@ void GSLocalMemory::ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch __declspec(align(16)) uint8 block[16 * 16]; - FOREACH_BLOCK_START(16, 16, 16) + FOREACH_BLOCK_START(16, 16, 16, PSM_PSMT8) { - ReadBlock8(BlockPtr8(x, y, bp, bw), (uint8*)block, sizeof(block) / 16); + ReadBlock8(src, (uint8*)block, sizeof(block) / 16); ExpandBlock8_16(block, dst, dstpitch, pal); } @@ -1786,9 +1789,9 @@ void GSLocalMemory::ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(32, 16, 32) + FOREACH_BLOCK_START(32, 16, 32, PSM_PSMT4) { - ReadAndExpandBlock4_32(BlockPtr4(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock4_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1798,9 +1801,9 @@ void GSLocalMemory::ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch __declspec(align(16)) uint8 block[(32 / 2) * 16]; - FOREACH_BLOCK_START(32, 16, 16) + FOREACH_BLOCK_START(32, 16, 16, PSM_PSMT4) { - ReadBlock4(BlockPtr4(x, y, bp, bw), (uint8*)block, sizeof(block) / 16); + ReadBlock4(src, (uint8*)block, sizeof(block) / 16); ExpandBlock4_16(block, dst, dstpitch, pal); } @@ -1814,9 +1817,9 @@ void GSLocalMemory::ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitc if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT8H) { - ReadAndExpandBlock8H_32(BlockPtr32(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock8H_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1826,9 +1829,9 @@ void GSLocalMemory::ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitc __declspec(align(16)) uint32 block[8 * 8]; - FOREACH_BLOCK_START(8, 8, 16) + FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT8H) { - ReadBlock32(BlockPtr32(x, y, bp, bw), (uint8*)block, sizeof(block) / 8); + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); ExpandBlock8H_16(block, dst, dstpitch, pal); } @@ -1842,9 +1845,9 @@ void GSLocalMemory::ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpit if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HL) { - ReadAndExpandBlock4HL_32(BlockPtr32(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock4HL_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1854,9 +1857,9 @@ void GSLocalMemory::ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpit __declspec(align(16)) uint32 block[8 * 8]; - FOREACH_BLOCK_START(8, 8, 16) + FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT4HL) { - ReadBlock32(BlockPtr32(x, y, bp, bw), (uint8*)block, sizeof(block) / 8); + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); ExpandBlock4HL_16(block, dst, dstpitch, pal); } @@ -1870,9 +1873,9 @@ void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpit if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) { - FOREACH_BLOCK_START(8, 8, 32) + FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HH) { - ReadAndExpandBlock4HH_32(BlockPtr32(x, y, bp, bw), dst, dstpitch, pal); + ReadAndExpandBlock4HH_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } @@ -1882,9 +1885,9 @@ void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpit __declspec(align(16)) uint32 block[8 * 8]; - FOREACH_BLOCK_START(8, 8, 16) + FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT4HH) { - ReadBlock32(BlockPtr32(x, y, bp, bw), (uint8*)block, sizeof(block) / 8); + ReadBlock32(src, (uint8*)block, sizeof(block) / 8); ExpandBlock4HH_16(block, dst, dstpitch, pal); } @@ -1894,18 +1897,18 @@ void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpit void GSLocalMemory::ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 8, 16) + FOREACH_BLOCK_START(16, 8, 16, PSM_PSMZ16) { - ReadBlock16(BlockPtr16Z(x, y, bp, bw), dst, dstpitch); + ReadBlock16(src, dst, dstpitch); } FOREACH_BLOCK_END } void GSLocalMemory::ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 8, 16) + FOREACH_BLOCK_START(16, 8, 16, PSM_PSMZ16S) { - ReadBlock16(BlockPtr16SZ(x, y, bp, bw), dst, dstpitch); + ReadBlock16(src, dst, dstpitch); } FOREACH_BLOCK_END } @@ -1958,45 +1961,45 @@ void GSLocalMemory::ReadTextureNP(const GSVector4i& r, uint8* dst, int dstpitch, void GSLocalMemory::ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(16, 16, 8) + FOREACH_BLOCK_START(16, 16, 8, PSM_PSMT8) { - ReadBlock8(BlockPtr8(x, y, bp, bw), dst, dstpitch); + ReadBlock8(src, dst, dstpitch); } FOREACH_BLOCK_END } void GSLocalMemory::ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(32, 16, 8) + FOREACH_BLOCK_START(32, 16, 8, PSM_PSMT4) { - ReadBlock4P(BlockPtr4(x, y, bp, bw), dst, dstpitch); + ReadBlock4P(src, dst, dstpitch); } FOREACH_BLOCK_END } void GSLocalMemory::ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 8) + FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT8H) { - ReadBlock8HP(BlockPtr32(x, y, bp, bw), dst, dstpitch); + ReadBlock8HP(src, dst, dstpitch); } FOREACH_BLOCK_END } void GSLocalMemory::ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 8) + FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT4HL) { - ReadBlock4HLP(BlockPtr32(x, y, bp, bw), dst, dstpitch); + ReadBlock4HLP(src, dst, dstpitch); } FOREACH_BLOCK_END } void GSLocalMemory::ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const { - FOREACH_BLOCK_START(8, 8, 8) + FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT4HH) { - ReadBlock4HHP(BlockPtr32(x, y, bp, bw), dst, dstpitch); + ReadBlock4HHP(src, dst, dstpitch); } FOREACH_BLOCK_END } diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 046483fba..b83f9cdcf 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -426,7 +426,7 @@ void GSRenderer::KeyEvent(GSKeyEventData* e) } } -void GSRenderer::GetTextureMinMax(GSVector4i& r) +void GSRenderer::GetTextureMinMax(GSVector4i& r, bool linear) { const GSDrawingContext* context = m_context; @@ -488,7 +488,7 @@ void GSRenderer::GetTextureMinMax(GSVector4i& r) { GSVector4 st = m_vt.m_min.t.xyxy(m_vt.m_max.t); - if(context->TEX1.IsLinear()) + if(linear) { st += GSVector4(-0x8000, 0x8000).xxyy(); } @@ -697,6 +697,21 @@ bool GSRenderer::TryAlphaTest(uint32& fm, uint32& zm) return true; } +bool GSRenderer::IsLinear() +{ + float qmin = m_vt.m_min.t.z; + float qmax = m_vt.m_max.t.z; + + if(PRIM->FST) + { + // assume Q = 1.0f => LOD > 0 (should not, but Q is very often bogus, 0 or DEN) + + qmin = qmax = 1.0f; + } + + return m_context->TEX1.IsLinear(qmin, qmax); +} + bool GSRenderer::IsOpaque() { if(PRIM->AA1) diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index 21f1651d4..1817ce078 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -53,9 +53,10 @@ protected: // following functions need m_vt to be initialized - void GetTextureMinMax(GSVector4i& r); + void GetTextureMinMax(GSVector4i& r, bool linear); void GetAlphaMinMax(); bool TryAlphaTest(uint32& fm, uint32& zm); + bool IsLinear(); bool IsOpaque(); public: @@ -127,6 +128,8 @@ protected: // FIXME: berserk fpsm = 27 (8H) Draw(); + + m_perfmon.Put(GSPerfMon::Draw, 1); } m_count = 0; @@ -222,9 +225,9 @@ protected: public: GSRendererT(uint8* base, bool mt, void (*irq)(), GSDevice* dev) : GSRenderer(base, mt, irq, dev) + , m_vertices(NULL) , m_count(0) , m_maxcount(0) - , m_vertices(NULL) { } diff --git a/plugins/GSdx/GSRendererDX.cpp b/plugins/GSdx/GSRendererDX.cpp new file mode 100644 index 000000000..77f6bfd19 --- /dev/null +++ b/plugins/GSdx/GSRendererDX.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererDX.h" \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX.h b/plugins/GSdx/GSRendererDX.h new file mode 100644 index 000000000..14a6fde4e --- /dev/null +++ b/plugins/GSdx/GSRendererDX.h @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +#include "GSRendererHW.h" +#include "GSTextureFX.h" + +template +class GSRendererDX : public GSRendererHW +{ + GSTextureFX* m_tfx; + bool m_logz; + bool m_fba; + +protected: + int m_topology; + GSVector2 m_pixelcenter; + + virtual void SetupDATE(GSTexture* rt, GSTexture* ds) {} + virtual void UpdateFBA(GSTexture* rt) {} + +public: + GSRendererDX(uint8* base, bool mt, void (*irq)(), GSDevice* dev, GSTextureCache* tc, GSTextureFX* tfx) + : GSRendererHW(base, mt, irq, dev, tc) + , m_tfx(tfx) + , m_topology(-1) + , m_pixelcenter(0, 0) + { + m_logz = !!theApp.GetConfig("logz", 0); + m_fba = !!theApp.GetConfig("fba", 1); + } + + virtual ~GSRendererDX() + { + delete m_tfx; + } + + bool Create(const string& title) + { + if(!__super::Create(title)) + return false; + + if(!m_tfx->Create(m_dev)) + return false; + + return true; + } + + void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) + { + GSDrawingEnvironment& env = m_env; + GSDrawingContext* context = m_context; + + // + + SetupDATE(rt, ds); + + // + + m_dev->BeginScene(); + + // om + + GSTextureFX::OMDepthStencilSelector om_dssel; + + om_dssel.zte = context->TEST.ZTE; + om_dssel.ztst = context->TEST.ZTST; + om_dssel.zwe = !context->ZBUF.ZMSK; + om_dssel.date = context->FRAME.PSM != PSM_PSMCT24 ? context->TEST.DATE : 0; + om_dssel.fba = m_fba ? context->FBA.FBA : 0; + + GSTextureFX::OMBlendSelector om_bsel; + + om_bsel.abe = !IsOpaque(); + om_bsel.a = context->ALPHA.A; + om_bsel.b = context->ALPHA.B; + om_bsel.c = context->ALPHA.C; + om_bsel.d = context->ALPHA.D; + om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff; + om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00; + om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000; + om_bsel.wa = (context->FRAME.FBMSK & 0xff000000) != 0xff000000; + + // vs + + GSTextureFX::VSSelector vs_sel; + + vs_sel.bppz = 0; + vs_sel.tme = PRIM->TME; + vs_sel.fst = PRIM->FST; + vs_sel.logz = m_logz ? 1 : 0; + vs_sel.prim = primclass; + + if(om_dssel.zte && om_dssel.ztst > 0 && om_dssel.zwe) + { + if(context->ZBUF.PSM == PSM_PSMZ24) + { + if(m_vt.m_max.p.z > 0xffffff) + { + ASSERT(m_vt.m_min.p.z > 0xffffff); + + vs_sel.bppz = 1; + om_dssel.ztst = 1; + } + } + else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) + { + if(m_vt.m_max.p.z > 0xffff) + { + ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo + + vs_sel.bppz = 2; + om_dssel.ztst = 1; + } + } + } + + GSTextureFX::VSConstantBuffer vs_cb; + + float sx = 2.0f * rt->m_scale.x / (rt->GetWidth() * 16); + float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16); + float ox = (float)(int)context->XYOFFSET.OFX; + float oy = (float)(int)context->XYOFFSET.OFY; + float ox2 = 2.0f * m_pixelcenter.x / rt->GetWidth(); + float oy2 = 2.0f * m_pixelcenter.y / rt->GetHeight(); + + vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f); + vs_cb.VertexOffset = GSVector4(ox * sx + ox2 + 1, -(oy * sy + oy2 + 1), 0.0f, -1.0f); + + if(PRIM->TME) + { + if(PRIM->FST) + { + vs_cb.TextureScale.x = 1.0f / (16 << context->TEX0.TW); + vs_cb.TextureScale.y = 1.0f / (16 << context->TEX0.TH); + } + else + { + vs_cb.TextureScale = GSVector2(1.0f, 1.0f); + } + } + + // gs + + GSTextureFX::GSSelector gs_sel; + + gs_sel.iip = PRIM->IIP; + gs_sel.prim = primclass; + + // ps + + GSTextureFX::PSSelector ps_sel; + + ps_sel.fst = PRIM->FST; + ps_sel.wms = context->CLAMP.WMS; + ps_sel.wmt = context->CLAMP.WMT; + ps_sel.bpp = 0; + ps_sel.aem = env.TEXA.AEM; + ps_sel.tfx = context->TEX0.TFX; + ps_sel.tcc = context->TEX0.TCC; + ps_sel.ate = context->TEST.ATE; + ps_sel.atst = context->TEST.ATST; + ps_sel.fog = PRIM->FGE; + ps_sel.clr1 = om_bsel.abe && om_bsel.a == 1 && om_bsel.b == 2 && om_bsel.d == 1; + ps_sel.fba = context->FBA.FBA; + ps_sel.aout = context->FRAME.PSM == PSM_PSMCT16 || context->FRAME.PSM == PSM_PSMCT16S || (context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0; + ps_sel.ltf = m_filter == 2 ? IsLinear() : m_filter; + + GSTextureFX::PSSamplerSelector ps_ssel; + + ps_ssel.tau = 0; + ps_ssel.tav = 0; + ps_ssel.ltf = ps_sel.ltf; + + GSTextureFX::PSConstantBuffer ps_cb; + + ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255; + + if(ps_sel.atst == 2 || ps_sel.atst == 5) + { + ps_cb.FogColor_AREF.a -= 0.9f / 255; + } + else if(ps_sel.atst == 3 || ps_sel.atst == 6) + { + ps_cb.FogColor_AREF.a += 0.9f / 255; + } + + if(tex) + { + ps_sel.bpp = tex->m_bpp; + + int w = tex->m_texture->GetWidth(); + int h = tex->m_texture->GetHeight(); + + ps_cb.WH = GSVector4((int)(1 << context->TEX0.TW), (int)(1 << context->TEX0.TH), w, h); + ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / GSVector4(w, h).xyxy(); + ps_cb.MinF_TA.z = (float)(int)env.TEXA.TA0 / 255; + ps_cb.MinF_TA.w = (float)(int)env.TEXA.TA1 / 255; + + switch(context->CLAMP.WMS) + { + case 0: + ps_ssel.tau = 1; + break; + case 1: + ps_ssel.tau = 0; + break; + case 2: + ps_cb.MinMax.x = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW); + ps_cb.MinMax.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); + ps_cb.MinF_TA.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); + ps_ssel.tau = 0; + break; + case 3: + ps_cb.MskFix.x = context->CLAMP.MINU; + ps_cb.MskFix.z = context->CLAMP.MAXU; + ps_ssel.tau = 1; + break; + default: + __assume(0); + } + + switch(context->CLAMP.WMT) + { + case 0: + ps_ssel.tav = 1; + break; + case 1: + ps_ssel.tav = 0; + break; + case 2: + ps_cb.MinMax.y = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH); + ps_cb.MinMax.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); + ps_cb.MinF_TA.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); + ps_ssel.tav = 0; + break; + case 3: + ps_cb.MskFix.y = context->CLAMP.MINV; + ps_cb.MskFix.w = context->CLAMP.MAXV; + ps_ssel.tav = 1; + break; + default: + __assume(0); + } + } + else + { + ps_sel.tfx = 4; + } + + // rs + + int w = rt->GetWidth(); + int h = rt->GetHeight(); + + GSVector4i scissor = GSVector4i(GSVector4(rt->m_scale).xyxy() * context->scissor.in).rintersect(GSVector4i(0, 0, w, h)); + + // + + uint8 afix = context->ALPHA.FIX; + + m_tfx->SetupOM(om_dssel, om_bsel, afix, rt, ds); + m_tfx->SetupIA(m_vertices, m_count, m_topology); + m_tfx->SetupVS(vs_sel, &vs_cb); + m_tfx->SetupGS(gs_sel); + m_tfx->SetupPS(ps_sel, &ps_cb, ps_ssel, tex ? tex->m_texture : NULL, tex ? tex->m_palette : NULL); + m_tfx->SetupRS(w, h, scissor); + + // draw + + if(context->TEST.DoFirstPass()) + { + m_dev->DrawPrimitive(); + } + + if(context->TEST.DoSecondPass()) + { + ASSERT(!env.PABE.PABE); + + static const uint32 iatst[] = {1, 0, 5, 6, 7, 2, 3, 4}; + + ps_sel.atst = iatst[ps_sel.atst]; + + m_tfx->UpdatePS(ps_sel, &ps_cb, ps_ssel); + + bool z = om_dssel.zwe; + bool r = om_bsel.wr; + bool g = om_bsel.wg; + bool b = om_bsel.wb; + bool a = om_bsel.wa; + + switch(context->TEST.AFAIL) + { + case 0: z = r = g = b = a = false; break; // none + case 1: z = false; break; // rgba + case 2: r = g = b = a = false; break; // z + case 3: z = a = false; break; // rgb + default: __assume(0); + } + + if(z || r || g || b || a) + { + om_dssel.zwe = z; + om_bsel.wr = r; + om_bsel.wg = g; + om_bsel.wb = b; + om_bsel.wa = a; + + m_tfx->UpdateOM(om_dssel, om_bsel, afix); + + m_dev->DrawPrimitive(); + } + } + + m_dev->EndScene(); + + if(om_dssel.fba) UpdateFBA(rt); + } +}; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX10.cpp b/plugins/GSdx/GSRendererDX10.cpp new file mode 100644 index 000000000..0bc018f78 --- /dev/null +++ b/plugins/GSdx/GSRendererDX10.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererDX10.h" +#include "GSCrc.h" +#include "resource.h" + +GSRendererDX10::GSRendererDX10(uint8* base, bool mt, void (*irq)()) + : GSRendererDX(base, mt, irq, new GSDevice10(), new GSTextureCache10(this), new GSTextureFX10()) +{ + InitVertexKick(); + + m_pixelcenter = GSVector2(-0.5f, -0.5f); +} + +bool GSRendererDX10::Create(const string& title) +{ + if(!__super::Create(title)) + return false; + + // + + D3D10_DEPTH_STENCIL_DESC dsd; + + memset(&dsd, 0, sizeof(dsd)); + + dsd.DepthEnable = false; + dsd.StencilEnable = true; + dsd.StencilReadMask = 1; + dsd.StencilWriteMask = 1; + dsd.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; + dsd.FrontFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE; + dsd.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; + dsd.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; + dsd.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS; + dsd.BackFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE; + dsd.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; + dsd.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; + + (*(GSDevice10*)m_dev)->CreateDepthStencilState(&dsd, &m_date.dss); + + D3D10_BLEND_DESC bd; + + memset(&bd, 0, sizeof(bd)); + + (*(GSDevice10*)m_dev)->CreateBlendState(&bd, &m_date.bs); + + // + + return true; +} + +template +void GSRendererDX10::VertexKick(bool skip) +{ + GSVertexHW10& dst = m_vl.AddTail(); + + dst.vi[0] = m_v.vi[0]; + dst.vi[1] = m_v.vi[1]; + + if(tme && fst) + { + GSVector4::storel(&dst.ST, m_v.GetUV()); + } + + int count = 0; + + if(GSVertexHW10* v = DrawingKick(skip, count)) + { + GSVector4i scissor = m_context->scissor.dx10; + + #if _M_SSE >= 0x401 + + GSVector4i pmin, pmax, v0, v1, v2; + + switch(prim) + { + case GS_POINTLIST: + v0 = GSVector4i::load((int)v[0].p.xy).upl16(); + pmin = v0; + pmax = v0; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + v0 = GSVector4i::load((int)v[0].p.xy); + v1 = GSVector4i::load((int)v[1].p.xy); + pmin = v0.min_u16(v1).upl16(); + pmax = v0.max_u16(v1).upl16(); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + v0 = GSVector4i::load((int)v[0].p.xy); + v1 = GSVector4i::load((int)v[1].p.xy); + v2 = GSVector4i::load((int)v[2].p.xy); + pmin = v0.min_u16(v1).min_u16(v2).upl16(); + pmax = v0.max_u16(v1).max_u16(v2).upl16(); + break; + } + + GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); + + if(test.mask() & 0xff) + { + return; + } + + #else + + switch(prim) + { + case GS_POINTLIST: + if(v[0].p.x < scissor.x + || v[0].p.x > scissor.z + || v[0].p.y < scissor.y + || v[0].p.y > scissor.w) + { + return; + } + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + if(v[0].p.x < scissor.x && v[1].p.x < scissor.x + || v[0].p.x > scissor.z && v[1].p.x > scissor.z + || v[0].p.y < scissor.y && v[1].p.y < scissor.y + || v[0].p.y > scissor.w && v[1].p.y > scissor.w) + { + return; + } + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x + || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z + || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y + || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) + { + return; + } + break; + } + + #endif + + m_count += count; + } +} + +void GSRendererDX10::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +{ + switch(primclass) + { + case GS_POINT_CLASS: + m_topology = D3D10_PRIMITIVE_TOPOLOGY_POINTLIST; + m_perfmon.Put(GSPerfMon::Prim, m_count); + break; + case GS_LINE_CLASS: + case GS_SPRITE_CLASS: + m_topology = D3D10_PRIMITIVE_TOPOLOGY_LINELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 2); + break; + case GS_TRIANGLE_CLASS: + m_topology = D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 3); + break; + default: + __assume(0); + } + + __super::Draw(primclass, rt, ds, tex); +} + +void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds) +{ + if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) + + GSDevice10* dev = (GSDevice10*)m_dev; + + int w = rt->GetWidth(); + int h = rt->GetHeight(); + + if(GSTexture* t = dev->CreateRenderTarget(w, h)) + { + // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows + + dev->BeginScene(); + + dev->ClearStencil(ds, 0); + + // om + + dev->OMSetDepthStencilState(m_date.dss, 1); + dev->OMSetBlendState(m_date.bs, 0); + dev->OMSetRenderTargets(t, ds); + + // ia + + GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 o = GSVector4(-1.0f, 1.0f); + + GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); + GSVector4 dst = src * 2.0f + o.xxxx(); + + GSVertexPT1 vertices[] = + { + {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, + {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, + {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, + {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, + }; + + dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + dev->IASetInputLayout(dev->m_convert.il); + dev->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // vs + + dev->VSSetShader(dev->m_convert.vs, NULL); + + // gs + + dev->GSSetShader(NULL); + + // ps + + dev->PSSetShaderResources(rt, NULL); + dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); + dev->PSSetSamplerState(dev->m_convert.pt, NULL); + + // rs + + dev->RSSet(w, h); + + // set + + dev->DrawPrimitive(); + + // + + dev->EndScene(); + + dev->Recycle(t); + } +} diff --git a/plugins/GSdx/GSRendererHW10.h b/plugins/GSdx/GSRendererDX10.h similarity index 86% rename from plugins/GSdx/GSRendererHW10.h rename to plugins/GSdx/GSRendererDX10.h index 056875862..1465fff56 100644 --- a/plugins/GSdx/GSRendererHW10.h +++ b/plugins/GSdx/GSRendererDX10.h @@ -21,28 +21,25 @@ #pragma once -#include "GSRendererHW.h" +#include "GSRendererDX.h" #include "GSVertexHW.h" #include "GSTextureCache10.h" #include "GSTextureFX10.h" -class GSRendererHW10 : public GSRendererHW +class GSRendererDX10 : public GSRendererDX { protected: - GSTextureFX10 m_tfx; - - void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex); - struct { CComPtr dss; CComPtr bs; } m_date; + void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); void SetupDATE(GSTexture* rt, GSTexture* ds); public: - GSRendererHW10(uint8* base, bool mt, void (*irq)()); + GSRendererDX10(uint8* base, bool mt, void (*irq)()); bool Create(const string& title); diff --git a/plugins/GSdx/GSRendererDX11.cpp b/plugins/GSdx/GSRendererDX11.cpp new file mode 100644 index 000000000..063c513a8 --- /dev/null +++ b/plugins/GSdx/GSRendererDX11.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererDX11.h" +#include "GSCrc.h" +#include "resource.h" + +GSRendererDX11::GSRendererDX11(uint8* base, bool mt, void (*irq)()) + : GSRendererDX(base, mt, irq, new GSDevice11(), new GSTextureCache11(this), new GSTextureFX11()) +{ + InitVertexKick(); + + m_pixelcenter = GSVector2(-0.5f, -0.5f); +} + +bool GSRendererDX11::Create(const string& title) +{ + if(!__super::Create(title)) + return false; + + // + + D3D11_DEPTH_STENCIL_DESC dsd; + + memset(&dsd, 0, sizeof(dsd)); + + dsd.DepthEnable = false; + dsd.StencilEnable = true; + dsd.StencilReadMask = 1; + dsd.StencilWriteMask = 1; + dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; + dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; + dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + + (*(GSDevice11*)m_dev)->CreateDepthStencilState(&dsd, &m_date.dss); + + D3D11_BLEND_DESC bd; + + memset(&bd, 0, sizeof(bd)); + + (*(GSDevice11*)m_dev)->CreateBlendState(&bd, &m_date.bs); + + // + + return true; +} + +template +void GSRendererDX11::VertexKick(bool skip) +{ + GSVertexHW11& dst = m_vl.AddTail(); + + dst.vi[0] = m_v.vi[0]; + dst.vi[1] = m_v.vi[1]; + + if(tme && fst) + { + GSVector4::storel(&dst.ST, m_v.GetUV()); + } + + int count = 0; + + if(GSVertexHW11* v = DrawingKick(skip, count)) + { + GSVector4i scissor = m_context->scissor.dx10; + + #if _M_SSE >= 0x401 + + GSVector4i pmin, pmax, v0, v1, v2; + + switch(prim) + { + case GS_POINTLIST: + v0 = GSVector4i::load((int)v[0].p.xy).upl16(); + pmin = v0; + pmax = v0; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + v0 = GSVector4i::load((int)v[0].p.xy); + v1 = GSVector4i::load((int)v[1].p.xy); + pmin = v0.min_u16(v1).upl16(); + pmax = v0.max_u16(v1).upl16(); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + v0 = GSVector4i::load((int)v[0].p.xy); + v1 = GSVector4i::load((int)v[1].p.xy); + v2 = GSVector4i::load((int)v[2].p.xy); + pmin = v0.min_u16(v1).min_u16(v2).upl16(); + pmax = v0.max_u16(v1).max_u16(v2).upl16(); + break; + } + + GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); + + if(test.mask() & 0xff) + { + return; + } + + #else + + switch(prim) + { + case GS_POINTLIST: + if(v[0].p.x < scissor.x + || v[0].p.x > scissor.z + || v[0].p.y < scissor.y + || v[0].p.y > scissor.w) + { + return; + } + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + if(v[0].p.x < scissor.x && v[1].p.x < scissor.x + || v[0].p.x > scissor.z && v[1].p.x > scissor.z + || v[0].p.y < scissor.y && v[1].p.y < scissor.y + || v[0].p.y > scissor.w && v[1].p.y > scissor.w) + { + return; + } + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x + || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z + || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y + || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) + { + return; + } + break; + } + + #endif + + m_count += count; + } +} + +void GSRendererDX11::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +{ + switch(primclass) + { + case GS_POINT_CLASS: + m_topology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + m_perfmon.Put(GSPerfMon::Prim, m_count); + break; + case GS_LINE_CLASS: + case GS_SPRITE_CLASS: + m_topology = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 2); + break; + case GS_TRIANGLE_CLASS: + m_topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 3); + break; + default: + __assume(0); + } + + __super::Draw(primclass, rt, ds, tex); +} + +void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds) +{ + if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) + + GSDevice11* dev = (GSDevice11*)m_dev; + + int w = rt->GetWidth(); + int h = rt->GetHeight(); + + if(GSTexture* t = dev->CreateRenderTarget(w, h)) + { + // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows + + dev->BeginScene(); + + dev->ClearStencil(ds, 0); + + // om + + dev->OMSetDepthStencilState(m_date.dss, 1); + dev->OMSetBlendState(m_date.bs, 0); + dev->OMSetRenderTargets(t, ds); + + // ia + + GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 o = GSVector4(-1.0f, 1.0f); + + GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); + GSVector4 dst = src * 2.0f + o.xxxx(); + + GSVertexPT1 vertices[] = + { + {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, + {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, + {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, + {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, + }; + + dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + dev->IASetInputLayout(dev->m_convert.il); + dev->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // vs + + dev->VSSetShader(dev->m_convert.vs, NULL); + + // gs + + dev->GSSetShader(NULL); + + // ps + + dev->PSSetShaderResources(rt, NULL); + dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); + dev->PSSetSamplerState(dev->m_convert.pt, NULL); + + // rs + + dev->RSSet(w, h); + + // set + + dev->DrawPrimitive(); + + // + + dev->EndScene(); + + dev->Recycle(t); + } +} diff --git a/plugins/GSdx/GSRendererHW11.h b/plugins/GSdx/GSRendererDX11.h similarity index 83% rename from plugins/GSdx/GSRendererHW11.h rename to plugins/GSdx/GSRendererDX11.h index fab4c7691..e30f2e7c0 100644 --- a/plugins/GSdx/GSRendererHW11.h +++ b/plugins/GSdx/GSRendererDX11.h @@ -21,17 +21,15 @@ #pragma once -#include "GSRendererHW.h" +#include "GSRendererDX.h" #include "GSVertexHW.h" #include "GSTextureCache11.h" #include "GSTextureFX11.h" -class GSRendererHW11 : public GSRendererHW +class GSRendererDX11 : public GSRendererDX { protected: - GSTextureFX11 m_tfx; - - void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex); + void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); struct { @@ -42,7 +40,7 @@ protected: void SetupDATE(GSTexture* rt, GSTexture* ds); public: - GSRendererHW11(uint8* base, bool mt, void (*irq)()); + GSRendererDX11(uint8* base, bool mt, void (*irq)()); bool Create(const string& title); diff --git a/plugins/GSdx/GSRendererDX9.cpp b/plugins/GSdx/GSRendererDX9.cpp new file mode 100644 index 000000000..c6e4be5a4 --- /dev/null +++ b/plugins/GSdx/GSRendererDX9.cpp @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2007-2009 Gabest + * http://www.gabest.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "stdafx.h" +#include "GSRendererDX9.h" +#include "GSCrc.h" +#include "resource.h" + +GSRendererDX9::GSRendererDX9(uint8* base, bool mt, void (*irq)()) + : GSRendererDX(base, mt, irq, new GSDevice9(), new GSTextureCache9(this), new GSTextureFX9()) +{ + InitVertexKick(); +} + +bool GSRendererDX9::Create(const string& title) +{ + if(!__super::Create(title)) + return false; + + // + + memset(&m_date.dss, 0, sizeof(m_date.dss)); + + m_date.dss.StencilEnable = true; + m_date.dss.StencilReadMask = 1; + m_date.dss.StencilWriteMask = 1; + m_date.dss.StencilFunc = D3DCMP_ALWAYS; + m_date.dss.StencilPassOp = D3DSTENCILOP_REPLACE; + m_date.dss.StencilRef = 1; + + memset(&m_date.bs, 0, sizeof(m_date.bs)); + + // + + memset(&m_fba.dss, 0, sizeof(m_fba.dss)); + + m_fba.dss.StencilEnable = true; + m_fba.dss.StencilReadMask = 2; + m_fba.dss.StencilWriteMask = 2; + m_fba.dss.StencilFunc = D3DCMP_EQUAL; + m_fba.dss.StencilPassOp = D3DSTENCILOP_ZERO; + m_fba.dss.StencilFailOp = D3DSTENCILOP_ZERO; + m_fba.dss.StencilDepthFailOp = D3DSTENCILOP_ZERO; + m_fba.dss.StencilRef = 2; + + memset(&m_fba.bs, 0, sizeof(m_fba.bs)); + + m_fba.bs.RenderTargetWriteMask = D3DCOLORWRITEENABLE_ALPHA; + + // + + return true; +} + +template +void GSRendererDX9::VertexKick(bool skip) +{ + GSVertexHW9 v; + + v.p = GSVector4(((GSVector4i)m_v.XYZ).upl16()); + + if(tme && !fst) + { + v.p = v.p.xyxy(GSVector4((float)m_v.XYZ.Z, m_v.RGBAQ.Q)); + } + else + { + v.p = v.p.xyxy(GSVector4::load((float)m_v.XYZ.Z)); + } + + if(tme) + { + if(fst) + { + v.t = m_v.GetUV(); + } + else + { + v.t = GSVector4::loadl(&m_v.ST); + } + } + + GSVertexHW9& dst = m_vl.AddTail(); + + dst = v; + + dst.c0 = m_v.RGBAQ.u32[0]; + dst.c1 = m_v.FOG.u32[1]; + + int count = 0; + + if(GSVertexHW9* v = DrawingKick(skip, count)) + { + GSVector4 scissor = m_context->scissor.dx9; + + GSVector4 pmin, pmax; + + switch(prim) + { + case GS_POINTLIST: + pmin = v[0].p; + pmax = v[0].p; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + pmin = v[0].p.minv(v[1].p); + pmax = v[0].p.maxv(v[1].p); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + pmin = v[0].p.minv(v[1].p).minv(v[2].p); + pmax = v[0].p.maxv(v[1].p).maxv(v[2].p); + break; + } + + GSVector4 test = (pmax < scissor) | (pmin > scissor.zwxy()); + + if(test.mask() & 3) + { + return; + } + + switch(prim) + { + case GS_POINTLIST: + break; + case GS_LINELIST: + case GS_LINESTRIP: + if(PRIM->IIP == 0) {v[0].c0 = v[1].c0;} + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + if(PRIM->IIP == 0) {v[0].c0 = v[1].c0 = v[2].c0;} + break; + case GS_SPRITE: + if(PRIM->IIP == 0) {v[0].c0 = v[1].c0;} + v[0].p.z = v[1].p.z; + v[0].p.w = v[1].p.w; + v[0].c1 = v[1].c1; + v[2] = v[1]; + v[3] = v[1]; + v[1].p.y = v[0].p.y; + v[1].t.y = v[0].t.y; + v[2].p.x = v[0].p.x; + v[2].t.x = v[0].t.x; + v[4] = v[1]; + v[5] = v[2]; + count += 4; + break; + } + + m_count += count; + } +} + +void GSRendererDX9::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +{ + switch(primclass) + { + case GS_POINT_CLASS: + m_topology = D3DPT_POINTLIST; + m_perfmon.Put(GSPerfMon::Prim, m_count); + break; + case GS_LINE_CLASS: + m_topology = D3DPT_LINELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 2); + break; + case GS_TRIANGLE_CLASS: + case GS_SPRITE_CLASS: + m_topology = D3DPT_TRIANGLELIST; + m_perfmon.Put(GSPerfMon::Prim, m_count / 3); + break; + default: + __assume(0); + } + + (*(GSDevice9*)m_dev)->SetRenderState(D3DRS_SHADEMODE, PRIM->IIP ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); // TODO + + __super::Draw(primclass, rt, ds, tex); +} + +void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds) +{ + if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) + + GSDevice9* dev = (GSDevice9*)m_dev; + + int w = rt->GetWidth(); + int h = rt->GetHeight(); + + if(GSTexture* t = dev->CreateRenderTarget(w, h)) + { + // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows + + dev->BeginScene(); + + dev->ClearStencil(ds, 0); + + // om + + dev->OMSetDepthStencilState(&m_date.dss); + dev->OMSetBlendState(&m_date.bs, 0); + dev->OMSetRenderTargets(t, ds); + + // ia + + GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 o = GSVector4(-1.0f, 1.0f); + + GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); + GSVector4 dst = src * 2.0f + o.xxxx(); + + GSVertexPT1 vertices[] = + { + {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, + {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, + {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, + {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, + }; + + dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + dev->IASetInputLayout(dev->m_convert.il); + dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); + + // vs + + dev->VSSetShader(dev->m_convert.vs, NULL, 0); + + // ps + + dev->PSSetShaderResources(rt, NULL); + dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL, 0); + dev->PSSetSamplerState(&dev->m_convert.pt); + + // rs + + dev->RSSet(w, h); + + // + + dev->DrawPrimitive(); + + // + + dev->EndScene(); + + dev->Recycle(t); + } +} + +void GSRendererDX9::UpdateFBA(GSTexture* rt) +{ + GSDevice9* dev = (GSDevice9*)m_dev; + + dev->BeginScene(); + + // om + + dev->OMSetDepthStencilState(&m_fba.dss); + dev->OMSetBlendState(&m_fba.bs, 0); + + // ia + + GSVector4 s = GSVector4(rt->m_scale.x / rt->GetWidth(), rt->m_scale.y / rt->GetHeight()); + GSVector4 o = GSVector4(-1.0f, 1.0f); + + GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); + GSVector4 dst = src * 2.0f + o.xxxx(); + + GSVertexPT1 vertices[] = + { + {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(0, 0)}, + {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(0, 0)}, + {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(0, 0)}, + {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(0, 0)}, + }; + + dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); + dev->IASetInputLayout(dev->m_convert.il); + dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); + + // vs + + dev->VSSetShader(dev->m_convert.vs, NULL, 0); + + // ps + + dev->PSSetShader(dev->m_convert.ps[4], NULL, 0); + + // rs + + dev->RSSet(rt->GetWidth(), rt->GetHeight()); + + // + + dev->DrawPrimitive(); + + // + + dev->EndScene(); +} diff --git a/plugins/GSdx/GSRendererHW9.h b/plugins/GSdx/GSRendererDX9.h similarity index 85% rename from plugins/GSdx/GSRendererHW9.h rename to plugins/GSdx/GSRendererDX9.h index 896fe892a..1bebe4e49 100644 --- a/plugins/GSdx/GSRendererHW9.h +++ b/plugins/GSdx/GSRendererDX9.h @@ -21,19 +21,14 @@ #pragma once -#include "GSRendererHW.h" +#include "GSRendererDX.h" #include "GSVertexHW.h" #include "GSTextureCache9.h" #include "GSTextureFX9.h" -class GSRendererHW9 : public GSRendererHW +class GSRendererDX9 : public GSRendererDX { protected: - GSTextureFX9 m_tfx; - bool m_logz; - - void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex); - struct { Direct3DDepthStencilState9 dss; @@ -42,16 +37,16 @@ protected: struct { - bool enabled; Direct3DDepthStencilState9 dss; Direct3DBlendState9 bs; } m_fba; + void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); void SetupDATE(GSTexture* rt, GSTexture* ds); void UpdateFBA(GSTexture* rt); public: - GSRendererHW9(uint8* base, bool mt, void (*irq)()); + GSRendererDX9(uint8* base, bool mt, void (*irq)()); bool Create(const string& title); diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index 392ac4066..536755108 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -81,7 +81,7 @@ protected: GSTexture* t = NULL; - if(GSTextureCache::GSRenderTarget* rt = m_tc->GetRenderTarget(TEX0, m_width, m_height, true)) + if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true, true)) { t = rt->m_texture; @@ -128,15 +128,15 @@ protected: TEX0.TBW = context->FRAME.FBW; TEX0.PSM = context->FRAME.PSM; - GSTextureCache::GSRenderTarget* rt = m_tc->GetRenderTarget(TEX0, m_width, m_height); + GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true); TEX0.TBP0 = context->ZBUF.Block(); TEX0.TBW = context->FRAME.FBW; TEX0.PSM = context->ZBUF.PSM; - GSTextureCache::GSDepthStencil* ds = m_tc->GetDepthStencil(TEX0, m_width, m_height); + GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, m_context->DepthWrite()); - GSTextureCache::GSCachedTexture* tex = NULL; + GSTextureCache::Source* tex = NULL; if(PRIM->TME) { @@ -144,9 +144,9 @@ protected: GSVector4i r; - GetTextureMinMax(r); + GetTextureMinMax(r, IsLinear()); - tex = m_tc->GetTexture(r); + tex = m_tc->LookupSource(context->TEX0, env.TEXA, r); if(!tex) return; } @@ -157,7 +157,7 @@ protected: string s; - if(s_save && PRIM->TME) + if(s_save && tex) { s = format("c:\\temp2\\_%05d_f%I64d_tex_%05x_%d_%d%d_%02x_%02x_%02x_%02x.dds", s_n, frame, (int)context->TEX0.TBP0, (int)context->TEX0.PSM, @@ -233,6 +233,30 @@ protected: // + GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in)); + + GIFRegBITBLTBUF BITBLTBUF; + + BITBLTBUF.DBW = context->FRAME.FBW; + + if(fm != 0xffffffff) + { + BITBLTBUF.DBP = context->FRAME.Block(); + BITBLTBUF.DPSM = context->FRAME.PSM; + + m_tc->InvalidateVideoMem(BITBLTBUF, r, false); + } + + if(zm != 0xffffffff) + { + BITBLTBUF.DBP = context->ZBUF.Block(); + BITBLTBUF.DPSM = context->ZBUF.PSM; + + m_tc->InvalidateVideoMem(BITBLTBUF, r, false); + } + + // + OverrideOutput(); if(s_dump) @@ -257,13 +281,11 @@ protected: s_n++; } - - m_tc->InvalidateTextures(context->FRAME, context->ZBUF); } - virtual void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex) = 0; + virtual void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) = 0; - virtual bool OverrideInput(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* t) + virtual bool OverrideInput(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { #pragma region ffxii pal video conversion @@ -424,7 +446,7 @@ protected: TEX0.TBW = FBW; TEX0.PSM = FPSM; - if(GSTextureCache::GSDepthStencil* ds = m_tc->GetDepthStencil(TEX0, m_width, m_height)) + if(GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, true)) { m_dev->ClearDepth(ds->m_texture, 0); } diff --git a/plugins/GSdx/GSRendererHW10.cpp b/plugins/GSdx/GSRendererHW10.cpp deleted file mode 100644 index 35a2da0ac..000000000 --- a/plugins/GSdx/GSRendererHW10.cpp +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Copyright (C) 2007-2009 Gabest - * http://www.gabest.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "stdafx.h" -#include "GSRendererHW10.h" -#include "GSCrc.h" -#include "resource.h" - -GSRendererHW10::GSRendererHW10(uint8* base, bool mt, void (*irq)()) - : GSRendererHW(base, mt, irq, new GSDevice10(), new GSTextureCache10(this)) -{ - InitVertexKick(); -} - -bool GSRendererHW10::Create(const string& title) -{ - if(!__super::Create(title)) - return false; - - if(!m_tfx.Create((GSDevice10*)m_dev)) - return false; - - // - - D3D10_DEPTH_STENCIL_DESC dsd; - - memset(&dsd, 0, sizeof(dsd)); - - dsd.DepthEnable = false; - dsd.StencilEnable = true; - dsd.StencilReadMask = 1; - dsd.StencilWriteMask = 1; - dsd.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; - dsd.FrontFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE; - dsd.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; - dsd.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; - dsd.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS; - dsd.BackFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE; - dsd.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; - dsd.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; - - (*(GSDevice10*)m_dev)->CreateDepthStencilState(&dsd, &m_date.dss); - - D3D10_BLEND_DESC bd; - - memset(&bd, 0, sizeof(bd)); - - (*(GSDevice10*)m_dev)->CreateBlendState(&bd, &m_date.bs); - - // - - return true; -} - -template -void GSRendererHW10::VertexKick(bool skip) -{ - GSVertexHW10& dst = m_vl.AddTail(); - - dst.vi[0] = m_v.vi[0]; - dst.vi[1] = m_v.vi[1]; - - if(tme && fst) - { - GSVector4::storel(&dst.ST, m_v.GetUV()); - } - - int count = 0; - - if(GSVertexHW10* v = DrawingKick(skip, count)) - { - GSVector4i scissor = m_context->scissor.dx10; - - #if _M_SSE >= 0x401 - - GSVector4i pmin, pmax, v0, v1, v2; - - switch(prim) - { - case GS_POINTLIST: - v0 = GSVector4i::load((int)v[0].p.xy).upl16(); - pmin = v0; - pmax = v0; - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - v0 = GSVector4i::load((int)v[0].p.xy); - v1 = GSVector4i::load((int)v[1].p.xy); - pmin = v0.min_u16(v1).upl16(); - pmax = v0.max_u16(v1).upl16(); - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - v0 = GSVector4i::load((int)v[0].p.xy); - v1 = GSVector4i::load((int)v[1].p.xy); - v2 = GSVector4i::load((int)v[2].p.xy); - pmin = v0.min_u16(v1).min_u16(v2).upl16(); - pmax = v0.max_u16(v1).max_u16(v2).upl16(); - break; - } - - GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); - - if(test.mask() & 0xff) - { - return; - } - - #else - - switch(prim) - { - case GS_POINTLIST: - if(v[0].p.x < scissor.x - || v[0].p.x > scissor.z - || v[0].p.y < scissor.y - || v[0].p.y > scissor.w) - { - return; - } - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w) - { - return; - } - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) - { - return; - } - break; - } - - #endif - - m_count += count; - } -} - -void GSRendererHW10::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex) -{ - GSDrawingEnvironment& env = m_env; - GSDrawingContext* context = m_context; - - D3D10_PRIMITIVE_TOPOLOGY topology; - int prims = 0; - - switch(primclass) - { - case GS_POINT_CLASS: - topology = D3D10_PRIMITIVE_TOPOLOGY_POINTLIST; - prims = m_count; - break; - case GS_LINE_CLASS: - case GS_SPRITE_CLASS: - topology = D3D10_PRIMITIVE_TOPOLOGY_LINELIST; - prims = m_count / 2; - break; - case GS_TRIANGLE_CLASS: - topology = D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - prims = m_count / 3; - break; - default: - __assume(0); - } - - m_perfmon.Put(GSPerfMon::Prim, prims); - m_perfmon.Put(GSPerfMon::Draw, 1); - - // date - - SetupDATE(rt, ds); - - // - - m_dev->BeginScene(); - - // om - - GSTextureFX::OMDepthStencilSelector om_dssel; - - om_dssel.zte = context->TEST.ZTE; - om_dssel.ztst = context->TEST.ZTST; - om_dssel.zwe = !context->ZBUF.ZMSK; - om_dssel.date = context->FRAME.PSM != PSM_PSMCT24 ? context->TEST.DATE : 0; - - GSTextureFX::OMBlendSelector om_bsel; - - om_bsel.abe = !IsOpaque(); - om_bsel.a = context->ALPHA.A; - om_bsel.b = context->ALPHA.B; - om_bsel.c = context->ALPHA.C; - om_bsel.d = context->ALPHA.D; - om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff; - om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00; - om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000; - om_bsel.wa = (context->FRAME.FBMSK & 0xff000000) != 0xff000000; - - float bf = (float)(int)context->ALPHA.FIX / 0x80; - - // vs - - GSTextureFX::VSSelector vs_sel; - - vs_sel.bppz = 0; - vs_sel.tme = PRIM->TME; - vs_sel.fst = PRIM->FST; - vs_sel.prim = primclass; - - if(om_dssel.zte && om_dssel.ztst > 0 && om_dssel.zwe) - { - if(context->ZBUF.PSM == PSM_PSMZ24) - { - if(m_vt.m_max.p.z > 0xffffff) - { - ASSERT(m_vt.m_min.p.z > 0xffffff); - - vs_sel.bppz = 1; - om_dssel.ztst = 1; - } - } - else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) - { - if(m_vt.m_max.p.z > 0xffff) - { - ASSERT(m_vt.m_min.p.z > 0xffff); - - vs_sel.bppz = 2; - om_dssel.ztst = 1; - } - } - } - - GSTextureFX::VSConstantBuffer vs_cb; - - float sx = 2.0f * rt->m_scale.x / (rt->GetWidth() * 16); - float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16); - float ox = (float)(int)context->XYOFFSET.OFX; - float oy = (float)(int)context->XYOFFSET.OFY; - float ox2 = 1.0f / rt->GetWidth(); - float oy2 = 1.0f / rt->GetHeight(); - - vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f); - vs_cb.VertexOffset = GSVector4(ox * sx - ox2 + 1, -(oy * sy - oy2 + 1), 0.0f, -1.0f); - vs_cb.TextureScale = GSVector2(1.0f, 1.0f); - - if(PRIM->TME && PRIM->FST) - { - vs_cb.TextureScale.x = 1.0f / (16 << context->TEX0.TW); - vs_cb.TextureScale.y = 1.0f / (16 << context->TEX0.TH); - } - - // gs - - GSTextureFX::GSSelector gs_sel; - - gs_sel.iip = PRIM->IIP; - gs_sel.prim = primclass; - - // ps - - GSTextureFX::PSSelector ps_sel; - - ps_sel.fst = PRIM->FST; - ps_sel.wms = context->CLAMP.WMS; - ps_sel.wmt = context->CLAMP.WMT; - ps_sel.bpp = 0; - ps_sel.aem = env.TEXA.AEM; - ps_sel.tfx = context->TEX0.TFX; - ps_sel.tcc = context->TEX0.TCC; - ps_sel.ate = context->TEST.ATE; - ps_sel.atst = context->TEST.ATST; - ps_sel.fog = PRIM->FGE; - ps_sel.clr1 = om_bsel.abe && om_bsel.a == 1 && om_bsel.b == 2 && om_bsel.d == 1; - ps_sel.fba = context->FBA.FBA; - ps_sel.aout = context->FRAME.PSM == PSM_PSMCT16 || context->FRAME.PSM == PSM_PSMCT16S || (context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0; - ps_sel.ltf = m_filter == 2 ? context->TEX1.IsLinear() : m_filter; - - GSTextureFX::PSSamplerSelector ps_ssel; - - ps_ssel.tau = 0; - ps_ssel.tav = 0; - ps_ssel.ltf = ps_sel.ltf; - - GSTextureFX::PSConstantBuffer ps_cb; - - ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255; - - if(ps_sel.atst == 2 || ps_sel.atst == 5) - { - ps_cb.FogColor_AREF.a -= 0.9f / 255; - } - else if(ps_sel.atst == 3 || ps_sel.atst == 6) - { - ps_cb.FogColor_AREF.a += 0.9f / 255; - } - - if(tex) - { - ps_sel.bpp = tex->m_bpp; - - int w = tex->m_texture->GetWidth(); - int h = tex->m_texture->GetHeight(); - - ps_cb.WH_TA = GSVector4((int)(1 << context->TEX0.TW), (int)(1 << context->TEX0.TH), env.TEXA.TA0, env.TEXA.TA1) / GSVector4(1, 255).xxyy(); - ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / GSVector4(w, h).xyxy(); - - switch(context->CLAMP.WMS) - { - case 0: - ps_ssel.tau = 1; - break; - case 1: - ps_ssel.tau = 0; - break; - case 2: - ps_cb.MinMax.x = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW); - ps_cb.MinMax.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); - ps_cb.MinMaxF.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); - ps_cb.MinMaxF.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); - ps_ssel.tau = 0; - break; - case 3: - ps_cb.MskFix.x = context->CLAMP.MINU; - ps_cb.MskFix.z = context->CLAMP.MAXU; - ps_ssel.tau = 1; - break; - default: - __assume(0); - } - - switch(context->CLAMP.WMT) - { - case 0: - ps_ssel.tav = 1; - break; - case 1: - ps_ssel.tav = 0; - break; - case 2: - ps_cb.MinMax.y = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH); - ps_cb.MinMax.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); - ps_cb.MinMaxF.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); - ps_cb.MinMaxF.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); - ps_ssel.tav = 0; - break; - case 3: - ps_cb.MskFix.y = context->CLAMP.MINV; - ps_cb.MskFix.w = context->CLAMP.MAXV; - ps_ssel.tav = 1; - break; - default: - __assume(0); - } - } - else - { - ps_sel.tfx = 4; - } - - // rs - - int w = rt->GetWidth(); - int h = rt->GetHeight(); - - GSVector4i scissor = GSVector4i(GSVector4(rt->m_scale).xyxy() * context->scissor.in).rintersect(GSVector4i(0, 0, w, h)); - - // - - m_tfx.SetupOM(om_dssel, om_bsel, bf, rt, ds); - m_tfx.SetupIA(m_vertices, m_count, topology); - m_tfx.SetupVS(vs_sel, &vs_cb); - m_tfx.SetupGS(gs_sel); - m_tfx.SetupPS(ps_sel, &ps_cb, ps_ssel, tex ? tex->m_texture : NULL, tex ? tex->m_palette : NULL); - m_tfx.SetupRS(w, h, scissor); - - // draw - - if(context->TEST.DoFirstPass()) - { - m_dev->DrawPrimitive(); - } - - if(context->TEST.DoSecondPass()) - { - ASSERT(!env.PABE.PABE); - - static const uint32 iatst[] = {1, 0, 5, 6, 7, 2, 3, 4}; - - ps_sel.atst = iatst[ps_sel.atst]; - - m_tfx.UpdatePS(ps_sel, &ps_cb, ps_ssel); - - bool z = om_dssel.zwe; - bool r = om_bsel.wr; - bool g = om_bsel.wg; - bool b = om_bsel.wb; - bool a = om_bsel.wa; - - switch(context->TEST.AFAIL) - { - case 0: z = r = g = b = a = false; break; // none - case 1: z = false; break; // rgba - case 2: r = g = b = a = false; break; // z - case 3: z = a = false; break; // rgb - default: __assume(0); - } - - if(z || r || g || b || a) - { - om_dssel.zwe = z; - om_bsel.wr = r; - om_bsel.wg = g; - om_bsel.wb = b; - om_bsel.wa = a; - - m_tfx.UpdateOM(om_dssel, om_bsel, bf); - - m_dev->DrawPrimitive(); - } - } - - m_dev->EndScene(); -} - -void GSRendererHW10::SetupDATE(GSTexture* rt, GSTexture* ds) -{ - if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) - - GSDevice10* dev = (GSDevice10*)m_dev; - - int w = rt->GetWidth(); - int h = rt->GetHeight(); - - if(GSTexture* t = dev->CreateRenderTarget(w, h)) - { - // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows - - dev->BeginScene(); - - dev->ClearStencil(ds, 0); - - // om - - dev->OMSetDepthStencilState(m_date.dss, 1); - dev->OMSetBlendState(m_date.bs, 0); - dev->OMSetRenderTargets(t, ds); - - // ia - - GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); - GSVector4 o = GSVector4(-1.0f, 1.0f); - - GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); - GSVector4 dst = src * 2.0f + o.xxxx(); - - GSVertexPT1 vertices[] = - { - {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, - {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, - {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, - {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, - }; - - dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); - dev->IASetInputLayout(dev->m_convert.il); - dev->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - // vs - - dev->VSSetShader(dev->m_convert.vs, NULL); - - // gs - - dev->GSSetShader(NULL); - - // ps - - dev->PSSetShaderResources(rt, NULL); - dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); - dev->PSSetSamplerState(dev->m_convert.pt, NULL); - - // rs - - dev->RSSet(w, h); - - // set - - dev->DrawPrimitive(); - - // - - dev->EndScene(); - - dev->Recycle(t); - } -} diff --git a/plugins/GSdx/GSRendererHW11.cpp b/plugins/GSdx/GSRendererHW11.cpp deleted file mode 100644 index e68eaad4d..000000000 --- a/plugins/GSdx/GSRendererHW11.cpp +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Copyright (C) 2007-2009 Gabest - * http://www.gabest.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "stdafx.h" -#include "GSRendererHW11.h" -#include "GSCrc.h" -#include "resource.h" - -GSRendererHW11::GSRendererHW11(uint8* base, bool mt, void (*irq)()) - : GSRendererHW(base, mt, irq, new GSDevice11(), new GSTextureCache11(this)) -{ - InitVertexKick(); -} - -bool GSRendererHW11::Create(const string& title) -{ - if(!__super::Create(title)) - return false; - - if(!m_tfx.Create((GSDevice11*)m_dev)) - return false; - - // - - D3D11_DEPTH_STENCIL_DESC dsd; - - memset(&dsd, 0, sizeof(dsd)); - - dsd.DepthEnable = false; - dsd.StencilEnable = true; - dsd.StencilReadMask = 1; - dsd.StencilWriteMask = 1; - dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; - dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; - dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - - (*(GSDevice11*)m_dev)->CreateDepthStencilState(&dsd, &m_date.dss); - - D3D11_BLEND_DESC bd; - - memset(&bd, 0, sizeof(bd)); - - (*(GSDevice11*)m_dev)->CreateBlendState(&bd, &m_date.bs); - - // - - return true; -} - -template -void GSRendererHW11::VertexKick(bool skip) -{ - GSVertexHW11& dst = m_vl.AddTail(); - - dst.vi[0] = m_v.vi[0]; - dst.vi[1] = m_v.vi[1]; - - if(tme && fst) - { - GSVector4::storel(&dst.ST, m_v.GetUV()); - } - - int count = 0; - - if(GSVertexHW11* v = DrawingKick(skip, count)) - { - GSVector4i scissor = m_context->scissor.dx10; - - #if _M_SSE >= 0x401 - - GSVector4i pmin, pmax, v0, v1, v2; - - switch(prim) - { - case GS_POINTLIST: - v0 = GSVector4i::load((int)v[0].p.xy).upl16(); - pmin = v0; - pmax = v0; - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - v0 = GSVector4i::load((int)v[0].p.xy); - v1 = GSVector4i::load((int)v[1].p.xy); - pmin = v0.min_u16(v1).upl16(); - pmax = v0.max_u16(v1).upl16(); - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - v0 = GSVector4i::load((int)v[0].p.xy); - v1 = GSVector4i::load((int)v[1].p.xy); - v2 = GSVector4i::load((int)v[2].p.xy); - pmin = v0.min_u16(v1).min_u16(v2).upl16(); - pmax = v0.max_u16(v1).max_u16(v2).upl16(); - break; - } - - GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); - - if(test.mask() & 0xff) - { - return; - } - - #else - - switch(prim) - { - case GS_POINTLIST: - if(v[0].p.x < scissor.x - || v[0].p.x > scissor.z - || v[0].p.y < scissor.y - || v[0].p.y > scissor.w) - { - return; - } - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w) - { - return; - } - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) - { - return; - } - break; - } - - #endif - - m_count += count; - } -} - -void GSRendererHW11::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex) -{ - GSDrawingEnvironment& env = m_env; - GSDrawingContext* context = m_context; - - D3D11_PRIMITIVE_TOPOLOGY topology; - int prims = 0; - - switch(primclass) - { - case GS_POINT_CLASS: - topology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; - prims = m_count; - break; - case GS_LINE_CLASS: - case GS_SPRITE_CLASS: - topology = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; - prims = m_count / 2; - break; - case GS_TRIANGLE_CLASS: - topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - prims = m_count / 3; - break; - default: - __assume(0); - } - - m_perfmon.Put(GSPerfMon::Prim, prims); - m_perfmon.Put(GSPerfMon::Draw, 1); - - // date - - SetupDATE(rt, ds); - - // - - m_dev->BeginScene(); - - // om - - GSTextureFX::OMDepthStencilSelector om_dssel; - - om_dssel.zte = context->TEST.ZTE; - om_dssel.ztst = context->TEST.ZTST; - om_dssel.zwe = !context->ZBUF.ZMSK; - om_dssel.date = context->FRAME.PSM != PSM_PSMCT24 ? context->TEST.DATE : 0; - - GSTextureFX::OMBlendSelector om_bsel; - - om_bsel.abe = !IsOpaque(); - om_bsel.a = context->ALPHA.A; - om_bsel.b = context->ALPHA.B; - om_bsel.c = context->ALPHA.C; - om_bsel.d = context->ALPHA.D; - om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff; - om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00; - om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000; - om_bsel.wa = (context->FRAME.FBMSK & 0xff000000) != 0xff000000; - - float bf = (float)(int)context->ALPHA.FIX / 0x80; - - // vs - - GSTextureFX::VSSelector vs_sel; - - vs_sel.bppz = 0; - vs_sel.tme = PRIM->TME; - vs_sel.fst = PRIM->FST; - vs_sel.prim = primclass; - - if(om_dssel.zte && om_dssel.ztst > 0 && om_dssel.zwe) - { - if(context->ZBUF.PSM == PSM_PSMZ24) - { - if(m_vt.m_max.p.z > 0xffffff) - { - ASSERT(m_vt.m_min.p.z > 0xffffff); - - vs_sel.bppz = 1; - om_dssel.ztst = 1; - } - } - else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) - { - if(m_vt.m_max.p.z > 0xffff) - { - ASSERT(m_vt.m_min.p.z > 0xffff); - - vs_sel.bppz = 2; - om_dssel.ztst = 1; - } - } - } - - GSTextureFX::VSConstantBuffer vs_cb; - - float sx = 2.0f * rt->m_scale.x / (rt->GetWidth() * 16); - float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16); - float ox = (float)(int)context->XYOFFSET.OFX; - float oy = (float)(int)context->XYOFFSET.OFY; - float ox2 = 1.0f / rt->GetWidth(); - float oy2 = 1.0f / rt->GetHeight(); - - vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f); - vs_cb.VertexOffset = GSVector4(ox * sx - ox2 + 1, -(oy * sy - oy2 + 1), 0.0f, -1.0f); - vs_cb.TextureScale = GSVector2(1.0f, 1.0f); - - if(PRIM->TME && PRIM->FST) - { - vs_cb.TextureScale.x = 1.0f / (16 << context->TEX0.TW); - vs_cb.TextureScale.y = 1.0f / (16 << context->TEX0.TH); - } - - // gs - - GSTextureFX::GSSelector gs_sel; - - gs_sel.iip = PRIM->IIP; - gs_sel.prim = primclass; - - // ps - - GSTextureFX::PSSelector ps_sel; - - ps_sel.fst = PRIM->FST; - ps_sel.wms = context->CLAMP.WMS; - ps_sel.wmt = context->CLAMP.WMT; - ps_sel.bpp = 0; - ps_sel.aem = env.TEXA.AEM; - ps_sel.tfx = context->TEX0.TFX; - ps_sel.tcc = context->TEX0.TCC; - ps_sel.ate = context->TEST.ATE; - ps_sel.atst = context->TEST.ATST; - ps_sel.fog = PRIM->FGE; - ps_sel.clr1 = om_bsel.abe && om_bsel.a == 1 && om_bsel.b == 2 && om_bsel.d == 1; - ps_sel.fba = context->FBA.FBA; - ps_sel.aout = context->FRAME.PSM == PSM_PSMCT16 || context->FRAME.PSM == PSM_PSMCT16S || (context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0; - ps_sel.ltf = m_filter == 2 ? context->TEX1.IsLinear() : m_filter; - - GSTextureFX::PSSamplerSelector ps_ssel; - - ps_ssel.tau = 0; - ps_ssel.tav = 0; - ps_ssel.ltf = ps_sel.ltf; - - GSTextureFX::PSConstantBuffer ps_cb; - - ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255; - - if(ps_sel.atst == 2 || ps_sel.atst == 5) - { - ps_cb.FogColor_AREF.a -= 0.9f / 255; - } - else if(ps_sel.atst == 3 || ps_sel.atst == 6) - { - ps_cb.FogColor_AREF.a += 0.9f / 255; - } - - if(tex) - { - ps_sel.bpp = tex->m_bpp; - - int w = tex->m_texture->GetWidth(); - int h = tex->m_texture->GetHeight(); - - ps_cb.WH_TA = GSVector4((int)(1 << context->TEX0.TW), (int)(1 << context->TEX0.TH), env.TEXA.TA0, env.TEXA.TA1) / GSVector4(1, 255).xxyy(); - ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / GSVector4(w, h).xyxy(); - - switch(context->CLAMP.WMS) - { - case 0: - ps_ssel.tau = 1; - break; - case 1: - ps_ssel.tau = 0; - break; - case 2: - ps_cb.MinMax.x = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW); - ps_cb.MinMax.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); - ps_cb.MinMaxF.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); - ps_cb.MinMaxF.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); - ps_ssel.tau = 0; - break; - case 3: - ps_cb.MskFix.x = context->CLAMP.MINU; - ps_cb.MskFix.z = context->CLAMP.MAXU; - ps_ssel.tau = 1; - break; - default: - __assume(0); - } - - switch(context->CLAMP.WMT) - { - case 0: - ps_ssel.tav = 1; - break; - case 1: - ps_ssel.tav = 0; - break; - case 2: - ps_cb.MinMax.y = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH); - ps_cb.MinMax.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); - ps_cb.MinMaxF.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); - ps_cb.MinMaxF.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); - ps_ssel.tav = 0; - break; - case 3: - ps_cb.MskFix.y = context->CLAMP.MINV; - ps_cb.MskFix.w = context->CLAMP.MAXV; - ps_ssel.tav = 1; - break; - default: - __assume(0); - } - } - else - { - ps_sel.tfx = 4; - } - - // rs - - int w = rt->GetWidth(); - int h = rt->GetHeight(); - - GSVector4i scissor = GSVector4i(GSVector4(rt->m_scale).xyxy() * context->scissor.in).rintersect(GSVector4i(0, 0, w, h)); - - // - - m_tfx.SetupOM(om_dssel, om_bsel, bf, rt, ds); - m_tfx.SetupIA(m_vertices, m_count, topology); - m_tfx.SetupVS(vs_sel, &vs_cb); - m_tfx.SetupGS(gs_sel); - m_tfx.SetupPS(ps_sel, &ps_cb, ps_ssel, tex ? tex->m_texture : NULL, tex ? tex->m_palette : NULL); - m_tfx.SetupRS(w, h, scissor); - - // draw - - if(context->TEST.DoFirstPass()) - { - m_dev->DrawPrimitive(); - } - - if(context->TEST.DoSecondPass()) - { - ASSERT(!env.PABE.PABE); - - static const uint32 iatst[] = {1, 0, 5, 6, 7, 2, 3, 4}; - - ps_sel.atst = iatst[ps_sel.atst]; - - m_tfx.UpdatePS(ps_sel, &ps_cb, ps_ssel); - - bool z = om_dssel.zwe; - bool r = om_bsel.wr; - bool g = om_bsel.wg; - bool b = om_bsel.wb; - bool a = om_bsel.wa; - - switch(context->TEST.AFAIL) - { - case 0: z = r = g = b = a = false; break; // none - case 1: z = false; break; // rgba - case 2: r = g = b = a = false; break; // z - case 3: z = a = false; break; // rgb - default: __assume(0); - } - - if(z || r || g || b || a) - { - om_dssel.zwe = z; - om_bsel.wr = r; - om_bsel.wg = g; - om_bsel.wb = b; - om_bsel.wa = a; - - m_tfx.UpdateOM(om_dssel, om_bsel, bf); - - m_dev->DrawPrimitive(); - } - } - - m_dev->EndScene(); -} - -void GSRendererHW11::SetupDATE(GSTexture* rt, GSTexture* ds) -{ - if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) - - GSDevice11* dev = (GSDevice11*)m_dev; - - int w = rt->GetWidth(); - int h = rt->GetHeight(); - - if(GSTexture* t = dev->CreateRenderTarget(w, h)) - { - // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows - - dev->BeginScene(); - - dev->ClearStencil(ds, 0); - - // om - - dev->OMSetDepthStencilState(m_date.dss, 1); - dev->OMSetBlendState(m_date.bs, 0); - dev->OMSetRenderTargets(t, ds); - - // ia - - GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); - GSVector4 o = GSVector4(-1.0f, 1.0f); - - GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); - GSVector4 dst = src * 2.0f + o.xxxx(); - - GSVertexPT1 vertices[] = - { - {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, - {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, - {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, - {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, - }; - - dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); - dev->IASetInputLayout(dev->m_convert.il); - dev->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - // vs - - dev->VSSetShader(dev->m_convert.vs, NULL); - - // gs - - dev->GSSetShader(NULL); - - // ps - - dev->PSSetShaderResources(rt, NULL); - dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); - dev->PSSetSamplerState(dev->m_convert.pt, NULL); - - // rs - - dev->RSSet(w, h); - - // set - - dev->DrawPrimitive(); - - // - - dev->EndScene(); - - dev->Recycle(t); - } -} diff --git a/plugins/GSdx/GSRendererHW9.cpp b/plugins/GSdx/GSRendererHW9.cpp deleted file mode 100644 index a4d635fc8..000000000 --- a/plugins/GSdx/GSRendererHW9.cpp +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (C) 2007-2009 Gabest - * http://www.gabest.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "stdafx.h" -#include "GSRendererHW9.h" -#include "GSCrc.h" -#include "resource.h" - -GSRendererHW9::GSRendererHW9(uint8* base, bool mt, void (*irq)()) - : GSRendererHW(base, mt, irq, new GSDevice9(), new GSTextureCache9(this)) -{ - m_fba.enabled = !!theApp.GetConfig("fba", 1); - m_logz = !!theApp.GetConfig("logz", 0); - - InitVertexKick(); -} - -bool GSRendererHW9::Create(const string& title) -{ - if(!__super::Create(title)) - return false; - - if(!m_tfx.Create((GSDevice9*)m_dev)) - return false; - - // - - memset(&m_date.dss, 0, sizeof(m_date.dss)); - - m_date.dss.StencilEnable = true; - m_date.dss.StencilReadMask = 1; - m_date.dss.StencilWriteMask = 1; - m_date.dss.StencilFunc = D3DCMP_ALWAYS; - m_date.dss.StencilPassOp = D3DSTENCILOP_REPLACE; - m_date.dss.StencilRef = 1; - - memset(&m_date.bs, 0, sizeof(m_date.bs)); - - // - - memset(&m_fba.dss, 0, sizeof(m_fba.dss)); - - m_fba.dss.StencilEnable = true; - m_fba.dss.StencilReadMask = 2; - m_fba.dss.StencilWriteMask = 2; - m_fba.dss.StencilFunc = D3DCMP_EQUAL; - m_fba.dss.StencilPassOp = D3DSTENCILOP_ZERO; - m_fba.dss.StencilFailOp = D3DSTENCILOP_ZERO; - m_fba.dss.StencilDepthFailOp = D3DSTENCILOP_ZERO; - m_fba.dss.StencilRef = 2; - - memset(&m_fba.bs, 0, sizeof(m_fba.bs)); - - m_fba.bs.RenderTargetWriteMask = D3DCOLORWRITEENABLE_ALPHA; - - // - - return true; -} - -template -void GSRendererHW9::VertexKick(bool skip) -{ - GSVertexHW9& dst = m_vl.AddTail(); - - dst.p.x = (float)(int)m_v.XYZ.X; - dst.p.y = (float)(int)m_v.XYZ.Y; - dst.p.z = (float)m_v.XYZ.Z; - - dst.c0 = m_v.RGBAQ.u32[0]; - dst.c1 = m_v.FOG.u32[1]; - - if(tme) - { - if(fst) - { - GSVector4::storel(&dst.t, m_v.GetUV()); - } - else - { - dst.t.x = m_v.ST.S; - dst.t.y = m_v.ST.T; - dst.p.w = m_v.RGBAQ.Q; - } - } - - int count = 0; - - if(GSVertexHW9* v = DrawingKick(skip, count)) - { - GSVector4 scissor = m_context->scissor.dx9; - - GSVector4 pmin, pmax; - - switch(prim) - { - case GS_POINTLIST: - pmin = v[0].p; - pmax = v[0].p; - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - pmin = v[0].p.minv(v[1].p); - pmax = v[0].p.maxv(v[1].p); - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - pmin = v[0].p.minv(v[1].p).minv(v[2].p); - pmax = v[0].p.maxv(v[1].p).maxv(v[2].p); - break; - } - - GSVector4 test = (pmax < scissor) | (pmin > scissor.zwxy()); - - if(test.mask() & 3) - { - return; - } - - switch(prim) - { - case GS_POINTLIST: - break; - case GS_LINELIST: - case GS_LINESTRIP: - if(PRIM->IIP == 0) {v[0].c0 = v[1].c0;} - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - if(PRIM->IIP == 0) {v[0].c0 = v[1].c0 = v[2].c0;} - break; - case GS_SPRITE: - if(PRIM->IIP == 0) {v[0].c0 = v[1].c0;} - v[0].p.z = v[1].p.z; - v[0].p.w = v[1].p.w; - v[0].c1 = v[1].c1; - v[2] = v[1]; - v[3] = v[1]; - v[1].p.y = v[0].p.y; - v[1].t.y = v[0].t.y; - v[2].p.x = v[0].p.x; - v[2].t.x = v[0].t.x; - v[4] = v[1]; - v[5] = v[2]; - count += 4; - break; - } - - m_count += count; - } -} - -void GSRendererHW9::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex) -{ - GSDrawingEnvironment& env = m_env; - GSDrawingContext* context = m_context; - - D3DPRIMITIVETYPE topology; - int prims = 0; - - switch(primclass) - { - case GS_POINT_CLASS: - topology = D3DPT_POINTLIST; - prims = m_count; - break; - case GS_LINE_CLASS: - topology = D3DPT_LINELIST; - prims = m_count / 2; - break; - case GS_TRIANGLE_CLASS: - case GS_SPRITE_CLASS: - topology = D3DPT_TRIANGLELIST; - prims = m_count / 3; - break; - default: - __assume(0); - } - - m_perfmon.Put(GSPerfMon::Prim, prims); - m_perfmon.Put(GSPerfMon::Draw, 1); - - // date - - SetupDATE(rt, ds); - - // - - m_dev->BeginScene(); - - (*(GSDevice9*)m_dev)->SetRenderState(D3DRS_SHADEMODE, PRIM->IIP ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); // TODO - - // om - - GSTextureFX::OMDepthStencilSelector om_dssel; - - om_dssel.zte = context->TEST.ZTE; - om_dssel.ztst = context->TEST.ZTST; - om_dssel.zwe = !context->ZBUF.ZMSK; - om_dssel.date = context->FRAME.PSM != PSM_PSMCT24 ? context->TEST.DATE : 0; - om_dssel.fba = m_fba.enabled ? context->FBA.FBA : 0; - - GSTextureFX::OMBlendSelector om_bsel; - - om_bsel.abe = !IsOpaque(); - om_bsel.a = context->ALPHA.A; - om_bsel.b = context->ALPHA.B; - om_bsel.c = context->ALPHA.C; - om_bsel.d = context->ALPHA.D; - om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff; - om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00; - om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000; - om_bsel.wa = (context->FRAME.FBMSK & 0xff000000) != 0xff000000; - - uint8 bf = context->ALPHA.FIX >= 0x80 ? 0xff : (uint8)(context->ALPHA.FIX * 2); - - // vs - - GSTextureFX::VSSelector vs_sel; - - vs_sel.bppz = 0; - vs_sel.tme = PRIM->TME; - vs_sel.fst = PRIM->FST; - vs_sel.logz = m_logz ? 1 : 0; - - if(om_dssel.zte && om_dssel.ztst > 0 && om_dssel.zwe) - { - if(context->ZBUF.PSM == PSM_PSMZ24) - { - if(m_vt.m_max.p.z > 0xffffff) - { - ASSERT(m_vt.m_min.p.z > 0xffffff); - - vs_sel.bppz = 1; - om_dssel.ztst = 1; - } - } - else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) - { - if(m_vt.m_max.p.z > 0xffff) - { - ASSERT(m_vt.m_min.p.z > 0xffff); - - vs_sel.bppz = 2; - om_dssel.ztst = 1; - } - } - } - - GSTextureFX::VSConstantBuffer vs_cb; - - float sx = 2.0f * rt->m_scale.x / (rt->GetWidth() * 16); - float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16); - float ox = (float)(int)context->XYOFFSET.OFX; - float oy = (float)(int)context->XYOFFSET.OFY; - - vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f); - vs_cb.VertexOffset = GSVector4(ox * sx + 1, -(oy * sy + 1), 0.0f, -1.0f); - vs_cb.TextureScale = GSVector2(1.0f, 1.0f); - - if(PRIM->TME && PRIM->FST) - { - vs_cb.TextureScale.x = 1.0f / (16 << context->TEX0.TW); - vs_cb.TextureScale.y = 1.0f / (16 << context->TEX0.TH); - } - - // ps - - GSTextureFX::PSSelector ps_sel; - - ps_sel.fst = PRIM->FST; - ps_sel.wms = context->CLAMP.WMS; - ps_sel.wmt = context->CLAMP.WMT; - ps_sel.bpp = 0; - ps_sel.aem = env.TEXA.AEM; - ps_sel.tfx = context->TEX0.TFX; - ps_sel.tcc = context->TEX0.TCC; - ps_sel.ate = context->TEST.ATE; - ps_sel.atst = context->TEST.ATST; - ps_sel.fog = PRIM->FGE; - ps_sel.clr1 = om_bsel.abe && om_bsel.a == 1 && om_bsel.b == 2 && om_bsel.d == 1; - ps_sel.rt = tex && tex->m_rendered; - ps_sel.ltf = m_filter == 2 ? context->TEX1.IsLinear() : m_filter; - - GSTextureFX::PSSamplerSelector ps_ssel; - - ps_ssel.tau = 0; - ps_ssel.tav = 0; - ps_ssel.ltf = ps_sel.ltf; - - GSTextureFX9::PSConstantBuffer ps_cb; - - ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255; - - if(ps_sel.atst == 2 || ps_sel.atst == 5) - { - ps_cb.FogColor_AREF.a -= 0.9f / 255; - } - else if(ps_sel.atst == 3 || ps_sel.atst == 6) - { - ps_cb.FogColor_AREF.a += 0.9f / 255; - } - - if(tex) - { - ps_sel.bpp = tex->m_bpp; - - int w = tex->m_texture->GetWidth(); - int h = tex->m_texture->GetHeight(); - - ps_cb.WH_TA = GSVector4(w, h, env.TEXA.TA0, env.TEXA.TA1) / GSVector4(1, 255).xxyy(); - ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / GSVector4(w, h).xyxy(); - - switch(context->CLAMP.WMS) - { - case 0: - ps_ssel.tau = 1; - break; - case 1: - ps_ssel.tau = 0; - break; - case 2: - ps_cb.MinMax.x = (float)(int)context->CLAMP.MINU / (1 << context->TEX0.TW); - ps_cb.MinMax.z = (float)(int)context->CLAMP.MAXU / (1 << context->TEX0.TW); - ps_cb.MinMaxF.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); - ps_cb.MinMaxF.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); - ps_ssel.tau = 0; - break; - case 3: - ps_cb.MskFix.x = context->CLAMP.MINU; - ps_cb.MskFix.z = context->CLAMP.MAXU; - ps_ssel.tau = 1; - break; - default: - __assume(0); - } - - switch(context->CLAMP.WMT) - { - case 0: - ps_ssel.tav = 1; - break; - case 1: - ps_ssel.tav = 0; - break; - case 2: - ps_cb.MinMax.y = (float)(int)context->CLAMP.MINV / (1 << context->TEX0.TH); - ps_cb.MinMax.w = (float)(int)context->CLAMP.MAXV / (1 << context->TEX0.TH); - ps_cb.MinMaxF.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); - ps_cb.MinMaxF.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); - ps_ssel.tav = 0; - break; - case 3: - ps_cb.MskFix.y = context->CLAMP.MINV; - ps_cb.MskFix.w = context->CLAMP.MAXV; - ps_ssel.tav = 1; - break; - default: - __assume(0); - } - } - else - { - ps_sel.tfx = 4; - } - - // rs - - int w = rt->GetWidth(); - int h = rt->GetHeight(); - - GSVector4i scissor = GSVector4i(GSVector4(rt->m_scale).xyxy() * context->scissor.in).rintersect(GSVector4i(0, 0, w, h)); - - // - - m_tfx.SetupOM(om_dssel, om_bsel, bf, rt, ds); - m_tfx.SetupIA(m_vertices, m_count, topology); - m_tfx.SetupVS(vs_sel, &vs_cb); - m_tfx.SetupPS(ps_sel, &ps_cb, ps_ssel, tex ? tex->m_texture : NULL, tex ? tex->m_palette : NULL); - m_tfx.SetupRS(w, h, scissor); - - // draw - - if(context->TEST.DoFirstPass()) - { - m_dev->DrawPrimitive(); - } - - if(context->TEST.DoSecondPass()) - { - ASSERT(!env.PABE.PABE); - - static const uint32 iatst[] = {1, 0, 5, 6, 7, 2, 3, 4}; - - ps_sel.atst = iatst[ps_sel.atst]; - - m_tfx.UpdatePS(ps_sel, &ps_cb, ps_ssel); - - bool z = om_dssel.zwe; - bool r = om_bsel.wr; - bool g = om_bsel.wg; - bool b = om_bsel.wb; - bool a = om_bsel.wa; - - switch(context->TEST.AFAIL) - { - case 0: z = r = g = b = a = false; break; // none - case 1: z = false; break; // rgba - case 2: r = g = b = a = false; break; // z - case 3: z = a = false; break; // rgb - default: __assume(0); - } - - if(z || r || g || b || a) - { - om_dssel.zwe = z; - om_bsel.wr = r; - om_bsel.wg = g; - om_bsel.wb = b; - om_bsel.wa = a; - - m_tfx.UpdateOM(om_dssel, om_bsel, bf); - - m_dev->DrawPrimitive(); - } - } - - m_dev->EndScene(); - - if(om_dssel.fba) UpdateFBA(rt); -} - -void GSRendererHW9::SetupDATE(GSTexture* rt, GSTexture* ds) -{ - if(!m_context->TEST.DATE) return; // || (::GetAsyncKeyState(VK_CONTROL) & 0x8000) - - GSDevice9* dev = (GSDevice9*)m_dev; - - int w = rt->GetWidth(); - int h = rt->GetHeight(); - - if(GSTexture* t = dev->CreateRenderTarget(w, h)) - { - // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows - - dev->BeginScene(); - - dev->ClearStencil(ds, 0); - - // om - - dev->OMSetDepthStencilState(&m_date.dss); - dev->OMSetBlendState(&m_date.bs, 0); - dev->OMSetRenderTargets(t, ds); - - // ia - - GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); - GSVector4 o = GSVector4(-1.0f, 1.0f); - - GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); - GSVector4 dst = src * 2.0f + o.xxxx(); - - GSVertexPT1 vertices[] = - { - {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)}, - {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)}, - {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)}, - {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)}, - }; - - dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); - dev->IASetInputLayout(dev->m_convert.il); - dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); - - // vs - - dev->VSSetShader(dev->m_convert.vs, NULL, 0); - - // ps - - dev->PSSetShaderResources(rt, NULL); - dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL, 0); - dev->PSSetSamplerState(&dev->m_convert.pt); - - // rs - - dev->RSSet(w, h); - - // - - dev->DrawPrimitive(); - - // - - dev->EndScene(); - - dev->Recycle(t); - } -} - -void GSRendererHW9::UpdateFBA(GSTexture* rt) -{ - GSDevice9* dev = (GSDevice9*)m_dev; - - dev->BeginScene(); - - // om - - dev->OMSetDepthStencilState(&m_fba.dss); - dev->OMSetBlendState(&m_fba.bs, 0); - - // ia - - GSVector4 s = GSVector4(rt->m_scale.x / rt->GetWidth(), rt->m_scale.y / rt->GetHeight()); - GSVector4 o = GSVector4(-1.0f, 1.0f); - - GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); - GSVector4 dst = src * 2.0f + o.xxxx(); - - GSVertexPT1 vertices[] = - { - {GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(0, 0)}, - {GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(0, 0)}, - {GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(0, 0)}, - {GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(0, 0)}, - }; - - dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); - dev->IASetInputLayout(dev->m_convert.il); - dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); - - // vs - - dev->VSSetShader(dev->m_convert.vs, NULL, 0); - - // ps - - dev->PSSetShader(dev->m_convert.ps[4], NULL, 0); - - // rs - - dev->RSSet(rt->GetWidth(), rt->GetHeight()); - - // - - dev->DrawPrimitive(); - - // - - dev->EndScene(); -} diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 942734e7d..107eea2ba 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -64,13 +64,12 @@ void GSRendererOGL::VertexKick(bool skip) } } -void GSRendererOGL::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex) +void GSRendererOGL::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) { GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; // m_perfmon.Put(GSPerfMon::Prim, prims); - m_perfmon.Put(GSPerfMon::Draw, 1); m_dev->BeginScene(); diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h index aa63b9918..9dc3587b9 100644 --- a/plugins/GSdx/GSRendererOGL.h +++ b/plugins/GSdx/GSRendererOGL.h @@ -29,7 +29,7 @@ class GSRendererOGL : public GSRendererHW { protected: - void Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex); + void Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); public: GSRendererOGL(uint8* base, bool mt, void (*irq)()); diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 9828f8757..63bee1db9 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -329,7 +329,7 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) p.sel.tfx = context->TEX0.TFX; p.sel.tcc = context->TEX0.TCC; p.sel.fst = PRIM->FST; - p.sel.ltf = context->TEX1.IsLinear(); + 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; @@ -394,7 +394,7 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) GSVector4i r; - GetTextureMinMax(r); + GetTextureMinMax(r, p.sel.ltf); const GSTextureCacheSW::GSTexture* t = m_tc->Lookup(context->TEX0, env.TEXA, r); diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 28ae26542..d8c71c3a0 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -34,94 +34,172 @@ GSTextureCache::~GSTextureCache() void GSTextureCache::RemoveAll() { - for(list::iterator i = m_rt.begin(); i != m_rt.end(); i++) + m_src.RemoveAll(); + + for(int type = 0; type < 2; type++) { - delete *i; + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) + { + delete *i; + } + + m_dst[type].clear(); } - - m_rt.clear(); - - for(list::iterator i = m_ds.begin(); i != m_ds.end(); i++) - { - delete *i; - } - - m_ds.clear(); - - for(list::iterator i = m_tex.begin(); i != m_tex.end(); i++) - { - delete *i; - } - - m_tex.clear(); } -GSTextureCache::GSRenderTarget* GSTextureCache::GetRenderTarget(const GIFRegTEX0& TEX0, int w, int h, bool fb) +GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r) { - GSRenderTarget* rt = NULL; + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; + const uint32* clut = m_renderer->m_mem.m_clut; + + Source* src = NULL; - if(rt == NULL) + const hash_map& map = m_src.m_map[TEX0.TBP0 >> 5]; + + for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) { - for(list::iterator i = m_rt.begin(); i != m_rt.end(); i++) + Source* s = i->first; + + if(((s->m_TEX0.u32[0] ^ TEX0.u32[0]) | ((s->m_TEX0.u32[1] ^ TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH { - GSRenderTarget* rt2 = *i; + continue; + } - if(rt2->m_TEX0.TBP0 == TEX0.TBP0) + if((psm.trbpp == 16 || psm.trbpp == 24) && TEX0.TCC && TEXA != s->m_TEXA) + { + continue; + } + + if(psm.pal > 0 && !GSVector4i::compare(s->m_clut, clut, psm.pal * sizeof(clut[0]))) + { + continue; + } + + src = s; + + break; + } + + Target* dst = NULL; + + if(src == NULL) + { + for(int type = 0; type < 2 && dst == NULL; type++) + { + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) { - m_rt.splice(m_rt.begin(), m_rt, i); + Target* t = *i; - rt = rt2; + if(t->m_used && t->m_dirty.empty() && GSUtil::HasSharedBits(t->m_TEX0.TBP0, t->m_TEX0.PSM, TEX0.TBP0, TEX0.PSM)) + { + dst = t; - if(!fb) rt->m_TEX0 = TEX0; - - rt->Update(); - - break; + break; + } } } } - if(rt == NULL && fb) + if(src == NULL) { - // HACK: try to find something close to the base pointer + src = CreateSource(); - for(list::iterator i = m_rt.begin(); i != m_rt.end(); i++) + if(!(dst ? src->Create(dst) : src->Create())) { - GSRenderTarget* rt2 = *i; - - if(rt2->m_TEX0.TBP0 <= TEX0.TBP0 && TEX0.TBP0 < rt2->m_TEX0.TBP0 + 0x700 && (!rt || rt2->m_TEX0.TBP0 >= rt->m_TEX0.TBP0)) - { - rt = rt2; - } - } - - if(rt) - { - rt->Update(); - } - } - - if(rt == NULL) - { - rt = CreateRenderTarget(); - - rt->m_TEX0 = TEX0; - - if(!rt->Create(w, h)) - { - delete rt; + delete src; return NULL; } - m_rt.push_front(rt); + if(psm.pal > 0) + { + memcpy(src->m_clut, clut, psm.pal * sizeof(clut[0])); + } + + m_src.Add(src, TEX0); + } + + if(psm.pal > 0) + { + int size = psm.pal * sizeof(clut[0]); + + if(src->m_palette) + { + if(src->m_initpalette || GSVector4i::update(src->m_clut, clut, size)) + { + src->m_palette->Update(GSVector4i(0, 0, psm.pal, 1), src->m_clut, size); + src->m_initpalette = false; + } + } + } + + src->Update(TEX0, TEXA, r); + + m_src.m_used = true; + + return src; +} + +GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used, bool fb) +{ + Target* dst = NULL; + + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) + { + Target* t = *i; + + if(t->m_TEX0.TBP0 == TEX0.TBP0) + { + m_dst[type].splice(m_dst[type].begin(), m_dst[type], i); + + dst = t; + + if(!fb) dst->m_TEX0 = TEX0; + + break; + } + } + + if(dst == NULL && fb) + { + // HACK: try to find something close to the base pointer + + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) + { + Target* t = *i; + + if(t->m_TEX0.TBP0 <= TEX0.TBP0 && TEX0.TBP0 < t->m_TEX0.TBP0 + 0x700 && (!dst || t->m_TEX0.TBP0 >= dst->m_TEX0.TBP0)) + { + dst = t; + } + } + } + + if(dst == NULL) + { + dst = CreateTarget(); + + dst->m_TEX0 = TEX0; + + if(!dst->Create(w, h, type)) + { + delete dst; + + return NULL; + } + + m_dst[type].push_front(dst); + } + else + { + dst->Update(); } if(m_renderer->CanUpscale()) { GSVector4i fr = m_renderer->GetFrameRect(); - int ww = (int)(fr.left + rt->m_TEX0.TBW * 64); + int ww = (int)(fr.left + dst->m_TEX0.TBW * 64); int hh = (int)(fr.top + m_renderer->GetDisplayRect().height()); if(hh <= m_renderer->GetDeviceSize().y / 2) @@ -136,346 +214,129 @@ GSTextureCache::GSRenderTarget* GSTextureCache::GetRenderTarget(const GIFRegTEX0 */ if(ww > 0 && hh > 0) { - rt->m_texture->m_scale.x = (float)w / ww; - rt->m_texture->m_scale.y = (float)h / hh; + dst->m_texture->m_scale.x = (float)w / ww; + dst->m_texture->m_scale.y = (float)h / hh; } } - if(!fb) + if(used) { - rt->m_used = true; + dst->m_used = true; } - return rt; + return dst; } -GSTextureCache::GSDepthStencil* GSTextureCache::GetDepthStencil(const GIFRegTEX0& TEX0, int w, int h) -{ - GSDepthStencil* ds = NULL; - - if(ds == NULL) - { - for(list::iterator i = m_ds.begin(); i != m_ds.end(); i++) - { - GSDepthStencil* ds2 = *i; - - if(ds2->m_TEX0.TBP0 == TEX0.TBP0) - { - m_ds.splice(m_ds.begin(), m_ds, i); - - ds = ds2; - - ds->m_TEX0 = TEX0; - - ds->Update(); - - break; - } - } - } - - if(ds == NULL) - { - ds = CreateDepthStencil(); - - ds->m_TEX0 = TEX0; - - if(!ds->Create(w, h)) - { - delete ds; - - return NULL; - } - - m_ds.push_front(ds); - } - - if(m_renderer->m_context->DepthWrite()) - { - ds->m_used = true; - } - - return ds; -} - -GSTextureCache::GSCachedTexture* GSTextureCache::GetTexture(const GSVector4i& r) -{ - const GIFRegTEX0& TEX0 = m_renderer->m_context->TEX0; - const GIFRegCLAMP& CLAMP = m_renderer->m_context->CLAMP; - const GIFRegTEXA& TEXA = m_renderer->m_env.TEXA; - - const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; - const uint32* clut = m_renderer->m_mem.m_clut; - - GSCachedTexture* t = NULL; - - for(list::iterator i = m_tex.begin(); i != m_tex.end(); i++) - { - GSCachedTexture* t2 = *i; - - if(((t2->m_TEX0.u32[0] ^ TEX0.u32[0]) | ((t2->m_TEX0.u32[1] ^ TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH - { - continue; - } - - if((psm.trbpp == 16 || psm.trbpp == 24) && TEX0.TCC && TEXA != t2->m_TEXA) - { - continue; - } - - if(psm.pal > 0 && !(t2->m_TEX0.CPSM == TEX0.CPSM && GSVector4i::compare(t2->m_clut, clut, psm.pal * sizeof(clut[0])))) - { - continue; - } - - t = t2; - - m_tex.splice(m_tex.begin(), m_tex, i); - - break; - } - - if(t == NULL) - { - for(list::iterator i = m_rt.begin(); i != m_rt.end(); i++) - { - GSRenderTarget* rt = *i; - - if(rt->m_dirty.empty() && GSUtil::HasSharedBits(rt->m_TEX0.TBP0, rt->m_TEX0.PSM, TEX0.TBP0, TEX0.PSM)) - { - t = CreateTexture(); - - if(!t->Create(rt)) - { - delete t; - - return NULL; - } - - m_tex.push_front(t); - - break; - } - } - } - - if(t == NULL) - { - for(list::iterator i = m_ds.begin(); i != m_ds.end(); i++) - { - GSDepthStencil* ds = *i; - - if(ds->m_dirty.empty() && ds->m_used && GSUtil::HasSharedBits(ds->m_TEX0.TBP0, ds->m_TEX0.PSM, TEX0.TBP0, TEX0.PSM)) - { - t = CreateTexture(); - - if(!t->Create(ds)) - { - delete t; - - return NULL; - } - - m_tex.push_front(t); - - break; - } - } - } - - if(t == NULL) - { - t = CreateTexture(); - - if(!t->Create()) - { - delete t; - - return NULL; - } - - m_tex.push_front(t); - } - - if(psm.pal > 0) - { - int size = psm.pal * sizeof(clut[0]); - - if(t->m_palette) - { - if(t->m_initpalette) - { - memcpy(t->m_clut, clut, size); - t->m_palette->Update(GSVector4i(0, 0, psm.pal, 1), t->m_clut, size); - t->m_initpalette = false; - } - else - { - if(GSVector4i::update(t->m_clut, clut, size)) - { - t->m_palette->Update(GSVector4i(0, 0, psm.pal, 1), t->m_clut, size); - } - } - } - else - { - memcpy(t->m_clut, clut, size); - } - } - - t->Update(r); - - m_tex_used = true; - - return t; -} - -void GSTextureCache::InvalidateTextures(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF) -{ - for(list::iterator i = m_tex.begin(); i != m_tex.end(); ) - { - list::iterator j = i++; - - GSCachedTexture* t = *j; - - if(GSUtil::HasSharedBits(FRAME.Block(), FRAME.PSM, t->m_TEX0.TBP0, t->m_TEX0.PSM) - || GSUtil::HasSharedBits(ZBUF.Block(), ZBUF.PSM, t->m_TEX0.TBP0, t->m_TEX0.PSM)) - { - m_tex.erase(j); - - delete t; - } - } -} - -void GSTextureCache::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) +void GSTextureCache::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& rect, bool target) { bool found = false; - for(list::iterator i = m_tex.begin(); i != m_tex.end(); ) + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[BITBLTBUF.DPSM]; + + uint32 bp = BITBLTBUF.DBP; + uint32 bw = BITBLTBUF.DBW; + + GSVector2i bs = (bp & 31) == 0 ? psm.pgs : psm.bs; + + GSVector4i r = rect.ralign(bs); + + if(!target) { - list::iterator j = i++; + const hash_map& map = m_src.m_map[bp >> 5]; - GSCachedTexture* t = *j; - - if(GSUtil::HasSharedBits(BITBLTBUF.DBP, BITBLTBUF.DPSM, t->m_TEX0.TBP0, t->m_TEX0.PSM)) + for(hash_map::const_iterator i = map.begin(); i != map.end(); ) { - if(BITBLTBUF.DBW == t->m_TEX0.TBW && !t->m_rendered) - { - t->m_dirty.push_back(GSDirtyRect(r, BITBLTBUF.DPSM)); + hash_map::const_iterator j = i++; - found = true; - } - else + Source* s = j->first; + + if(GSUtil::HasSharedBits(bp, BITBLTBUF.DPSM, s->m_TEX0.TBP0, s->m_TEX0.PSM)) { - m_tex.erase(j); - delete t; + m_src.RemoveAt(s); } } - else if(GSUtil::HasCompatibleBits(BITBLTBUF.DPSM, t->m_TEX0.PSM)) + } + + for(int y = r.top; y < r.bottom; y += bs.y) + { + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = r.left; x < r.right; x += bs.x) { - if(BITBLTBUF.DBW == t->m_TEX0.TBW && !t->m_rendered) + uint32 page = (base + psm.blockOffset[x >> 3]) >> 5; + + if(page < MAX_PAGES) { - int rowsize = (int)BITBLTBUF.DBW * 8192; - int offset = ((int)BITBLTBUF.DBP - (int)t->m_TEX0.TBP0) * 256; + const hash_map& map = m_src.m_map[page]; - if(rowsize > 0 && offset % rowsize == 0) + for(hash_map::const_iterator i = map.begin(); i != map.end(); ) { - int y = m_renderer->m_mem.m_psm[BITBLTBUF.DPSM].pgs.y * offset / rowsize; + hash_map::const_iterator j = i++; - GSVector4i r2(r.left, r.top + y, r.right, r.bottom + y); + Source* s = j->first; - int w = 1 << t->m_TEX0.TW; - int h = 1 << t->m_TEX0.TH; - - if(r2.bottom > 0 && r2.top < h && r2.right > 0 && r2.left < w) + if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, s->m_TEX0.PSM)) { - t->m_dirty.push_back(GSDirtyRect(r2, BITBLTBUF.DPSM)); + if(!s->m_target) + { + s->m_valid[page] = 0; + + found = true; + } + else + { + if(s->m_TEX0.TBP0 == bp) + { + m_src.RemoveAt(s); + } + } } } } } } - for(list::iterator i = m_rt.begin(); i != m_rt.end(); ) + if(!target) return; + + for(int type = 0; type < 2; type++) { - list::iterator j = i++; - - GSRenderTarget* rt = *j; - - if(GSUtil::HasSharedBits(BITBLTBUF.DBP, BITBLTBUF.DPSM, rt->m_TEX0.TBP0, rt->m_TEX0.PSM)) + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); ) { - if(!found && GSUtil::HasCompatibleBits(BITBLTBUF.DPSM, rt->m_TEX0.PSM)) - { - rt->m_dirty.push_back(GSDirtyRect(r, BITBLTBUF.DPSM)); - rt->m_TEX0.TBW = BITBLTBUF.DBW; - } - else - { - m_rt.erase(j); - delete rt; - continue; - } - } + list::iterator j = i++; - if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, rt->m_TEX0.PSM) && BITBLTBUF.DBP < rt->m_TEX0.TBP0) - { - uint32 rowsize = BITBLTBUF.DBW * 8192; - uint32 offset = (uint32)((rt->m_TEX0.TBP0 - BITBLTBUF.DBP) * 256); + Target* t = *j; - if(rowsize > 0 && offset % rowsize == 0) + if(GSUtil::HasSharedBits(BITBLTBUF.DBP, BITBLTBUF.DPSM, t->m_TEX0.TBP0, t->m_TEX0.PSM)) { - int y = m_renderer->m_mem.m_psm[BITBLTBUF.DPSM].pgs.y * offset / rowsize; - - if(r.bottom > y) + if(!found && GSUtil::HasCompatibleBits(BITBLTBUF.DPSM, t->m_TEX0.PSM)) { - // TODO: do not add this rect above too - rt->m_dirty.push_back(GSDirtyRect(GSVector4i(r.left, r.top - y, r.right, r.bottom - y), BITBLTBUF.DPSM)); - rt->m_TEX0.TBW = BITBLTBUF.DBW; + t->m_dirty.push_back(GSDirtyRect(r, BITBLTBUF.DPSM)); + t->m_TEX0.TBW = BITBLTBUF.DBW; + } + else + { + m_dst[type].erase(j); + delete t; continue; } } - } - } - // copypaste for ds - - for(list::iterator i = m_ds.begin(); i != m_ds.end(); ) - { - list::iterator j = i++; - - GSDepthStencil* ds = *j; - - if(GSUtil::HasSharedBits(BITBLTBUF.DBP, BITBLTBUF.DPSM, ds->m_TEX0.TBP0, ds->m_TEX0.PSM)) - { - if(!found && GSUtil::HasCompatibleBits(BITBLTBUF.DPSM, ds->m_TEX0.PSM)) + if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, t->m_TEX0.PSM) && BITBLTBUF.DBP < t->m_TEX0.TBP0) { - ds->m_dirty.push_back(GSDirtyRect(r, BITBLTBUF.DPSM)); - ds->m_TEX0.TBW = BITBLTBUF.DBW; - } - else - { - m_ds.erase(j); - delete ds; - continue; - } - } + uint32 rowsize = BITBLTBUF.DBW * 8192; + uint32 offset = (uint32)((t->m_TEX0.TBP0 - BITBLTBUF.DBP) * 256); - if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, ds->m_TEX0.PSM) && BITBLTBUF.DBP < ds->m_TEX0.TBP0) - { - uint32 rowsize = BITBLTBUF.DBW * 8192; - uint32 offset = (uint32)((ds->m_TEX0.TBP0 - BITBLTBUF.DBP) * 256); - - if(rowsize > 0 && offset % rowsize == 0) - { - int y = m_renderer->m_mem.m_psm[BITBLTBUF.DPSM].pgs.y * offset / rowsize; - - if(r.bottom > y) + if(rowsize > 0 && offset % rowsize == 0) { - // TODO: do not add this rect above too - ds->m_dirty.push_back(GSDirtyRect(GSVector4i(r.left, r.top - y, r.right, r.bottom - y), BITBLTBUF.DPSM)); - ds->m_TEX0.TBW = BITBLTBUF.DBW; - continue; + int y = GSLocalMemory::m_psm[BITBLTBUF.DPSM].pgs.y * offset / rowsize; + + if(r.bottom > y) + { + // TODO: do not add this rect above too + t->m_dirty.push_back(GSDirtyRect(GSVector4i(r.left, r.top - y, r.right, r.bottom - y), BITBLTBUF.DPSM)); + t->m_TEX0.TBW = BITBLTBUF.DBW; + continue; + } } } } @@ -484,31 +345,33 @@ void GSTextureCache::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) { - for(list::iterator i = m_rt.begin(); i != m_rt.end(); ) + for(list::iterator i = m_dst[RenderTarget].begin(); i != m_dst[RenderTarget].end(); ) { - list::iterator j = i++; + list::iterator j = i++; - GSRenderTarget* rt = *j; + Target* t = *j; - if(GSUtil::HasSharedBits(BITBLTBUF.SBP, BITBLTBUF.SPSM, rt->m_TEX0.TBP0, rt->m_TEX0.PSM)) + if(GSUtil::HasSharedBits(BITBLTBUF.SBP, BITBLTBUF.SPSM, t->m_TEX0.TBP0, t->m_TEX0.PSM)) { - if(GSUtil::HasCompatibleBits(BITBLTBUF.SPSM, rt->m_TEX0.PSM)) + if(GSUtil::HasCompatibleBits(BITBLTBUF.SPSM, t->m_TEX0.PSM)) { - rt->Read(r); + t->Read(r); + return; } - else if(BITBLTBUF.SPSM == PSM_PSMCT32 && (rt->m_TEX0.PSM == PSM_PSMCT16 || rt->m_TEX0.PSM == PSM_PSMCT16S)) + else if(BITBLTBUF.SPSM == PSM_PSMCT32 && (t->m_TEX0.PSM == PSM_PSMCT16 || t->m_TEX0.PSM == PSM_PSMCT16S)) { // ffx-2 riku changing to her default (shoots some reflecting glass at the end), 16-bit rt read as 32-bit - rt->Read(GSVector4i(r.left, r.top, r.right, r.top + (r.bottom - r.top) * 2)); + t->Read(GSVector4i(r.left, r.top, r.right, r.top + (r.bottom - r.top) * 2)); + return; } else { - m_rt.erase(j); - delete rt; - continue; + m_dst[RenderTarget].erase(j); + + delete t; } } } @@ -533,7 +396,7 @@ void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const if(rowsize > 0 && offset % rowsize == 0) { - int y = m_renderer->m_mem.m_psm[BITBLTBUF.SPSM].pgs.y * offset / rowsize; + int y = GSLocalMemory::m_psm[BITBLTBUF.SPSM].pgs.y * offset / rowsize; if(y < ymin && y < 512) { @@ -555,57 +418,291 @@ void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const void GSTextureCache::IncAge() { - RecycleByAge(m_tex, m_tex_used ? 2 : 30); - RecycleByAge(m_rt); - RecycleByAge(m_ds); + int maxage = m_src.m_used ? 3 : 30; - m_tex_used = false; + for(hash_map::iterator i = m_src.m_surfaces.begin(); i != m_src.m_surfaces.end(); ) + { + hash_map::iterator j = i++; + + Source* s = j->first; + + if(++s->m_age > maxage) + { + m_src.RemoveAt(s); + } + } + + m_src.m_used = false; + + maxage = 3; + + for(int type = 0; type < 2; type++) + { + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); ) + { + list::iterator j = i++; + + Target* t = *j; + + if(++t->m_age > maxage) + { + m_dst[type].erase(j); + + delete t; + } + } + } } -// GSTextureCache::GSSurface +// GSTextureCache::Surface -GSTextureCache::GSSurface::GSSurface(GSRenderer* r) +GSTextureCache::Surface::Surface(GSRenderer* r) : m_renderer(r) , m_texture(NULL) - , m_palette(NULL) - , m_initpalette(false) , m_age(0) { m_TEX0.TBP0 = (uint32)~0; } -GSTextureCache::GSSurface::~GSSurface() +GSTextureCache::Surface::~Surface() { m_renderer->m_dev->Recycle(m_texture); - m_renderer->m_dev->Recycle(m_palette); - - m_texture = NULL; - m_palette = NULL; } -void GSTextureCache::GSSurface::Update() +void GSTextureCache::Surface::Update() { m_age = 0; } -// GSTextureCache::GSRenderTarget +// GSTextureCache::Source -GSTextureCache::GSRenderTarget::GSRenderTarget(GSRenderer* r) - : GSSurface(r) - , m_used(true) +GSTextureCache::Source::Source(GSRenderer* r) + : Surface(r) + , m_palette(NULL) + , m_initpalette(false) + , m_bpp(0) + , m_target(false) +{ + memset(m_valid, 0, sizeof(m_valid)); + + m_clut = (uint32*)_aligned_malloc(256 * sizeof(uint32), 16); + + memset(m_clut, 0, sizeof(m_clut)); +} + +GSTextureCache::Source::~Source() +{ + m_renderer->m_dev->Recycle(m_palette); + + _aligned_free(m_clut); +} + +void GSTextureCache::Source::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect) +{ + __super::Update(); + + if(m_target) + { + return; + } + + m_TEX0 = TEX0; + m_TEXA = TEXA; + + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[m_TEX0.PSM]; + + GSVector2i s = psm.bs; + + int tw = 1 << m_TEX0.TW; + int th = 1 << m_TEX0.TH; + + GSVector4i tr(0, 0, tw, th); + + GSVector4i r = rect.ralign(s); + + uint32 bp = m_TEX0.TBP0; + uint32 bw = m_TEX0.TBW; + + uint32 blocks = 0; + + // TODO + static uint8* buff = (uint8*)_aligned_malloc(1024 * 16 * sizeof(uint32), 16); // max decompressed size for a row of blocks (1024 x 16, 4bpp) + + int pitch = max(tw, s.x) * sizeof(uint32); + + GSLocalMemory::readTexture rtx = psm.rtx; + + const GSLocalMemory& mem = m_renderer->m_mem; + + // TODO: bw == 0 (sfex) + + if(tw <= (bw << 6)) + { + // r.right = min(r.right, bw << 6); + + for(int y = r.top; y < r.bottom; y += s.y) + { + uint32 base = psm.bn(0, y, bp, bw); + + int left = r.left; + int right = r.left; + + for(int x = r.left; x < r.right; x += s.x) + { + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + uint32 row = block >> 5; + uint32 col = 1 << (block & 31); + + if((m_valid[row] & col) == 0) + { + m_valid[row] |= col; + + if(right < x) + { + Write(GSVector4i(left, y, right, y + s.y).rintersect(tr), buff, pitch); + + left = right = x; + } + + right += s.x; + + blocks++; + } + } + } + + if(left < right) + { + Write(GSVector4i(left, y, right, y + s.y).rintersect(tr), buff, pitch); + } + } + } + else + { + // unfortunatelly a block may be part of the same texture multiple times at different places (tw 1024 > tbw 640, between 640 -> 1024 it is repeated from the next row), + // so just can't set the block's bit to valid in one pass, even if 99.9% of the games don't address the repeated part at the right side + + // TODO: still bogus if those repeated parts aren't fetched together + + for(int y = r.top; y < r.bottom; y += s.y) + { + uint32 base = psm.bn(0, y, bp, bw); + + int left = r.left; + int right = r.left; + + for(int x = r.left; x < r.right; x += s.x) + { + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + uint32 row = block >> 5; + uint32 col = 1 << (block & 31); + + if((m_valid[row] & col) == 0) + { + if(right < x) + { + Write(GSVector4i(left, y, right, y + s.y).rintersect(tr), buff, pitch); + + left = right = x; + } + + right += s.x; + + blocks++; + } + } + } + + if(left < right) + { + Write(GSVector4i(left, y, right, y + s.y).rintersect(tr), buff, pitch); + } + } + + for(int y = r.top; y < r.bottom; y += s.y) + { + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = r.left; x < r.right; x += s.x) + { + uint32 block = base + psm.blockOffset[x >> 3]; + + if(block < MAX_BLOCKS) + { + uint32 row = block >> 5; + uint32 col = 1 << (block & 31); + + m_valid[row] |= col; + } + } + } + } + + //_aligned_free(buff); + + m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, s.x * s.y * sizeof(uint32) * blocks); +} + +void GSTextureCache::Source::Write(const GSVector4i& r, uint8* buff, int pitch) +{ + if(r.rempty()) return; + + GSLocalMemory::readTexture rtx = GSLocalMemory::m_psm[m_TEX0.PSM].rtx; + + GSTexture::GSMap m; + + if(m_texture->Map(m, &r)) + { + (m_renderer->m_mem.*rtx)(r, m.bits, m.pitch, m_TEX0, m_TEXA); + + m_texture->Unmap(); + } + else + { + (m_renderer->m_mem.*rtx)(r, buff, pitch, m_TEX0, m_TEXA); + + m_texture->Update(r, buff, pitch); + } +} + +// GSTextureCache::Target + +GSTextureCache::Target::Target(GSRenderer* r) + : Surface(r) + , m_type(-1) + , m_used(false) { } -bool GSTextureCache::GSRenderTarget::Create(int w, int h) +bool GSTextureCache::Target::Create(int w, int h, int type) { + ASSERT(m_texture == NULL); + // FIXME: initial data should be unswizzled from local mem in Update() if dirty - m_texture = m_renderer->m_dev->CreateRenderTarget(w, h); + m_type = type; + + if(type == RenderTarget) + { + m_texture = m_renderer->m_dev->CreateRenderTarget(w, h); + + m_used = true; + } + else if(type == DepthStencil) + { + m_texture = m_renderer->m_dev->CreateDepthStencil(w, h); + } return m_texture != NULL; } -void GSTextureCache::GSRenderTarget::Update() +void GSTextureCache::Target::Update() { __super::Update(); @@ -615,200 +712,112 @@ void GSTextureCache::GSRenderTarget::Update() if(r.rempty()) return; - int w = r.width(); - int h = r.height(); - - if(GSTexture* t = m_renderer->m_dev->CreateTexture(w, h)) + if(m_type == RenderTarget) { - GIFRegTEXA TEXA; + int w = r.width(); + int h = r.height(); - TEXA.AEM = 1; - TEXA.TA0 = 0; - TEXA.TA1 = 0x80; - - GSTexture::GSMap m; - - if(t->Map(m)) + if(GSTexture* t = m_renderer->m_dev->CreateTexture(w, h)) { - m_renderer->m_mem.ReadTexture(r, m.bits, m.pitch, m_TEX0, TEXA); + GIFRegTEXA TEXA; - t->Unmap(); - } - else - { - static uint8* buff = (uint8*)::_aligned_malloc(1024 * 1024 * 4, 16); - - int pitch = ((w + 3) & ~3) * 4; + TEXA.AEM = 1; + TEXA.TA0 = 0; + TEXA.TA1 = 0x80; - m_renderer->m_mem.ReadTexture(r, buff, pitch, m_TEX0, TEXA); - - t->Update(r.rsize(), buff, pitch); - } + GSTexture::GSMap m; - // m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, w * h * 4); + if(t->Map(m)) + { + m_renderer->m_mem.ReadTexture(r, m.bits, m.pitch, m_TEX0, TEXA); - m_renderer->m_dev->StretchRect(t, m_texture, GSVector4(r) * GSVector4(m_texture->m_scale).xyxy()); + t->Unmap(); + } + else + { + static uint8* buff = (uint8*)::_aligned_malloc(1024 * 1024 * 4, 16); + + int pitch = ((w + 3) & ~3) * 4; - m_renderer->m_dev->Recycle(t); - } -} + m_renderer->m_mem.ReadTexture(r, buff, pitch, m_TEX0, TEXA); + + t->Update(r.rsize(), buff, pitch); + } -// GSTextureCache::GSDepthStencil + // m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, w * h * 4); -GSTextureCache::GSDepthStencil::GSDepthStencil(GSRenderer* r) - : GSSurface(r) - , m_used(false) -{ -} + m_renderer->m_dev->StretchRect(t, m_texture, GSVector4(r) * GSVector4(m_texture->m_scale).xyxy()); -bool GSTextureCache::GSDepthStencil::Create(int w, int h) -{ - // FIXME: initial data should be unswizzled from local mem in Update() if dirty - - m_texture = m_renderer->m_dev->CreateDepthStencil(w, h); - - return m_texture != NULL; -} - -void GSTextureCache::GSDepthStencil::Update() -{ - __super::Update(); - - GSVector4i r = m_dirty.GetDirtyRectAndClear(m_TEX0, m_texture->GetSize()); - - if(r.rempty()) return; - - // TODO - - m_renderer->m_dev->ClearDepth(m_texture, 0); -} - -// GSTextureCache::GSCachedTexture - -GSTextureCache::GSCachedTexture::GSCachedTexture(GSRenderer* r) - : GSSurface(r) - , m_bpp(0) - , m_rendered(false) -{ - m_valid = GSVector4i::zero(); - - m_clut = (uint32*)_aligned_malloc(256 * sizeof(uint32), 16); - - memset(m_clut, 0, sizeof(m_clut)); -} - -GSTextureCache::GSCachedTexture::~GSCachedTexture() -{ - _aligned_free(m_clut); -} - -void GSTextureCache::GSCachedTexture::Update(const GSVector4i& rect) -{ - __super::Update(); - - if(m_rendered) - { - return; - } - - GSVector4i r = rect; - - if(!GetDirtyRect(r)) - { - return; - } - - m_valid = m_valid.runion(r); - - GSTexture::GSMap m; - - if(m_texture->Map(m, &r)) - { - // in dx9 managed textures can be written directly, less copying is faster, but still not as fast as dx10's UpdateResource - - m_renderer->m_mem.ReadTexture(r, m.bits, m.pitch, m_renderer->m_context->TEX0, m_renderer->m_env.TEXA); - - m_texture->Unmap(); - } - else - { - static uint8* buff = (uint8*)::_aligned_malloc(1024 * 1024 * 4, 16); - - int pitch = ((r.width() + 3) & ~3) * 4; - - m_renderer->m_mem.ReadTexture(r, buff, pitch, m_renderer->m_context->TEX0, m_renderer->m_env.TEXA); - - m_texture->Update(r, buff, pitch); - } - - m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, r.width() * r.height() * 4); -} - -bool GSTextureCache::GSCachedTexture::GetDirtyRect(GSVector4i& r) -{ - int w = 1 << m_TEX0.TW; - int h = 1 << m_TEX0.TH; - - GSVector4i tr(0, 0, w, h); - - for(list::iterator i = m_dirty.begin(); i != m_dirty.end(); i++) - { - const GSVector4i& dirty = i->GetDirtyRect(m_TEX0).rintersect(tr); - - if(!m_valid.rintersect(dirty).rempty()) - { - // find the rect having the largest area, outside dirty, inside m_valid - - GSVector4i left(m_valid.left, m_valid.top, min(m_valid.right, dirty.left), m_valid.bottom); - GSVector4i top(m_valid.left, m_valid.top, m_valid.right, min(m_valid.bottom, dirty.top)); - GSVector4i right(max(m_valid.left, dirty.right), m_valid.top, m_valid.right, m_valid.bottom); - GSVector4i bottom(m_valid.left, max(m_valid.top, dirty.bottom), m_valid.right, m_valid.bottom); - - int leftsize = !left.rempty() ? left.width() * left.height() : 0; - int topsize = !top.rempty() ? top.width() * top.height() : 0; - int rightsize = !right.rempty() ? right.width() * right.height() : 0; - int bottomsize = !bottom.rempty() ? bottom.width() * bottom.height() : 0; - - // TODO: sort - - m_valid = - leftsize > 0 ? left : - topsize > 0 ? top : - rightsize > 0 ? right : - bottomsize > 0 ? bottom : - GSVector4i::zero(); + m_renderer->m_dev->Recycle(t); } } + else if(m_type == DepthStencil) + { + // do the most likely thing a direct write would do, clear it - m_dirty.clear(); + m_renderer->m_dev->ClearDepth(m_texture, 0); + } +} - if(GSUtil::IsRectInRect(r, m_valid)) +// GSTextureCache::SourceMap + +void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0) +{ + m_surfaces[s] = true; + + int tw = 1 << TEX0.TW; + int th = 1 << TEX0.TH; + + uint32 bp = TEX0.TBP0; + uint32 bw = TEX0.TBW; + + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; + + GSVector2i bs = (bp & 31) == 0 ? psm.pgs : psm.bs; + + int blocks = 0; + + for(int y = 0; y < th; y += bs.y) { - return false; + uint32 base = psm.bn(0, y, bp, bw); + + for(int x = 0; x < tw; x += bs.x) + { + uint32 page = (base + psm.blockOffset[x >> 3]) >> 5; + + if(page < MAX_PAGES) + { + m_map[page][s] = true; + + s->m_pages.push_back(page); + } + } } - else if(GSUtil::IsRectInRectH(r, m_valid) && (r.left >= m_valid.left || r.right <= m_valid.right)) +} + +void GSTextureCache::SourceMap::RemoveAll() +{ + for(hash_map::iterator i = m_surfaces.begin(); i != m_surfaces.end(); i++) { - r.top = m_valid.top; - r.bottom = m_valid.bottom; - if(r.left < m_valid.left) r.right = m_valid.left; - else r.left = m_valid.right; // if(r.right > m_valid.right) - } - else if(GSUtil::IsRectInRectV(r, m_valid) && (r.top >= m_valid.top || r.bottom <= m_valid.bottom)) - { - r.left = m_valid.left; - r.right = m_valid.right; - if(r.top < m_valid.top) r.bottom = m_valid.top; - else r.top = m_valid.bottom; // if(r.bottom > m_valid.bottom) - } - else - { - r = r.runion(m_valid); + delete i->first; } - if(r.rempty()) + m_surfaces.clear(); + + for(int i = 0; i < MAX_PAGES; i++) { - return false; + m_map[i].clear(); + } +} + +void GSTextureCache::SourceMap::RemoveAt(Source* s) +{ + m_surfaces.erase(s); + + for(list::iterator i = s->m_pages.begin(); i != s->m_pages.end(); i++) + { + m_map[*i].erase(s); } - return true; -} \ No newline at end of file + delete s; +} diff --git a/plugins/GSdx/GSTextureCache.h b/plugins/GSdx/GSTextureCache.h index 300d648bf..5857ed535 100644 --- a/plugins/GSdx/GSTextureCache.h +++ b/plugins/GSdx/GSTextureCache.h @@ -26,101 +26,86 @@ class GSTextureCache { public: - class GSSurface : public GSAlignedClass<16> + enum {RenderTarget, DepthStencil}; + + class Surface : public GSAlignedClass<16> { protected: GSRenderer* m_renderer; public: GSTexture* m_texture; - GSTexture* m_palette; - bool m_initpalette; - int m_age; - GSDirtyRectList m_dirty; GIFRegTEX0 m_TEX0; GIFRegTEXA m_TEXA; + int m_age; - explicit GSSurface(GSRenderer* r); - virtual ~GSSurface(); + public: + explicit Surface(GSRenderer* r); + virtual ~Surface(); virtual void Update(); }; - class GSRenderTarget : public GSSurface + class Target; + + class Source : public Surface { public: - bool m_used; - - explicit GSRenderTarget(GSRenderer* r); - - void Update(); - - virtual bool Create(int w, int h); - virtual void Read(const GSVector4i& r) = 0; - }; - - class GSDepthStencil : public GSSurface - { - public: - bool m_used; - - explicit GSDepthStencil(GSRenderer* renderer); - - void Update(); - - virtual bool Create(int w, int h); - }; - - class GSCachedTexture : public GSSurface - { - protected: - bool GetDirtyRect(GSVector4i& r); - - public: - uint32* m_clut; // * - GSVector4i m_valid; + GSTexture* m_palette; + bool m_initpalette; + list m_pages; + uint32 m_valid[MAX_PAGES]; // each uint32 bits map to the 32 blocks of that page + uint32* m_clut; int m_bpp; - bool m_rendered; + bool m_target; - explicit GSCachedTexture(GSRenderer* renderer); - virtual ~GSCachedTexture(); - - void Update(const GSVector4i& rect); + public: + explicit Source(GSRenderer* renderer); + virtual ~Source(); virtual bool Create() = 0; - virtual bool Create(GSRenderTarget* rt) = 0; - virtual bool Create(GSDepthStencil* ds) = 0; + virtual bool Create(Target* dst) = 0; + virtual void Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect); + + void Write(const GSVector4i& r, uint8* buff, int pitch); + }; + + class Target : public Surface + { + public: + int m_type; + bool m_used; + GSDirtyRectList m_dirty; + + public: + explicit Target(GSRenderer* r); + + virtual bool Create(int w, int h, int type); + virtual void Update(); + virtual void Read(const GSVector4i& r) = 0; }; protected: GSRenderer* m_renderer; - list m_rt; - list m_ds; - list m_tex; - - bool m_tex_used; - - template void RecycleByAge(list& l, int maxage = 60) + struct SourceMap { - for(list::iterator i = l.begin(); i != l.end(); ) - { - list::iterator j = i++; + hash_map m_surfaces; + hash_map m_map[MAX_PAGES]; + bool m_used; - T* t = *j; + SourceMap() : m_used(false) {} - if(++t->m_age > maxage) - { - l.erase(j); + void Add(Source* s, const GIFRegTEX0& TEX0); + void RemoveAll(); + void RemoveAt(Source* s); - delete t; - } - } - } + } m_src; - virtual GSRenderTarget* CreateRenderTarget() = 0; - virtual GSDepthStencil* CreateDepthStencil() = 0; - virtual GSCachedTexture* CreateTexture() = 0; + list m_dst[2]; + + virtual Source* CreateSource() = 0; + virtual Target* CreateTarget() = 0; public: GSTextureCache(GSRenderer* r); @@ -128,12 +113,10 @@ public: void RemoveAll(); - GSRenderTarget* GetRenderTarget(const GIFRegTEX0& TEX0, int w, int h, bool fb = false); - GSDepthStencil* GetDepthStencil(const GIFRegTEX0& TEX0, int w, int h); - GSCachedTexture* GetTexture(const GSVector4i& r); + Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r); + Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used, bool fb = false); - void InvalidateTextures(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF); - void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); + void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool target = true); void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); void IncAge(); diff --git a/plugins/GSdx/GSTextureCache10.cpp b/plugins/GSdx/GSTextureCache10.cpp index 0c20e24c2..e4914cb09 100644 --- a/plugins/GSdx/GSTextureCache10.cpp +++ b/plugins/GSdx/GSTextureCache10.cpp @@ -29,16 +29,207 @@ GSTextureCache10::GSTextureCache10(GSRenderer* r) { } -// GSRenderTargetHW10 +// Source10 -void GSTextureCache10::GSRenderTargetHW10::Read(const GSVector4i& r) +bool GSTextureCache10::Source10::Create() { + // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); + + m_TEX0 = m_renderer->m_context->TEX0; + m_TEXA = m_renderer->m_env.TEXA; + + m_bpp = 0; + + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); + + return m_texture != NULL; +} + +bool GSTextureCache10::Source10::Create(Target* dst) +{ + m_target = true; + + if(dst->m_type != RenderTarget) + { + // TODO + + return false; + } + + // TODO: clean up this mess + + dst->Update(); + + // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); + + m_TEX0 = m_renderer->m_context->TEX0; + m_TEXA = m_renderer->m_env.TEXA; + + int tw = 1 << m_TEX0.TW; + int th = 1 << m_TEX0.TH; + int tp = (int)m_TEX0.TW << 6; + + // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) + + int w = (int)(dst->m_texture->m_scale.x * tw); + int h = (int)(dst->m_texture->m_scale.y * th); + + GSVector2i dstsize = dst->m_texture->GetSize(); + + // pitch conversion + + if(dst->m_TEX0.TBW != m_TEX0.TBW) // && dst->m_TEX0.PSM == m_TEX0.PSM + { + // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) + + // ASSERT(dst->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) + + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y); + + GSVector4 size = GSVector4(dstsize).xyxy(); + GSVector4 scale = GSVector4(dst->m_texture->m_scale).xyxy(); + + int bw = 64; + int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; + + GSVector4i br(0, 0, bw, bh); + + int sw = (int)dst->m_TEX0.TBW << 6; + + int dw = (int)m_TEX0.TBW << 6; + int dh = 1 << m_TEX0.TH; + + if(sw != 0) + for(int dy = 0; dy < dh; dy += bh) + { + for(int dx = 0; dx < dw; dx += bw) + { + int o = dy * dw / bh + dx; + + int sx = o % sw; + int sy = o / sw; + + GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; + GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; + + m_renderer->m_dev->StretchRect(dst->m_texture, sr, m_texture, dr); + + // TODO: this is quite a lot of StretchRect, do it with one Draw + } + } + } + else if(tw < tp) + { + // FIXME: timesplitters blurs the render target by blending itself over a couple of times + + if(tw == 256 && th == 128 && tp == 512 && (m_TEX0.TBP0 == 0 || m_TEX0.TBP0 == 0x00e00)) + { + return false; + } + } + + // width/height conversion + + GSVector2 scale = dst->m_texture->m_scale; + + GSVector4 dr(0, 0, w, h); + + if(w > dstsize.x) + { + scale.x = (float)dstsize.x / tw; + dr.z = (float)dstsize.x * scale.x / dst->m_texture->m_scale.x; + w = dstsize.x; + } + + if(h > dstsize.y) + { + scale.y = (float)dstsize.y / th; + dr.w = (float)dstsize.y * scale.y / dst->m_texture->m_scale.y; + h = dstsize.y; + } + + GSVector4 sr(0, 0, w, h); + + GSTexture* st = m_texture ? m_texture : dst->m_texture; + GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); + + if(!m_texture) + { + m_texture = dt; + } + + if((sr == dr).alltrue()) + { + D3D10_BOX box = {0, 0, 0, w, h, 1}; + + (*(GSDevice10*)m_renderer->m_dev)->CopySubresourceRegion(*(GSTexture10*)dt, 0, 0, 0, 0, *(GSTexture10*)st, 0, &box); + } + else + { + sr.z /= st->GetWidth(); + sr.w /= st->GetHeight(); + + m_renderer->m_dev->StretchRect(st, sr, dt, dr); + } + + if(dt != m_texture) + { + m_renderer->m_dev->Recycle(m_texture); + + m_texture = dt; + } + + m_texture->m_scale = scale; + + switch(m_TEX0.PSM) + { + case PSM_PSMCT32: + m_bpp = 0; + break; + case PSM_PSMCT24: + m_bpp = 1; + break; + case PSM_PSMCT16: + case PSM_PSMCT16S: + m_bpp = 2; + break; + case PSM_PSMT8H: + m_bpp = 3; + m_palette = m_renderer->m_dev->CreateTexture(256, 1); + m_initpalette = true; + break; + case PSM_PSMT4HL: + case PSM_PSMT4HH: + ASSERT(0); // TODO + break; + } + + return true; +} + + +// Target10 + +void GSTextureCache10::Target10::Read(const GSVector4i& r) +{ + if(m_type != RenderTarget) + { + // TODO + + return; + } + if(m_TEX0.PSM != PSM_PSMCT32 && m_TEX0.PSM != PSM_PSMCT24 && m_TEX0.PSM != PSM_PSMCT16 && m_TEX0.PSM != PSM_PSMCT16S) { //ASSERT(0); + return; } @@ -121,272 +312,3 @@ void GSTextureCache10::GSRenderTargetHW10::Read(const GSVector4i& r) m_renderer->m_dev->Recycle(offscreen); } } - -// GSTextureHW10 - -bool GSTextureCache10::GSCachedTextureHW10::Create() -{ - // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); - - m_TEX0 = m_renderer->m_context->TEX0; - m_TEXA = m_renderer->m_env.TEXA; - - m_bpp = 0; - - ASSERT(m_texture == NULL); - - m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); - - return m_texture != NULL; -} - -bool GSTextureCache10::GSCachedTextureHW10::Create(GSRenderTarget* rt) -{ - m_rendered = true; - - // TODO: clean up this mess - - rt->Update(); - - // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); - - m_TEX0 = m_renderer->m_context->TEX0; - m_TEXA = m_renderer->m_env.TEXA; - - int tw = 1 << m_TEX0.TW; - int th = 1 << m_TEX0.TH; - int tp = (int)m_TEX0.TW << 6; - - // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) - - int w = (int)(rt->m_texture->m_scale.x * tw); - int h = (int)(rt->m_texture->m_scale.y * th); - - GSVector2i rtsize = rt->m_texture->GetSize(); - - // pitch conversion - - if(rt->m_TEX0.TBW != m_TEX0.TBW) // && rt->m_TEX0.PSM == m_TEX0.PSM - { - // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) - - // ASSERT(rt->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) - - ASSERT(m_texture == NULL); - - m_texture = m_renderer->m_dev->CreateRenderTarget(rtsize.x, rtsize.y); - - GSVector4 size = GSVector4(rtsize).xyxy(); - GSVector4 scale = GSVector4(rt->m_texture->m_scale).xyxy(); - - int bw = 64; - int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; - - GSVector4i br(0, 0, bw, bh); - - int sw = (int)rt->m_TEX0.TBW << 6; - - int dw = (int)m_TEX0.TBW << 6; - int dh = 1 << m_TEX0.TH; - - if(sw != 0) - for(int dy = 0; dy < dh; dy += bh) - { - for(int dx = 0; dx < dw; dx += bw) - { - int o = dy * dw / bh + dx; - - int sx = o % sw; - int sy = o / sw; - - GSVector4 src = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; - GSVector4 dst = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; - - m_renderer->m_dev->StretchRect(rt->m_texture, src, m_texture, dst); - - // TODO: this is quite a lot of StretchRect, do it with one Draw - } - } - } - else if(tw < tp) - { - // FIXME: timesplitters blurs the render target by blending itself over a couple of times - - if(tw == 256 && th == 128 && tp == 512 && (m_TEX0.TBP0 == 0 || m_TEX0.TBP0 == 0x00e00)) - { - return false; - } - } - - // width/height conversion - - GSVector2 scale = rt->m_texture->m_scale; - - GSVector4 dst(0, 0, w, h); - - if(w > rtsize.x) - { - scale.x = (float)rtsize.x / tw; - dst.z = (float)rtsize.x * scale.x / rt->m_texture->m_scale.x; - w = rtsize.x; - } - - if(h > rtsize.y) - { - scale.y = (float)rtsize.y / th; - dst.w = (float)rtsize.y * scale.y / rt->m_texture->m_scale.y; - h = rtsize.y; - } - - GSVector4 src(0, 0, w, h); - - GSTexture* st = m_texture ? m_texture : rt->m_texture; - GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); - - if(!m_texture) - { - m_texture = dt; - } - - if(src.x == dst.x && src.y == dst.y && src.z == dst.z && src.w == dst.w) - { - D3D10_BOX box = {0, 0, 0, w, h, 1}; - - (*(GSDevice10*)m_renderer->m_dev)->CopySubresourceRegion(*(GSTexture10*)dt, 0, 0, 0, 0, *(GSTexture10*)st, 0, &box); - } - else - { - src.z /= st->GetWidth(); - src.w /= st->GetHeight(); - - m_renderer->m_dev->StretchRect(st, src, dt, dst); - } - - if(dt != m_texture) - { - m_renderer->m_dev->Recycle(m_texture); - - m_texture = dt; - } - - m_texture->m_scale = scale; - - switch(m_TEX0.PSM) - { - case PSM_PSMCT32: - m_bpp = 0; - break; - case PSM_PSMCT24: - m_bpp = 1; - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - m_bpp = 2; - break; - case PSM_PSMT8H: - m_bpp = 3; - m_palette = m_renderer->m_dev->CreateTexture(256, 1); - m_initpalette = true; - break; - case PSM_PSMT4HL: - case PSM_PSMT4HH: - ASSERT(0); // TODO - break; - } - - return true; -} - -bool GSTextureCache10::GSCachedTextureHW10::Create(GSDepthStencil* ds) -{ - m_rendered = true; - - return false; -/* - // TODO: clean up this mess - - ds->Update(); - - // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); - - m_TEX0 = m_renderer->m_context->TEX0; - m_TEXA = m_renderer->m_env.TEXA; - - int tw = 1 << m_TEX0.TW; - int th = 1 << m_TEX0.TH; - int tp = (int)m_TEX0.TW << 6; - - // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) - - int w = (int)(ds->m_texture->m_scale.x * tw); - int h = (int)(ds->m_texture->m_scale.y * th); - - GSVector2i dssize = ds->m_texture->GetSize(); - - // pitch conversion - - if(ds->m_TEX0.TBW != m_TEX0.TBW) // && rt->m_TEX0.PSM == m_TEX0.PSM - { - ASSERT(0); - } - else if(tw < tp) - { - } - - // width/height conversion - - GSVector2 scale = ds->m_texture->m_scale; - - GSVector4 dst(0, 0, w, h); - - if(w > dssize.x) - { - scale.x = (float)dssize.x / tw; - dst.z = (float)dssize.x * scale.x / ds->m_texture->m_scale.x; - w = dssize.x; - } - - if(h > dssize.y) - { - scale.y = (float)dssize.y / th; - dst.w = (float)dssize.y * scale.y / ds->m_texture->m_scale.y; - h = dssize.y; - } - - m_texture = m_renderer->m_dev->CreateRenderTarget(w, h); - - GSVector4 src(0, 0, w, h); - - src.z /= ds->m_texture->GetWidth(); - src.w /= ds->m_texture->GetHeight(); - - m_renderer->m_dev->StretchRect(ds->m_texture, src, m_texture, dst, 7); - - m_texture->m_scale = scale; - - switch(m_TEX0.PSM) - { - case PSM_PSMCT32: - m_bpp = 0; - break; - case PSM_PSMCT24: - m_bpp = 1; - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - m_bpp = 2; - break; - case PSM_PSMT8H: - m_bpp = 3; - m_palette = m_renderer->m_dev->CreateTexture(256, 1); - m_initpalette = true; - break; - case PSM_PSMT4HL: - case PSM_PSMT4HH: - ASSERT(0); // TODO - break; - } - - return true; -*/ -} diff --git a/plugins/GSdx/GSTextureCache10.h b/plugins/GSdx/GSTextureCache10.h index bc480bea4..857d37c4e 100644 --- a/plugins/GSdx/GSTextureCache10.h +++ b/plugins/GSdx/GSTextureCache10.h @@ -26,34 +26,26 @@ class GSTextureCache10 : public GSTextureCache { - class GSRenderTargetHW10 : public GSRenderTarget + class Source10 : public Source { public: - explicit GSRenderTargetHW10(GSRenderer* r) : GSRenderTarget(r) {} + explicit Source10(GSRenderer* r) : Source(r) {} + + bool Create(); + bool Create(Target* dst); + }; + + class Target10 : public Target + { + public: + explicit Target10(GSRenderer* r) : Target(r) {} void Read(const GSVector4i& r); }; - class GSDepthStencilHW10 : public GSDepthStencil - { - public: - explicit GSDepthStencilHW10(GSRenderer* r) : GSDepthStencil(r) {} - }; - - class GSCachedTextureHW10 : public GSCachedTexture - { - public: - explicit GSCachedTextureHW10(GSRenderer* r) : GSCachedTexture(r) {} - - bool Create(); - bool Create(GSRenderTarget* rt); - bool Create(GSDepthStencil* ds); - }; - protected: - GSRenderTarget* CreateRenderTarget() {return new GSRenderTargetHW10(m_renderer);} - GSDepthStencil* CreateDepthStencil() {return new GSDepthStencilHW10(m_renderer);} - GSCachedTexture* CreateTexture() {return new GSCachedTextureHW10(m_renderer);} + Source* CreateSource() {return new Source10(m_renderer);} + Target* CreateTarget() {return new Target10(m_renderer);} public: GSTextureCache10(GSRenderer* r); diff --git a/plugins/GSdx/GSTextureCache11.cpp b/plugins/GSdx/GSTextureCache11.cpp index 221bfb7cd..fc0e4ee0b 100644 --- a/plugins/GSdx/GSTextureCache11.cpp +++ b/plugins/GSdx/GSTextureCache11.cpp @@ -29,16 +29,208 @@ GSTextureCache11::GSTextureCache11(GSRenderer* r) { } -// GSRenderTargetHW10 +// Source11 -void GSTextureCache11::GSRenderTargetHW11::Read(const GSVector4i& r) +bool GSTextureCache11::Source11::Create() { + // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); + + m_TEX0 = m_renderer->m_context->TEX0; + m_TEXA = m_renderer->m_env.TEXA; + + m_bpp = 0; + + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); + + return m_texture != NULL; +} + +bool GSTextureCache11::Source11::Create(Target* dst) +{ + m_target = true; + + if(dst->m_type != RenderTarget) + { + // TODO + + return false; + } + + // TODO: clean up this mess + + dst->Update(); + + // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); + + m_TEX0 = m_renderer->m_context->TEX0; + m_TEXA = m_renderer->m_env.TEXA; + + int tw = 1 << m_TEX0.TW; + int th = 1 << m_TEX0.TH; + int tp = (int)m_TEX0.TW << 6; + + // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) + + int w = (int)(dst->m_texture->m_scale.x * tw); + int h = (int)(dst->m_texture->m_scale.y * th); + + GSVector2i dstsize = dst->m_texture->GetSize(); + + // pitch conversion + + if(dst->m_TEX0.TBW != m_TEX0.TBW) // && dst->m_TEX0.PSM == m_TEX0.PSM + { + // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) + + // ASSERT(dst->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) + + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y); + + GSVector4 size = GSVector4(dstsize).xyxy(); + GSVector4 scale = GSVector4(dst->m_texture->m_scale).xyxy(); + + int bw = 64; + int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; + + GSVector4i br(0, 0, bw, bh); + + int sw = (int)dst->m_TEX0.TBW << 6; + + int dw = (int)m_TEX0.TBW << 6; + int dh = 1 << m_TEX0.TH; + + if(sw != 0) + for(int dy = 0; dy < dh; dy += bh) + { + for(int dx = 0; dx < dw; dx += bw) + { + int o = dy * dw / bh + dx; + + int sx = o % sw; + int sy = o / sw; + + GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; + GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; + + m_renderer->m_dev->StretchRect(dst->m_texture, sr, m_texture, dr); + + // TODO: this is quite a lot of StretchRect, do it with one Draw + } + } + } + else if(tw < tp) + { + // FIXME: timesplitters blurs the render target by blending itself over a couple of times + + if(tw == 256 && th == 128 && tp == 512 && (m_TEX0.TBP0 == 0 || m_TEX0.TBP0 == 0x00e00)) + { + return false; + } + } + + // width/height conversion + + GSVector2 scale = dst->m_texture->m_scale; + + GSVector4 dr(0, 0, w, h); + + if(w > dstsize.x) + { + scale.x = (float)dstsize.x / tw; + dr.z = (float)dstsize.x * scale.x / dst->m_texture->m_scale.x; + w = dstsize.x; + } + + if(h > dstsize.y) + { + scale.y = (float)dstsize.y / th; + dr.w = (float)dstsize.y * scale.y / dst->m_texture->m_scale.y; + h = dstsize.y; + } + + GSVector4 sr(0, 0, w, h); + + GSTexture* st = m_texture ? m_texture : dst->m_texture; + GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); + + if(!m_texture) + { + m_texture = dt; + } + + if((sr == dr).alltrue()) + { + D3D11_BOX box = {0, 0, 0, w, h, 1}; + + ID3D11DeviceContext* ctx = *(GSDevice11*)m_renderer->m_dev; + + ctx->CopySubresourceRegion(*(GSTexture11*)dt, 0, 0, 0, 0, *(GSTexture11*)st, 0, &box); + } + else + { + sr.z /= st->GetWidth(); + sr.w /= st->GetHeight(); + + m_renderer->m_dev->StretchRect(st, sr, dt, dr); + } + + if(dt != m_texture) + { + m_renderer->m_dev->Recycle(m_texture); + + m_texture = dt; + } + + m_texture->m_scale = scale; + + switch(m_TEX0.PSM) + { + case PSM_PSMCT32: + m_bpp = 0; + break; + case PSM_PSMCT24: + m_bpp = 1; + break; + case PSM_PSMCT16: + case PSM_PSMCT16S: + m_bpp = 2; + break; + case PSM_PSMT8H: + m_bpp = 3; + m_palette = m_renderer->m_dev->CreateTexture(256, 1); + m_initpalette = true; + break; + case PSM_PSMT4HL: + case PSM_PSMT4HH: + ASSERT(0); // TODO + break; + } + + return true; +} + +// Target11 + +void GSTextureCache11::Target11::Read(const GSVector4i& r) +{ + if(m_type != RenderTarget) + { + // TODO + + return; + } + if(m_TEX0.PSM != PSM_PSMCT32 && m_TEX0.PSM != PSM_PSMCT24 && m_TEX0.PSM != PSM_PSMCT16 && m_TEX0.PSM != PSM_PSMCT16S) { //ASSERT(0); + return; } @@ -122,188 +314,3 @@ void GSTextureCache11::GSRenderTargetHW11::Read(const GSVector4i& r) } } -// GSTextureHW10 - -bool GSTextureCache11::GSCachedTextureHW11::Create() -{ - // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); - - m_TEX0 = m_renderer->m_context->TEX0; - m_TEXA = m_renderer->m_env.TEXA; - - m_bpp = 0; - - ASSERT(m_texture == NULL); - - m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); - - return m_texture != NULL; -} - -bool GSTextureCache11::GSCachedTextureHW11::Create(GSRenderTarget* rt) -{ - // TODO: clean up this mess - - rt->Update(); - - // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); - - m_TEX0 = m_renderer->m_context->TEX0; - m_TEXA = m_renderer->m_env.TEXA; - - m_rendered = true; - - int tw = 1 << m_TEX0.TW; - int th = 1 << m_TEX0.TH; - int tp = (int)m_TEX0.TW << 6; - - // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) - - int w = (int)(rt->m_texture->m_scale.x * tw); - int h = (int)(rt->m_texture->m_scale.y * th); - - GSVector2i rtsize = rt->m_texture->GetSize(); - - // pitch conversion - - if(rt->m_TEX0.TBW != m_TEX0.TBW) // && rt->m_TEX0.PSM == m_TEX0.PSM - { - // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) - - // ASSERT(rt->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) - - ASSERT(m_texture == NULL); - - m_texture = m_renderer->m_dev->CreateRenderTarget(rtsize.x, rtsize.y); - - GSVector4 size = GSVector4(rtsize).xyxy(); - GSVector4 scale = GSVector4(rt->m_texture->m_scale).xyxy(); - - int bw = 64; - int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; - - GSVector4i br(0, 0, bw, bh); - - int sw = (int)rt->m_TEX0.TBW << 6; - - int dw = (int)m_TEX0.TBW << 6; - int dh = 1 << m_TEX0.TH; - - if(sw != 0) - for(int dy = 0; dy < dh; dy += bh) - { - for(int dx = 0; dx < dw; dx += bw) - { - int o = dy * dw / bh + dx; - - int sx = o % sw; - int sy = o / sw; - - GSVector4 src = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; - GSVector4 dst = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; - - m_renderer->m_dev->StretchRect(rt->m_texture, src, m_texture, dst); - - // TODO: this is quite a lot of StretchRect, do it with one Draw - } - } - } - else if(tw < tp) - { - // FIXME: timesplitters blurs the render target by blending itself over a couple of times - - if(tw == 256 && th == 128 && tp == 512 && (m_TEX0.TBP0 == 0 || m_TEX0.TBP0 == 0x00e00)) - { - return false; - } - } - - // width/height conversion - - GSVector2 scale = rt->m_texture->m_scale; - - GSVector4 dst(0, 0, w, h); - - if(w > rtsize.x) - { - scale.x = (float)rtsize.x / tw; - dst.z = (float)rtsize.x * scale.x / rt->m_texture->m_scale.x; - w = rtsize.x; - } - - if(h > rtsize.y) - { - scale.y = (float)rtsize.y / th; - dst.w = (float)rtsize.y * scale.y / rt->m_texture->m_scale.y; - h = rtsize.y; - } - - GSVector4 src(0, 0, w, h); - - GSTexture* st = m_texture ? m_texture : rt->m_texture; - GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); - - if(!m_texture) - { - m_texture = dt; - } - - if(src.x == dst.x && src.y == dst.y && src.z == dst.z && src.w == dst.w) - { - D3D11_BOX box = {0, 0, 0, w, h, 1}; - - ID3D11DeviceContext* ctx = *(GSDevice11*)m_renderer->m_dev; - - ctx->CopySubresourceRegion(*(GSTexture11*)dt, 0, 0, 0, 0, *(GSTexture11*)st, 0, &box); - } - else - { - src.z /= st->GetWidth(); - src.w /= st->GetHeight(); - - m_renderer->m_dev->StretchRect(st, src, dt, dst); - } - - if(dt != m_texture) - { - m_renderer->m_dev->Recycle(m_texture); - - m_texture = dt; - } - - m_texture->m_scale = scale; - - switch(m_TEX0.PSM) - { - case PSM_PSMCT32: - m_bpp = 0; - break; - case PSM_PSMCT24: - m_bpp = 1; - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - m_bpp = 2; - break; - case PSM_PSMT8H: - m_bpp = 3; - m_palette = m_renderer->m_dev->CreateTexture(256, 1); - m_initpalette = true; - break; - case PSM_PSMT4HL: - case PSM_PSMT4HH: - ASSERT(0); // TODO - break; - } - - return true; -} - -bool GSTextureCache11::GSCachedTextureHW11::Create(GSDepthStencil* ds) -{ - m_rendered = true; - - // TODO - - return false; -} diff --git a/plugins/GSdx/GSTextureCache11.h b/plugins/GSdx/GSTextureCache11.h index ec3d883f8..d02c9c5f7 100644 --- a/plugins/GSdx/GSTextureCache11.h +++ b/plugins/GSdx/GSTextureCache11.h @@ -26,34 +26,26 @@ class GSTextureCache11 : public GSTextureCache { - class GSRenderTargetHW11 : public GSRenderTarget + class Source11 : public Source { public: - explicit GSRenderTargetHW11(GSRenderer* r) : GSRenderTarget(r) {} + explicit Source11(GSRenderer* r) : Source(r) {} + + bool Create(); + bool Create(Target* dst); + }; + + class Target11 : public Target + { + public: + explicit Target11(GSRenderer* r) : Target(r) {} void Read(const GSVector4i& r); }; - class GSDepthStencilHW11 : public GSDepthStencil - { - public: - explicit GSDepthStencilHW11(GSRenderer* r) : GSDepthStencil(r) {} - }; - - class GSCachedTextureHW11 : public GSCachedTexture - { - public: - explicit GSCachedTextureHW11(GSRenderer* r) : GSCachedTexture(r) {} - - bool Create(); - bool Create(GSRenderTarget* rt); - bool Create(GSDepthStencil* ds); - }; - protected: - GSRenderTarget* CreateRenderTarget() {return new GSRenderTargetHW11(m_renderer);} - GSDepthStencil* CreateDepthStencil() {return new GSDepthStencilHW11(m_renderer);} - GSCachedTexture* CreateTexture() {return new GSCachedTextureHW11(m_renderer);} + Source* CreateSource() {return new Source11(m_renderer);} + Target* CreateTarget() {return new Target11(m_renderer);} public: GSTextureCache11(GSRenderer* r); diff --git a/plugins/GSdx/GSTextureCache9.cpp b/plugins/GSdx/GSTextureCache9.cpp index e9b685ae1..6b3324985 100644 --- a/plugins/GSdx/GSTextureCache9.cpp +++ b/plugins/GSdx/GSTextureCache9.cpp @@ -29,16 +29,207 @@ GSTextureCache9::GSTextureCache9(GSRenderer* r) { } -// GSRenderTarget9 +// Source9 -void GSTextureCache9::GSRenderTarget9::Read(const GSVector4i& r) +bool GSTextureCache9::Source9::Create() { + // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); + + m_TEX0 = m_renderer->m_context->TEX0; + m_TEXA = m_renderer->m_env.TEXA; + + m_bpp = 0; + + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); + + return m_texture != NULL; +} + +bool GSTextureCache9::Source9::Create(Target* dst) +{ + m_target = true; + + if(dst->m_type != RenderTarget) + { + // TODO + + return false; + } + + // TODO: clean up this mess + + dst->Update(); + + // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); + + m_TEX0 = m_renderer->m_context->TEX0; + m_TEXA = m_renderer->m_env.TEXA; + + int tw = 1 << m_TEX0.TW; + int th = 1 << m_TEX0.TH; + int tp = (int)m_TEX0.TW << 6; + + // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) + + int w = (int)(dst->m_texture->m_scale.x * tw); + int h = (int)(dst->m_texture->m_scale.y * th); + + GSVector2i dstsize = dst->m_texture->GetSize(); + + // pitch conversion + + if(dst->m_TEX0.TBW != m_TEX0.TBW) // && dst->m_TEX0.PSM == m_TEX0.PSM + { + // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) + + // ASSERT(dst->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) + + ASSERT(m_texture == NULL); + + m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y); + + GSVector4 size = GSVector4(dstsize).xyxy(); + GSVector4 scale = GSVector4(dst->m_texture->m_scale).xyxy(); + + int bw = 64; + int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; + + GSVector4i br(0, 0, bw, bh); + + int sw = (int)dst->m_TEX0.TBW << 6; + + int dw = (int)m_TEX0.TBW << 6; + int dh = 1 << m_TEX0.TH; + + if(sw != 0) + for(int dy = 0; dy < dh; dy += bh) + { + for(int dx = 0; dx < dw; dx += bw) + { + int o = dy * dw / bh + dx; + + int sx = o % sw; + int sy = o / sw; + + GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; + GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; + + m_renderer->m_dev->StretchRect(dst->m_texture, sr, m_texture, dr); + + // TODO: this is quite a lot of StretchRect, do it with one Draw + } + } + } + else if(tw < tp) + { + // FIXME: timesplitters blurs the render target by blending itself over a couple of times + + if(tw == 256 && th == 128 && tp == 512 && (m_TEX0.TBP0 == 0 || m_TEX0.TBP0 == 0x00e00)) + { + return false; + } + } + + // width/height conversion + + GSVector2 scale = dst->m_texture->m_scale; + + GSVector4 dr(0, 0, w, h); + + if(w > dstsize.x) + { + scale.x = (float)dstsize.x / tw; + dr.z = (float)dstsize.x * scale.x / dst->m_texture->m_scale.x; + w = dstsize.x; + } + + if(h > dstsize.y) + { + scale.y = (float)dstsize.y / th; + dr.w = (float)dstsize.y * scale.y / dst->m_texture->m_scale.y; + h = dstsize.y; + } + + GSVector4 sr(0, 0, w, h); + + GSTexture* st = m_texture ? m_texture : dst->m_texture; + GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); + + if(!m_texture) + { + m_texture = dt; + } + + if((sr == dr).alltrue()) + { + GSVector4i r(0, 0, w, h); + + (*(GSDevice9*)m_renderer->m_dev)->StretchRect(*(GSTexture9*)st, r, *(GSTexture9*)dt, r, D3DTEXF_POINT); + } + else + { + sr.z /= st->GetWidth(); + sr.w /= st->GetHeight(); + + m_renderer->m_dev->StretchRect(st, sr, dt, dr); + } + + if(dt != m_texture) + { + m_renderer->m_dev->Recycle(m_texture); + + m_texture = dt; + } + + m_texture->m_scale = scale; + + switch(m_TEX0.PSM) + { + case PSM_PSMCT32: + m_bpp = 0; + break; + case PSM_PSMCT24: + m_bpp = 1; + break; + case PSM_PSMCT16: + case PSM_PSMCT16S: + m_bpp = 2; + break; + case PSM_PSMT8H: + m_bpp = 3; + m_palette = m_renderer->m_dev->CreateTexture(256, 1); + m_initpalette = true; + break; + case PSM_PSMT4HL: + case PSM_PSMT4HH: + ASSERT(0); // TODO + break; + } + + return true; +} + + +// Target9 + +void GSTextureCache9::Target9::Read(const GSVector4i& r) +{ + if(m_type != RenderTarget) + { + // TODO + + return; + } + if(m_TEX0.PSM != PSM_PSMCT32 && m_TEX0.PSM != PSM_PSMCT24 && m_TEX0.PSM != PSM_PSMCT16 && m_TEX0.PSM != PSM_PSMCT16S) { //ASSERT(0); + return; } @@ -120,186 +311,3 @@ void GSTextureCache9::GSRenderTarget9::Read(const GSVector4i& r) } } -// GSTexture9 - -bool GSTextureCache9::GSCachedTexture9::Create() -{ - // m_renderer->m_perfmon.Put(GSPerfMon::WriteTexture, 1); - - m_TEX0 = m_renderer->m_context->TEX0; - m_TEXA = m_renderer->m_env.TEXA; - - m_bpp = 0; - - ASSERT(m_texture == NULL); - - m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH); - - return m_texture != NULL; -} - -bool GSTextureCache9::GSCachedTexture9::Create(GSRenderTarget* rt) -{ - // TODO: clean up this mess - - rt->Update(); - - // m_renderer->m_perfmon.Put(GSPerfMon::ConvertRT2T, 1); - - m_TEX0 = m_renderer->m_context->TEX0; - m_TEXA = m_renderer->m_env.TEXA; - - m_rendered = true; - - int tw = 1 << m_TEX0.TW; - int th = 1 << m_TEX0.TH; - int tp = (int)m_TEX0.TW << 6; - - // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) - - int w = (int)(rt->m_texture->m_scale.x * tw); - int h = (int)(rt->m_texture->m_scale.y * th); - - GSVector2i rtsize = rt->m_texture->GetSize(); - - // pitch conversion - - if(rt->m_TEX0.TBW != m_TEX0.TBW) // && rt->m_TEX0.PSM == m_TEX0.PSM - { - // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) - - // ASSERT(rt->m_TEX0.TBW > m_TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) - - ASSERT(m_texture == NULL); - - m_texture = m_renderer->m_dev->CreateRenderTarget(rtsize.x, rtsize.y); - - GSVector4 size = GSVector4(rtsize).xyxy(); - GSVector4 scale = GSVector4(rt->m_texture->m_scale).xyxy(); - - int bw = 64; - int bh = m_TEX0.PSM == PSM_PSMCT32 || m_TEX0.PSM == PSM_PSMCT24 ? 32 : 64; - - GSVector4i br(0, 0, bw, bh); - - int sw = (int)rt->m_TEX0.TBW << 6; - - int dw = (int)m_TEX0.TBW << 6; - int dh = 1 << m_TEX0.TH; - - if(sw != 0) - for(int dy = 0; dy < dh; dy += bh) - { - for(int dx = 0; dx < dw; dx += bw) - { - int o = dy * dw / bh + dx; - - int sx = o % sw; - int sy = o / sw; - - GSVector4 src = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; - GSVector4 dst = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; - - m_renderer->m_dev->StretchRect(rt->m_texture, src, m_texture, dst); - - // TODO: this is quite a lot of StretchRect, do it with one Draw - } - } - } - else if(tw < tp) - { - // FIXME: timesplitters blurs the render target by blending itself over a couple of times - - if(tw == 256 && th == 128 && tp == 512 && (m_TEX0.TBP0 == 0 || m_TEX0.TBP0 == 0x00e00)) - { - return false; - } - } - - // width/height conversion - - GSVector2 scale = rt->m_texture->m_scale; - - GSVector4 dst(0, 0, w, h); - - if(w > rtsize.x) - { - scale.x = (float)rtsize.x / tw; - dst.z = (float)rtsize.x * scale.x / rt->m_texture->m_scale.x; - w = rtsize.x; - } - - if(h > rtsize.y) - { - scale.y = (float)rtsize.y / th; - dst.w = (float)rtsize.y * scale.y / rt->m_texture->m_scale.y; - h = rtsize.y; - } - - GSVector4 src(0, 0, w, h); - - GSTexture* st = m_texture ? m_texture : rt->m_texture; - GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h); - - if(!m_texture) - { - m_texture = dt; - } - - if(src.x == dst.x && src.y == dst.y && src.z == dst.z && src.w == dst.w) - { - GSVector4i r(0, 0, w, h); - - (*(GSDevice9*)m_renderer->m_dev)->StretchRect(*(GSTexture9*)st, r, *(GSTexture9*)dt, r, D3DTEXF_POINT); - } - else - { - src.z /= st->GetWidth(); - src.w /= st->GetHeight(); - - m_renderer->m_dev->StretchRect(st, src, dt, dst); - } - - if(dt != m_texture) - { - m_renderer->m_dev->Recycle(m_texture); - - m_texture = dt; - } - - m_texture->m_scale = scale; - - switch(m_TEX0.PSM) - { - case PSM_PSMCT32: - m_bpp = 0; - break; - case PSM_PSMCT24: - m_bpp = 1; - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - m_bpp = 2; - break; - case PSM_PSMT8H: - m_bpp = 3; - m_palette = m_renderer->m_dev->CreateTexture(256, 1); - m_initpalette = true; - break; - case PSM_PSMT4HL: - case PSM_PSMT4HH: - ASSERT(0); // TODO - break; - } - - return true; -} - -bool GSTextureCache9::GSCachedTexture9::Create(GSDepthStencil* ds) -{ - m_rendered = true; - - // TODO - - return false; -} diff --git a/plugins/GSdx/GSTextureCache9.h b/plugins/GSdx/GSTextureCache9.h index 3f3afe0b2..0d0aedb2e 100644 --- a/plugins/GSdx/GSTextureCache9.h +++ b/plugins/GSdx/GSTextureCache9.h @@ -26,34 +26,26 @@ class GSTextureCache9 : public GSTextureCache { - class GSRenderTarget9 : public GSRenderTarget + class Source9 : public Source { public: - explicit GSRenderTarget9(GSRenderer* r) : GSRenderTarget(r) {} + explicit Source9(GSRenderer* r) : Source(r) {} + + bool Create(); + bool Create(Target* dst); + }; + + class Target9 : public Target + { + public: + explicit Target9(GSRenderer* r) : Target(r) {} void Read(const GSVector4i& r); }; - class GSDepthStencil9 : public GSDepthStencil - { - public: - explicit GSDepthStencil9(GSRenderer* r) : GSDepthStencil(r) {} - }; - - class GSCachedTexture9 : public GSCachedTexture - { - public: - explicit GSCachedTexture9(GSRenderer* r) : GSCachedTexture(r) {} - - bool Create(); - bool Create(GSRenderTarget* rt); - bool Create(GSDepthStencil* ds); - }; - protected: - GSRenderTarget* CreateRenderTarget() {return new GSRenderTarget9(m_renderer);} - GSDepthStencil* CreateDepthStencil() {return new GSDepthStencil9(m_renderer);} - GSCachedTexture* CreateTexture() {return new GSCachedTexture9(m_renderer);} + Source* CreateSource() {return new Source9(m_renderer);} + Target* CreateTarget() {return new Target9(m_renderer);} public: GSTextureCache9(GSRenderer* r); diff --git a/plugins/GSdx/GSTextureCacheOGL.cpp b/plugins/GSdx/GSTextureCacheOGL.cpp index b47093518..99131040d 100644 --- a/plugins/GSdx/GSTextureCacheOGL.cpp +++ b/plugins/GSdx/GSTextureCacheOGL.cpp @@ -29,34 +29,27 @@ GSTextureCacheOGL::GSTextureCacheOGL(GSRenderer* r) { } -// GSRenderTargetOGL +// SourceOGL -void GSTextureCacheOGL::GSRenderTargetOGL::Read(const GSVector4i& r) -{ - // TODO -} - -// GSTextureOGL - -bool GSTextureCacheOGL::GSCachedTextureOGL::Create() +bool GSTextureCacheOGL::SourceOGL::Create() { // TODO return true; } -bool GSTextureCacheOGL::GSCachedTextureOGL::Create(GSRenderTarget* rt) +bool GSTextureCacheOGL::SourceOGL::Create(Target* dst) { + m_target = true; + // TODO return true; } -bool GSTextureCacheOGL::GSCachedTextureOGL::Create(GSDepthStencil* ds) +// TargetOGL + +void GSTextureCacheOGL::TargetOGL::Read(const GSVector4i& r) { - m_rendered = true; - // TODO - - return false; } diff --git a/plugins/GSdx/GSTextureCacheOGL.h b/plugins/GSdx/GSTextureCacheOGL.h index c553559bd..41bb7d4c8 100644 --- a/plugins/GSdx/GSTextureCacheOGL.h +++ b/plugins/GSdx/GSTextureCacheOGL.h @@ -26,34 +26,26 @@ class GSTextureCacheOGL : public GSTextureCache { - class GSRenderTargetOGL : public GSRenderTarget + class SourceOGL : public Source { public: - explicit GSRenderTargetOGL(GSRenderer* r) : GSRenderTarget(r) {} + explicit SourceOGL(GSRenderer* r) : Source(r) {} + + bool Create(); + bool Create(Target* dst); + }; + + class TargetOGL : public Target + { + public: + explicit TargetOGL(GSRenderer* r) : Target(r) {} void Read(const GSVector4i& r); }; - class GSDepthStencilOGL : public GSDepthStencil - { - public: - explicit GSDepthStencilOGL(GSRenderer* r) : GSDepthStencil(r) {} - }; - - class GSCachedTextureOGL : public GSCachedTexture - { - public: - explicit GSCachedTextureOGL(GSRenderer* r) : GSCachedTexture(r) {} - - bool Create(); - bool Create(GSRenderTarget* rt); - bool Create(GSDepthStencil* ds); - }; - protected: - GSRenderTarget* CreateRenderTarget() {return new GSRenderTargetOGL(m_renderer);} - GSDepthStencil* CreateDepthStencil() {return new GSDepthStencilOGL(m_renderer);} - GSCachedTexture* CreateTexture() {return new GSCachedTextureOGL(m_renderer);} + Source* CreateSource() {return new SourceOGL(m_renderer);} + Target* CreateTarget() {return new TargetOGL(m_renderer);} public: GSTextureCacheOGL(GSRenderer* r); diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index 1be3e4b6a..17bd19817 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -34,17 +34,15 @@ GSTextureCacheSW::~GSTextureCacheSW() const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r) { - GSLocalMemory& mem = m_state->m_mem; - const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; - const hash_map& map = m_map[TEX0.TBP0 >> 5]; - GSTexture* t = NULL; + const hash_map& map = m_map[TEX0.TBP0 >> 5]; + for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) { - GSTexture* t2 = (*i).first; + GSTexture* t2 = i->first; if(((t2->m_TEX0.u32[0] ^ TEX0.u32[0]) | ((t2->m_TEX0.u32[1] ^ TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH { @@ -85,12 +83,10 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE { uint32 page = (base + psm.blockOffset[x >> 3]) >> 5; - if(page >= MAX_PAGES) + if(page < MAX_PAGES) { - continue; + m_map[page][t] = true; } - - m_map[page][t] = true; } } } @@ -170,20 +166,21 @@ void GSTextureCacheSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, cons { uint32 page = (base + psm.blockOffset[x >> 3]) >> 5; - if(page >= MAX_PAGES) + if(page < MAX_PAGES) { - continue; - } + const hash_map& map = m_map[page]; - const hash_map& map = m_map[page]; + for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) + { + GSTexture* t = i->first; - for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) - { - GSTexture* t = (*i).first; + if(GSUtil::HasSharedBits(BITBLTBUF.DPSM, t->m_TEX0.PSM)) + { + t->m_valid[page] = 0; - t->m_valid[page] = 0; - - t->m_complete = false; + t->m_complete = false; + } + } } } } @@ -219,13 +216,8 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX m_TEX0 = TEX0; m_TEXA = TEXA; - GSLocalMemory& mem = m_state->m_mem; - const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; - uint32 bp = TEX0.TBP0; - uint32 bw = TEX0.TBW; - GSVector2i s = psm.bs; int tw = max(1 << TEX0.TW, s.x); @@ -250,8 +242,13 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX m_complete = true; // lame, but better than nothing } + GSLocalMemory& mem = m_state->m_mem; + + uint32 bp = TEX0.TBP0; + uint32 bw = TEX0.TBW; + GSLocalMemory::readTextureBlock rtxb = psm.rtxbP; - + int bytes = psm.pal > 0 ? 1 : 4; uint32 pitch = (1 << m_tw) * bytes; diff --git a/plugins/GSdx/GSTextureCacheSW.h b/plugins/GSdx/GSTextureCacheSW.h index 4e99396ca..ccb57495e 100644 --- a/plugins/GSdx/GSTextureCacheSW.h +++ b/plugins/GSdx/GSTextureCacheSW.h @@ -23,9 +23,6 @@ #include "GSRenderer.h" -#define MAX_PAGES 512 -#define MAX_BLOCKS 16384 - class GSTextureCacheSW { public: diff --git a/plugins/GSdx/GSTextureFX.cpp b/plugins/GSdx/GSTextureFX.cpp index 16a86f247..f243c4167 100644 --- a/plugins/GSdx/GSTextureFX.cpp +++ b/plugins/GSdx/GSTextureFX.cpp @@ -21,3 +21,16 @@ #include "stdafx.h" #include "GSTextureFX.h" + +GSTextureFX::GSTextureFX() + : m_dev(NULL) +{ +} + +bool GSTextureFX::Create(GSDevice* dev) +{ + m_dev = dev; + + return true; +} + diff --git a/plugins/GSdx/GSTextureFX.h b/plugins/GSdx/GSTextureFX.h index ed338a59b..b3b3dcf69 100644 --- a/plugins/GSdx/GSTextureFX.h +++ b/plugins/GSdx/GSTextureFX.h @@ -22,8 +22,10 @@ #pragma once #include "GSVector.h" +#include "GSDevice.h" +#include "GSAlignedClass.h" -class GSTextureFX +class GSTextureFX : public GSAlignedClass<16> { public: #pragma pack(push, 1) @@ -87,9 +89,9 @@ public: { GSVector4 FogColor_AREF; GSVector4 HalfTexel; - GSVector4 WH_TA; + GSVector4 WH; GSVector4 MinMax; - GSVector4 MinMaxF; + GSVector4 MinF_TA; GSVector4i MskFix; struct PSConstantBuffer() @@ -240,4 +242,21 @@ public: }; #pragma pack(pop) + +protected: + GSDevice* m_dev; + +public: + GSTextureFX(); + + virtual bool Create(GSDevice* dev); + + virtual void SetupIA(const void* vertices, int count, int prim) = 0; + virtual void SetupVS(VSSelector sel, const VSConstantBuffer* cb) = 0; + virtual void SetupGS(GSSelector sel) = 0; + virtual void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) = 0; + virtual void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) = 0; + virtual void SetupRS(int w, int h, const GSVector4i& scissor) = 0; + virtual void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) = 0; + virtual void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) = 0; }; diff --git a/plugins/GSdx/GSTextureFX10.cpp b/plugins/GSdx/GSTextureFX10.cpp index 0a3497979..3750a5b9c 100644 --- a/plugins/GSdx/GSTextureFX10.cpp +++ b/plugins/GSdx/GSTextureFX10.cpp @@ -24,21 +24,17 @@ #include "resource.h" GSTextureFX10::GSTextureFX10() - : m_dev(NULL) { memset(&m_vs_cb_cache, 0, sizeof(m_vs_cb_cache)); memset(&m_ps_cb_cache, 0, sizeof(m_ps_cb_cache)); } -bool GSTextureFX10::Create(GSDevice10* dev) +bool GSTextureFX10::Create(GSDevice* dev) { - m_dev = dev; - - VSSelector sel; - - VSConstantBuffer cb; - - SetupVS(sel, &cb); // creates layout + if(!__super::Create(dev)) + { + return false; + } HRESULT hr; @@ -50,7 +46,7 @@ bool GSTextureFX10::Create(GSDevice10* dev) bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - hr = (*m_dev)->CreateBuffer(&bd, NULL, &m_vs_cb); + hr = (*(GSDevice10*)dev)->CreateBuffer(&bd, NULL, &m_vs_cb); if(FAILED(hr)) return false; @@ -60,7 +56,7 @@ bool GSTextureFX10::Create(GSDevice10* dev) bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - hr = (*m_dev)->CreateBuffer(&bd, NULL, &m_ps_cb); + hr = (*(GSDevice10*)dev)->CreateBuffer(&bd, NULL, &m_ps_cb); if(FAILED(hr)) return false; @@ -76,7 +72,7 @@ bool GSTextureFX10::Create(GSDevice10* dev) sd.MaxAnisotropy = 16; sd.ComparisonFunc = D3D10_COMPARISON_NEVER; - hr = (*m_dev)->CreateSamplerState(&sd, &m_palette_ss); + hr = (*(GSDevice10*)dev)->CreateSamplerState(&sd, &m_palette_ss); if(FAILED(hr)) return false; @@ -85,17 +81,19 @@ bool GSTextureFX10::Create(GSDevice10* dev) return true; } -bool GSTextureFX10::SetupIA(const GSVertexHW10* vertices, int count, D3D10_PRIMITIVE_TOPOLOGY prim) +void GSTextureFX10::SetupIA(const void* vertices, int count, int prim) { - m_dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), count); - m_dev->IASetInputLayout(m_il); - m_dev->IASetPrimitiveTopology(prim); + GSDevice10* dev = (GSDevice10*)m_dev; - return true; + dev->IASetVertexBuffer(vertices, sizeof(GSVertexHW10), count); + dev->IASetInputLayout(m_il); + dev->IASetPrimitiveTopology((D3D10_PRIMITIVE_TOPOLOGY)prim); } -bool GSTextureFX10::SetupVS(VSSelector sel, const VSConstantBuffer* cb) +void GSTextureFX10::SetupVS(VSSelector sel, const VSConstantBuffer* cb) { + GSDevice10* dev = (GSDevice10*)m_dev; + hash_map >::const_iterator i = m_vs.find(sel); if(i == m_vs.end()) @@ -129,7 +127,7 @@ bool GSTextureFX10::SetupVS(VSSelector sel, const VSConstantBuffer* cb) CComPtr il; CComPtr vs; - m_dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); + dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); if(m_il == NULL) { @@ -143,17 +141,15 @@ bool GSTextureFX10::SetupVS(VSSelector sel, const VSConstantBuffer* cb) if(m_vs_cb_cache.Update(cb)) { - (*m_dev)->UpdateSubresource(m_vs_cb, 0, NULL, cb, 0, 0); + (*dev)->UpdateSubresource(m_vs_cb, 0, NULL, cb, 0, 0); } - m_dev->VSSetShader((*i).second, m_vs_cb); - - return true; + dev->VSSetShader(i->second, m_vs_cb); } -bool GSTextureFX10::SetupGS(GSSelector sel) +void GSTextureFX10::SetupGS(GSSelector sel) { - HRESULT hr; + GSDevice10* dev = (GSDevice10*)m_dev; ID3D10GeometryShader* gs = NULL; @@ -163,7 +159,7 @@ bool GSTextureFX10::SetupGS(GSSelector sel) if(i != m_gs.end()) { - gs = (*i).second; + gs = i->second; } else { @@ -179,29 +175,25 @@ bool GSTextureFX10::SetupGS(GSSelector sel) {NULL, NULL}, }; - hr = m_dev->CompileShader(IDR_TFX_FX, "gs_main", macro, &gs); + dev->CompileShader(IDR_TFX_FX, "gs_main", macro, &gs); m_gs[sel] = gs; } } - m_dev->GSSetShader(gs); - - return true; + dev->GSSetShader(gs); } -bool GSTextureFX10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) +void GSTextureFX10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) { - m_dev->PSSetShaderResources(tex, pal); + ((GSDevice10*)m_dev)->PSSetShaderResources(tex, pal); UpdatePS(sel, cb, ssel); - - return true; } void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { - HRESULT hr; + GSDevice10* dev = (GSDevice10*)m_dev; hash_map >::const_iterator i = m_ps.find(sel); @@ -245,7 +237,7 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl CComPtr ps; - hr = m_dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); + dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); m_ps[sel] = ps; @@ -254,10 +246,10 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl if(m_ps_cb_cache.Update(cb)) { - (*m_dev)->UpdateSubresource(m_ps_cb, 0, NULL, cb, 0, 0); + (*dev)->UpdateSubresource(m_ps_cb, 0, NULL, cb, 0, 0); } - m_dev->PSSetShader((*i).second, m_ps_cb); + dev->PSSetShader(i->second, m_ps_cb); ID3D10SamplerState* ss0 = NULL; ID3D10SamplerState* ss1 = NULL; @@ -291,7 +283,7 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl sd.MaxAnisotropy = 16; sd.ComparisonFunc = D3D10_COMPARISON_NEVER; - hr = (*m_dev)->CreateSamplerState(&sd, &ss0); + (*dev)->CreateSamplerState(&sd, &ss0); m_ps_ss[ssel] = ss0; } @@ -302,24 +294,24 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl } } - m_dev->PSSetSamplerState(ss0, ss1); + dev->PSSetSamplerState(ss0, ss1); } void GSTextureFX10::SetupRS(int w, int h, const GSVector4i& scissor) { - m_dev->RSSet(w, h, &scissor); + ((GSDevice10*)m_dev)->RSSet(w, h, &scissor); } -void GSTextureFX10::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf, GSTexture* rt, GSTexture* ds) +void GSTextureFX10::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) { - UpdateOM(dssel, bsel, bf); + UpdateOM(dssel, bsel, afix); - m_dev->OMSetRenderTargets(rt, ds); + ((GSDevice10*)m_dev)->OMSetRenderTargets(rt, ds); } -void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf) +void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) { - HRESULT hr; + GSDevice10* dev = (GSDevice10*)m_dev; hash_map >::const_iterator i = m_om_dss.find(dssel); @@ -361,14 +353,14 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, CComPtr dss; - hr = (*m_dev)->CreateDepthStencilState(&dsd, &dss); + (*dev)->CreateDepthStencilState(&dsd, &dss); m_om_dss[dssel] = dss; i = m_om_dss.find(dssel); } - m_dev->OMSetDepthStencilState((*i).second, 1); + dev->OMSetDepthStencilState((*i).second, 1); hash_map >::const_iterator j = m_om_bs.find(bsel); @@ -502,12 +494,12 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, CComPtr bs; - hr = (*m_dev)->CreateBlendState(&bd, &bs); + (*dev)->CreateBlendState(&bd, &bs); m_om_bs[bsel] = bs; j = m_om_bs.find(bsel); } - m_dev->OMSetBlendState((*j).second, bf); + dev->OMSetBlendState(j->second, (float)(int)afix / 0x80); } diff --git a/plugins/GSdx/GSTextureFX10.h b/plugins/GSdx/GSTextureFX10.h index 9e3c18a5e..566809a36 100644 --- a/plugins/GSdx/GSTextureFX10.h +++ b/plugins/GSdx/GSTextureFX10.h @@ -26,7 +26,6 @@ class GSTextureFX10 : public GSTextureFX { - GSDevice10* m_dev; CComPtr m_il; hash_map > m_vs; CComPtr m_vs_cb; @@ -44,14 +43,14 @@ class GSTextureFX10 : public GSTextureFX public: GSTextureFX10(); - bool Create(GSDevice10* dev); + bool Create(GSDevice* dev); - bool SetupIA(const GSVertexHW10* vertices, int count, D3D10_PRIMITIVE_TOPOLOGY prim); - bool SetupVS(VSSelector sel, const VSConstantBuffer* cb); - bool SetupGS(GSSelector sel); - bool SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); + void SetupIA(const void* vertices, int count, int prim); + void SetupVS(VSSelector sel, const VSConstantBuffer* cb); + void SetupGS(GSSelector sel); + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); void SetupRS(int w, int h, const GSVector4i& scissor); - void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf, GSTexture* rt, GSTexture* ds); - void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); + void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); }; diff --git a/plugins/GSdx/GSTextureFX11.cpp b/plugins/GSdx/GSTextureFX11.cpp index d3c120588..24e2b25db 100644 --- a/plugins/GSdx/GSTextureFX11.cpp +++ b/plugins/GSdx/GSTextureFX11.cpp @@ -24,21 +24,17 @@ #include "resource.h" GSTextureFX11::GSTextureFX11() - : m_dev(NULL) { memset(&m_vs_cb_cache, 0, sizeof(m_vs_cb_cache)); memset(&m_ps_cb_cache, 0, sizeof(m_ps_cb_cache)); } -bool GSTextureFX11::Create(GSDevice11* dev) +bool GSTextureFX11::Create(GSDevice* dev) { - m_dev = dev; - - VSSelector sel; - - VSConstantBuffer cb; - - SetupVS(sel, &cb); // creates layout + if(!__super::Create(dev)) + { + return false; + } HRESULT hr; @@ -50,7 +46,7 @@ bool GSTextureFX11::Create(GSDevice11* dev) bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - hr = (*m_dev)->CreateBuffer(&bd, NULL, &m_vs_cb); + hr = (*(GSDevice11*)dev)->CreateBuffer(&bd, NULL, &m_vs_cb); if(FAILED(hr)) return false; @@ -60,7 +56,7 @@ bool GSTextureFX11::Create(GSDevice11* dev) bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - hr = (*m_dev)->CreateBuffer(&bd, NULL, &m_ps_cb); + hr = (*(GSDevice11*)dev)->CreateBuffer(&bd, NULL, &m_ps_cb); if(FAILED(hr)) return false; @@ -76,7 +72,7 @@ bool GSTextureFX11::Create(GSDevice11* dev) sd.MaxAnisotropy = 16; sd.ComparisonFunc = D3D11_COMPARISON_NEVER; - hr = (*m_dev)->CreateSamplerState(&sd, &m_palette_ss); + hr = (*(GSDevice11*)dev)->CreateSamplerState(&sd, &m_palette_ss); if(FAILED(hr)) return false; @@ -85,17 +81,19 @@ bool GSTextureFX11::Create(GSDevice11* dev) return true; } -bool GSTextureFX11::SetupIA(const GSVertexHW11* vertices, int count, D3D11_PRIMITIVE_TOPOLOGY prim) +void GSTextureFX11::SetupIA(const void* vertices, int count, int prim) { - m_dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), count); - m_dev->IASetInputLayout(m_il); - m_dev->IASetPrimitiveTopology(prim); + GSDevice11* dev = (GSDevice11*)m_dev; - return true; + dev->IASetVertexBuffer(vertices, sizeof(GSVertexHW11), count); + dev->IASetInputLayout(m_il); + dev->IASetPrimitiveTopology((D3D11_PRIMITIVE_TOPOLOGY)prim); } -bool GSTextureFX11::SetupVS(VSSelector sel, const VSConstantBuffer* cb) +void GSTextureFX11::SetupVS(VSSelector sel, const VSConstantBuffer* cb) { + GSDevice11* dev = (GSDevice11*)m_dev; + hash_map >::const_iterator i = m_vs.find(sel); if(i == m_vs.end()) @@ -129,7 +127,7 @@ bool GSTextureFX11::SetupVS(VSSelector sel, const VSConstantBuffer* cb) CComPtr il; CComPtr vs; - m_dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); + dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); if(m_il == NULL) { @@ -143,19 +141,17 @@ bool GSTextureFX11::SetupVS(VSSelector sel, const VSConstantBuffer* cb) if(m_vs_cb_cache.Update(cb)) { - ID3D11DeviceContext* ctx = *m_dev; + ID3D11DeviceContext* ctx = *dev; ctx->UpdateSubresource(m_vs_cb, 0, NULL, cb, 0, 0); } - m_dev->VSSetShader((*i).second, m_vs_cb); - - return true; + dev->VSSetShader(i->second, m_vs_cb); } -bool GSTextureFX11::SetupGS(GSSelector sel) +void GSTextureFX11::SetupGS(GSSelector sel) { - HRESULT hr; + GSDevice11* dev = (GSDevice11*)m_dev; ID3D11GeometryShader* gs = NULL; @@ -165,7 +161,7 @@ bool GSTextureFX11::SetupGS(GSSelector sel) if(i != m_gs.end()) { - gs = (*i).second; + gs = i->second; } else { @@ -181,29 +177,25 @@ bool GSTextureFX11::SetupGS(GSSelector sel) {NULL, NULL}, }; - hr = m_dev->CompileShader(IDR_TFX_FX, "gs_main", macro, &gs); + dev->CompileShader(IDR_TFX_FX, "gs_main", macro, &gs); m_gs[sel] = gs; } } - m_dev->GSSetShader(gs); - - return true; + dev->GSSetShader(gs); } -bool GSTextureFX11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) +void GSTextureFX11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) { - m_dev->PSSetShaderResources(tex, pal); + ((GSDevice11*)m_dev)->PSSetShaderResources(tex, pal); UpdatePS(sel, cb, ssel); - - return true; } void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { - HRESULT hr; + GSDevice11* dev = (GSDevice11*)m_dev; hash_map >::const_iterator i = m_ps.find(sel); @@ -247,7 +239,7 @@ void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl CComPtr ps; - hr = m_dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); + dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); m_ps[sel] = ps; @@ -256,12 +248,12 @@ void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl if(m_ps_cb_cache.Update(cb)) { - ID3D11DeviceContext* ctx = *m_dev; + ID3D11DeviceContext* ctx = *dev; ctx->UpdateSubresource(m_ps_cb, 0, NULL, cb, 0, 0); } - m_dev->PSSetShader((*i).second, m_ps_cb); + dev->PSSetShader(i->second, m_ps_cb); ID3D11SamplerState* ss0 = NULL; ID3D11SamplerState* ss1 = NULL; @@ -277,7 +269,7 @@ void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl if(i != m_ps_ss.end()) { - ss0 = (*i).second; + ss0 = i->second; } else { @@ -295,7 +287,7 @@ void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl sd.MaxAnisotropy = 16; sd.ComparisonFunc = D3D11_COMPARISON_NEVER; - hr = (*m_dev)->CreateSamplerState(&sd, &ss0); + (*dev)->CreateSamplerState(&sd, &ss0); m_ps_ss[ssel] = ss0; } @@ -306,24 +298,24 @@ void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl } } - m_dev->PSSetSamplerState(ss0, ss1); + dev->PSSetSamplerState(ss0, ss1); } void GSTextureFX11::SetupRS(int w, int h, const GSVector4i& scissor) { - m_dev->RSSet(w, h, &scissor); + ((GSDevice11*)m_dev)->RSSet(w, h, &scissor); } -void GSTextureFX11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf, GSTexture* rt, GSTexture* ds) +void GSTextureFX11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) { - UpdateOM(dssel, bsel, bf); + UpdateOM(dssel, bsel, afix); - m_dev->OMSetRenderTargets(rt, ds); + ((GSDevice11*)m_dev)->OMSetRenderTargets(rt, ds); } -void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf) +void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) { - HRESULT hr; + GSDevice11* dev = (GSDevice11*)m_dev; hash_map >::const_iterator i = m_om_dss.find(dssel); @@ -365,14 +357,14 @@ void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, CComPtr dss; - hr = (*m_dev)->CreateDepthStencilState(&dsd, &dss); + (*dev)->CreateDepthStencilState(&dsd, &dss); m_om_dss[dssel] = dss; i = m_om_dss.find(dssel); } - m_dev->OMSetDepthStencilState((*i).second, 1); + dev->OMSetDepthStencilState(i->second, 1); hash_map >::const_iterator j = m_om_bs.find(bsel); @@ -506,12 +498,12 @@ void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, CComPtr bs; - hr = (*m_dev)->CreateBlendState(&bd, &bs); + (*dev)->CreateBlendState(&bd, &bs); m_om_bs[bsel] = bs; j = m_om_bs.find(bsel); } - m_dev->OMSetBlendState((*j).second, bf); + dev->OMSetBlendState(j->second, (float)(int)afix / 0x80); } diff --git a/plugins/GSdx/GSTextureFX11.h b/plugins/GSdx/GSTextureFX11.h index 53a4f2f33..5c2b67bcc 100644 --- a/plugins/GSdx/GSTextureFX11.h +++ b/plugins/GSdx/GSTextureFX11.h @@ -26,7 +26,6 @@ class GSTextureFX11 : public GSTextureFX { - GSDevice11* m_dev; CComPtr m_il; hash_map > m_vs; CComPtr m_vs_cb; @@ -44,14 +43,14 @@ class GSTextureFX11 : public GSTextureFX public: GSTextureFX11(); - bool Create(GSDevice11* dev); + bool Create(GSDevice* dev); - bool SetupIA(const GSVertexHW11* vertices, int count, D3D11_PRIMITIVE_TOPOLOGY prim); - bool SetupVS(VSSelector sel, const VSConstantBuffer* cb); - bool SetupGS(GSSelector sel); - bool SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); + void SetupIA(const void* vertices, int count, int prim); + void SetupVS(VSSelector sel, const VSConstantBuffer* cb); + void SetupGS(GSSelector sel); + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); void SetupRS(int w, int h, const GSVector4i& scissor); - void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf, GSTexture* rt, GSTexture* ds); - void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float bf); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); + void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); }; diff --git a/plugins/GSdx/GSTextureFX9.cpp b/plugins/GSdx/GSTextureFX9.cpp index 5327f2d93..891085c94 100644 --- a/plugins/GSdx/GSTextureFX9.cpp +++ b/plugins/GSdx/GSTextureFX9.cpp @@ -24,19 +24,24 @@ #include "resource.h" GSTextureFX9::GSTextureFX9() - : m_dev(NULL) { } -bool GSTextureFX9::Create(GSDevice9* dev) +bool GSTextureFX9::Create(GSDevice* dev) { - m_dev = dev; + if(!__super::Create(dev)) + { + return false; + } + + // create layout VSSelector sel; - VSConstantBuffer cb; - SetupVS(sel, &cb); // creates layout + SetupVS(sel, &cb); + + // return true; } @@ -51,7 +56,7 @@ GSTexture* GSTextureFX9::CreateMskFix(uint32 size, uint32 msk, uint32 fix) if(i != m_mskfix.end()) { - t = (*i).second; + t = i->second; } else { @@ -78,17 +83,19 @@ GSTexture* GSTextureFX9::CreateMskFix(uint32 size, uint32 msk, uint32 fix) return t; } -bool GSTextureFX9::SetupIA(const GSVertexHW9* vertices, int count, D3DPRIMITIVETYPE prim) +void GSTextureFX9::SetupIA(const void* vertices, int count, int prim) { - m_dev->IASetVertexBuffer(vertices, sizeof(vertices[0]), count); - m_dev->IASetInputLayout(m_il); - m_dev->IASetPrimitiveTopology(prim); + GSDevice9* dev = (GSDevice9*)m_dev; - return true; + dev->IASetVertexBuffer(vertices, sizeof(GSVertexHW9), count); + dev->IASetInputLayout(m_il); + dev->IASetPrimitiveTopology((D3DPRIMITIVETYPE)prim); } -bool GSTextureFX9::SetupVS(VSSelector sel, const VSConstantBuffer* cb) +void GSTextureFX9::SetupVS(VSSelector sel, const VSConstantBuffer* cb) { + GSDevice9* dev = (GSDevice9*)m_dev; + hash_map >::const_iterator i = m_vs.find(sel); if(i == m_vs.end()) @@ -121,7 +128,7 @@ bool GSTextureFX9::SetupVS(VSSelector sel, const VSConstantBuffer* cb) CComPtr il; CComPtr vs; - m_dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); + dev->CompileShader(IDR_TFX_FX, "vs_main", macro, &vs, layout, countof(layout), &il); if(m_il == NULL) { @@ -133,14 +140,14 @@ bool GSTextureFX9::SetupVS(VSSelector sel, const VSConstantBuffer* cb) i = m_vs.find(sel); } - m_dev->VSSetShader((*i).second, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); - - return true; + dev->VSSetShader(i->second, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); } -bool GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) +void GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) { - m_dev->PSSetShaderResources(tex, pal); + GSDevice9* dev = (GSDevice9*)m_dev; + + dev->PSSetShaderResources(tex, pal); if(tex && (sel.wms == 3 || sel.wmt == 3)) { @@ -148,7 +155,7 @@ bool GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSampler { if(GSTexture* t = CreateMskFix(tex->GetWidth(), cb->MskFix.x, cb->MskFix.z)) { - (*m_dev)->SetTexture(2, *(GSTexture9*)t); + (*dev)->SetTexture(2, *(GSTexture9*)t); } } @@ -156,19 +163,17 @@ bool GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSampler { if(GSTexture* t = CreateMskFix(tex->GetHeight(), cb->MskFix.y, cb->MskFix.w)) { - (*m_dev)->SetTexture(3, *(GSTexture9*)t); + (*dev)->SetTexture(3, *(GSTexture9*)t); } } } UpdatePS(sel, cb, ssel); - - return true; } void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { - HRESULT hr; + GSDevice9* dev = (GSDevice9*)m_dev; hash_map >::const_iterator i = m_ps.find(sel); @@ -210,14 +215,14 @@ void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSample CComPtr ps; - hr = m_dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); + dev->CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); m_ps[sel] = ps; i = m_ps.find(sel); } - m_dev->PSSetShader((*i).second, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); + dev->PSSetShader(i->second, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); Direct3DSamplerState9* ss = NULL; @@ -232,7 +237,7 @@ void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSample if(i != m_ps_ss.end()) { - ss = (*i).second; + ss = i->second; } else { @@ -252,23 +257,25 @@ void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSample } } - m_dev->PSSetSamplerState(ss); + dev->PSSetSamplerState(ss); } void GSTextureFX9::SetupRS(int w, int h, const GSVector4i& scissor) { - m_dev->RSSet(w, h, &scissor); + ((GSDevice9*)m_dev)->RSSet(w, h, &scissor); } -void GSTextureFX9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 bf, GSTexture* rt, GSTexture* ds) +void GSTextureFX9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) { - UpdateOM(dssel, bsel, bf); + UpdateOM(dssel, bsel, afix); - m_dev->OMSetRenderTargets(rt, ds); + ((GSDevice9*)m_dev)->OMSetRenderTargets(rt, ds); } -void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 bf) +void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) { + GSDevice9* dev = (GSDevice9*)m_dev; + Direct3DDepthStencilState9* dss = NULL; hash_map::const_iterator i = m_om_dss.find(dssel); @@ -311,7 +318,7 @@ void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, i = m_om_dss.find(dssel); } - m_dev->OMSetDepthStencilState((*i).second); + dev->OMSetDepthStencilState(i->second); hash_map::const_iterator j = m_om_bs.find(bsel); @@ -448,5 +455,5 @@ void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, j = m_om_bs.find(bsel); } - m_dev->OMSetBlendState((*j).second, 0x010101 * bf); + dev->OMSetBlendState(j->second, afix >= 0x80 ? 0xffffff : 0x020202 * afix); } diff --git a/plugins/GSdx/GSTextureFX9.h b/plugins/GSdx/GSTextureFX9.h index 50f187a3b..317037f69 100644 --- a/plugins/GSdx/GSTextureFX9.h +++ b/plugins/GSdx/GSTextureFX9.h @@ -26,7 +26,6 @@ class GSTextureFX9 : public GSTextureFX { - GSDevice9* m_dev; CComPtr m_il; hash_map > m_vs; D3DXHANDLE m_vs_params; @@ -41,13 +40,14 @@ class GSTextureFX9 : public GSTextureFX public: GSTextureFX9(); - bool Create(GSDevice9* dev); + bool Create(GSDevice* dev); - bool SetupIA(const GSVertexHW9* vertices, int count, D3DPRIMITIVETYPE prim); - bool SetupVS(VSSelector sel, const VSConstantBuffer* cb); - bool SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); + void SetupIA(const void* vertices, int count, int prim); + void SetupVS(VSSelector sel, const VSConstantBuffer* cb); + void SetupGS(GSSelector sel) {} + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); void SetupRS(int w, int h, const GSVector4i& scissor); - void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 bf, GSTexture* rt, GSTexture* ds); - void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 bf); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); + void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); }; diff --git a/plugins/GSdx/GSVector.cpp b/plugins/GSdx/GSVector.cpp index a1741d5e0..d7f6e7ec7 100644 --- a/plugins/GSdx/GSVector.cpp +++ b/plugins/GSdx/GSVector.cpp @@ -27,16 +27,16 @@ const GSVector4 GSVector4::m_ps4567(4.0f, 5.0f, 6.0f, 7.0f); const GSVector4 GSVector4::m_x3f800000(_mm_castsi128_ps(_mm_set1_epi32(0x3f800000))); const GSVector4 GSVector4::m_x4b000000(_mm_castsi128_ps(_mm_set1_epi32(0x4b000000))); -void GSVector4::operator = (const GSVector4i& v) -{ - m = _mm_cvtepi32_ps(v); -} - -void GSVector4i::operator = (const GSVector4& v) +GSVector4i::GSVector4i(const GSVector4& v) { m = _mm_cvttps_epi32(v); } +GSVector4::GSVector4(const GSVector4i& v) +{ + m = _mm_cvtepi32_ps(v); +} + GSVector4i GSVector4i::cast(const GSVector4& v) { return GSVector4i(_mm_castps_si128(v.m)); diff --git a/plugins/GSdx/GSVector.h b/plugins/GSdx/GSVector.h index cfd2bc020..2b6455e27 100644 --- a/plugins/GSdx/GSVector.h +++ b/plugins/GSdx/GSVector.h @@ -121,18 +121,13 @@ public: this->m = m; } - explicit GSVector4i(const GSVector4& v) - { - *this = v; - } + explicit GSVector4i(const GSVector4& v); void operator = (const GSVector4i& v) { m = v.m; } - void operator = (const GSVector4& v); - void operator = (int i) { m = _mm_set1_epi32(i); @@ -1822,6 +1817,11 @@ public: GSVector4i* s = (GSVector4i*)src; GSVector4i* d = (GSVector4i*)dst; + if(!d[0].eq(s[0])) + { + return false; + } + GSVector4i v = GSVector4i::xffffffff(); for(int i = 0; i < size; i++) @@ -2312,18 +2312,13 @@ public: *this = GSVector4(GSVector4i::load((int)u32).u8to32()); } - explicit GSVector4(const GSVector4i& v) - { - *this = v; - } + explicit GSVector4(const GSVector4i& v); void operator = (const GSVector4& v) { m = v.m; } - void operator = (const GSVector4i& v); - void operator = (float f) { m = _mm_set1_ps(f); @@ -2625,10 +2620,10 @@ public: { GSVector4i mask = GSVector4i::x000000ff(); - a = v & mask; - b = (v >> 8) & mask; - c = (v >> 16) & mask; - d = (v >> 24); + a = GSVector4(v & mask); + b = GSVector4((v >> 8) & mask); + c = GSVector4((v >> 16) & mask); + d = GSVector4((v >> 24)); } __forceinline static void transpose(GSVector4& a, GSVector4& b, GSVector4& c, GSVector4& d) diff --git a/plugins/GSdx/GSVertexHW.h b/plugins/GSdx/GSVertexHW.h index 9948a76b1..6314d31f3 100644 --- a/plugins/GSdx/GSVertexHW.h +++ b/plugins/GSdx/GSVertexHW.h @@ -30,9 +30,21 @@ __declspec(align(16)) union GSVertexHW9 { struct { - GSVector2 t; - union {struct {uint8 r, g, b, a;}; uint32 c0;}; - union {struct {uint8 ta0, ta1, res, f;}; uint32 c1;}; + union + { + struct + { + GSVector4 t; + }; + + struct + { + uint32 _pad[2]; + union {struct {uint8 r, g, b, a;}; uint32 c0;}; + union {struct {uint8 ta0, ta1, res, f;}; uint32 c1;}; + }; + }; + GSVector4 p; }; diff --git a/plugins/GSdx/GSdx_vs2008.vcproj b/plugins/GSdx/GSdx_vs2008.vcproj index 7addc2fb0..8de80b528 100644 --- a/plugins/GSdx/GSdx_vs2008.vcproj +++ b/plugins/GSdx/GSdx_vs2008.vcproj @@ -1276,54 +1276,58 @@ RelativePath=".\GSRenderer.cpp" > + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - @@ -1790,22 +1794,26 @@ RelativePath=".\GSRenderer.h" > + + + + + + + + - - - - - - diff --git a/plugins/GSdx/GSdx_vs2010.vcxproj b/plugins/GSdx/GSdx_vs2010.vcxproj index 6048be5f4..a92685924 100644 --- a/plugins/GSdx/GSdx_vs2010.vcxproj +++ b/plugins/GSdx/GSdx_vs2010.vcxproj @@ -1320,9 +1320,9 @@ - - - + + + @@ -1445,9 +1445,9 @@ - - - + + + diff --git a/plugins/GSdx/GSdx_vs2010.vcxproj.filters b/plugins/GSdx/GSdx_vs2010.vcxproj.filters index a9652e38e..4ca7e0481 100644 --- a/plugins/GSdx/GSdx_vs2010.vcxproj.filters +++ b/plugins/GSdx/GSdx_vs2010.vcxproj.filters @@ -201,13 +201,13 @@ Source Files - + Source Files - + Source Files - + Source Files @@ -521,13 +521,13 @@ Header Files - + Header Files - + Header Files - + Header Files diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx index 84ebbe190..2bb2b3b96 100644 --- a/plugins/GSdx/res/tfx.fx +++ b/plugins/GSdx/res/tfx.fx @@ -76,10 +76,10 @@ cbuffer cb1 float3 FogColor; float AREF; float4 HalfTexel; - float2 WH; - float2 TA; + float4 WH; float4 MinMax; - float4 MinMaxF; + float2 MinF; + float2 TA; uint4 MskFix; }; @@ -145,11 +145,11 @@ float4 ps_params[5]; #define FogColor ps_params[0].bgr #define AREF ps_params[0].a #define HalfTexel ps_params[1] -#define WH ps_params[2].xy -#define TA0 ps_params[2].z -#define TA1 ps_params[2].w +#define WH ps_params[2] #define MinMax ps_params[3] -#define MinMaxF ps_params[4] +#define MinF ps_params[4].xy +#define TA0 ps_params[4].z +#define TA1 ps_params[4].w #endif @@ -198,7 +198,7 @@ float4 wrapuv(float4 uv) else if(PS_WMS == 3) { #if SHADER_MODEL >= 0x400 - uv.xz = (float2)(((int2)(uv * WH.xyxy).xz & MskFix.xx) | MskFix.zz) / WH; + uv.xz = (float2)(((int2)(uv * WH.xyxy).xz & MskFix.xx) | MskFix.zz) / WH.xy; #elif SHADER_MODEL <= 0x300 uv.x = tex1D(UMSKFIX, uv.x); uv.z = tex1D(UMSKFIX, uv.z); @@ -220,7 +220,7 @@ float4 wrapuv(float4 uv) else if(PS_WMT == 3) { #if SHADER_MODEL >= 0x400 - uv.yw = (float2)(((int2)(uv * WH.xyxy).yw & MskFix.yy) | MskFix.ww) / WH; + uv.yw = (float2)(((int2)(uv * WH.xyxy).yw & MskFix.yy) | MskFix.ww) / WH.xy; #elif SHADER_MODEL <= 0x300 uv.y = tex1D(VMSKFIX, uv.y); uv.w = tex1D(VMSKFIX, uv.w); @@ -235,15 +235,15 @@ float2 clampuv(float2 uv) { if(PS_WMS == 2 && PS_WMT == 2) { - uv = clamp(uv, MinMaxF.xy, MinMaxF.zw); + uv = clamp(uv, MinF, MinMax.zw); } else if(PS_WMS == 2) { - uv.x = clamp(uv.x, MinMaxF.x, MinMaxF.z); + uv.x = clamp(uv.x, MinF.x, MinMax.z); } else if(PS_WMT == 2) { - uv.y = clamp(uv.y, MinMaxF.y, MinMaxF.w); + uv.y = clamp(uv.y, MinF.y, MinMax.w); } return uv; @@ -476,7 +476,7 @@ float4 sample(float2 tc, float w) Texture.GetDimensions(w, h); float4 uv2 = tc.xyxy + HalfTexel; - float2 dd = frac(uv2.xy * float2(w, h)); + float2 dd = frac(uv2.xy * float2(w, h)); // * WH.zw float4 uv = wrapuv(uv2); float4 t00, t01, t10, t11; @@ -637,7 +637,7 @@ float4 sample(float2 tc, float w) else { float4 uv2 = tc.xyxy + HalfTexel; - float2 dd = frac(uv2.xy * WH); + float2 dd = frac(uv2.xy * WH.zw); float4 uv = wrapuv(uv2); float4 t00, t01, t10, t11;