GSdx: Removed DX10 support in favour of DX11. I am told that this shouldn't affect anyone and it reduces code duplication. (DX11 was already missing some changes in DX10, I have ported them.)

GSdx: Removed OpenGL "support".  Nobody showed any interest in getting this working.
GSdx: Removed PS1 GPU support.  pcsx2 does not use this and it is unmaintained, likely broken, and frequently confuses intellisense.
GSDumpGUI: Use the correct export for the library name, was using the PS1 version.

If any of the above code is needed in the future, we have this wonderful technology called version control.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2754 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
sudonim1 2010-03-19 20:27:06 +00:00
parent c09114e08b
commit 8c0fc49f61
57 changed files with 104 additions and 9183 deletions

View File

@ -1,298 +0,0 @@
/*
* 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 "GSdx.h"
#include "GSUtil.h"
#include "GPURendererSW.h"
#ifdef _WINDOWS
#include "GSDevice7.h"
#include "GSDevice9.h"
#include "GSDevice10.h"
#endif
#include "GPUSettingsDlg.h"
#define PSE_LT_GPU 2
static HRESULT s_hr = E_FAIL;
static GPURenderer* s_gpu = NULL;
EXPORT_C_(uint32) PSEgetLibType()
{
return PSE_LT_GPU;
}
EXPORT_C_(char*) PSEgetLibName()
{
return GSUtil::GetLibName();
}
EXPORT_C_(uint32) PSEgetLibVersion()
{
static const uint32 version = 1;
static const uint32 revision = 1;
return version << 16 | revision << 8 | PLUGIN_VERSION;
}
EXPORT_C_(int32) GPUinit()
{
return 0;
}
EXPORT_C_(int32) GPUshutdown()
{
return 0;
}
EXPORT_C_(int32) GPUclose()
{
delete s_gpu;
s_gpu = NULL;
#ifdef _WINDOWS
if(SUCCEEDED(s_hr))
{
::CoUninitialize();
s_hr = E_FAIL;
}
#endif
return 0;
}
EXPORT_C_(int32) GPUopen(HWND hWnd)
{
GPUclose();
#ifdef _WINDOWS
s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(!GSUtil::CheckDirectX())
{
return -1;
}
#endif
if(!GSUtil::CheckSSE())
{
return -1;
}
int renderer = theApp.GetConfig("Renderer", 1);
switch(renderer)
{
default:
case 0: s_gpu = new GPURendererSW(new GSDevice7()); break;
case 1: s_gpu = new GPURendererSW(new GSDevice9()); break;
case 2: s_gpu = new GPURendererSW(new GSDevice10()); break;
// TODO: case 3: s_gpu = new GPURendererNull(new GSDeviceNull()); break;
}
if(!s_gpu->Create(hWnd))
{
GPUclose();
return -1;
}
return 0;
}
EXPORT_C_(int32) GPUconfigure()
{
GPUSettingsDlg dlg;
if(IDOK == dlg.DoModal())
{
GPUshutdown();
GPUinit();
}
return 0;
}
EXPORT_C_(int32) GPUtest()
{
return 0;
}
EXPORT_C GPUabout()
{
// TODO
}
EXPORT_C GPUwriteDataMem(const uint8* mem, uint32 size)
{
s_gpu->WriteData(mem, size);
}
EXPORT_C GPUwriteData(uint32 data)
{
s_gpu->WriteData((uint8*)&data, 1);
}
EXPORT_C GPUreadDataMem(uint8* mem, uint32 size)
{
s_gpu->ReadData(mem, size);
}
EXPORT_C_(uint32) GPUreadData()
{
uint32 data = 0;
s_gpu->ReadData((uint8*)&data, 1);
return data;
}
EXPORT_C GPUwriteStatus(uint32 status)
{
s_gpu->WriteStatus(status);
}
EXPORT_C_(uint32) GPUreadStatus()
{
return s_gpu->ReadStatus();
}
EXPORT_C_(uint32) GPUdmaChain(const uint8* mem, uint32 addr)
{
uint32 last[3];
memset(last, 0xff, sizeof(last));
do
{
if(addr == last[1] || addr == last[2])
{
break;
}
(addr < last[0] ? last[1] : last[2]) = addr;
last[0] = addr;
uint8 size = mem[addr + 3];
if(size > 0)
{
s_gpu->WriteData(&mem[addr + 4], size);
}
addr = *(uint32*)&mem[addr] & 0xffffff;
}
while(addr != 0xffffff);
return 0;
}
EXPORT_C_(uint32) GPUgetMode()
{
// TODO
return 0;
}
EXPORT_C GPUsetMode(uint32 mode)
{
// TODO
}
EXPORT_C GPUupdateLace()
{
s_gpu->VSync();
}
EXPORT_C GPUmakeSnapshot()
{
s_gpu->MakeSnapshot("c:/"); // TODO
}
EXPORT_C GPUdisplayText(char* text)
{
// TODO
}
EXPORT_C GPUdisplayFlags(uint32 flags)
{
// TODO
}
EXPORT_C_(int32) GPUfreeze(uint32 type, GPUFreezeData* data)
{
if(!data || data->version != 1)
{
return 0;
}
if(type == 0)
{
s_gpu->Defrost(data);
return 1;
}
else if(type == 1)
{
s_gpu->Freeze(data);
return 1;
}
else if(type == 2)
{
int slot = *(int*)data + 1;
if(slot < 1 || slot > 9)
{
return 0;
}
// TODO
return 1;
}
return 0;
}
EXPORT_C GPUgetScreenPic(uint8* mem)
{
// TODO
}
EXPORT_C GPUshowScreenPic(uint8* mem)
{
// TODO
}
EXPORT_C GPUcursor(int player, int x, int y)
{
// TODO
}

View File

@ -1,276 +0,0 @@
/*
* 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
#pragma pack(push, 1)
#include "GS.h"
enum
{
GPU_POLYGON = 1,
GPU_LINE = 2,
GPU_SPRITE = 3,
};
REG32_(GPUReg, STATUS)
uint32 TX:4;
uint32 TY:1;
uint32 ABR:2;
uint32 TP:2;
uint32 DTD:1;
uint32 DFE:1;
uint32 MD:1;
uint32 ME:1;
uint32 _PAD0:3;
uint32 WIDTH1:1;
uint32 WIDTH0:2;
uint32 HEIGHT:1;
uint32 ISPAL:1;
uint32 ISRGB24:1;
uint32 ISINTER:1;
uint32 DEN:1;
uint32 _PAD1:2;
uint32 IDLE:1;
uint32 IMG:1;
uint32 COM:1;
uint32 DMA:2;
uint32 LCF:1;
/*
uint32 TX:4;
uint32 TY:1;
uint32 ABR:2;
uint32 TP:2;
uint32 DTD:1;
uint32 DFE:1;
uint32 PBW:1;
uint32 PBC:1;
uint32 _PAD0:3;
uint32 HRES2:1;
uint32 HRES1:2;
uint32 VRES:1;
uint32 ISPAL:1;
uint32 ISRGB24:1;
uint32 ISINTER:1;
uint32 ISSTOP:1;
uint32 _PAD1:1;
uint32 DMARDY:1;
uint32 IDIDLE:1;
uint32 DATARDY:1;
uint32 ISEMPTY:1;
uint32 TMODE:2;
uint32 ODE:1;
*/
REG_END
REG32_(GPUReg, PACKET)
uint32 _PAD:24;
uint32 OPTION:5;
uint32 TYPE:3;
REG_END
REG32_(GPUReg, PRIM)
uint32 VTX:24;
uint32 TGE:1;
uint32 ABE:1;
uint32 TME:1;
uint32 _PAD2:1;
uint32 IIP:1;
uint32 TYPE:3;
REG_END
REG32_(GPUReg, POLYGON)
uint32 _PAD:24;
uint32 TGE:1;
uint32 ABE:1;
uint32 TME:1;
uint32 VTX:1;
uint32 IIP:1;
uint32 TYPE:3;
REG_END
REG32_(GPUReg, LINE)
uint32 _PAD:24;
uint32 ZERO1:1;
uint32 ABE:1;
uint32 ZERO2:1;
uint32 PLL:1;
uint32 IIP:1;
uint32 TYPE:3;
REG_END
REG32_(GPUReg, SPRITE)
uint32 _PAD:24;
uint32 ZERO:1;
uint32 ABE:1;
uint32 TME:1;
uint32 SIZE:2;
uint32 TYPE:3;
REG_END
REG32_(GPUReg, RESET)
uint32 _PAD:32;
REG_END
REG32_(GPUReg, DEN)
uint32 DEN:1;
uint32 _PAD:31;
REG_END
REG32_(GPUReg, DMA)
uint32 DMA:2;
uint32 _PAD:30;
REG_END
REG32_(GPUReg, DAREA)
uint32 X:10;
uint32 Y:9;
uint32 _PAD:13;
REG_END
REG32_(GPUReg, DHRANGE)
uint32 X1:12;
uint32 X2:12;
uint32 _PAD:8;
REG_END
REG32_(GPUReg, DVRANGE)
uint32 Y1:10;
uint32 Y2:11;
uint32 _PAD:11;
REG_END
REG32_(GPUReg, DMODE)
uint32 WIDTH0:2;
uint32 HEIGHT:1;
uint32 ISPAL:1;
uint32 ISRGB24:1;
uint32 ISINTER:1;
uint32 WIDTH1:1;
uint32 REVERSE:1;
uint32 _PAD:24;
REG_END
REG32_(GPUReg, GPUINFO)
uint32 PARAM:24;
uint32 _PAD:8;
REG_END
REG32_(GPUReg, MODE)
uint32 TX:4;
uint32 TY:1;
uint32 ABR:2;
uint32 TP:2;
uint32 DTD:1;
uint32 DFE:1;
uint32 _PAD:21;
REG_END
REG32_(GPUReg, MASK)
uint32 MD:1;
uint32 ME:1;
uint32 _PAD:30;
REG_END
REG32_(GPUReg, DRAREA)
uint32 X:10;
uint32 Y:10;
uint32 _PAD:12;
REG_END
REG32_(GPUReg, DROFF)
int32 X:11;
int32 Y:11;
int32 _PAD:10;
REG_END
REG32_(GPUReg, RGB)
uint32 R:8;
uint32 G:8;
uint32 B:8;
uint32 _PAD:8;
REG_END
REG32_(GPUReg, XY)
int32 X:11;
int32 _PAD1:5;
int32 Y:11;
int32 _PAD2:5;
REG_END
REG32_(GPUReg, UV)
uint32 U:8;
uint32 V:8;
uint32 _PAD:16;
REG_END
REG32_(GPUReg, TWIN)
uint32 TWW:5;
uint32 TWH:5;
uint32 TWX:5;
uint32 TWY:5;
uint32 _PAD:12;
REG_END
REG32_(GPUReg, CLUT)
uint32 _PAD1:16;
uint32 X:6;
uint32 Y:9;
uint32 _PAD2:1;
REG_END
REG32_SET(GPUReg)
GPURegSTATUS STATUS;
GPURegPACKET PACKET;
GPURegPRIM PRIM;
GPURegPOLYGON POLYGON;
GPURegLINE LINE;
GPURegSPRITE SPRITE;
GPURegRESET RESET;
GPURegDEN DEN;
GPURegDMA DMA;
GPURegDAREA DAREA;
GPURegDHRANGE DHRANGE;
GPURegDVRANGE DVRANGE;
GPURegDMODE DMODE;
GPURegGPUINFO GPUINFO;
GPURegMODE MODE;
GPURegMASK MASK;
GPURegDRAREA DRAREA;
GPURegDROFF DROFF;
GPURegRGB RGB;
GPURegXY XY;
GPURegUV UV;
GPURegTWIN TWIN;
GPURegCLUT CLUT;
REG_SET_END
struct GPUFreezeData
{
uint32 version; // == 1
uint32 status;
uint32 control[256];
uint16 vram[1024 * 1024];
};
#pragma pack(pop)

View File

