GSdx: experimenting with msaa, add msaa=N to gsdx.ini to activate it (N=2,4,8)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1597 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-08-02 23:07:30 +00:00
parent 37b63f8a0c
commit cea0f395aa
36 changed files with 395 additions and 223 deletions

View File

@ -20,6 +20,7 @@
*/
#include "StdAfx.h"
#include "GSdx.h"
#include "GSDevice.h"
GSDevice::GSDevice()
@ -32,6 +33,11 @@ GSDevice::GSDevice()
, m_1x1(NULL)
{
memset(&m_vertices, 0, sizeof(m_vertices));
m_msaa = theApp.GetConfig("msaa", 0);
m_msaa_desc.Count = 1;
m_msaa_desc.Quality = 0;
}
GSDevice::~GSDevice()
@ -83,7 +89,7 @@ void GSDevice::Present(const GSVector4i& r, int shader, bool limit)
int w = std::max<int>(cr.width(), 1);
int h = std::max<int>(cr.height(), 1);
if(!m_backbuffer || m_backbuffer->m_size.x != w || m_backbuffer->m_size.y != h)
if(!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h)
{
if(!Reset(w, h, DontCare))
{
@ -103,15 +109,20 @@ void GSDevice::Present(const GSVector4i& r, int shader, bool limit)
Flip(limit);
}
GSTexture* GSDevice::Fetch(int type, int w, int h, int format)
GSTexture* GSDevice::Fetch(int type, int w, int h, bool msaa, int format)
{
if(m_msaa < 2)
{
msaa = false;
}
GSVector2i size(w, h);
for(list<GSTexture*>::iterator i = m_pool.begin(); i != m_pool.end(); i++)
{
GSTexture* t = *i;
if(t->GetType() == type && t->GetFormat() == format && t->GetSize() == size)
if(t->GetType() == type && t->GetFormat() == format && t->GetSize() == size && t->IsMSAA() == msaa)
{
m_pool.erase(i);
@ -119,7 +130,7 @@ GSTexture* GSDevice::Fetch(int type, int w, int h, int format)
}
}
return Create(type, w, h, format);
return Create(type, w, h, msaa, format);
}
void GSDevice::EndScene()
@ -143,24 +154,24 @@ void GSDevice::Recycle(GSTexture* t)
}
}
GSTexture* GSDevice::CreateRenderTarget(int w, int h, int format)
GSTexture* GSDevice::CreateRenderTarget(int w, int h, bool msaa, int format)
{
return Fetch(GSTexture::RenderTarget, w, h, format);
return Fetch(GSTexture::RenderTarget, w, h, msaa, format);
}
GSTexture* GSDevice::CreateDepthStencil(int w, int h, int format)
GSTexture* GSDevice::CreateDepthStencil(int w, int h, bool msaa, int format)
{
return Fetch(GSTexture::DepthStencil, w, h, format);
return Fetch(GSTexture::DepthStencil, w, h, msaa, format);
}
GSTexture* GSDevice::CreateTexture(int w, int h, int format)
{
return Fetch(GSTexture::Texture, w, h, format);
return Fetch(GSTexture::Texture, w, h, false, format);
}
GSTexture* GSDevice::CreateOffscreen(int w, int h, int format)
{
return Fetch(GSTexture::Offscreen, w, h, format);
return Fetch(GSTexture::Offscreen, w, h, false, format);
}
void GSDevice::StretchRect(GSTexture* st, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
@ -177,7 +188,7 @@ void GSDevice::Merge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, const GSVec
{
if(!m_merge || !(m_merge->GetSize() == fs))
{
m_merge = CreateRenderTarget(fs.x, fs.y);
m_merge = CreateRenderTarget(fs.x, fs.y, false);
}
// TODO: m_1x1
@ -188,7 +199,25 @@ void GSDevice::Merge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, const GSVec
if(m_merge)
{
DoMerge(st, sr, dr, m_merge, slbg, mmod, c);
GSTexture* tex[2] = {NULL, NULL};
for(int i = 0; i < countof(tex); i++)
{
if(st[i] != NULL)
{
tex[i] = st[i]->IsMSAA() ? Resolve(st[i]) : st[i];
}
}
DoMerge(tex, sr, dr, m_merge, slbg, mmod, c);
for(int i = 0; i < countof(tex); i++)
{
if(tex[i] != st[i])
{
Recycle(tex[i]);
}
}
}
else
{
@ -202,7 +231,7 @@ void GSDevice::Interlace(const GSVector2i& ds, int field, int mode, float yoffse
{
if(!m_weavebob || !(m_weavebob->GetSize() == ds))
{
m_weavebob = CreateRenderTarget(ds.x, ds.y);
m_weavebob = CreateRenderTarget(ds.x, ds.y, false);
}
if(mode == 0 || mode == 2) // weave or blend
@ -217,7 +246,7 @@ void GSDevice::Interlace(const GSVector2i& ds, int field, int mode, float yoffse
if(!m_blend || !(m_blend->GetSize() == ds))
{
m_blend = CreateRenderTarget(ds.x, ds.y);
m_blend = CreateRenderTarget(ds.x, ds.y, false);
}
DoInterlace(m_weavebob, m_blend, 2, false, 0);
@ -247,7 +276,7 @@ bool GSDevice::ResizeTexture(GSTexture** t, int w, int h)
GSTexture* t2 = *t;
if(t2 == NULL || t2->m_size.x != w || t2->m_size.y != h)
if(t2 == NULL || t2->GetWidth() != w || t2->GetHeight() != h)
{
delete t2;

View File

@ -50,7 +50,7 @@ class GSDevice : public GSAlignedClass<16>
{
list<GSTexture*> m_pool;
GSTexture* Fetch(int type, int w, int h, int format);
GSTexture* Fetch(int type, int w, int h, bool msaa, int format);
protected:
GSWnd* m_wnd;
@ -64,8 +64,10 @@ protected:
GSTexture* m_current;
struct {D3D_FEATURE_LEVEL level; string model, vs, gs, ps;} m_shader;
struct {size_t stride, start, count, limit;} m_vertices;
uint32 m_msaa;
DXGI_SAMPLE_DESC m_msaa_desc;
virtual GSTexture* Create(int type, int w, int h, int format) = 0;
virtual GSTexture* Create(int type, int w, int h, bool msaa, int format) = 0;
virtual void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) = 0;
virtual void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset) = 0;
@ -93,11 +95,13 @@ public:
virtual void ClearDepth(GSTexture* t, float c) {}
virtual void ClearStencil(GSTexture* t, uint8 c) {}
virtual GSTexture* CreateRenderTarget(int w, int h, int format = 0);
virtual GSTexture* CreateDepthStencil(int w, int h, int format = 0);
virtual GSTexture* CreateRenderTarget(int w, int h, bool msaa, int format = 0);
virtual GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
virtual GSTexture* CreateTexture(int w, int h, int format = 0);
virtual GSTexture* CreateOffscreen(int w, int h, int format = 0);
virtual GSTexture* Resolve(GSTexture* t) {return NULL;}
virtual GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0) {return NULL;}
virtual void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r) {}

View File

@ -43,7 +43,7 @@ bool GSDevice10::Create(GSWnd* wnd, bool vsync)
return false;
}
HRESULT hr;
HRESULT hr = E_FAIL;
DXGI_SWAP_CHAIN_DESC scd;
D3D10_BUFFER_DESC bd;
@ -66,7 +66,7 @@ bool GSDevice10::Create(GSWnd* wnd, bool vsync)
scd.SampleDesc.Quality = 0;
scd.Windowed = TRUE;
uint32 flags = D3D10_CREATE_DEVICE_SINGLETHREADED; //disables thread safety, should be fine (speedup)
uint32 flags = D3D10_CREATE_DEVICE_SINGLETHREADED;
#ifdef DEBUG
flags |= D3D10_CREATE_DEVICE_DEBUG;
@ -95,6 +95,22 @@ bool GSDevice10::Create(GSWnd* wnd, bool vsync)
if(FAILED(hr)) return false;
// msaa
for(uint32 i = 2; i <= D3D10_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
{
uint32 quality[2] = {0, 0};
if(SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, i, &quality[0])) && quality[0] > 0
&& SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, i, &quality[1])) && quality[1] > 0)
{
m_msaa_desc.Count = i;
m_msaa_desc.Quality = std::min<uint32>(quality[0] - 1, quality[1] - 1);
if(i >= m_msaa) break;
}
}
// convert
D3D10_INPUT_ELEMENT_DESC il_convert[] =
@ -179,7 +195,7 @@ bool GSDevice10::Create(GSWnd* wnd, bool vsync)
rd.SlopeScaledDepthBias = 0;
rd.DepthClipEnable = false; // ???
rd.ScissorEnable = true;
rd.MultisampleEnable = false;
rd.MultisampleEnable = true;
rd.AntialiasedLineEnable = false;
hr = m_dev->CreateRasterizerState(&rd, &m_rs);
@ -265,7 +281,7 @@ void GSDevice10::ClearStencil(GSTexture* t, uint8 c)
m_dev->ClearDepthStencilView(*(GSTexture10*)t, D3D10_CLEAR_STENCIL, 0, c);
}
GSTexture* GSDevice10::Create(int type, int w, int h, int format)
GSTexture* GSDevice10::Create(int type, int w, int h, bool msaa, int format)
{
HRESULT hr;
@ -282,6 +298,11 @@ GSTexture* GSDevice10::Create(int type, int w, int h, int format)
desc.SampleDesc.Quality = 0;
desc.Usage = D3D10_USAGE_DEFAULT;
if(msaa)
{
desc.SampleDesc = m_msaa_desc;
}
switch(type)
{
case GSTexture::RenderTarget:
@ -323,14 +344,14 @@ GSTexture* GSDevice10::Create(int type, int w, int h, int format)
return t;
}
GSTexture* GSDevice10::CreateRenderTarget(int w, int h, int format)
GSTexture* GSDevice10::CreateRenderTarget(int w, int h, bool msaa, int format)
{
return __super::CreateRenderTarget(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM);
return __super::CreateRenderTarget(w, h, msaa, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM);
}
GSTexture* GSDevice10::CreateDepthStencil(int w, int h, int format)
GSTexture* GSDevice10::CreateDepthStencil(int w, int h, bool msaa, int format)
{
return __super::CreateDepthStencil(w, h, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT); // DXGI_FORMAT_R32G8X24_TYPELESS
return __super::CreateDepthStencil(w, h, msaa, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT); // DXGI_FORMAT_R32G8X24_TYPELESS
}
GSTexture* GSDevice10::CreateTexture(int w, int h, int format)
@ -343,6 +364,22 @@ GSTexture* GSDevice10::CreateOffscreen(int w, int h, int format)
return __super::CreateOffscreen(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM);
}
GSTexture* GSDevice10::Resolve(GSTexture* t)
{
ASSERT(t != NULL && t->IsMSAA());
if(GSTexture* dst = CreateRenderTarget(t->GetWidth(), t->GetHeight(), false, t->GetFormat()))
{
dst->SetScale(t->GetScale());
m_dev->ResolveSubresource(*(GSTexture10*)dst, 0, *(GSTexture10*)t, 0, (DXGI_FORMAT)t->GetFormat());
return dst;
}
return NULL;
}
GSTexture* GSDevice10::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
{
GSTexture* dst = NULL;
@ -359,11 +396,16 @@ GSTexture* GSDevice10::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w,
return false;
}
if(GSTexture* rt = CreateRenderTarget(w, h, format))
if(GSTexture* rt = CreateRenderTarget(w, h, false, format))
{
GSVector4 dr(0, 0, w, h);
StretchRect(src, sr, rt, dr, m_convert.ps[format == DXGI_FORMAT_R16_UINT ? 1 : 0], NULL);
if(GSTexture* src2 = src->IsMSAA() ? Resolve(src) : src)
{
StretchRect(src2, sr, rt, dr, m_convert.ps[format == DXGI_FORMAT_R16_UINT ? 1 : 0], NULL);
if(src2 != src) Recycle(src2);
}
dst = CreateOffscreen(w, h, format);
@ -690,9 +732,9 @@ void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
m_dev->OMSetRenderTargets(1, &rtv, dsv);
}
if(m_state.viewport != rt->m_size)
if(m_state.viewport != rt->GetSize())
{
m_state.viewport = rt->m_size;
m_state.viewport = rt->GetSize();
D3D10_VIEWPORT vp;
@ -700,15 +742,15 @@ void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
vp.TopLeftX = 0;
vp.TopLeftY = 0;
vp.Width = rt->m_size.x;
vp.Height = rt->m_size.y;
vp.Width = rt->GetWidth();
vp.Height = rt->GetHeight();
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
m_dev->RSSetViewports(1, &vp);
}
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy();
if(!m_state.scissor.eq(r))
{

View File

@ -26,7 +26,7 @@
class GSDevice10 : public GSDevice
{
GSTexture* Create(int type, int w, int h, int format);
GSTexture* Create(int type, int w, int h, bool msaa, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);
@ -103,11 +103,13 @@ public:
void ClearDepth(GSTexture* t, float c);
void ClearStencil(GSTexture* t, uint8 c);
GSTexture* CreateRenderTarget(int w, int h, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, int format = 0);
GSTexture* CreateRenderTarget(int w, int h, bool msaa, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
GSTexture* CreateOffscreen(int w, int h, int format = 0);
GSTexture* Resolve(GSTexture* t);
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);

View File

@ -43,7 +43,7 @@ bool GSDevice11::Create(GSWnd* wnd, bool vsync)
return false;
}
HRESULT hr;
HRESULT hr = E_FAIL;
DXGI_SWAP_CHAIN_DESC scd;
D3D11_BUFFER_DESC bd;
@ -66,7 +66,7 @@ bool GSDevice11::Create(GSWnd* wnd, bool vsync)
scd.SampleDesc.Quality = 0;
scd.Windowed = TRUE;
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED; //disables thread safety, should be fine (speedup)
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
#ifdef DEBUG
flags |= D3D11_CREATE_DEVICE_DEBUG;
@ -95,6 +95,22 @@ bool GSDevice11::Create(GSWnd* wnd, bool vsync)
hr = m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &options, sizeof(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS));
// msaa
for(uint32 i = 2; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
{
uint32 quality[2] = {0, 0};
if(SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, i, &quality[0])) && quality[0] > 0
&& SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, i, &quality[1])) && quality[1] > 0)
{
m_msaa_desc.Count = i;
m_msaa_desc.Quality = std::min<uint32>(quality[0] - 1, quality[1] - 1);
if(i >= m_msaa) break;
}
}
// convert
D3D11_INPUT_ELEMENT_DESC il_convert[] =
@ -178,7 +194,7 @@ bool GSDevice11::Create(GSWnd* wnd, bool vsync)
rd.SlopeScaledDepthBias = 0;
rd.DepthClipEnable = false; // ???
rd.ScissorEnable = true;
rd.MultisampleEnable = false;
rd.MultisampleEnable = true;
rd.AntialiasedLineEnable = false;
hr = m_dev->CreateRasterizerState(&rd, &m_rs);
@ -264,7 +280,7 @@ void GSDevice11::ClearStencil(GSTexture* t, uint8 c)
m_ctx->ClearDepthStencilView(*(GSTexture11*)t, D3D11_CLEAR_STENCIL, 0, c);
}
GSTexture* GSDevice11::Create(int type, int w, int h, int format)
GSTexture* GSDevice11::Create(int type, int w, int h, bool msaa, int format)
{
HRESULT hr;
@ -281,6 +297,11 @@ GSTexture* GSDevice11::Create(int type, int w, int h, int format)
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
if(msaa)
{
desc.SampleDesc = m_msaa_desc;
}
switch(type)
{
case GSTexture::RenderTarget:
@ -322,14 +343,14 @@ GSTexture* GSDevice11::Create(int type, int w, int h, int format)
return t;
}
GSTexture* GSDevice11::CreateRenderTarget(int w, int h, int format)
GSTexture* GSDevice11::CreateRenderTarget(int w, int h, bool msaa, int format)
{
return __super::CreateRenderTarget(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM);
return __super::CreateRenderTarget(w, h, msaa, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM);
}
GSTexture* GSDevice11::CreateDepthStencil(int w, int h, int format)
GSTexture* GSDevice11::CreateDepthStencil(int w, int h, bool msaa, int format)
{
return __super::CreateDepthStencil(w, h, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
return __super::CreateDepthStencil(w, h, msaa, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
}
GSTexture* GSDevice11::CreateTexture(int w, int h, int format)
@ -342,6 +363,22 @@ GSTexture* GSDevice11::CreateOffscreen(int w, int h, int format)
return __super::CreateOffscreen(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM);
}
GSTexture* GSDevice11::Resolve(GSTexture* t)
{
ASSERT(t != NULL && t->IsMSAA());
if(GSTexture* dst = CreateRenderTarget(t->GetWidth(), t->GetHeight(), false, t->GetFormat()))
{
dst->SetScale(t->GetScale());
m_ctx->ResolveSubresource(*(GSTexture11*)dst, 0, *(GSTexture11*)t, 0, (DXGI_FORMAT)t->GetFormat());
return dst;
}
return NULL;
}
GSTexture* GSDevice11::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
{
GSTexture* dst = NULL;
@ -358,11 +395,16 @@ GSTexture* GSDevice11::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w,
return false;
}
if(GSTexture* rt = CreateRenderTarget(w, h, format))
if(GSTexture* rt = CreateRenderTarget(w, h, false, format))
{
GSVector4 dr(0, 0, w, h);
StretchRect(src, sr, rt, dr, m_convert.ps[format == DXGI_FORMAT_R16_UINT ? 1 : 0], NULL);
if(GSTexture* src2 = src->IsMSAA() ? Resolve(src) : src)
{
StretchRect(src2, sr, rt, dr, m_convert.ps[format == DXGI_FORMAT_R16_UINT ? 1 : 0], NULL);
if(src2 != src) Recycle(src2);
}
dst = CreateOffscreen(w, h, format);
@ -689,9 +731,9 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
}
if(m_state.viewport != rt->m_size)
if(m_state.viewport != rt->GetSize())
{
m_state.viewport = rt->m_size;
m_state.viewport = rt->GetSize();
D3D11_VIEWPORT vp;
@ -699,15 +741,15 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
vp.TopLeftX = 0;
vp.TopLeftY = 0;
vp.Width = rt->m_size.x;
vp.Height = rt->m_size.y;
vp.Width = rt->GetWidth();
vp.Height = rt->GetHeight();
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
m_ctx->RSSetViewports(1, &vp);
}
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy();
if(!m_state.scissor.eq(r))
{

View File

@ -26,7 +26,7 @@
class GSDevice11 : public GSDevice
{
GSTexture* Create(int type, int w, int h, int format);
GSTexture* Create(int type, int w, int h, bool msaa, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);
@ -104,11 +104,13 @@ public:
void ClearDepth(GSTexture* t, float c);
void ClearStencil(GSTexture* t, uint8 c);
GSTexture* CreateRenderTarget(int w, int h, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, int format = 0);
GSTexture* CreateRenderTarget(int w, int h, bool msaa, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
GSTexture* CreateOffscreen(int w, int h, int format = 0);
GSTexture* Resolve(GSTexture* t);
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);

View File

@ -145,7 +145,7 @@ void GSDevice7::Present(const GSVector4i& r, int shader, bool limit)
int w = std::max<int>(cr.width(), 1);
int h = std::max<int>(cr.height(), 1);
if(!m_backbuffer || m_backbuffer->m_size.x != w || m_backbuffer->m_size.y != h)
if(!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h)
{
if(!Reset(w, h, DontCare))
{
@ -198,7 +198,7 @@ void GSDevice7::Present(const GSVector4i& r, int shader, bool limit)
}
}
GSTexture* GSDevice7::Create(int type, int w, int h, int format)
GSTexture* GSDevice7::Create(int type, int w, int h, bool msaa, int format)
{
HRESULT hr;

View File

@ -31,7 +31,7 @@ private:
CComPtr<IDirectDrawSurface7> m_primary;
bool m_lost;
GSTexture* Create(int type, int w, int h, int format);
GSTexture* Create(int type, int w, int h, bool msaa, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);

View File

@ -124,6 +124,22 @@ bool GSDevice9::Create(GSWnd* wnd, bool vsync)
return false;
}
// msaa
for(uint32 i = 2; i <= 16; i++)
{
DWORD quality[2] = {0, 0};
if(SUCCEEDED(m_d3d->CheckDeviceMultiSampleType(m_d3dcaps.AdapterOrdinal, m_d3dcaps.DeviceType, D3DFMT_A8R8G8B8, TRUE, (D3DMULTISAMPLE_TYPE)i, &quality[0])) && quality[0] > 0
&& SUCCEEDED(m_d3d->CheckDeviceMultiSampleType(m_d3dcaps.AdapterOrdinal, m_d3dcaps.DeviceType, D3DFMT_D24S8, TRUE, (D3DMULTISAMPLE_TYPE)i, &quality[1])) && quality[1] > 0)
{
m_msaa_desc.Count = i;
m_msaa_desc.Quality = std::min<DWORD>(quality[0] - 1, quality[1] - 1);
if(i >= m_msaa) break;
}
}
//
if(!Reset(1, 1, theApp.GetConfig("windowed", 1) ? Windowed : Fullscreen))
@ -278,9 +294,13 @@ bool GSDevice9::Reset(int w, int h, int mode)
if(!m_dev)
{
//D3DCREATE_MULTITHREADED flag shouldn't be needed
uint32 flags = m_d3dcaps.VertexProcessingCaps ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING;
if(flags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
{
flags |= D3DCREATE_PUREDEVICE;
}
hr = m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, (HWND)m_wnd->GetHandle(), flags, &m_pp, &m_dev);
if(FAILED(hr)) return false;
@ -423,7 +443,7 @@ void GSDevice9::ClearRenderTarget(GSTexture* rt, uint32 c)
void GSDevice9::ClearDepth(GSTexture* t, float c)
{
GSTexture* rt = CreateRenderTarget(t->m_size.x, t->m_size.y);
GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight(), t->IsMSAA());
CComPtr<IDirect3DSurface9> rtsurface;
CComPtr<IDirect3DSurface9> dssurface;
@ -444,7 +464,7 @@ void GSDevice9::ClearDepth(GSTexture* t, float c)
void GSDevice9::ClearStencil(GSTexture* t, uint8 c)
{
GSTexture* rt = CreateRenderTarget(t->m_size.x, t->m_size.y);
GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight(), t->IsMSAA());
CComPtr<IDirect3DSurface9> rtsurface;
CComPtr<IDirect3DSurface9> dssurface;
@ -463,20 +483,23 @@ void GSDevice9::ClearStencil(GSTexture* t, uint8 c)
Recycle(rt);
}
GSTexture* GSDevice9::Create(int type, int w, int h, int format)
GSTexture* GSDevice9::Create(int type, int w, int h, bool msaa, int format)
{
HRESULT hr;
CComPtr<IDirect3DTexture9> texture;
CComPtr<IDirect3DSurface9> surface;
// TODO: msaa
switch(type)
{
case GSTexture::RenderTarget:
hr = m_dev->CreateTexture(w, h, 1, D3DUSAGE_RENDERTARGET, (D3DFORMAT)format, D3DPOOL_DEFAULT, &texture, NULL);
if(msaa) hr = m_dev->CreateRenderTarget(w, h, (D3DFORMAT)format, (D3DMULTISAMPLE_TYPE)m_msaa_desc.Count, m_msaa_desc.Quality, FALSE, &surface, NULL);
else hr = m_dev->CreateTexture(w, h, 1, D3DUSAGE_RENDERTARGET, (D3DFORMAT)format, D3DPOOL_DEFAULT, &texture, NULL);
break;
case GSTexture::DepthStencil:
hr = m_dev->CreateDepthStencilSurface(w, h, (D3DFORMAT)format, D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
hr = m_dev->CreateDepthStencilSurface(w, h, (D3DFORMAT)format, (D3DMULTISAMPLE_TYPE)m_msaa_desc.Count, m_msaa_desc.Quality, FALSE, &surface, NULL);
break;
case GSTexture::Texture:
hr = m_dev->CreateTexture(w, h, 1, 0, (D3DFORMAT)format, D3DPOOL_MANAGED, &texture, NULL);
@ -514,14 +537,14 @@ GSTexture* GSDevice9::Create(int type, int w, int h, int format)
return t;
}
GSTexture* GSDevice9::CreateRenderTarget(int w, int h, int format)
GSTexture* GSDevice9::CreateRenderTarget(int w, int h, bool msaa, int format)
{
return __super::CreateRenderTarget(w, h, format ? format : D3DFMT_A8R8G8B8);
return __super::CreateRenderTarget(w, h, msaa, format ? format : D3DFMT_A8R8G8B8);
}
GSTexture* GSDevice9::CreateDepthStencil(int w, int h, int format)
GSTexture* GSDevice9::CreateDepthStencil(int w, int h, bool msaa, int format)
{
return __super::CreateDepthStencil(w, h, format ? format : D3DFMT_D24S8);
return __super::CreateDepthStencil(w, h, msaa, format ? format : D3DFMT_D24S8);
}
GSTexture* GSDevice9::CreateTexture(int w, int h, int format)
@ -534,6 +557,22 @@ GSTexture* GSDevice9::CreateOffscreen(int w, int h, int format)
return __super::CreateOffscreen(w, h, format ? format : D3DFMT_A8R8G8B8);
}
GSTexture* GSDevice9::Resolve(GSTexture* t)
{
ASSERT(t != NULL && t->IsMSAA());
if(GSTexture* dst = CreateRenderTarget(t->GetWidth(), t->GetHeight(), false, t->GetFormat()))
{
dst->SetScale(t->GetScale());
m_dev->StretchRect(*(GSTexture9*)t, NULL, *(GSTexture9*)dst, NULL, D3DTEXF_POINT);
return dst;
}
return NULL;
}
GSTexture* GSDevice9::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
{
GSTexture* dst = NULL;
@ -550,11 +589,16 @@ GSTexture* GSDevice9::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w,
return false;
}
if(GSTexture* rt = CreateRenderTarget(w, h, format))
if(GSTexture* rt = CreateRenderTarget(w, h, false, format))
{
GSVector4 dr(0, 0, w, h);
StretchRect(src, sr, rt, dr, m_convert.ps[1], NULL, 0);
if(GSTexture* src2 = src->IsMSAA() ? Resolve(src) : src)
{
StretchRect(src2, sr, rt, dr, m_convert.ps[1], NULL, 0);
if(src2 != src) Recycle(src2);
}
dst = CreateOffscreen(w, h, format);
@ -933,7 +977,7 @@ void GSDevice9::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4
m_dev->SetDepthStencilSurface(dsv);
}
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy();
if(!m_state.scissor.eq(r))
{

View File

@ -61,7 +61,7 @@ struct Direct3DBlendState9
class GSDevice9 : public GSDevice
{
GSTexture* Create(int type, int w, int h, int format);
GSTexture* Create(int type, int w, int h, bool msaa, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);
@ -142,11 +142,13 @@ public:
void ClearDepth(GSTexture* t, float c);
void ClearStencil(GSTexture* t, uint8 c);
GSTexture* CreateRenderTarget(int w, int h, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, int format = 0);
GSTexture* CreateRenderTarget(int w, int h, bool msaa, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
GSTexture* CreateOffscreen(int w, int h, int format = 0);
GSTexture* Resolve(GSTexture* t);
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);

View File

@ -42,7 +42,7 @@ bool GSDeviceNull::Reset(int w, int h, int mode)
return true;
}
GSTexture* GSDeviceNull::Create(int type, int w, int h, int format)
GSTexture* GSDeviceNull::Create(int type, int w, int h, bool msaa, int format)
{
return new GSTextureNull(type, w, h, format);
}

View File

@ -27,7 +27,7 @@
class GSDeviceNull : public GSDevice
{
private:
GSTexture* Create(int type, int w, int h, int format);
GSTexture* Create(int type, int w, int h, bool msaa, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c) {}
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0) {}

View File

@ -252,7 +252,7 @@ void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
glClear(GL_STENCIL_BUFFER_BIT); CheckError();
}
GSTexture* GSDeviceOGL::Create(int type, int w, int h, int format)
GSTexture* GSDeviceOGL::Create(int type, int w, int h, bool msaa, int format)
{
GLuint texture = 0;
@ -296,14 +296,14 @@ GSTexture* GSDeviceOGL::Create(int type, int w, int h, int format)
return t;
}
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, int format)
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, bool msaa, int format)
{
return __super::CreateRenderTarget(w, h, format ? format : GL_RGBA8);
return __super::CreateRenderTarget(w, h, msaa, format ? format : GL_RGBA8);
}
GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, int format)
GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, bool msaa, int format)
{
return __super::CreateDepthStencil(w, h, format ? format : GL_DEPTH32F_STENCIL8); // TODO: GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8
return __super::CreateDepthStencil(w, h, msaa, format ? format : GL_DEPTH32F_STENCIL8); // TODO: GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8
}
GSTexture* GSDeviceOGL::CreateTexture(int w, int h, int format)
@ -509,14 +509,14 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, dsi); CheckError();
}
if(m_viewport != rt->m_size)
if(m_viewport != rt->GetSize())
{
m_viewport = rt->m_size;
m_viewport = rt->GetSize();
glViewport(0, 0, rt->m_size.x, rt->m_size.y); CheckError();
glViewport(0, 0, rt->GetWidth(), rt->GetHeight()); CheckError();
}
GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy();
GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy();
if(!m_scissor.eq(r))
{

View File

@ -100,7 +100,7 @@ class GSDeviceOGL : public GSDevice
//
GSTexture* Create(int type, int w, int h, int format);
GSTexture* Create(int type, int w, int h, bool msaa, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);
@ -121,8 +121,8 @@ public:
void ClearDepth(GSTexture* t, float c);
void ClearStencil(GSTexture* t, uint8 c);
GSTexture* CreateRenderTarget(int w, int h, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, int format = 0);
GSTexture* CreateRenderTarget(int w, int h, bool msaa, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
GSTexture* CreateOffscreen(int w, int h, int format = 0);

View File

@ -208,7 +208,7 @@ bool GSRenderer::Merge(int field)
r += GSVector4i(0, 1).xyxy();
}
GSVector4 scale = GSVector4(tex[i]->m_scale).xyxy();
GSVector4 scale = GSVector4(tex[i]->GetScale()).xyxy();
src[i] = GSVector4(r) * scale / GSVector4(tex[i]->GetSize()).xyxy();
@ -216,7 +216,7 @@ bool GSRenderer::Merge(int field)
if(dr[i].top - baseline >= 4) // 2?
{
o.y = tex[i]->m_scale.y * (dr[i].top - baseline);
o.y = tex[i]->GetScale().y * (dr[i].top - baseline);
if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD)
{
@ -251,7 +251,7 @@ bool GSRenderer::Merge(int field)
int field2 = 1 - ((m_interlace - 1) & 1);
int mode = (m_interlace - 1) >> 1;
m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->m_scale.y : tex[0]->m_scale.y);
m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y);
}
}

