GSdx: dx9 hw mode got a vertex buffer too (as dx10), it was an old TODO...

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1250 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-05-23 23:52:53 +00:00
parent 20f0e52a1a
commit 081006bcbe
11 changed files with 181 additions and 94 deletions

View File

@ -27,10 +27,7 @@
class GSDevice10 : public GSDevice class GSDevice10 : public GSDevice
{ {
private: private:
// state cache
ID3D10Buffer* m_vb; ID3D10Buffer* m_vb;
int m_vb_count;
size_t m_vb_stride; size_t m_vb_stride;
ID3D10InputLayout* m_layout; ID3D10InputLayout* m_layout;
D3D10_PRIMITIVE_TOPOLOGY m_topology; D3D10_PRIMITIVE_TOPOLOGY m_topology;

View File

@ -26,8 +26,6 @@
GSDevice9::GSDevice9() GSDevice9::GSDevice9()
: m_vb(NULL) : m_vb(NULL)
, m_vb_count(0)
, m_vb_vertices(NULL)
, m_vb_stride(0) , m_vb_stride(0)
, m_layout(NULL) , m_layout(NULL)
, m_topology((D3DPRIMITIVETYPE)0) , m_topology((D3DPRIMITIVETYPE)0)
@ -145,6 +143,8 @@ bool GSDevice9::Create(HWND hWnd, bool vsync)
CompileShader(IDR_CONVERT9_FX, format("ps_main%d", i), NULL, &m_convert.ps[i]); CompileShader(IDR_CONVERT9_FX, format("ps_main%d", i), NULL, &m_convert.ps[i]);
} }
m_dev->CreateVertexBuffer(4 * sizeof(GSVertexPT1), D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_convert.vb, NULL);
m_convert.dss.DepthEnable = false; m_convert.dss.DepthEnable = false;
m_convert.dss.StencilEnable = false; m_convert.dss.StencilEnable = false;
@ -550,7 +550,16 @@ void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, c
vertices[i].p.y += 1.0f / ds.y; vertices[i].p.y += 1.0f / ds.y;
} }
IASetVertexBuffer(4, vertices); void* buff = NULL;
if(SUCCEEDED(m_convert.vb->Lock(0, 0, &buff, D3DLOCK_DISCARD)))
{
memcpy(buff, vertices, sizeof(vertices));
m_convert.vb->Unlock();
}
IASetVertexBuffer(m_convert.vb, sizeof(vertices[0]));
IASetInputLayout(m_convert.il); IASetInputLayout(m_convert.il);
IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
@ -570,7 +579,7 @@ void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, c
// //
DrawPrimitive(); DrawPrimitive(countof(vertices));
// //
@ -610,18 +619,9 @@ void GSDevice9::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linea
StretchRect(st, sr, dt, dr, m_interlace.ps[shader], (const float*)&cb, 1, linear); StretchRect(st, sr, dt, dr, m_interlace.ps[shader], (const float*)&cb, 1, linear);
} }
/*
void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, uint32 count, const void* vertices, size_t stride) void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, size_t stride)
{ {
void* data = NULL;
if(SUCCEEDED(vb->Lock(0, count * stride, &data, D3DLOCK_DISCARD)))
{
memcpy(data, vertices, count * stride);
vb->Unlock();
}
if(m_vb != vb || m_vb_stride != stride) if(m_vb != vb || m_vb_stride != stride)
{ {
m_dev->SetStreamSource(0, vb, 0, stride); m_dev->SetStreamSource(0, vb, 0, stride);
@ -630,23 +630,14 @@ void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, uint32 count, cons
m_vb_stride = stride; m_vb_stride = stride;
} }
} }
*/
void GSDevice9::IASetVertexBuffer(int count, const void* vertices, size_t stride)
{
m_vb_count = count;
m_vb_vertices = vertices;
m_vb_stride = stride;
}
void GSDevice9::IASetInputLayout(IDirect3DVertexDeclaration9* layout) void GSDevice9::IASetInputLayout(IDirect3DVertexDeclaration9* layout)
{ {
// TODO: get rid of all SetFVF before enabling this if(m_layout != layout)
// if(m_layout != layout)
{ {
m_dev->SetVertexDeclaration(layout); m_dev->SetVertexDeclaration(layout);
// m_layout = layout; m_layout = layout;
} }
} }
@ -855,31 +846,31 @@ void GSDevice9::OMSetRenderTargets(GSTexture* rt, GSTexture* ds)
} }
} }
void GSDevice9::DrawPrimitive() void GSDevice9::DrawPrimitive(uint32 count, uint32 start)
{ {
int prims = 0; int prims = 0;
switch(m_topology) switch(m_topology)
{ {
case D3DPT_TRIANGLELIST: case D3DPT_TRIANGLELIST:
prims = m_vb_count / 3; prims = count / 3;
break; break;
case D3DPT_LINELIST: case D3DPT_LINELIST:
prims = m_vb_count / 2; prims = count / 2;
break; break;
case D3DPT_POINTLIST: case D3DPT_POINTLIST:
prims = m_vb_count; prims = count;
break; break;
case D3DPT_TRIANGLESTRIP: case D3DPT_TRIANGLESTRIP:
case D3DPT_TRIANGLEFAN: case D3DPT_TRIANGLEFAN:
prims = m_vb_count - 2; prims = count - 2;
break; break;
case D3DPT_LINESTRIP: case D3DPT_LINESTRIP:
prims = m_vb_count - 1; prims = count - 1;
break; break;
} }
m_dev->DrawPrimitiveUP(m_topology, prims, m_vb_vertices, m_vb_stride); m_dev->DrawPrimitive(m_topology, start, prims);
} }
// FIXME: D3DXCompileShaderFromResource of d3dx9 v37 (march 2008) calls GetFullPathName on id for some reason and then crashes // FIXME: D3DXCompileShaderFromResource of d3dx9 v37 (march 2008) calls GetFullPathName on id for some reason and then crashes