@ -1,119 +0,0 @@
/*
* 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 "GPUDrawScanline.h"
GPUDrawScanline::GPUDrawScanline(GPUState* state, int id)
: m_state(state)
, m_id(id)
, m_sp(m_env)
, m_ds(m_env)
{
}
GPUDrawScanline::~GPUDrawScanline()
{
}
void GPUDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f)
{
GPUDrawingEnvironment& env = m_state->m_env;
const GPUScanlineParam* p = (const GPUScanlineParam*)data->param;
m_env.sel = p->sel;
m_env.vm = m_state->m_mem.GetPixelAddress(0, 0);
if(m_env.sel.tme)
{
m_env.tex = p->tex;
m_env.clut = p->clut;
if(m_env.sel.twin)
{
uint32 u, v;
u = ~(env.TWIN.TWW << 3) & 0xff;
v = ~(env.TWIN.TWH << 3) & 0xff;
m_env.twin[0].u = GSVector4i((u << 16) | u);
m_env.twin[0].v = GSVector4i((v << 16) | v);
u = env.TWIN.TWX << 3;
v = env.TWIN.TWY << 3;
m_env.twin[1].u = GSVector4i((u << 16) | u) & ~m_env.twin[0].u;
m_env.twin[1].v = GSVector4i((v << 16) | v) & ~m_env.twin[0].v;
}
}
//
f->ssl = m_ds[m_env.sel];
f->sr = NULL; // TODO
// doesn't need all bits => less functions generated
GPUScanlineSelector sel;
sel.key = 0;
sel.iip = m_env.sel.iip;
sel.tfx = m_env.sel.tfx;
sel.twin = m_env.sel.twin;
sel.sprite = m_env.sel.sprite;
f->ssp = m_sp[sel];
}
void GPUDrawScanline::EndDraw(const GSRasterizerStats& stats)
{
m_ds.UpdateStats(stats, m_state->m_perfmon.GetFrame());
}
//
GPUDrawScanline::GPUSetupPrimMap::GPUSetupPrimMap(GPUScanlineEnvironment& env)
: GSCodeGeneratorFunctionMap("GPUSetupPrim")
, m_env(env)
{
}
GPUSetupPrimCodeGenerator* GPUDrawScanline::GPUSetupPrimMap::Create(uint32 key, void* ptr, size_t maxsize)
{
return new GPUSetupPrimCodeGenerator(m_env, ptr, maxsize);
}
//
GPUDrawScanline::GPUDrawScanlineMap::GPUDrawScanlineMap(GPUScanlineEnvironment& env)
: GSCodeGeneratorFunctionMap("GPUDrawScanline")
, m_env(env)
{
}
GPUDrawScanlineCodeGenerator* GPUDrawScanline::GPUDrawScanlineMap::Create(uint32 key, void* ptr, size_t maxsize)
{
return new GPUDrawScanlineCodeGenerator(m_env, ptr, maxsize);
}

View File

@ -1,69 +0,0 @@
/*
* 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 "GPUState.h"
#include "GSRasterizer.h"
#include "GPUScanlineEnvironment.h"
#include "GPUSetupPrimCodeGenerator.h"
#include "GPUDrawScanlineCodeGenerator.h"
class GPUDrawScanline : public IDrawScanline
{
GPUScanlineEnvironment m_env;
//
class GPUSetupPrimMap : public GSCodeGeneratorFunctionMap<GPUSetupPrimCodeGenerator, uint32, SetupPrimStaticPtr>
{
GPUScanlineEnvironment& m_env;
public:
GPUSetupPrimMap(GPUScanlineEnvironment& env);
GPUSetupPrimCodeGenerator* Create(uint32 key, void* ptr, size_t maxsize);
} m_sp;
//
class GPUDrawScanlineMap : public GSCodeGeneratorFunctionMap<GPUDrawScanlineCodeGenerator, uint32, DrawScanlineStaticPtr>
{
GPUScanlineEnvironment& m_env;
public:
GPUDrawScanlineMap(GPUScanlineEnvironment& env);
GPUDrawScanlineCodeGenerator* Create(uint32 key, void* ptr, size_t maxsize);
} m_ds;
protected:
GPUState* m_state;
int m_id;
public:
GPUDrawScanline(GPUState* state, int id);
virtual ~GPUDrawScanline();
// IDrawScanline
void BeginDraw(const GSRasterizerData* data, Functions* f);
void EndDraw(const GSRasterizerStats& stats);
void PrintStats() {m_ds.PrintStats();}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
/*
* 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 "GPUScanlineEnvironment.h"
#include "xbyak/xbyak.h"
#include "xbyak/xbyak_util.h"
using namespace Xbyak;
class GPUDrawScanlineCodeGenerator : public CodeGenerator
{
void operator = (const GPUDrawScanlineCodeGenerator&);
static const GSVector4i m_test[8];
static const uint16 m_dither[4][16];
util::Cpu m_cpu;
GPUScanlineEnvironment& m_env;
void Generate();
void Init(int params);
void Step();
void TestMask();
void SampleTexture();
void ColorTFX();
void AlphaBlend();
void Dither();
void WriteFrame();
void ReadTexel(const Xmm& dst, const Xmm& addr);
template<int shift> void modulate16(const Xmm& a, const Operand& f);
template<int shift> void lerp16(const Xmm& a, const Xmm& b, const Operand& f);
void alltrue();
void blend8(const Xmm& a, const Xmm& b);
void blend(const Xmm& a, const Xmm& b, const Xmm& mask);
public:
GPUDrawScanlineCodeGenerator(GPUScanlineEnvironment& env, void* ptr, size_t maxsize);
};

View File

@ -1,79 +0,0 @@
/*
* 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 "GPU.h"
#pragma pack(push, 1)
__aligned16 class GPUDrawingEnvironment
{
public:
GPURegSTATUS STATUS;
GPURegPRIM PRIM;
GPURegDAREA DAREA;
GPURegDHRANGE DHRANGE;
GPURegDVRANGE DVRANGE;
GPURegDRAREA DRAREATL;
GPURegDRAREA DRAREABR;
GPURegDROFF DROFF;
GPURegTWIN TWIN;
GPURegCLUT CLUT;
GPUDrawingEnvironment()
{
Reset();
}
void Reset()
{
memset(this, 0, sizeof(*this));
STATUS.IDLE = 1;
STATUS.COM = 1;
STATUS.WIDTH0 = 1;
DVRANGE.Y1 = 16;
DVRANGE.Y2 = 256;
}
GSVector4i GetDisplayRect()
{
static int s_width[] = {256, 320, 512, 640, 368, 384, 512, 640};
static int s_height[] = {240, 480};
GSVector4i r;
r.left = DAREA.X & ~7; // FIXME
r.top = DAREA.Y;
r.right = r.left + s_width[(STATUS.WIDTH1 << 2) | STATUS.WIDTH0];
r.bottom = r.top + (DVRANGE.Y2 - DVRANGE.Y1) * s_height[STATUS.HEIGHT] / 240;
return r.rintersect(GSVector4i(0, 0, 1024, 512));
}
int GetFPS()
{
return STATUS.ISPAL ? 50 : 60;
}
};
#pragma pack(pop)

View File

@ -1,667 +0,0 @@
/*
* 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 "GPULocalMemory.h"
#include "GSdx.h"
const GSVector4i GPULocalMemory::m_xxxa(0x00008000);
const GSVector4i GPULocalMemory::m_xxbx(0x00007c00);
const GSVector4i GPULocalMemory::m_xgxx(0x000003e0);
const GSVector4i GPULocalMemory::m_rxxx(0x0000001f);
GPULocalMemory::GPULocalMemory()
{
m_scale.x = min(max(theApp.GetConfig("scale_x", 0), 0), 2);
m_scale.y = min(max(theApp.GetConfig("scale_y", 0), 0), 2);
//
int size = (1 << (12 + 11)) * sizeof(uint16);
m_vm = (uint16*)VirtualAlloc(NULL, size * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
memset(m_vm, 0, size);
//
m_clut.buff = m_vm + size;
m_clut.dirty = true;
//
size = 256 * 256 * (1 + 1 + 4) * 32;
m_texture.buff[0] = (uint8*)VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
m_texture.buff[1] = m_texture.buff[0] + 256 * 256 * 32;
m_texture.buff[2] = m_texture.buff[1] + 256 * 256 * 32;
memset(m_texture.buff[0], 0, size);
memset(m_texture.valid, 0, sizeof(m_texture.valid));
for(int y = 0, offset = 0; y < 2; y++)
{
for(int x = 0; x < 16; x++, offset += 256 * 256)
{
m_texture.page[0][y][x] = &((uint8*)m_texture.buff[0])[offset];
m_texture.page[1][y][x] = &((uint8*)m_texture.buff[1])[offset];
}
}
for(int y = 0, offset = 0; y < 2; y++)
{
for(int x = 0; x < 16; x++, offset += 256 * 256)
{
m_texture.page[2][y][x] = &((uint32*)m_texture.buff[2])[offset];
}
}
}
GPULocalMemory::~GPULocalMemory()
{
VirtualFree(m_vm, 0, MEM_RELEASE);
VirtualFree(m_texture.buff[0], 0, MEM_RELEASE);
}
const uint16* GPULocalMemory::GetCLUT(int tp, int cx, int cy)
{
if(m_clut.dirty || m_clut.tp != tp || m_clut.cx != cx || m_clut.cy != cy)
{
uint16* src = GetPixelAddressScaled(cx << 4, cy);
uint16* dst = m_clut.buff;
if(m_scale.x == 0)
{
memcpy(dst, src, (tp == 0 ? 16 : 256) * 2);
}
else if(m_scale.x == 1)
{
if(tp == 0)
{
for(int i = 0; i < 16; i++)
{
dst[i] = src[i * 2];
}
}
else if(tp == 1)
{
for(int i = 0; i < 256; i++)
{
dst[i] = src[i * 2];
}
}
}
else if(m_scale.x == 2)
{
if(tp == 0)
{
for(int i = 0; i < 16; i++)
{
dst[i] = src[i * 4];
}
}
else if(tp == 1)
{
for(int i = 0; i < 256; i++)
{
dst[i] = src[i * 4];
}
}
}
else
{
ASSERT(0);
}
m_clut.tp = tp;
m_clut.cx = cx;
m_clut.cy = cy;
m_clut.dirty = false;
}
return m_clut.buff;
}
const void* GPULocalMemory::GetTexture(int tp, int tx, int ty)
{
if(tp == 3)
{
ASSERT(0);
return NULL;
}
void* buff = m_texture.page[tp][ty][tx];
uint32 flag = 1 << tx;
if((m_texture.valid[tp][ty] & flag) == 0)
{
int bpp = 0;
switch(tp)
{
case 0:
ReadPage4(tx, ty, (uint8*)buff);
bpp = 4;
break;
case 1:
ReadPage8(tx, ty, (uint8*)buff);
bpp = 8;
break;
case 2:
case 3:
ReadPage16(tx, ty, (uint16*)buff);
bpp = 16;
default:
// FIXME: __assume(0); // vc9 generates bogus code in release mode
break;
}
// TODO: m_state->m_perfmon.Put(GSPerfMon::Unswizzle, 256 * 256 * bpp >> 3);
m_texture.valid[tp][ty] |= flag;
}
return buff;
}
void GPULocalMemory::Invalidate(const GSVector4i& r)
{
if(!m_clut.dirty)
{
if(r.top <= m_clut.cy && m_clut.cy < r.bottom)
{
int left = m_clut.cx << 4;
int right = left + (m_clut.tp == 0 ? 16 : 256);
if(r.left < right && r.right > left)
{
m_clut.dirty = true;
}
}
}
for(int y = 0, ye = min(r.bottom, 512), j = 0; y < ye; y += 256, j++)
{
if(r.top >= y + 256) continue;
for(int x = 0, xe = min(r.right, 1024), i = 0; x < xe; x += 64, i++)
{
uint32 flag = 1 << i;
if(r.left >= x + 256) continue;
m_texture.valid[2][j] &= ~flag;
if(r.left >= x + 128) continue;
m_texture.valid[1][j] &= ~flag;
if(r.left >= x + 64) continue;
m_texture.valid[0][j] &= ~flag;
}
}
}
void GPULocalMemory::FillRect(const GSVector4i& r, uint16 c)
{
Invalidate(r);
uint16* RESTRICT dst = GetPixelAddressScaled(r.left, r.top);
int w = r.width() << m_scale.x;
int h = r.height() << m_scale.y;
int pitch = GetWidth();
for(int j = 0; j < h; j++, dst += pitch)
{
for(int i = 0; i < w; i++)
{
dst[i] = c;
}
}
}
void GPULocalMemory::WriteRect(const GSVector4i& r, const uint16* RESTRICT src)
{
Invalidate(r);
uint16* RESTRICT dst = GetPixelAddressScaled(r.left, r.top);
int w = r.width();
int h = r.height();
int pitch = GetWidth();
if(m_scale.x == 0)
{
for(int j = 0; j < h; j++, src += w)
{
for(int k = 1 << m_scale.y; k >= 1; k--, dst += pitch)
{
memcpy(dst, src, w * 2);
}
}
}
else if(m_scale.x == 1)
{
for(int j = 0; j < h; j++, src += w)
{
for(int k = 1 << m_scale.y; k >= 1; k--, dst += pitch)
{
for(int i = 0; i < w; i++)
{
dst[i * 2 + 0] = src[i];
dst[i * 2 + 1] = src[i];
}
}
}
}
else if(m_scale.x == 2)
{
for(int j = 0; j < h; j++, src += w)
{
for(int k = 1 << m_scale.y; k >= 1; k--, dst += pitch)
{
for(int i = 0; i < w; i++)
{
dst[i * 4 + 0] = src[i];
dst[i * 4 + 1] = src[i];
dst[i * 4 + 2] = src[i];
dst[i * 4 + 3] = src[i];
}
}
}
}
else
{
ASSERT(0);
}
}
void GPULocalMemory::ReadRect(const GSVector4i& r, uint16* RESTRICT dst)
{
uint16* RESTRICT src = GetPixelAddressScaled(r.left, r.top);
int w = r.width();
int h = r.height();
int pitch = GetWidth() << m_scale.y;
if(m_scale.x == 0)
{
for(int j = 0; j < h; j++, src += pitch, dst += w)
{
memcpy(dst, src, w * 2);
}
}
else if(m_scale.x == 1)
{
for(int j = 0; j < h; j++, src += pitch, dst += w)
{
for(int i = 0; i < w; i++)
{
dst[i] = src[i * 2];
}
}
}
else if(m_scale.x == 2)
{
for(int j = 0; j < h; j++, src += pitch, dst += w)
{
for(int i = 0; i < w; i++)
{
dst[i] = src[i * 4];
}
}
}
else
{
ASSERT(0);
}
}
void GPULocalMemory::MoveRect(int sx, int sy, int dx, int dy, int w, int h)
{
Invalidate(GSVector4i(dx, dy, dx + w, dy + h));
uint16* s = GetPixelAddressScaled(sx, sy);
uint16* d = GetPixelAddressScaled(dx, dy);
w <<= m_scale.x;
h <<= m_scale.y;
int pitch = GetWidth();
for(int i = 0; i < h; i++, s += pitch, d += pitch)
{
memcpy(d, s, w * sizeof(uint16));
}
}
void GPULocalMemory::ReadPage4(int tx, int ty, uint8* RESTRICT dst)
{
uint16* src = GetPixelAddressScaled(tx << 6, ty << 8);
int pitch = GetWidth() << m_scale.y;
if(m_scale.x == 0)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
for(int i = 0; i < 64; i++)
{
dst[i * 4 + 0] = (src[i] >> 0) & 0xf;
dst[i * 4 + 1] = (src[i] >> 4) & 0xf;
dst[i * 4 + 2] = (src[i] >> 8) & 0xf;
dst[i * 4 + 3] = (src[i] >> 12) & 0xf;
}
}
}
else if(m_scale.x == 1)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
for(int i = 0; i < 64; i++)
{
dst[i * 4 + 0] = (src[i * 2] >> 0) & 0xf;
dst[i * 4 + 1] = (src[i * 2] >> 4) & 0xf;
dst[i * 4 + 2] = (src[i * 2] >> 8) & 0xf;
dst[i * 4 + 3] = (src[i * 2] >> 12) & 0xf;
}
}
}
else if(m_scale.x == 2)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
for(int i = 0; i < 64; i++)
{
dst[i * 4 + 0] = (src[i * 4] >> 0) & 0xf;
dst[i * 4 + 1] = (src[i * 4] >> 4) & 0xf;
dst[i * 4 + 2] = (src[i * 4] >> 8) & 0xf;
dst[i * 4 + 3] = (src[i * 4] >> 12) & 0xf;
}
}
}
else
{
ASSERT(0);
}
}
void GPULocalMemory::ReadPage8(int tx, int ty, uint8* RESTRICT dst)
{
uint16* src = GetPixelAddressScaled(tx << 6, ty << 8);
int pitch = GetWidth() << m_scale.y;
if(m_scale.x == 0)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
memcpy(dst, src, 256);
}
}
else if(m_scale.x == 1)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
for(int i = 0; i < 128; i++)
{
((uint16*)dst)[i] = src[i * 2];
}
}
}
else if(m_scale.x == 2)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
for(int i = 0; i < 128; i++)
{
((uint16*)dst)[i] = src[i * 4];
}
}
}
else
{
ASSERT(0);
}
}
void GPULocalMemory::ReadPage16(int tx, int ty, uint16* RESTRICT dst)
{
uint16* src = GetPixelAddressScaled(tx << 6, ty << 8);
int pitch = GetWidth() << m_scale.y;
if(m_scale.x == 0)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
memcpy(dst, src, 512);
}
}
else if(m_scale.x == 1)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
for(int i = 0; i < 256; i++)
{
dst[i] = src[i * 2];
}
}
}
else if(m_scale.x == 2)
{
for(int j = 0; j < 256; j++, src += pitch, dst += 256)
{
for(int i = 0; i < 256; i++)
{
dst[i] = src[i * 4];
}
}
}
else
{
ASSERT(0);
}
}
void GPULocalMemory::ReadFrame32(const GSVector4i& r, uint32* RESTRICT dst, bool rgb24)
{
uint16* src = GetPixelAddress(r.left, r.top);
int pitch = GetWidth();
if(rgb24)
{
for(int i = r.top; i < r.bottom; i++, src += pitch, dst += pitch)
{
Expand24(src, dst, r.width());
}
}
else
{
for(int i = r.top; i < r.bottom; i++, src += pitch, dst += pitch)
{
Expand16(src, dst, r.width());
}
}
}
void GPULocalMemory::Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels)
{
GSVector4i rm = m_rxxx;
GSVector4i gm = m_xgxx;
GSVector4i bm = m_xxbx;
GSVector4i am = m_xxxa;
GSVector4i* s = (GSVector4i*)src;
GSVector4i* d = (GSVector4i*)dst;
for(int i = 0, j = pixels >> 3; i < j; i++)
{
GSVector4i c = s[i];
GSVector4i l = c.upl16();
GSVector4i h = c.uph16();
d[i * 2 + 0] = ((l & rm) << 3) | ((l & gm) << 6) | ((l & bm) << 9) | ((l & am) << 16);
d[i * 2 + 1] = ((h & rm) << 3) | ((h & gm) << 6) | ((h & bm) << 9) | ((h & am) << 16);
}
}
void GPULocalMemory::Expand24(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels)
{
uint8* s = (uint8*)src;
if(m_scale.x == 0)
{
for(int i = 0; i < pixels; i += 2, s += 6)
{
dst[i + 0] = (s[2] << 16) | (s[1] << 8) | s[0];
dst[i + 1] = (s[5] << 16) | (s[4] << 8) | s[3];
}
}
else if(m_scale.x == 1)
{
for(int i = 0; i < pixels; i += 4, s += 12)
{
dst[i + 0] = dst[i + 1] = (s[4] << 16) | (s[1] << 8) | s[0];
dst[i + 2] = dst[i + 3] = (s[9] << 16) | (s[8] << 8) | s[5];
}
}
else if(m_scale.x == 2)
{
for(int i = 0; i < pixels; i += 8, s += 24)
{
dst[i + 0] = dst[i + 1] = dst[i + 2] = dst[i + 3] = (s[8] << 16) | (s[1] << 8) | s[0];
dst[i + 4] = dst[i + 5] = dst[i + 6] = dst[i + 7] = (s[17] << 16) | (s[16] << 8) | s[9];
}
}
else
{
ASSERT(0);
}
}
void GPULocalMemory::SaveBMP(const string& path, const GSVector4i& r2, int tp, int cx, int cy)
{
GSVector4i r;
r.left = r2.left << m_scale.x;
r.top = r2.top << m_scale.y;
r.right = r2.right << m_scale.x;
r.bottom = r2.bottom << m_scale.y;
r.left &= ~1;
r.right &= ~1;
if(FILE* fp = fopen(path.c_str(), "wb"))
{
BITMAPINFOHEADER bih;
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biWidth = r.width();
bih.biHeight = r.height();
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = bih.biWidth * bih.biHeight * 4;
BITMAPFILEHEADER bfh;
memset(&bfh, 0, sizeof(bfh));
bfh.bfType = 'MB';
bfh.bfOffBits = sizeof(bfh) + sizeof(bih);
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;
bfh.bfReserved1 = bfh.bfReserved2 = 0;
fwrite(&bfh, 1, sizeof(bfh), fp);
fwrite(&bih, 1, sizeof(bih), fp);
int pitch = GetWidth();
uint16* buff = (uint16*)_aligned_malloc(pitch * sizeof(WORD), 16);
uint32* buff32 = (uint32*)_aligned_malloc(pitch * sizeof(uint32), 16);
uint16* src = GetPixelAddress(r.left, r.bottom - 1);
const uint16* clut = GetCLUT(tp, cx, cy);
for(int j = r.bottom - 1; j >= r.top; j--, src -= pitch)
{
switch(tp)
{
case 0: // 4 bpp
for(int i = 0, k = r.width() / 2; i < k; i++)
{
buff[i * 2 + 0] = clut[((uint8*)src)[i] & 0xf];
buff[i * 2 + 1] = clut[((uint8*)src)[i] >> 4];
}
break;
case 1: // 8 bpp
for(int i = 0, k = r.width(); i < k; i++)
{
buff[i] = clut[((uint8*)src)[i]];
}
break;
case 2: // 16 bpp;
for(int i = 0, k = r.width(); i < k; i++)
{
buff[i] = src[i];
}
break;
case 3: // 24 bpp
// TODO
break;
}
Expand16(buff, buff32, r.width());
for(int i = 0, k = r.width(); i < k; i++)
{
buff32[i] = (buff32[i] & 0xff00ff00) | ((buff32[i] & 0x00ff0000) >> 16) | ((buff32[i] & 0x000000ff) << 16);
}
fwrite(buff32, 1, r.width() * 4, fp);
}
_aligned_free(buff);
_aligned_free(buff32);
fclose(fp);
}
}

View File

@ -1,86 +0,0 @@
/*
* 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 "GPU.h"
#include "GSVector.h"
class GPULocalMemory
{
static const GSVector4i m_xxxa;
static const GSVector4i m_xxbx;
static const GSVector4i m_xgxx;
static const GSVector4i m_rxxx;
uint16* m_vm;
struct
{
uint16* buff;
int tp, cx, cy;
bool dirty;
} m_clut;
struct
{
uint8* buff[3];
void* page[3][2][16];
uint16 valid[3][2];
} m_texture;
GSVector2i m_scale;
public:
GPULocalMemory();
virtual ~GPULocalMemory();
GSVector2i GetScale() {return m_scale;}
int GetWidth() {return 1 << (10 + m_scale.x);}
int GetHeight() {return 1 << (9 + m_scale.y);}
uint16* GetPixelAddress(int x, int y) const {return &m_vm[(y << (10 + m_scale.x)) + x];}
uint16* GetPixelAddressScaled(int x, int y) const {return &m_vm[((y << m_scale.y) << (10 + m_scale.x)) + (x << m_scale.x)];}
const uint16* GetCLUT(int tp, int cx, int cy);
const void* GetTexture(int tp, int tx, int ty);
void Invalidate(const GSVector4i& r);
void FillRect(const GSVector4i& r, uint16 c);
void WriteRect(const GSVector4i& r, const uint16* RESTRICT src);
void ReadRect(const GSVector4i& r, uint16* RESTRICT dst);
void MoveRect(int sx, int sy, int dx, int dy, int w, int h);
void ReadPage4(int tx, int ty, uint8* RESTRICT dst);
void ReadPage8(int tx, int ty, uint8* RESTRICT dst);
void ReadPage16(int tx, int ty, uint16* RESTRICT dst);
void ReadFrame32(const GSVector4i& r, uint32* RESTRICT dst, bool rgb24);
void Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels);
void Expand24(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels);
void SaveBMP(const string& path, const GSVector4i& r, int tp, int cx, int cy);
};
#pragma warning(default: 4244)

View File

@ -1,222 +0,0 @@
/*
* 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 "GPURenderer.h"
#include "GSdx.h"
map<HWND, GPURenderer*> GPURenderer::m_wnd2gpu;
GPURenderer::GPURenderer(GSDevice* dev)
: m_dev(dev)
, m_hWnd(NULL)
, m_wndproc(NULL)
{
m_filter = theApp.GetConfig("filter", 0);
m_dither = theApp.GetConfig("dithering", 1);
m_aspectratio = theApp.GetConfig("AspectRatio", 1);
m_vsync = !!theApp.GetConfig("vsync", 0);
m_scale = m_mem.GetScale();
}
GPURenderer::~GPURenderer()
{
if(m_wndproc)
{
SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_wndproc);
m_wnd2gpu.erase(m_hWnd);
}
}
bool GPURenderer::Create(HWND hWnd)
{
// TODO: move subclassing inside GSWnd::Attach
m_hWnd = hWnd;
m_wndproc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc);
if(!m_wnd.Attach(m_hWnd))
{
return false;
}
m_wnd2gpu[hWnd] = this;
DWORD style = GetWindowLong(hWnd, GWL_STYLE);
style |= WS_OVERLAPPEDWINDOW;
SetWindowLong(hWnd, GWL_STYLE, style);
m_wnd.Show();
if(!m_dev->Create(&m_wnd))
{
return false;
}
m_dev->SetVsync(m_vsync);
Reset();
return true;
}
bool GPURenderer::Merge()
{
GSTexture* st[2] = {GetOutput(), NULL};
if(!st[0])
{
return false;
}
GSVector2i s = st[0]->GetSize();
GSVector4 sr[2];
GSVector4 dr[2];
sr[0] = GSVector4(0, 0, 1, 1);
dr[0] = GSVector4(0, 0, s.x, s.y);
m_dev->Merge(st, sr, dr, s, 1, 1, GSVector4(0, 0, 0, 1));
return true;
}
void GPURenderer::VSync()
{
GSPerfMonAutoTimer pmat(m_perfmon);
m_perfmon.Put(GSPerfMon::Frame);
// m_env.STATUS.LCF = ~m_env.STATUS.LCF; // ?
if(!IsWindow(m_hWnd)) return;
Flush();
if(!m_dev->IsLost(true))
{
if(!Merge())
{
return;
}
}
else
{
ResetDevice();
}
// osd
if((m_perfmon.GetFrame() & 0x1f) == 0)
{
m_perfmon.Update();
double fps = 1000.0f / m_perfmon.Get(GSPerfMon::Frame);
GSVector4i r = m_env.GetDisplayRect();
int w = r.width() << m_scale.x;
int h = r.height() << m_scale.y;
string s = format(
"%I64d | %d x %d | %.2f fps (%d%%) | %d/%d | %d%% CPU | %.2f | %.2f",
m_perfmon.GetFrame(), w, h, fps, (int)(100.0 * fps / m_env.GetFPS()),
(int)m_perfmon.Get(GSPerfMon::Prim),
(int)m_perfmon.Get(GSPerfMon::Draw),
m_perfmon.CPU(),
m_perfmon.Get(GSPerfMon::Swizzle) / 1024,
m_perfmon.Get(GSPerfMon::Unswizzle) / 1024
);
double fillrate = m_perfmon.Get(GSPerfMon::Fillrate);
if(fillrate > 0)
{
s = format("%s | %.2f mpps", s.c_str(), fps * fillrate / (1024 * 1024));
}
SetWindowText(m_hWnd, s.c_str());
}
GSVector4i r;
GetClientRect(m_hWnd, r);
m_dev->Present(r.fit(m_aspectratio), 0);
}
bool GPURenderer::MakeSnapshot(const string& path)
{
time_t t = time(NULL);
char buff[16];
if(!strftime(buff, sizeof(buff), "%Y%m%d%H%M%S", localtime(&t)))
{
return false;
}
if(GSTexture* t = m_dev->GetCurrent())
{
return t->Save(format("%s_%s.bmp", path.c_str(), buff));
}
return false;
}
LRESULT CALLBACK GPURenderer::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
map<HWND, GPURenderer*>::iterator i = m_wnd2gpu.find(hWnd);
if(i != m_wnd2gpu.end())
{
return i->second->OnMessage(message, wParam, lParam);
}
ASSERT(0);
return 0;
}
LRESULT GPURenderer::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_KEYUP)
{
switch(wParam)
{
case VK_DELETE:
m_filter = (m_filter + 1) % 3;
return 0;
case VK_END:
m_dither = m_dither ? 0 : 1;
return 0;
case VK_NEXT:
m_aspectratio = (m_aspectratio + 1) % 3;
return 0;
}
}
return CallWindowProc(m_wndproc, m_hWnd, message, wParam, lParam);
}

View File

@ -1,178 +0,0 @@
/*
* 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 "GPUState.h"
#include "GSVertexList.h"
#include "GSDevice.h"
class GPURenderer : public GPUState
{
bool Merge();
protected:
GSDevice* m_dev;
int m_filter;
int m_dither;
int m_aspectratio;
bool m_vsync;
GSVector2i m_scale;
virtual void ResetDevice() {}
virtual GSTexture* GetOutput() = 0;
HWND m_hWnd;
WNDPROC m_wndproc;
static map<HWND, GPURenderer*> m_wnd2gpu;
GSWnd m_wnd;
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
public:
GPURenderer(GSDevice* dev);
virtual ~GPURenderer();
virtual bool Create(HWND hWnd);
virtual void VSync();
virtual bool MakeSnapshot(const string& path);
};
template<class Vertex>
class GPURendererT : public GPURenderer
{
protected:
Vertex* m_vertices;
int m_count;
int m_maxcount;
GSVertexList<Vertex> m_vl;
void Reset()
{
m_count = 0;
m_vl.RemoveAll();
__super::Reset();
}
void ResetPrim()
{
m_vl.RemoveAll();
}
void FlushPrim()
{
if(m_count > 0)
{
/*
Dump("db");
if(m_env.PRIM.TME)
{
GSVector4i r;
r.left = m_env.STATUS.TX << 6;
r.top = m_env.STATUS.TY << 8;
r.right = r.left + 256;
r.bottom = r.top + 256;
Dump(format("da_%d_%d_%d_%d_%d", m_env.STATUS.TP, r).c_str(), m_env.STATUS.TP, r, false);
}
*/
Draw();
m_count = 0;
//Dump("dc", false);
}
}
void GrowVertexBuffer()
{
m_maxcount = max(10000, m_maxcount * 3/2);
m_vertices = (Vertex*)_aligned_realloc(m_vertices, sizeof(Vertex) * m_maxcount, 16);
m_maxcount -= 100;
}
__forceinline Vertex* DrawingKick(int& count)
{
count = (int)m_env.PRIM.VTX;
if(m_vl.GetCount() < count)
{
return NULL;
}
if(m_count >= m_maxcount)
{
GrowVertexBuffer();
}
Vertex* v = &m_vertices[m_count];
switch(m_env.PRIM.TYPE)
{
case GPU_POLYGON:
m_vl.GetAt(0, v[0]);
m_vl.GetAt(1, v[1]);
m_vl.GetAt(2, v[2]);
m_vl.RemoveAll();
break;
case GPU_LINE:
m_vl.GetAt(0, v[0]);
m_vl.GetAt(1, v[1]);
m_vl.RemoveAll();
break;
case GPU_SPRITE:
m_vl.GetAt(0, v[0]);
m_vl.GetAt(1, v[1]);
m_vl.RemoveAll();
break;
default:
ASSERT(0);
m_vl.RemoveAll();
return NULL;
}
return v;
}
virtual void VertexKick() = 0;
virtual void Draw() = 0;
public:
GPURendererT(GSDevice* dev)
: GPURenderer(dev)
, m_count(0)
, m_maxcount(0)
, m_vertices(NULL)
{
}
virtual ~GPURendererT()
{
if(m_vertices) _aligned_free(m_vertices);
}
};

View File