View File

@ -163,12 +163,12 @@ public:
GSTextureFX::VSConstantBuffer vs_cb;
float sx = 2.0f * rt->m_scale.x / (rt->m_size.x << 4);
float sy = 2.0f * rt->m_scale.y / (rt->m_size.y << 4);
float sx = 2.0f * rt->GetScale().x / (rt->GetWidth() << 4);
float sy = 2.0f * rt->GetScale().y / (rt->GetHeight() << 4);
float ox = (float)(int)context->XYOFFSET.OFX;
float oy = (float)(int)context->XYOFFSET.OFY;
float ox2 = 2.0f * m_pixelcenter.x / rt->m_size.x;
float oy2 = 2.0f * m_pixelcenter.y / rt->m_size.y;
float ox2 = 2.0f * m_pixelcenter.x / rt->GetWidth();
float oy2 = 2.0f * m_pixelcenter.y / rt->GetHeight();
vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f);
vs_cb.VertexOffset = GSVector4(ox * sx + ox2 + 1, -(oy * sy + oy2 + 1), 0.0f, -1.0f);
@ -230,8 +230,8 @@ public:
ps_sel.ltf = m_filter == 2 ? IsLinear() : m_filter;
ps_sel.rt = tex->m_target;
int w = tex->m_texture->m_size.x;
int h = tex->m_texture->m_size.y;
int w = tex->m_texture->GetWidth();
int h = tex->m_texture->GetHeight();
int tw = (int)(1 << context->TEX0.TW);
int th = (int)(1 << context->TEX0.TH);
@ -266,7 +266,7 @@ public:
// rs
GSVector4i scissor = GSVector4i(GSVector4(rt->m_scale).xyxy() * context->scissor.in).rintersect(GSVector4i(rt->GetSize()).zwxy());
GSVector4i scissor = GSVector4i(GSVector4(rt->GetScale()).xyxy() * context->scissor.in).rintersect(GSVector4i(rt->GetSize()).zwxy());
m_dev->OMSetRenderTargets(rt, ds, &scissor);
m_dev->PSSetShaderResources(tex ? tex->m_texture : NULL, tex ? tex->m_palette : NULL);

