mirror of https://github.com/PCSX2/pcsx2.git
GSdx: little code cleanup
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1591 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
8b288e8917
commit
3f4f3db3e6
|
@ -31,6 +31,7 @@ GSDevice::GSDevice()
|
||||||
, m_blend(NULL)
|
, m_blend(NULL)
|
||||||
, m_1x1(NULL)
|
, m_1x1(NULL)
|
||||||
{
|
{
|
||||||
|
memset(&m_vertices, 0, sizeof(m_vertices));
|
||||||
}
|
}
|
||||||
|
|
||||||
GSDevice::~GSDevice()
|
GSDevice::~GSDevice()
|
||||||
|
@ -121,6 +122,12 @@ GSTexture* GSDevice::Fetch(int type, int w, int h, int format)
|
||||||
return Create(type, w, h, format);
|
return Create(type, w, h, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSDevice::EndScene()
|
||||||
|
{
|
||||||
|
m_vertices.start += m_vertices.count;
|
||||||
|
m_vertices.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void GSDevice::Recycle(GSTexture* t)
|
void GSDevice::Recycle(GSTexture* t)
|
||||||
{
|
{
|
||||||
if(t)
|
if(t)
|
||||||
|
|
|
@ -63,6 +63,7 @@ protected:
|
||||||
GSTexture* m_1x1;
|
GSTexture* m_1x1;
|
||||||
GSTexture* m_current;
|
GSTexture* m_current;
|
||||||
struct {D3D_FEATURE_LEVEL level; string model, vs, gs, ps;} m_shader;
|
struct {D3D_FEATURE_LEVEL level; string model, vs, gs, ps;} m_shader;
|
||||||
|
struct {size_t stride, start, count, limit;} m_vertices;
|
||||||
|
|
||||||
virtual GSTexture* Create(int type, int w, int h, int format) = 0;
|
virtual GSTexture* Create(int type, int w, int h, int format) = 0;
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ public:
|
||||||
|
|
||||||
virtual void BeginScene() {}
|
virtual void BeginScene() {}
|
||||||
virtual void DrawPrimitive() {};
|
virtual void DrawPrimitive() {};
|
||||||
virtual void EndScene() {}
|
virtual void EndScene();
|
||||||
|
|
||||||
virtual void ClearRenderTarget(GSTexture* t, const GSVector4& c) {}
|
virtual void ClearRenderTarget(GSTexture* t, const GSVector4& c) {}
|
||||||
virtual void ClearRenderTarget(GSTexture* t, uint32 c) {}
|
virtual void ClearRenderTarget(GSTexture* t, uint32 c) {}
|
||||||
|
|
|
@ -25,31 +25,11 @@
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
GSDevice10::GSDevice10()
|
GSDevice10::GSDevice10()
|
||||||
: m_vb(NULL)
|
|
||||||
, m_vb_stride(0)
|
|
||||||
, m_layout(NULL)
|
|
||||||
, m_topology(D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED)
|
|
||||||
, m_vs(NULL)
|
|
||||||
, m_vs_cb(NULL)
|
|
||||||
, m_gs(NULL)
|
|
||||||
, m_ps(NULL)
|
|
||||||
, m_ps_cb(NULL)
|
|
||||||
, m_scissor(0, 0, 0, 0)
|
|
||||||
, m_viewport(0, 0)
|
|
||||||
, m_dss(NULL)
|
|
||||||
, m_sref(0)
|
|
||||||
, m_bs(NULL)
|
|
||||||
, m_bf(-1)
|
|
||||||
, m_rtv(NULL)
|
|
||||||
, m_dsv(NULL)
|
|
||||||
{
|
{
|
||||||
memset(m_ps_srv, 0, sizeof(m_ps_srv));
|
memset(&m_state, 0, sizeof(m_state));
|
||||||
memset(m_ps_ss, 0, sizeof(m_ps_ss));
|
|
||||||
|
|
||||||
m_vertices.stride = 0;
|
m_state.topology = D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||||
m_vertices.start = 0;
|
m_state.bf = -1;
|
||||||
m_vertices.count = 0;
|
|
||||||
m_vertices.limit = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GSDevice10::~GSDevice10()
|
GSDevice10::~GSDevice10()
|
||||||
|
@ -258,27 +238,11 @@ void GSDevice10::Flip(bool limit)
|
||||||
m_swapchain->Present(m_vsync && limit ? 1 : 0, 0);
|
m_swapchain->Present(m_vsync && limit ? 1 : 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice10::BeginScene()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSDevice10::DrawPrimitive()
|
void GSDevice10::DrawPrimitive()
|
||||||
{
|
{
|
||||||
m_dev->Draw(m_vertices.count, m_vertices.start);
|
m_dev->Draw(m_vertices.count, m_vertices.start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice10::EndScene()
|
|
||||||
{
|
|
||||||
//PSSetShaderResources(NULL, NULL);
|
|
||||||
|
|
||||||
// not clearing the rt/ds gives a little fps boost in complex games (5-10%)
|
|
||||||
|
|
||||||
// OMSetRenderTargets(NULL, NULL);
|
|
||||||
|
|
||||||
m_vertices.start += m_vertices.count;
|
|
||||||
m_vertices.count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSDevice10::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
void GSDevice10::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||||
{
|
{
|
||||||
m_dev->ClearRenderTargetView(*(GSTexture10*)t, c.v);
|
m_dev->ClearRenderTargetView(*(GSTexture10*)t, c.v);
|
||||||
|
@ -483,6 +447,8 @@ void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
|
||||||
//
|
//
|
||||||
|
|
||||||
EndScene();
|
EndScene();
|
||||||
|
|
||||||
|
PSSetShaderResources(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice10::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
|
void GSDevice10::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
|
||||||
|
@ -525,14 +491,15 @@ void GSDevice10::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
|
||||||
|
|
||||||
if(count * stride > m_vertices.limit * m_vertices.stride)
|
if(count * stride > m_vertices.limit * m_vertices.stride)
|
||||||
{
|
{
|
||||||
m_vertices.vb_old = m_vertices.vb;
|
m_vb_old = m_vb;
|
||||||
m_vertices.vb = NULL;
|
m_vb = NULL;
|
||||||
|
|
||||||
m_vertices.start = 0;
|
m_vertices.start = 0;
|
||||||
m_vertices.count = 0;
|
m_vertices.count = 0;
|
||||||
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_vertices.vb == NULL)
|
if(m_vb == NULL)
|
||||||
{
|
{
|
||||||
D3D10_BUFFER_DESC bd;
|
D3D10_BUFFER_DESC bd;
|
||||||
|
|
||||||
|
@ -545,7 +512,7 @@ void GSDevice10::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
hr = m_dev->CreateBuffer(&bd, NULL, &m_vertices.vb);
|
hr = m_dev->CreateBuffer(&bd, NULL, &m_vb);
|
||||||
|
|
||||||
if(FAILED(hr)) return;
|
if(FAILED(hr)) return;
|
||||||
}
|
}
|
||||||
|
@ -561,25 +528,25 @@ void GSDevice10::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
|
||||||
|
|
||||||
void* v = NULL;
|
void* v = NULL;
|
||||||
|
|
||||||
if(SUCCEEDED(m_vertices.vb->Map(type, 0, &v)))
|
if(SUCCEEDED(m_vb->Map(type, 0, &v)))
|
||||||
{
|
{
|
||||||
GSVector4i::storent((uint8*)v + m_vertices.start * stride, vertices, count * stride);
|
GSVector4i::storent((uint8*)v + m_vertices.start * stride, vertices, count * stride);
|
||||||
|
|
||||||
m_vertices.vb->Unmap();
|
m_vb->Unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vertices.count = count;
|
m_vertices.count = count;
|
||||||
m_vertices.stride = stride;
|
m_vertices.stride = stride;
|
||||||
|
|
||||||
IASetVertexBuffer(m_vertices.vb, stride);
|
IASetVertexBuffer(m_vb, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice10::IASetVertexBuffer(ID3D10Buffer* vb, size_t stride)
|
void GSDevice10::IASetVertexBuffer(ID3D10Buffer* vb, size_t stride)
|
||||||
{
|
{
|
||||||
if(m_vb != vb || m_vb_stride != stride)
|
if(m_state.vb != vb || m_state.vb_stride != stride)
|
||||||
{
|
{
|
||||||
m_vb = vb;
|
m_state.vb = vb;
|
||||||
m_vb_stride = stride;
|
m_state.vb_stride = stride;
|
||||||
|
|
||||||
uint32 offset = 0;
|
uint32 offset = 0;
|
||||||
|
|
||||||
|
@ -589,9 +556,9 @@ void GSDevice10::IASetVertexBuffer(ID3D10Buffer* vb, size_t stride)
|
||||||
|
|
||||||
void GSDevice10::IASetInputLayout(ID3D10InputLayout* layout)
|
void GSDevice10::IASetInputLayout(ID3D10InputLayout* layout)
|
||||||
{
|
{
|
||||||
if(m_layout != layout)
|
if(m_state.layout != layout)
|
||||||
{
|
{
|
||||||
m_layout = layout;
|
m_state.layout = layout;
|
||||||
|
|
||||||
m_dev->IASetInputLayout(layout);
|
m_dev->IASetInputLayout(layout);
|
||||||
}
|
}
|
||||||
|
@ -599,9 +566,9 @@ void GSDevice10::IASetInputLayout(ID3D10InputLayout* layout)
|
||||||
|
|
||||||
void GSDevice10::IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY topology)
|
void GSDevice10::IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY topology)
|
||||||
{
|
{
|
||||||
if(m_topology != topology)
|
if(m_state.topology != topology)
|
||||||
{
|
{
|
||||||
m_topology = topology;
|
m_state.topology = topology;
|
||||||
|
|
||||||
m_dev->IASetPrimitiveTopology(topology);
|
m_dev->IASetPrimitiveTopology(topology);
|
||||||
}
|
}
|
||||||
|
@ -609,16 +576,16 @@ void GSDevice10::IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY topology)
|
||||||
|
|
||||||
void GSDevice10::VSSetShader(ID3D10VertexShader* vs, ID3D10Buffer* vs_cb)
|
void GSDevice10::VSSetShader(ID3D10VertexShader* vs, ID3D10Buffer* vs_cb)
|
||||||
{
|
{
|
||||||
if(m_vs != vs)
|
if(m_state.vs != vs)
|
||||||
{
|
{
|
||||||
m_vs = vs;
|
m_state.vs = vs;
|
||||||
|
|
||||||
m_dev->VSSetShader(vs);
|
m_dev->VSSetShader(vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_vs_cb != vs_cb)
|
if(m_state.vs_cb != vs_cb)
|
||||||
{
|
{
|
||||||
m_vs_cb = vs_cb;
|
m_state.vs_cb = vs_cb;
|
||||||
|
|
||||||
m_dev->VSSetConstantBuffers(0, 1, &vs_cb);
|
m_dev->VSSetConstantBuffers(0, 1, &vs_cb);
|
||||||
}
|
}
|
||||||
|
@ -626,9 +593,9 @@ void GSDevice10::VSSetShader(ID3D10VertexShader* vs, ID3D10Buffer* vs_cb)
|
||||||
|
|
||||||
void GSDevice10::GSSetShader(ID3D10GeometryShader* gs)
|
void GSDevice10::GSSetShader(ID3D10GeometryShader* gs)
|
||||||
{
|
{
|
||||||
if(m_gs != gs)
|
if(m_state.gs != gs)
|
||||||
{
|
{
|
||||||
m_gs = gs;
|
m_state.gs = gs;
|
||||||
|
|
||||||
m_dev->GSSetShader(gs);
|
m_dev->GSSetShader(gs);
|
||||||
}
|
}
|
||||||
|
@ -642,10 +609,10 @@ void GSDevice10::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
if(sr0) srv0 = *(GSTexture10*)sr0;
|
if(sr0) srv0 = *(GSTexture10*)sr0;
|
||||||
if(sr1) srv1 = *(GSTexture10*)sr1;
|
if(sr1) srv1 = *(GSTexture10*)sr1;
|
||||||
|
|
||||||
if(m_ps_srv[0] != srv0 || m_ps_srv[1] != srv1)
|
if(m_state.ps_srv[0] != srv0 || m_state.ps_srv[1] != srv1)
|
||||||
{
|
{
|
||||||
m_ps_srv[0] = srv0;
|
m_state.ps_srv[0] = srv0;
|
||||||
m_ps_srv[1] = srv1;
|
m_state.ps_srv[1] = srv1;
|
||||||
|
|
||||||
ID3D10ShaderResourceView* srvs[] = {srv0, srv1};
|
ID3D10ShaderResourceView* srvs[] = {srv0, srv1};
|
||||||
|
|
||||||
|
@ -655,16 +622,16 @@ void GSDevice10::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
|
|
||||||
void GSDevice10::PSSetShader(ID3D10PixelShader* ps, ID3D10Buffer* ps_cb)
|
void GSDevice10::PSSetShader(ID3D10PixelShader* ps, ID3D10Buffer* ps_cb)
|
||||||
{
|
{
|
||||||
if(m_ps != ps)
|
if(m_state.ps != ps)
|
||||||
{
|
{
|
||||||
m_ps = ps;
|
m_state.ps = ps;
|
||||||
|
|
||||||
m_dev->PSSetShader(ps);
|
m_dev->PSSetShader(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_ps_cb != ps_cb)
|
if(m_state.ps_cb != ps_cb)
|
||||||
{
|
{
|
||||||
m_ps_cb = ps_cb;
|
m_state.ps_cb = ps_cb;
|
||||||
|
|
||||||
m_dev->PSSetConstantBuffers(0, 1, &ps_cb);
|
m_dev->PSSetConstantBuffers(0, 1, &ps_cb);
|
||||||
}
|
}
|
||||||
|
@ -672,10 +639,10 @@ void GSDevice10::PSSetShader(ID3D10PixelShader* ps, ID3D10Buffer* ps_cb)
|
||||||
|
|
||||||
void GSDevice10::PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState* ss1)
|
void GSDevice10::PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState* ss1)
|
||||||
{
|
{
|
||||||
if(m_ps_ss[0] != ss0 || m_ps_ss[1] != ss1)
|
if(m_state.ps_ss[0] != ss0 || m_state.ps_ss[1] != ss1)
|
||||||
{
|
{
|
||||||
m_ps_ss[0] = ss0;
|
m_state.ps_ss[0] = ss0;
|
||||||
m_ps_ss[1] = ss1;
|
m_state.ps_ss[1] = ss1;
|
||||||
|
|
||||||
ID3D10SamplerState* sss[] = {ss0, ss1};
|
ID3D10SamplerState* sss[] = {ss0, ss1};
|
||||||
|
|
||||||
|
@ -685,10 +652,10 @@ void GSDevice10::PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState*
|
||||||
|
|
||||||
void GSDevice10::OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref)
|
void GSDevice10::OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref)
|
||||||
{
|
{
|
||||||
if(m_dss != dss || m_sref != sref)
|
if(m_state.dss != dss || m_state.sref != sref)
|
||||||
{
|
{
|
||||||
m_dss = dss;
|
m_state.dss = dss;
|
||||||
m_sref = sref;
|
m_state.sref = sref;
|
||||||
|
|
||||||
m_dev->OMSetDepthStencilState(dss, sref);
|
m_dev->OMSetDepthStencilState(dss, sref);
|
||||||
}
|
}
|
||||||
|
@ -696,10 +663,10 @@ void GSDevice10::OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref
|
||||||
|
|
||||||
void GSDevice10::OMSetBlendState(ID3D10BlendState* bs, float bf)
|
void GSDevice10::OMSetBlendState(ID3D10BlendState* bs, float bf)
|
||||||
{
|
{
|
||||||
if(m_bs != bs || m_bf != bf)
|
if(m_state.bs != bs || m_state.bf != bf)
|
||||||
{
|
{
|
||||||
m_bs = bs;
|
m_state.bs = bs;
|
||||||
m_bf = bf;
|
m_state.bf = bf;
|
||||||
|
|
||||||
float BlendFactor[] = {bf, bf, bf, 0};
|
float BlendFactor[] = {bf, bf, bf, 0};
|
||||||
|
|
||||||
|
@ -715,17 +682,17 @@ void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
|
||||||
if(rt) rtv = *(GSTexture10*)rt;
|
if(rt) rtv = *(GSTexture10*)rt;
|
||||||
if(ds) dsv = *(GSTexture10*)ds;
|
if(ds) dsv = *(GSTexture10*)ds;
|
||||||
|
|
||||||
if(m_rtv != rtv || m_dsv != dsv)
|
if(m_state.rtv != rtv || m_state.dsv != dsv)
|
||||||
{
|
{
|
||||||
m_rtv = rtv;
|
m_state.rtv = rtv;
|
||||||
m_dsv = dsv;
|
m_state.dsv = dsv;
|
||||||
|
|
||||||
m_dev->OMSetRenderTargets(1, &rtv, dsv);
|
m_dev->OMSetRenderTargets(1, &rtv, dsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_viewport != rt->m_size)
|
if(m_state.viewport != rt->m_size)
|
||||||
{
|
{
|
||||||
m_viewport = rt->m_size;
|
m_state.viewport = rt->m_size;
|
||||||
|
|
||||||
D3D10_VIEWPORT vp;
|
D3D10_VIEWPORT vp;
|
||||||
|
|
||||||
|
@ -743,9 +710,9 @@ void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
|
||||||
|
|
||||||
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
|
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
|
||||||
|
|
||||||
if(!m_scissor.eq(r))
|
if(!m_state.scissor.eq(r))
|
||||||
{
|
{
|
||||||
m_scissor = r;
|
m_state.scissor = r;
|
||||||
|
|
||||||
m_dev->RSSetScissorRects(1, r);
|
m_dev->RSSetScissorRects(1, r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,28 +26,6 @@
|
||||||
|
|
||||||
class GSDevice10 : public GSDevice
|
class GSDevice10 : public GSDevice
|
||||||
{
|
{
|
||||||
ID3D10Buffer* m_vb;
|
|
||||||
size_t m_vb_stride;
|
|
||||||
ID3D10InputLayout* m_layout;
|
|
||||||
D3D10_PRIMITIVE_TOPOLOGY m_topology;
|
|
||||||
ID3D10VertexShader* m_vs;
|
|
||||||
ID3D10Buffer* m_vs_cb;
|
|
||||||
ID3D10GeometryShader* m_gs;
|
|
||||||
ID3D10ShaderResourceView* m_ps_srv[2];
|
|
||||||
ID3D10PixelShader* m_ps;
|
|
||||||
ID3D10Buffer* m_ps_cb;
|
|
||||||
ID3D10SamplerState* m_ps_ss[2];
|
|
||||||
GSVector2i m_viewport;
|
|
||||||
GSVector4i m_scissor;
|
|
||||||
ID3D10DepthStencilState* m_dss;
|
|
||||||
uint8 m_sref;
|
|
||||||
ID3D10BlendState* m_bs;
|
|
||||||
float m_bf;
|
|
||||||
ID3D10RenderTargetView* m_rtv;
|
|
||||||
ID3D10DepthStencilView* m_dsv;
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
GSTexture* Create(int type, int w, int h, int format);
|
GSTexture* Create(int type, int w, int h, int format);
|
||||||
|
|
||||||
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
|
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
|
||||||
|
@ -57,12 +35,31 @@ class GSDevice10 : public GSDevice
|
||||||
|
|
||||||
CComPtr<ID3D10Device1> m_dev;
|
CComPtr<ID3D10Device1> m_dev;
|
||||||
CComPtr<IDXGISwapChain> m_swapchain;
|
CComPtr<IDXGISwapChain> m_swapchain;
|
||||||
|
CComPtr<ID3D10Buffer> m_vb;
|
||||||
|
CComPtr<ID3D10Buffer> m_vb_old;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
CComPtr<ID3D10Buffer> vb, vb_old;
|
ID3D10Buffer* vb;
|
||||||
size_t stride, start, count, limit;
|
size_t vb_stride;
|
||||||
} m_vertices;
|
ID3D10InputLayout* layout;
|
||||||
|
D3D10_PRIMITIVE_TOPOLOGY topology;
|
||||||
|
ID3D10VertexShader* vs;
|
||||||
|
ID3D10Buffer* vs_cb;
|
||||||
|
ID3D10GeometryShader* gs;
|
||||||
|
ID3D10ShaderResourceView* ps_srv[2];
|
||||||
|
ID3D10PixelShader* ps;
|
||||||
|
ID3D10Buffer* ps_cb;
|
||||||
|
ID3D10SamplerState* ps_ss[2];
|
||||||
|
GSVector2i viewport;
|
||||||
|
GSVector4i scissor;
|
||||||
|
ID3D10DepthStencilState* dss;
|
||||||
|
uint8 sref;
|
||||||
|
ID3D10BlendState* bs;
|
||||||
|
float bf;
|
||||||
|
ID3D10RenderTargetView* rtv;
|
||||||
|
ID3D10DepthStencilView* dsv;
|
||||||
|
} m_state;
|
||||||
|
|
||||||
public: // TODO
|
public: // TODO
|
||||||
CComPtr<ID3D10RasterizerState> m_rs;
|
CComPtr<ID3D10RasterizerState> m_rs;
|
||||||
|
@ -99,9 +96,7 @@ public:
|
||||||
bool Reset(int w, int h, int mode);
|
bool Reset(int w, int h, int mode);
|
||||||
void Flip(bool limit);
|
void Flip(bool limit);
|
||||||
|
|
||||||
void BeginScene();
|
|
||||||
void DrawPrimitive();
|
void DrawPrimitive();
|
||||||
void EndScene();
|
|
||||||
|
|
||||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
|
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
|
||||||
void ClearRenderTarget(GSTexture* t, uint32 c);
|
void ClearRenderTarget(GSTexture* t, uint32 c);
|
||||||
|
|
|
@ -25,31 +25,11 @@
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
GSDevice11::GSDevice11()
|
GSDevice11::GSDevice11()
|
||||||
: m_vb(NULL)
|
|
||||||
, m_vb_stride(0)
|
|
||||||
, m_layout(NULL)
|
|
||||||
, m_topology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED)
|
|
||||||
, m_vs(NULL)
|
|
||||||
, m_vs_cb(NULL)
|
|
||||||
, m_gs(NULL)
|
|
||||||
, m_ps(NULL)
|
|
||||||
, m_ps_cb(NULL)
|
|
||||||
, m_scissor(0, 0, 0, 0)
|
|
||||||
, m_viewport(0, 0)
|
|
||||||
, m_dss(NULL)
|
|
||||||
, m_sref(0)
|
|
||||||
, m_bs(NULL)
|
|
||||||
, m_bf(-1)
|
|
||||||
, m_rtv(NULL)
|
|
||||||
, m_dsv(NULL)
|
|
||||||
{
|
{
|
||||||
memset(m_ps_srv, 0, sizeof(m_ps_srv));
|
memset(&m_state, 0, sizeof(m_state));
|
||||||
memset(m_ps_ss, 0, sizeof(m_ps_ss));
|
|
||||||
|
|
||||||
m_vertices.stride = 0;
|
m_state.topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||||
m_vertices.start = 0;
|
m_state.bf = -1;
|
||||||
m_vertices.count = 0;
|
|
||||||
m_vertices.limit = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GSDevice11::~GSDevice11()
|
GSDevice11::~GSDevice11()
|
||||||
|
@ -257,27 +237,11 @@ void GSDevice11::Flip(bool limit)
|
||||||
m_swapchain->Present(m_vsync && limit ? 1 : 0, 0);
|
m_swapchain->Present(m_vsync && limit ? 1 : 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::BeginScene()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSDevice11::DrawPrimitive()
|
void GSDevice11::DrawPrimitive()
|
||||||
{
|
{
|
||||||
m_ctx->Draw(m_vertices.count, m_vertices.start);
|
m_ctx->Draw(m_vertices.count, m_vertices.start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::EndScene()
|
|
||||||
{
|
|
||||||
//PSSetShaderResources(NULL, NULL);
|
|
||||||
|
|
||||||
// not clearing the rt/ds gives a little fps boost in complex games (5-10%)
|
|
||||||
|
|
||||||
// OMSetRenderTargets(NULL, NULL);
|
|
||||||
|
|
||||||
m_vertices.start += m_vertices.count;
|
|
||||||
m_vertices.count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSDevice11::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
void GSDevice11::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||||
{
|
{
|
||||||
m_ctx->ClearRenderTargetView(*(GSTexture11*)t, c.v);
|
m_ctx->ClearRenderTargetView(*(GSTexture11*)t, c.v);
|
||||||
|
@ -482,6 +446,8 @@ void GSDevice11::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
|
||||||
//
|
//
|
||||||
|
|
||||||
EndScene();
|
EndScene();
|
||||||
|
|
||||||
|
PSSetShaderResources(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
|
void GSDevice11::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
|
||||||
|
@ -524,14 +490,15 @@ void GSDevice11::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
|
||||||
|
|
||||||
if(count * stride > m_vertices.limit * m_vertices.stride)
|
if(count * stride > m_vertices.limit * m_vertices.stride)
|
||||||
{
|
{
|
||||||
m_vertices.vb_old = m_vertices.vb;
|
m_vb_old = m_vb;
|
||||||
m_vertices.vb = NULL;
|
m_vb = NULL;
|
||||||
|
|
||||||
m_vertices.start = 0;
|
m_vertices.start = 0;
|
||||||
m_vertices.count = 0;
|
m_vertices.count = 0;
|
||||||
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_vertices.vb == NULL)
|
if(m_vb == NULL)
|
||||||
{
|
{
|
||||||
D3D11_BUFFER_DESC bd;
|
D3D11_BUFFER_DESC bd;
|
||||||
|
|
||||||
|
@ -544,7 +511,7 @@ void GSDevice11::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
hr = m_dev->CreateBuffer(&bd, NULL, &m_vertices.vb);
|
hr = m_dev->CreateBuffer(&bd, NULL, &m_vb);
|
||||||
|
|
||||||
if(FAILED(hr)) return;
|
if(FAILED(hr)) return;
|
||||||
}
|
}
|
||||||
|
@ -560,25 +527,25 @@ void GSDevice11::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE m;
|
D3D11_MAPPED_SUBRESOURCE m;
|
||||||
|
|
||||||
if(SUCCEEDED(m_ctx->Map(m_vertices.vb, 0, type, 0, &m)))
|
if(SUCCEEDED(m_ctx->Map(m_vb, 0, type, 0, &m)))
|
||||||
{
|
{
|
||||||
GSVector4i::storent((uint8*)m.pData + m_vertices.start * stride, vertices, count * stride);
|
GSVector4i::storent((uint8*)m.pData + m_vertices.start * stride, vertices, count * stride);
|
||||||
|
|
||||||
m_ctx->Unmap(m_vertices.vb, 0);
|
m_ctx->Unmap(m_vb, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vertices.count = count;
|
m_vertices.count = count;
|
||||||
m_vertices.stride = stride;
|
m_vertices.stride = stride;
|
||||||
|
|
||||||
IASetVertexBuffer(m_vertices.vb, stride);
|
IASetVertexBuffer(m_vb, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::IASetVertexBuffer(ID3D11Buffer* vb, size_t stride)
|
void GSDevice11::IASetVertexBuffer(ID3D11Buffer* vb, size_t stride)
|
||||||
{
|
{
|
||||||
if(m_vb != vb || m_vb_stride != stride)
|
if(m_state.vb != vb || m_state.vb_stride != stride)
|
||||||
{
|
{
|
||||||
m_vb = vb;
|
m_state.vb = vb;
|
||||||
m_vb_stride = stride;
|
m_state.vb_stride = stride;
|
||||||
|
|
||||||
uint32 offset = 0;
|
uint32 offset = 0;
|
||||||
|
|
||||||
|
@ -588,9 +555,9 @@ void GSDevice11::IASetVertexBuffer(ID3D11Buffer* vb, size_t stride)
|
||||||
|
|
||||||
void GSDevice11::IASetInputLayout(ID3D11InputLayout* layout)
|
void GSDevice11::IASetInputLayout(ID3D11InputLayout* layout)
|
||||||
{
|
{
|
||||||
if(m_layout != layout)
|
if(m_state.layout != layout)
|
||||||
{
|
{
|
||||||
m_layout = layout;
|
m_state.layout = layout;
|
||||||
|
|
||||||
m_ctx->IASetInputLayout(layout);
|
m_ctx->IASetInputLayout(layout);
|
||||||
}
|
}
|
||||||
|
@ -598,9 +565,9 @@ void GSDevice11::IASetInputLayout(ID3D11InputLayout* layout)
|
||||||
|
|
||||||
void GSDevice11::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology)
|
void GSDevice11::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology)
|
||||||
{
|
{
|
||||||
if(m_topology != topology)
|
if(m_state.topology != topology)
|
||||||
{
|
{
|
||||||
m_topology = topology;
|
m_state.topology = topology;
|
||||||
|
|
||||||
m_ctx->IASetPrimitiveTopology(topology);
|
m_ctx->IASetPrimitiveTopology(topology);
|
||||||
}
|
}
|
||||||
|
@ -608,16 +575,16 @@ void GSDevice11::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology)
|
||||||
|
|
||||||
void GSDevice11::VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb)
|
void GSDevice11::VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb)
|
||||||
{
|
{
|
||||||
if(m_vs != vs)
|
if(m_state.vs != vs)
|
||||||
{
|
{
|
||||||
m_vs = vs;
|
m_state.vs = vs;
|
||||||
|
|
||||||
m_ctx->VSSetShader(vs, NULL, 0);
|
m_ctx->VSSetShader(vs, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_vs_cb != vs_cb)
|
if(m_state.vs_cb != vs_cb)
|
||||||
{
|
{
|
||||||
m_vs_cb = vs_cb;
|
m_state.vs_cb = vs_cb;
|
||||||
|
|
||||||
m_ctx->VSSetConstantBuffers(0, 1, &vs_cb);
|
m_ctx->VSSetConstantBuffers(0, 1, &vs_cb);
|
||||||
}
|
}
|
||||||
|
@ -625,11 +592,11 @@ void GSDevice11::VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb)
|
||||||
|
|
||||||
void GSDevice11::GSSetShader(ID3D11GeometryShader* gs)
|
void GSDevice11::GSSetShader(ID3D11GeometryShader* gs)
|
||||||
{
|
{
|
||||||
if(m_gs != gs)
|
if(m_state.gs != gs)
|
||||||
{
|
{
|
||||||
m_ctx->GSSetShader(gs, NULL, 0);
|
m_state.gs = gs;
|
||||||
|
|
||||||
m_gs = gs;
|
m_ctx->GSSetShader(gs, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,10 +608,10 @@ void GSDevice11::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
if(sr0) srv0 = *(GSTexture11*)sr0;
|
if(sr0) srv0 = *(GSTexture11*)sr0;
|
||||||
if(sr1) srv1 = *(GSTexture11*)sr1;
|
if(sr1) srv1 = *(GSTexture11*)sr1;
|
||||||
|
|
||||||
if(m_ps_srv[0] != srv0 || m_ps_srv[1] != srv1)
|
if(m_state.ps_srv[0] != srv0 || m_state.ps_srv[1] != srv1)
|
||||||
{
|
{
|
||||||
m_ps_srv[0] = srv0;
|
m_state.ps_srv[0] = srv0;
|
||||||
m_ps_srv[1] = srv1;
|
m_state.ps_srv[1] = srv1;
|
||||||
|
|
||||||
ID3D11ShaderResourceView* srvs[] = {srv0, srv1};
|
ID3D11ShaderResourceView* srvs[] = {srv0, srv1};
|
||||||
|
|
||||||
|
@ -654,16 +621,16 @@ void GSDevice11::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
|
|
||||||
void GSDevice11::PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb)
|
void GSDevice11::PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb)
|
||||||
{
|
{
|
||||||
if(m_ps != ps)
|
if(m_state.ps != ps)
|
||||||
{
|
{
|
||||||
m_ps = ps;
|
m_state.ps = ps;
|
||||||
|
|
||||||
m_ctx->PSSetShader(ps, NULL, 0);
|
m_ctx->PSSetShader(ps, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_ps_cb != ps_cb)
|
if(m_state.ps_cb != ps_cb)
|
||||||
{
|
{
|
||||||
m_ps_cb = ps_cb;
|
m_state.ps_cb = ps_cb;
|
||||||
|
|
||||||
m_ctx->PSSetConstantBuffers(0, 1, &ps_cb);
|
m_ctx->PSSetConstantBuffers(0, 1, &ps_cb);
|
||||||
}
|
}
|
||||||
|
@ -671,10 +638,10 @@ void GSDevice11::PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb)
|
||||||
|
|
||||||
void GSDevice11::PSSetSamplerState(ID3D11SamplerState* ss0, ID3D11SamplerState* ss1)
|
void GSDevice11::PSSetSamplerState(ID3D11SamplerState* ss0, ID3D11SamplerState* ss1)
|
||||||
{
|
{
|
||||||
if(m_ps_ss[0] != ss0 || m_ps_ss[1] != ss1)
|
if(m_state.ps_ss[0] != ss0 || m_state.ps_ss[1] != ss1)
|
||||||
{
|
{
|
||||||
m_ps_ss[0] = ss0;
|
m_state.ps_ss[0] = ss0;
|
||||||
m_ps_ss[1] = ss1;
|
m_state.ps_ss[1] = ss1;
|
||||||
|
|
||||||
ID3D11SamplerState* sss[] = {ss0, ss1};
|
ID3D11SamplerState* sss[] = {ss0, ss1};
|
||||||
|
|
||||||
|
@ -684,25 +651,25 @@ void GSDevice11::PSSetSamplerState(ID3D11SamplerState* ss0, ID3D11SamplerState*
|
||||||
|
|
||||||
void GSDevice11::OMSetDepthStencilState(ID3D11DepthStencilState* dss, uint8 sref)
|
void GSDevice11::OMSetDepthStencilState(ID3D11DepthStencilState* dss, uint8 sref)
|
||||||
{
|
{
|
||||||
if(m_dss != dss || m_sref != sref)
|
if(m_state.dss != dss || m_state.sref != sref)
|
||||||
{
|
{
|
||||||
m_ctx->OMSetDepthStencilState(dss, sref);
|
m_state.dss = dss;
|
||||||
|
m_state.sref = sref;
|
||||||
|
|
||||||
m_dss = dss;
|
m_ctx->OMSetDepthStencilState(dss, sref);
|
||||||
m_sref = sref;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice11::OMSetBlendState(ID3D11BlendState* bs, float bf)
|
void GSDevice11::OMSetBlendState(ID3D11BlendState* bs, float bf)
|
||||||
{
|
{
|
||||||
if(m_bs != bs || m_bf != bf)
|
if(m_state.bs != bs || m_state.bf != bf)
|
||||||
{
|
{
|
||||||
|
m_state.bs = bs;
|
||||||
|
m_state.bf = bf;
|
||||||
|
|
||||||
float BlendFactor[] = {bf, bf, bf, 0};
|
float BlendFactor[] = {bf, bf, bf, 0};
|
||||||
|
|
||||||
m_ctx->OMSetBlendState(bs, BlendFactor, 0xffffffff);
|
m_ctx->OMSetBlendState(bs, BlendFactor, 0xffffffff);
|
||||||
|
|
||||||
m_bs = bs;
|
|
||||||
m_bf = bf;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,17 +681,17 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
|
||||||
if(rt) rtv = *(GSTexture11*)rt;
|
if(rt) rtv = *(GSTexture11*)rt;
|
||||||
if(ds) dsv = *(GSTexture11*)ds;
|
if(ds) dsv = *(GSTexture11*)ds;
|
||||||
|
|
||||||
if(m_rtv != rtv || m_dsv != dsv)
|
if(m_state.rtv != rtv || m_state.dsv != dsv)
|
||||||
{
|
{
|
||||||
m_rtv = rtv;
|
m_state.rtv = rtv;
|
||||||
m_dsv = dsv;
|
m_state.dsv = dsv;
|
||||||
|
|
||||||
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
|
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_viewport != rt->m_size)
|
if(m_state.viewport != rt->m_size)
|
||||||
{
|
{
|
||||||
m_viewport = rt->m_size;
|
m_state.viewport = rt->m_size;
|
||||||
|
|
||||||
D3D11_VIEWPORT vp;
|
D3D11_VIEWPORT vp;
|
||||||
|
|
||||||
|
@ -742,9 +709,9 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
|
||||||
|
|
||||||
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
|
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
|
||||||
|
|
||||||
if(!m_scissor.eq(r))
|
if(!m_state.scissor.eq(r))
|
||||||
{
|
{
|
||||||
m_scissor = r;
|
m_state.scissor = r;
|
||||||
|
|
||||||
m_ctx->RSSetScissorRects(1, r);
|
m_ctx->RSSetScissorRects(1, r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,28 +26,6 @@
|
||||||
|
|
||||||
class GSDevice11 : public GSDevice
|
class GSDevice11 : public GSDevice
|
||||||
{
|
{
|
||||||
ID3D11Buffer* m_vb;
|
|
||||||
size_t m_vb_stride;
|
|
||||||
ID3D11InputLayout* m_layout;
|
|
||||||
D3D11_PRIMITIVE_TOPOLOGY m_topology;
|
|
||||||
ID3D11VertexShader* m_vs;
|
|
||||||
ID3D11Buffer* m_vs_cb;
|
|
||||||
ID3D11GeometryShader* m_gs;
|
|
||||||
ID3D11ShaderResourceView* m_ps_srv[2];
|
|
||||||
ID3D11PixelShader* m_ps;
|
|
||||||
ID3D11Buffer* m_ps_cb;
|
|
||||||
ID3D11SamplerState* m_ps_ss[2];
|
|
||||||
GSVector2i m_viewport;
|
|
||||||
GSVector4i m_scissor;
|
|
||||||
ID3D11DepthStencilState* m_dss;
|
|
||||||
uint8 m_sref;
|
|
||||||
ID3D11BlendState* m_bs;
|
|
||||||
float m_bf;
|
|
||||||
ID3D11RenderTargetView* m_rtv;
|
|
||||||
ID3D11DepthStencilView* m_dsv;
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
GSTexture* Create(int type, int w, int h, int format);
|
GSTexture* Create(int type, int w, int h, int format);
|
||||||
|
|
||||||
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
|
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
|
||||||
|
@ -58,12 +36,31 @@ class GSDevice11 : public GSDevice
|
||||||
CComPtr<ID3D11Device> m_dev;
|
CComPtr<ID3D11Device> m_dev;
|
||||||
CComPtr<ID3D11DeviceContext> m_ctx;
|
CComPtr<ID3D11DeviceContext> m_ctx;
|
||||||
CComPtr<IDXGISwapChain> m_swapchain;
|
CComPtr<IDXGISwapChain> m_swapchain;
|
||||||
|
CComPtr<ID3D11Buffer> m_vb;
|
||||||
|
CComPtr<ID3D11Buffer> m_vb_old;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
CComPtr<ID3D11Buffer> vb, vb_old;
|
ID3D11Buffer* vb;
|
||||||
size_t stride, start, count, limit;
|
size_t vb_stride;
|
||||||
} m_vertices;
|
ID3D11InputLayout* layout;
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY topology;
|
||||||
|
ID3D11VertexShader* vs;
|
||||||
|
ID3D11Buffer* vs_cb;
|
||||||
|
ID3D11GeometryShader* gs;
|
||||||
|
ID3D11ShaderResourceView* ps_srv[2];
|
||||||
|
ID3D11PixelShader* ps;
|
||||||
|
ID3D11Buffer* ps_cb;
|
||||||
|
ID3D11SamplerState* ps_ss[2];
|
||||||
|
GSVector2i viewport;
|
||||||
|
GSVector4i scissor;
|
||||||
|
ID3D11DepthStencilState* dss;
|
||||||
|
uint8 sref;
|
||||||
|
ID3D11BlendState* bs;
|
||||||
|
float bf;
|
||||||
|
ID3D11RenderTargetView* rtv;
|
||||||
|
ID3D11DepthStencilView* dsv;
|
||||||
|
} m_state;
|
||||||
|
|
||||||
public: // TODO
|
public: // TODO
|
||||||
CComPtr<ID3D11RasterizerState> m_rs;
|
CComPtr<ID3D11RasterizerState> m_rs;
|
||||||
|
@ -100,9 +97,7 @@ public:
|
||||||
bool Reset(int w, int h, int mode);
|
bool Reset(int w, int h, int mode);
|
||||||
void Flip(bool limit);
|
void Flip(bool limit);
|
||||||
|
|
||||||
void BeginScene();
|
|
||||||
void DrawPrimitive();
|
void DrawPrimitive();
|
||||||
void EndScene();
|
|
||||||
|
|
||||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
|
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
|
||||||
void ClearRenderTarget(GSTexture* t, uint32 c);
|
void ClearRenderTarget(GSTexture* t, uint32 c);
|
||||||
|
|
|
@ -25,42 +25,23 @@
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
GSDevice9::GSDevice9()
|
GSDevice9::GSDevice9()
|
||||||
: m_vb(NULL)
|
: m_lost(false)
|
||||||
, m_vb_stride(0)
|
|
||||||
, m_layout(NULL)
|
|
||||||
, m_topology((D3DPRIMITIVETYPE)0)
|
|
||||||
, m_vs(NULL)
|
|
||||||
, m_vs_cb(NULL)
|
|
||||||
, m_vs_cb_len(0)
|
|
||||||
, m_ps(NULL)
|
|
||||||
, m_ps_cb(NULL)
|
|
||||||
, m_ps_cb_len(0)
|
|
||||||
, m_ps_ss(NULL)
|
|
||||||
, m_scissor(0, 0, 0, 0)
|
|
||||||
, m_dss(NULL)
|
|
||||||
, m_bs(NULL)
|
|
||||||
, m_bf(0xffffffff)
|
|
||||||
, m_rtv(NULL)
|
|
||||||
, m_dsv(NULL)
|
|
||||||
, m_lost(false)
|
|
||||||
{
|
{
|
||||||
m_rbswapped = true;
|
m_rbswapped = true;
|
||||||
|
|
||||||
memset(&m_pp, 0, sizeof(m_pp));
|
memset(&m_pp, 0, sizeof(m_pp));
|
||||||
memset(&m_ddcaps, 0, sizeof(m_ddcaps));
|
memset(&m_ddcaps, 0, sizeof(m_ddcaps));
|
||||||
memset(&m_d3dcaps, 0, sizeof(m_d3dcaps));
|
memset(&m_d3dcaps, 0, sizeof(m_d3dcaps));
|
||||||
memset(m_ps_srvs, 0, sizeof(m_ps_srvs));
|
|
||||||
|
|
||||||
m_vertices.stride = 0;
|
memset(&m_state, 0, sizeof(m_state));
|
||||||
m_vertices.start = 0;
|
|
||||||
m_vertices.count = 0;
|
m_state.bf = 0xffffffff;
|
||||||
m_vertices.limit = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GSDevice9::~GSDevice9()
|
GSDevice9::~GSDevice9()
|
||||||
{
|
{
|
||||||
if(m_vs_cb) _aligned_free(m_vs_cb);
|
if(m_state.vs_cb) _aligned_free(m_state.vs_cb);
|
||||||
if(m_ps_cb) _aligned_free(m_ps_cb);
|
if(m_state.ps_cb) _aligned_free(m_state.ps_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSDevice9::Create(GSWnd* wnd, bool vsync)
|
bool GSDevice9::Create(GSWnd* wnd, bool vsync)
|
||||||
|
@ -111,12 +92,17 @@ bool GSDevice9::Create(GSWnd* wnd, bool vsync)
|
||||||
//
|
//
|
||||||
|
|
||||||
if(m_d3dcaps.VertexShaderVersion < (m_d3dcaps.PixelShaderVersion & ~0x10000))
|
if(m_d3dcaps.VertexShaderVersion < (m_d3dcaps.PixelShaderVersion & ~0x10000))
|
||||||
|
{
|
||||||
|
if(m_d3dcaps.VertexShaderVersion > D3DVS_VERSION(0, 0))
|
||||||
{
|
{
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// else vertex shader should be emulated in software (gma950)
|
||||||
|
}
|
||||||
|
|
||||||
m_d3dcaps.VertexShaderVersion = m_d3dcaps.PixelShaderVersion & ~0x10000;
|
m_d3dcaps.VertexShaderVersion = m_d3dcaps.PixelShaderVersion & ~0x10000;
|
||||||
|
|
||||||
if(m_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
|
if(m_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
|
||||||
|
@ -246,30 +232,18 @@ bool GSDevice9::Reset(int w, int h, int mode)
|
||||||
|
|
||||||
m_swapchain = NULL;
|
m_swapchain = NULL;
|
||||||
|
|
||||||
m_vertices.vb = NULL;
|
m_vb = NULL;
|
||||||
m_vertices.vb_old = NULL;
|
m_vb_old = NULL;
|
||||||
|
|
||||||
m_vertices.start = 0;
|
m_vertices.start = 0;
|
||||||
m_vertices.count = 0;
|
m_vertices.count = 0;
|
||||||
|
|
||||||
if(m_vs_cb) _aligned_free(m_vs_cb);
|
if(m_state.vs_cb) _aligned_free(m_state.vs_cb);
|
||||||
if(m_ps_cb) _aligned_free(m_ps_cb);
|
if(m_state.ps_cb) _aligned_free(m_state.ps_cb);
|
||||||
|
|
||||||
m_vb = NULL;
|
memset(&m_state, 0, sizeof(m_state));
|
||||||
m_vb_stride = 0;
|
|
||||||
m_layout = NULL;
|
m_state.bf = 0xffffffff;
|
||||||
m_vs = NULL;
|
|
||||||
m_vs_cb = NULL;
|
|
||||||
m_vs_cb_len = 0;
|
|
||||||
m_ps = NULL;
|
|
||||||
m_ps_cb = NULL;
|
|
||||||
m_ps_cb_len = 0;
|
|
||||||
m_ps_ss = NULL;
|
|
||||||
m_scissor = GSVector4i::zero();
|
|
||||||
m_dss = NULL;
|
|
||||||
m_bs = NULL;
|
|
||||||
m_bf = 0xffffffff;
|
|
||||||
m_rtv = NULL;
|
|
||||||
m_dsv = NULL;
|
|
||||||
|
|
||||||
memset(&m_pp, 0, sizeof(m_pp));
|
memset(&m_pp, 0, sizeof(m_pp));
|
||||||
|
|
||||||
|
@ -403,7 +377,7 @@ void GSDevice9::DrawPrimitive()
|
||||||
{
|
{
|
||||||
int prims = 0;
|
int prims = 0;
|
||||||
|
|
||||||
switch(m_topology)
|
switch(m_state.topology)
|
||||||
{
|
{
|
||||||
case D3DPT_TRIANGLELIST:
|
case D3DPT_TRIANGLELIST:
|
||||||
prims = m_vertices.count / 3;
|
prims = m_vertices.count / 3;
|
||||||
|
@ -423,15 +397,14 @@ void GSDevice9::DrawPrimitive()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dev->DrawPrimitive(m_topology, m_vertices.start, prims);
|
m_dev->DrawPrimitive(m_state.topology, m_vertices.start, prims);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice9::EndScene()
|
void GSDevice9::EndScene()
|
||||||
{
|
{
|
||||||
// m_dev->EndScene();
|
// m_dev->EndScene();
|
||||||
|
|
||||||
m_vertices.start += m_vertices.count;
|
__super::EndScene();
|
||||||
m_vertices.count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice9::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
void GSDevice9::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||||
|
@ -707,18 +680,19 @@ void GSDevice9::IASetVertexBuffer(const void* vertices, size_t stride, size_t co
|
||||||
|
|
||||||
if(count * stride > m_vertices.limit * m_vertices.stride)
|
if(count * stride > m_vertices.limit * m_vertices.stride)
|
||||||
{
|
{
|
||||||
m_vertices.vb_old = m_vertices.vb;
|
m_vb_old = m_vb;
|
||||||
m_vertices.vb = NULL;
|
m_vb = NULL;
|
||||||
|
|
||||||
m_vertices.start = 0;
|
m_vertices.start = 0;
|
||||||
m_vertices.count = 0;
|
m_vertices.count = 0;
|
||||||
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_vertices.vb == NULL)
|
if(m_vb == NULL)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
hr = m_dev->CreateVertexBuffer(m_vertices.limit * stride, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertices.vb, NULL);
|
hr = m_dev->CreateVertexBuffer(m_vertices.limit * stride, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vb, NULL);
|
||||||
|
|
||||||
if(FAILED(hr)) return;
|
if(FAILED(hr)) return;
|
||||||
}
|
}
|
||||||
|
@ -734,25 +708,25 @@ void GSDevice9::IASetVertexBuffer(const void* vertices, size_t stride, size_t co
|
||||||
|
|
||||||
void* v = NULL;
|
void* v = NULL;
|
||||||
|
|
||||||
if(SUCCEEDED(m_vertices.vb->Lock(m_vertices.start * stride, count * stride, &v, flags)))
|
if(SUCCEEDED(m_vb->Lock(m_vertices.start * stride, count * stride, &v, flags)))
|
||||||
{
|
{
|
||||||
GSVector4i::storent(v, vertices, count * stride);
|
GSVector4i::storent(v, vertices, count * stride);
|
||||||
|
|
||||||
m_vertices.vb->Unlock();
|
m_vb->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vertices.count = count;
|
m_vertices.count = count;
|
||||||
m_vertices.stride = stride;
|
m_vertices.stride = stride;
|
||||||
|
|
||||||
IASetVertexBuffer(m_vertices.vb, stride);
|
IASetVertexBuffer(m_vb, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, size_t stride)
|
void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, size_t stride)
|
||||||
{
|
{
|
||||||
if(m_vb != vb || m_vb_stride != stride)
|
if(m_state.vb != vb || m_state.vb_stride != stride)
|
||||||
{
|
{
|
||||||
m_vb = vb;
|
m_state.vb = vb;
|
||||||
m_vb_stride = stride;
|
m_state.vb_stride = stride;
|
||||||
|
|
||||||
m_dev->SetStreamSource(0, vb, 0, stride);
|
m_dev->SetStreamSource(0, vb, 0, stride);
|
||||||
}
|
}
|
||||||
|
@ -760,9 +734,9 @@ void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, size_t stride)
|
||||||
|
|
||||||
void GSDevice9::IASetInputLayout(IDirect3DVertexDeclaration9* layout)
|
void GSDevice9::IASetInputLayout(IDirect3DVertexDeclaration9* layout)
|
||||||
{
|
{
|
||||||
if(m_layout != layout)
|
if(m_state.layout != layout)
|
||||||
{
|
{
|
||||||
m_layout = layout;
|
m_state.layout = layout;
|
||||||
|
|
||||||
m_dev->SetVertexDeclaration(layout);
|
m_dev->SetVertexDeclaration(layout);
|
||||||
}
|
}
|
||||||
|
@ -770,14 +744,14 @@ void GSDevice9::IASetInputLayout(IDirect3DVertexDeclaration9* layout)
|
||||||
|
|
||||||
void GSDevice9::IASetPrimitiveTopology(D3DPRIMITIVETYPE topology)
|
void GSDevice9::IASetPrimitiveTopology(D3DPRIMITIVETYPE topology)
|
||||||
{
|
{
|
||||||
m_topology = topology;
|
m_state.topology = topology;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDevice9::VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int vs_cb_len)
|
void GSDevice9::VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int vs_cb_len)
|
||||||
{
|
{
|
||||||
if(m_vs != vs)
|
if(m_state.vs != vs)
|
||||||
{
|
{
|
||||||
m_vs = vs;
|
m_state.vs = vs;
|
||||||
|
|
||||||
m_dev->SetVertexShader(vs);
|
m_dev->SetVertexShader(vs);
|
||||||
}
|
}
|
||||||
|
@ -786,18 +760,18 @@ void GSDevice9::VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int
|
||||||
{
|
{
|
||||||
int size = vs_cb_len * sizeof(float) * 4;
|
int size = vs_cb_len * sizeof(float) * 4;
|
||||||
|
|
||||||
if(m_vs_cb_len != vs_cb_len || m_vs_cb == NULL || memcmp(m_vs_cb, vs_cb, size))
|
if(m_state.vs_cb_len != vs_cb_len || m_state.vs_cb == NULL || memcmp(m_state.vs_cb, vs_cb, size))
|
||||||
{
|
{
|
||||||
if(m_vs_cb == NULL || m_vs_cb_len < vs_cb_len)
|
if(m_state.vs_cb == NULL || m_state.vs_cb_len < vs_cb_len)
|
||||||
{
|
{
|
||||||
if(m_vs_cb) _aligned_free(m_vs_cb);
|
if(m_state.vs_cb) _aligned_free(m_state.vs_cb);
|
||||||
|
|
||||||
m_vs_cb = (float*)_aligned_malloc(size, 16);
|
m_state.vs_cb = (float*)_aligned_malloc(size, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vs_cb_len = vs_cb_len;
|
m_state.vs_cb_len = vs_cb_len;
|
||||||
|
|
||||||
memcpy(m_vs_cb, vs_cb, size);
|
memcpy(m_state.vs_cb, vs_cb, size);
|
||||||
|
|
||||||
m_dev->SetVertexShaderConstantF(0, vs_cb, vs_cb_len);
|
m_dev->SetVertexShaderConstantF(0, vs_cb, vs_cb_len);
|
||||||
}
|
}
|
||||||
|
@ -812,16 +786,16 @@ void GSDevice9::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
if(sr0) srv0 = *(GSTexture9*)sr0;
|
if(sr0) srv0 = *(GSTexture9*)sr0;
|
||||||
if(sr1) srv1 = *(GSTexture9*)sr1;
|
if(sr1) srv1 = *(GSTexture9*)sr1;
|
||||||
|
|
||||||
if(m_ps_srvs[0] != srv0)
|
if(m_state.ps_srvs[0] != srv0)
|
||||||
{
|
{
|
||||||
m_ps_srvs[0] = srv0;
|
m_state.ps_srvs[0] = srv0;
|
||||||
|
|
||||||
m_dev->SetTexture(0, srv0);
|
m_dev->SetTexture(0, srv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_ps_srvs[1] != srv1)
|
if(m_state.ps_srvs[1] != srv1)
|
||||||
{
|
{
|
||||||
m_ps_srvs[1] = srv1;
|
m_state.ps_srvs[1] = srv1;
|
||||||
|
|
||||||
m_dev->SetTexture(1, srv1);
|
m_dev->SetTexture(1, srv1);
|
||||||
}
|
}
|
||||||
|
@ -829,9 +803,9 @@ void GSDevice9::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
|
|
||||||
void GSDevice9::PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len)
|
void GSDevice9::PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len)
|
||||||
{
|
{
|
||||||
if(m_ps != ps)
|
if(m_state.ps != ps)
|
||||||
{
|
{
|
||||||
m_ps = ps;
|
m_state.ps = ps;
|
||||||
|
|
||||||
m_dev->SetPixelShader(ps);
|
m_dev->SetPixelShader(ps);
|
||||||
}
|
}
|
||||||
|
@ -840,18 +814,18 @@ void GSDevice9::PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int p
|
||||||
{
|
{
|
||||||
int size = ps_cb_len * sizeof(float) * 4;
|
int size = ps_cb_len * sizeof(float) * 4;
|
||||||
|
|
||||||
if(m_ps_cb_len != ps_cb_len || m_ps_cb == NULL || memcmp(m_ps_cb, ps_cb, size))
|
if(m_state.ps_cb_len != ps_cb_len || m_state.ps_cb == NULL || memcmp(m_state.ps_cb, ps_cb, size))
|
||||||
{
|
{
|
||||||
if(m_ps_cb == NULL || m_ps_cb_len < ps_cb_len)
|
if(m_state.ps_cb == NULL || m_state.ps_cb_len < ps_cb_len)
|
||||||
{
|
{
|
||||||
if(m_ps_cb) _aligned_free(m_ps_cb);
|
if(m_state.ps_cb) _aligned_free(m_state.ps_cb);
|
||||||
|
|
||||||
m_ps_cb = (float*)_aligned_malloc(size, 16);
|
m_state.ps_cb = (float*)_aligned_malloc(size, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ps_cb_len = ps_cb_len;
|
m_state.ps_cb_len = ps_cb_len;
|
||||||
|
|
||||||
memcpy(m_ps_cb, ps_cb, size);
|
memcpy(m_state.ps_cb, ps_cb, size);
|
||||||
|
|
||||||
m_dev->SetPixelShaderConstantF(0, ps_cb, ps_cb_len);
|
m_dev->SetPixelShaderConstantF(0, ps_cb, ps_cb_len);
|
||||||
}
|
}
|
||||||
|
@ -860,9 +834,9 @@ void GSDevice9::PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int p
|
||||||
|
|
||||||
void GSDevice9::PSSetSamplerState(Direct3DSamplerState9* ss)
|
void GSDevice9::PSSetSamplerState(Direct3DSamplerState9* ss)
|
||||||
{
|
{
|
||||||
if(ss && m_ps_ss != ss)
|
if(ss && m_state.ps_ss != ss)
|
||||||
{
|
{
|
||||||
m_ps_ss = ss;
|
m_state.ps_ss = ss;
|
||||||
|
|
||||||
m_dev->SetSamplerState(0, D3DSAMP_ADDRESSU, ss->AddressU);
|
m_dev->SetSamplerState(0, D3DSAMP_ADDRESSU, ss->AddressU);
|
||||||
m_dev->SetSamplerState(0, D3DSAMP_ADDRESSV, ss->AddressV);
|
m_dev->SetSamplerState(0, D3DSAMP_ADDRESSV, ss->AddressV);
|
||||||
|
@ -885,9 +859,9 @@ void GSDevice9::PSSetSamplerState(Direct3DSamplerState9* ss)
|
||||||
|
|
||||||
void GSDevice9::OMSetDepthStencilState(Direct3DDepthStencilState9* dss)
|
void GSDevice9::OMSetDepthStencilState(Direct3DDepthStencilState9* dss)
|
||||||
{
|
{
|
||||||
if(m_dss != dss)
|
if(m_state.dss != dss)
|
||||||
{
|
{
|
||||||
m_dss = dss;
|
m_state.dss = dss;
|
||||||
|
|
||||||
m_dev->SetRenderState(D3DRS_ZENABLE, dss->DepthEnable);
|
m_dev->SetRenderState(D3DRS_ZENABLE, dss->DepthEnable);
|
||||||
m_dev->SetRenderState(D3DRS_ZWRITEENABLE, dss->DepthWriteMask);
|
m_dev->SetRenderState(D3DRS_ZWRITEENABLE, dss->DepthWriteMask);
|
||||||
|
@ -914,10 +888,10 @@ void GSDevice9::OMSetDepthStencilState(Direct3DDepthStencilState9* dss)
|
||||||
|
|
||||||
void GSDevice9::OMSetBlendState(Direct3DBlendState9* bs, uint32 bf)
|
void GSDevice9::OMSetBlendState(Direct3DBlendState9* bs, uint32 bf)
|
||||||
{
|
{
|
||||||
if(m_bs != bs || m_bf != bf)
|
if(m_state.bs != bs || m_state.bf != bf)
|
||||||
{
|
{
|
||||||
m_bs = bs;
|
m_state.bs = bs;
|
||||||
m_bf = bf;
|
m_state.bf = bf;
|
||||||
|
|
||||||
m_dev->SetRenderState(D3DRS_ALPHABLENDENABLE, bs->BlendEnable);
|
m_dev->SetRenderState(D3DRS_ALPHABLENDENABLE, bs->BlendEnable);
|
||||||
|
|
||||||
|
@ -945,25 +919,25 @@ void GSDevice9::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4
|
||||||
if(rt) rtv = *(GSTexture9*)rt;
|
if(rt) rtv = *(GSTexture9*)rt;
|
||||||
if(ds) dsv = *(GSTexture9*)ds;
|
if(ds) dsv = *(GSTexture9*)ds;
|
||||||
|
|
||||||
if(m_rtv != rtv)
|
if(m_state.rtv != rtv)
|
||||||
{
|
{
|
||||||
m_rtv = rtv;
|
m_state.rtv = rtv;
|
||||||
|
|
||||||
m_dev->SetRenderTarget(0, rtv);
|
m_dev->SetRenderTarget(0, rtv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_dsv != dsv)
|
if(m_state.dsv != dsv)
|
||||||
{
|
{
|
||||||
m_dsv = dsv;
|
m_state.dsv = dsv;
|
||||||
|
|
||||||
m_dev->SetDepthStencilSurface(dsv);
|
m_dev->SetDepthStencilSurface(dsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
|
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
|
||||||
|
|
||||||
if(!m_scissor.eq(r))
|
if(!m_state.scissor.eq(r))
|
||||||
{
|
{
|
||||||
m_scissor = r;
|
m_state.scissor = r;
|
||||||
|
|
||||||
m_dev->SetScissorRect(r);
|
m_dev->SetScissorRect(r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,28 +61,6 @@ struct Direct3DBlendState9
|
||||||
|
|
||||||
class GSDevice9 : public GSDevice
|
class GSDevice9 : public GSDevice
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
IDirect3DVertexBuffer9* m_vb;
|
|
||||||
size_t m_vb_stride;
|
|
||||||
IDirect3DVertexDeclaration9* m_layout;
|
|
||||||
D3DPRIMITIVETYPE m_topology;
|
|
||||||
IDirect3DVertexShader9* m_vs;
|
|
||||||
float* m_vs_cb;
|
|
||||||
int m_vs_cb_len;
|
|
||||||
IDirect3DTexture9* m_ps_srvs[2];
|
|
||||||
IDirect3DPixelShader9* m_ps;
|
|
||||||
float* m_ps_cb;
|
|
||||||
int m_ps_cb_len;
|
|
||||||
Direct3DSamplerState9* m_ps_ss;
|
|
||||||
GSVector4i m_scissor;
|
|
||||||
Direct3DDepthStencilState9* m_dss;
|
|
||||||
Direct3DBlendState9* m_bs;
|
|
||||||
uint32 m_bf;
|
|
||||||
IDirect3DSurface9* m_rtv;
|
|
||||||
IDirect3DSurface9* m_dsv;
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
GSTexture* Create(int type, int w, int h, int format);
|
GSTexture* Create(int type, int w, int h, int format);
|
||||||
|
|
||||||
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
|
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
|
||||||
|
@ -96,13 +74,31 @@ private:
|
||||||
CComPtr<IDirect3D9> m_d3d;
|
CComPtr<IDirect3D9> m_d3d;
|
||||||
CComPtr<IDirect3DDevice9> m_dev;
|
CComPtr<IDirect3DDevice9> m_dev;
|
||||||
CComPtr<IDirect3DSwapChain9> m_swapchain;
|
CComPtr<IDirect3DSwapChain9> m_swapchain;
|
||||||
|
CComPtr<IDirect3DVertexBuffer9> m_vb;
|
||||||
|
CComPtr<IDirect3DVertexBuffer9> m_vb_old;
|
||||||
bool m_lost;
|
bool m_lost;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
CComPtr<IDirect3DVertexBuffer9> vb, vb_old;
|
IDirect3DVertexBuffer9* vb;
|
||||||
size_t stride, start, count, limit;
|
size_t vb_stride;
|
||||||
} m_vertices;
|
IDirect3DVertexDeclaration9* layout;
|
||||||
|
D3DPRIMITIVETYPE topology;
|
||||||
|
IDirect3DVertexShader9* vs;
|
||||||
|
float* vs_cb;
|
||||||
|
int vs_cb_len;
|
||||||
|
IDirect3DTexture9* ps_srvs[2];
|
||||||
|
IDirect3DPixelShader9* ps;
|
||||||
|
float* ps_cb;
|
||||||
|
int ps_cb_len;
|
||||||
|
Direct3DSamplerState9* ps_ss;
|
||||||
|
GSVector4i scissor;
|
||||||
|
Direct3DDepthStencilState9* dss;
|
||||||
|
Direct3DBlendState9* bs;
|
||||||
|
uint32 bf;
|
||||||
|
IDirect3DSurface9* rtv;
|
||||||
|
IDirect3DSurface9* dsv;
|
||||||
|
} m_state;
|
||||||
|
|
||||||
public: // TODO
|
public: // TODO
|
||||||
|
|
||||||
|
|
|
@ -203,21 +203,11 @@ void GSDeviceOGL::Flip(bool limit)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::BeginScene()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSDeviceOGL::DrawPrimitive()
|
void GSDeviceOGL::DrawPrimitive()
|
||||||
{
|
{
|
||||||
glDrawArrays(m_topology, m_vertices.count, m_vertices.start); CheckError();
|
glDrawArrays(m_topology, m_vertices.count, m_vertices.start); CheckError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::EndScene()
|
|
||||||
{
|
|
||||||
m_vertices.start += m_vertices.count;
|
|
||||||
m_vertices.count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||||
{
|
{
|
||||||
GLuint texture = *(GSTextureOGL*)t;
|
GLuint texture = *(GSTextureOGL*)t;
|
||||||
|
|
|
@ -114,9 +114,7 @@ public:
|
||||||
void Present(const GSVector4i& r, int shader, bool limit);
|
void Present(const GSVector4i& r, int shader, bool limit);
|
||||||
void Flip(bool limit);
|
void Flip(bool limit);
|
||||||
|
|
||||||
void BeginScene();
|
|
||||||
void DrawPrimitive();
|
void DrawPrimitive();
|
||||||
void EndScene();
|
|
||||||
|
|
||||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
|
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
|
||||||
void ClearRenderTarget(GSTexture* t, uint32 c);
|
void ClearRenderTarget(GSTexture* t, uint32 c);
|
||||||
|
|
|
@ -495,7 +495,7 @@ protected:
|
||||||
|
|
||||||
GSTexture* t = NULL;
|
GSTexture* t = NULL;
|
||||||
|
|
||||||
if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true, true))
|
if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height))
|
||||||
{
|
{
|
||||||
t = rt->m_texture;
|
t = rt->m_texture;
|
||||||
|
|
||||||
|
|
|
@ -106,21 +106,12 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
||||||
|
|
||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
src = CreateSource();
|
src = CreateSource(TEX0, TEXA, dst);
|
||||||
|
|
||||||
if(!(dst ? src->Create(dst) : src->Create(m_paltex)))
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
delete src;
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(psm.pal > 0)
|
|
||||||
{
|
|
||||||
memcpy(src->m_clut, clut, psm.pal * sizeof(clut[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_src.Add(src, TEX0, m_renderer->m_context->offset.tex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(psm.pal > 0)
|
if(psm.pal > 0)
|
||||||
|
@ -144,7 +135,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used, bool fb)
|
GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used)
|
||||||
{
|
{
|
||||||
uint32 bp = TEX0.TBP0;
|
uint32 bp = TEX0.TBP0;
|
||||||
|
|
||||||
|
@ -160,41 +151,20 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
|
||||||
|
|
||||||
dst = t;
|
dst = t;
|
||||||
|
|
||||||
if(!fb) dst->m_TEX0 = TEX0;
|
dst->m_TEX0 = TEX0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dst == NULL && fb)
|
if(dst == NULL)
|
||||||
{
|
{
|
||||||
// HACK: try to find something close to the base pointer
|
dst = CreateTarget(TEX0, w, h, type);
|
||||||
|
|
||||||
for(list<Target*>::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++)
|
|
||||||
{
|
|
||||||
Target* t = *i;
|
|
||||||
|
|
||||||
if(t->m_TEX0.TBP0 <= bp && bp < t->m_TEX0.TBP0 + 0x700 && (!dst || t->m_TEX0.TBP0 >= dst->m_TEX0.TBP0))
|
|
||||||
{
|
|
||||||
dst = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dst == NULL)
|
if(dst == NULL)
|
||||||
{
|
{
|
||||||
dst = CreateTarget();
|
|
||||||
|
|
||||||
dst->m_TEX0 = TEX0;
|
|
||||||
|
|
||||||
if(!dst->Create(w, h, type))
|
|
||||||
{
|
|
||||||
delete dst;
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dst[type].push_front(dst);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -212,12 +182,12 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
|
||||||
{
|
{
|
||||||
hh *= 2;
|
hh *= 2;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if(hh < 512)
|
if(hh < 512 && m_renderer->m_context->SCISSOR.SCAY1 == 511) // vp2
|
||||||
{
|
{
|
||||||
hh = 512;
|
hh = 512;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if(ww > 0 && hh > 0)
|
if(ww > 0 && hh > 0)
|
||||||
{
|
{
|
||||||
dst->m_texture->m_scale.x = (float)w / ww;
|
dst->m_texture->m_scale.x = (float)w / ww;
|
||||||
|
@ -233,6 +203,52 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int w, int h)
|
||||||
|
{
|
||||||
|
uint32 bp = TEX0.TBP0;
|
||||||
|
|
||||||
|
Target* dst = NULL;
|
||||||
|
|
||||||
|
for(list<Target*>::iterator i = m_dst[RenderTarget].begin(); i != m_dst[RenderTarget].end(); i++)
|
||||||
|
{
|
||||||
|
Target* t = *i;
|
||||||
|
|
||||||
|
if(bp == t->m_TEX0.TBP0)
|
||||||
|
{
|
||||||
|
dst = t;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// HACK: try to find something close to the base pointer
|
||||||
|
|
||||||
|
if(t->m_TEX0.TBP0 <= bp && bp < t->m_TEX0.TBP0 + 0x700 && (!dst || t->m_TEX0.TBP0 >= dst->m_TEX0.TBP0))
|
||||||
|
{
|
||||||
|
dst = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dst == NULL)
|
||||||
|
{
|
||||||
|
dst = CreateTarget(TEX0, w, h, RenderTarget);
|
||||||
|
|
||||||
|
if(dst == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
dst->m_used = true;
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
void GSTextureCache::InvalidateVideoMem(const GSOffset* o, const GSVector4i& rect, bool target)
|
void GSTextureCache::InvalidateVideoMem(const GSOffset* o, const GSVector4i& rect, bool target)
|
||||||
{
|
{
|
||||||
uint32 bp = o->bp;
|
uint32 bp = o->bp;
|
||||||
|
@ -368,12 +384,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset* o, const GSVector4i& r)
|
||||||
{
|
{
|
||||||
if(GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM))
|
if(GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM))
|
||||||
{
|
{
|
||||||
GSVector4i r2 = r.rintersect(t->m_valid);
|
Read(t, r.rintersect(t->m_valid));
|
||||||
|
|
||||||
if(!r2.rempty())
|
|
||||||
{
|
|
||||||
t->Read(r2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -381,12 +392,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset* o, const GSVector4i& r)
|
||||||
{
|
{
|
||||||
// ffx-2 riku changing to her default (shoots some reflecting glass at the end), 16-bit rt read as 32-bit
|
// ffx-2 riku changing to her default (shoots some reflecting glass at the end), 16-bit rt read as 32-bit
|
||||||
|
|
||||||
GSVector4i r2 = GSVector4i(r.left, r.top, r.right, r.top + (r.bottom - r.top) * 2).rintersect(t->m_valid);
|
Read(t, GSVector4i(r.left, r.top, r.right, r.top + (r.bottom - r.top) * 2).rintersect(t->m_valid));
|
||||||
|
|
||||||
if(!r2.rempty())
|
|
||||||
{
|
|
||||||
t->Read(r2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -477,6 +483,241 @@ void GSTextureCache::IncAge()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst)
|
||||||
|
{
|
||||||
|
Source* src = new Source(m_renderer);
|
||||||
|
|
||||||
|
src->m_TEX0 = TEX0;
|
||||||
|
src->m_TEXA = TEXA;
|
||||||
|
|
||||||
|
int tw = 1 << TEX0.TW;
|
||||||
|
int th = 1 << TEX0.TH;
|
||||||
|
int tp = (int)TEX0.TW << 6;
|
||||||
|
|
||||||
|
if(dst == NULL)
|
||||||
|
{
|
||||||
|
if(m_paltex && GSLocalMemory::m_psm[TEX0.PSM].pal > 0)
|
||||||
|
{
|
||||||
|
src->m_fmt = GSTextureFX::FMT_8;
|
||||||
|
|
||||||
|
src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat());
|
||||||
|
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src->m_fmt = GSTextureFX::FMT_32;
|
||||||
|
|
||||||
|
src->m_texture = m_renderer->m_dev->CreateTexture(tw, th);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: clean up this mess
|
||||||
|
|
||||||
|
src->m_target = true;
|
||||||
|
|
||||||
|
if(dst->m_type != RenderTarget)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
delete src;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst->Update();
|
||||||
|
|
||||||
|
// 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 != TEX0.TBW) // && dst->m_TEX0.PSM == TEX0.PSM
|
||||||
|
{
|
||||||
|
// sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left)
|
||||||
|
|
||||||
|
// ASSERT(dst->m_TEX0.TBW > TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO)
|
||||||
|
|
||||||
|
src->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 = TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 ? 32 : 64;
|
||||||
|
|
||||||
|
GSVector4i br(0, 0, bw, bh);
|
||||||
|
|
||||||
|
int sw = (int)dst->m_TEX0.TBW << 6;
|
||||||
|
|
||||||
|
int dw = (int)TEX0.TBW << 6;
|
||||||
|
int dh = 1 << 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, src->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 && (TEX0.TBP0 == 0 || 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 = src->m_texture ? src->m_texture : dst->m_texture;
|
||||||
|
GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h);
|
||||||
|
|
||||||
|
if(!src->m_texture)
|
||||||
|
{
|
||||||
|
src->m_texture = dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((sr == dr).alltrue())
|
||||||
|
{
|
||||||
|
m_renderer->m_dev->CopyRect(st, dt, GSVector4i(0, 0, w, h));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sr.z /= st->m_size.x;
|
||||||
|
sr.w /= st->m_size.y;
|
||||||
|
|
||||||
|
m_renderer->m_dev->StretchRect(st, sr, dt, dr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dt != src->m_texture)
|
||||||
|
{
|
||||||
|
m_renderer->m_dev->Recycle(src->m_texture);
|
||||||
|
|
||||||
|
src->m_texture = dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
src->m_texture->m_scale = scale;
|
||||||
|
|
||||||
|
switch(TEX0.PSM)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
case PSM_PSMCT32:
|
||||||
|
src->m_fmt = GSTextureFX::FMT_32;
|
||||||
|
break;
|
||||||
|
case PSM_PSMCT24:
|
||||||
|
src->m_fmt = GSTextureFX::FMT_24;
|
||||||
|
break;
|
||||||
|
case PSM_PSMCT16:
|
||||||
|
case PSM_PSMCT16S:
|
||||||
|
src->m_fmt = GSTextureFX::FMT_16;
|
||||||
|
break;
|
||||||
|
case PSM_PSMT8H:
|
||||||
|
src->m_fmt = GSTextureFX::FMT_8H;
|
||||||
|
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
||||||
|
break;
|
||||||
|
case PSM_PSMT4HL:
|
||||||
|
src->m_fmt = GSTextureFX::FMT_4HL;
|
||||||
|
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
||||||
|
break;
|
||||||
|
case PSM_PSMT4HH:
|
||||||
|
src->m_fmt = GSTextureFX::FMT_4HH;
|
||||||
|
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(src->m_texture == NULL)
|
||||||
|
{
|
||||||
|
ASSERT(0);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
|
||||||
|
|
||||||
|
if(psm.pal > 0)
|
||||||
|
{
|
||||||
|
memcpy(src->m_clut, (const uint32*)m_renderer->m_mem.m_clut, psm.pal * sizeof(uint32));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_src.Add(src, TEX0, m_renderer->m_context->offset.tex);
|
||||||
|
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type)
|
||||||
|
{
|
||||||
|
Target* t = new Target(m_renderer);
|
||||||
|
|
||||||
|
t->m_TEX0 = TEX0;
|
||||||
|
|
||||||
|
// FIXME: initial data should be unswizzled from local mem in Update() if dirty
|
||||||
|
|
||||||
|
t->m_type = type;
|
||||||
|
|
||||||
|
if(type == RenderTarget)
|
||||||
|
{
|
||||||
|
t->m_texture = m_renderer->m_dev->CreateRenderTarget(w, h);
|
||||||
|
|
||||||
|
t->m_used = true; // FIXME
|
||||||
|
}
|
||||||
|
else if(type == DepthStencil)
|
||||||
|
{
|
||||||
|
t->m_texture = m_renderer->m_dev->CreateDepthStencil(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(t->m_texture == NULL)
|
||||||
|
{
|
||||||
|
ASSERT(0);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dst[type].push_front(t);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
// GSTextureCache::Surface
|
// GSTextureCache::Surface
|
||||||
|
|
||||||
GSTextureCache::Surface::Surface(GSRenderer* r)
|
GSTextureCache::Surface::Surface(GSRenderer* r)
|
||||||
|
@ -526,197 +767,6 @@ GSTextureCache::Source::~Source()
|
||||||
_aligned_free(m_write.rect);
|
_aligned_free(m_write.rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSTextureCache::Source::Create(bool paltex)
|
|
||||||
{
|
|
||||||
m_TEX0 = m_renderer->m_context->TEX0;
|
|
||||||
m_TEXA = m_renderer->m_env.TEXA;
|
|
||||||
|
|
||||||
ASSERT(m_texture == NULL);
|
|
||||||
|
|
||||||
if(paltex && GSLocalMemory::m_psm[m_TEX0.PSM].pal > 0)
|
|
||||||
{
|
|
||||||
m_fmt = GSTextureFX::FMT_8;
|
|
||||||
|
|
||||||
m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH, Get8bitFormat());
|
|
||||||
m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_fmt = GSTextureFX::FMT_32;
|
|
||||||
|
|
||||||
m_texture = m_renderer->m_dev->CreateTexture(1 << m_TEX0.TW, 1 << m_TEX0.TH);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_texture != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GSTextureCache::Source::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())
|
|
||||||
{
|
|
||||||
m_renderer->m_dev->CopyRect(st, dt, GSVector4i(0, 0, w, h));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sr.z /= st->m_size.x;
|
|
||||||
sr.w /= st->m_size.y;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
ASSERT(0);
|
|
||||||
case PSM_PSMCT32:
|
|
||||||
m_fmt = GSTextureFX::FMT_32;
|
|
||||||
break;
|
|
||||||
case PSM_PSMCT24:
|
|
||||||
m_fmt = GSTextureFX::FMT_24;
|
|
||||||
break;
|
|
||||||
case PSM_PSMCT16:
|
|
||||||
case PSM_PSMCT16S:
|
|
||||||
m_fmt = GSTextureFX::FMT_16;
|
|
||||||
break;
|
|
||||||
case PSM_PSMT8H:
|
|
||||||
m_fmt = GSTextureFX::FMT_8H;
|
|
||||||
m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
|
||||||
break;
|
|
||||||
case PSM_PSMT4HL:
|
|
||||||
m_fmt = GSTextureFX::FMT_4HL;
|
|
||||||
m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
|
||||||
break;
|
|
||||||
case PSM_PSMT4HH:
|
|
||||||
m_fmt = GSTextureFX::FMT_4HH;
|
|
||||||
m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSTextureCache::Source::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect)
|
void GSTextureCache::Source::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect)
|
||||||
{
|
{
|
||||||
__super::Update();
|
__super::Update();
|
||||||
|
@ -912,28 +962,6 @@ GSTextureCache::Target::Target(GSRenderer* r)
|
||||||
m_valid = GSVector4i::zero();
|
m_valid = GSVector4i::zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSTextureCache::Target::Create(int w, int h, int type)
|
|
||||||
{
|
|
||||||
ASSERT(m_texture == NULL);
|
|
||||||
|
|
||||||
// FIXME: initial data should be unswizzled from local mem in Update() if dirty
|
|
||||||
|
|
||||||
m_type = type;
|
|
||||||
|
|
||||||
if(type == RenderTarget)
|
|
||||||
{
|
|
||||||
m_texture = m_renderer->m_dev->CreateRenderTarget(w, h);
|
|
||||||
|
|
||||||
m_used = true;
|
|
||||||
}
|
|
||||||
else if(type == DepthStencil)
|
|
||||||
{
|
|
||||||
m_texture = m_renderer->m_dev->CreateDepthStencil(w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_texture != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSTextureCache::Target::Update()
|
void GSTextureCache::Target::Update()
|
||||||
{
|
{
|
||||||
__super::Update();
|
__super::Update();
|
||||||
|
|
|
@ -46,8 +46,6 @@ public:
|
||||||
virtual void Update();
|
virtual void Update();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Target;
|
|
||||||
|
|
||||||
class Source : public Surface
|
class Source : public Surface
|
||||||
{
|
{
|
||||||
struct {GSVector4i* rect; uint32 count;} m_write;
|
struct {GSVector4i* rect; uint32 count;} m_write;
|
||||||
|
@ -55,9 +53,6 @@ public:
|
||||||
void Write(const GSVector4i& r);
|
void Write(const GSVector4i& r);
|
||||||
void Flush(uint32 count);
|
void Flush(uint32 count);
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual int Get8bitFormat() = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSTexture* m_palette;
|
GSTexture* m_palette;
|
||||||
bool m_initpalette;
|
bool m_initpalette;
|
||||||
|
@ -68,11 +63,9 @@ public:
|
||||||
bool m_complete;
|
bool m_complete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Source(GSRenderer* renderer);
|
explicit Source(GSRenderer* r);
|
||||||
virtual ~Source();
|
virtual ~Source();
|
||||||
|
|
||||||
virtual bool Create(bool paltex);
|
|
||||||
virtual bool Create(Target* dst);
|
|
||||||
virtual void Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect);
|
virtual void Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& rect);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,9 +80,7 @@ public:
|
||||||
public:
|
public:
|
||||||
explicit Target(GSRenderer* r);
|
explicit Target(GSRenderer* r);
|
||||||
|
|
||||||
virtual bool Create(int w, int h, int type);
|
|
||||||
virtual void Update();
|
virtual void Update();
|
||||||
virtual void Read(const GSVector4i& r) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -113,8 +104,14 @@ protected:
|
||||||
|
|
||||||
list<Target*> m_dst[2];
|
list<Target*> m_dst[2];
|
||||||
|
|
||||||
virtual Source* CreateSource() = 0;
|
virtual Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t = NULL);
|
||||||
virtual Target* CreateTarget() = 0;
|
virtual Target* CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type);
|
||||||
|
|
||||||
|
virtual int Get8bitFormat() = 0;
|
||||||
|
|
||||||
|
// TODO: virtual void Write(Source* s, const GSVector4i& r) = 0;
|
||||||
|
// TODO: virtual void Write(Target* t, const GSVector4i& r) = 0;
|
||||||
|
virtual void Read(Target* t, const GSVector4i& r) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSTextureCache(GSRenderer* r);
|
GSTextureCache(GSRenderer* r);
|
||||||
|
@ -123,7 +120,8 @@ public:
|
||||||
void RemoveAll();
|
void RemoveAll();
|
||||||
|
|
||||||
Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, 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);
|
Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used);
|
||||||
|
Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h);
|
||||||
|
|
||||||
void InvalidateVideoMem(const GSOffset* o, const GSVector4i& r, bool target = true);
|
void InvalidateVideoMem(const GSOffset* o, const GSVector4i& r, bool target = true);
|
||||||
void InvalidateLocalMem(const GSOffset* o, const GSVector4i& r);
|
void InvalidateLocalMem(const GSOffset* o, const GSVector4i& r);
|
||||||
|
|
|
@ -29,46 +29,42 @@ GSTextureCache10::GSTextureCache10(GSRenderer* r)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source10
|
void GSTextureCache10::Read(Target* t, const GSVector4i& r)
|
||||||
|
|
||||||
// Target10
|
|
||||||
|
|
||||||
void GSTextureCache10::Target10::Read(const GSVector4i& r)
|
|
||||||
{
|
{
|
||||||
if(m_type != RenderTarget)
|
if(t->m_type != RenderTarget)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_TEX0.PSM != PSM_PSMCT32
|
const GIFRegTEX0& TEX0 = t->m_TEX0;
|
||||||
&& m_TEX0.PSM != PSM_PSMCT24
|
|
||||||
&& m_TEX0.PSM != PSM_PSMCT16
|
if(TEX0.PSM != PSM_PSMCT32
|
||||||
&& m_TEX0.PSM != PSM_PSMCT16S)
|
&& TEX0.PSM != PSM_PSMCT24
|
||||||
|
&& TEX0.PSM != PSM_PSMCT16
|
||||||
|
&& TEX0.PSM != PSM_PSMCT16S)
|
||||||
{
|
{
|
||||||
//ASSERT(0);
|
//ASSERT(0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_dirty.empty())
|
if(!t->m_dirty.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, m_TEX0.TBP0);
|
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, TEX0.TBP0);
|
||||||
|
|
||||||
// m_renderer->m_perfmon.Put(GSPerfMon::ReadRT, 1);
|
|
||||||
|
|
||||||
int w = r.width();
|
int w = r.width();
|
||||||
int h = r.height();
|
int h = r.height();
|
||||||
|
|
||||||
GSVector4 src = GSVector4(r) * GSVector4(m_texture->m_scale).xyxy() / GSVector4(m_texture->GetSize()).xyxy();
|
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->m_scale).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
|
||||||
|
|
||||||
DXGI_FORMAT format = m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
|
||||||
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(m_texture, src, w, h, format))
|
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(t->m_texture, src, w, h, format))
|
||||||
{
|
{
|
||||||
GSTexture::GSMap m;
|
GSTexture::GSMap m;
|
||||||
|
|
||||||
|
@ -76,9 +72,9 @@ void GSTextureCache10::Target10::Read(const GSVector4i& r)
|
||||||
{
|
{
|
||||||
// TODO: block level write
|
// TODO: block level write
|
||||||
|
|
||||||
GSOffset* o = m_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM);
|
GSOffset* o = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM);
|
||||||
|
|
||||||
switch(m_TEX0.PSM)
|
switch(TEX0.PSM)
|
||||||
{
|
{
|
||||||
case PSM_PSMCT32:
|
case PSM_PSMCT32:
|
||||||
m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r);
|
m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r);
|
||||||
|
|
|
@ -26,26 +26,10 @@
|
||||||
|
|
||||||
class GSTextureCache10 : public GSTextureCache
|
class GSTextureCache10 : public GSTextureCache
|
||||||
{
|
{
|
||||||
class Source10 : public Source
|
protected:
|
||||||
{
|
|
||||||
protected:
|
|
||||||
int Get8bitFormat() {return DXGI_FORMAT_A8_UNORM;}
|
int Get8bitFormat() {return DXGI_FORMAT_A8_UNORM;}
|
||||||
|
|
||||||
public:
|
void Read(Target* t, const GSVector4i& r);
|
||||||
explicit Source10(GSRenderer* r) : Source(r) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Target10 : public Target
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Target10(GSRenderer* r) : Target(r) {}
|
|
||||||
|
|
||||||
void Read(const GSVector4i& r);
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Source* CreateSource() {return new Source10(m_renderer);}
|
|
||||||
Target* CreateTarget() {return new Target10(m_renderer);}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSTextureCache10(GSRenderer* r);
|
GSTextureCache10(GSRenderer* r);
|
||||||
|
|
|
@ -29,46 +29,42 @@ GSTextureCache11::GSTextureCache11(GSRenderer* r)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source11
|
void GSTextureCache11::Read(Target* t, const GSVector4i& r)
|
||||||
|
|
||||||
// Target11
|
|
||||||
|
|
||||||
void GSTextureCache11::Target11::Read(const GSVector4i& r)
|
|
||||||
{
|
{
|
||||||
if(m_type != RenderTarget)
|
if(t->m_type != RenderTarget)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_TEX0.PSM != PSM_PSMCT32
|
const GIFRegTEX0& TEX0 = t->m_TEX0;
|
||||||
&& m_TEX0.PSM != PSM_PSMCT24
|
|
||||||
&& m_TEX0.PSM != PSM_PSMCT16
|
if(TEX0.PSM != PSM_PSMCT32
|
||||||
&& m_TEX0.PSM != PSM_PSMCT16S)
|
&& TEX0.PSM != PSM_PSMCT24
|
||||||
|
&& TEX0.PSM != PSM_PSMCT16
|
||||||
|
&& TEX0.PSM != PSM_PSMCT16S)
|
||||||
{
|
{
|
||||||
//ASSERT(0);
|
//ASSERT(0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_dirty.empty())
|
if(!t->m_dirty.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, m_TEX0.TBP0);
|
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, TEX0.TBP0);
|
||||||
|
|
||||||
// m_renderer->m_perfmon.Put(GSPerfMon::ReadRT, 1);
|
|
||||||
|
|
||||||
int w = r.width();
|
int w = r.width();
|
||||||
int h = r.height();
|
int h = r.height();
|
||||||
|
|
||||||
GSVector4 src = GSVector4(r) * GSVector4(m_texture->m_scale).xyxy() / GSVector4(m_texture->GetSize()).xyxy();
|
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->m_scale).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
|
||||||
|
|
||||||
DXGI_FORMAT format = m_TEX0.PSM == PSM_PSMCT16 || m_TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
|
||||||
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(m_texture, src, w, h, format))
|
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(t->m_texture, src, w, h, format))
|
||||||
{
|
{
|
||||||
GSTexture::GSMap m;
|
GSTexture::GSMap m;
|
||||||
|
|
||||||
|
@ -76,9 +72,9 @@ void GSTextureCache11::Target11::Read(const GSVector4i& r)
|
||||||
{
|
{
|
||||||
// TODO: block level write
|
// TODO: block level write
|
||||||
|
|
||||||
GSOffset* o = m_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM);
|
GSOffset* o = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM);
|
||||||
|
|
||||||
switch(m_TEX0.PSM)
|
switch(TEX0.PSM)
|
||||||
{
|
{
|
||||||
case PSM_PSMCT32:
|
case PSM_PSMCT32:
|
||||||
m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r);
|
m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r);
|
||||||
|
|
|
@ -26,26 +26,10 @@
|
||||||
|
|
||||||
class GSTextureCache11 : public GSTextureCache
|
class GSTextureCache11 : public GSTextureCache
|
||||||
{
|
{
|
||||||
class Source11 : public Source
|
protected:
|
||||||
{
|
|
||||||
protected:
|
|
||||||
int Get8bitFormat() {return DXGI_FORMAT_A8_UNORM;}
|
int Get8bitFormat() {return DXGI_FORMAT_A8_UNORM;}
|
||||||
|
|
||||||
public:
|
void Read(Target* t, const GSVector4i& r);
|
||||||
explicit Source11(GSRenderer* r) : Source(r) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Target11 : public Target
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Target11(GSRenderer* r) : Target(r) {}
|
|
||||||
|
|
||||||
void Read(const GSVector4i& r);
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Source* CreateSource() {return new Source11(m_renderer);}
|
|
||||||
Target* CreateTarget() {return new Target11(m_renderer);}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSTextureCache11(GSRenderer* r);
|
GSTextureCache11(GSRenderer* r);
|
||||||
|
|
|
@ -29,44 +29,40 @@ GSTextureCache9::GSTextureCache9(GSRenderer* r)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source9
|
void GSTextureCache9::Read(Target* t, const GSVector4i& r)
|
||||||
|
|
||||||
// Target9
|
|
||||||
|
|
||||||
void GSTextureCache9::Target9::Read(const GSVector4i& r)
|
|
||||||
{
|
{
|
||||||
if(m_type != RenderTarget)
|
if(t->m_type != RenderTarget)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_TEX0.PSM != PSM_PSMCT32
|
const GIFRegTEX0& TEX0 = t->m_TEX0;
|
||||||
&& m_TEX0.PSM != PSM_PSMCT24
|
|
||||||
&& m_TEX0.PSM != PSM_PSMCT16
|
if(TEX0.PSM != PSM_PSMCT32
|
||||||
&& m_TEX0.PSM != PSM_PSMCT16S)
|
&& TEX0.PSM != PSM_PSMCT24
|
||||||
|
&& TEX0.PSM != PSM_PSMCT16
|
||||||
|
&& TEX0.PSM != PSM_PSMCT16S)
|
||||||
{
|
{
|
||||||
//ASSERT(0);
|
//ASSERT(0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_dirty.empty())
|
if(!t->m_dirty.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, m_TEX0.TBP0);
|
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, TEX0.TBP0);
|
||||||
|
|
||||||
// m_renderer->m_perfmon.Put(GSPerfMon::ReadRT, 1);
|
|
||||||
|
|
||||||
int w = r.width();
|
int w = r.width();
|
||||||
int h = r.height();
|
int h = r.height();
|
||||||
|
|
||||||
GSVector4 src = GSVector4(r) * GSVector4(m_texture->m_scale).xyxy() / GSVector4(m_texture->GetSize()).xyxy();
|
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->m_scale).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
|
||||||
|
|
||||||
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(m_texture, src, w, h))
|
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(t->m_texture, src, w, h))
|
||||||
{
|
{
|
||||||
GSTexture::GSMap m;
|
GSTexture::GSMap m;
|
||||||
|
|
||||||
|
@ -74,9 +70,9 @@ void GSTextureCache9::Target9::Read(const GSVector4i& r)
|
||||||
{
|
{
|
||||||
// TODO: block level write
|
// TODO: block level write
|
||||||
|
|
||||||
GSOffset* o = m_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM);
|
GSOffset* o = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM);
|
||||||
|
|
||||||
switch(m_TEX0.PSM)
|
switch(TEX0.PSM)
|
||||||
{
|
{
|
||||||
case PSM_PSMCT32:
|
case PSM_PSMCT32:
|
||||||
m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r);
|
m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r);
|
||||||
|
|
|
@ -26,26 +26,10 @@
|
||||||
|
|
||||||
class GSTextureCache9 : public GSTextureCache
|
class GSTextureCache9 : public GSTextureCache
|
||||||
{
|
{
|
||||||
class Source9 : public Source
|
protected:
|
||||||
{
|
|
||||||
protected:
|
|
||||||
int Get8bitFormat() {return D3DFMT_A8;}
|
int Get8bitFormat() {return D3DFMT_A8;}
|
||||||
|
|
||||||
public:
|
void Read(Target* t, const GSVector4i& r);
|
||||||
explicit Source9(GSRenderer* r) : Source(r) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Target9 : public Target
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Target9(GSRenderer* r) : Target(r) {}
|
|
||||||
|
|
||||||
void Read(const GSVector4i& r);
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Source* CreateSource() {return new Source9(m_renderer);}
|
|
||||||
Target* CreateTarget() {return new Target9(m_renderer);}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSTextureCache9(GSRenderer* r);
|
GSTextureCache9(GSRenderer* r);
|
||||||
|
|
|
@ -28,12 +28,3 @@ GSTextureCacheOGL::GSTextureCacheOGL(GSRenderer* r)
|
||||||
: GSTextureCache(r)
|
: GSTextureCache(r)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// SourceOGL
|
|
||||||
|
|
||||||
// TargetOGL
|
|
||||||
|
|
||||||
void GSTextureCacheOGL::TargetOGL::Read(const GSVector4i& r)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,26 +26,10 @@
|
||||||
|
|
||||||
class GSTextureCacheOGL : public GSTextureCache
|
class GSTextureCacheOGL : public GSTextureCache
|
||||||
{
|
{
|
||||||
class SourceOGL : public Source
|
protected:
|
||||||
{
|
|
||||||
protected:
|
|
||||||
int Get8bitFormat() {return 0;} // TODO
|
int Get8bitFormat() {return 0;} // TODO
|
||||||
|
|
||||||
public:
|
void Read(Target* t, const GSVector4i& r) {} // TODO
|
||||||
explicit SourceOGL(GSRenderer* r) : Source(r) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TargetOGL : public Target
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit TargetOGL(GSRenderer* r) : Target(r) {}
|
|
||||||
|
|
||||||
void Read(const GSVector4i& r);
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Source* CreateSource() {return new SourceOGL(m_renderer);}
|
|
||||||
Target* CreateTarget() {return new TargetOGL(m_renderer);}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSTextureCacheOGL(GSRenderer* r);
|
GSTextureCacheOGL(GSRenderer* r);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<_PropertySheetDisplayName>common</_PropertySheetDisplayName>
|
<_PropertySheetDisplayName>common</_PropertySheetDisplayName>
|
||||||
<OutDir>$(SolutionDir)\bin\$(PcsxSubsection)\</OutDir>
|
<OutDir>$(SolutionDir)bin\$(PcsxSubsection)\</OutDir>
|
||||||
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
|
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)-$(SSEtype)</TargetName>
|
<TargetName>$(ProjectName)-$(SSEtype)</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
Loading…
Reference in New Issue