@ -1,193 +0,0 @@
/*
* 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 "GPURendererSW.h"
#include "GSdx.h"
GPURendererSW::GPURendererSW(GSDevice* dev)
: GPURendererT(dev)
, m_texture(NULL)
{
m_rl.Create<GPUDrawScanline>(this, theApp.GetConfig("swthreads", 1));
}
GPURendererSW::~GPURendererSW()
{
delete m_texture;
}
void GPURendererSW::ResetDevice()
{
__super::ResetDevice();
delete m_texture;
m_texture = NULL;
}
GSTexture* GPURendererSW::GetOutput()
{
GSVector4i r = m_env.GetDisplayRect();
r.left <<= m_scale.x;
r.top <<= m_scale.y;
r.right <<= m_scale.x;
r.bottom <<= m_scale.y;
if(m_dev->ResizeTexture(&m_texture, r.width(), r.height()))
{
// TODO
static uint32* buff = (uint32*)_aligned_malloc(m_mem.GetWidth() * m_mem.GetHeight() * sizeof(uint32), 16);
m_mem.ReadFrame32(r, buff, !!m_env.STATUS.ISRGB24);
m_texture->Update(r.rsize(), buff, m_mem.GetWidth() * sizeof(uint32));
}
return m_texture;
}
void GPURendererSW::Draw()
{
const GPUDrawingEnvironment& env = m_env;
//
GPUScanlineParam p;
p.sel.key = 0;
p.sel.iip = env.PRIM.IIP;
p.sel.me = env.STATUS.ME;
if(env.PRIM.ABE)
{
p.sel.abe = env.PRIM.ABE;
p.sel.abr = env.STATUS.ABR;
}
p.sel.tge = env.PRIM.TGE;
if(env.PRIM.TME)
{
p.sel.tme = env.PRIM.TME;
p.sel.tlu = env.STATUS.TP < 2;
p.sel.twin = (env.TWIN.u32 & 0xfffff) != 0;
p.sel.ltf = m_filter == 1 && env.PRIM.TYPE == GPU_POLYGON || m_filter == 2 ? 1 : 0;
const void* t = m_mem.GetTexture(env.STATUS.TP, env.STATUS.TX, env.STATUS.TY);
if(!t) {ASSERT(0); return;}
p.tex = t;
p.clut = m_mem.GetCLUT(env.STATUS.TP, env.CLUT.X, env.CLUT.Y);
}
p.sel.dtd = m_dither ? env.STATUS.DTD : 0;
p.sel.md = env.STATUS.MD;
p.sel.sprite = env.PRIM.TYPE == GPU_SPRITE;
p.sel.scalex = m_mem.GetScale().x;
//
GSRasterizerData data;
data.vertices = m_vertices;
data.count = m_count;
data.param = &p;
data.scissor.left = (int)m_env.DRAREATL.X << m_scale.x;
data.scissor.top = (int)m_env.DRAREATL.Y << m_scale.y;
data.scissor.right = min((int)(m_env.DRAREABR.X + 1) << m_scale.x, m_mem.GetWidth());
data.scissor.bottom = min((int)(m_env.DRAREABR.Y + 1) << m_scale.y, m_mem.GetHeight());
switch(env.PRIM.TYPE)
{
case GPU_POLYGON: data.primclass = GS_TRIANGLE_CLASS; break;
case GPU_LINE: data.primclass = GS_LINE_CLASS; break;
case GPU_SPRITE: data.primclass = GS_SPRITE_CLASS; break;
default: __assume(0);
}
m_rl.Draw(&data);
GSRasterizerStats stats;
m_rl.GetStats(stats);
m_perfmon.Put(GSPerfMon::Draw, 1);
m_perfmon.Put(GSPerfMon::Prim, stats.prims);
m_perfmon.Put(GSPerfMon::Fillrate, stats.pixels);
// TODO
{
GSVector4 tl(+1e10f);
GSVector4 br(-1e10f);
for(int i = 0, j = m_count; i < j; i++)
{
GSVector4 p = m_vertices[i].p;
tl = tl.min(p);
br = br.max(p);
}
GSVector4i r = GSVector4i(tl.xyxy(br)).rintersect(data.scissor);
r.left >>= m_scale.x;
r.top >>= m_scale.y;
r.right >>= m_scale.x;
r.bottom >>= m_scale.y;
Invalidate(r);
}
}
void GPURendererSW::VertexKick()
{
GSVertexSW& dst = m_vl.AddTail();
// TODO: x/y + off.x/y should wrap around at +/-1024
int x = (int)(m_v.XY.X + m_env.DROFF.X) << m_scale.x;
int y = (int)(m_v.XY.Y + m_env.DROFF.Y) << m_scale.y;
int s = m_v.UV.X;
int t = m_v.UV.Y;
GSVector4 pt(x, y, s, t);
dst.p = pt.xyxy(GSVector4::zero());
dst.t = (pt.zwzw(GSVector4::zero()) + GSVector4(0.125f)) * 256.0f;
// dst.c = GSVector4(m_v.RGB.u32) * 128.0f;
dst.c = GSVector4(GSVector4i::load((int)m_v.RGB.u32).u8to32() << 7);
int count = 0;
if(GSVertexSW* v = DrawingKick(count))
{
// TODO
m_count += count;
}
}

View File

@ -1,41 +0,0 @@
/*
* 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 "GPURenderer.h"
#include "GPUDrawScanline.h"
class GPURendererSW : public GPURendererT<GSVertexSW>
{
protected:
GSRasterizerList m_rl;
GSTexture* m_texture;
void ResetDevice();
GSTexture* GetOutput();
void VertexKick();
void Draw();
public:
GPURendererSW(GSDevice* dev);
virtual ~GPURendererSW();
};

View File

@ -1,81 +0,0 @@
/*
* 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 "GSVector.h"
#include "GPULocalMemory.h"
union GPUScanlineSelector
{
struct
{
uint32 iip:1; // 0
uint32 me:1; // 1
uint32 abe:1; // 2
uint32 abr:2; // 3
uint32 tge:1; // 5
uint32 tme:1; // 6
uint32 twin:1; // 7
uint32 tlu:1; // 8
uint32 dtd:1; // 9
uint32 ltf:1; // 10
uint32 md:1; // 11
uint32 sprite:1; // 12
uint32 scalex:2; // 13
};
struct
{
uint32 _pad1:1; // 0
uint32 rfb:2; // 1
uint32 _pad2:2; // 3
uint32 tfx:2; // 5
};
uint32 key;
operator uint32() {return key;}
};
__aligned16 struct GPUScanlineParam
{
GPUScanlineSelector sel;
const void* tex;
const uint16* clut;
};
__aligned16 struct GPUScanlineEnvironment
{
GPUScanlineSelector sel;
void* vm;
const void* tex;
const uint16* clut;
// GSVector4i md; // similar to gs fba
struct {GSVector4i u, v;} twin[3];
struct {GSVector4i s, t, r, g, b, _pad[3];} d;
struct {GSVector4i st, c;} d8;
struct {GSVector4i s, t, r, b, g, uf, vf, dither, fd, test;} temp;
};

View File

@ -1,206 +0,0 @@
/*
* 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 "GSdx.h"
#include "GSUtil.h"
#include "GPUSettingsDlg.h"
#include "resource.h"
GSSetting GPUSettingsDlg::g_renderers[] =
{
{0, "Direct3D7 (Software)", NULL},
{1, "Direct3D9 (Software)", NULL},
{2, "Direct3D10 (Software)", NULL},
{3, "Direct3D11 (Software)", NULL},
// {4, "Null (Null)", NULL},
};
GSSetting GPUSettingsDlg::g_filter[] =
{
{0, "Nearest", NULL},
{1, "Bilinear (polygons only)", NULL},
{2, "Bilinear", NULL},
};
GSSetting GPUSettingsDlg::g_dithering[] =
{
{0, "Disabled", NULL},
{1, "Auto", NULL},
};
GSSetting GPUSettingsDlg::g_aspectratio[] =
{
{0, "Stretch", NULL},
{1, "4:3", NULL},
{2, "16:9", NULL},
};
GSSetting GPUSettingsDlg::g_scale[] =
{
{0 | (0 << 2), "H x 1 - V x 1", NULL},
{1 | (0 << 2), "H x 2 - V x 1", NULL},
{0 | (1 << 2), "H x 1 - V x 2", NULL},
{1 | (1 << 2), "H x 2 - V x 2", NULL},
{2 | (1 << 2), "H x 4 - V x 2", NULL},
{1 | (2 << 2), "H x 2 - V x 4", NULL},
{2 | (2 << 2), "H x 4 - V x 4", NULL},
};
GPUSettingsDlg::GPUSettingsDlg()
: GSDialog(IDD_GPUCONFIG)
{
}
void GPUSettingsDlg::OnInit()
{
__super::OnInit();
m_modes.clear();
{
D3DDISPLAYMODE mode;
memset(&mode, 0, sizeof(mode));
m_modes.push_back(mode);
ComboBoxAppend(IDC_RESOLUTION, "Please select...", (LPARAM)&m_modes.back(), true);
if(CComPtr<IDirect3D9> d3d = Direct3DCreate9(D3D_SDK_VERSION))
{
uint32 w = theApp.GetConfig("ModeWidth", 0);
uint32 h = theApp.GetConfig("ModeHeight", 0);
uint32 hz = theApp.GetConfig("ModeRefreshRate", 0);
uint32 n = d3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
for(uint32 i = 0; i < n; i++)
{
if(S_OK == d3d->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode))
{
m_modes.push_back(mode);
string str = format("%dx%d %dHz", mode.Width, mode.Height, mode.RefreshRate);
ComboBoxAppend(IDC_RESOLUTION, str.c_str(), (LPARAM)&m_modes.back(), w == mode.Width && h == mode.Height && hz == mode.RefreshRate);
}
}
}
}
bool isdx10avail = GSUtil::IsDirect3D10Available();
bool isdx11avail = GSUtil::IsDirect3D11Available();
vector<GSSetting> renderers;
for(size_t i = 0; i < countof(g_renderers); i++)
{
if(i >= 3 && i <= 5 && !isdx10avail) continue;
if(i >= 6 && i <= 8 && !isdx11avail) continue;
renderers.push_back(g_renderers[i]);
}
ComboBoxInit(IDC_RENDERER, &renderers[0], renderers.size(), theApp.GetConfig("Renderer", 0));
ComboBoxInit(IDC_FILTER, g_filter, countof(g_filter), theApp.GetConfig("filter", 0));
ComboBoxInit(IDC_DITHERING, g_dithering, countof(g_dithering), theApp.GetConfig("dithering", 1));
ComboBoxInit(IDC_ASPECTRATIO, g_aspectratio, countof(g_aspectratio), theApp.GetConfig("AspectRatio", 1));
ComboBoxInit(IDC_SCALE, g_scale, countof(g_scale), theApp.GetConfig("scale_x", 0) | (theApp.GetConfig("scale_y", 0) << 2));
CheckDlgButton(m_hWnd, IDC_WINDOWED, theApp.GetConfig("windowed", 1));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 1));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("swthreads", 1), 0));
UpdateControls();
}
bool GPUSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code)
{
if(id == IDC_RENDERER && code == CBN_SELCHANGE)
{
UpdateControls();
}
else if(id == IDOK)
{
INT_PTR data;
if(ComboBoxGetSelData(IDC_RESOLUTION, data))
{
const D3DDISPLAYMODE* mode = (D3DDISPLAYMODE*)data;
theApp.SetConfig("ModeWidth", (int)mode->Width);
theApp.SetConfig("ModeHeight", (int)mode->Height);
theApp.SetConfig("ModeRefreshRate", (int)mode->RefreshRate);
}
if(ComboBoxGetSelData(IDC_RENDERER, data))
{
theApp.SetConfig("Renderer", (int)data);
}
if(ComboBoxGetSelData(IDC_FILTER, data))
{
theApp.SetConfig("filter", (int)data);
}
if(ComboBoxGetSelData(IDC_DITHERING, data))
{
theApp.SetConfig("dithering", (int)data);
}
if(ComboBoxGetSelData(IDC_ASPECTRATIO, data))
{
theApp.SetConfig("AspectRatio", (int)data);
}
if(ComboBoxGetSelData(IDC_SCALE, data))
{
theApp.SetConfig("scale_x", data & 3);
theApp.SetConfig("scale_y", (data >> 2) & 3);
}
theApp.SetConfig("swthreads", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_GETPOS, 0, 0));
theApp.SetConfig("windowed", (int)IsDlgButtonChecked(m_hWnd, IDC_WINDOWED));
}
return __super::OnCommand(hWnd, id, code);
}
void GPUSettingsDlg::UpdateControls()
{
INT_PTR i;
if(ComboBoxGetSelData(IDC_RENDERER, i))
{
bool dx9 = i == 1;
bool dx10 = i == 2;
bool dx11 = i == 3;
bool sw = i >= 0 && i <= 3;
ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO9), dx9 ? SW_SHOW : SW_HIDE);
ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO10), dx10 ? SW_SHOW : SW_HIDE);
// TODO: ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO11), dx11 ? SW_SHOW : SW_HIDE);
EnableWindow(GetDlgItem(m_hWnd, IDC_SCALE), sw);
EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS_EDIT), sw);
EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS), sw);
}
}

View File

@ -1,45 +0,0 @@
/*
* 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 "GSDialog.h"
#include "GSSetting.h"
class GPUSettingsDlg : public GSDialog
{
list<D3DDISPLAYMODE> m_modes;
void UpdateControls();
protected:
void OnInit();
bool OnCommand(HWND hWnd, UINT id, UINT code);
public:
GPUSettingsDlg();
static GSSetting g_renderers[];
static GSSetting g_filter[];
static GSSetting g_dithering[];
static GSSetting g_aspectratio[];
static GSSetting g_scale[];
};

View File

@ -1,216 +0,0 @@
/*
* 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
*
*/
// TODO: x64
#include "StdAfx.h"
#include "GSVertexSW.h"
#include "GPUSetupPrimCodeGenerator.h"
GPUSetupPrimCodeGenerator::GPUSetupPrimCodeGenerator(GPUScanlineEnvironment& env, void* ptr, size_t maxsize)
: CodeGenerator(maxsize, ptr)
, m_env(env)
{
#if _M_AMD64
#error TODO
#endif
Generate();
}
void GPUSetupPrimCodeGenerator::Generate()
{
if(m_env.sel.tme && !m_env.sel.twin)
{
pcmpeqd(xmm0, xmm0);
if(m_env.sel.sprite)
{
// t = (GSVector4i(vertices[1].t) >> 8) - GSVector4i::x00000001();
cvttps2dq(xmm1, xmmword[ecx + sizeof(GSVertexSW) * 1 + 32]);
psrld(xmm1, 8);
psrld(xmm0, 31);
psubd(xmm1, xmm0);
// t = t.ps32(t);
// t = t.upl16(t);
packssdw(xmm1, xmm1);
punpcklwd(xmm1, xmm1);
// m_env.twin[2].u = t.xxxx();
// m_env.twin[2].v = t.yyyy();
pshufd(xmm2, xmm1, _MM_SHUFFLE(0, 0, 0, 0));
pshufd(xmm3, xmm1, _MM_SHUFFLE(1, 1, 1, 1));
movdqa(xmmword[&m_env.twin[2].u], xmm2);
movdqa(xmmword[&m_env.twin[2].v], xmm3);
}
else
{
// TODO: not really needed
// m_env.twin[2].u = GSVector4i::x00ff();
// m_env.twin[2].v = GSVector4i::x00ff();
psrlw(xmm0, 8);
movdqa(xmmword[&m_env.twin[2].u], xmm0);
movdqa(xmmword[&m_env.twin[2].v], xmm0);
}
}
if(m_env.sel.tme || m_env.sel.iip && m_env.sel.tfx != 3)
{
for(int i = 0; i < 3; i++)
{
movaps(Xmm(5 + i), xmmword[&m_shift[i]]);
}
// GSVector4 dt = dscan.t;
// GSVector4 dc = dscan.c;
movaps(xmm4, xmmword[edx]);
movaps(xmm3, xmmword[edx + 32]);
// GSVector4i dtc8 = GSVector4i(dt * 8.0f).ps32(GSVector4i(dc * 8.0f));
movaps(xmm1, xmm3);
mulps(xmm1, xmm5);
cvttps2dq(xmm1, xmm1);
movaps(xmm2, xmm4);
mulps(xmm2, xmm5);
cvttps2dq(xmm2, xmm2);
packssdw(xmm1, xmm2);
if(m_env.sel.tme)
{
// m_env.d8.st = dtc8.upl16(dtc8);
movdqa(xmm0, xmm1);
punpcklwd(xmm0, xmm0);
movdqa(xmmword[&m_env.d8.st], xmm0);
}
if(m_env.sel.iip && m_env.sel.tfx != 3)
{
// m_env.d8.c = dtc8.uph16(dtc8);
punpckhwd(xmm1, xmm1);
movdqa(xmmword[&m_env.d8.c], xmm1);
}
// xmm3 = dt
// xmm4 = dc
// xmm6 = ps0123
// xmm7 = ps4567
// xmm0, xmm1, xmm2, xmm5 = free
if(m_env.sel.tme)
{
// GSVector4 dtx = dt.xxxx();
// GSVector4 dty = dt.yyyy();
movaps(xmm0, xmm3);
shufps(xmm3, xmm3, _MM_SHUFFLE(0, 0, 0, 0));
shufps(xmm0, xmm0, _MM_SHUFFLE(1, 1, 1, 1));
// m_env.d.s = GSVector4i(dtx * ps0123).ps32(GSVector4i(dtx * ps4567));
movaps(xmm1, xmm3);
mulps(xmm3, xmm6);
mulps(xmm1, xmm7);
cvttps2dq(xmm3, xmm3);
cvttps2dq(xmm1, xmm1);
packssdw(xmm3, xmm1);
movdqa(xmmword[&m_env.d.s], xmm3);
// m_env.d.t = GSVector4i(dty * ps0123).ps32(GSVector4i(dty * ps4567));
movaps(xmm1, xmm0);
mulps(xmm0, xmm6);
mulps(xmm1, xmm7);
cvttps2dq(xmm0, xmm0);
cvttps2dq(xmm1, xmm1);
packssdw(xmm0, xmm1);
movdqa(xmmword[&m_env.d.t], xmm0);
}
// xmm4 = dc
// xmm6 = ps0123
// xmm7 = ps4567
// xmm0, xmm1, zmm2, xmm3, xmm5 = free
if(m_env.sel.iip && m_env.sel.tfx != 3)
{
// GSVector4 dcx = dc.xxxx();
// GSVector4 dcy = dc.yyyy();
// GSVector4 dcz = dc.zzzz();
movaps(xmm0, xmm4);
movaps(xmm1, xmm4);
shufps(xmm4, xmm4, _MM_SHUFFLE(0, 0, 0, 0));
shufps(xmm0, xmm0, _MM_SHUFFLE(1, 1, 1, 1));
shufps(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2));
// m_env.d.r = GSVector4i(dcx * ps0123).ps32(GSVector4i(dcx * ps4567));
movaps(xmm2, xmm4);
mulps(xmm4, xmm6);
mulps(xmm2, xmm7);
cvttps2dq(xmm4, xmm4);
cvttps2dq(xmm2, xmm2);
packssdw(xmm4, xmm2);
movdqa(xmmword[&m_env.d.r], xmm4);
// m_env.d.g = GSVector4i(dcy * ps0123).ps32(GSVector4i(dcy * ps4567));
movaps(xmm2, xmm0);
mulps(xmm0, xmm6);
mulps(xmm2, xmm7);
cvttps2dq(xmm0, xmm0);
cvttps2dq(xmm2, xmm2);
packssdw(xmm0, xmm2);
movdqa(xmmword[&m_env.d.g], xmm0);
// m_env.d.b = GSVector4i(dcz * ps0123).ps32(GSVector4i(dcz * ps4567));
movaps(xmm2, xmm1);
mulps(xmm1, xmm6);
mulps(xmm2, xmm7);
cvttps2dq(xmm1, xmm1);
cvttps2dq(xmm2, xmm2);
packssdw(xmm1, xmm2);
movdqa(xmmword[&m_env.d.b], xmm1);
}
}
ret();
}
const GSVector4 GPUSetupPrimCodeGenerator::m_shift[3] =
{
GSVector4(8.0f, 8.0f, 8.0f, 8.0f),
GSVector4(0.0f, 1.0f, 2.0f, 3.0f),
GSVector4(4.0f, 5.0f, 6.0f, 7.0f),
};

View File

