This commit is contained in:
gabest
2008-12-06 20:22:55 +00:00
parent d1b7b97774
commit 49cf6935f2
15 changed files with 631 additions and 68 deletions

View File

@@ -22,6 +22,7 @@
#include "stdafx.h"
#include "GSUtil.h"
#include "GPURendererSW.h"
#include "GSDevice7.h"
#include "GSDevice9.h"
#include "GSDevice10.h"
#include "GPUSettingsDlg.h"
@@ -112,10 +113,10 @@ EXPORT_C_(INT32) GPUopen(HWND hWnd)
switch(renderer)
{
default:
// TODO: case 0: s_gpu = new GPURendererSW<GSDevice7>(rs); break;
case 0: s_gpu = new GPURendererSW<GSDevice7>(rs, threads); break;
case 1: s_gpu = new GPURendererSW<GSDevice9>(rs, threads); break;
case 2: s_gpu = new GPURendererSW<GSDevice10>(rs, threads); break;
// TODO: case 3: s_gpu = new GPURendererNull<GSDeviceNull>(rs); break;
// TODO: case 3: s_gpu = new GPURendererNull<GSDeviceNull>(rs, threads); break;
}
s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);

View File

@@ -28,7 +28,7 @@
GSSetting GPUSettingsDlg::g_renderers[] =
{
// {0, _T("Direct3D7 (Software)"), NULL},
{0, _T("Direct3D7 (Software)"), NULL},
{1, _T("Direct3D9 (Software)"), NULL},
{2, _T("Direct3D10 (Software)"), NULL},
// {3, _T("Null (Null)"), NULL},

241
gsdx/GSDevice7.cpp Normal file
View File

@@ -0,0 +1,241 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
// dumb device implementation, only good for simple image output
#include "stdafx.h"
#include "GSDevice7.h"
GSDevice7::GSDevice7()
{
}
GSDevice7::~GSDevice7()
{
}
bool GSDevice7::Create(HWND hWnd, bool vsync)
{
if(!__super::Create(hWnd, vsync))
{
return false;
}
if(FAILED(DirectDrawCreateEx(NULL, (VOID**)&m_dd, IID_IDirectDraw7, NULL)))
{
return false;
}
// TODO: fullscreen
if(FAILED(m_dd->SetCooperativeLevel(hWnd, DDSCL_NORMAL)))
{
return false;
}
DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if(FAILED(m_dd->CreateSurface(&desc, &m_primary, NULL)))
{
return false;
}
CComPtr<IDirectDrawClipper> clipper;
if(FAILED(m_dd->CreateClipper(0, &clipper, NULL))
|| FAILED(clipper->SetHWnd(0, hWnd))
|| FAILED(m_primary->SetClipper(clipper)))
{
return false;
}
Reset(1, 1, true);
return true;
}
bool GSDevice7::Reset(int w, int h, bool fs)
{
if(!__super::Reset(w, h, fs))
return false;
m_backbuffer = NULL;
DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE;
desc.dwWidth = w;
desc.dwHeight = h;
if(FAILED(m_dd->CreateSurface(&desc, &m_backbuffer, NULL)))
{
return false;
}
CComPtr<IDirectDrawClipper> clipper;
if(FAILED(m_dd->CreateClipper(0, &clipper, NULL)))
{
return false;
}
{
// ???
HRGN hrgn = CreateRectRgn(0, 0, w, h);
BYTE buff[1024];
GetRegionData(hrgn, sizeof(buff), (RGNDATA*)buff);
DeleteObject(hrgn);
clipper->SetClipList((RGNDATA*)buff, 0);
if(FAILED(m_backbuffer->SetClipper(clipper)))
{
return false;
}
}
return true;
}
void GSDevice7::Present(const CRect& r)
{
HRESULT hr;
CRect cr;
GetClientRect(m_hWnd, &cr);
DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
hr = m_backbuffer->GetSurfaceDesc(&desc);
if(desc.dwWidth != cr.Width() || desc.dwHeight != cr.Height())
{
Reset(cr.Width(), cr.Height(), false);
}
DDBLTFX fx;
memset(&fx, 0, sizeof(fx));
fx.dwSize = sizeof(fx);
fx.dwFillColor = 0;
hr = m_backbuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
CRect r2 = r;
hr = m_backbuffer->Blt(&r2, m_merge, NULL, DDBLT_WAIT, NULL);
r2 = cr;
MapWindowPoints(m_hWnd, HWND_DESKTOP, (POINT*)&r2, 2);
if(m_vsync)
{
hr = m_dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
}
hr = m_primary->Blt(&r2, m_backbuffer, &cr, DDBLT_WAIT, NULL);
if(hr == DDERR_SURFACELOST)
{
// TODO
HRESULT hr = m_dd->TestCooperativeLevel();
if(hr == DDERR_WRONGMODE)
{
}
}
}
bool GSDevice7::Create(int type, Texture& t, int w, int h, int format)
{
HRESULT hr;
t = Texture();
DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
desc.dwWidth = w;
desc.dwHeight = h;
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
desc.ddpfPixelFormat.dwRGBBitCount = 32;
desc.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000;
desc.ddpfPixelFormat.dwRBitMask = 0x00ff0000;
desc.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
desc.ddpfPixelFormat.dwBBitMask = 0x000000ff;
CComPtr<IDirectDrawSurface7> system, video;
switch(type)
{
case GSTexture::RenderTarget:
case GSTexture::DepthStencil:
case GSTexture::Texture:
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
if(FAILED(hr = m_dd->CreateSurface(&desc, &system, NULL))) return false;
desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
if(FAILED(hr = m_dd->CreateSurface(&desc, &video, NULL))) return false;
t = Texture(type, system, video);
break;
case GSTexture::Offscreen:
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
if(FAILED(hr = m_dd->CreateSurface(&desc, &system, NULL))) return false;
t = Texture(type, system, video);
break;
}
return !!t;
}
void GSDevice7::DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c)
{
HRESULT hr;
hr = dt->Blt(NULL, st[0], NULL, DDBLT_WAIT, NULL);
}
void GSDevice7::DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset)
{
}