View File

@ -199,9 +199,9 @@ void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds)
GSDevice10* dev = (GSDevice10*)m_dev;
const GSVector2i& size = rt->m_size;
const GSVector2i& size = rt->GetSize();
if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y))
if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y, rt->IsMSAA()))
{
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
@ -217,7 +217,7 @@ void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds)
// ia
GSVector4 s = GSVector4(rt->m_scale.x / size.x, rt->m_scale.y / size.y);
GSVector4 s = GSVector4(rt->GetScale().x / size.x, rt->GetScale().y / size.y);
GSVector4 o = GSVector4(-1.0f, 1.0f);
GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy());
@ -245,7 +245,9 @@ void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds)
// ps
dev->PSSetShaderResources(rt, NULL);
GSTexture* rt2 = rt->IsMSAA() ? dev->Resolve(rt) : rt;
dev->PSSetShaderResources(rt2, NULL);
dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL);
dev->PSSetSamplerState(dev->m_convert.pt, NULL);
@ -258,5 +260,7 @@ void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds)
dev->EndScene();
dev->Recycle(t);
if(rt2 != rt) dev->Recycle(rt2);
}
}

View File

@ -199,9 +199,9 @@ void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds)
GSDevice11* dev = (GSDevice11*)m_dev;
const GSVector2i& size = rt->m_size;
const GSVector2i& size = rt->GetSize();
if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y))
if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y, rt->IsMSAA()))
{
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
@ -217,7 +217,7 @@ void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds)
// ia
GSVector4 s = GSVector4(rt->m_scale.x / size.x, rt->m_scale.y / size.y);
GSVector4 s = GSVector4(rt->GetScale().x / size.x, rt->GetScale().y / size.y);
GSVector4 o = GSVector4(-1.0f, 1.0f);
GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy());
@ -245,7 +245,9 @@ void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds)
// ps
dev->PSSetShaderResources(rt, NULL);
GSTexture* rt2 = rt->IsMSAA() ? dev->Resolve(rt) : rt;
dev->PSSetShaderResources(rt2, NULL);
dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL);
dev->PSSetSamplerState(dev->m_convert.pt, NULL);
@ -258,5 +260,7 @@ void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds)
dev->EndScene();
dev->Recycle(t);
if(rt2 != rt) dev->Recycle(rt2);
}
}