@ -1,44 +0,0 @@
/*
* 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 "GPUScanlineEnvironment.h"
#include "xbyak/xbyak.h"
#include "xbyak/xbyak_util.h"
using namespace Xbyak;
class GPUSetupPrimCodeGenerator : public CodeGenerator
{
void operator = (const GPUSetupPrimCodeGenerator&);
static const GSVector4 m_shift[3];
util::Cpu m_cpu;
GPUScanlineEnvironment& m_env;
void Generate();
public:
GPUSetupPrimCodeGenerator(GPUScanlineEnvironment& env, void* ptr, size_t maxsize);
};

View File

@ -1,744 +0,0 @@
/*
* 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 "GPUState.h"
GPUState::GPUState()
: s_n(0)
{
memset(m_status, 0, sizeof(m_status));
for(int i = 0; i < countof(m_fpGPUStatusCommandHandlers); i++)
{
m_fpGPUStatusCommandHandlers[i] = &GPUState::SCH_Null;
}
m_fpGPUStatusCommandHandlers[0x00] = &GPUState::SCH_ResetGPU;
m_fpGPUStatusCommandHandlers[0x01] = &GPUState::SCH_ResetCommandBuffer;
m_fpGPUStatusCommandHandlers[0x02] = &GPUState::SCH_ResetIRQ;
m_fpGPUStatusCommandHandlers[0x03] = &GPUState::SCH_DisplayEnable;
m_fpGPUStatusCommandHandlers[0x04] = &GPUState::SCH_DMASetup;
m_fpGPUStatusCommandHandlers[0x05] = &GPUState::SCH_StartOfDisplayArea;
m_fpGPUStatusCommandHandlers[0x06] = &GPUState::SCH_HorizontalDisplayRange;
m_fpGPUStatusCommandHandlers[0x07] = &GPUState::SCH_VerticalDisplayRange;
m_fpGPUStatusCommandHandlers[0x08] = &GPUState::SCH_DisplayMode;
m_fpGPUStatusCommandHandlers[0x10] = &GPUState::SCH_GPUInfo;
m_fpGPUPacketHandler[0] = &GPUState::PH_Command;
m_fpGPUPacketHandler[1] = &GPUState::PH_Polygon;
m_fpGPUPacketHandler[2] = &GPUState::PH_Line;
m_fpGPUPacketHandler[3] = &GPUState::PH_Sprite;
m_fpGPUPacketHandler[4] = &GPUState::PH_Move;
m_fpGPUPacketHandler[5] = &GPUState::PH_Write;
m_fpGPUPacketHandler[6] = &GPUState::PH_Read;
m_fpGPUPacketHandler[7] = &GPUState::PH_Environment;
Reset();
}
GPUState::~GPUState()
{
}
void GPUState::Reset()
{
m_env.Reset();
m_mem.Invalidate(GSVector4i(0, 0, 1024, 512));
memset(&m_v, 0, sizeof(m_v));
}
void GPUState::Flush()
{
FlushPrim();
}
void GPUState::SetPrim(GPUReg* r)
{
if(m_env.PRIM.TYPE != r->PRIM.TYPE)
{
ResetPrim();
}
GPURegPRIM PRIM = r->PRIM;
PRIM.VTX = 0;
switch(r->PRIM.TYPE)
{
case GPU_POLYGON:
PRIM.u32 = (r->PRIM.u32 & 0xF7000000) | 3; // TYPE IIP TME ABE TGE
break;
case GPU_LINE:
PRIM.u32 = (r->PRIM.u32 & 0xF2000000) | 2; // TYPE IIP ABE
PRIM.TGE = 1; // ?
break;
case GPU_SPRITE:
PRIM.u32 = (r->PRIM.u32 & 0xE7000000) | 2; // TYPE TME ABE TGE
break;
}
if(m_env.PRIM.u32 != PRIM.u32)
{
Flush();
m_env.PRIM = PRIM;
}
}
void GPUState::SetCLUT(GPUReg* r)
{
uint32 mask = 0xFFFF0000; // X Y
uint32 value = (m_env.CLUT.u32 & ~mask) | (r->u32 & mask);
if(m_env.CLUT.u32 != value)
{
Flush();
m_env.CLUT.u32 = value;
}
}
void GPUState::SetTPAGE(GPUReg* r)
{
uint32 mask = 0x000001FF; // TP ABR TY TX
uint32 value = (m_env.STATUS.u32 & ~mask) | ((r->u32 >> 16) & mask);
if(m_env.STATUS.u32 != value)
{
Flush();
m_env.STATUS.u32 = value;
}
}
void GPUState::Invalidate(const GSVector4i& r)
{
m_mem.Invalidate(r);
}
void GPUState::WriteData(const uint8* mem, uint32 size)
{
GSPerfMonAutoTimer pmat(m_perfmon);
size <<= 2;
m_write.Append(mem, size);
int i = 0;
while(i < m_write.bytes)
{
GPUReg* r = (GPUReg*)&m_write.buff[i];
int ret = (this->*m_fpGPUPacketHandler[r->PACKET.TYPE])(r, (m_write.bytes - i) >> 2);
if(ret == 0) return; // need more data
i += ret << 2;
}
m_write.Remove(i);
}
void GPUState::ReadData(uint8* mem, uint32 size)
{
GSPerfMonAutoTimer pmat(m_perfmon);
int remaining = m_read.bytes - m_read.cur;
int bytes = (int)size << 2;
if(bytes > remaining)
{
// ASSERT(0);
// printf"WARNING: ReadData\n");
// memset(&mem[remaining], 0, bytes - remaining);
bytes = remaining;
}
memcpy(mem, &m_read.buff[m_read.cur], bytes);
m_read.cur += bytes;
if(m_read.cur >= m_read.bytes)
{
m_env.STATUS.IMG = 0;
}
}
void GPUState::WriteStatus(uint32 status)
{
GSPerfMonAutoTimer pmat(m_perfmon);
uint32 b = status >> 24;
m_status[b] = status;
(this->*m_fpGPUStatusCommandHandlers[b])((GPUReg*)&status);
}
uint32 GPUState::ReadStatus()
{
GSPerfMonAutoTimer pmat(m_perfmon);
m_env.STATUS.LCF = ~m_env.STATUS.LCF; // ?
return m_env.STATUS.u32;
}
void GPUState::Freeze(GPUFreezeData* data)
{
data->status = m_env.STATUS.u32;
memcpy(data->control, m_status, 256 * 4);
m_mem.ReadRect(GSVector4i(0, 0, 1024, 512), data->vram);
}
void GPUState::Defrost(const GPUFreezeData* data)
{
m_env.STATUS.u32 = data->status;
memcpy(m_status, data->control, 256 * 4);
m_mem.WriteRect(GSVector4i(0, 0, 1024, 512), data->vram);
for(int i = 0; i <= 8; i++)
{
WriteStatus(m_status[i]);
}
}
void GPUState::SCH_Null(GPUReg* r)
{
ASSERT(0);
}
void GPUState::SCH_ResetGPU(GPUReg* r)
{
Reset();
}
void GPUState::SCH_ResetCommandBuffer(GPUReg* r)
{
// ?
}
void GPUState::SCH_ResetIRQ(GPUReg* r)
{
// ?
}
void GPUState::SCH_DisplayEnable(GPUReg* r)
{
m_env.STATUS.DEN = r->DEN.DEN;
}
void GPUState::SCH_DMASetup(GPUReg* r)
{
m_env.STATUS.DMA = r->DMA.DMA;
}
void GPUState::SCH_StartOfDisplayArea(GPUReg* r)
{
m_env.DAREA = r->DAREA;
}
void GPUState::SCH_HorizontalDisplayRange(GPUReg* r)
{
m_env.DHRANGE = r->DHRANGE;
}
void GPUState::SCH_VerticalDisplayRange(GPUReg* r)
{
m_env.DVRANGE = r->DVRANGE;
}
void GPUState::SCH_DisplayMode(GPUReg* r)
{
m_env.STATUS.WIDTH0 = r->DMODE.WIDTH0;
m_env.STATUS.HEIGHT = r->DMODE.HEIGHT;
m_env.STATUS.ISPAL = r->DMODE.ISPAL;
m_env.STATUS.ISRGB24 = r->DMODE.ISRGB24;
m_env.STATUS.ISINTER = r->DMODE.ISINTER;
m_env.STATUS.WIDTH1 = r->DMODE.WIDTH1;
}
void GPUState::SCH_GPUInfo(GPUReg* r)
{
uint32 value = 0;
switch(r->GPUINFO.PARAM)
{
case 0x2:
value = m_env.TWIN.u32;
break;
case 0x0:
case 0x1:
case 0x3:
value = m_env.DRAREATL.u32;
break;
case 0x4:
value = m_env.DRAREABR.u32;
break;
case 0x5:
case 0x6:
value = m_env.DROFF.u32;
break;
case 0x7:
value = 2;
break;
case 0x8:
case 0xf:
value = 0xBFC03720; // ?
break;
default:
ASSERT(0);
break;
}
m_read.RemoveAll();
m_read.Append((uint8*)&value, 4);
m_read.cur = 0;
}
int GPUState::PH_Command(GPUReg* r, int size)
{
switch(r->PACKET.OPTION)
{
case 0: // ???
return 1;
case 1: // clear cache
return 1;
case 2: // fillrect
if(size < 3) return 0;
Flush();
GSVector4i r2;
r2.left = r[1].XY.X;
r2.top = r[1].XY.Y;
r2.right = r2.left + r[2].XY.X;
r2.bottom = r2.top + r[2].XY.Y;
uint16 c = (uint16)(((r[0].RGB.R >> 3) << 10) | ((r[0].RGB.R >> 3) << 5) | (r[0].RGB.R >> 3));
m_mem.FillRect(r2, c);
Invalidate(r2);
Dump("f");
return 3;
}
ASSERT(0);
return 1;
}
int GPUState::PH_Polygon(GPUReg* r, int size)
{
int required = 1;
int vertices = r[0].POLYGON.VTX ? 4 : 3;
required += vertices;
if(r[0].POLYGON.TME) required += vertices;
if(r[0].POLYGON.IIP) required += vertices - 1;
if(size < required) return 0;
//
SetPrim(r);
if(r[0].POLYGON.TME)
{
SetCLUT(&r[2]);
SetTPAGE(&r[r[0].POLYGON.IIP ? 5 : 4]);
}
//
GPUVertex v[4];
for(int i = 0, j = 0; j < vertices; j++)
{
v[j].RGB = r[r[0].POLYGON.IIP ? i : 0].RGB;
if(j == 0 || r[0].POLYGON.IIP) i++;
v[j].XY = r[i++].XY;
if(r[0].POLYGON.TME)
{
v[j].UV.X = r[i].UV.U;
v[j].UV.Y = r[i].UV.V;
i++;
}
}
for(int i = 0; i <= vertices - 3; i++)
{
for(int j = 0; j < 3; j++)
{
m_v = v[i + j];
VertexKick();
}
}
//
return required;
}
int GPUState::PH_Line(GPUReg* r, int size)
{
int required = 1;
int vertices = 0;
if(r->LINE.PLL)
{
required++;
for(int i = 1; i < size; i++)
{
if(r[i].u32 == 0x55555555)
{
vertices = i - 1;
}
}
if(vertices < 2)
{
return 0;
}
}
else
{
vertices = 2;
}
required += vertices;
if(r->LINE.IIP) required += vertices - 1;
//
SetPrim(r);
//
for(int i = 0, j = 0; j < vertices; j++)
{
if(j >= 2) VertexKick();
m_v.RGB = r[r[0].LINE.IIP ? i : 0].RGB;
if(j == 0 || r[0].LINE.IIP) i++;
m_v.XY = r[i++].XY;
VertexKick();
}
//
return required;
}
int GPUState::PH_Sprite(GPUReg* r, int size)
{
int required = 2;
if(r[0].SPRITE.TME) required++;
if(r[0].SPRITE.SIZE == 0) required++;
if(size < required) return 0;
//
SetPrim(r);
if(r[0].SPRITE.TME)
{
SetCLUT(&r[2]);
}
//
int i = 0;
m_v.RGB = r[i++].RGB;
m_v.XY = r[i++].XY;
if(r[0].SPRITE.TME)
{
m_v.UV.X = r[i].UV.U;
m_v.UV.Y = r[i].UV.V;
i++;
}
VertexKick();
int w = 0;
int h = 0;
switch(r[0].SPRITE.SIZE)
{
case 0: w = r[i].XY.X; h = r[i].XY.Y; i++; break;
case 1: w = h = 1; break;
case 2: w = h = 8; break;
case 3: w = h = 16; break;
default: __assume(0);
}
m_v.XY.X += w;
m_v.XY.Y += h;
if(r[0].SPRITE.TME)
{
m_v.UV.X += w;
m_v.UV.Y += h;
}
VertexKick();
//
return required;
}
int GPUState::PH_Move(GPUReg* r, int size)
{
if(size < 4) return 0;
Flush();
int sx = r[1].XY.X;
int sy = r[1].XY.Y;
int dx = r[2].XY.X;
int dy = r[2].XY.Y;
int w = r[3].XY.X;
int h = r[3].XY.Y;
m_mem.MoveRect(sx, sy, dx, dy, w, h);
Invalidate(GSVector4i(dx, dy, dx + w, dy + h));
// Dump("m");
return 4;
}
int GPUState::PH_Write(GPUReg* r, int size)
{
if(size < 3) return 0;
int w = r[2].XY.X;
int h = r[2].XY.Y;
int required = 3 + ((w * h + 1) >> 1);
if(size < required) return 0;
Flush();
GSVector4i r2;
r2.left = r[1].XY.X;
r2.top = r[1].XY.Y;
r2.right = r2.left + w;
r2.bottom = r2.top + h;
m_mem.WriteRect(r2, (const uint16*)&r[3]);
Invalidate(r2);
Dump("w");
m_perfmon.Put(GSPerfMon::Swizzle, w * h * 2);
return required;
}
int GPUState::PH_Read(GPUReg* r, int size)
{
if(size < 3) return 0;
Flush();
int w = r[2].XY.X;
int h = r[2].XY.Y;
GSVector4i r2;
r2.left = r[1].XY.X;
r2.top = r[1].XY.Y;
r2.right = r2.left + w;
r2.bottom = r2.top + h;
m_read.bytes = ((w * h + 1) & ~1) * 2;
m_read.cur = 0;
m_read.Reserve(m_read.bytes);
m_mem.ReadRect(r2, (uint16*)m_read.buff);
Dump("r");
m_env.STATUS.IMG = 1;
return 3;
}
int GPUState::PH_Environment(GPUReg* r, int size)
{
Flush(); // TODO: only call when something really changes
switch(r->PACKET.OPTION)
{
case 1: // draw mode setting
m_env.STATUS.TX = r->MODE.TX;
m_env.STATUS.TY = r->MODE.TY;
m_env.STATUS.ABR = r->MODE.ABR;
m_env.STATUS.TP = r->MODE.TP;
m_env.STATUS.DTD = r->MODE.DTD;
m_env.STATUS.DFE = r->MODE.DFE;
return 1;
case 2: // texture window setting
m_env.TWIN = r->TWIN;
return 1;
case 3: // set drawing area top left
m_env.DRAREATL = r->DRAREA;
return 1;
case 4: // set drawing area bottom right
m_env.DRAREABR = r->DRAREA;
return 1;
case 5: // drawing offset
m_env.DROFF = r->DROFF;
return 1;
case 6: // mask setting
m_env.STATUS.MD = r->MASK.MD;
m_env.STATUS.ME = r->MASK.ME;
return 1;
}
ASSERT(0);
return 1;
}
//
GPUState::Buffer::Buffer()
{
bytes = 0;
maxbytes = 4096;
buff = (uint8*)_aligned_malloc(maxbytes, 16);
cur = 0;
}
GPUState::Buffer::~Buffer()
{
_aligned_free(buff);
}
void GPUState::Buffer::Reserve(int size)
{
if(size > maxbytes)
{
maxbytes = (maxbytes + size + 1023) & ~1023;
buff = (uint8*)_aligned_realloc(buff, maxbytes, 16);
}
}
void GPUState::Buffer::Append(const uint8* src, int size)
{
Reserve(bytes + (int)size);
memcpy(&buff[bytes], src, size);
bytes += size;
}
void GPUState::Buffer::Remove(int size)
{
ASSERT(size <= bytes);
if(size < bytes)
{
memmove(&buff[0], &buff[size], bytes - size);
bytes -= size;
}
else
{
bytes = 0;
}
#ifdef DEBUG
memset(&buff[bytes], 0xff, maxbytes - bytes);
#endif
}
void GPUState::Buffer::RemoveAll()
{
bytes = 0;
}

View File

@ -1,141 +0,0 @@
/*
* 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 "GPU.h"
#include "GPUDrawingEnvironment.h"
#include "GPULocalMemory.h"
#include "GPUVertex.h"
#include "GSAlignedClass.h"
#include "GSUtil.h"
#include "GSPerfMon.h"
class GPUState : public GSAlignedClass<16>
{
typedef void (GPUState::*GPUStatusCommandHandler)(GPUReg* r);
GPUStatusCommandHandler m_fpGPUStatusCommandHandlers[256];
void SCH_Null(GPUReg* r);
void SCH_ResetGPU(GPUReg* r);
void SCH_ResetCommandBuffer(GPUReg* r);
void SCH_ResetIRQ(GPUReg* r);
void SCH_DisplayEnable(GPUReg* r);
void SCH_DMASetup(GPUReg* r);
void SCH_StartOfDisplayArea(GPUReg* r);
void SCH_HorizontalDisplayRange(GPUReg* r);
void SCH_VerticalDisplayRange(GPUReg* r);
void SCH_DisplayMode(GPUReg* r);
void SCH_GPUInfo(GPUReg* r);
typedef int (GPUState::*GPUPacketHandler)(GPUReg* r, int size);
GPUPacketHandler m_fpGPUPacketHandler[8];
int PH_Command(GPUReg* r, int size);
int PH_Polygon(GPUReg* r, int size);
int PH_Line(GPUReg* r, int size);
int PH_Sprite(GPUReg* r, int size);
int PH_Move(GPUReg* r, int size);
int PH_Write(GPUReg* r, int size);
int PH_Read(GPUReg* r, int size);
int PH_Environment(GPUReg* r, int size);
class Buffer
{
public:
int bytes;
int maxbytes;
uint8* buff;
int cur;
public:
Buffer();
~Buffer();
void Reserve(int size);
void Append(const uint8* src, int size);
void Remove(int size);
void RemoveAll();
};
Buffer m_write;
Buffer m_read;
void SetPrim(GPUReg* r);
void SetCLUT(GPUReg* r);
void SetTPAGE(GPUReg* r);
protected:
int s_n;
void Dump(const string& s, uint32 TP, const GSVector4i& r, int inc = true)
{
//if(m_perfmon.GetFrame() < 1000)
//if((m_env.TWIN.u32 & 0xfffff) == 0)
//if(!m_env.STATUS.ME && !m_env.STATUS.MD)
return;
if(inc) s_n++;
//if(s_n < 86) return;
int dir = 1;
#ifdef DEBUG
dir = 2;
#endif
m_mem.SaveBMP(format("c:\\temp%d\\%04d_%s.bmp", dir, s_n, s), r, TP, m_env.CLUT.X, m_env.CLUT.Y);
}
void Dump(const string& s, int inc = true)
{
Dump(s, 2, GSVector4i(0, 0, 1024, 512), inc);
}
public:
GPUDrawingEnvironment m_env;
GPULocalMemory m_mem;
GPUVertex m_v;
GSPerfMon m_perfmon;
uint32 m_status[256];
public:
GPUState();
virtual ~GPUState();
virtual void Reset();
virtual void Flush();
virtual void FlushPrim() = 0;
virtual void ResetPrim() = 0;
virtual void VertexKick() = 0;
virtual void Invalidate(const GSVector4i& r);
void WriteData(const uint8* mem, uint32 size);
void ReadData(uint8* mem, uint32 size);
void WriteStatus(uint32 status);
uint32 ReadStatus();
void Freeze(GPUFreezeData* data);
void Defrost(const GPUFreezeData* data);
};

View File

@ -1,51 +0,0 @@
/*
* 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 "GPU.h"
#include "GSVector.h"
#pragma pack(push, 1)
__aligned16 struct GPUVertex
{
union
{
struct
{
GPURegRGB RGB;
GPURegXY XY;
GPURegXY UV;
};
struct {__m128i m128i;};
struct {__m128 m128;};
};
GPUVertex() {memset(this, 0, sizeof(*this));}
};
struct GPUVertexNull
{
};
#pragma pack(pop)

View File

@ -22,9 +22,7 @@
#include "stdafx.h"
#include "GSUtil.h"
#include "GSRendererDX9.h"
#include "GSRendererDX10.h"
#include "GSRendererDX11.h"
#include "GSRendererOGL.h"
#include "GSRendererSW.h"
#include "GSRendererNull.h"
#include "GSSettingsDlg.h"
@ -172,11 +170,7 @@ static INT32 _GSopen(void* dsp, char* title, int renderer)
{
default:
case 0: case 1: case 2: dev = new GSDevice9(); break;
case 3: case 4: case 5: dev = new GSDevice10(); break;
#if 0
case 6: case 7: case 8: dev = new GSDevice11(); break;
case 9: case 10: case 11: dev = new GSDeviceOGL(); break;
#endif
case 3: case 4: case 5: dev = new GSDevice11(); break;
case 12: case 13: new GSDeviceNull(); break;
}
@ -188,11 +182,7 @@ static INT32 _GSopen(void* dsp, char* title, int renderer)
{
default:
case 0: s_gs = new GSRendererDX9(); break;
case 3: s_gs = new GSRendererDX10(); break;
#if 0
case 6: s_gs = new GSRendererDX11(); break;
case 9: s_gs = new GSRendererOGL(); break;
#endif
case 3: s_gs = new GSRendererDX11(); break;
case 2: case 5: case 8: case 11: case 13:
s_gs = new GSRendererNull(); break;
@ -256,8 +246,8 @@ EXPORT_C_(INT32) GSopen2( void* dsp, INT32 flags )
int renderer = theApp.GetConfig("renderer", 0);
if( flags & 4 )
{
static bool isdx10avail = GSUtil::IsDirect3D10Available();
if (isdx10avail) renderer = 4; //dx10 sw
static bool isdx11avail = GSUtil::IsDirect3D11Available();
if (isdx11avail) renderer = 4; //dx11 sw
else renderer = 1; //dx9 sw
}
@ -277,8 +267,8 @@ EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt)
if(mt == 2)
{
// pcsx2 sent a switch renderer request
static bool isdx10avail = GSUtil::IsDirect3D10Available();
if (isdx10avail) renderer = 4; //dx10 sw
static bool isdx11avail = GSUtil::IsDirect3D11Available();
if (isdx11avail) renderer = 4; //dx11 sw
else renderer = 1; //dx9 sw
mt = 1;
}

View File

@ -1,988 +0,0 @@
/*
* 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 "GSdx.h"
#include "GSDevice10.h"
#include "resource.h"
GSDevice10::GSDevice10()
{
memset(&m_state, 0, sizeof(m_state));
memset(&m_vs_cb_cache, 0, sizeof(m_vs_cb_cache));
memset(&m_ps_cb_cache, 0, sizeof(m_ps_cb_cache));
m_state.topology = D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED;
m_state.bf = -1;
}
GSDevice10::~GSDevice10()
{
}
bool GSDevice10::Create(GSWnd* wnd)
{
if(!__super::Create(wnd))
{
return false;
}
HRESULT hr = E_FAIL;
DXGI_SWAP_CHAIN_DESC scd;
D3D10_BUFFER_DESC bd;
D3D10_SAMPLER_DESC sd;
D3D10_DEPTH_STENCIL_DESC dsd;
D3D10_RASTERIZER_DESC rd;
D3D10_BLEND_DESC bsd;
memset(&scd, 0, sizeof(scd));
scd.BufferCount = 2;
scd.BufferDesc.Width = 1;
scd.BufferDesc.Height = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
//scd.BufferDesc.RefreshRate.Numerator = 60;
//scd.BufferDesc.RefreshRate.Denominator = 1;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = (HWND)m_wnd->GetHandle();
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
// Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less
// required if we want to add support for dual displays later on. The fullscreen/exclusive flip
// will be issued after all other initializations are complete.
scd.Windowed = TRUE;
// NOTE : D3D10_CREATE_DEVICE_SINGLETHREADED
// This flag is safe as long as the DXGI's internal message pump is disabled or is on the
// same thread as the GS window (which the emulator makes sure of, if it utilizes a
// multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes.
uint32 flags = D3D10_CREATE_DEVICE_SINGLETHREADED;
#ifdef DEBUG
flags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
D3D10_FEATURE_LEVEL1 levels[] =
{
D3D10_FEATURE_LEVEL_10_1,
D3D10_FEATURE_LEVEL_10_0
};
for(int i = 0; i < countof(levels); i++)
{
hr = D3D10CreateDeviceAndSwapChain1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, levels[i], D3D10_1_SDK_VERSION, &scd, &m_swapchain, &m_dev);
if(SUCCEEDED(hr))
{
if(!SetFeatureLevel((D3D_FEATURE_LEVEL)levels[i], true))
{
return false;
}
break;
}
}
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[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0},
};
hr = CompileShader(IDR_CONVERT_FX, "vs_main", NULL, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il);
for(int i = 0; i < countof(m_convert.ps); i++)
{
hr = CompileShader(IDR_CONVERT_FX, format("ps_main%d", i), NULL, &m_convert.ps[i]);
}
memset(&dsd, 0, sizeof(dsd));
dsd.DepthEnable = false;
dsd.StencilEnable = false;
hr = m_dev->CreateDepthStencilState(&dsd, &m_convert.dss);
memset(&bsd, 0, sizeof(bsd));
bsd.BlendEnable[0] = false;
bsd.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
hr = m_dev->CreateBlendState(&bsd, &m_convert.bs);
// merge
memset(&bd, 0, sizeof(bd));
bd.ByteWidth = sizeof(MergeConstantBuffer);
bd.Usage = D3D10_USAGE_DEFAULT;
bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb);
for(int i = 0; i < countof(m_merge.ps); i++)
{
hr = CompileShader(IDR_MERGE_FX, format("ps_main%d", i), NULL, &m_merge.ps[i]);
}
memset(&bsd, 0, sizeof(bsd));
bsd.BlendEnable[0] = true;
bsd.BlendOp = D3D10_BLEND_OP_ADD;
bsd.SrcBlend = D3D10_BLEND_SRC_ALPHA;
bsd.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
bsd.BlendOpAlpha = D3D10_BLEND_OP_ADD;
bsd.SrcBlendAlpha = D3D10_BLEND_ONE;
bsd.DestBlendAlpha = D3D10_BLEND_ZERO;
bsd.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
hr = m_dev->CreateBlendState(&bsd, &m_merge.bs);
// interlace
memset(&bd, 0, sizeof(bd));
bd.ByteWidth = sizeof(InterlaceConstantBuffer);
bd.Usage = D3D10_USAGE_DEFAULT;
bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb);
for(int i = 0; i < countof(m_interlace.ps); i++)
{
hr = CompileShader(IDR_INTERLACE_FX, format("ps_main%d", i), NULL, &m_interlace.ps[i]);
}
//
memset(&rd, 0, sizeof(rd));
rd.FillMode = D3D10_FILL_SOLID;
rd.CullMode = D3D10_CULL_NONE;
rd.FrontCounterClockwise = false;
rd.DepthBias = false;
rd.DepthBiasClamp = 0;
rd.SlopeScaledDepthBias = 0;
rd.DepthClipEnable = false; // ???
rd.ScissorEnable = true;
rd.MultisampleEnable = true;
rd.AntialiasedLineEnable = false;
hr = m_dev->CreateRasterizerState(&rd, &m_rs);
m_dev->RSSetState(m_rs);
//
memset(&sd, 0, sizeof(sd));
sd.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
sd.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
sd.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
sd.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
sd.MaxLOD = FLT_MAX;
sd.MaxAnisotropy = 16;
sd.ComparisonFunc = D3D10_COMPARISON_NEVER;
hr = m_dev->CreateSamplerState(&sd, &m_convert.ln);
sd.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT;
hr = m_dev->CreateSamplerState(&sd, &m_convert.pt);
//
Reset(1, 1);
//
CreateTextureFX();
//
memset(&dsd, 0, sizeof(dsd));
dsd.DepthEnable = false;
dsd.StencilEnable = true;
dsd.StencilReadMask = 1;
dsd.StencilWriteMask = 1;
dsd.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
dsd.FrontFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE;
dsd.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsd.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP;
dsd.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
dsd.BackFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE;
dsd.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsd.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP;
m_dev->CreateDepthStencilState(&dsd, &m_date.dss);
D3D10_BLEND_DESC blend;
memset(&blend, 0, sizeof(blend));
m_dev->CreateBlendState(&blend, &m_date.bs);
// Exclusive/Fullscreen flip, issued for legacy (managed) windows only. GSopen2 style
// emulators will issue the flip themselves later on.
if(m_wnd->IsManaged())
{
SetExclusive( !theApp.GetConfig("windowed", 1) );
}
return true;
}
bool GSDevice10::Reset(int w, int h)
{
if(!__super::Reset(w, h))
return false;
if(m_swapchain)
{
DXGI_SWAP_CHAIN_DESC scd;
memset(&scd, 0, sizeof(scd));
m_swapchain->GetDesc(&scd);
m_swapchain->ResizeBuffers(scd.BufferCount, w, h, scd.BufferDesc.Format, 0);
CComPtr<ID3D10Texture2D> backbuffer;
if(FAILED(m_swapchain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)&backbuffer)))
{
return false;
}
m_backbuffer = new GSTexture10(backbuffer);
}
return true;
}
void GSDevice10::SetExclusive(bool isExcl)
{
if(!m_swapchain) return;
// TODO : Support for alternative display modes, by finishing this code below:
// Video mode info should be pulled form config/ini.
/*DXGI_MODE_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.RefreshRate = 0; // must be zero for best results.
m_swapchain->ResizeTarget(&desc);
*/
HRESULT hr = m_swapchain->SetFullscreenState( isExcl, NULL );
if(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
fprintf(stderr, "(GSdx10) SetExclusive(%s) failed; request unavailable.", isExcl ? "true" : "false");
}
void GSDevice10::Flip()
{
m_swapchain->Present(m_vsync, 0);
}
void GSDevice10::DrawPrimitive()
{
m_dev->Draw(m_vertices.count, m_vertices.start);
}
void GSDevice10::ClearRenderTarget(GSTexture* t, const GSVector4& c)
{
m_dev->ClearRenderTargetView(*(GSTexture10*)t, c.v);
}
void GSDevice10::ClearRenderTarget(GSTexture* t, uint32 c)
{
GSVector4 color = GSVector4(c) * (1.0f / 255);
m_dev->ClearRenderTargetView(*(GSTexture10*)t, color.v);
}
void GSDevice10::ClearDepth(GSTexture* t, float c)
{
m_dev->ClearDepthStencilView(*(GSTexture10*)t, D3D10_CLEAR_DEPTH, c, 0);
}
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, bool msaa, int format)
{
HRESULT hr;
D3D10_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.Width = w;
desc.Height = h;
desc.Format = (DXGI_FORMAT)format;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D10_USAGE_DEFAULT;
if(msaa)
{
desc.SampleDesc = m_msaa_desc;
}
switch(type)
{
case GSTexture::RenderTarget:
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
break;
case GSTexture::DepthStencil:
desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;// | D3D10_BIND_SHADER_RESOURCE;
break;
case GSTexture::Texture:
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
break;
case GSTexture::Offscreen:
desc.Usage = D3D10_USAGE_STAGING;
desc.CPUAccessFlags |= D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE;
break;
}
GSTexture10* t = NULL;
CComPtr<ID3D10Texture2D> texture;
hr = m_dev->CreateTexture2D(&desc, NULL, &texture);
if(SUCCEEDED(hr))
{
t = new GSTexture10(texture);
switch(type)
{
case GSTexture::RenderTarget:
ClearRenderTarget(t, 0);
break;
case GSTexture::DepthStencil:
ClearDepth(t, 0);
break;
}
}
return t;
}
GSTexture* GSDevice10::CreateRenderTarget(int w, int h, bool msaa, int format)
{
return __super::CreateRenderTarget(w, h, msaa, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM);
}
GSTexture* GSDevice10::CreateDepthStencil(int w, int h, bool msaa, int format)
{
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)
{
return __super::CreateTexture(w, h, format ? format : DXGI_FORMAT_R8G8B8A8_UNORM);
}
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;
if(format == 0)
{
format = DXGI_FORMAT_R8G8B8A8_UNORM;
}
if(format != DXGI_FORMAT_R8G8B8A8_UNORM && format != DXGI_FORMAT_R16_UINT)
{
ASSERT(0);
return false;
}
if(GSTexture* rt = CreateRenderTarget(w, h, false, format))
{
GSVector4 dr(0, 0, w, h);
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);
if(dst)
{
m_dev->CopyResource(*(GSTexture10*)dst, *(GSTexture10*)rt);
}
Recycle(rt);
}
return dst;
}
void GSDevice10::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
{
D3D10_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
m_dev->CopySubresourceRegion(*(GSTexture10*)dt, 0, r.left, r.top, 0, *(GSTexture10*)st, 0, &box);
}
void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
{
StretchRect(st, sr, dt, dr, m_convert.ps[shader], NULL, linear);
}
void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, bool linear)
{
StretchRect(st, sr, dt, dr, ps, ps_cb, m_convert.bs, linear);
}
void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, ID3D10BlendState* bs, bool linear)
{
BeginScene();
GSVector2i ds = dt->GetSize();
// om
OMSetDepthStencilState(m_convert.dss, 0);
OMSetBlendState(bs, 0);
OMSetRenderTargets(dt, NULL);
// ia
float left = dr.x * 2 / ds.x - 1.0f;
float top = 1.0f - dr.y * 2 / ds.y;
float right = dr.z * 2 / ds.x - 1.0f;
float bottom = 1.0f - dr.w * 2 / ds.y;
GSVertexPT1 vertices[] =
{
{GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)},
{GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)},
{GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)},
{GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)},
};
IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices));
IASetInputLayout(m_convert.il);
IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
// vs
VSSetShader(m_convert.vs, NULL);
// gs
GSSetShader(NULL);
// ps
PSSetShader(ps, ps_cb);
PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL);
PSSetShaderResources(st, NULL);
//
DrawPrimitive();
//
EndScene();
PSSetShaderResources(NULL, NULL);
}
void GSDevice10::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
{
ClearRenderTarget(dt, c);
if(st[1] && !slbg)
{
StretchRect(st[1], sr[1], dt, dr[1], m_merge.ps[0], NULL, true);
}
if(st[0])
{
m_dev->UpdateSubresource(m_merge.cb, 0, NULL, &c, 0, 0);
StretchRect(st[0], sr[0], dt, dr[0], m_merge.ps[mmod ? 1 : 0], m_merge.cb, m_merge.bs, true);
}
}
void GSDevice10::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
{
GSVector4 s = GSVector4(dt->GetSize());
GSVector4 sr(0, 0, 1, 1);
GSVector4 dr(0.0f, yoffset, s.x, s.y + yoffset);
InterlaceConstantBuffer cb;
cb.ZrH = GSVector2(0, 1.0f / s.y);
cb.hH = s.y / 2;
m_dev->UpdateSubresource(m_interlace.cb, 0, NULL, &cb, 0, 0);
StretchRect(st, sr, dt, dr, m_interlace.ps[shader], m_interlace.cb, linear);
}
void GSDevice10::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1 (&iaVertices)[4], bool datm)
{
const GSVector2i& size = rt->GetSize();
if(GSTexture* t = CreateRenderTarget(size.x, size.y, rt->IsMSAA()))
{
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
BeginScene();
ClearStencil(ds, 0);
// om
OMSetDepthStencilState(m_date.dss, 1);
OMSetBlendState(m_date.bs, 0);
OMSetRenderTargets(t, ds);
// ia
IASetVertexBuffer(iaVertices, sizeof(iaVertices[0]), countof(iaVertices));
IASetInputLayout(m_convert.il);
IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
// vs
VSSetShader(m_convert.vs, NULL);
// gs
GSSetShader(NULL);
// ps
GSTexture* rt2 = rt->IsMSAA() ? Resolve(rt) : rt;
PSSetShaderResources(rt2, NULL);
PSSetShader(m_convert.ps[datm ? 2 : 3], NULL);
PSSetSamplerState(m_convert.pt, NULL);
//
DrawPrimitive();
//
EndScene();
Recycle(t);
if(rt2 != rt) Recycle(rt2);
}
}
void GSDevice10::IASetVertexBuffer(const void* vertices, size_t stride, size_t count)
{
ASSERT(m_vertices.count == 0);
if(count * stride > m_vertices.limit * m_vertices.stride)
{
m_vb_old = m_vb;
m_vb = NULL;
m_vertices.start = 0;
m_vertices.count = 0;
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
}
if(m_vb == NULL)
{
D3D10_BUFFER_DESC bd;
memset(&bd, 0, sizeof(bd));
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = m_vertices.limit * stride;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
HRESULT hr;
hr = m_dev->CreateBuffer(&bd, NULL, &m_vb);
if(FAILED(hr)) return;
}
D3D10_MAP type = D3D10_MAP_WRITE_NO_OVERWRITE;
if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride)
{
m_vertices.start = 0;
type = D3D10_MAP_WRITE_DISCARD;
}
void* v = NULL;
if(SUCCEEDED(m_vb->Map(type, 0, &v)))
{
GSVector4i::storent((uint8*)v + m_vertices.start * stride, vertices, count * stride);
m_vb->Unmap();
}
m_vertices.count = count;
m_vertices.stride = stride;
IASetVertexBuffer(m_vb, stride);
}
void GSDevice10::IASetVertexBuffer(ID3D10Buffer* vb, size_t stride)
{
if(m_state.vb != vb || m_state.vb_stride != stride)
{
m_state.vb = vb;
m_state.vb_stride = stride;
uint32 offset = 0;
m_dev->IASetVertexBuffers(0, 1, &vb, &stride, &offset);
}
}
void GSDevice10::IASetInputLayout(ID3D10InputLayout* layout)
{
if(m_state.layout != layout)
{
m_state.layout = layout;
m_dev->IASetInputLayout(layout);
}
}
void GSDevice10::IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY topology)
{
if(m_state.topology != topology)
{
m_state.topology = topology;
m_dev->IASetPrimitiveTopology(topology);
}
}
void GSDevice10::VSSetShader(ID3D10VertexShader* vs, ID3D10Buffer* vs_cb)
{
if(m_state.vs != vs)
{
m_state.vs = vs;
m_dev->VSSetShader(vs);
}
if(m_state.vs_cb != vs_cb)
{
m_state.vs_cb = vs_cb;
m_dev->VSSetConstantBuffers(0, 1, &vs_cb);
}
}
void GSDevice10::GSSetShader(ID3D10GeometryShader* gs)
{
if(m_state.gs != gs)
{
m_state.gs = gs;
m_dev->GSSetShader(gs);
}
}
void GSDevice10::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
{
ID3D10ShaderResourceView* srv0 = NULL;
ID3D10ShaderResourceView* srv1 = NULL;
if(sr0) srv0 = *(GSTexture10*)sr0;
if(sr1) srv1 = *(GSTexture10*)sr1;
if(m_state.ps_srv[0] != srv0 || m_state.ps_srv[1] != srv1)
{
m_state.ps_srv[0] = srv0;
m_state.ps_srv[1] = srv1;
ID3D10ShaderResourceView* srvs[] = {srv0, srv1};
m_dev->PSSetShaderResources(0, 2, srvs);
}
}
void GSDevice10::PSSetShader(ID3D10PixelShader* ps, ID3D10Buffer* ps_cb)
{
if(m_state.ps != ps)
{
m_state.ps = ps;
m_dev->PSSetShader(ps);
}
if(m_state.ps_cb != ps_cb)
{
m_state.ps_cb = ps_cb;
m_dev->PSSetConstantBuffers(0, 1, &ps_cb);
}
}
void GSDevice10::PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState* ss1)
{
if(m_state.ps_ss[0] != ss0 || m_state.ps_ss[1] != ss1)
{
m_state.ps_ss[0] = ss0;
m_state.ps_ss[1] = ss1;
ID3D10SamplerState* sss[] = {ss0, ss1};
m_dev->PSSetSamplers(0, 2, sss);
}
}
void GSDevice10::OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref)
{
if(m_state.dss != dss || m_state.sref != sref)
{
m_state.dss = dss;
m_state.sref = sref;
m_dev->OMSetDepthStencilState(dss, sref);
}
}
void GSDevice10::OMSetBlendState(ID3D10BlendState* bs, float bf)
{
if(m_state.bs != bs || m_state.bf != bf)
{
m_state.bs = bs;
m_state.bf = bf;
float BlendFactor[] = {bf, bf, bf, 0};
m_dev->OMSetBlendState(bs, BlendFactor, 0xffffffff);
}
}
void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
{
ID3D10RenderTargetView* rtv = NULL;
ID3D10DepthStencilView* dsv = NULL;
if(rt) rtv = *(GSTexture10*)rt;
if(ds) dsv = *(GSTexture10*)ds;
if(m_state.rtv != rtv || m_state.dsv != dsv)
{
m_state.rtv = rtv;
m_state.dsv = dsv;
m_dev->OMSetRenderTargets(1, &rtv, dsv);
}
if(m_state.viewport != rt->GetSize())
{
m_state.viewport = rt->GetSize();
D3D10_VIEWPORT vp;
memset(&vp, 0, sizeof(vp));
vp.TopLeftX = 0;
vp.TopLeftY = 0;
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->GetSize()).zwxy();
if(!m_state.scissor.eq(r))
{
m_state.scissor = r;
m_dev->RSSetScissorRects(1, r);
}
}
HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10VertexShader** vs, D3D10_INPUT_ELEMENT_DESC* layout, int count, ID3D10InputLayout** il)
{
HRESULT hr;
vector<D3D10_SHADER_MACRO> m;
PrepareShaderMacro(m, macro);
CComPtr<ID3D10Blob> shader, error;
hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.vs.c_str(), 0, 0, NULL, &shader, &error, NULL);
if(error)
{
printf("%s\n", (const char*)error->GetBufferPointer());
}
if(FAILED(hr))
{
return hr;
}
hr = m_dev->CreateVertexShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), vs);
if(FAILED(hr))
{
return hr;
}
hr = m_dev->CreateInputLayout(layout, count, shader->GetBufferPointer(), shader->GetBufferSize(), il);
if(FAILED(hr))
{
return hr;
}
return hr;
}
HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10GeometryShader** gs)
{
HRESULT hr;
vector<D3D10_SHADER_MACRO> m;
PrepareShaderMacro(m, macro);
CComPtr<ID3D10Blob> shader, error;
hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.gs.c_str(), 0, 0, NULL, &shader, &error, NULL);
if(error)
{
printf("%s\n", (const char*)error->GetBufferPointer());
}
if(FAILED(hr))
{
return hr;
}
hr = m_dev->CreateGeometryShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), gs);
if(FAILED(hr))
{
return hr;
}
return hr;
}
HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10PixelShader** ps)
{
HRESULT hr;
vector<D3D10_SHADER_MACRO> m;
PrepareShaderMacro(m, macro);
CComPtr<ID3D10Blob> shader, error;
hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.ps.c_str(), 0, 0, NULL, &shader, &error, NULL);
if(error)
{
printf("%s\n", (const char*)error->GetBufferPointer());
}
if(FAILED(hr))
{
return hr;
}
hr = m_dev->CreatePixelShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), ps);
if(FAILED(hr))
{
return hr;
}
return hr;
}

