mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
GSdx: added a shortcut in GSState::Transfer for the most frequent vertex format I found (helps quite a lot), less thread-syncing for the sw renderer, and the bios boot logo was fixed (just had to clear the memory on reset).
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5072 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
@@ -28,8 +28,8 @@ const GSVector4i GPULocalMemory::m_xxbx(0x00007c00);
|
||||
const GSVector4i GPULocalMemory::m_xgxx(0x000003e0);
|
||||
const GSVector4i GPULocalMemory::m_rxxx(0x0000001f);
|
||||
|
||||
#define VM_SIZE ((1 << (12 + 11)) * sizeof(uint16))
|
||||
#define VM_ALLOC_SIZE (VM_SIZE * 2)
|
||||
#define VM_REAL_SIZE ((1 << (12 + 11)) * sizeof(uint16))
|
||||
#define VM_ALLOC_SIZE (VM_REAL_SIZE * 2)
|
||||
#define TEX_ALLOC_SIZE (256 * 256 * (1 + 1 + 4) * 32)
|
||||
|
||||
GPULocalMemory::GPULocalMemory()
|
||||
@@ -39,7 +39,7 @@ GPULocalMemory::GPULocalMemory()
|
||||
|
||||
//
|
||||
|
||||
int size = VM_SIZE;
|
||||
int size = VM_REAL_SIZE;
|
||||
|
||||
m_vm = (uint16*)vmalloc(VM_ALLOC_SIZE, false);
|
||||
|
||||
|
||||
+1
-1
@@ -207,7 +207,7 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
|
||||
s_gs = NULL;
|
||||
}
|
||||
|
||||
if(renderer == 12)
|
||||
if(renderer == 15)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
|
||||
|
||||
+11
-2
@@ -90,6 +90,11 @@ enum GIF_REG
|
||||
GIF_REG_NOP = 0x0f,
|
||||
};
|
||||
|
||||
enum GIF_REG_COMPLEX
|
||||
{
|
||||
GIF_REG_STQRGBAXYZF2 = 0x00,
|
||||
};
|
||||
|
||||
enum GIF_A_D_REG
|
||||
{
|
||||
GIF_A_D_REG_PRIM = 0x00,
|
||||
@@ -1093,9 +1098,11 @@ __aligned(struct, 32) GIFPath
|
||||
uint32 reg;
|
||||
uint32 nreg;
|
||||
uint32 nloop;
|
||||
uint32 adonly;
|
||||
uint32 type;
|
||||
GSVector4i regs;
|
||||
|
||||
enum {TYPE_UNKNOWN, TYPE_ADONLY, TYPE_STQRGBAXYZF2};
|
||||
|
||||
void SetTag(const void* mem)
|
||||
{
|
||||
GSVector4i v = GSVector4i::load<false>(mem);
|
||||
@@ -1104,7 +1111,9 @@ __aligned(struct, 32) GIFPath
|
||||
regs = v.uph8(v >> 4) & 0x0f0f0f0f;
|
||||
nreg = tag.NREG ? tag.NREG : 16;
|
||||
nloop = tag.NLOOP;
|
||||
adonly = regs.eq8(GSVector4i(0x0e0e0e0e)).mask() == (1 << nreg) - 1;
|
||||
type = TYPE_UNKNOWN;
|
||||
if(regs.u32[0] == 0x00040102 && nreg == 3) type = TYPE_STQRGBAXYZF2;
|
||||
else if(regs.eq8(GSVector4i(0x0e0e0e0e)).mask() == (1 << nreg) - 1) type = TYPE_ADONLY;
|
||||
}
|
||||
|
||||
__forceinline uint8 GetReg()
|
||||
|
||||
@@ -729,7 +729,6 @@ void GSDevice11::IASetVertexBuffer(const void* vertex, size_t stride, size_t cou
|
||||
m_vb = NULL;
|
||||
|
||||
m_vertex.start = 0;
|
||||
m_vertex.count = 0;
|
||||
m_vertex.limit = std::max<int>(count * 3 / 2, 11000);
|
||||
}
|
||||
|
||||
@@ -798,7 +797,7 @@ void GSDevice11::IASetIndexBuffer(const void* index, size_t count)
|
||||
m_ib_old = m_ib;
|
||||
m_ib = NULL;
|
||||
|
||||
m_index.count = 0;
|
||||
m_index.start = 0;
|
||||
m_index.limit = std::max<int>(count * 3 / 2, 11000);
|
||||
}
|
||||
|
||||
@@ -904,7 +903,11 @@ void GSDevice11::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||
{
|
||||
PSSetShaderResource(0, sr0);
|
||||
PSSetShaderResource(1, sr1);
|
||||
PSSetShaderResource(2, NULL);
|
||||
|
||||
for(int i = 2; i < countof(m_state.ps_srv); i++)
|
||||
{
|
||||
PSSetShaderResource(i, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::PSSetShaderResource(int i, GSTexture* sr)
|
||||
@@ -913,6 +916,13 @@ void GSDevice11::PSSetShaderResource(int i, GSTexture* sr)
|
||||
|
||||
if(sr) srv = *(GSTexture11*)sr;
|
||||
|
||||
PSSetShaderResourceView(i, srv);
|
||||
}
|
||||
|
||||
void GSDevice11::PSSetShaderResourceView(int i, ID3D11ShaderResourceView* srv)
|
||||
{
|
||||
ASSERT(i < countof(m_state.ps_srv));
|
||||
|
||||
if(m_state.ps_srv[i] != srv)
|
||||
{
|
||||
m_state.ps_srv[i] = srv;
|
||||
@@ -944,14 +954,14 @@ void GSDevice11::PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb)
|
||||
|
||||
if(m_srv_changed)
|
||||
{
|
||||
m_ctx->PSSetShaderResources(0, 3, m_state.ps_srv);
|
||||
m_ctx->PSSetShaderResources(0, countof(m_state.ps_srv), m_state.ps_srv);
|
||||
|
||||
m_srv_changed = false;
|
||||
}
|
||||
|
||||
if(m_ss_changed)
|
||||
{
|
||||
m_ctx->PSSetSamplers(0, 3, m_state.ps_ss);
|
||||
m_ctx->PSSetSamplers(0, countof(m_state.ps_ss), m_state.ps_ss);
|
||||
|
||||
m_ss_changed = false;
|
||||
}
|
||||
@@ -1036,6 +1046,8 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
|
||||
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
|
||||
}
|
||||
|
||||
memset(m_state.uav, 0, sizeof(m_state.uav));
|
||||
|
||||
if(m_state.viewport != rt->GetSize())
|
||||
{
|
||||
m_state.viewport = rt->GetSize();
|
||||
@@ -1064,6 +1076,52 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::OMSetRenderTargets(const GSVector2i& rtsize, ID3D11UnorderedAccessView** uav, int count, const GSVector4i* scissor)
|
||||
{
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
if(m_state.uav[i] != uav[i])
|
||||
{
|
||||
memcpy(m_state.uav, uav, sizeof(uav[0]) * count);
|
||||
memset(m_state.uav + count, 0, sizeof(m_state.uav) - sizeof(uav[0]) * count);
|
||||
|
||||
m_ctx->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, count, uav, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_state.rtv = NULL;
|
||||
m_state.dsv = NULL;
|
||||
|
||||
if(m_state.viewport != rtsize)
|
||||
{
|
||||
m_state.viewport = rtsize;
|
||||
|
||||
D3D11_VIEWPORT vp;
|
||||
|
||||
memset(&vp, 0, sizeof(vp));
|
||||
|
||||
vp.TopLeftX = 0;
|
||||
vp.TopLeftY = 0;
|
||||
vp.Width = (float)rtsize.x;
|
||||
vp.Height = (float)rtsize.y;
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
|
||||
m_ctx->RSSetViewports(1, &vp);
|
||||
}
|
||||
|
||||
GSVector4i r = scissor ? *scissor : GSVector4i(rtsize).zwxy();
|
||||
|
||||
if(!m_state.scissor.eq(r))
|
||||
{
|
||||
m_state.scissor = r;
|
||||
|
||||
m_ctx->RSSetScissorRects(1, r);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT GSDevice11::CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il)
|
||||
{
|
||||
HRESULT hr;
|
||||
@@ -1135,6 +1193,38 @@ HRESULT GSDevice11::CompileShader(uint32 id, const char* entry, D3D11_SHADER_MAC
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT GSDevice11::CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11GeometryShader** gs, D3D11_SO_DECLARATION_ENTRY* layout, int count)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
vector<D3D11_SHADER_MACRO> m;
|
||||
|
||||
PrepareShaderMacro(m, macro);
|
||||
|
||||
CComPtr<ID3D11Blob> shader, error;
|
||||
|
||||
hr = D3DX11CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry, m_shader.gs.c_str(), 0, 0, NULL, &shader, &error, NULL);
|
||||
|
||||
if(error)
|
||||
{
|
||||
printf("%s\n", (const char*)error->GetBufferPointer());
|
||||
}
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_dev->CreateGeometryShaderWithStreamOutput((void*)shader->GetBufferPointer(), shader->GetBufferSize(), layout, count, NULL, 0, D3D11_SO_NO_RASTERIZED_STREAM, NULL, gs);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT GSDevice11::CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11PixelShader** ps)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
@@ -60,7 +60,7 @@ class GSDevice11 : public GSDeviceDX
|
||||
ID3D11VertexShader* vs;
|
||||
ID3D11Buffer* vs_cb;
|
||||
ID3D11GeometryShader* gs;
|
||||
ID3D11ShaderResourceView* ps_srv[3];
|
||||
ID3D11ShaderResourceView* ps_srv[16];
|
||||
ID3D11PixelShader* ps;
|
||||
ID3D11Buffer* ps_cb;
|
||||
ID3D11SamplerState* ps_ss[3];
|
||||
@@ -73,6 +73,7 @@ class GSDevice11 : public GSDeviceDX
|
||||
float bf;
|
||||
ID3D11RenderTargetView* rtv;
|
||||
ID3D11DepthStencilView* dsv;
|
||||
ID3D11UnorderedAccessView* uav[8];
|
||||
} m_state;
|
||||
|
||||
public: // TODO
|
||||
@@ -178,6 +179,7 @@ public:
|
||||
void GSSetShader(ID3D11GeometryShader* gs);
|
||||
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
|
||||
void PSSetShaderResource(int i, GSTexture* sr);
|
||||
void PSSetShaderResourceView(int i, ID3D11ShaderResourceView* srv);
|
||||
void PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb);
|
||||
void PSSetSamplerState(ID3D11SamplerState* ss0, ID3D11SamplerState* ss1, ID3D11SamplerState* ss2 = NULL);
|
||||
void CSSetShaderSRV(int i, ID3D11ShaderResourceView* srv);
|
||||
@@ -186,6 +188,7 @@ public:
|
||||
void OMSetDepthStencilState(ID3D11DepthStencilState* dss, uint8 sref);
|
||||
void OMSetBlendState(ID3D11BlendState* bs, float bf);
|
||||
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
|
||||
void OMSetRenderTargets(const GSVector2i& rtsize, ID3D11UnorderedAccessView** uav, int count, const GSVector4i* scissor = NULL);
|
||||
|
||||
void SetupIA(const void* vertex, int vertex_count, const uint32* index, int index_count, int prim);
|
||||
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
|
||||
@@ -202,6 +205,7 @@ public:
|
||||
|
||||
HRESULT CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il);
|
||||
HRESULT CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11GeometryShader** gs);
|
||||
HRESULT CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11GeometryShader** gs, D3D11_SO_DECLARATION_ENTRY* layout, int count);
|
||||
HRESULT CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11PixelShader** ps);
|
||||
HRESULT CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11ComputeShader** cs);
|
||||
HRESULT CompileShader(const char* fn, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11ComputeShader** cs);
|
||||
|
||||
@@ -53,7 +53,8 @@ public:
|
||||
GSOffset* fb;
|
||||
GSOffset* zb;
|
||||
GSOffset* tex;
|
||||
GSPixelOffset4* fzb;
|
||||
GSPixelOffset* fzb;
|
||||
GSPixelOffset4* fzb4;
|
||||
} offset;
|
||||
|
||||
GSDrawingContext()
|
||||
|
||||
@@ -473,6 +473,62 @@ GSOffset* GSLocalMemory::GetOffset(uint32 bp, uint32 bw, uint32 psm)
|
||||
return o;
|
||||
}
|
||||
|
||||
GSPixelOffset* GSLocalMemory::GetPixelOffset(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF)
|
||||
{
|
||||
uint32 fbp = FRAME.Block();
|
||||
uint32 zbp = ZBUF.Block();
|
||||
uint32 fpsm = FRAME.PSM;
|
||||
uint32 zpsm = ZBUF.PSM;
|
||||
uint32 bw = FRAME.FBW;
|
||||
|
||||
ASSERT(m_psm[fpsm].trbpp > 8 || m_psm[zpsm].trbpp > 8);
|
||||
|
||||
// "(psm & 0x0f) ^ ((psm & 0xf0) >> 2)" creates 4 bit unique identifiers for render target formats (only)
|
||||
|
||||
uint32 fpsm_hash = (fpsm & 0x0f) ^ ((fpsm & 0x30) >> 2);
|
||||
uint32 zpsm_hash = (zpsm & 0x0f) ^ ((zpsm & 0x30) >> 2);
|
||||
|
||||
uint32 hash = (FRAME.FBP << 0) | (ZBUF.ZBP << 9) | (bw << 18) | (fpsm_hash << 24) | (zpsm_hash << 28);
|
||||
|
||||
hash_map<uint32, GSPixelOffset*>::iterator i = m_pomap.find(hash);
|
||||
|
||||
if(i != m_pomap.end())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
|
||||
GSPixelOffset* o = (GSPixelOffset*)_aligned_malloc(sizeof(GSPixelOffset), 32);
|
||||
|
||||
o->hash = hash;
|
||||
o->fbp = fbp;
|
||||
o->zbp = zbp;
|
||||
o->fpsm = fpsm;
|
||||
o->zpsm = zpsm;
|
||||
o->bw = bw;
|
||||
|
||||
pixelAddress fpa = m_psm[fpsm].pa;
|
||||
pixelAddress zpa = m_psm[zpsm].pa;
|
||||
|
||||
int fs = m_psm[fpsm].bpp >> 5;
|
||||
int zs = m_psm[zpsm].bpp >> 5;
|
||||
|
||||
for(int i = 0; i < 2048; i++)
|
||||
{
|
||||
o->row[i].x = (int)fpa(0, i, fbp, bw) << fs;
|
||||
o->row[i].y = (int)zpa(0, i, zbp, bw) << zs;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 2048; i++)
|
||||
{
|
||||
o->col[i].x = m_psm[fpsm].rowOffset[0][i] << fs;
|
||||
o->col[i].y = m_psm[zpsm].rowOffset[0][i] << zs;
|
||||
}
|
||||
|
||||
m_pomap[hash] = o;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
GSPixelOffset4* GSLocalMemory::GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF)
|
||||
{
|
||||
uint32 fbp = FRAME.Block();
|
||||
|
||||
@@ -56,6 +56,16 @@ public:
|
||||
uint32* GetPages(const GSVector4i& rect, uint32* pages = NULL, GSVector4i* bbox = NULL);
|
||||
};
|
||||
|
||||
struct GSPixelOffset
|
||||
{
|
||||
// 16 bit offsets (m_vm16[...])
|
||||
|
||||
GSVector2i row[2048]; // f yn | z yn
|
||||
GSVector2i col[2048]; // f xn | z xn
|
||||
uint32 hash;
|
||||
uint32 fbp, zbp, fpsm, zpsm, bw;
|
||||
};
|
||||
|
||||
struct GSPixelOffset4
|
||||
{
|
||||
// 16 bit offsets (m_vm16[...])
|
||||
@@ -158,6 +168,7 @@ protected:
|
||||
//
|
||||
|
||||
hash_map<uint32, GSOffset*> m_omap;
|
||||
hash_map<uint32, GSPixelOffset*> m_pomap;
|
||||
hash_map<uint32, GSPixelOffset4*> m_po4map;
|
||||
hash_map<uint64, vector<GSVector2i>*> m_p2tmap;
|
||||
|
||||
@@ -166,6 +177,7 @@ public:
|
||||
virtual ~GSLocalMemory();
|
||||
|
||||
GSOffset* GetOffset(uint32 bp, uint32 bw, uint32 psm);
|
||||
GSPixelOffset* GetPixelOffset(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF);
|
||||
GSPixelOffset4* GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF);
|
||||
vector<GSVector2i>* GetPage2TileMap(const GIFRegTEX0& TEX0);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
|
||||
enum counter_t
|
||||
{
|
||||
Frame, Prim, Draw, Swizzle, Unswizzle, Fillrate, Quad,
|
||||
Frame, Prim, Draw, Swizzle, Unswizzle, Fillrate, Quad, SyncPoint,
|
||||
CounterLast,
|
||||
};
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ GSRasterizer::GSRasterizer(IDrawScanline* ds, int id, int threads, GSPerfMon* pe
|
||||
m_edge.buff = (GSVertexSW*)vmalloc(sizeof(GSVertexSW) * 2048, false);
|
||||
m_edge.count = 0;
|
||||
|
||||
m_myscanline = (uint8*)_aligned_malloc((2048 >> THREAD_HEIGHT) + 16, 64);
|
||||
m_scanline = (uint8*)_aligned_malloc((2048 >> THREAD_HEIGHT) + 16, 64);
|
||||
|
||||
int row = 0;
|
||||
|
||||
@@ -48,14 +48,14 @@ GSRasterizer::GSRasterizer(IDrawScanline* ds, int id, int threads, GSPerfMon* pe
|
||||
{
|
||||
for(int i = 0; i < threads; i++, row++)
|
||||
{
|
||||
m_myscanline[row] = i == id ? 1 : 0;
|
||||
m_scanline[row] = i == id ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSRasterizer::~GSRasterizer()
|
||||
{
|
||||
_aligned_free(m_myscanline);
|
||||
_aligned_free(m_scanline);
|
||||
|
||||
if(m_edge.buff != NULL) vmfree(m_edge.buff, sizeof(GSVertexSW) * 2048);
|
||||
|
||||
@@ -66,7 +66,7 @@ bool GSRasterizer::IsOneOfMyScanlines(int top) const
|
||||
{
|
||||
ASSERT(top >= 0 && top < 2048);
|
||||
|
||||
return m_myscanline[top >> THREAD_HEIGHT] != 0;
|
||||
return m_scanline[top >> THREAD_HEIGHT] != 0;
|
||||
}
|
||||
|
||||
bool GSRasterizer::IsOneOfMyScanlines(int top, int bottom) const
|
||||
@@ -78,7 +78,7 @@ bool GSRasterizer::IsOneOfMyScanlines(int top, int bottom) const
|
||||
|
||||
while(top < bottom)
|
||||
{
|
||||
if(m_myscanline[top++])
|
||||
if(m_scanline[top++])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -91,9 +91,9 @@ int GSRasterizer::FindMyNextScanline(int top) const
|
||||
{
|
||||
int i = top >> THREAD_HEIGHT;
|
||||
|
||||
if(m_myscanline[i] == 0)
|
||||
if(m_scanline[i] == 0)
|
||||
{
|
||||
while(m_myscanline[++i] == 0);
|
||||
while(m_scanline[++i] == 0);
|
||||
|
||||
top = i << THREAD_HEIGHT;
|
||||
}
|
||||
@@ -904,11 +904,20 @@ void GSRasterizer::Flush(const GSVertexSW* vertex, const uint32* index, const GS
|
||||
|
||||
//
|
||||
|
||||
GSRasterizerList::GSRasterizerList()
|
||||
: GSJobQueue<shared_ptr<GSRasterizerData> >()
|
||||
, m_sync_count(0)
|
||||
, m_syncpoint_count(0)
|
||||
GSRasterizerList::GSRasterizerList(int threads, GSPerfMon* perfmon)
|
||||
: m_perfmon(perfmon)
|
||||
{
|
||||
m_scanline = (uint8*)_aligned_malloc((2048 >> THREAD_HEIGHT) + 16, 64);
|
||||
|
||||
int row = 0;
|
||||
|
||||
while(row < (2048 >> THREAD_HEIGHT))
|
||||
{
|
||||
for(int i = 0; i < threads; i++, row++)
|
||||
{
|
||||
m_scanline[row] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSRasterizerList::~GSRasterizerList()
|
||||
@@ -917,31 +926,54 @@ GSRasterizerList::~GSRasterizerList()
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
|
||||
_aligned_free(m_scanline);
|
||||
}
|
||||
|
||||
void GSRasterizerList::Queue(shared_ptr<GSRasterizerData> data)
|
||||
{
|
||||
// disable dispatcher thread for now and pass-through directly,
|
||||
// would only be relevant if data->syncpoint was utilized more,
|
||||
// it would hide the syncing latency from the main gs thread
|
||||
if(data->syncpoint)
|
||||
{
|
||||
Sync();
|
||||
}
|
||||
|
||||
// Push(data);
|
||||
GSVector4i r = data->bbox.rintersect(data->scissor);
|
||||
|
||||
Process(data); m_count++;
|
||||
ASSERT(r.top >= 0 && r.top < 2048 && r.bottom >= 0 && r.bottom < 2048);
|
||||
|
||||
int top = r.top >> THREAD_HEIGHT;
|
||||
int bottom = std::min<int>((r.bottom + (1 << THREAD_HEIGHT) - 1) >> THREAD_HEIGHT, top + m_workers.size());
|
||||
|
||||
while(top < bottom)
|
||||
{
|
||||
m_workers[m_scanline[top++]]->Push(data);
|
||||
}
|
||||
}
|
||||
|
||||
void GSRasterizerList::Sync()
|
||||
{
|
||||
if(GetCount() == 0) return;
|
||||
if(!IsSynced())
|
||||
{
|
||||
for(size_t i = 0; i < m_workers.size(); i++)
|
||||
{
|
||||
m_workers[i]->Wait();
|
||||
}
|
||||
|
||||
Wait(); // first dispatch all items to workers
|
||||
m_perfmon->Put(GSPerfMon::SyncPoint, 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool GSRasterizerList::IsSynced() const
|
||||
{
|
||||
for(size_t i = 0; i < m_workers.size(); i++)
|
||||
{
|
||||
m_workers[i]->Wait(); // then wait all workers to finish their jobs
|
||||
if(!m_workers[i]->IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_sync_count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
int GSRasterizerList::GetPixels(bool reset)
|
||||
@@ -956,24 +988,6 @@ int GSRasterizerList::GetPixels(bool reset)
|
||||
return pixels;
|
||||
}
|
||||
|
||||
void GSRasterizerList::Process(shared_ptr<GSRasterizerData>& item)
|
||||
{
|
||||
if(item->syncpoint)
|
||||
{
|
||||
for(size_t i = 0; i < m_workers.size(); i++)
|
||||
{
|
||||
m_workers[i]->Wait();
|
||||
}
|
||||
|
||||
m_syncpoint_count++;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < m_workers.size(); i++)
|
||||
{
|
||||
m_workers[i]->Push(item);
|
||||
}
|
||||
}
|
||||
|
||||
// GSRasterizerList::GSWorker
|
||||
|
||||
GSRasterizerList::GSWorker::GSWorker(GSRasterizer* r)
|
||||
@@ -994,16 +1008,6 @@ int GSRasterizerList::GSWorker::GetPixels(bool reset)
|
||||
return m_r->GetPixels(reset);
|
||||
}
|
||||
|
||||
void GSRasterizerList::GSWorker::Push(const shared_ptr<GSRasterizerData>& item)
|
||||
{
|
||||
GSVector4i r = item->bbox.rintersect(item->scissor);
|
||||
|
||||
if(m_r->IsOneOfMyScanlines(r.top, r.bottom))
|
||||
{
|
||||
GSJobQueue<shared_ptr<GSRasterizerData> >::Push(item);
|
||||
}
|
||||
}
|
||||
|
||||
void GSRasterizerList::GSWorker::Process(shared_ptr<GSRasterizerData>& item)
|
||||
{
|
||||
m_r->Draw(item.get());
|
||||
|
||||
@@ -109,6 +109,7 @@ public:
|
||||
|
||||
virtual void Queue(shared_ptr<GSRasterizerData> data) = 0;
|
||||
virtual void Sync() = 0;
|
||||
virtual bool IsSynced() const = 0;
|
||||
virtual int GetPixels(bool reset = true) = 0;
|
||||
};
|
||||
|
||||
@@ -119,7 +120,7 @@ protected:
|
||||
IDrawScanline* m_ds;
|
||||
int m_id;
|
||||
int m_threads;
|
||||
uint8* m_myscanline;
|
||||
uint8* m_scanline;
|
||||
GSVector4i m_scissor;
|
||||
GSVector4 m_fscissor_x;
|
||||
GSVector4 m_fscissor_y;
|
||||
@@ -155,12 +156,12 @@ public:
|
||||
|
||||
void Queue(shared_ptr<GSRasterizerData> data);
|
||||
void Sync() {}
|
||||
bool IsSynced() const {return true;}
|
||||
int GetPixels(bool reset);
|
||||
};
|
||||
|
||||
class GSRasterizerList
|
||||
: public IRasterizer
|
||||
, private GSJobQueue<shared_ptr<GSRasterizerData> >
|
||||
{
|
||||
protected:
|
||||
class GSWorker : public GSJobQueue<shared_ptr<GSRasterizerData> >
|
||||
@@ -175,17 +176,14 @@ protected:
|
||||
|
||||
// GSJobQueue
|
||||
|
||||
void Push(const shared_ptr<GSRasterizerData>& item);
|
||||
void Process(shared_ptr<GSRasterizerData>& item);
|
||||
};
|
||||
|
||||
GSPerfMon* m_perfmon;
|
||||
vector<GSWorker*> m_workers;
|
||||
uint8* m_scanline;
|
||||
|
||||
GSRasterizerList();
|
||||
|
||||
// GSJobQueue
|
||||
|
||||
void Process(shared_ptr<GSRasterizerData>& item);
|
||||
GSRasterizerList(int threads, GSPerfMon* perfmon);
|
||||
|
||||
public:
|
||||
virtual ~GSRasterizerList();
|
||||
@@ -200,7 +198,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
GSRasterizerList* rl = new GSRasterizerList();
|
||||
GSRasterizerList* rl = new GSRasterizerList(threads, perfmon);
|
||||
|
||||
for(int i = 0; i < threads; i++)
|
||||
{
|
||||
@@ -211,12 +209,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int m_sync_count;
|
||||
int m_syncpoint_count;
|
||||
|
||||
// IRasterizer
|
||||
|
||||
void Queue(shared_ptr<GSRasterizerData> data);
|
||||
void Sync();
|
||||
bool IsSynced() const;
|
||||
int GetPixels(bool reset);
|
||||
};
|
||||
|
||||
@@ -257,7 +257,7 @@ bool GSRenderer::Merge(int field)
|
||||
{
|
||||
int field2 = 1 - ((m_interlace - 1) & 1);
|
||||
int mode = (m_interlace - 1) >> 1;
|
||||
|
||||
|
||||
m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y);
|
||||
}
|
||||
|
||||
@@ -304,6 +304,8 @@ void GSRenderer::VSync(int field)
|
||||
ResetDevice();
|
||||
}
|
||||
|
||||
m_dev->AgePool();
|
||||
|
||||
// osd
|
||||
|
||||
if((m_perfmon.GetFrame() & 0x1f) == 0)
|
||||
@@ -332,7 +334,7 @@ void GSRenderer::VSync(int field)
|
||||
s2.c_str(),
|
||||
theApp.m_gs_interlace[m_interlace].name.c_str(),
|
||||
theApp.m_gs_aspectratio[m_aspectratio].name.c_str(),
|
||||
(int)m_perfmon.Get(GSPerfMon::Quad),
|
||||
(int)m_perfmon.Get(GSPerfMon::SyncPoint),
|
||||
(int)m_perfmon.Get(GSPerfMon::Prim),
|
||||
(int)m_perfmon.Get(GSPerfMon::Draw),
|
||||
m_perfmon.CPU(),
|
||||
|
||||
+518
-188
File diff suppressed because it is too large
Load Diff
@@ -26,28 +26,105 @@
|
||||
|
||||
class GSRendererCS : public GSRenderer
|
||||
{
|
||||
class GSVertexTraceCS : public GSVertexTrace
|
||||
struct VSSelector
|
||||
{
|
||||
public:
|
||||
GSVertexTraceCS(const GSState* state) : GSVertexTrace(state) {}
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32 tme:1;
|
||||
uint32 fst:1;
|
||||
};
|
||||
|
||||
uint32 key;
|
||||
};
|
||||
|
||||
operator uint32() {return key & 0x3;}
|
||||
|
||||
VSSelector() : key(0) {}
|
||||
};
|
||||
|
||||
__aligned(struct, 32) VSConstantBuffer
|
||||
{
|
||||
GSVector4 VertexScale;
|
||||
GSVector4 VertexOffset;
|
||||
};
|
||||
|
||||
struct GSSelector
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32 iip:1;
|
||||
uint32 prim:2;
|
||||
};
|
||||
|
||||
uint32 key;
|
||||
};
|
||||
|
||||
operator uint32() {return key & 0x7;}
|
||||
|
||||
GSSelector() : key(0) {}
|
||||
};
|
||||
|
||||
struct PSSelector
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32 TODO:1;
|
||||
};
|
||||
|
||||
uint32 key;
|
||||
};
|
||||
|
||||
operator uint32() {return key & 0x1;}
|
||||
|
||||
PSSelector() : key(0) {}
|
||||
};
|
||||
|
||||
__aligned(struct, 32) PSConstantBuffer
|
||||
{
|
||||
GSVector4 TODO;
|
||||
};
|
||||
|
||||
CComPtr<ID3D11DepthStencilState> m_dss;
|
||||
CComPtr<ID3D11BlendState> m_bs;
|
||||
CComPtr<ID3D11SamplerState> m_ss;
|
||||
CComPtr<ID3D11Buffer> m_vm;
|
||||
//CComPtr<ID3D11Texture2D> m_vm;
|
||||
CComPtr<ID3D11UnorderedAccessView> m_vm_uav;
|
||||
CComPtr<ID3D11Buffer> m_vb;
|
||||
CComPtr<ID3D11Buffer> m_ib;
|
||||
CComPtr<ID3D11Buffer> m_pb;
|
||||
hash_map<uint32, CComPtr<ID3D11ComputeShader> > m_cs;
|
||||
uint32 m_vm_valid[16];
|
||||
CComPtr<ID3D11Buffer> m_pb;
|
||||
//CComPtr<ID3D11Texture2D> m_pb;
|
||||
hash_map<uint32, GSVertexShader11 > m_vs;
|
||||
CComPtr<ID3D11Buffer> m_vs_cb;
|
||||
hash_map<uint32, CComPtr<ID3D11GeometryShader> > m_gs;
|
||||
hash_map<uint32, CComPtr<ID3D11PixelShader> > m_ps;
|
||||
CComPtr<ID3D11Buffer> m_ps_cb;
|
||||
CComPtr<ID3D11Buffer> m_sob;
|
||||
|
||||
void Write(GSOffset* o, const GSVector4i& r);
|
||||
void Read(GSOffset* o, const GSVector4i& r, bool invalidate);
|
||||
|
||||
|
||||
struct OffsetBuffer
|
||||
{
|
||||
CComPtr<ID3D11Buffer> row, col;
|
||||
CComPtr<ID3D11ShaderResourceView> row_view, col_view;
|
||||
};
|
||||
|
||||
hash_map<uint32, OffsetBuffer> m_offset;
|
||||
|
||||
bool GetOffsetBuffer(OffsetBuffer** fzbo);
|
||||
|
||||
protected:
|
||||
template<uint32 prim, uint32 tme, uint32 fst>
|
||||
void ConvertVertex(size_t dst_index, size_t src_index);
|
||||
|
||||
|
||||
bool CreateDevice(GSDevice* dev);
|
||||
void VSync(int field);
|
||||
GSTexture* GetOutput(int i);
|
||||
void Draw();
|
||||
void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r);
|
||||
|
||||
@@ -233,7 +233,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
|
||||
}
|
||||
}
|
||||
|
||||
if (env.COLCLAMP.CLAMP == 0 && /* hack */ !tex && PRIM->PRIM != GS_POINTLIST)
|
||||
if(env.COLCLAMP.CLAMP == 0 && /* hack */ !tex && PRIM->PRIM != GS_POINTLIST)
|
||||
{
|
||||
ps_sel.colclip = 1;
|
||||
}
|
||||
|
||||
@@ -101,19 +101,18 @@ void GSRendererHW::Reset()
|
||||
|
||||
void GSRendererHW::VSync(int field)
|
||||
{
|
||||
GSRenderer::VSync(field);
|
||||
|
||||
m_tc->IncAge();
|
||||
m_dev->AgePool();
|
||||
|
||||
m_skip = 0;
|
||||
|
||||
if(m_reset)
|
||||
{
|
||||
m_tc->RemoveAll();
|
||||
|
||||
m_reset = false;
|
||||
}
|
||||
|
||||
GSRenderer::VSync(field);
|
||||
|
||||
m_tc->IncAge();
|
||||
|
||||
m_skip = 0;
|
||||
}
|
||||
|
||||
void GSRendererHW::ResetDevice()
|
||||
|
||||
+287
-141
File diff suppressed because it is too large
Load Diff
@@ -48,8 +48,9 @@ protected:
|
||||
GSTextureCacheSW* m_tc;
|
||||
GSTexture* m_texture[2];
|
||||
uint8* m_output;
|
||||
bool m_reset;
|
||||
GSPixelOffset4* m_fzb;
|
||||
GSVector4i m_fzb_bbox;
|
||||
uint32 m_fzb_cur_pages[16];
|
||||
uint32 m_fzb_pages[512]; // uint16 frame/zbuf pages interleaved
|
||||
uint16 m_tex_pages[512];
|
||||
uint32 m_tmp_pages[512 + 1];
|
||||
@@ -66,7 +67,7 @@ protected:
|
||||
|
||||
void UsePages(const uint32* pages, int type);
|
||||
void ReleasePages(const uint32* pages, int type);
|
||||
template<uint32 mask> bool CheckTargetPages(const uint32* pages);
|
||||
bool CheckTargetPages(const uint32* fb_pages, const uint32* zb_pages, const GSVector4i& r);
|
||||
|
||||
bool GetScanlineGlobalData(SharedData* data);
|
||||
|
||||
|
||||
+74
-15
@@ -209,6 +209,9 @@ void GSState::SetFrameSkip(int skip)
|
||||
|
||||
void GSState::Reset()
|
||||
{
|
||||
printf("GS reset\n");
|
||||
|
||||
memset(m_mem.m_vm8, 0, m_mem.m_vmsize);
|
||||
memset(&m_path[0], 0, sizeof(m_path[0]) * countof(m_path));
|
||||
memset(&m_v, 0, sizeof(m_v));
|
||||
|
||||
@@ -253,6 +256,7 @@ void GSState::ResetHandlers()
|
||||
m_fpGIFRegHandlerXYZ[P][1] = &GSState::GIFRegHandlerXYZF2<P, 1>; \
|
||||
m_fpGIFRegHandlerXYZ[P][2] = &GSState::GIFRegHandlerXYZ2<P, 0>; \
|
||||
m_fpGIFRegHandlerXYZ[P][3] = &GSState::GIFRegHandlerXYZ2<P, 1>; \
|
||||
m_fpGIFPackedRegHandlerSTQRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZF2<P>; \
|
||||
|
||||
SetHandlerXYZ(GS_POINTLIST);
|
||||
SetHandlerXYZ(GS_LINELIST);
|
||||
@@ -546,6 +550,36 @@ void GSState::GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r)
|
||||
{
|
||||
}
|
||||
|
||||
template<uint32 prim>
|
||||
void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, uint32 size)
|
||||
{
|
||||
ASSERT(size > 0 && size % 3 == 0);
|
||||
|
||||
const GIFPackedReg* RESTRICT r_end = r + size;
|
||||
|
||||
while(r < r_end)
|
||||
{
|
||||
GSVector4i st = GSVector4i::loadl(&r[0].u64[0]);
|
||||
GSVector4i q = GSVector4i::loadl(&r[0].u64[1]);
|
||||
GSVector4i rgba = (GSVector4i::load<false>(&r[1]) & GSVector4i::x000000ff()).ps32().pu16();
|
||||
|
||||
m_v.m[0] = st.upl64(rgba.upl32(q));
|
||||
|
||||
GSVector4i xy = GSVector4i::loadl(&r[2].u64[0]);
|
||||
GSVector4i zf = GSVector4i::loadl(&r[2].u64[1]);
|
||||
xy = xy.upl16(xy.srl<4>()).upl32(GSVector4i::loadl(&m_v.UV));
|
||||
zf = zf.srl32(4) & GSVector4i::x00ffffff().upl32(GSVector4i::x000000ff());
|
||||
|
||||
m_v.m[1] = xy.upl32(zf);
|
||||
|
||||
VertexKick<prim>(r[2].XYZF2.Skip());
|
||||
|
||||
r += 3;
|
||||
}
|
||||
|
||||
m_q = r[-3].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time
|
||||
}
|
||||
|
||||
// GIFRegHandler*
|
||||
|
||||
void GSState::GIFRegHandlerNull(const GIFReg* RESTRICT r)
|
||||
@@ -1037,7 +1071,8 @@ template<int i> void GSState::GIFRegHandlerFRAME(const GIFReg* RESTRICT r)
|
||||
{
|
||||
m_env.CTXT[i].offset.fb = m_mem.GetOffset(r->FRAME.Block(), r->FRAME.FBW, r->FRAME.PSM);
|
||||
m_env.CTXT[i].offset.zb = m_mem.GetOffset(m_env.CTXT[i].ZBUF.Block(), r->FRAME.FBW, m_env.CTXT[i].ZBUF.PSM);
|
||||
m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset4(r->FRAME, m_env.CTXT[i].ZBUF);
|
||||
m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset(r->FRAME, m_env.CTXT[i].ZBUF);
|
||||
m_env.CTXT[i].offset.fzb4 = m_mem.GetPixelOffset4(r->FRAME, m_env.CTXT[i].ZBUF);
|
||||
}
|
||||
|
||||
m_env.CTXT[i].FRAME = (GSVector4i)r->FRAME;
|
||||
@@ -1075,7 +1110,8 @@ template<int i> void GSState::GIFRegHandlerZBUF(const GIFReg* RESTRICT r)
|
||||
if((m_env.CTXT[i].ZBUF.u32[0] ^ ZBUF.u32[0]) & 0x3f0001ff) // ZBP PSM
|
||||
{
|
||||
m_env.CTXT[i].offset.zb = m_mem.GetOffset(ZBUF.Block(), m_env.CTXT[i].FRAME.FBW, ZBUF.PSM);
|
||||
m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, ZBUF);
|
||||
m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset(m_env.CTXT[i].FRAME, ZBUF);
|
||||
m_env.CTXT[i].offset.fzb4 = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, ZBUF);
|
||||
}
|
||||
|
||||
m_env.CTXT[i].ZBUF = (GSVector4i)ZBUF;
|
||||
@@ -1726,8 +1762,28 @@ template<int index> void GSState::Transfer(const uint8* mem, uint32 size)
|
||||
{
|
||||
size -= total;
|
||||
|
||||
if(path.adonly)
|
||||
switch(path.type)
|
||||
{
|
||||
case GIFPath::TYPE_UNKNOWN:
|
||||
|
||||
{
|
||||
uint32 reg = 0;
|
||||
|
||||
do
|
||||
{
|
||||
(this->*m_fpGIFPackedRegHandlers[path.GetReg(reg++)])((GIFPackedReg*)mem);
|
||||
|
||||
mem += sizeof(GIFPackedReg);
|
||||
|
||||
reg = reg & ((int)(reg - path.nreg) >> 31); // resets reg back to 0 when it becomes equal to path.nreg
|
||||
}
|
||||
while(--total > 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GIFPath::TYPE_ADONLY: // very common
|
||||
|
||||
do
|
||||
{
|
||||
(this->*m_fpGIFRegHandlers[((GIFPackedReg*)mem)->A_D.ADDR])(&((GIFPackedReg*)mem)->r);
|
||||
@@ -1735,20 +1791,20 @@ template<int index> void GSState::Transfer(const uint8* mem, uint32 size)
|
||||
mem += sizeof(GIFPackedReg);
|
||||
}
|
||||
while(--total > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 reg = 0;
|
||||
|
||||
do
|
||||
{
|
||||
(this->*m_fpGIFPackedRegHandlers[path.GetReg(reg++)])((GIFPackedReg*)mem);
|
||||
break;
|
||||
|
||||
case GIFPath::TYPE_STQRGBAXYZF2: // majority of the vertices are formatted like this
|
||||
|
||||
mem += sizeof(GIFPackedReg);
|
||||
(this->*m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZF2])((GIFPackedReg*)mem, total);
|
||||
|
||||
reg = reg & ((int)(reg - path.nreg) >> 31); // resets reg back to 0 when it becomes equal to path.nreg
|
||||
}
|
||||
while(--total > 0);
|
||||
mem += total * sizeof(GIFPackedReg);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
path.nloop = 0;
|
||||
@@ -2070,7 +2126,8 @@ int GSState::Defrost(const GSFreezeData* fd)
|
||||
m_env.CTXT[i].offset.fb = m_mem.GetOffset(m_env.CTXT[i].FRAME.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].FRAME.PSM);
|
||||
m_env.CTXT[i].offset.zb = m_mem.GetOffset(m_env.CTXT[i].ZBUF.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].ZBUF.PSM);
|
||||
m_env.CTXT[i].offset.tex = m_mem.GetOffset(m_env.CTXT[i].TEX0.TBP0, m_env.CTXT[i].TEX0.TBW, m_env.CTXT[i].TEX0.PSM);
|
||||
m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, m_env.CTXT[i].ZBUF);
|
||||
m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset(m_env.CTXT[i].FRAME, m_env.CTXT[i].ZBUF);
|
||||
m_env.CTXT[i].offset.fzb4 = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, m_env.CTXT[i].ZBUF);
|
||||
}
|
||||
|
||||
UpdateScissor();
|
||||
@@ -2116,6 +2173,8 @@ void GSState::UpdateVertexKick()
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_XYZ2] = m_fpGIFRegHandlerXYZ[prim][2];
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_XYZ3] = m_fpGIFRegHandlerXYZ[prim][3];
|
||||
|
||||
m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZF2] = m_fpGIFPackedRegHandlerSTQRGBAXYZF2[prim];
|
||||
|
||||
m_cvf = m_cv[prim][PRIM->TME][PRIM->FST];
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,13 @@ class GSState : public GSAlignedClass<32>
|
||||
GIFRegHandler m_fpGIFRegHandlers[256];
|
||||
GIFRegHandler m_fpGIFRegHandlerXYZ[8][4];
|
||||
|
||||
typedef void (GSState::*GIFPackedRegHandlerC)(const GIFPackedReg* RESTRICT r, uint32 size);
|
||||
|
||||
GIFPackedRegHandlerC m_fpGIFPackedRegHandlersC[1];
|
||||
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8];
|
||||
|
||||
template<uint32 prim> void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, uint32 size);
|
||||
|
||||
template<int i> void ApplyTEX0(GIFRegTEX0& TEX0);
|
||||
void ApplyPRIM(const GIFRegPRIM& PRIM);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user