View File

@ -216,9 +216,9 @@ void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds)
GSDevice9* dev = (GSDevice9*)m_dev;
const GSVector2i& size = rt->m_size;
const GSVector2i& size = rt->GetSize();
if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y))
if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y, rt->IsMSAA()))
{
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
@ -234,7 +234,7 @@ void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds)
// ia
GSVector4 s = GSVector4(rt->m_scale.x / size.x, rt->m_scale.y / size.y);
GSVector4 s = GSVector4(rt->GetScale().x / size.x, rt->GetScale().y / size.y);
GSVector4 o = GSVector4(-1.0f, 1.0f);
GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy());
@ -258,7 +258,9 @@ void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds)
// ps
dev->PSSetShaderResources(rt, NULL);
GSTexture* rt2 = rt->IsMSAA() ? dev->Resolve(rt) : rt;
dev->PSSetShaderResources(rt2, NULL);
dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL, 0);
dev->PSSetSamplerState(&dev->m_convert.pt);
@ -271,6 +273,8 @@ void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds)
dev->EndScene();
dev->Recycle(t);
if(rt2 != rt) dev->Recycle(rt2);
}
}
@ -287,7 +291,7 @@ void GSRendererDX9::UpdateFBA(GSTexture* rt)
// ia
GSVector4 s = GSVector4(rt->m_scale.x / rt->m_size.x, rt->m_scale.y / rt->m_size.y);
GSVector4 s = GSVector4(rt->GetScale().x / rt->GetWidth(), rt->GetScale().y / rt->GetHeight());
GSVector4 o = GSVector4(-1.0f, 1.0f);
GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy());