View File

@ -1,177 +0,0 @@
/*
* 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 "GSDeviceDX.h"
#include "GSTexture10.h"
struct GSVertexShader10
{
CComPtr<ID3D10VertexShader> vs;
CComPtr<ID3D10InputLayout> il;
};
class GSDevice10 : public GSDeviceDX
{
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);
//
CComPtr<ID3D10Device1> m_dev;
CComPtr<IDXGISwapChain> m_swapchain;
CComPtr<ID3D10Buffer> m_vb;
CComPtr<ID3D10Buffer> m_vb_old;
struct
{
ID3D10Buffer* vb;
size_t vb_stride;
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
CComPtr<ID3D10RasterizerState> m_rs;
struct
{
CComPtr<ID3D10InputLayout> il;
CComPtr<ID3D10VertexShader> vs;
CComPtr<ID3D10PixelShader> ps[7];
CComPtr<ID3D10SamplerState> ln;
CComPtr<ID3D10SamplerState> pt;
CComPtr<ID3D10DepthStencilState> dss;
CComPtr<ID3D10BlendState> bs;
} m_convert;
struct
{
CComPtr<ID3D10PixelShader> ps[2];
CComPtr<ID3D10Buffer> cb;
CComPtr<ID3D10BlendState> bs;
} m_merge;
struct
{
CComPtr<ID3D10PixelShader> ps[4];
CComPtr<ID3D10Buffer> cb;
} m_interlace;
struct
{
CComPtr<ID3D10DepthStencilState> dss;
CComPtr<ID3D10BlendState> bs;
} m_date;
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1 (&iaVertices)[4], bool datm);
hash_map<uint32, GSVertexShader10 > m_vs;
CComPtr<ID3D10Buffer> m_vs_cb;
hash_map<uint32, CComPtr<ID3D10GeometryShader> > m_gs;
hash_map<uint32, CComPtr<ID3D10PixelShader> > m_ps;
CComPtr<ID3D10Buffer> m_ps_cb;
hash_map<uint32, CComPtr<ID3D10SamplerState> > m_ps_ss;
CComPtr<ID3D10SamplerState> m_palette_ss;
// hash_map<uint32, CComPtr<ID3D10DepthStencilState> > m_om_dss;
CComPtr<ID3D10DepthStencilState> m_om_dss[32];
hash_map<uint32, CComPtr<ID3D10BlendState> > m_om_bs;
VSConstantBuffer m_vs_cb_cache;
PSConstantBuffer m_ps_cb_cache;
public:
GSDevice10();
virtual ~GSDevice10();
void SetExclusive(bool isExcl);
bool Create(GSWnd* wnd);
bool CreateTextureFX();
bool Reset(int w, int h);
void Flip();
void DrawPrimitive();
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
void ClearRenderTarget(GSTexture* t, uint32 c);
void ClearDepth(GSTexture* t, float c);
void ClearStencil(GSTexture* t, uint8 c);
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);
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, bool linear = true);
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, ID3D10BlendState* bs, bool linear = true);
void IASetVertexBuffer(const void* vertices, size_t stride, size_t count);
void IASetVertexBuffer(ID3D10Buffer* vb, size_t stride);
void IASetInputLayout(ID3D10InputLayout* layout);
void IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY topology);
void VSSetShader(ID3D10VertexShader* vs, ID3D10Buffer* vs_cb);
void GSSetShader(ID3D10GeometryShader* gs);
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
void PSSetShader(ID3D10PixelShader* ps, ID3D10Buffer* ps_cb);
void PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState* ss1);
void OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref);
void OMSetBlendState(ID3D10BlendState* bs, float bf);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
void SetupIA(const void* vertices, int count, int prim);
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
void SetupGS(GSSelector sel);
void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel);
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
ID3D10Device* operator->() {return m_dev;}
operator ID3D10Device*() {return m_dev;}
HRESULT CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10VertexShader** vs, D3D10_INPUT_ELEMENT_DESC* layout, int count, ID3D10InputLayout** il);
HRESULT CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10GeometryShader** gs);
HRESULT CompileShader(uint32 id, const string& entry, D3D10_SHADER_MACRO* macro, ID3D10PixelShader** ps);
};

View File

@ -67,8 +67,17 @@ bool GSDevice11::Create(GSWnd* wnd)
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
// Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less
// required if we want to add support for dual displays later on. The fullscreen/exclusive flip
// will be issued after all other initializations are complete.
scd.Windowed = TRUE;
// NOTE : D3D11_CREATE_DEVICE_SINGLETHREADED
// This flag is safe as long as the DXGI's internal message pump is disabled or is on the
// same thread as the GS window (which the emulator makes sure of, if it utilizes a
// multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes.
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
#ifdef DEBUG
@ -255,7 +264,8 @@ bool GSDevice11::Create(GSWnd* wnd)
m_dev->CreateBlendState(&blend, &m_date.bs);
//
// Exclusive/Fullscreen flip, issued for legacy (managed) windows only. GSopen2 style
// emulators will issue the flip themselves later on.
if(m_wnd->IsManaged())
{
@ -410,7 +420,7 @@ GSTexture* GSDevice11::CreateRenderTarget(int w, int h, bool msaa, int format)
GSTexture* GSDevice11::CreateDepthStencil(int w, int h, bool msaa, int format)
{
return __super::CreateDepthStencil(w, h, msaa, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
return __super::CreateDepthStencil(w, h, msaa, format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT); // DXGI_FORMAT_R32G8X24_TYPELESS
}
GSTexture* GSDevice11::CreateTexture(int w, int h, int format)
@ -651,7 +661,7 @@ void GSDevice11::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
m_vertices.start = 0;
m_vertices.count = 0;
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
m_vertices.limit = std::max<int>(count * 3 / 2, 11000);
}
if(m_vb == NULL)
@ -952,7 +962,7 @@ HRESULT GSDevice11::CompileShader(uint32 id, const string& entry, D3D11_SHADER_M
PrepareShaderMacro(m, macro);
CComPtr<ID3D10Blob> shader, error;
CComPtr<ID3D11Blob> shader, error;
hr = D3DX11CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.ps.c_str(), 0, 0, NULL, &shader, &error, NULL);

View File

@ -1,256 +0,0 @@
/*
* 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()
: m_lost(false)
{
}
GSDevice7::~GSDevice7()
{
}
bool GSDevice7::Create(GSWnd* wnd)
{
if(!__super::Create(wnd))
{
return false;
}
if(FAILED(DirectDrawCreateEx(NULL, (VOID**)&m_dd, IID_IDirectDraw7, NULL)))
{
return false;
}
HWND hWnd = (HWND)m_wnd->GetHandle();
// 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);
return true;
}
bool GSDevice7::Reset(int w, int h)
{
if(!__super::Reset(w, h))
return false;
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;
CComPtr<IDirectDrawSurface7> backbuffer;
if(FAILED(m_dd->CreateSurface(&desc, &backbuffer, NULL)))
{
return false;
}
m_backbuffer = new GSTexture7(GSTexture::RenderTarget, backbuffer);
CComPtr<IDirectDrawClipper> clipper;
if(FAILED(m_dd->CreateClipper(0, &clipper, NULL)))
{
return false;
}
{
// ???
HRGN hrgn = CreateRectRgn(0, 0, w, h);
uint8 buff[1024];
GetRegionData(hrgn, sizeof(buff), (RGNDATA*)buff);
DeleteObject(hrgn);
clipper->SetClipList((RGNDATA*)buff, 0);
if(FAILED(backbuffer->SetClipper(clipper)))
{
return false;
}
}
m_lost = false;
return true;
}
void GSDevice7::Present(const GSVector4i& r, int shader)
{
HRESULT hr;
GSVector4i cr = m_wnd->GetClientRect();
int w = std::max<int>(cr.width(), 1);
int h = std::max<int>(cr.height(), 1);
if(!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h)
{
if(!Reset(w, h))
{
return;
}
}
CComPtr<IDirectDrawSurface7> backbuffer = *(GSTexture7*)m_backbuffer;
DDBLTFX fx;
memset(&fx, 0, sizeof(fx));
fx.dwSize = sizeof(fx);
fx.dwFillColor = 0;
hr = backbuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
GSVector4i r2 = r;
if(m_current)
{
hr = backbuffer->Blt(r2, *(GSTexture7*)m_current, NULL, DDBLT_WAIT, NULL);
}
// if ClearRenderTarget was implemented the parent class could handle these tasks until this point
r2 = cr;
MapWindowPoints((HWND)m_wnd->GetHandle(), HWND_DESKTOP, (POINT*)&r2, 2);
if(m_vsync)
{
hr = m_dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
}
hr = m_primary->Blt(r2, backbuffer, cr, DDBLT_WAIT, NULL);
if(hr == DDERR_SURFACELOST)
{
m_lost = true;
// TODO
HRESULT hr = m_dd->TestCooperativeLevel();
if(hr == DDERR_WRONGMODE)
{
}
}
}
GSTexture* GSDevice7::Create(int type, int w, int h, bool msaa, int format)
{
HRESULT hr;
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;
GSTexture7* t = NULL;
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 = new GSTexture7(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 = new GSTexture7(type, system);
break;
}
return t;
}
void GSDevice7::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
{
HRESULT hr;
hr = (*(GSTexture7*)dt)->Blt(NULL, *(GSTexture7*)st[0], NULL, DDBLT_WAIT, NULL);
}
void GSDevice7::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
{
}

View File

@ -1,47 +0,0 @@
/*
* 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
{
private:
CComPtr<IDirectDraw7> m_dd;
CComPtr<IDirectDrawSurface7> m_primary;
bool m_lost;
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);
public:
GSDevice7();
virtual ~GSDevice7();
bool Create(GSWnd* wnd);
bool Reset(int w, int h);
bool IsLost(bool update) {return m_lost;}
void Present(const GSVector4i& r, int shader);
};

View File

@ -674,12 +674,12 @@ void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, c
}
IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices));
IASetInputLayout(m_convert.il);
IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
// vs
VSSetShader(m_convert.vs, NULL, 0);
IASetInputLayout(m_convert.il);
// ps
@ -751,12 +751,12 @@ void GSDevice9::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1 (&iaVe
// ia
IASetVertexBuffer(iaVertices, sizeof(iaVertices[0]), countof(iaVertices));
IASetInputLayout(m_convert.il);
IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
// vs
VSSetShader(m_convert.vs, NULL, 0);
IASetInputLayout(m_convert.il);
// ps

View File

@ -1,532 +0,0 @@
/*
* 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 "GSdx.h"
#include "GSDeviceOGL.h"
#include "resource.h"
GSDeviceOGL::GSDeviceOGL()
: m_hDC(NULL)
, m_hGLRC(NULL)
, m_vbo(0)
, m_fbo(0)
, m_context(0)
, m_topology(-1)
, m_ps_ss(NULL)
, m_scissor(0, 0, 0, 0)
, m_viewport(0, 0)
, m_dss(NULL)
, m_bs(NULL)
, m_bf(-1)
, m_rt((GLuint)-1)
, m_ds((GLuint)-1)
{
m_vertices.stride = 0;
m_vertices.start = 0;
m_vertices.count = 0;
m_vertices.limit = 0;
}
GSDeviceOGL::~GSDeviceOGL()
{
if(m_context) cgDestroyContext(m_context);
if(m_vbo) glDeleteBuffers(1, &m_vbo);
if(m_fbo) glDeleteFramebuffers(1, &m_fbo);
#ifdef _WINDOWS
if(m_hGLRC) {wglMakeCurrent(NULL, NULL); wglDeleteContext(m_hGLRC);}
if(m_hDC) ReleaseDC((HWND)m_wnd->GetHandle(), m_hDC);
#endif
}
void GSDeviceOGL::OnCgError(CGcontext ctx, CGerror err)
{
printf("%s\n", cgGetErrorString(err));
printf("%s\n", cgGetLastListing(ctx)); // ?
}
bool GSDeviceOGL::Create(GSWnd* wnd)
{
if(!__super::Create(wnd))
{
return false;
}
cgSetErrorHandler(OnStaticCgError, this);
#ifdef _WINDOWS
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32; // 24?
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
m_hDC = GetDC((HWND)m_wnd->GetHandle());
if(!m_hDC) return false;
if(!SetPixelFormat(m_hDC, ChoosePixelFormat(m_hDC, &pfd), &pfd))
{
return false;
}
m_hGLRC = wglCreateContext(m_hDC);
if(!m_hGLRC) return false;
if(!wglMakeCurrent(m_hDC, m_hGLRC))
{
return false;
}
#endif
if(glewInit() != GLEW_OK)
{
return false;
}
const char* vendor = (const char*)glGetString(GL_VENDOR);
const char* renderer = (const char*)glGetString(GL_RENDERER);
const char* version = (const char*)glGetString(GL_VERSION);
const char* exts = (const char*)glGetString(GL_EXTENSIONS);
printf("%s, %s, OpenGL %s\n", vendor, renderer, version);
const char* str = strstr(exts, "ARB_texture_non_power_of_two");
glGenBuffers(1, &m_vbo); CheckError();
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); CheckError();
// TODO: setup layout?
m_context = cgCreateContext();
// cgGLSetDebugMode(CG_FALSE); CheckCgError();
cgSetParameterSettingMode(m_context, CG_DEFERRED_PARAMETER_SETTING); CheckCgError();
/*
struct {CGprofile vs, gs, ps;} m_profile;
m_profile.vs = cgGLGetLatestProfile(CG_GL_VERTEX); CheckCgError();
m_profile.gs = cgGLGetLatestProfile(CG_GL_GEOMETRY); CheckCgError();
m_profile.ps = cgGLGetLatestProfile(CG_GL_FRAGMENT); CheckCgError();
*/
GSVector4i r = wnd->GetClientRect();
Reset(r.width(), r.height());
return true;
}
void GSDeviceOGL::SetVsync(bool enable)
{
__super::SetVsync(enable);
#ifdef _WINDOWS
if(WGLEW_EXT_swap_control)
{
wglSwapIntervalEXT(m_vsync ? 1 : 0);
}
#endif
}
bool GSDeviceOGL::Reset(int w, int h)
{
if(!__super::Reset(w, h))
return false;
glCullFace(GL_FRONT_AND_BACK); CheckError();
glDisable(GL_LIGHTING); CheckError();
glDisable(GL_ALPHA_TEST); CheckError();
glEnable(GL_SCISSOR_TEST); CheckError();
glMatrixMode(GL_PROJECTION); CheckError();
glLoadIdentity(); CheckError();
glMatrixMode(GL_MODELVIEW); CheckError();
glLoadIdentity(); CheckError();
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); CheckError();
// glViewport(0, 0, w, h);
if(m_fbo) {glDeleteFramebuffersEXT(1, &m_fbo); m_fbo = 0;}
glGenFramebuffers(1, &m_fbo); CheckError();
if(m_fbo == 0) return false;
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); CheckError();
return true;
}
void GSDeviceOGL::Present(const GSVector4i& r, int shader)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0); CheckError();
// TODO: m_current => backbuffer
Flip();
}
void GSDeviceOGL::Flip()
{
#ifdef _WINDOWS
SwapBuffers(m_hDC);
#endif
}
void GSDeviceOGL::DrawPrimitive()
{
glDrawArrays(m_topology, m_vertices.count, m_vertices.start); CheckError();
}
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
{
GLuint texture = *(GSTextureOGL*)t;
if(texture == 0)
{
// TODO: backbuffer
}
else
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, texture); CheckError();
}
// TODO: disable scissor, color mask
glClearColor(c.r, c.g, c.b, c.a); CheckError();
glClear(GL_COLOR_BUFFER_BIT); CheckError();
}
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
{
ClearRenderTarget(t, GSVector4(c) * (1.0f / 255));
}
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, *(GSTextureOGL*)t); CheckError();
// TODO: disable scissor, depth mask
glClearDepth(c); CheckError();
glClear(GL_DEPTH_BUFFER_BIT); CheckError();
}
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX, *(GSTextureOGL*)t); CheckError();
// TODO: disable scissor, depth (?) mask
glClearStencil((GLint)c); CheckError();
glClear(GL_STENCIL_BUFFER_BIT); CheckError();
}
GSTexture* GSDeviceOGL::Create(int type, int w, int h, bool msaa, int format)
{
GLuint texture = 0;
switch(type)
{
case GSTexture::RenderTarget:
glGenTextures(1, &texture); CheckError();
glBindTexture(GL_TEXTURE_2D, texture); CheckError();
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); CheckError();
break;
case GSTexture::DepthStencil:
glGenRenderbuffers(1, &texture); CheckError();
glBindRenderbuffer(GL_RENDERBUFFER, texture); CheckError();
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH32F_STENCIL8, w, h); CheckError();
// TODO: depth textures?
break;
case GSTexture::Texture:
glGenTextures(1, &texture); CheckError();
glBindTexture(GL_TEXTURE_2D, texture); CheckError();
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); CheckError();
break;
case GSTexture::Offscreen:
// TODO: ???
break;
}
if(!texture) return false;
GSTextureOGL* t = new GSTextureOGL(texture, type, w, h, format);
switch(type)
{
case GSTexture::RenderTarget:
ClearRenderTarget(t, 0);
break;
case GSTexture::DepthStencil:
ClearDepth(t, 0);
break;
}
return t;
}
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, bool msaa, int format)
{
return __super::CreateRenderTarget(w, h, msaa, format ? format : GL_RGBA8);
}
GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, bool msaa, int format)
{
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)
{
return __super::CreateTexture(w, h, format ? format : GL_RGBA8);
}
GSTexture* GSDeviceOGL::CreateOffscreen(int w, int h, int format)
{
return __super::CreateOffscreen(w, h, format ? format : GL_RGBA8);
}
GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
{
// TODO
return NULL;
}
void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
{
// TODO
}
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
{
// TODO
}
void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
{
// TODO
}
void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
{
// TODO
}
void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t count)
{
ASSERT(m_vertices.count == 0);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); CheckError();
bool growbuffer = false;
bool discard = false; // in opengl 3.x this should be a flag to glMapBuffer, as I read somewhere
if(count * stride > m_vertices.limit * m_vertices.stride)
{
m_vertices.start = 0;
m_vertices.count = 0;
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
growbuffer = true;
}
if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride)
{
m_vertices.start = 0;
discard = true;
}
if(growbuffer || discard)
{
glBufferData(GL_ARRAY_BUFFER, m_vertices.limit * stride, NULL, GL_DYNAMIC_DRAW); CheckError(); // GL_STREAM_DRAW?
}
glBufferSubData(GL_ARRAY_BUFFER, m_vertices.start * stride, count * stride, vertices); CheckError();
/*
if(GLvoid* v = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY))
{
GSVector4i::storent((uint8*)v + m_vertices.start * stride, vertices, count * stride);
glUnmapBuffer(GL_ARRAY_BUFFER); CheckError();
}
*/
m_vertices.count = count;
m_vertices.stride = stride;
}
void GSDeviceOGL::IASetInputLayout()
{
// TODO
}
void GSDeviceOGL::IASetPrimitiveTopology(int topology)
{
m_topology = topology;
}
void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
{
// TODO
}
void GSDeviceOGL::PSSetSamplerState(SamplerStateOGL* ss)
{
if(ss && m_ps_ss != ss)
{
m_ps_ss = ss;
glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ss->wrap.s);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ss->wrap.t);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ss->filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ss->filter);
glActiveTexture(GL_TEXTURE1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ss->wrap.s);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ss->wrap.t);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ss->filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ss->filter);
glActiveTexture(GL_TEXTURE2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_POINT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_POINT);
glActiveTexture(GL_TEXTURE3);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_POINT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_POINT);
}
}
void GSDeviceOGL::OMSetDepthStencilState(DepthStencilStateOGL* dss)
{
if(m_dss != dss)
{
m_dss = dss;
if(dss->depth.enable)
{
glEnable(GL_DEPTH_TEST); CheckError();
glDepthFunc(dss->depth.func); CheckError();
glDepthMask(dss->depth.write); CheckError();
}
else
{
glDisable(GL_DEPTH_TEST); CheckError();
}
if(dss->stencil.enable)
{
glEnable(GL_STENCIL_TEST); CheckError();
glStencilFunc(dss->stencil.func, dss->stencil.ref, dss->stencil.mask); CheckError();
glStencilOp(dss->stencil.sfail, dss->stencil.dpfail, dss->stencil.dppass); CheckError();
glStencilMask(dss->stencil.wmask); CheckError();
}
else
{
glDisable(GL_STENCIL_TEST); CheckError();
}
}
}
void GSDeviceOGL::OMSetBlendState(BlendStateOGL* bs, float bf)
{
if(m_bs != bs || m_bf != bf)
{
m_bs = bs;
m_bf = bf;
if(bs->enable)
{
glEnable(GL_BLEND); CheckError();
glBlendEquationSeparate(bs->modeRGB, bs->modeAlpha); CheckError();
glBlendFuncSeparate(bs->srcRGB, bs->dstRGB, bs->srcAlpha, bs->dstAlpha); CheckError();
glBlendColor(bf, bf, bf, 0); CheckError();
}
else
{
glDisable(GL_BLEND); CheckError();
}
glColorMask(bs->mask.r, bs->mask.g, bs->mask.b, bs->mask.a); CheckError();
}
}
void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
{
GLuint rti = 0;
GLuint dsi = 0;
if(rt) rti = *(GSTextureOGL*)rt;
if(ds) dsi = *(GSTextureOGL*)ds;
if(m_rt != rti)
{
m_rt = rti;
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rti); CheckError();
}
if(m_ds != dsi)
{
m_ds = dsi;
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, dsi); CheckError();
}
if(m_viewport != rt->GetSize())
{
m_viewport = rt->GetSize();
glViewport(0, 0, rt->GetWidth(), rt->GetHeight()); CheckError();
}
GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy();
if(!m_scissor.eq(r))
{
m_scissor = r;
glScissor(r.left, r.top, r.width(), r.height()); CheckError();
}
}