View File

@ -61,11 +61,7 @@ struct Direct3DBlendState9
class GSDevice9 : public GSDevice class GSDevice9 : public GSDevice
{ {
private: private:
// state cache
IDirect3DVertexBuffer9* m_vb; IDirect3DVertexBuffer9* m_vb;
int m_vb_count;
const void* m_vb_vertices;
size_t m_vb_stride; size_t m_vb_stride;
IDirect3DVertexDeclaration9* m_layout; IDirect3DVertexDeclaration9* m_layout;
D3DPRIMITIVETYPE m_topology; D3DPRIMITIVETYPE m_topology;
@ -106,8 +102,9 @@ public: // TODO
struct struct
{ {
CComPtr<IDirect3DVertexShader9> vs; CComPtr<IDirect3DVertexBuffer9> vb;
CComPtr<IDirect3DVertexDeclaration9> il; CComPtr<IDirect3DVertexDeclaration9> il;
CComPtr<IDirect3DVertexShader9> vs;
CComPtr<IDirect3DPixelShader9> ps[7]; CComPtr<IDirect3DPixelShader9> ps[7];
Direct3DSamplerState9 ln; Direct3DSamplerState9 ln;
Direct3DSamplerState9 pt; Direct3DSamplerState9 pt;
@ -157,8 +154,7 @@ public:
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, bool linear = true); void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, bool linear = true);
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, Direct3DBlendState9* bs, bool linear = true); void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, Direct3DBlendState9* bs, bool linear = true);
// TODO: void IASetVertexBuffer(IDirect3DVertexBuffer9* vb, uint32 count, const void* vertices, size_t stride); void IASetVertexBuffer(IDirect3DVertexBuffer9* vb, size_t stride);
void IASetVertexBuffer(int count, const void* vertices, size_t stride);
void IASetInputLayout(IDirect3DVertexDeclaration9* layout); void IASetInputLayout(IDirect3DVertexDeclaration9* layout);
void IASetPrimitiveTopology(D3DPRIMITIVETYPE topology); void IASetPrimitiveTopology(D3DPRIMITIVETYPE topology);
void VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int vs_cb_len); void VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int vs_cb_len);
@ -169,12 +165,7 @@ public:
void OMSetDepthStencilState(Direct3DDepthStencilState9* dss, uint32 sref); void OMSetDepthStencilState(Direct3DDepthStencilState9* dss, uint32 sref);
void OMSetBlendState(Direct3DBlendState9* bs, uint32 bf); void OMSetBlendState(Direct3DBlendState9* bs, uint32 bf);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); void OMSetRenderTargets(GSTexture* rt, GSTexture* ds);
void DrawPrimitive(); void DrawPrimitive(uint32 count, uint32 start = 0);
template<class T> void IASetVertexBuffer(int count, T* vertices)
{
IASetVertexBuffer(count, vertices, sizeof(T));
}
IDirect3DDevice9* operator->() {return m_dev;} IDirect3DDevice9* operator->() {return m_dev;}
operator IDirect3DDevice9*() {return m_dev;} operator IDirect3DDevice9*() {return m_dev;}