View File

@ -21,3 +21,11 @@
#include "StdAfx.h"
#include "GSTexture.h"
GSTexture::GSTexture()
: m_scale(1, 1)
, m_size(0, 0)
, m_type(None)
, m_msaa(false)
{
}

View File

@ -25,30 +25,38 @@
class GSTexture
{
public:
protected:
GSVector2 m_scale;
GSVector2i m_size;
int m_type;
int m_format;
bool m_msaa;
public:
struct GSMap {uint8* bits; int pitch;};
enum {None, RenderTarget, DepthStencil, Texture, Offscreen};
public:
GSTexture() : m_scale(1, 1), m_size(0, 0) {}
GSTexture();
virtual ~GSTexture() {}
virtual operator bool() {ASSERT(0); return false;}
virtual int GetType() const = 0;
virtual int GetFormat() const = 0;
virtual bool Update(const GSVector4i& r, const void* data, int pitch) = 0;
virtual bool Map(GSMap& m, const GSVector4i* r = NULL) = 0;
virtual void Unmap() = 0;
virtual bool Save(const string& fn, bool dds = false) = 0;
GSVector2 GetScale() const {return m_scale;}
void SetScale(const GSVector2& scale) {m_scale = scale;}
int GetWidth() const {return m_size.x;}
int GetHeight() const {return m_size.y;}
GSVector2i GetSize() const {return m_size;}
int GetType() const {return m_type;}
int GetFormat() const {return m_format;}
bool IsMSAA() const {return m_msaa;}
};