View File

@ -1,186 +0,0 @@
/*
* 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 "GSTextureOGL.h"
struct SamplerStateOGL
{
struct {GLenum s, t;} wrap;
GLenum filter;
};
struct DepthStencilStateOGL
{
struct
{
bool enable;
bool write;
GLenum func;
} depth;
struct
{
bool enable;
GLenum func;
GLint ref;
GLuint mask;
GLenum sfail;
GLenum dpfail;
GLenum dppass;
GLuint wmask;
} stencil;
};
struct BlendStateOGL
{
bool enable;
GLenum srcRGB;
GLenum dstRGB;
GLenum srcAlpha;
GLenum dstAlpha;
GLenum modeRGB;
GLenum modeAlpha;
union {uint8 r:1, g:1, b:1, a:1;} mask;
};
class GSDeviceOGL : public GSDevice
{
#ifdef _WINDOWS
HDC m_hDC;
HGLRC m_hGLRC;
#endif
GLuint m_vbo;
GLuint m_fbo;
struct
{
size_t stride, start, count, limit;
} m_vertices;
int m_topology;
SamplerStateOGL* m_ps_ss;
GSVector4i m_scissor;
GSVector2i m_viewport;
DepthStencilStateOGL* m_dss;
BlendStateOGL* m_bs;
float m_bf;
GLuint m_rt;
GLuint m_ds;
//
CGcontext m_context;
static void OnStaticCgError(CGcontext ctx, CGerror err, void* p) {((GSDeviceOGL*)p)->OnCgError(ctx, err);}
void OnCgError(CGcontext ctx, CGerror err);
//
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);
public:
GSDeviceOGL();
virtual ~GSDeviceOGL();
bool Create(GSWnd* wnd);
bool Reset(int w, int h);
void Present(const GSVector4i& r, int shader);
void Flip();
void SetVsync(bool enable);
void DrawPrimitive();
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
void ClearRenderTarget(GSTexture* t, uint32 c);
void ClearDepth(GSTexture* t, float c);
void ClearStencil(GSTexture* t, uint8 c);
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* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
void IASetVertexBuffer(const void* vertices, size_t stride, size_t count);
void IASetInputLayout(); // TODO
void IASetPrimitiveTopology(int topology);
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
void PSSetSamplerState(SamplerStateOGL* ss);
void OMSetDepthStencilState(DepthStencilStateOGL* dss);
void OMSetBlendState(BlendStateOGL* bs, float bf);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
static void CheckError()
{
#ifdef _DEBUG
GLenum error = glGetError();
if(error != GL_NO_ERROR)
{
printf("%s\n", gluErrorString(error));
}
#endif
}
static void CheckFrameBuffer()
{
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
{
printf("%d\n", status);
}
}
void CheckCgError()
{
CGerror error;
const char* s = cgGetLastErrorString(&error);
if(error != CG_NO_ERROR)
{
printf("%s\n", s);
if(error == CG_COMPILER_ERROR)
{
printf("%s\n", cgGetLastListing(m_context));
}
}
}
};

View File

@ -1,223 +0,0 @@
/*
* 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 "GSRendererDX10.h"
#include "GSCrc.h"
#include "resource.h"
GSRendererDX10::GSRendererDX10()
: GSRendererDX<GSVertexHW10>(new GSTextureCache10(this), GSVector2(-0.5f, -0.5f))
{
InitVertexKick<GSRendererDX10>();
}
bool GSRendererDX10::CreateDevice(GSDevice* dev)
{
if(!__super::CreateDevice(dev))
return false;
return true;
}
template<uint32 prim, uint32 tme, uint32 fst>
void GSRendererDX10::VertexKick(bool skip)
{
GSVertexHW10& dst = m_vl.AddTail();
dst.vi[0] = m_v.vi[0];
dst.vi[1] = m_v.vi[1];
#ifdef USE_UPSCALE_HACKS
if(tme && fst)
{
//GSVector4::storel(&dst.ST, m_v.GetUV());
int Udiff = 0;
int Vdiff = 0;
int Uadjust = 0;
int Vadjust = 0;
int multiplier = upscale_Multiplier();
if (multiplier > 1) {
Udiff = m_v.UV.U & 4095;
Vdiff = m_v.UV.V & 4095;
if (Udiff != 0){
if (Udiff >= 4080) {/*printf("U+ %d %d\n", Udiff, m_v.UV.U);*/ Uadjust = -1; }
else if (Udiff <= 16) {/*printf("U- %d %d\n", Udiff, m_v.UV.U);*/ Uadjust = 1; }
}
if (Vdiff != 0){
if (Vdiff >= 4080) {/*printf("V+ %d %d\n", Vdiff, m_v.UV.V);*/ Vadjust = -1; }
else if (Vdiff <= 16) {/*printf("V- %d %d\n", Vdiff, m_v.UV.V);*/ Vadjust = 1; }
}
Udiff = m_v.UV.U & 255;
Vdiff = m_v.UV.V & 255;
if (Udiff != 0){
if (Udiff >= 248) { Uadjust = -1; }
else if (Udiff <= 8) { Uadjust = 1; }
}
if (Vdiff != 0){
if (Vdiff >= 248) { Vadjust = -1; }
else if (Vdiff <= 8) { Vadjust = 1; }
}
Udiff = m_v.UV.U & 15;
Vdiff = m_v.UV.V & 15;
if (Udiff != 0){
if (Udiff >= 15) { Uadjust = -1; }
else if (Udiff <= 1) { Uadjust = 1; }
}
if (Vdiff != 0){
if (Vdiff >= 15) { Vadjust = -1; }
else if (Vdiff <= 1) { Vadjust = 1; }
}
}
dst.ST.S = (float)m_v.UV.U - Uadjust;
dst.ST.T = (float)m_v.UV.V - Vadjust;
}
else if (tme)
{
// Wip :p
//dst.XYZ.X += 5;
//dst.XYZ.Y += 5;
}
#else
if(tme && fst)
{
GSVector4::storel(&dst.ST, m_v.GetUV());
}
#endif
int count = 0;
if(GSVertexHW10* v = DrawingKick<prim>(skip, count))
{
GSVector4i scissor = m_context->scissor.dx10;
GSVector4i pmin, pmax;
#if _M_SSE >= 0x401
GSVector4i v0, v1, v2;
switch(prim)
{
case GS_POINTLIST:
v0 = GSVector4i::load((int)v[0].p.xy).upl16();
pmin = v0;
pmax = v0;
break;
case GS_LINELIST:
case GS_LINESTRIP:
case GS_SPRITE:
v0 = GSVector4i::load((int)v[0].p.xy);
v1 = GSVector4i::load((int)v[1].p.xy);
pmin = v0.min_u16(v1).upl16();
pmax = v0.max_u16(v1).upl16();
break;
case GS_TRIANGLELIST:
case GS_TRIANGLESTRIP:
case GS_TRIANGLEFAN:
v0 = GSVector4i::load((int)v[0].p.xy);
v1 = GSVector4i::load((int)v[1].p.xy);
v2 = GSVector4i::load((int)v[2].p.xy);
pmin = v0.min_u16(v1).min_u16(v2).upl16();
pmax = v0.max_u16(v1).max_u16(v2).upl16();
break;
}
#else
switch(prim)
{
case GS_POINTLIST:
pmin.x = v[0].p.x;
pmin.y = v[0].p.y;
pmax.x = v[0].p.x;
pmax.y = v[0].p.y;
break;
case GS_LINELIST:
case GS_LINESTRIP:
case GS_SPRITE:
pmin.x = std::min<uint16>(v[0].p.x, v[1].p.x);
pmin.y = std::min<uint16>(v[0].p.y, v[1].p.y);
pmax.x = std::max<uint16>(v[0].p.x, v[1].p.x);
pmax.y = std::max<uint16>(v[0].p.y, v[1].p.y);
break;
case GS_TRIANGLELIST:
case GS_TRIANGLESTRIP:
case GS_TRIANGLEFAN:
pmin.x = std::min<uint16>(std::min<uint16>(v[0].p.x, v[1].p.x), v[2].p.x);
pmin.y = std::min<uint16>(std::min<uint16>(v[0].p.y, v[1].p.y), v[2].p.y);
pmax.x = std::max<uint16>(std::max<uint16>(v[0].p.x, v[1].p.x), v[2].p.x);
pmax.y = std::max<uint16>(std::max<uint16>(v[0].p.y, v[1].p.y), v[2].p.y);
break;
}
#endif
GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy());
switch(prim)
{
case GS_TRIANGLELIST:
case GS_TRIANGLESTRIP:
case GS_TRIANGLEFAN:
case GS_SPRITE:
test |= pmin == pmax;
break;
}
if(test.mask() & 0xff)
{
return;
}
m_count += count;
}
}
void GSRendererDX10::Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex)
{
switch(m_vt.m_primclass)
{
case GS_POINT_CLASS:
m_topology = D3D10_PRIMITIVE_TOPOLOGY_POINTLIST;
m_perfmon.Put(GSPerfMon::Prim, m_count);
break;
case GS_LINE_CLASS:
case GS_SPRITE_CLASS:
m_topology = D3D10_PRIMITIVE_TOPOLOGY_LINELIST;
m_perfmon.Put(GSPerfMon::Prim, m_count / 2);
break;
case GS_TRIANGLE_CLASS:
m_topology = D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
m_perfmon.Put(GSPerfMon::Prim, m_count / 3);
break;
default:
__assume(0);
}
__super::Draw(rt, ds, tex);
}