58
gsdx/GSDevice7.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GSDevice.h"
#include "GSTexture7.h"
class GSDevice7 : public GSDevice<GSTexture7>
{
public:
typedef GSTexture7 Texture;
private:
CComPtr<IDirectDraw7> m_dd;
CComPtr<IDirectDrawSurface7> m_primary;
CComPtr<IDirectDrawSurface7> m_backbuffer;
bool Create(int type, Texture& t, int w, int h, int format);
void DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c);
void DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset = 0);
public:
GSDevice7();
virtual ~GSDevice7();
bool Create(HWND hWnd, bool vsync);
bool Reset(int w, int h, bool fs);
bool IsLost() {return false;}
void Present(const CRect& r);
void BeginScene() {}
void EndScene() {}
void Draw(LPCTSTR str) {}
bool CopyOffscreen(Texture& src, const GSVector4& sr, Texture& dst, int w, int h, int format = 0) {return false;}
void ClearRenderTarget(Texture& t, const GSVector4& c) {}
void ClearRenderTarget(Texture& t, DWORD c) {}
void ClearDepth(Texture& t, float c) {}
void ClearStencil(Texture& t, BYTE c) {}
};

View File

@@ -535,3 +535,64 @@ DWORD GSRasterizerMT::ThreadProc()
return 0;
}
//
GSRasterizerList::GSRasterizerList()
{
// get a whole cache line (twice the size for future cpus ;)
m_sync = (long*)_aligned_malloc(sizeof(*m_sync), 128);
}
GSRasterizerList::~GSRasterizerList()
{
_aligned_free(m_sync);
FreeRasterizers();
}
void GSRasterizerList::FreeRasterizers()
{
while(!IsEmpty())
{
delete RemoveHead();
}
}
int GSRasterizerList::Draw(GSVertexSW* vertices, int count, const void* texture)
{
*m_sync = 0;
int prims = 0;
POSITION pos = GetHeadPosition();
while(pos)
{
GSRasterizerMT* r = GetNext(pos);
prims += r->Draw(vertices, count, texture);
}
while(*m_sync)
{
_mm_pause();
}
return prims;
}
int GSRasterizerList::GetPixels()
{
int pixels = 0;
POSITION pos = GetHeadPosition();
while(pos)
{
pixels += GetNext(pos)->GetPixels();
}
return pixels;
}

View File