View File

@ -400,7 +400,7 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
if(context->TEST.DoFirstPass()) if(context->TEST.DoFirstPass())
{ {
((GSDevice9*)m_dev)->DrawPrimitive(); m_tfx.Draw();
} }
if(context->TEST.DoSecondPass()) if(context->TEST.DoSecondPass())
@ -438,7 +438,7 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
m_tfx.UpdateOM(om_dssel, om_bsel, bf); m_tfx.UpdateOM(om_dssel, om_bsel, bf);
((GSDevice9*)m_dev)->DrawPrimitive(); m_tfx.Draw();
} }
} }
@ -536,7 +536,16 @@ void GSRendererHW9::SetupDATE(GSTexture* rt, GSTexture* ds)
{GSVector4(mm.z, -mm.w, 0.5f, 1.0f), GSVector2(uv.z, uv.w)}, {GSVector4(mm.z, -mm.w, 0.5f, 1.0f), GSVector2(uv.z, uv.w)},
}; };
dev->IASetVertexBuffer(4, vertices); void* buff = NULL;
if(SUCCEEDED(dev->m_convert.vb->Lock(0, 0, &buff, D3DLOCK_DISCARD)))
{
memcpy(buff, vertices, sizeof(vertices));
dev->m_convert.vb->Unlock();
}
dev->IASetVertexBuffer(dev->m_convert.vb, sizeof(vertices[0]));
dev->IASetInputLayout(dev->m_convert.il); dev->IASetInputLayout(dev->m_convert.il);
dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP); dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
@ -556,7 +565,7 @@ void GSRendererHW9::SetupDATE(GSTexture* rt, GSTexture* ds)
// //
dev->DrawPrimitive(); dev->DrawPrimitive(countof(vertices));
// //
@ -570,6 +579,11 @@ void GSRendererHW9::UpdateFBA(GSTexture* rt)
{ {
GSDevice9* dev = (GSDevice9*)m_dev; GSDevice9* dev = (GSDevice9*)m_dev;
int w = rt->GetWidth();
int h = rt->GetHeight();
GSVector4 mm = GSVector4(-1, -1, 1, 1);
dev->BeginScene(); dev->BeginScene();
// om // om
@ -577,30 +591,44 @@ void GSRendererHW9::UpdateFBA(GSTexture* rt)
dev->OMSetDepthStencilState(&m_fba.dss, 2); dev->OMSetDepthStencilState(&m_fba.dss, 2);
dev->OMSetBlendState(&m_fba.bs, 0); dev->OMSetBlendState(&m_fba.bs, 0);
// ia
GSVertexPT1 vertices[] =
{
{GSVector4(mm.x, -mm.y, 0.5f, 1.0f), GSVector2(0, 0)},
{GSVector4(mm.z, -mm.y, 0.5f, 1.0f), GSVector2(0, 0)},
{GSVector4(mm.x, -mm.w, 0.5f, 1.0f), GSVector2(0, 0)},
{GSVector4(mm.z, -mm.w, 0.5f, 1.0f), GSVector2(0, 0)},
};
void* buff = NULL;
if(SUCCEEDED(dev->m_convert.vb->Lock(0, 0, &buff, D3DLOCK_DISCARD)))
{
memcpy(buff, vertices, sizeof(vertices));
dev->m_convert.vb->Unlock();
}
dev->IASetVertexBuffer(dev->m_convert.vb, sizeof(vertices[0]));
dev->IASetInputLayout(dev->m_convert.il);
dev->IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
// vs // vs
dev->VSSetShader(NULL, NULL, 0); dev->VSSetShader(dev->m_convert.vs, NULL, 0);
// ps // ps
dev->PSSetShader(dev->m_convert.ps[4], NULL, 0); dev->PSSetShader(dev->m_convert.ps[4], NULL, 0);
// rs
dev->RSSet(w, h);
// //
int w = rt->GetWidth(); dev->DrawPrimitive(countof(vertices));
int h = rt->GetHeight();
GSVertexP vertices[] =
{
{GSVector4(0, 0, 0, 0)},
{GSVector4(w, 0, 0, 0)},
{GSVector4(0, h, 0, 0)},
{GSVector4(w, h, 0, 0)},
};
(*dev)->SetFVF(D3DFVF_XYZRHW);
(*dev)->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(vertices[0]));
// //

View File

@ -1765,9 +1765,9 @@ bool GSC_SFEX3(const GSFrameInfo& fi, int& skip)
{ {
if(skip == 0) if(skip == 0)
{ {
if(fi.TME && fi.FBP == 0x00f00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00500 || fi.TBP0 == 0x00000) && fi.TPSM == PSM_PSMCT32) if(fi.TME && fi.FBP == 0x00500 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00f00 && fi.TPSM == PSM_PSMCT16)
{ {
skip = 4; skip = 2; // blur
} }
} }

View File

@ -37,8 +37,6 @@ bool GSTextureFX10::Create(GSDevice10* dev)
{ {
m_dev = dev; m_dev = dev;
//
VSSelector sel; VSSelector sel;
sel.bppz = 0; sel.bppz = 0;
@ -127,19 +125,7 @@ bool GSTextureFX10::SetupIA(const GSVertexHW10* vertices, int count, D3D10_PRIMI
int next = m_vb_start + m_vb_count; int next = m_vb_start + m_vb_count;
if(next + count > m_vb_max) if(next + count <= m_vb_max)
{
if(SUCCEEDED(m_vb->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&v)))
{
memcpy(v, vertices, count * sizeof(vertices[0]));
m_vb->Unmap();
}
m_vb_start = 0;
m_vb_count = count;
}
else
{ {
if(SUCCEEDED(m_vb->Map(D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&v))) if(SUCCEEDED(m_vb->Map(D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&v)))
{ {
@ -151,6 +137,18 @@ bool GSTextureFX10::SetupIA(const GSVertexHW10* vertices, int count, D3D10_PRIMI
m_vb_start = next; m_vb_start = next;
m_vb_count = count; m_vb_count = count;
} }
else
{
if(SUCCEEDED(m_vb->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&v)))
{
memcpy(v, vertices, count * sizeof(vertices[0]));
m_vb->Unmap();
}
m_vb_start = 0;
m_vb_count = count;
}
m_dev->IASetVertexBuffer(m_vb, sizeof(vertices[0])); m_dev->IASetVertexBuffer(m_vb, sizeof(vertices[0]));
m_dev->IASetInputLayout(m_il); m_dev->IASetInputLayout(m_il);

View File

@ -25,6 +25,9 @@
GSTextureFX9::GSTextureFX9() GSTextureFX9::GSTextureFX9()
: m_dev(NULL) : m_dev(NULL)
, m_vb_max(0)
, m_vb_start(0)
, m_vb_count(0)
{ {
} }
@ -86,7 +89,57 @@ GSTexture* GSTextureFX9::CreateMskFix(uint32 size, uint32 msk, uint32 fix)
bool GSTextureFX9::SetupIA(const GSVertexHW9* vertices, int count, D3DPRIMITIVETYPE prim) bool GSTextureFX9::SetupIA(const GSVertexHW9* vertices, int count, D3DPRIMITIVETYPE prim)
{ {
m_dev->IASetVertexBuffer(count, vertices); HRESULT hr;
if(max(count * 3 / 2, 10000) > m_vb_max)
{
m_vb_old = m_vb;
m_vb = NULL;
m_vb_max = max(count * 2, 10000);
m_vb_start = 0;
m_vb_count = 0;
}
if(!m_vb)
{
hr = (*m_dev)->CreateVertexBuffer(m_vb_max * sizeof(vertices[0]), D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_vb, NULL);
if(FAILED(hr)) return false;
}
GSVertexHW9* v = NULL;
int next = m_vb_start + m_vb_count;
int size = count * sizeof(vertices[0]);
if(next + count <= m_vb_max)
{
int offset = next * sizeof(vertices[0]);
if(SUCCEEDED(m_vb->Lock(offset, size, (void**)&v, D3DLOCK_NOOVERWRITE)))
{
memcpy(v, vertices, size);
m_vb->Unlock();
}
m_vb_start = next;
m_vb_count = count;
}
else
{
if(SUCCEEDED(m_vb->Lock(0, size, (void**)&v, D3DLOCK_DISCARD)))
{
memcpy(v, vertices, size);
m_vb->Unlock();
}
m_vb_start = 0;
m_vb_count = count;
}
m_dev->IASetVertexBuffer(m_vb, sizeof(vertices[0]));
m_dev->IASetInputLayout(m_il); m_dev->IASetInputLayout(m_il);
m_dev->IASetPrimitiveTopology(prim); m_dev->IASetPrimitiveTopology(prim);
@ -470,3 +523,8 @@ void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel,
m_dev->OMSetBlendState(bs, 0x010101 * bf); m_dev->OMSetBlendState(bs, 0x010101 * bf);
} }
void GSTextureFX9::Draw()
{
m_dev->DrawPrimitive(m_vb_count, m_vb_start);
}

View File

@ -155,6 +155,12 @@ private:
hash_map<uint32, Direct3DSamplerState9* > m_ps_ss; hash_map<uint32, Direct3DSamplerState9* > m_ps_ss;
hash_map<uint32, Direct3DDepthStencilState9* > m_om_dss; hash_map<uint32, Direct3DDepthStencilState9* > m_om_dss;
hash_map<uint32, Direct3DBlendState9* > m_om_bs; hash_map<uint32, Direct3DBlendState9* > m_om_bs;
CComPtr<IDirect3DVertexBuffer9> m_vb, m_vb_old;
int m_vb_max;
int m_vb_start;
int m_vb_count;
hash_map<uint32, GSTexture*> m_mskfix; hash_map<uint32, GSTexture*> m_mskfix;
GSTexture* CreateMskFix(uint32 size, uint32 msk, uint32 fix); GSTexture* CreateMskFix(uint32 size, uint32 msk, uint32 fix);
@ -171,4 +177,5 @@ public:
void SetupRS(int w, int h, const GSVector4i& scissor); void SetupRS(int w, int h, const GSVector4i& scissor);
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 bf, GSTexture* rt, GSTexture* ds); void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 bf, GSTexture* rt, GSTexture* ds);
void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 bf); void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 bf);
void Draw();
}; };

View File

@ -171,6 +171,10 @@ public:
} }
GSVector4i runion(const GSVector4i& a) const GSVector4i runion(const GSVector4i& a) const
{
int i = (upl64(a) < uph64(a)).mask();
if(i == 0xffff)
{ {
#if _M_SSE >= 0x401 #if _M_SSE >= 0x401
@ -183,6 +187,19 @@ public:
#endif #endif
} }
if((i & 0x00ff) == 0x00ff)
{
return *this;
}
if((i & 0xff00) == 0xff00)
{
return a;
}
return GSVector4i::zero();
}
GSVector4i rintersect(const GSVector4i& a) const GSVector4i rintersect(const GSVector4i& a) const
{ {
return sat_i32(a); return sat_i32(a);

View File

@ -76,7 +76,7 @@ float4 ps_crt(PS_INPUT input, uint i)
float4(1, 1, 1, 0) float4(1, 1, 1, 0)
}; };
return Texture.Sample(Sampler, input.t) * saturate(mask[i] + 0.25f); return Texture.Sample(Sampler, input.t) * saturate(mask[i] + 0.5f);
} }
float4 ps_main5(PS_INPUT input) : SV_Target0 // triangular float4 ps_main5(PS_INPUT input) : SV_Target0 // triangular