View File

@ -1,40 +0,0 @@
/*
* 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 "GSRendererDX.h"
#include "GSVertexHW.h"
#include "GSTextureCache10.h"
class GSRendererDX10 : public GSRendererDX<GSVertexHW10>
{
protected:
void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex);
public:
GSRendererDX10();
virtual ~GSRendererDX10() {}
bool CreateDevice(GSDevice* dev);
template<uint32 prim, uint32 tme, uint32 fst> void VertexKick(bool skip);
};

View File

@ -46,10 +46,68 @@ void GSRendererDX11::VertexKick(bool skip)
dst.vi[0] = m_v.vi[0];
dst.vi[1] = m_v.vi[1];
#ifdef USE_UPSCALE_HACKS
if(tme && fst)
{
//GSVector4::storel(&dst.ST, m_v.GetUV());
int Udiff = 0;
int Vdiff = 0;
int Uadjust = 0;
int Vadjust = 0;
int multiplier = upscale_Multiplier();
if (multiplier > 1) {
Udiff = m_v.UV.U & 4095;
Vdiff = m_v.UV.V & 4095;
if (Udiff != 0){
if (Udiff >= 4080) {/*printf("U+ %d %d\n", Udiff, m_v.UV.U);*/ Uadjust = -1; }
else if (Udiff <= 16) {/*printf("U- %d %d\n", Udiff, m_v.UV.U);*/ Uadjust = 1; }
}
if (Vdiff != 0){
if (Vdiff >= 4080) {/*printf("V+ %d %d\n", Vdiff, m_v.UV.V);*/ Vadjust = -1; }
else if (Vdiff <= 16) {/*printf("V- %d %d\n", Vdiff, m_v.UV.V);*/ Vadjust = 1; }
}
Udiff = m_v.UV.U & 255;
Vdiff = m_v.UV.V & 255;
if (Udiff != 0){
if (Udiff >= 248) { Uadjust = -1; }
else if (Udiff <= 8) { Uadjust = 1; }
}
if (Vdiff != 0){
if (Vdiff >= 248) { Vadjust = -1; }
else if (Vdiff <= 8) { Vadjust = 1; }
}
Udiff = m_v.UV.U & 15;
Vdiff = m_v.UV.V & 15;
if (Udiff != 0){
if (Udiff >= 15) { Uadjust = -1; }
else if (Udiff <= 1) { Uadjust = 1; }
}
if (Vdiff != 0){
if (Vdiff >= 15) { Vadjust = -1; }
else if (Vdiff <= 1) { Vadjust = 1; }
}
}
dst.ST.S = (float)m_v.UV.U - Uadjust;
dst.ST.T = (float)m_v.UV.V - Vadjust;
}
else if (tme)
{
// Wip :p
//dst.XYZ.X += 5;
//dst.XYZ.Y += 5;
}
#else
if(tme && fst)
{
GSVector4::storel(&dst.ST, m_v.GetUV());
}
#endif
int count = 0;

View File

@ -1,79 +0,0 @@
/*
* 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 "GSRendererOGL.h"
#include "GSCrc.h"
#include "resource.h"
GSRendererOGL::GSRendererOGL()
: GSRendererHW<GSVertexOGL>(new GSTextureCacheOGL(this))
{
InitVertexKick<GSRendererOGL>();
}
bool GSRendererOGL::CreateDevice(GSDevice* dev)
{
if(!__super::CreateDevice(dev))
return false;
// TODO
/*
if(!m_tfx.Create((GSDeviceOGL*)m_dev))
return false;
*/
return true;
}
template<uint32 prim, uint32 tme, uint32 fst>
void GSRendererOGL::VertexKick(bool skip)
{
GSVertexOGL& dst = m_vl.AddTail();
// TODO
int count = 0;
if(GSVertexOGL* v = DrawingKick<prim>(skip, count))
{
// TODO
m_count += count;
}
}
void GSRendererOGL::Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex)
{
GSDrawingEnvironment& env = m_env;
GSDrawingContext* context = m_context;
// m_perfmon.Put(GSPerfMon::Prim, prims);
m_dev->BeginScene();
// TODO
m_dev->EndScene();
}

View File

@ -1,40 +0,0 @@
/*
* 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 "GSRendererHW.h"
#include "GSVertexHW.h"
#include "GSTextureCacheOGL.h"
class GSRendererOGL : public GSRendererHW<GSVertexOGL>
{
protected:
void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex);
public:
GSRendererOGL();
virtual ~GSRendererOGL() {}
bool CreateDevice(GSDevice* dev);
template<uint32 prim, uint32 tme, uint32 fst> void VertexKick(bool skip);
};

View File

@ -30,17 +30,9 @@ GSSetting GSSettingsDlg::g_renderers[] =
{0, "Direct3D9 (Hardware)", NULL},
{1, "Direct3D9 (Software)", NULL},
{2, "Direct3D9 (Null)", NULL},
{3, "Direct3D10 (Hardware)", NULL},
{4, "Direct3D10 (Software)", NULL},
{5, "Direct3D10 (Null)", NULL},
#if 0
{6, "Direct3D11 (Hardware)", NULL},
{7, "Direct3D11 (Software)", NULL},
{8, "Direct3D11 (Null)", NULL},
{9, "OpenGL (Hardware)", NULL},
{10, "OpenGL (Software)", NULL},
{11, "OpenGL (Null)", NULL},
#endif
{3, "Direct3D11 (Hardware)", NULL},
{4, "Direct3D11 (Software)", NULL},
{5, "Direct3D11 (Null)", NULL},
{12, "Null (Software)", NULL},
{13, "Null (Null)", NULL},
};
@ -115,15 +107,13 @@ void GSSettingsDlg::OnInit()
}
}
bool isdx10avail = GSUtil::IsDirect3D10Available();
bool isdx11avail = false; //GSUtil::IsDirect3D11Available();
bool isdx11avail = GSUtil::IsDirect3D11Available();
vector<GSSetting> renderers;
for(size_t i = 0; i < countof(g_renderers); i++)
{
if(i >= 3 && i <= 5 && !isdx10avail) continue;
if(i >= 6 && i <= 8 && !isdx11avail) continue;
if(i >= 3 && i <= 5 && !isdx11avail) continue;
renderers.push_back(g_renderers[i]);
}

View File

@ -1,214 +0,0 @@
/*
* 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 "GSTexture10.h"
GSTexture10::GSTexture10(ID3D10Texture2D* texture)
: m_texture(texture)
{
ASSERT(m_texture);
m_texture->GetDevice(&m_dev);
m_texture->GetDesc(&m_desc);
m_size.x = (int)m_desc.Width;
m_size.y = (int)m_desc.Height;
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;
m_format = (int)m_desc.Format;
m_msaa = m_desc.SampleDesc.Count > 1;
}
bool GSTexture10::Update(const GSVector4i& r, const void* data, int pitch)
{
if(m_dev && m_texture)
{
D3D10_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
m_dev->UpdateSubresource(m_texture, 0, &box, data, pitch, 0);
return true;
}
return false;
}
bool GSTexture10::Map(GSMap& m, const GSVector4i* r)
{
if(r != NULL)
{
// ASSERT(0); // not implemented
return false;
}
if(m_texture && m_desc.Usage == D3D10_USAGE_STAGING)
{
D3D10_MAPPED_TEXTURE2D map;
if(SUCCEEDED(m_texture->Map(0, D3D10_MAP_READ_WRITE, 0, &map)))
{
m.bits = (uint8*)map.pData;
m.pitch = (int)map.RowPitch;
return true;
}
}
return false;
}
void GSTexture10::Unmap()
{
if(m_texture)
{
m_texture->Unmap(0);
}
}
bool GSTexture10::Save(const string& fn, bool dds)
{
CComPtr<ID3D10Resource> res;
if(m_desc.BindFlags & D3D10_BIND_DEPTH_STENCIL)
{
HRESULT hr;
D3D10_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
m_texture->GetDesc(&desc);
desc.Usage = D3D10_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
CComPtr<ID3D10Texture2D> src, dst;
hr = m_dev->CreateTexture2D(&desc, NULL, &src);
m_dev->CopyResource(src, m_texture);
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
hr = m_dev->CreateTexture2D(&desc, NULL, &dst);
D3D10_MAPPED_TEXTURE2D sm, dm;
hr = src->Map(0, D3D10_MAP_READ, 0, &sm);
hr = dst->Map(0, D3D10_MAP_WRITE, 0, &dm);
uint8* s = (uint8*)sm.pData;
uint8* d = (uint8*)dm.pData;
for(uint32 y = 0; y < desc.Height; y++, s += sm.RowPitch, d += dm.RowPitch)
{
for(uint32 x = 0; x < desc.Width; x++)
{
((uint32*)d)[x] = (uint32)(((float*)s)[x*2] * UINT_MAX);
}
}
src->Unmap(0);
dst->Unmap(0);
res = dst;
}
else
{
res = m_texture;
}
return SUCCEEDED(D3DX10SaveTextureToFile(res, dds ? D3DX10_IFF_DDS : D3DX10_IFF_BMP, fn.c_str()));
}
GSTexture10::operator ID3D10Texture2D*()
{
return m_texture;
}
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)
{
desc = new D3D10_SHADER_RESOURCE_VIEW_DESC();
memset(desc, 0, sizeof(*desc));
desc->Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
desc->ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
desc->Texture2D.MostDetailedMip = 0;
desc->Texture2D.MipLevels = 1;
}
m_dev->CreateShaderResourceView(m_texture, desc, &m_srv);
delete desc;
}
return m_srv;
}
GSTexture10::operator ID3D10RenderTargetView*()
{
ASSERT(m_dev);
if(!m_rtv && m_dev && m_texture)
{
m_dev->CreateRenderTargetView(m_texture, NULL, &m_rtv);
}
return m_rtv;
}
GSTexture10::operator ID3D10DepthStencilView*()
{
if(!m_dsv && m_dev && m_texture)
{
D3D10_DEPTH_STENCIL_VIEW_DESC* desc = NULL;
if(m_desc.Format == DXGI_FORMAT_R32G8X24_TYPELESS)
{
desc = new D3D10_DEPTH_STENCIL_VIEW_DESC();
memset(desc, 0, sizeof(*desc));
desc->Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
desc->ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
}
m_dev->CreateDepthStencilView(m_texture, desc, &m_dsv);
delete desc;
}
return m_dsv;
}

View File

@ -1,47 +0,0 @@
/*
* 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"
class GSTexture10 : public GSTexture
{
CComPtr<ID3D10Device> m_dev;
CComPtr<ID3D10Texture2D> m_texture;
D3D10_TEXTURE2D_DESC m_desc;
CComPtr<ID3D10ShaderResourceView> m_srv;
CComPtr<ID3D10RenderTargetView> m_rtv;
CComPtr<ID3D10DepthStencilView> m_dsv;
public:
explicit GSTexture10(ID3D10Texture2D* texture);
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();
bool Save(const string& fn, bool dds = false);
operator ID3D10Texture2D*();
operator ID3D10ShaderResourceView*();
operator ID3D10RenderTargetView*();
operator ID3D10DepthStencilView*();
};

View File

@ -1,164 +0,0 @@
/*
* 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(int type, IDirectDrawSurface7* system)
: m_system(system)
{
memset(&m_desc, 0, sizeof(m_desc));
m_desc.dwSize = sizeof(m_desc);
system->GetSurfaceDesc(&m_desc);
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_system(system)
, m_video(video)
{
memset(&m_desc, 0, sizeof(m_desc));
m_desc.dwSize = sizeof(m_desc);
video->GetSurfaceDesc(&m_desc);
m_size.x = (int)m_desc.dwWidth;
m_size.y = (int)m_desc.dwHeight;
m_type = type;
m_format = (int)m_desc.ddpfPixelFormat.dwFourCC;
}
bool GSTexture7::Update(const GSVector4i& r, const void* data, int pitch)
{
HRESULT hr;
GSVector4i 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)))
{
uint8* src = (uint8*)data;
uint8* dst = (uint8*)desc.lpSurface;
int bytes = std::min<int>(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(GSMap& m, const GSVector4i* r)
{
HRESULT hr;
if(r != NULL)
{
// ASSERT(0); // not implemented
return false;
}
DDSURFACEDESC2 desc;
if(SUCCEEDED(hr = m_system->Lock(NULL, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL)))
{
m.bits = (uint8*)desc.lpSurface;
m.pitch = (int)desc.lPitch;
return true;
}
return false;
}
void GSTexture7::Unmap()
{
HRESULT hr;
hr = m_system->Unlock(NULL);
if(m_video)
{
hr = m_video->Blt(NULL, m_system, NULL, DDBLT_WAIT, NULL);
}
}
bool GSTexture7::Save(const string& 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;
}

View File

@ -1,45 +0,0 @@
/*
* 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
{
CComPtr<IDirectDrawSurface7> m_system;
CComPtr<IDirectDrawSurface7> m_video;
DDSURFACEDESC2 m_desc;
public:
GSTexture7(int type, IDirectDrawSurface7* system);
GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface7* video);
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();
bool Save(const string& fn, bool dds = false);
IDirectDrawSurface7* operator->(); // TODO: remove direct access
operator IDirectDrawSurface7*();
};

View File

@ -1,98 +0,0 @@
/*
* 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 "GSTextureCache10.h"
// GSTextureCache10
GSTextureCache10::GSTextureCache10(GSRenderer* r)
: GSTextureCache(r)
{
}
void GSTextureCache10::Read(Target* t, const GSVector4i& r)
{
if(t->m_type != RenderTarget)
{
// TODO
return;
}
const GIFRegTEX0& TEX0 = t->m_TEX0;
if(TEX0.PSM != PSM_PSMCT32
&& TEX0.PSM != PSM_PSMCT24
&& TEX0.PSM != PSM_PSMCT16
&& TEX0.PSM != PSM_PSMCT16S)
{
//ASSERT(0);
return;
}
if(!t->m_dirty.empty())
{
return;
}
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, TEX0.TBP0);
int w = r.width();
int h = r.height();
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;
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(t->m_texture, src, w, h, format))
{
GSTexture::GSMap m;
if(offscreen->Map(m))
{
// TODO: block level write
GSOffset* o = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM);
switch(TEX0.PSM)
{
case PSM_PSMCT32:
m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r);
break;
case PSM_PSMCT24:
m_renderer->m_mem.WritePixel24(m.bits, m.pitch, o, r);
break;
case PSM_PSMCT16:
case PSM_PSMCT16S:
m_renderer->m_mem.WritePixel16(m.bits, m.pitch, o, r);
break;
default:
ASSERT(0);
}
offscreen->Unmap();
}
m_renderer->m_dev->Recycle(offscreen);
}
}

View File

@ -1,36 +0,0 @@
/*
* 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 "GSTextureCache.h"
#include "GSDevice10.h"
class GSTextureCache10 : public GSTextureCache
{
protected:
int Get8bitFormat() {return DXGI_FORMAT_A8_UNORM;}
void Read(Target* t, const GSVector4i& r);
public:
GSTextureCache10(GSRenderer* r);
};

View File

@ -1,30 +0,0 @@
/*
* 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 "GSTextureCacheOGL.h"
// GSTextureCacheOGL
GSTextureCacheOGL::GSTextureCacheOGL(GSRenderer* r)
: GSTextureCache(r)
{
}

View File

@ -1,36 +0,0 @@
/*
* 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 "GSTextureCache.h"
#include "GSDeviceOGL.h"
class GSTextureCacheOGL : public GSTextureCache
{
protected:
int Get8bitFormat() {return 0;} // TODO
void Read(Target* t, const GSVector4i& r) {} // TODO
public:
GSTextureCacheOGL(GSRenderer* r);
};

View File

@ -1,398 +0,0 @@
/*
* 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 "GSDevice10.h"
#include "resource.h"
#include "GSTables.h"
bool GSDevice10::CreateTextureFX()
{
HRESULT hr;
D3D10_BUFFER_DESC bd;
memset(&bd, 0, sizeof(bd));
bd.ByteWidth = sizeof(VSConstantBuffer);
bd.Usage = D3D10_USAGE_DEFAULT;
bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
hr = m_dev->CreateBuffer(&bd, NULL, &m_vs_cb);
if(FAILED(hr)) return false;
memset(&bd, 0, sizeof(bd));
bd.ByteWidth = sizeof(PSConstantBuffer);
bd.Usage = D3D10_USAGE_DEFAULT;
bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
hr = m_dev->CreateBuffer(&bd, NULL, &m_ps_cb);
if(FAILED(hr)) return false;
D3D10_SAMPLER_DESC sd;
memset(&sd, 0, sizeof(sd));
sd.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT;
sd.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
sd.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
sd.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
sd.MaxLOD = FLT_MAX;
sd.MaxAnisotropy = 16;
sd.ComparisonFunc = D3D10_COMPARISON_NEVER;
hr = m_dev->CreateSamplerState(&sd, &m_palette_ss);
if(FAILED(hr)) return false;
// create layout
VSSelector sel;
VSConstantBuffer cb;
SetupVS(sel, &cb);
return true;
}
void GSDevice10::SetupIA(const void* vertices, int count, int prim)
{
IASetVertexBuffer(vertices, sizeof(GSVertexHW10), count);
IASetPrimitiveTopology((D3D10_PRIMITIVE_TOPOLOGY)prim);
}
void GSDevice10::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
{
hash_map<uint32, GSVertexShader10 >::const_iterator i = m_vs.find(sel);
if(i == m_vs.end())
{
string str[3];
str[0] = format("%d", sel.bppz);
str[1] = format("%d", sel.tme);
str[2] = format("%d", sel.fst);
D3D10_SHADER_MACRO macro[] =
{
{"VS_BPPZ", str[0].c_str()},
{"VS_TME", str[1].c_str()},
{"VS_FST", str[2].c_str()},
{NULL, NULL},
};
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"POSITION", 0, DXGI_FORMAT_R16G16_UINT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"POSITION", 1, DXGI_FORMAT_R32_UINT, 0, 20, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 28, D3D10_INPUT_PER_VERTEX_DATA, 0},
};
GSVertexShader10 vs;
CompileShader(IDR_TFX_FX, "vs_main", macro, &vs.vs, layout, countof(layout), &vs.il);
m_vs[sel] = vs;
i = m_vs.find(sel);
}
if(m_vs_cb_cache.Update(cb))
{
m_dev->UpdateSubresource(m_vs_cb, 0, NULL, cb, 0, 0);
}
VSSetShader(i->second.vs, m_vs_cb);
IASetInputLayout(i->second.il);
}
void GSDevice10::SetupGS(GSSelector sel)
{
ID3D10GeometryShader* gs = NULL;
if(sel.prim > 0 && (sel.iip == 0 || sel.prim == 3)) // geometry shader works in every case, but not needed
{
hash_map<uint32, CComPtr<ID3D10GeometryShader> >::const_iterator i = m_gs.find(sel);
if(i != m_gs.end())
{
gs = i->second;
}
else
{
string str[2];
str[0] = format("%d", sel.iip);
str[1] = format("%d", sel.prim);
D3D10_SHADER_MACRO macro[] =
{
{"GS_IIP", str[0].c_str()},
{"GS_PRIM", str[1].c_str()},
{NULL, NULL},
};
CompileShader(IDR_TFX_FX, "gs_main", macro, &gs);
m_gs[sel] = gs;
}
}
GSSetShader(gs);
}
void GSDevice10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel)
{
hash_map<uint32, CComPtr<ID3D10PixelShader> >::const_iterator i = m_ps.find(sel);
if(i == m_ps.end())
{
string str[14];
str[0] = format("%d", sel.fst);
str[1] = format("%d", sel.wms);
str[2] = format("%d", sel.wmt);
str[3] = format("%d", sel.fmt);
str[4] = format("%d", sel.aem);
str[5] = format("%d", sel.tfx);
str[6] = format("%d", sel.tcc);
str[7] = format("%d", sel.atst);
str[8] = format("%d", sel.fog);
str[9] = format("%d", sel.clr1);
str[10] = format("%d", sel.fba);
str[11] = format("%d", sel.aout);
str[12] = format("%d", sel.ltf);
str[13] = format("%d", sel.colclip);
D3D10_SHADER_MACRO macro[] =
{
{"PS_FST", str[0].c_str()},
{"PS_WMS", str[1].c_str()},
{"PS_WMT", str[2].c_str()},
{"PS_FMT", str[3].c_str()},
{"PS_AEM", str[4].c_str()},
{"PS_TFX", str[5].c_str()},
{"PS_TCC", str[6].c_str()},
{"PS_ATST", str[7].c_str()},
{"PS_FOG", str[8].c_str()},
{"PS_CLR1", str[9].c_str()},
{"PS_FBA", str[10].c_str()},
{"PS_AOUT", str[11].c_str()},
{"PS_LTF", str[12].c_str()},
{"PS_COLCLIP", str[13].c_str()},
{NULL, NULL},
};
CComPtr<ID3D10PixelShader> ps;
CompileShader(IDR_TFX_FX, "ps_main", macro, &ps);
m_ps[sel] = ps;
i = m_ps.find(sel);
}
if(m_ps_cb_cache.Update(cb))
{
m_dev->UpdateSubresource(m_ps_cb, 0, NULL, cb, 0, 0);
}
PSSetShader(i->second, m_ps_cb);
ID3D10SamplerState* ss0 = NULL;
ID3D10SamplerState* ss1 = NULL;
if(sel.tfx != 4)
{
if(!(sel.fmt < 3 && sel.wms < 3 && sel.wmt < 3))
{
ssel.ltf = 0;
}
hash_map<uint32, CComPtr<ID3D10SamplerState> >::const_iterator i = m_ps_ss.find(ssel);
if(i != m_ps_ss.end())
{
ss0 = i->second;
}
else
{
D3D10_SAMPLER_DESC sd;
memset(&sd, 0, sizeof(sd));
sd.Filter = ssel.ltf ? D3D10_FILTER_MIN_MAG_LINEAR_MIP_POINT : D3D10_FILTER_MIN_MAG_MIP_POINT;
sd.AddressU = ssel.tau ? D3D10_TEXTURE_ADDRESS_WRAP : D3D10_TEXTURE_ADDRESS_CLAMP;
sd.AddressV = ssel.tav ? D3D10_TEXTURE_ADDRESS_WRAP : D3D10_TEXTURE_ADDRESS_CLAMP;
sd.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
sd.MaxLOD = FLT_MAX;
sd.MaxAnisotropy = 16;
sd.ComparisonFunc = D3D10_COMPARISON_NEVER;
m_dev->CreateSamplerState(&sd, &ss0);
m_ps_ss[ssel] = ss0;
}
if(sel.fmt >= 3)
{
ss1 = m_palette_ss;
}
}
PSSetSamplerState(ss0, ss1);
}
void GSDevice10::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix)
{
/*
hash_map<uint32, CComPtr<ID3D10DepthStencilState> >::const_iterator i = m_om_dss.find(dssel);
if(i == m_om_dss.end())
{
*/
CComPtr<ID3D10DepthStencilState>& om_dss = m_om_dss[dssel];
if(om_dss == NULL)
{
D3D10_DEPTH_STENCIL_DESC dsd;
memset(&dsd, 0, sizeof(dsd));
if(dssel.date)
{
dsd.StencilEnable = true;
dsd.StencilReadMask = 1;
dsd.StencilWriteMask = 1;
dsd.FrontFace.StencilFunc = D3D10_COMPARISON_EQUAL;
dsd.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsd.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsd.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP;
dsd.BackFace.StencilFunc = D3D10_COMPARISON_EQUAL;
dsd.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsd.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsd.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP;
}
if(dssel.ztst != ZTST_ALWAYS || dssel.zwe)
{
static const D3D10_COMPARISON_FUNC ztst[] =
{
D3D10_COMPARISON_NEVER,
D3D10_COMPARISON_ALWAYS,
D3D10_COMPARISON_GREATER_EQUAL,
D3D10_COMPARISON_GREATER
};
dsd.DepthEnable = true;
dsd.DepthWriteMask = dssel.zwe ? D3D10_DEPTH_WRITE_MASK_ALL : D3D10_DEPTH_WRITE_MASK_ZERO;
dsd.DepthFunc = ztst[dssel.ztst];
}
/*
CComPtr<ID3D10DepthStencilState> dss;
m_dev->CreateDepthStencilState(&dsd, &dss);
m_om_dss[dssel] = dss;
i = m_om_dss.find(dssel);
*/
m_dev->CreateDepthStencilState(&dsd, &om_dss);
}
// OMSetDepthStencilState(i->second, 1);
OMSetDepthStencilState(om_dss, 1);
hash_map<uint32, CComPtr<ID3D10BlendState> >::const_iterator j = m_om_bs.find(bsel);
if(j == m_om_bs.end())
{
D3D10_BLEND_DESC bd;
memset(&bd, 0, sizeof(bd));
bd.BlendEnable[0] = bsel.abe;
if(bsel.abe)
{
int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d;
bd.BlendOp = (D3D10_BLEND_OP)blendMapD3D9[i].op;
bd.SrcBlend = (D3D10_BLEND)blendMapD3D9[i].src;
bd.DestBlend = (D3D10_BLEND)blendMapD3D9[i].dst;
bd.BlendOpAlpha = D3D10_BLEND_OP_ADD;
bd.SrcBlendAlpha = D3D10_BLEND_ONE;
bd.DestBlendAlpha = D3D10_BLEND_ZERO;
// SRC* -> SRC1*
// Yes, this casting mess really is needed. I want to go back to C
if (bd.SrcBlend >= 3 && bd.SrcBlend <= 6)
bd.SrcBlend = (D3D10_BLEND)((int)bd.SrcBlend + 13);
if (bd.DestBlend >= 3 && bd.DestBlend <= 6)
bd.DestBlend = (D3D10_BLEND)((int)bd.DestBlend + 13);
// Not very good but I don't wanna write another 81 row table
if (bsel.negative) {
if (bd.BlendOp == D3D10_BLEND_OP_ADD)
bd.BlendOp = D3D10_BLEND_OP_REV_SUBTRACT;
else if (bd.BlendOp == D3D10_BLEND_OP_REV_SUBTRACT)
bd.BlendOp = D3D10_BLEND_OP_ADD;
else
; // god knows, best just not to mess with it for now
}
if(blendMapD3D9[i].bogus == 1)
{
(bsel.a == 0 ? bd.SrcBlend : bd.DestBlend) = D3D10_BLEND_ONE;
const string afixstr = format("%d >> 7", afix);
const char *col[3] = {"Cs", "Cd", "0"};
const char *alpha[3] = {"As", "Ad", afixstr.c_str()};
printf("Impossible blend for D3D: (%s - %s) * %s + %s\n",
col[bsel.a], col[bsel.b], alpha[bsel.c], col[bsel.d]);
}
}
if(bsel.wr) bd.RenderTargetWriteMask[0] |= D3D10_COLOR_WRITE_ENABLE_RED;
if(bsel.wg) bd.RenderTargetWriteMask[0] |= D3D10_COLOR_WRITE_ENABLE_GREEN;
if(bsel.wb) bd.RenderTargetWriteMask[0] |= D3D10_COLOR_WRITE_ENABLE_BLUE;
if(bsel.wa) bd.RenderTargetWriteMask[0] |= D3D10_COLOR_WRITE_ENABLE_ALPHA;
CComPtr<ID3D10BlendState> bs;
m_dev->CreateBlendState(&bd, &bs);
m_om_bs[bsel] = bs;
j = m_om_bs.find(bsel);
}
OMSetBlendState(j->second, (float)(int)afix / 0x80);
}