@@ -101,28 +101,11 @@ class GSRasterizerList : public CAtlList<GSRasterizerMT*>
{
long* m_sync;
void FreeRasterizers()
{
while(!IsEmpty())
{
delete RemoveHead();
}
}
void FreeRasterizers();
public:
GSRasterizerList()
{
// get a whole cache line (twice the size for future cpus ;)
m_sync = (long*)_aligned_malloc(sizeof(*m_sync), 128);
}
virtual ~GSRasterizerList()
{
_aligned_free(m_sync);
FreeRasterizers();
}
GSRasterizerList();
virtual ~GSRasterizerList();
template<class DS, class T> void Create(T* parent, IDrawAsync* da, int threads)
{
@@ -136,42 +119,6 @@ public:
}
}
int Draw(GSVertexSW* vertices, int count, const void* texture)
{
*m_sync = 0;
int prims = 0;
POSITION pos = GetHeadPosition();
while(pos)
{
GSRasterizerMT* r = GetNext(pos);
prims += r->Draw(vertices, count, texture);
}
// wait for the other threads to finish
while(*m_sync)
{
_mm_pause();
}
return prims;
}
int GetPixels()
{
int pixels = 0;
POSITION pos = GetHeadPosition();
while(pos)
{
pixels += GetNext(pos)->GetPixels();
}
return pixels;
}
};
int Draw(GSVertexSW* vertices, int count, const void* texture);
int GetPixels();
};

View File

@@ -39,7 +39,7 @@ public:
virtual int GetWidth() const = 0;
virtual int GetHeight() const = 0;
virtual int GetFormat() const = 0;
virtual bool Update(CRect r, const void* data, int pitch) = 0;
virtual bool Update(const CRect& r, const void* data, int pitch) = 0;
virtual bool Map(BYTE** bits, int& pitch, const RECT* r = NULL) = 0;
virtual void Unmap() = 0;
virtual bool Save(CString fn, bool dds = false) = 0;

View File

@@ -69,7 +69,7 @@ int GSTexture10::GetFormat() const
return m_desc.Format;
}
bool GSTexture10::Update(CRect r, const void* data, int pitch)
bool GSTexture10::Update(const CRect& r, const void* data, int pitch)
{
if(m_dev && m_texture)
{

View File

@@ -43,7 +43,7 @@ public:
int GetWidth() const;
int GetHeight() const;
int GetFormat() const;
bool Update(CRect r, const void* data, int pitch);
bool Update(const CRect& r, const void* data, int pitch);
bool Map(BYTE** bits, int& pitch, const RECT* r = NULL);
void Unmap();
bool Save(CString fn, bool dds = false);

184
gsdx/GSTexture7.cpp Normal file
View File

@@ -0,0 +1,184 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSTexture7.h"
GSTexture7::GSTexture7()
: m_type(GSTexture::None)
{
memset(&m_desc, 0, sizeof(m_desc));
}
GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system)
: m_type(type)
, m_system(system)
{
memset(&m_desc, 0, sizeof(m_desc));
m_desc.dwSize = sizeof(m_desc);
system->GetSurfaceDesc(&m_desc);
}
GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface7* video)
: m_type(type)
, m_system(system)
, m_video(video)
{
memset(&m_desc, 0, sizeof(m_desc));
m_desc.dwSize = sizeof(m_desc);
video->GetSurfaceDesc(&m_desc);
}
GSTexture7::~GSTexture7()
{
}
GSTexture7::operator bool()
{
return !!m_system;
}
int GSTexture7::GetType() const
{
return m_type;
}
int GSTexture7::GetWidth() const
{
return m_desc.dwWidth;
}
int GSTexture7::GetHeight() const
{
return m_desc.dwHeight;
}
int GSTexture7::GetFormat() const
{
return (int)m_desc.ddpfPixelFormat.dwFourCC;
}
bool GSTexture7::Update(const CRect& r, const void* data, int pitch)
{
HRESULT hr;
CRect r2 = r;
DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
if(SUCCEEDED(hr = m_system->Lock(&r2, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL)))
{
BYTE* src = (BYTE*)data;
BYTE* dst = (BYTE*)desc.lpSurface;
int bytes = min(pitch, desc.lPitch);
for(int i = 0, j = r.Height(); i < j; i++, src += pitch, dst += desc.lPitch)
{
// memcpy(dst, src, bytes);
// HACK!!!
GSVector4i* s = (GSVector4i*)src;
GSVector4i* d = (GSVector4i*)dst;
int w = bytes >> 4;
for(int x = 0; x < w; x++)
{
GSVector4i c = s[x];
c = (c & 0xff00ff00) | ((c & 0x00ff0000) >> 16) | ((c & 0x000000ff) << 16);
d[x] = c;
}
}
hr = m_system->Unlock(&r2);
if(m_video)
{
hr = m_video->Blt(&r2, m_system, &r2, DDBLT_WAIT, NULL);
}
return true;
}
return false;
}
bool GSTexture7::Map(BYTE** bits, int& pitch, const RECT* r)
{
HRESULT hr;
CRect r2 = r;
DDSURFACEDESC2 desc;
if(SUCCEEDED(hr = m_system->Lock(&r2, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL)))
{
*bits = (BYTE*)desc.lpSurface;
pitch = (int)desc.lPitch;
m_lr = r;
return true;
}
return false;
}
void GSTexture7::Unmap()
{
HRESULT hr;
hr = m_system->Unlock(NULL);
if(m_video)
{
hr = m_video->Blt(&m_lr, m_system, &m_lr, DDBLT_WAIT, NULL);
}
}
bool GSTexture7::Save(CString fn, bool dds)
{
// TODO
return false;
}
IDirectDrawSurface7* GSTexture7::operator->()
{
return m_video ? m_video : m_system;
}
GSTexture7::operator IDirectDrawSurface7*()
{
return m_video ? m_video : m_system;
}