View File

@ -32,20 +32,15 @@ GSTexture10::GSTexture10(ID3D10Texture2D* texture)
m_size.x = (int)m_desc.Width;
m_size.y = (int)m_desc.Height;
}
int GSTexture10::GetType() const
{
if(m_desc.BindFlags & D3D10_BIND_RENDER_TARGET) return GSTexture::RenderTarget;
if(m_desc.BindFlags & D3D10_BIND_DEPTH_STENCIL) return GSTexture::DepthStencil;
if(m_desc.BindFlags & D3D10_BIND_SHADER_RESOURCE) return GSTexture::Texture;
if(m_desc.Usage == D3D10_USAGE_STAGING) return GSTexture::Offscreen;
return GSTexture::None;
}
if(m_desc.BindFlags & D3D10_BIND_RENDER_TARGET) m_type = RenderTarget;
else if(m_desc.BindFlags & D3D10_BIND_DEPTH_STENCIL) m_type = DepthStencil;
else if(m_desc.BindFlags & D3D10_BIND_SHADER_RESOURCE) m_type = Texture;
else if(m_desc.Usage == D3D10_USAGE_STAGING) m_type = Offscreen;
int GSTexture10::GetFormat() const
{
return m_desc.Format;
m_format = (int)m_desc.Format;
m_msaa = m_desc.SampleDesc.Count > 1;
}
bool GSTexture10::Update(const GSVector4i& r, const void* data, int pitch)
@ -162,6 +157,8 @@ GSTexture10::operator ID3D10ShaderResourceView*()
{
if(!m_srv && m_dev && m_texture)
{
ASSERT(!m_msaa);
D3D10_SHADER_RESOURCE_VIEW_DESC* desc = NULL;
if(m_desc.Format == DXGI_FORMAT_R32G8X24_TYPELESS)

View File

@ -35,9 +35,6 @@ class GSTexture10 : public GSTexture
public:
explicit GSTexture10(ID3D10Texture2D* texture);
int GetType() const;
int GetFormat() const;
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();

View File

@ -34,20 +34,15 @@ GSTexture11::GSTexture11(ID3D11Texture2D* texture)
m_size.x = (int)m_desc.Width;
m_size.y = (int)m_desc.Height;
}
int GSTexture11::GetType() const
{
if(m_desc.BindFlags & D3D11_BIND_RENDER_TARGET) return GSTexture::RenderTarget;
if(m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) return GSTexture::DepthStencil;
if(m_desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) return GSTexture::Texture;
if(m_desc.Usage == D3D11_USAGE_STAGING) return GSTexture::Offscreen;
return GSTexture::None;
}
if(m_desc.BindFlags & D3D11_BIND_RENDER_TARGET) m_type = RenderTarget;
else if(m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) m_type = DepthStencil;
else if(m_desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) m_type = Texture;
else if(m_desc.Usage == D3D11_USAGE_STAGING) m_type = Offscreen;
int GSTexture11::GetFormat() const
{
return m_desc.Format;
m_format = (int)m_desc.Format;
m_msaa = m_desc.SampleDesc.Count > 1;
}
bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch)
@ -164,6 +159,8 @@ GSTexture11::operator ID3D11ShaderResourceView*()
{
if(!m_srv && m_dev && m_texture)
{
ASSERT(!m_msaa);
m_dev->CreateShaderResourceView(m_texture, NULL, &m_srv);
}

View File

@ -36,9 +36,6 @@ class GSTexture11 : public GSTexture
public:
explicit GSTexture11(ID3D11Texture2D* texture);
int GetType() const;
int GetFormat() const;
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();

View File

@ -23,8 +23,7 @@
#include "GSTexture7.h"
GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system)
: m_type(type)
, m_system(system)
: m_system(system)
{
memset(&m_desc, 0, sizeof(m_desc));
@ -34,11 +33,14 @@ GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system)
m_size.x = (int)m_desc.dwWidth;
m_size.y = (int)m_desc.dwHeight;
m_type = type;
m_format = (int)m_desc.ddpfPixelFormat.dwFourCC;
}
GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface7* video)
: m_type(type)
, m_system(system)
: m_system(system)
, m_video(video)
{
memset(&m_desc, 0, sizeof(m_desc));
@ -49,16 +51,10 @@ GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface
m_size.x = (int)m_desc.dwWidth;
m_size.y = (int)m_desc.dwHeight;
}
int GSTexture7::GetType() const
{
return m_type;
}
m_type = type;
int GSTexture7::GetFormat() const
{
return (int)m_desc.ddpfPixelFormat.dwFourCC;
m_format = (int)m_desc.ddpfPixelFormat.dwFourCC;
}
bool GSTexture7::Update(const GSVector4i& r, const void* data, int pitch)