View File

@ -1,111 +0,0 @@
/*
* 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 "GSTextureOGL.h"
#include "GSDeviceOGL.h"
GSTextureOGL::GSTextureOGL(GLuint texture, int type, int width, int height, int format)
: m_texture(texture)
{
m_size.x = width;
m_size.y = height;
// 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()
{
if(m_pbo)
{
glDeleteBuffers(1, &m_pbo); GSDeviceOGL::CheckError();
}
if(m_texture)
{
switch(m_type)
{
case DepthStencil:
glDeleteRenderbuffers(1, &m_texture); GSDeviceOGL::CheckError();
break;
default:
glDeleteTextures(1, &m_texture); GSDeviceOGL::CheckError();
break;
}
}
}
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo); GSDeviceOGL::CheckError();
int w = r.width();
int h = r.height();
int bpp = 32; // TODO: should be in sync with m_format
int dstpitch = w * bpp >> 3;
glBufferData(GL_PIXEL_UNPACK_BUFFER, h * dstpitch, NULL, GL_STREAM_DRAW); GSDeviceOGL::CheckError();
if(uint8* dst = (uint8*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY))
{
uint8* src = (uint8*)data;
for(int i = 0; i < h; i++, src += pitch, dst += dstpitch)
{
memcpy(dst, src, dstpitch);
}
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); GSDeviceOGL::CheckError();
}
glBindTexture(GL_TEXTURE_2D, m_texture); GSDeviceOGL::CheckError();
glTexSubImage2D(GL_TEXTURE_2D, 0, r.left, r.top, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0); GSDeviceOGL::CheckError();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); GSDeviceOGL::CheckError();
return false;
}
bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
{
// TODO
return false;
}
void GSTextureOGL::Unmap()
{
// TODO
}
bool GSTextureOGL::Save(const string& fn, bool dds)
{
// TODO
return false;
}

View File

@ -1,44 +0,0 @@
/*
* 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"
class GSTextureOGL : public GSTexture
{
GLuint m_texture;
GLuint m_pbo;
int m_type;
int m_format;
public:
GSTextureOGL(GLuint texture, int type, int width, int height, int format = 0);
virtual ~GSTextureOGL();
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();
bool Save(const string& fn, bool dds = false);
operator GLuint() {return m_texture;}
};

View File

@ -189,18 +189,6 @@ bool GSUtil::CheckSSE()
return true;
}
bool GSUtil::IsDirect3D10Available()
{
if(HMODULE hModule = LoadLibrary(_T("d3d10_1.dll")))
{
FreeLibrary(hModule);
return true;
}
return false;
}
bool GSUtil::IsDirect3D11Available()
{
if(HMODULE hModule = LoadLibrary(_T("d3d11.dll")))

View File

@ -36,7 +36,6 @@ public:
static bool CheckDirectX();
static bool CheckSSE();
static bool IsDirect3D10Available();
static bool IsDirect3D11Available();
static char* GetLibName();

View File

@ -56,7 +56,7 @@ __aligned16 union GSVertexHW9
float GetQ() {return p.w;}
};
__aligned16 union GSVertexHW10
__aligned16 union GSVertexHW11
{
struct
{
@ -88,13 +88,9 @@ __aligned16 union GSVertexHW10
struct {GSVector4i vi[2];};
struct {GSVector4 vf[2];};
GSVertexHW10& operator = (GSVertexHW10& v) {vi[0] = v.vi[0]; vi[1] = v.vi[1]; return *this;}
GSVertexHW11& operator = (GSVertexHW11& v) {vi[0] = v.vi[0]; vi[1] = v.vi[1]; return *this;}
float GetQ() {return q;}
};
typedef GSVertexHW10 GSVertexHW11; // TODO
typedef GSVertexHW9 GSVertexOGL; // TODO
#pragma pack(pop)

View File

@ -86,9 +86,9 @@ void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primcl
m_alpha.valid = false;
}
void GSVertexTrace::Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass)
void GSVertexTrace::Update(const GSVertexHW11* v, int count, GS_PRIM_CLASS primclass)
{
m_map_hw10[Hash(primclass)](v, count, m_min, m_max);
m_map_hw11[Hash(primclass)](v, count, m_min, m_max);
const GSDrawingContext* context = m_state->m_context;
@ -480,7 +480,7 @@ L("loop");
ret();
}
GSVertexTrace::CGHW10::CGHW10(uint32 key, void* ptr, size_t maxsize)
GSVertexTrace::CGHW11::CGHW11(uint32 key, void* ptr, size_t maxsize)
: CodeGenerator(maxsize, ptr)
{
#if _M_AMD64
@ -564,7 +564,7 @@ L("loop");
{
if(color && (iip || j == n - 1) || tme)
{
movaps(xmm0, xmmword[edx + j * sizeof(GSVertexHW10)]);
movaps(xmm0, xmmword[edx + j * sizeof(GSVertexHW11)]);
}
if(color && (iip || j == n - 1))
@ -593,7 +593,7 @@ L("loop");
maxps(xmm7, xmm0);
}
movdqa(xmm0, xmmword[edx + j * sizeof(GSVertexHW10) + 16]);
movdqa(xmm0, xmmword[edx + j * sizeof(GSVertexHW11) + 16]);
if(m_cpu.has(util::Cpu::tSSE41))
{
@ -614,7 +614,7 @@ L("loop");
maxps(xmm5, xmm1);
}
add(edx, n * sizeof(GSVertexHW10));
add(edx, n * sizeof(GSVertexHW11));
sub(ecx, n);
jg("loop");

View File

@ -66,24 +66,24 @@ __aligned16 class GSVertexTrace
CGHW9* Create(uint32 key, void* ptr, size_t maxsize) {return new CGHW9(key, ptr, maxsize);}
};
class CGHW10 : public Xbyak::CodeGenerator
class CGHW11 : public Xbyak::CodeGenerator
{
Xbyak::util::Cpu m_cpu;
public:
CGHW10(uint32 key, void* ptr, size_t maxsize);
CGHW11(uint32 key, void* ptr, size_t maxsize);
};
class GSVertexTraceMapHW10 : public GSCodeGeneratorFunctionMap<CGHW10, uint32, VertexTracePtr>
class GSVertexTraceMapHW11 : public GSCodeGeneratorFunctionMap<CGHW11, uint32, VertexTracePtr>
{
public:
GSVertexTraceMapHW10() : GSCodeGeneratorFunctionMap("VertexTraceHW10") {}
CGHW10* Create(uint32 key, void* ptr, size_t maxsize) {return new CGHW10(key, ptr, maxsize);}
GSVertexTraceMapHW11() : GSCodeGeneratorFunctionMap("VertexTraceHW11") {}
CGHW11* Create(uint32 key, void* ptr, size_t maxsize) {return new CGHW11(key, ptr, maxsize);}
};
GSVertexTraceMapSW m_map_sw;
GSVertexTraceMapHW9 m_map_hw9;
GSVertexTraceMapHW10 m_map_hw10;
GSVertexTraceMapHW11 m_map_hw11;
uint32 Hash(GS_PRIM_CLASS primclass);
@ -105,6 +105,6 @@ public:
void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass);
void Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass);
void Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass);
void Update(const GSVertexHW11* v, int count, GS_PRIM_CLASS primclass);
void Update(const GSVertexNull* v, int count, GS_PRIM_CLASS primclass) {}
};

View File

@ -41,30 +41,3 @@ EXPORTS
GSgetLastTag
GSReplay
GSBenchmark
PSEgetLibType
PSEgetLibName
PSEgetLibVersion
GPUinit
GPUshutdown
GPUopen
GPUclose
GPUconfigure
GPUabout
GPUtest
GPUwriteData
GPUwriteStatus
GPUreadData
GPUreadStatus
GPUdmaChain
GPUgetMode
GPUsetMode
GPUupdateLace
GPUmakeSnapshot
GPUwriteDataMem
GPUreadDataMem
GPUdisplayText
GPUdisplayFlags
GPUfreeze
GPUshowScreenPic
GPUgetScreenPic
GPUcursor

View File

@ -1039,42 +1039,6 @@
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\GPU.cpp"
>
</File>
<File
RelativePath=".\GPUDrawScanline.cpp"
>
</File>
<File
RelativePath=".\GPUDrawScanlineCodeGenerator.cpp"
>
</File>
<File
RelativePath=".\GPULocalMemory.cpp"
>
</File>
<File
RelativePath=".\GPURenderer.cpp"
>
</File>
<File
RelativePath=".\GPURendererSW.cpp"
>
</File>
<File
RelativePath=".\GPUSettingsDlg.cpp"
>
</File>
<File
RelativePath=".\GPUSetupPrimCodeGenerator.cpp"
>
</File>
<File
RelativePath=".\GPUState.cpp"
>
</File>
<File
RelativePath=".\GS.cpp"
>
@ -1135,18 +1099,10 @@
RelativePath=".\GSDevice.cpp"
>
</File>
<File
RelativePath=".\GSDevice10.cpp"
>
</File>
<File
RelativePath=".\GSDevice11.cpp"
>
</File>
<File
RelativePath=".\GSDevice7.cpp"
>
</File>
<File
RelativePath=".\GSDevice9.cpp"
>
@ -1155,74 +1111,6 @@
RelativePath=".\GSDeviceNull.cpp"
>
</File>
<File
RelativePath=".\GSDeviceOGL.cpp"
>
<FileConfiguration
Name="Debug SSE2|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSE2|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSSE3|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug SSSE3|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug SSE4|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSE4|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSDialog.cpp"
>
@ -1351,26 +1239,6 @@
RelativePath=".\GSRendererDX.cpp"
>
</File>
<File
RelativePath=".\GSRendererDX10.cpp"
>
<FileConfiguration
Name="Release SSE2|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSSE3|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSRendererDX11.cpp"
>
@ -1403,74 +1271,6 @@
RelativePath=".\GSRendererNull.cpp"
>
</File>
<File
RelativePath=".\GSRendererOGL.cpp"
>
<FileConfiguration
Name="Debug SSE2|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSE2|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSSE3|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug SSSE3|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug SSE4|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSE4|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSRendererSW.cpp"
>
@ -1531,18 +1331,10 @@
RelativePath=".\GSTexture.cpp"
>
</File>
<File
RelativePath=".\GSTexture10.cpp"
>
</File>
<File
RelativePath=".\GSTexture11.cpp"
>
</File>
<File
RelativePath=".\GSTexture7.cpp"
>
</File>
<File
RelativePath=".\GSTexture9.cpp"
>
@ -1559,10 +1351,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSTextureCache10.cpp"
>
</File>
<File
RelativePath=".\GSTextureCache11.cpp"
>
@ -1571,74 +1359,6 @@
RelativePath=".\GSTextureCache9.cpp"
>
</File>
<File
RelativePath=".\GSTextureCacheOGL.cpp"
>
<FileConfiguration
Name="Debug SSE2|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSE2|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSSE3|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug SSSE3|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug SSE4|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSE4|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSTextureCacheSW.cpp"
>
@ -1651,18 +1371,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSTextureFX10.cpp"
>
<FileConfiguration
Name="Release SSE4|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSTextureFX11.cpp"
>
@ -1675,74 +1383,6 @@
RelativePath=".\GSTextureNull.cpp"
>
</File>
<File
RelativePath=".\GSTextureOGL.cpp"
>
<FileConfiguration
Name="Debug SSE2|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSE2|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSSE3|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug SSSE3|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug SSE4|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release SSE4|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSThread.cpp"
>
@ -1901,54 +1541,6 @@
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\GPU.h"
>
</File>
<File
RelativePath=".\GPUDrawingEnvironment.h"
>
</File>
<File
RelativePath=".\GPUDrawScanline.h"
>
</File>
<File
RelativePath=".\GPUDrawScanlineCodeGenerator.h"
>
</File>
<File
RelativePath=".\GPULocalMemory.h"
>
</File>
<File
RelativePath=".\GPURenderer.h"
>
</File>
<File
RelativePath=".\GPURendererSW.h"
>
</File>
<File
RelativePath=".\GPUScanlineEnvironment.h"
>
</File>
<File
RelativePath=".\GPUSettingsDlg.h"
>
</File>
<File
RelativePath=".\GPUSetupPrimCodeGenerator.h"
>
</File>
<File
RelativePath=".\GPUState.h"
>
</File>
<File
RelativePath=".\GPUVertex.h"
>
</File>
<File
RelativePath=".\GS.h"
>
@ -1985,18 +1577,10 @@
RelativePath=".\GSDevice.h"
>
</File>
<File
RelativePath=".\GSDevice10.h"
>
</File>
<File
RelativePath=".\GSDevice11.h"
>
</File>
<File
RelativePath=".\GSDevice7.h"
>
</File>
<File
RelativePath=".\GSDevice9.h"
>
@ -2009,10 +1593,6 @@
RelativePath=".\GSDeviceNull.h"
>
</File>
<File
RelativePath=".\GSDeviceOGL.h"
>
</File>
<File
RelativePath=".\GSDialog.h"
>
@ -2069,10 +1649,6 @@
RelativePath=".\GSRendererDX.h"
>
</File>
<File
RelativePath=".\GSRendererDX10.h"
>
</File>
<File
RelativePath=".\GSRendererDX11.h"
>
@ -2089,10 +1665,6 @@
RelativePath=".\GSRendererNull.h"
>
</File>
<File
RelativePath=".\GSRendererOGL.h"
>
</File>
<File
RelativePath=".\GSRendererSW.h"
>
@ -2126,11 +1698,7 @@
>
</File>
<File
RelativePath=".\GSTexture10.h"
>
</File>
<File
RelativePath=".\GSTexture7.h"
RelativePath=".\GSTexture11.h"
>
</File>
<File
@ -2141,10 +1709,6 @@
RelativePath=".\GSTextureCache.h"
>
</File>
<File
RelativePath=".\GSTextureCache10.h"
>
</File>
<File
RelativePath=".\GSTextureCache11.h"
>
@ -2153,10 +1717,6 @@
RelativePath=".\GSTextureCache9.h"
>
</File>
<File
RelativePath=".\GSTextureCacheOGL.h"
>
</File>
<File
RelativePath=".\GSTextureCacheSW.h"
>
@ -2169,10 +1729,6 @@
RelativePath=".\GSTextureNull.h"
>
</File>
<File
RelativePath=".\GSTextureOGL.h"
>
</File>
<File
RelativePath=".\GSThread.h"
>

View File

@ -122,8 +122,6 @@ typedef signed long long int64;
#include <ddraw.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3d10.h>
#include <d3dx10.h>
#include <d3d9.h>
#include <d3dx9.h>

View File

@ -24,6 +24,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>

View File

@ -28,7 +28,7 @@ namespace GSDumpGUI
if (hmod.ToInt64() > 0)
{
IntPtr funcaddrReplay = NativeMethods.GetProcAddress(hmod, "GSReplay");
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PSEgetLibName");
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
NativeMethods.FreeLibrary(hmod);
@ -64,7 +64,7 @@ namespace GSDumpGUI
if (hmod.ToInt64() > 0)
{
IntPtr funcaddrReplay = NativeMethods.GetProcAddress(hmod, "GSReplay");
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PSEgetLibName");
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
gsReplay = (GSReplay)Marshal.GetDelegateForFunctionPointer(funcaddrReplay, typeof(GSReplay));