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:
gabest11
2012-01-18 11:47:31 +00:00
parent da4ea83134
commit 9aabcc1701
27 changed files with 1549 additions and 528 deletions
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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()
+95 -5
View File
@@ -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;
+5 -1
View File
@@ -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);
+2 -1
View File
@@ -53,7 +53,8 @@ public:
GSOffset* fb;
GSOffset* zb;
GSOffset* tex;
GSPixelOffset4* fzb;
GSPixelOffset* fzb;
GSPixelOffset4* fzb4;
} offset;
GSDrawingContext()
+56
View File
@@ -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();
+12
View File
@@ -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);
+1 -1
View File
@@ -35,7 +35,7 @@ public:
enum counter_t
{
Frame, Prim, Draw, Swizzle, Unswizzle, Fillrate, Quad,
Frame, Prim, Draw, Swizzle, Unswizzle, Fillrate, Quad, SyncPoint,
CounterLast,
};
+52 -48
View File
@@ -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());
+8 -12
View File
@@ -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);
};
+4 -2
View File
@@ -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(),
File diff suppressed because it is too large Load Diff
+86 -9
View File
@@ -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);
+1 -1
View File
@@ -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;
}
+6 -7
View File
@@ -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()
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -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
View File
@@ -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];
}
+7
View File
@@ -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