View File

@ -26,7 +26,6 @@
class GSTexture7 : public GSTexture
{
int m_type;
CComPtr<IDirectDrawSurface7> m_system;
CComPtr<IDirectDrawSurface7> m_video;
DDSURFACEDESC2 m_desc;
@ -35,9 +34,6 @@ public:
GSTexture7(int type, IDirectDrawSurface7* system);
GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface7* video);
int GetType() const;
int GetFormat() const;
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();

View File

@ -38,6 +38,15 @@ GSTexture9::GSTexture9(IDirect3DSurface9* surface)
m_size.x = (int)m_desc.Width;
m_size.y = (int)m_desc.Height;
if(m_desc.Usage & D3DUSAGE_RENDERTARGET) m_type = RenderTarget;
else if(m_desc.Usage & D3DUSAGE_DEPTHSTENCIL) m_type = DepthStencil;
else if(m_desc.Pool == D3DPOOL_MANAGED) m_type = Texture;
else if(m_desc.Pool == D3DPOOL_SYSTEMMEM) m_type = Offscreen;
m_format = (int)m_desc.Format;
m_msaa = m_desc.MultiSampleType != D3DMULTISAMPLE_NONE;
}
GSTexture9::GSTexture9(IDirect3DTexture9* texture)
@ -52,26 +61,21 @@ GSTexture9::GSTexture9(IDirect3DTexture9* texture)
m_size.x = (int)m_desc.Width;
m_size.y = (int)m_desc.Height;
if(m_desc.Usage & D3DUSAGE_RENDERTARGET) m_type = RenderTarget;
else if(m_desc.Usage & D3DUSAGE_DEPTHSTENCIL) m_type = DepthStencil;
else if(m_desc.Pool == D3DPOOL_MANAGED) m_type = Texture;
else if(m_desc.Pool == D3DPOOL_SYSTEMMEM) m_type = Offscreen;
m_format = (int)m_desc.Format;
m_msaa = m_desc.MultiSampleType > 1;
}
GSTexture9::~GSTexture9()
{
}
int GSTexture9::GetType() const
{
if(m_desc.Usage & D3DUSAGE_RENDERTARGET) return GSTexture::RenderTarget;
if(m_desc.Usage & D3DUSAGE_DEPTHSTENCIL) return GSTexture::DepthStencil;
if(m_desc.Pool == D3DPOOL_MANAGED) return GSTexture::Texture;
if(m_desc.Pool == D3DPOOL_SYSTEMMEM) return GSTexture::Offscreen;
return GSTexture::None;
}
int GSTexture9::GetFormat() const
{
return m_desc.Format;
}
bool GSTexture9::Update(const GSVector4i& r, const void* data, int pitch)
{
if(m_surface)

View File

@ -35,9 +35,6 @@ public:
explicit GSTexture9(IDirect3DTexture9* texture);
virtual ~GSTexture9();
int GetType() const;
int GetFormat() const;
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();

View File

@ -190,8 +190,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
if(ww > 0 && hh > 0)
{
dst->m_texture->m_scale.x = (float)w / ww;
dst->m_texture->m_scale.y = (float)h / hh;
dst->m_texture->SetScale(GSVector2((float)w / ww, (float)h / hh));
}
}
@ -527,10 +526,19 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
dst->Update();
GSTexture* tmp = NULL;
if(dst->m_texture->IsMSAA())
{
tmp = dst->m_texture;
dst->m_texture = m_renderer->m_dev->Resolve(dst->m_texture);
}
// 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);
int w = (int)(dst->m_texture->GetScale().x * tw);
int h = (int)(dst->m_texture->GetScale().y * th);
GSVector2i dstsize = dst->m_texture->GetSize();
@ -542,10 +550,10 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
// 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);
src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false);
GSVector4 size = GSVector4(dstsize).xyxy();
GSVector4 scale = GSVector4(dst->m_texture->m_scale).xyxy();
GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy();
int bw = 64;
int bh = TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 ? 32 : 64;
@ -588,28 +596,28 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
// width/height conversion
GSVector2 scale = dst->m_texture->m_scale;
GSVector2 scale = dst->m_texture->GetScale();
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;
dr.z = (float)dstsize.x * scale.x / dst->m_texture->GetScale().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;
dr.w = (float)dstsize.y * scale.y / dst->m_texture->GetScale().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);
GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h, false);
if(!src->m_texture)
{
@ -622,8 +630,8 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
}
else
{
sr.z /= st->m_size.x;
sr.w /= st->m_size.y;
sr.z /= st->GetWidth();
sr.w /= st->GetHeight();
m_renderer->m_dev->StretchRect(st, sr, dt, dr);
}
@ -635,7 +643,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_texture = dt;
}
src->m_texture->m_scale = scale;
src->m_texture->SetScale(scale);
switch(TEX0.PSM)
{
@ -664,6 +672,13 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
break;
}
if(tmp != NULL)
{
m_renderer->m_dev->Recycle(dst->m_texture);
dst->m_texture = tmp;
}
}
if(src->m_texture == NULL)
@ -697,13 +712,13 @@ GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int
if(type == RenderTarget)
{
t->m_texture = m_renderer->m_dev->CreateRenderTarget(w, h);
t->m_texture = m_renderer->m_dev->CreateRenderTarget(w, h, true);
t->m_used = true; // FIXME
}
else if(type == DepthStencil)
{
t->m_texture = m_renderer->m_dev->CreateDepthStencil(w, h);
t->m_texture = m_renderer->m_dev->CreateDepthStencil(w, h, true);
}
if(t->m_texture == NULL)
@ -1008,7 +1023,7 @@ void GSTextureCache::Target::Update()
// m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, w * h * 4);
m_renderer->m_dev->StretchRect(t, m_texture, GSVector4(r) * GSVector4(m_texture->m_scale).xyxy());
m_renderer->m_dev->StretchRect(t, m_texture, GSVector4(r) * GSVector4(m_texture->GetScale()).xyxy());
m_renderer->m_dev->Recycle(t);
}

View File

@ -60,7 +60,7 @@ void GSTextureCache10::Read(Target* t, const GSVector4i& r)
int w = r.width();
int h = r.height();
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->m_scale).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;

View File

@ -60,7 +60,7 @@ void GSTextureCache11::Read(Target* t, const GSVector4i& r)
int w = r.width();
int h = r.height();
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->m_scale).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;

View File

@ -60,7 +60,7 @@ void GSTextureCache9::Read(Target* t, const GSVector4i& r)
int w = r.width();
int h = r.height();
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->m_scale).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(t->m_texture, src, w, h))
{

View File

@ -25,8 +25,6 @@
GSTextureOGL::GSTextureOGL(GLuint texture, int type, int width, int height, int format)
: m_texture(texture)
, m_type(type)
, m_format(format)
{
m_size.x = width;
m_size.y = height;
@ -34,6 +32,10 @@ GSTextureOGL::GSTextureOGL(GLuint texture, int type, int width, int height, int
// TODO: offscreen type should be just a memory array, also returned in Map
glGenBuffers(1, &m_pbo); GSDeviceOGL::CheckError();
m_type = type;
m_format = format;
}
GSTextureOGL::~GSTextureOGL()
@ -57,16 +59,6 @@ GSTextureOGL::~GSTextureOGL()
}
}
int GSTextureOGL::GetType() const
{
return m_type;
}
int GSTextureOGL::GetFormat() const
{
return m_format;
}
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo); GSDeviceOGL::CheckError();

View File

@ -35,9 +35,6 @@ public:
GSTextureOGL(GLuint texture, int type, int width, int height, int format = 0);
virtual ~GSTextureOGL();
int GetType() const;
int GetFormat() const;
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();

View File

@ -138,12 +138,10 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
@ -160,7 +158,6 @@
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug SSE2|Win32'">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug SSE2|X64'">
@ -171,7 +168,6 @@
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release SSE2|Win32'">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
@ -183,7 +179,6 @@
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release SSSE3|Win32'">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
@ -195,7 +190,6 @@
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug SSSE3|Win32'">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug SSSE3|X64'">
@ -205,7 +199,6 @@
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug SSE4|Win32'">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug SSE4|X64'">
@ -215,7 +208,6 @@
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release SSE4|Win32'">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>