55
gsdx/GSTexture7.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GSTexture.h"
#include <ddraw.h>
class GSTexture7 : public GSTexture
{
int m_type;
CComPtr<IDirectDrawSurface7> m_system;
CComPtr<IDirectDrawSurface7> m_video;
DDSURFACEDESC2 m_desc;
CRect m_lr;
public:
GSTexture7();
explicit GSTexture7(int type, IDirectDrawSurface7* system);
GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface7* video);
virtual ~GSTexture7();
operator bool();
int GetType() const;
int GetWidth() const;
int GetHeight() const;
int GetFormat() const;
bool Update(const CRect& r, const void* data, int pitch);
bool Map(BYTE** bits, int& pitch, const RECT* r = NULL);
void Unmap();
bool Save(CString fn, bool dds = false);
IDirectDrawSurface7* operator->(); // TODO: remove direct access
operator IDirectDrawSurface7*();
};

View File

@@ -83,7 +83,7 @@ int GSTexture9::GetFormat() const
return m_desc.Format;
}
bool GSTexture9::Update(CRect r, const void* data, int pitch)
bool GSTexture9::Update(const CRect& r, const void* data, int pitch)
{
if(CComPtr<IDirect3DSurface9> surface = *this)
{

View File

@@ -42,7 +42,7 @@ public:
int GetWidth() const;
int GetHeight() const;
int GetFormat() const;
bool Update(CRect r, const void* data, int pitch);
bool Update(const CRect& r, const void* data, int pitch);
bool Map(BYTE** bits, int& pitch, const RECT* r = NULL);
void Unmap();
bool Save(CString fn, bool dds = false);

View File

@@ -37,7 +37,7 @@ public:
int GetWidth() const {return m_desc.w;}
int GetHeight() const {return m_desc.h;}
int GetFormat() const {return m_desc.format;}
bool Update(CRect r, const void* data, int pitch) {return true;}
bool Update(const CRect& r, const void* data, int pitch) {return true;}
bool Map(BYTE** bits, int& pitch, const RECT* r = NULL) {return true;}
void Unmap() {}
bool Save(CString fn, bool dds = false) {return false;}

View File

@@ -1147,6 +1147,10 @@
RelativePath=".\GSDevice10.cpp"
>
</File>
<File
RelativePath=".\GSDevice7.cpp"
>
</File>
<File
RelativePath=".\GSDevice9.cpp"
>
@@ -1395,6 +1399,10 @@
RelativePath=".\GSTexture10.cpp"
>
</File>
<File
RelativePath=".\GSTexture7.cpp"
>
</File>
<File
RelativePath=".\GSTexture9.cpp"
>
@@ -1669,6 +1677,10 @@
RelativePath=".\GSDevice10.h"
>
</File>
<File
RelativePath=".\GSDevice7.h"
>
</File>
<File
RelativePath=".\GSDevice9.h"
>
@@ -1761,6 +1773,10 @@
RelativePath=".\GSTexture10.h"
>
</File>
<File
RelativePath=".\GSTexture7.h"
>
</File>
<File
RelativePath=".\GSTexture9.h"
>