mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
c09114e08b
commit
8c0fc49f61
|
@ -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
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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
|
@ -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);
|
|
||||||
};
|
|
|
@ -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)
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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();
|
|
||||||
};
|
|
|
@ -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;
|
|
||||||
};
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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[];
|
|
||||||
};
|
|
|
@ -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),
|
|
||||||
};
|
|
|
@ -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);
|
|
||||||
};
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
};
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -22,9 +22,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "GSUtil.h"
|
#include "GSUtil.h"
|
||||||
#include "GSRendererDX9.h"
|
#include "GSRendererDX9.h"
|
||||||
#include "GSRendererDX10.h"
|
|
||||||
#include "GSRendererDX11.h"
|
#include "GSRendererDX11.h"
|
||||||
#include "GSRendererOGL.h"
|
|
||||||
#include "GSRendererSW.h"
|
#include "GSRendererSW.h"
|
||||||
#include "GSRendererNull.h"
|
#include "GSRendererNull.h"
|
||||||
#include "GSSettingsDlg.h"
|
#include "GSSettingsDlg.h"
|
||||||
|
@ -172,11 +170,7 @@ static INT32 _GSopen(void* dsp, char* title, int renderer)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case 0: case 1: case 2: dev = new GSDevice9(); break;
|
case 0: case 1: case 2: dev = new GSDevice9(); break;
|
||||||
case 3: case 4: case 5: dev = new GSDevice10(); break;
|
case 3: case 4: case 5: dev = new GSDevice11(); 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 12: case 13: new GSDeviceNull(); break;
|
case 12: case 13: new GSDeviceNull(); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,11 +182,7 @@ static INT32 _GSopen(void* dsp, char* title, int renderer)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case 0: s_gs = new GSRendererDX9(); break;
|
case 0: s_gs = new GSRendererDX9(); break;
|
||||||
case 3: s_gs = new GSRendererDX10(); break;
|
case 3: s_gs = new GSRendererDX11(); break;
|
||||||
#if 0
|
|
||||||
case 6: s_gs = new GSRendererDX11(); break;
|
|
||||||
case 9: s_gs = new GSRendererOGL(); break;
|
|
||||||
#endif
|
|
||||||
case 2: case 5: case 8: case 11: case 13:
|
case 2: case 5: case 8: case 11: case 13:
|
||||||
s_gs = new GSRendererNull(); break;
|
s_gs = new GSRendererNull(); break;
|
||||||
|
|
||||||
|
@ -256,8 +246,8 @@ EXPORT_C_(INT32) GSopen2( void* dsp, INT32 flags )
|
||||||
int renderer = theApp.GetConfig("renderer", 0);
|
int renderer = theApp.GetConfig("renderer", 0);
|
||||||
if( flags & 4 )
|
if( flags & 4 )
|
||||||
{
|
{
|
||||||
static bool isdx10avail = GSUtil::IsDirect3D10Available();
|
static bool isdx11avail = GSUtil::IsDirect3D11Available();
|
||||||
if (isdx10avail) renderer = 4; //dx10 sw
|
if (isdx11avail) renderer = 4; //dx11 sw
|
||||||
else renderer = 1; //dx9 sw
|
else renderer = 1; //dx9 sw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,8 +267,8 @@ EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt)
|
||||||
if(mt == 2)
|
if(mt == 2)
|
||||||
{
|
{
|
||||||
// pcsx2 sent a switch renderer request
|
// pcsx2 sent a switch renderer request
|
||||||
static bool isdx10avail = GSUtil::IsDirect3D10Available();
|
static bool isdx11avail = GSUtil::IsDirect3D11Available();
|
||||||
if (isdx10avail) renderer = 4; //dx10 sw
|
if (isdx11avail) renderer = 4; //dx11 sw
|
||||||
else renderer = 1; //dx9 sw
|
else renderer = 1; //dx9 sw
|
||||||
mt = 1;
|
mt = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
};
|
|
|
@ -67,8 +67,17 @@ bool GSDevice11::Create(GSWnd* wnd)
|
||||||
scd.SampleDesc.Count = 1;
|
scd.SampleDesc.Count = 1;
|
||||||
scd.SampleDesc.Quality = 0;
|
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;
|
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;
|
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -255,7 +264,8 @@ bool GSDevice11::Create(GSWnd* wnd)
|
||||||
|
|
||||||
m_dev->CreateBlendState(&blend, &m_date.bs);
|
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())
|
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)
|
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)
|
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.start = 0;
|
||||||
m_vertices.count = 0;
|
m_vertices.count = 0;
|
||||||
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
m_vertices.limit = std::max<int>(count * 3 / 2, 11000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_vb == NULL)
|
if(m_vb == NULL)
|
||||||
|
@ -952,7 +962,7 @@ HRESULT GSDevice11::CompileShader(uint32 id, const string& entry, D3D11_SHADER_M
|
||||||
|
|
||||||
PrepareShaderMacro(m, macro);
|
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);
|
hr = D3DX11CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.ps.c_str(), 0, 0, NULL, &shader, &error, NULL);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
};
|
|
|
@ -674,12 +674,12 @@ void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, c
|
||||||
}
|
}
|
||||||
|
|
||||||
IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices));
|
IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices));
|
||||||
IASetInputLayout(m_convert.il);
|
|
||||||
IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
|
IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
|
||||||
|
|
||||||
// vs
|
// vs
|
||||||
|
|
||||||
VSSetShader(m_convert.vs, NULL, 0);
|
VSSetShader(m_convert.vs, NULL, 0);
|
||||||
|
IASetInputLayout(m_convert.il);
|
||||||
|
|
||||||
// ps
|
// ps
|
||||||
|
|
||||||
|
@ -751,12 +751,12 @@ void GSDevice9::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1 (&iaVe
|
||||||
// ia
|
// ia
|
||||||
|
|
||||||
IASetVertexBuffer(iaVertices, sizeof(iaVertices[0]), countof(iaVertices));
|
IASetVertexBuffer(iaVertices, sizeof(iaVertices[0]), countof(iaVertices));
|
||||||
IASetInputLayout(m_convert.il);
|
|
||||||
IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
|
IASetPrimitiveTopology(D3DPT_TRIANGLESTRIP);
|
||||||
|
|
||||||
// vs
|
// vs
|
||||||
|
|
||||||
VSSetShader(m_convert.vs, NULL, 0);
|
VSSetShader(m_convert.vs, NULL, 0);
|
||||||
|
IASetInputLayout(m_convert.il);
|
||||||
|
|
||||||
// ps
|
// ps
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
};
|
|
|
@ -46,10 +46,68 @@ void GSRendererDX11::VertexKick(bool skip)
|
||||||
dst.vi[0] = m_v.vi[0];
|
dst.vi[0] = m_v.vi[0];
|
||||||
dst.vi[1] = m_v.vi[1];
|
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)
|
if(tme && fst)
|
||||||
{
|
{
|
||||||
GSVector4::storel(&dst.ST, m_v.GetUV());
|
GSVector4::storel(&dst.ST, m_v.GetUV());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
};
|
|
|
@ -30,17 +30,9 @@ GSSetting GSSettingsDlg::g_renderers[] =
|
||||||
{0, "Direct3D9 (Hardware)", NULL},
|
{0, "Direct3D9 (Hardware)", NULL},
|
||||||
{1, "Direct3D9 (Software)", NULL},
|
{1, "Direct3D9 (Software)", NULL},
|
||||||
{2, "Direct3D9 (Null)", NULL},
|
{2, "Direct3D9 (Null)", NULL},
|
||||||
{3, "Direct3D10 (Hardware)", NULL},
|
{3, "Direct3D11 (Hardware)", NULL},
|
||||||
{4, "Direct3D10 (Software)", NULL},
|
{4, "Direct3D11 (Software)", NULL},
|
||||||
{5, "Direct3D10 (Null)", NULL},
|
{5, "Direct3D11 (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
|
|
||||||
{12, "Null (Software)", NULL},
|
{12, "Null (Software)", NULL},
|
||||||
{13, "Null (Null)", NULL},
|
{13, "Null (Null)", NULL},
|
||||||
};
|
};
|
||||||
|
@ -115,15 +107,13 @@ void GSSettingsDlg::OnInit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isdx10avail = GSUtil::IsDirect3D10Available();
|
bool isdx11avail = GSUtil::IsDirect3D11Available();
|
||||||
bool isdx11avail = false; //GSUtil::IsDirect3D11Available();
|
|
||||||
|
|
||||||
vector<GSSetting> renderers;
|
vector<GSSetting> renderers;
|
||||||
|
|
||||||
for(size_t i = 0; i < countof(g_renderers); i++)
|
for(size_t i = 0; i < countof(g_renderers); i++)
|
||||||
{
|
{
|
||||||
if(i >= 3 && i <= 5 && !isdx10avail) continue;
|
if(i >= 3 && i <= 5 && !isdx11avail) continue;
|
||||||
if(i >= 6 && i <= 8 && !isdx11avail) continue;
|
|
||||||
|
|
||||||
renderers.push_back(g_renderers[i]);
|
renderers.push_back(g_renderers[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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*();
|
|
||||||
};
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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*();
|
|
||||||
};
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
};
|
|
|
@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
};
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;}
|
|
||||||
};
|
|
|
@ -189,18 +189,6 @@ bool GSUtil::CheckSSE()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSUtil::IsDirect3D10Available()
|
|
||||||
{
|
|
||||||
if(HMODULE hModule = LoadLibrary(_T("d3d10_1.dll")))
|
|
||||||
{
|
|
||||||
FreeLibrary(hModule);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GSUtil::IsDirect3D11Available()
|
bool GSUtil::IsDirect3D11Available()
|
||||||
{
|
{
|
||||||
if(HMODULE hModule = LoadLibrary(_T("d3d11.dll")))
|
if(HMODULE hModule = LoadLibrary(_T("d3d11.dll")))
|
||||||
|
|
|
@ -36,7 +36,6 @@ public:
|
||||||
static bool CheckDirectX();
|
static bool CheckDirectX();
|
||||||
static bool CheckSSE();
|
static bool CheckSSE();
|
||||||
|
|
||||||
static bool IsDirect3D10Available();
|
|
||||||
static bool IsDirect3D11Available();
|
static bool IsDirect3D11Available();
|
||||||
|
|
||||||
static char* GetLibName();
|
static char* GetLibName();
|
||||||
|
|
|
@ -56,7 +56,7 @@ __aligned16 union GSVertexHW9
|
||||||
float GetQ() {return p.w;}
|
float GetQ() {return p.w;}
|
||||||
};
|
};
|
||||||
|
|
||||||
__aligned16 union GSVertexHW10
|
__aligned16 union GSVertexHW11
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -88,13 +88,9 @@ __aligned16 union GSVertexHW10
|
||||||
struct {GSVector4i vi[2];};
|
struct {GSVector4i vi[2];};
|
||||||
struct {GSVector4 vf[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;}
|
float GetQ() {return q;}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GSVertexHW10 GSVertexHW11; // TODO
|
|
||||||
|
|
||||||
typedef GSVertexHW9 GSVertexOGL; // TODO
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
|
@ -86,9 +86,9 @@ void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primcl
|
||||||
m_alpha.valid = false;
|
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;
|
const GSDrawingContext* context = m_state->m_context;
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ L("loop");
|
||||||
ret();
|
ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
GSVertexTrace::CGHW10::CGHW10(uint32 key, void* ptr, size_t maxsize)
|
GSVertexTrace::CGHW11::CGHW11(uint32 key, void* ptr, size_t maxsize)
|
||||||
: CodeGenerator(maxsize, ptr)
|
: CodeGenerator(maxsize, ptr)
|
||||||
{
|
{
|
||||||
#if _M_AMD64
|
#if _M_AMD64
|
||||||
|
@ -564,7 +564,7 @@ L("loop");
|
||||||
{
|
{
|
||||||
if(color && (iip || j == n - 1) || tme)
|
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))
|
if(color && (iip || j == n - 1))
|
||||||
|
@ -593,7 +593,7 @@ L("loop");
|
||||||
maxps(xmm7, xmm0);
|
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))
|
if(m_cpu.has(util::Cpu::tSSE41))
|
||||||
{
|
{
|
||||||
|
@ -614,7 +614,7 @@ L("loop");
|
||||||
maxps(xmm5, xmm1);
|
maxps(xmm5, xmm1);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(edx, n * sizeof(GSVertexHW10));
|
add(edx, n * sizeof(GSVertexHW11));
|
||||||
sub(ecx, n);
|
sub(ecx, n);
|
||||||
|
|
||||||
jg("loop");
|
jg("loop");
|
||||||
|
|
|
@ -66,24 +66,24 @@ __aligned16 class GSVertexTrace
|
||||||
CGHW9* Create(uint32 key, void* ptr, size_t maxsize) {return new CGHW9(key, ptr, maxsize);}
|
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;
|
Xbyak::util::Cpu m_cpu;
|
||||||
|
|
||||||
public:
|
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:
|
public:
|
||||||
GSVertexTraceMapHW10() : GSCodeGeneratorFunctionMap("VertexTraceHW10") {}
|
GSVertexTraceMapHW11() : GSCodeGeneratorFunctionMap("VertexTraceHW11") {}
|
||||||
CGHW10* Create(uint32 key, void* ptr, size_t maxsize) {return new CGHW10(key, ptr, maxsize);}
|
CGHW11* Create(uint32 key, void* ptr, size_t maxsize) {return new CGHW11(key, ptr, maxsize);}
|
||||||
};
|
};
|
||||||
|
|
||||||
GSVertexTraceMapSW m_map_sw;
|
GSVertexTraceMapSW m_map_sw;
|
||||||
GSVertexTraceMapHW9 m_map_hw9;
|
GSVertexTraceMapHW9 m_map_hw9;
|
||||||
GSVertexTraceMapHW10 m_map_hw10;
|
GSVertexTraceMapHW11 m_map_hw11;
|
||||||
|
|
||||||
uint32 Hash(GS_PRIM_CLASS primclass);
|
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 GSVertexSW* v, int count, GS_PRIM_CLASS primclass);
|
||||||
void Update(const GSVertexHW9* 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) {}
|
void Update(const GSVertexNull* v, int count, GS_PRIM_CLASS primclass) {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -41,30 +41,3 @@ EXPORTS
|
||||||
GSgetLastTag
|
GSgetLastTag
|
||||||
GSReplay
|
GSReplay
|
||||||
GSBenchmark
|
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
|
|
||||||
|
|
|
@ -1039,42 +1039,6 @@
|
||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
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
|
<File
|
||||||
RelativePath=".\GS.cpp"
|
RelativePath=".\GS.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1135,18 +1099,10 @@
|
||||||
RelativePath=".\GSDevice.cpp"
|
RelativePath=".\GSDevice.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSDevice10.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSDevice11.cpp"
|
RelativePath=".\GSDevice11.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSDevice7.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSDevice9.cpp"
|
RelativePath=".\GSDevice9.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1155,74 +1111,6 @@
|
||||||
RelativePath=".\GSDeviceNull.cpp"
|
RelativePath=".\GSDeviceNull.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</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
|
<File
|
||||||
RelativePath=".\GSDialog.cpp"
|
RelativePath=".\GSDialog.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1351,26 +1239,6 @@
|
||||||
RelativePath=".\GSRendererDX.cpp"
|
RelativePath=".\GSRendererDX.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</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
|
<File
|
||||||
RelativePath=".\GSRendererDX11.cpp"
|
RelativePath=".\GSRendererDX11.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1403,74 +1271,6 @@
|
||||||
RelativePath=".\GSRendererNull.cpp"
|
RelativePath=".\GSRendererNull.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</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
|
<File
|
||||||
RelativePath=".\GSRendererSW.cpp"
|
RelativePath=".\GSRendererSW.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1531,18 +1331,10 @@
|
||||||
RelativePath=".\GSTexture.cpp"
|
RelativePath=".\GSTexture.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSTexture10.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSTexture11.cpp"
|
RelativePath=".\GSTexture11.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSTexture7.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSTexture9.cpp"
|
RelativePath=".\GSTexture9.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1559,10 +1351,6 @@
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSTextureCache10.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSTextureCache11.cpp"
|
RelativePath=".\GSTextureCache11.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1571,74 +1359,6 @@
|
||||||
RelativePath=".\GSTextureCache9.cpp"
|
RelativePath=".\GSTextureCache9.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</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
|
<File
|
||||||
RelativePath=".\GSTextureCacheSW.cpp"
|
RelativePath=".\GSTextureCacheSW.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1651,18 +1371,6 @@
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSTextureFX10.cpp"
|
|
||||||
>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Release SSE4|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="4"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSTextureFX11.cpp"
|
RelativePath=".\GSTextureFX11.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1675,74 +1383,6 @@
|
||||||
RelativePath=".\GSTextureNull.cpp"
|
RelativePath=".\GSTextureNull.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</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
|
<File
|
||||||
RelativePath=".\GSThread.cpp"
|
RelativePath=".\GSThread.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1901,54 +1541,6 @@
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
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
|
<File
|
||||||
RelativePath=".\GS.h"
|
RelativePath=".\GS.h"
|
||||||
>
|
>
|
||||||
|
@ -1985,18 +1577,10 @@
|
||||||
RelativePath=".\GSDevice.h"
|
RelativePath=".\GSDevice.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSDevice10.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSDevice11.h"
|
RelativePath=".\GSDevice11.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSDevice7.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSDevice9.h"
|
RelativePath=".\GSDevice9.h"
|
||||||
>
|
>
|
||||||
|
@ -2009,10 +1593,6 @@
|
||||||
RelativePath=".\GSDeviceNull.h"
|
RelativePath=".\GSDeviceNull.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSDeviceOGL.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSDialog.h"
|
RelativePath=".\GSDialog.h"
|
||||||
>
|
>
|
||||||
|
@ -2069,10 +1649,6 @@
|
||||||
RelativePath=".\GSRendererDX.h"
|
RelativePath=".\GSRendererDX.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSRendererDX10.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSRendererDX11.h"
|
RelativePath=".\GSRendererDX11.h"
|
||||||
>
|
>
|
||||||
|
@ -2089,10 +1665,6 @@
|
||||||
RelativePath=".\GSRendererNull.h"
|
RelativePath=".\GSRendererNull.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSRendererOGL.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSRendererSW.h"
|
RelativePath=".\GSRendererSW.h"
|
||||||
>
|
>
|
||||||
|
@ -2126,11 +1698,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSTexture10.h"
|
RelativePath=".\GSTexture11.h"
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\GSTexture7.h"
|
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
@ -2141,10 +1709,6 @@
|
||||||
RelativePath=".\GSTextureCache.h"
|
RelativePath=".\GSTextureCache.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSTextureCache10.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSTextureCache11.h"
|
RelativePath=".\GSTextureCache11.h"
|
||||||
>
|
>
|
||||||
|
@ -2153,10 +1717,6 @@
|
||||||
RelativePath=".\GSTextureCache9.h"
|
RelativePath=".\GSTextureCache9.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSTextureCacheOGL.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSTextureCacheSW.h"
|
RelativePath=".\GSTextureCacheSW.h"
|
||||||
>
|
>
|
||||||
|
@ -2169,10 +1729,6 @@
|
||||||
RelativePath=".\GSTextureNull.h"
|
RelativePath=".\GSTextureNull.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\GSTextureOGL.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\GSThread.h"
|
RelativePath=".\GSThread.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -122,8 +122,6 @@ typedef signed long long int64;
|
||||||
#include <ddraw.h>
|
#include <ddraw.h>
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <d3dx11.h>
|
#include <d3dx11.h>
|
||||||
#include <d3d10.h>
|
|
||||||
#include <d3dx10.h>
|
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
#include <d3dx9.h>
|
#include <d3dx9.h>
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace GSDumpGUI
|
||||||
if (hmod.ToInt64() > 0)
|
if (hmod.ToInt64() > 0)
|
||||||
{
|
{
|
||||||
IntPtr funcaddrReplay = NativeMethods.GetProcAddress(hmod, "GSReplay");
|
IntPtr funcaddrReplay = NativeMethods.GetProcAddress(hmod, "GSReplay");
|
||||||
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PSEgetLibName");
|
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
|
||||||
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
|
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
|
||||||
|
|
||||||
NativeMethods.FreeLibrary(hmod);
|
NativeMethods.FreeLibrary(hmod);
|
||||||
|
@ -64,7 +64,7 @@ namespace GSDumpGUI
|
||||||
if (hmod.ToInt64() > 0)
|
if (hmod.ToInt64() > 0)
|
||||||
{
|
{
|
||||||
IntPtr funcaddrReplay = NativeMethods.GetProcAddress(hmod, "GSReplay");
|
IntPtr funcaddrReplay = NativeMethods.GetProcAddress(hmod, "GSReplay");
|
||||||
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PSEgetLibName");
|
IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
|
||||||
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
|
IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
|
||||||
|
|
||||||
gsReplay = (GSReplay)Marshal.GetDelegateForFunctionPointer(funcaddrReplay, typeof(GSReplay));
|
gsReplay = (GSReplay)Marshal.GetDelegateForFunctionPointer(funcaddrReplay, typeof(GSReplay));
|
||||||
|
|
Loading…
Reference in New Issue