mirror of https://github.com/PCSX2/pcsx2.git
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
This commit is contained in:
parent
6e5d4a5d15
commit
7bb9a3cc25
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
Lamune,
|
||||
KyuuketsuKitanMoonties,
|
||||
PiaCarroteYoukosoGPGakuenPrincess,
|
||||
KazokuKeikakuKokoroNoKizuna,
|
||||
FFX,
|
||||
FFX2,
|
||||
FFXII,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
{
|
||||
for(hash_map<KEY, ActivePtr*>::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<KEY, ActivePtr*>::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<KEY, ActivePtr*>::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<uint64, CG*>::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
|
||||
{
|
||||
|
|
|
@ -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<uint32, Offset*>::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<uint32, Offset4*>::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<true>(BlockPtr32(x, y, bp, bw), dst, dstpitch);
|
||||
ReadBlock32<true>(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<true>(BlockPtr32(x, y, bp, bw), dst, dstpitch, TEXA);
|
||||
ReadAndExpandBlock24<true>(src, dst, dstpitch, TEXA);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
else
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32)
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT24)
|
||||
{
|
||||
ReadAndExpandBlock24<false>(BlockPtr32(x, y, bp, bw), dst, dstpitch, TEXA);
|
||||
ReadAndExpandBlock24<false>(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<true>(BlockPtr16(x, y, bp, bw), (uint8*)block, sizeof(block) / 8);
|
||||
ReadBlock16<true>(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<true>(BlockPtr16S(x, y, bp, bw), (uint8*)block, sizeof(block) / 8);
|
||||
ReadBlock16<true>(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<true>(BlockPtr32Z(x, y, bp, bw), dst, dstpitch);
|
||||
ReadBlock32<true>(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<true>(BlockPtr32Z(x, y, bp, bw), dst, dstpitch, TEXA);
|
||||
ReadAndExpandBlock24<true>(src, dst, dstpitch, TEXA);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
else
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32)
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ24)
|
||||
{
|
||||
ReadAndExpandBlock24<false>(BlockPtr32Z(x, y, bp, bw), dst, dstpitch, TEXA);
|
||||
ReadAndExpandBlock24<false>(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<true>(BlockPtr16Z(x, y, bp, bw), (uint8*)block, sizeof(block) / 8);
|
||||
ReadBlock16<true>(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<true>(BlockPtr16SZ(x, y, bp, bw), (uint8*)block, sizeof(block) / 8);
|
||||
ReadBlock16<true>(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<true>(BlockPtr16(x, y, bp, bw), dst, dstpitch);
|
||||
ReadBlock16<true>(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<true>(BlockPtr16S(x, y, bp, bw), dst, dstpitch);
|
||||
ReadBlock16<true>(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<true>(BlockPtr8(x, y, bp, bw), (uint8*)block, sizeof(block) / 16);
|
||||
ReadBlock8<true>(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<true>(BlockPtr4(x, y, bp, bw), (uint8*)block, sizeof(block) / 16);
|
||||
ReadBlock4<true>(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<true>(BlockPtr32(x, y, bp, bw), (uint8*)block, sizeof(block) / 8);
|
||||
ReadBlock32<true>(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<true>(BlockPtr32(x, y, bp, bw), (uint8*)block, sizeof(block) / 8);
|
||||
ReadBlock32<true>(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<true>(BlockPtr32(x, y, bp, bw), (uint8*)block, sizeof(block) / 8);
|
||||
ReadBlock32<true>(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<true>(BlockPtr16Z(x, y, bp, bw), dst, dstpitch);
|
||||
ReadBlock16<true>(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<true>(BlockPtr16SZ(x, y, bp, bw), dst, dstpitch);
|
||||
ReadBlock16<true>(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<true>(BlockPtr8(x, y, bp, bw), dst, dstpitch);
|
||||
ReadBlock8<true>(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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
|
@ -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 Vertex>
|
||||
class GSRendererDX : public GSRendererHW<Vertex>
|
||||
{
|
||||
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<Vertex>(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);
|
||||
}
|
||||
};
|
|
@ -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<GSVertexHW10>(base, mt, irq, new GSDevice10(), new GSTextureCache10(this), new GSTextureFX10())
|
||||
{
|
||||
InitVertexKick<GSRendererDX10>();
|
||||
|
||||
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<uint32 prim, uint32 tme, uint32 fst>
|
||||
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<prim>(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);
|
||||
}
|
||||
}
|
|
@ -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<GSVertexHW10>
|
||||
class GSRendererDX10 : public GSRendererDX<GSVertexHW10>
|
||||
{
|
||||
protected:
|
||||
GSTextureFX10 m_tfx;
|
||||
|
||||
void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::GSCachedTexture* tex);
|
||||
|
||||
struct
|
||||
{
|
||||
CComPtr<ID3D10DepthStencilState> dss;
|
||||
CComPtr<ID3D10BlendState> 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);
|
||||
|
|
@ -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<GSVertexHW11>(base, mt, irq, new GSDevice11(), new GSTextureCache11(this), new GSTextureFX11())
|
||||
{
|
||||
InitVertexKick<GSRendererDX11>();
|
||||
|
||||
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<uint32 prim, uint32 tme, uint32 fst>
|
||||
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<prim>(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);
|
||||
}
|
||||
}
|
|
@ -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<GSVertexHW11>
|
||||
class GSRendererDX11 : public GSRendererDX<GSVertexHW11>
|
||||
{
|
||||
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);
|
||||
|
|
@ -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<GSVertexHW9>(base, mt, irq, new GSDevice9(), new GSTextureCache9(this), new GSTextureFX9())
|
||||
{
|
||||
InitVertexKick<GSRendererDX9>();
|
||||
}
|
||||
|
||||
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<uint32 prim, uint32 tme, uint32 fst>
|
||||
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<prim>(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();
|
||||
}
|
|
@ -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<GSVertexHW9>
|
||||
class GSRendererDX9 : public GSRendererDX<GSVertexHW9>
|
||||
{
|
||||
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);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<GSVertexHW10>(base, mt, irq, new GSDevice10(), new GSTextureCache10(this))
|
||||
{
|
||||
InitVertexKick<GSRendererHW10>();
|
||||
}
|
||||
|
||||
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<uint32 prim, uint32 tme, uint32 fst>
|
||||
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<prim>(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);
|
||||
}
|
||||
}
|
|
@ -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<GSVertexHW11>(base, mt, irq, new GSDevice11(), new GSTextureCache11(this))
|
||||
{
|
||||
InitVertexKick<GSRendererHW11>();
|
||||
}
|
||||
|
||||
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<uint32 prim, uint32 tme, uint32 fst>
|
||||
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<prim>(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);
|
||||
}
|
||||
}
|
|
@ -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<GSVertexHW9>(base, mt, irq, new GSDevice9(), new GSTextureCache9(this))
|
||||
{
|
||||
m_fba.enabled = !!theApp.GetConfig("fba", 1);
|
||||
m_logz = !!theApp.GetConfig("logz", 0);
|
||||
|
||||
InitVertexKick<GSRendererHW9>();
|
||||
}
|
||||
|
||||
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<uint32 prim, uint32 tme, uint32 fst>
|
||||
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<prim>(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();
|
||||
}
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
class GSRendererOGL : public GSRendererHW<GSVertexOGL>
|
||||
{
|
||||
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)());
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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<int> 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<GSRenderTarget*> m_rt;
|
||||
list<GSDepthStencil*> m_ds;
|
||||
list<GSCachedTexture*> m_tex;
|
||||
|
||||
bool m_tex_used;
|
||||
|
||||
template<class T> void RecycleByAge(list<T*>& l, int maxage = 60)
|
||||
struct SourceMap
|
||||
{
|
||||
for(list<T*>::iterator i = l.begin(); i != l.end(); )
|
||||
{
|
||||
list<T*>::iterator j = i++;
|
||||
hash_map<Source*, bool> m_surfaces;
|
||||
hash_map<Source*, bool> 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<Target*> 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();
|
||||
|
|
|
@ -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;
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<GSTexture*, bool>& map = m_map[TEX0.TBP0 >> 5];
|
||||
|
||||
GSTexture* t = NULL;
|
||||
|
||||
const hash_map<GSTexture*, bool>& map = m_map[TEX0.TBP0 >> 5];
|
||||
|
||||
for(hash_map<GSTexture*, bool>::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<GSTexture*, bool>& map = m_map[page];
|
||||
|
||||
const hash_map<GSTexture*, bool>& map = m_map[page];
|
||||
for(hash_map<GSTexture*, bool>::const_iterator i = map.begin(); i != map.end(); i++)
|
||||
{
|
||||
GSTexture* t = i->first;
|
||||
|
||||
for(hash_map<GSTexture*, bool>::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;
|
||||
|
|
|
@ -23,9 +23,6 @@
|
|||
|
||||
#include "GSRenderer.h"
|
||||
|
||||
#define MAX_PAGES 512
|
||||
#define MAX_BLOCKS 16384
|
||||
|
||||
class GSTextureCacheSW
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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<uint32, CComPtr<ID3D10VertexShader> >::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<ID3D10InputLayout> il;
|
||||
CComPtr<ID3D10VertexShader> 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<uint32, CComPtr<ID3D10PixelShader> >::const_iterator i = m_ps.find(sel);
|
||||
|
||||
|
@ -245,7 +237,7 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl
|
|||
|
||||
CComPtr<ID3D10PixelShader> 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<uint32, CComPtr<ID3D10DepthStencilState> >::const_iterator i = m_om_dss.find(dssel);
|
||||
|
||||
|
@ -361,14 +353,14 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel,
|
|||
|
||||
CComPtr<ID3D10DepthStencilState> 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<uint32, CComPtr<ID3D10BlendState> >::const_iterator j = m_om_bs.find(bsel);
|
||||
|
||||
|
@ -502,12 +494,12 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel,
|
|||
|
||||
CComPtr<ID3D10BlendState> 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);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
class GSTextureFX10 : public GSTextureFX
|
||||
{
|
||||
GSDevice10* m_dev;
|
||||
CComPtr<ID3D10InputLayout> m_il;
|
||||
hash_map<uint32, CComPtr<ID3D10VertexShader> > m_vs;
|
||||
CComPtr<ID3D10Buffer> 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);
|
||||
};
|
||||
|
|
|
@ -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<uint32, CComPtr<ID3D11VertexShader> >::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<ID3D11InputLayout> il;
|
||||
CComPtr<ID3D11VertexShader> 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<uint32, CComPtr<ID3D11PixelShader> >::const_iterator i = m_ps.find(sel);
|
||||
|
||||
|
@ -247,7 +239,7 @@ void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl
|
|||
|
||||
CComPtr<ID3D11PixelShader> 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<uint32, CComPtr<ID3D11DepthStencilState> >::const_iterator i = m_om_dss.find(dssel);
|
||||
|
||||
|
@ -365,14 +357,14 @@ void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel,
|
|||
|
||||
CComPtr<ID3D11DepthStencilState> 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<uint32, CComPtr<ID3D11BlendState> >::const_iterator j = m_om_bs.find(bsel);
|
||||
|
||||
|
@ -506,12 +498,12 @@ void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel,
|
|||
|
||||
CComPtr<ID3D11BlendState> 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);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
class GSTextureFX11 : public GSTextureFX
|
||||
{
|
||||
GSDevice11* m_dev;
|
||||
CComPtr<ID3D11InputLayout> m_il;
|
||||
hash_map<uint32, CComPtr<ID3D11VertexShader> > m_vs;
|
||||
CComPtr<ID3D11Buffer> 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);
|
||||
};
|
||||
|
|
|
@ -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<uint32, CComPtr<IDirect3DVertexShader9> >::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<IDirect3DVertexDeclaration9> il;
|
||||
CComPtr<IDirect3DVertexShader9> 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<uint32, CComPtr<IDirect3DPixelShader9> >::const_iterator i = m_ps.find(sel);
|
||||
|
||||
|
@ -210,14 +215,14 @@ void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSample
|
|||
|
||||
CComPtr<IDirect3DPixelShader9> 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<uint32, Direct3DDepthStencilState9*>::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<uint32, Direct3DBlendState9*>::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);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
class GSTextureFX9 : public GSTextureFX
|
||||
{
|
||||
GSDevice9* m_dev;
|
||||
CComPtr<IDirect3DVertexDeclaration9> m_il;
|
||||
hash_map<uint32, CComPtr<IDirect3DVertexShader9> > 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);
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -1276,54 +1276,58 @@
|
|||
RelativePath=".\GSRenderer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererDX.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererDX10.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release SSE2|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release SSSE3|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererDX11.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererDX9.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release SSE2|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release SSSE3|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererHW.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererHW10.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release SSE2|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release SSSE3|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererHW11.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererHW9.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release SSE2|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release SSSE3|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererNull.cpp"
|
||||
>
|
||||
|
@ -1790,22 +1794,26 @@
|
|||
RelativePath=".\GSRenderer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererDX.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererDX10.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererDX11.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererDX9.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererHW.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererHW10.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererHW11.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererHW9.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GSRendererNull.h"
|
||||
>
|
||||
|
|
|
@ -1320,9 +1320,9 @@
|
|||
<ClCompile Include="GSRasterizer.cpp" />
|
||||
<ClCompile Include="GSRenderer.cpp" />
|
||||
<ClCompile Include="GSRendererHW.cpp" />
|
||||
<ClCompile Include="GSRendererHW10.cpp" />
|
||||
<ClCompile Include="GSRendererHW11.cpp" />
|
||||
<ClCompile Include="GSRendererHW9.cpp" />
|
||||
<ClCompile Include="GSRendererDX10.cpp" />
|
||||
<ClCompile Include="GSRendererDX11.cpp" />
|
||||
<ClCompile Include="GSRendererDX9.cpp" />
|
||||
<ClCompile Include="GSRendererNull.cpp" />
|
||||
<ClCompile Include="GSRendererOGL.cpp" />
|
||||
<ClCompile Include="GSRendererSW.cpp" />
|
||||
|
@ -1445,9 +1445,9 @@
|
|||
<ClInclude Include="GSRasterizer.h" />
|
||||
<ClInclude Include="GSRenderer.h" />
|
||||
<ClInclude Include="GSRendererHW.h" />
|
||||
<ClInclude Include="GSRendererHW10.h" />
|
||||
<ClInclude Include="GSRendererHW11.h" />
|
||||
<ClInclude Include="GSRendererHW9.h" />
|
||||
<ClInclude Include="GSRendererDX10.h" />
|
||||
<ClInclude Include="GSRendererDX11.h" />
|
||||
<ClInclude Include="GSRendererDX9.h" />
|
||||
<ClInclude Include="GSRendererNull.h" />
|
||||
<ClInclude Include="GSRendererOGL.h" />
|
||||
<ClInclude Include="GSRendererSW.h" />
|
||||
|
|
|
@ -201,13 +201,13 @@
|
|||
<ClCompile Include="GSRendererHW.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GSRendererHW10.cpp">
|
||||
<ClCompile Include="GSRendererDX10.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GSRendererHW11.cpp">
|
||||
<ClCompile Include="GSRendererDX11.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GSRendererHW9.cpp">
|
||||
<ClCompile Include="GSRendererDX9.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GSRendererNull.cpp">
|
||||
|
@ -521,13 +521,13 @@
|
|||
<ClInclude Include="GSRendererHW.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GSRendererHW10.h">
|
||||
<ClInclude Include="GSRendererDX10.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GSRendererHW11.h">
|
||||
<ClInclude Include="GSRendererDX11.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GSRendererHW9.h">
|
||||
<ClInclude Include="GSRendererDX9.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GSRendererNull.h">
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue