gsdx: Remove psx/ps1 emulator compatibility.

ePSXe for example.
There is little to no benefit in keeping it, especially when nobody was
maintaining the code. If we ever want to reintroduce it we can do so
from older branches like 1.6.
Plus if we want to integrate plugins into pcsx2 itself this is a required step.
PS1 games can ofc still be played within pcsx2.
This commit is contained in:
lightningterror 2019-12-01 13:46:02 +01:00
parent 2b884a7e7c
commit 0b9d68e60c
29 changed files with 1 additions and 5597 deletions

View File

@ -53,14 +53,6 @@ if(OPENCL_FOUND)
endif() endif()
set(GSdxSources set(GSdxSources
PSX/GPU.cpp
PSX/GPUDrawScanline.cpp
PSX/GPUDrawScanlineCodeGenerator.cpp
PSX/GPULocalMemory.cpp
PSX/GPURenderer.cpp
PSX/GPURendererSW.cpp
PSX/GPUSetupPrimCodeGenerator.cpp
PSX/GPUState.cpp
GS.cpp GS.cpp
GSAlignedClass.cpp GSAlignedClass.cpp
GSBlock.cpp GSBlock.cpp
@ -154,17 +146,6 @@ set(GSdxHeaders
GSVector8.h GSVector8.h
GSVector8i.h GSVector8i.h
stdafx.h stdafx.h
PSX/GPUDrawingEnvironment.h
PSX/GPUDrawScanlineCodeGenerator.h
PSX/GPUDrawScanline.h
PSX/GPU.h
PSX/GPULocalMemory.h
PSX/GPURenderer.h
PSX/GPURendererSW.h
PSX/GPUScanlineEnvironment.h
PSX/GPUSetupPrimCodeGenerator.h
PSX/GPUState.h
PSX/GPUVertex.h
Renderers/Common/GSDevice.h Renderers/Common/GSDevice.h
Renderers/Common/GSDirtyRect.h Renderers/Common/GSDirtyRect.h
Renderers/Common/GSFastList.h Renderers/Common/GSFastList.h
@ -224,7 +205,6 @@ if(Windows)
Window/GSSettingsDlg.cpp Window/GSSettingsDlg.cpp
Window/GSWndDX.cpp Window/GSWndDX.cpp
Window/GSWndWGL.cpp Window/GSWndWGL.cpp
PSX/GPUSettingsDlg.cpp
) )
LIST(APPEND GSdxHeaders LIST(APPEND GSdxHeaders
@ -234,7 +214,6 @@ if(Windows)
Renderers/DX11/GSTextureCache11.h Renderers/DX11/GSTextureCache11.h
Window/GSWndDX.h Window/GSWndDX.h
Window/GSWndWGL.h Window/GSWndWGL.h
PSX/GPUSettingsDlg.h
resource.h resource.h
targetver.h targetver.h
) )

View File

@ -22,7 +22,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "GSdx.h" #include "GSdx.h"
#include "GS.h" #include "GS.h"
#include "PSX/GPU.h"
#include <fstream> #include <fstream>
static void* s_hModule; static void* s_hModule;
@ -314,29 +313,6 @@ void GSdxApp::Init()
m_gs_tv_shaders.push_back(GSSetting(3, "Triangular filter", "")); m_gs_tv_shaders.push_back(GSSetting(3, "Triangular filter", ""));
m_gs_tv_shaders.push_back(GSSetting(4, "Wave filter", "")); m_gs_tv_shaders.push_back(GSSetting(4, "Wave filter", ""));
// PSX options that start with m_gpu.
m_gpu_renderers.push_back(GSSetting(static_cast<int8>(GPURendererType::D3D11_SW), "Direct3D 11", "Software"));
m_gpu_renderers.push_back(GSSetting(static_cast<int8>(GPURendererType::NULL_Renderer), "Null", ""));
m_gpu_filter.push_back(GSSetting(0, "Nearest", ""));
m_gpu_filter.push_back(GSSetting(1, "Bilinear (polygons only)", ""));
m_gpu_filter.push_back(GSSetting(2, "Bilinear", ""));
m_gpu_dithering.push_back(GSSetting(0, "Disabled", ""));
m_gpu_dithering.push_back(GSSetting(1, "Auto", ""));
m_gpu_aspectratio.push_back(GSSetting(0, "Stretch", ""));
m_gpu_aspectratio.push_back(GSSetting(1, "4:3", ""));
m_gpu_aspectratio.push_back(GSSetting(2, "16:9", ""));
m_gpu_scale.push_back(GSSetting(0 | (0 << 2), "H x 1 - V x 1", ""));
m_gpu_scale.push_back(GSSetting(1 | (0 << 2), "H x 2 - V x 1", ""));
m_gpu_scale.push_back(GSSetting(0 | (1 << 2), "H x 1 - V x 2", ""));
m_gpu_scale.push_back(GSSetting(1 | (1 << 2), "H x 2 - V x 2", ""));
m_gpu_scale.push_back(GSSetting(2 | (1 << 2), "H x 4 - V x 2", ""));
m_gpu_scale.push_back(GSSetting(1 | (2 << 2), "H x 2 - V x 4", ""));
m_gpu_scale.push_back(GSSetting(2 | (2 << 2), "H x 4 - V x 4", ""));
// Avoid to clutter the ini file with useless options // Avoid to clutter the ini file with useless options
#ifdef _WIN32 #ifdef _WIN32
// Per OS option. // Per OS option.
@ -344,15 +320,9 @@ void GSdxApp::Init()
m_default_configuration["CaptureFileName"] = ""; m_default_configuration["CaptureFileName"] = "";
m_default_configuration["CaptureVideoCodecDisplayName"] = ""; m_default_configuration["CaptureVideoCodecDisplayName"] = "";
m_default_configuration["dx_break_on_severity"] = "0"; m_default_configuration["dx_break_on_severity"] = "0";
m_default_configuration["windowed"] = "1";
// D3D Blending option // D3D Blending option
m_default_configuration["accurate_blending_unit_d3d11"] = "1"; m_default_configuration["accurate_blending_unit_d3d11"] = "1";
// PSX option. Not supported on linux.
m_default_configuration["dithering"] = "1";
m_default_configuration["scale_x"] = "0";
m_default_configuration["scale_y"] = "0";
m_default_configuration["windowed"] = "1";
#else #else
m_default_configuration["linux_replay"] = "1"; m_default_configuration["linux_replay"] = "1";
#endif #endif

View File

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

View File

@ -81,12 +81,6 @@ public:
std::vector<GSSetting> m_gs_acc_blend_level; std::vector<GSSetting> m_gs_acc_blend_level;
std::vector<GSSetting> m_gs_acc_blend_level_d3d11; std::vector<GSSetting> m_gs_acc_blend_level_d3d11;
std::vector<GSSetting> m_gs_tv_shaders; std::vector<GSSetting> m_gs_tv_shaders;
std::vector<GSSetting> m_gpu_renderers;
std::vector<GSSetting> m_gpu_filter;
std::vector<GSSetting> m_gpu_dithering;
std::vector<GSSetting> m_gpu_aspectratio;
std::vector<GSSetting> m_gpu_scale;
}; };
struct GSDXError {}; struct GSDXError {};

View File

@ -253,33 +253,6 @@ BEGIN
COMBOBOX IDC_COLORSPACE,102,47,48,32,CBS_DROPDOWNLIST | WS_TABSTOP COMBOBOX IDC_COLORSPACE,102,47,48,32,CBS_DROPDOWNLIST | WS_TABSTOP
END END
IDD_GPUCONFIG DIALOGEX 0, 0, 242, 189
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Settings..."
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL IDB_LOGO11,IDC_LOGO11,"Static",SS_BITMAP | SS_REALSIZECONTROL,6,6,230,44
CONTROL IDB_NULL,IDC_NULL,"Static",SS_BITMAP | SS_REALSIZECONTROL,6,6,230,44
LTEXT "Renderer:",IDC_STATIC,7,59,34,8
COMBOBOX IDC_RENDERER,108,57,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Resolution:",IDC_RESOLUTION_TEXT,7,74,37,8
COMBOBOX IDC_RESOLUTION,108,72,127,125,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Texture Filter (Del):",IDC_FILTER_TEXT,7,90,64,8
COMBOBOX IDC_FILTER,108,87,127,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Dithering (End):",IDC_DITHERING_TEXT,7,105,52,8
COMBOBOX IDC_DITHERING,108,102,127,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Aspect Ratio (PgDn):",IDC_ASPECTRATIO_TEXT,7,120,68,8
COMBOBOX IDC_ASPECTRATIO,108,117,127,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Internal Resolution:",IDC_SCALE_TEXT,7,135,64,8
COMBOBOX IDC_SCALE,108,132,127,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Windowed",IDC_WINDOWED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,149,49,10
LTEXT "Extra Rend. Threads:",IDC_SWTHREADS_TEXT,108,150,70,8
EDITTEXT IDC_SWTHREADS_EDIT,200,147,35,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
DEFPUSHBUTTON "OK",IDOK,68,168,50,14
PUSHBUTTON "Cancel",IDCANCEL,124,168,50,14
END
IDD_CONFIG DIALOGEX 0, 0, 242, 371 IDD_CONFIG DIALOGEX 0, 0, 242, 371
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "GSdx Settings" CAPTION "GSdx Settings"
@ -380,16 +353,6 @@ BEGIN
HORZGUIDE, 54 HORZGUIDE, 54
END END
IDD_GPUCONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 182
VERTGUIDE, 80
VERTGUIDE, 182
TOPMARGIN, 7
BOTTOMMARGIN, 192
END
IDD_CONFIG, DIALOG IDD_CONFIG, DIALOG
BEGIN BEGIN
LEFTMARGIN, 6 LEFTMARGIN, 6

View File

@ -162,15 +162,6 @@
<ClCompile Include="Window\GSWnd.cpp" /> <ClCompile Include="Window\GSWnd.cpp" />
<ClCompile Include="Window\GSWndDX.cpp" /> <ClCompile Include="Window\GSWndDX.cpp" />
<ClCompile Include="Window\GSWndWGL.cpp" /> <ClCompile Include="Window\GSWndWGL.cpp" />
<ClCompile Include="PSX\GPU.cpp" />
<ClCompile Include="PSX\GPUDrawScanline.cpp" />
<ClCompile Include="PSX\GPUDrawScanlineCodeGenerator.cpp" />
<ClCompile Include="PSX\GPULocalMemory.cpp" />
<ClCompile Include="PSX\GPURenderer.cpp" />
<ClCompile Include="PSX\GPURendererSW.cpp" />
<ClCompile Include="PSX\GPUSettingsDlg.cpp" />
<ClCompile Include="PSX\GPUSetupPrimCodeGenerator.cpp" />
<ClCompile Include="PSX\GPUState.cpp" />
<ClCompile Include="stdafx.cpp"> <ClCompile Include="stdafx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader> <PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile> </ClCompile>
@ -248,18 +239,6 @@
<ClInclude Include="Window\GSWnd.h" /> <ClInclude Include="Window\GSWnd.h" />
<ClInclude Include="Window\GSWndDX.h" /> <ClInclude Include="Window\GSWndDX.h" />
<ClInclude Include="Window\GSWndWGL.h" /> <ClInclude Include="Window\GSWndWGL.h" />
<ClInclude Include="PSX\GPU.h" />
<ClInclude Include="PSX\GPUDrawingEnvironment.h" />
<ClInclude Include="PSX\GPUDrawScanline.h" />
<ClInclude Include="PSX\GPUDrawScanlineCodeGenerator.h" />
<ClInclude Include="PSX\GPULocalMemory.h" />
<ClInclude Include="PSX\GPURenderer.h" />
<ClInclude Include="PSX\GPURendererSW.h" />
<ClInclude Include="PSX\GPUScanlineEnvironment.h" />
<ClInclude Include="PSX\GPUSettingsDlg.h" />
<ClInclude Include="PSX\GPUSetupPrimCodeGenerator.h" />
<ClInclude Include="PSX\GPUState.h" />
<ClInclude Include="PSX\GPUVertex.h" />
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
<ClInclude Include="svnrev.h" /> <ClInclude Include="svnrev.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />

View File

@ -234,33 +234,6 @@
<ClCompile Include="GSPng.cpp"> <ClCompile Include="GSPng.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="PSX\GPU.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PSX\GPUDrawScanline.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PSX\GPUDrawScanlineCodeGenerator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PSX\GPULocalMemory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PSX\GPURenderer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PSX\GPURendererSW.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PSX\GPUSettingsDlg.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PSX\GPUSetupPrimCodeGenerator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PSX\GPUState.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GSLzma.cpp"> <ClCompile Include="GSLzma.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@ -497,42 +470,6 @@
<ClInclude Include="GSPng.h"> <ClInclude Include="GSPng.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="PSX\GPU.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPUDrawingEnvironment.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPUDrawScanline.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPUDrawScanlineCodeGenerator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPULocalMemory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPURenderer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPURendererSW.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPUScanlineEnvironment.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPUSettingsDlg.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPUSetupPrimCodeGenerator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPUState.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PSX\GPUVertex.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GSThread_CXX11.h"> <ClInclude Include="GSThread_CXX11.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@ -1,352 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSdx.h"
#include "GSUtil.h"
#include "Renderers/Null/GSDeviceNull.h"
#include "GPURendererSW.h"
#ifdef _WIN32
#include "GPUSettingsDlg.h"
#include "Renderers/DX11/GSDevice11.h"
static HRESULT s_hr = E_FAIL;
#endif
#define PSE_LT_GPU 2
static GPURenderer* s_gpu = NULL;
EXPORT_C_(uint32) PSEgetLibType()
{
return PSE_LT_GPU;
}
EXPORT_C_(const 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;
}
static void InitVectors()
{
GSVector4i::InitVectors();
GSVector4::InitVectors();
#if _M_SSE >= 0x500
GSVector8::InitVectors();
#endif
#if _M_SSE >= 0x501
GSVector8i::InitVectors();
#endif
GPUDrawScanlineCodeGenerator::InitVectors();
GPULocalMemory::InitVectors();
GPUSetupPrimCodeGenerator::InitVectors();
}
EXPORT_C_(int32) GPUinit()
{
if(!GSUtil::CheckSSE())
{
return -1;
}
theApp.Init();
InitVectors();
return 0;
}
EXPORT_C_(int32) GPUshutdown()
{
return 0;
}
EXPORT_C_(int32) GPUclose()
{
delete s_gpu;
s_gpu = NULL;
#ifdef _WIN32
GSDevice11::FreeD3DCompiler();
if(SUCCEEDED(s_hr))
{
::CoUninitialize();
s_hr = E_FAIL;
}
#endif
return 0;
}
EXPORT_C_(int32) GPUopen(void* hWnd)
{
GPUclose();
if(!GSUtil::CheckSSE())
{
return -1;
}
#ifdef _WIN32
s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(!GSUtil::CheckDirectX())
{
return -1;
}
if (!GSDevice11::LoadD3DCompiler())
return -1;
#endif
GPURendererType renderer = static_cast<GPURendererType>(theApp.GetConfigI("Renderer"));
int threads = theApp.GetConfigI("extrathreads");
switch(renderer)
{
#ifdef _WIN32
case GPURendererType::D3D11_SW: s_gpu = new GPURendererSW(new GSDevice11(), threads); break;
#endif
case GPURendererType::NULL_Renderer: s_gpu = new GPURendererSW(new GSDeviceNull(), threads); break;
default: // Fall back to D3D11/Null mode if unknown value is read. No one could possibly enter here anyway.
#ifdef _WIN32
s_gpu = new GPURendererSW(new GSDevice11(), threads); break;
#else
s_gpu = new GPURendererSW(new GSDeviceNull(), threads); break;
#endif
}
if(!s_gpu->Create(hWnd))
{
GPUclose();
return -1;
}
return 0;
}
EXPORT_C_(int32) GPUconfigure()
{
if(!GSUtil::CheckSSE())
{
return -1;
}
theApp.Init();
#ifdef _WIN32
GPUSettingsDlg dlg;
if(IDOK == dlg.DoModal())
{
GPUshutdown();
GPUinit();
}
#else
// TODO: linux
#endif
return 0;
}
EXPORT_C_(int32) GPUtest()
{
if(!GSUtil::CheckSSE())
{
return -1;
}
return 0;
}
EXPORT_C GPUabout()
{
// TODO
}
EXPORT_C GPUwriteDataMem(const uint8* mem, uint32 size)
{
s_gpu->WriteData(mem, size);
}
EXPORT_C GPUwriteData(uint32 data)
{
s_gpu->WriteData((uint8*)&data, 1);
}
EXPORT_C GPUreadDataMem(uint8* mem, uint32 size)
{
s_gpu->ReadData(mem, size);
}
EXPORT_C_(uint32) GPUreadData()
{
uint32 data = 0;
s_gpu->ReadData((uint8*)&data, 1);
return data;
}
EXPORT_C GPUwriteStatus(uint32 status)
{
s_gpu->WriteStatus(status);
}
EXPORT_C_(uint32) GPUreadStatus()
{
return s_gpu->ReadStatus();
}
EXPORT_C_(uint32) GPUdmaChain(const uint8* mem, uint32 addr)
{
uint32 last[3];
memset(last, 0xff, sizeof(last));
do
{
if(addr == last[1] || addr == last[2])
{
break;
}
(addr < last[0] ? last[1] : last[2]) = addr;
last[0] = addr;
uint8 size = mem[addr + 3];
if(size > 0)
{
s_gpu->WriteData(&mem[addr + 4], size);
}
addr = *(uint32*)&mem[addr] & 0xffffff;
}
while(addr != 0xffffff);
return 0;
}
EXPORT_C_(uint32) GPUgetMode()
{
// TODO
return 0;
}
EXPORT_C GPUsetMode(uint32 mode)
{
// TODO
}
EXPORT_C GPUupdateLace()
{
s_gpu->VSync();
}
EXPORT_C GPUmakeSnapshot()
{
s_gpu->MakeSnapshot("c:/"); // TODO
}
EXPORT_C GPUdisplayText(char* text)
{
// TODO
}
EXPORT_C GPUdisplayFlags(uint32 flags)
{
// TODO
}
EXPORT_C_(int32) GPUfreeze(uint32 type, GPUFreezeData* data)
{
if(!data || data->version != 1)
{
return 0;
}
if(type == 0)
{
s_gpu->Defrost(data);
return 1;
}
else if(type == 1)
{
s_gpu->Freeze(data);
return 1;
}
else if(type == 2)
{
int slot = *(int*)data + 1;
if(slot < 1 || slot > 9)
{
return 0;
}
// TODO
return 1;
}
return 0;
}
EXPORT_C GPUgetScreenPic(uint8* mem)
{
// TODO
}
EXPORT_C GPUshowScreenPic(uint8* mem)
{
// TODO
}
EXPORT_C GPUcursor(int player, int x, int y)
{
// TODO
}

View File

@ -1,282 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 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
enum class GPURendererType : int8
{
D3D11_SW = 1,
NULL_Renderer = 2,
};
struct GPUFreezeData
{
uint32 version; // == 1
uint32 status;
uint32 control[256];
uint16 vram[1024 * 1024];
};
#pragma pack(pop)

View File

@ -1,491 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GPUDrawScanline.h"
GPUDrawScanline::GPUDrawScanline()
: m_sp_map("GPUSetupPrim", &m_local)
, m_ds_map("GPUDrawScanline", &m_local)
{
memset(&m_local, 0, sizeof(m_local));
m_local.gd = &m_global;
}
void GPUDrawScanline::BeginDraw(const GSRasterizerData* data)
{
memcpy(&m_global, &((const SharedData*)data)->global, sizeof(m_global));
if(m_global.sel.tme && m_global.sel.twin)
{
uint32 u, v;
u = ~(m_global.twin.x << 3) & 0xff; // TWW
v = ~(m_global.twin.y << 3) & 0xff; // TWH
m_local.twin[0].u = GSVector4i((u << 16) | u);
m_local.twin[0].v = GSVector4i((v << 16) | v);
u = m_global.twin.z << 3; // TWX
v = m_global.twin.w << 3; // TWY
m_local.twin[1].u = GSVector4i((u << 16) | u) & ~m_local.twin[0].u;
m_local.twin[1].v = GSVector4i((v << 16) | v) & ~m_local.twin[0].v;
}
m_ds = m_ds_map[m_global.sel];
m_de = NULL;
m_dr = NULL; // TODO
// doesn't need all bits => less functions generated
GPUScanlineSelector sel;
sel.key = 0;
sel.iip = m_global.sel.iip;
sel.tfx = m_global.sel.tfx;
sel.twin = m_global.sel.twin;
sel.sprite = m_global.sel.sprite;
m_sp = m_sp_map[sel];
}
void GPUDrawScanline::EndDraw(uint64 frame, uint64 ticks, int actual, int total)
{
m_ds_map.UpdateStats(frame, ticks, actual, total);
}
#ifndef ENABLE_JIT_RASTERIZER
void GPUDrawScanline::SetupPrim(const GSVertexSW* vertex, const uint32* index, const GSVertexSW& dscan)
{
GPUScanlineSelector sel = m_global.sel;
const GSVector4* shift = GPUSetupPrimCodeGenerator::m_shift;
if(sel.tme && !sel.twin)
{
if(sel.sprite)
{
GSVector4i t = (GSVector4i(vertex[index[1]].t) >> 8) - GSVector4i::x00000001();
t = t.ps32(t);
t = t.upl16(t);
m_local.twin[2].u = t.xxxx();
m_local.twin[2].v = t.yyyy();
}
else
{
// TODO: not really needed
m_local.twin[2].u = GSVector4i::x00ff();
m_local.twin[2].v = GSVector4i::x00ff();
}
}
if(sel.tme || sel.iip && sel.tfx != 3)
{
GSVector4 dt = dscan.t;
GSVector4 dc = dscan.c;
GSVector4i dtc8 = GSVector4i(dt * shift[0]).ps32(GSVector4i(dc * shift[0]));
if(sel.tme)
{
m_local.d8.st = dtc8.upl16(dtc8);
}
if(sel.iip && sel.tfx != 3)
{
m_local.d8.c = dtc8.uph16(dtc8);
}
if(sel.tme)
{
GSVector4 dtx = dt.xxxx();
GSVector4 dty = dt.yyyy();
m_local.d.s = GSVector4i(dtx * shift[1]).ps32(GSVector4i(dtx * shift[2]));
m_local.d.t = GSVector4i(dty * shift[1]).ps32(GSVector4i(dty * shift[2]));
}
if(sel.iip && sel.tfx != 3)
{
GSVector4 dcx = dc.xxxx();
GSVector4 dcy = dc.yyyy();
GSVector4 dcz = dc.zzzz();
m_local.d.r = GSVector4i(dcx * shift[1]).ps32(GSVector4i(dcx * shift[2]));
m_local.d.g = GSVector4i(dcy * shift[1]).ps32(GSVector4i(dcy * shift[2]));
m_local.d.b = GSVector4i(dcz * shift[1]).ps32(GSVector4i(dcz * shift[2]));
}
}
}
void GPUDrawScanline::DrawScanline(int pixels, int left, int top, const GSVertexSW& scan)
{
// TODO: not tested yet, probably bogus
GPUScanlineSelector sel = m_global.sel;
GSVector4i s, t;
GSVector4i uf, vf;
GSVector4i rf, gf, bf;
GSVector4i dither;
// Init
uint16* fb = (uint16*)m_global.vm + (top << (10 + sel.scalex)) + left;
int steps = pixels - 8;
if(sel.dtd)
{
dither = GSVector4i::load<false>(&GPUDrawScanlineCodeGenerator::m_dither[top & 3][left & 3]);
}
if(sel.tme)
{
GSVector4i vt = GSVector4i(scan.t).xxzzl();
s = vt.xxxx().add16(m_local.d.s);
t = vt.yyyy();
if(!sel.sprite)
{
t = t.add16(m_local.d.t);
}
else
{
if(sel.ltf)
{
vf = t.sll16(1).srl16(1);
}
}
}
if(sel.tfx != 3)
{
GSVector4i vc = GSVector4i(scan.c).xxzzlh();
rf = vc.xxxx();
gf = vc.yyyy();
bf = vc.zzzz();
if(sel.iip)
{
rf = rf.add16(m_local.d.r);
gf = gf.add16(m_local.d.g);
bf = bf.add16(m_local.d.b);
}
}
while(1)
{
do
{
GSVector4i test = GPUDrawScanlineCodeGenerator::m_test[7 + (steps & (steps >> 31))];
GSVector4i fd = GSVector4i::load(fb, fb + 8);
GSVector4i r, g, b, a;
// TestMask
if(sel.me)
{
test |= fd.sra16(15);
if(test.alltrue()) continue;
}
// SampleTexture
if(sel.tme)
{
GSVector4i u0, v0, u1, v1;
GSVector4i addr00, addr01, addr10, addr11;
GSVector4i c00, c01, c10, c11;
if(sel.ltf)
{
u0 = s.sub16(GSVector4i(0x00200020)); // - 0.125f
v0 = t.sub16(GSVector4i(0x00200020)); // - 0.125f
uf = u0.sll16(8).srl16(1);
vf = v0.sll16(8).srl16(1);;
}
else
{
u0 = s;
v0 = t;
}
u0 = u0.srl16(8);
v0 = v0.srl16(8);
if(sel.ltf)
{
u1 = u0.add16(GSVector4i::x0001());
v1 = v0.add16(GSVector4i::x0001());
if(sel.twin)
{
u0 = (u0 & m_local.twin[0].u).add16(m_local.twin[1].u);
v0 = (v0 & m_local.twin[0].v).add16(m_local.twin[1].v);
u1 = (u1 & m_local.twin[0].u).add16(m_local.twin[1].u);
v1 = (v1 & m_local.twin[0].v).add16(m_local.twin[1].v);
}
else
{
u0 = u0.min_i16(m_local.twin[2].u);
v0 = v0.min_i16(m_local.twin[2].v);
u1 = u1.min_i16(m_local.twin[2].u);
v1 = v1.min_i16(m_local.twin[2].v);
}
addr00 = v0.sll16(8) | u0;
addr01 = v0.sll16(8) | u1;
addr10 = v1.sll16(8) | u0;
addr11 = v1.sll16(8) | u1;
// TODO
if(sel.tlu)
{
c00 = addr00.gather16_16((const uint16*)m_global.vm, m_global.clut);
c01 = addr01.gather16_16((const uint16*)m_global.vm, m_global.clut);
c10 = addr10.gather16_16((const uint16*)m_global.vm, m_global.clut);
c11 = addr11.gather16_16((const uint16*)m_global.vm, m_global.clut);
}
else
{
c00 = addr00.gather16_16((const uint16*)m_global.vm);
c01 = addr01.gather16_16((const uint16*)m_global.vm);
c10 = addr10.gather16_16((const uint16*)m_global.vm);
c11 = addr11.gather16_16((const uint16*)m_global.vm);
}
GSVector4i r00 = c00.sll16(11).srl16(8);
GSVector4i r01 = c01.sll16(11).srl16(8);
GSVector4i r10 = c10.sll16(11).srl16(8);
GSVector4i r11 = c11.sll16(11).srl16(8);
r00 = r00.lerp16<0>(r01, uf);
r10 = r10.lerp16<0>(r11, uf);
GSVector4i g00 = c00.sll16(6).srl16(11).sll16(3);
GSVector4i g01 = c01.sll16(6).srl16(11).sll16(3);
GSVector4i g10 = c10.sll16(6).srl16(11).sll16(3);
GSVector4i g11 = c11.sll16(6).srl16(11).sll16(3);
g00 = g00.lerp16<0>(g01, uf);
g10 = g10.lerp16<0>(g11, uf);
GSVector4i b00 = c00.sll16(1).srl16(11).sll16(3);
GSVector4i b01 = c01.sll16(1).srl16(11).sll16(3);
GSVector4i b10 = c10.sll16(1).srl16(11).sll16(3);
GSVector4i b11 = c11.sll16(1).srl16(11).sll16(3);
b00 = b00.lerp16<0>(b01, uf);
b10 = b10.lerp16<0>(b11, uf);
GSVector4i a00 = c00.sra16(15).sll16(8);
GSVector4i a01 = c01.sra16(15).sll16(8);
GSVector4i a10 = c10.sra16(15).sll16(8);
GSVector4i a11 = c11.sra16(15).sll16(8);
a00 = a00.lerp16<0>(a01, uf);
a10 = a10.lerp16<0>(a11, uf);
r = r00.lerp16<0>(r10, vf);
g = g00.lerp16<0>(g10, vf);
b = b00.lerp16<0>(b10, vf);
a = a00.lerp16<0>(a10, vf);
test |= (r | g | b | a).eq16(GSVector4i::zero()); // mask out blank pixels (not perfect)
a = a.gt16(GSVector4i::zero());
}
else
{
if(sel.twin)
{
u0 = (u0 & m_local.twin[0].u).add16(m_local.twin[1].u);
v0 = (v0 & m_local.twin[0].v).add16(m_local.twin[1].v);
}
else
{
u0 = u0.min_i16(m_local.twin[2].u);
v0 = v0.min_i16(m_local.twin[2].v);
}
addr00 = v0.sll16(8) | u0;
// TODO
if(sel.tlu)
{
c00 = addr00.gather16_16((const uint16*)m_global.vm, m_global.clut);
}
else
{
c00 = addr00.gather16_16((const uint16*)m_global.vm);
}
r = (c00 << 3) & 0x00f800f8;
g = (c00 >> 2) & 0x00f800f8;
b = (c00 >> 7) & 0x00f800f8;
a = c00.sra16(15);
test |= c00.eq16(GSVector4i::zero()); // mask out blank pixels
}
}
// ColorTFX
switch(sel.tfx)
{
case 0: // none (tfx = 0)
case 1: // none (tfx = tge)
r = rf.srl16(7);
g = gf.srl16(7);
b = bf.srl16(7);
break;
case 2: // modulate (tfx = tme | tge)
r = r.modulate16<1>(rf).clamp8();
g = g.modulate16<1>(gf).clamp8();
b = b.modulate16<1>(bf).clamp8();
break;
case 3: // decal (tfx = tme)
break;
default:
__assume(0);
}
// AlphaBlend
if(sel.abe)
{
GSVector4i rs = r;
GSVector4i gs = g;
GSVector4i bs = b;
GSVector4i rd = (fd & 0x001f001f) << 3;
GSVector4i gd = (fd & 0x03e003e0) >> 2;
GSVector4i bd = (fd & 0x7c007c00) >> 7;
switch(sel.abr)
{
case 0:
r = rd.avg8(rs);
g = gd.avg8(gs);
b = bd.avg8(bs);
break;
case 1:
r = rd.addus8(rs);
g = gd.addus8(gs);
b = bd.addus8(bs);
break;
case 2:
r = rd.subus8(rs);
g = gd.subus8(gs);
b = bd.subus8(bs);
break;
case 3:
r = rd.addus8(rs.srl16(2));
g = gd.addus8(gs.srl16(2));
b = bd.addus8(bs.srl16(2));
break;
default:
__assume(0);
}
if(sel.tme)
{
r = rs.blend8(rd, a);
g = gs.blend8(gd, a);
b = bs.blend8(bd, a);
}
}
// Dither
if(sel.dtd)
{
r = r.addus8(dither);
g = g.addus8(dither);
b = b.addus8(dither);
}
// WriteFrame
GSVector4i fs = r | g | b | (sel.md ? GSVector4i(0x80008000) : sel.tme ? a : GSVector4i::zero());
fs = fs.blend8(fd, test);
GSVector4i::store(fb, fb + 8, fs);
}
while(0);
if(steps <= 0) break;
steps -= 8;
fb += 8;
if(sel.tme)
{
GSVector4i st = m_local.d8.st;
s = s.add16(st.xxxx());
t = t.add16(st.yyyy());
}
if(sel.tfx != 3) // != decal
{
if(sel.iip)
{
GSVector4i c = m_local.d8.c;
rf = rf.add16(c.xxxx());
gf = gf.add16(c.yyyy());
bf = bf.add16(c.zzzz());
}
}
}
}
void GPUDrawScanline::DrawEdge(int pixels, int left, int top, const GSVertexSW& scan)
{
ASSERT(0);
}
void GPUDrawScanline::DrawRect(const GSVector4i& r, const GSVertexSW& v)
{
// TODO
}
#endif

View File

@ -1,76 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GPUState.h"
#include "Renderers/SW/GSRasterizer.h"
#include "GPUScanlineEnvironment.h"
#include "GPUSetupPrimCodeGenerator.h"
#include "GPUDrawScanlineCodeGenerator.h"
class GPUDrawScanline : public IDrawScanline
{
public:
class SharedData : public GSRasterizerData
{
public:
GPUScanlineGlobalData global;
public:
SharedData()
{
global.clut = NULL;
}
virtual ~SharedData()
{
if(global.clut) _aligned_free(global.clut);
}
};
protected:
GPUScanlineGlobalData m_global;
GPUScanlineLocalData m_local;
GSCodeGeneratorFunctionMap<GPUSetupPrimCodeGenerator, uint32, SetupPrimPtr> m_sp_map;
GSCodeGeneratorFunctionMap<GPUDrawScanlineCodeGenerator, uint32, DrawScanlinePtr> m_ds_map;
public:
GPUDrawScanline();
virtual ~GPUDrawScanline() = default;
// IDrawScanline
void BeginDraw(const GSRasterizerData* data);
void EndDraw(uint64 frame, uint64 ticks, int actual, int total);
#ifndef ENABLE_JIT_RASTERIZER
void SetupPrim(const GSVertexSW* vertex, const uint32* index, const GSVertexSW& dscan);
void DrawScanline(int pixels, int left, int top, const GSVertexSW& scan);
void DrawEdge(int pixels, int left, int top, const GSVertexSW& scan);
void DrawRect(const GSVector4i& r, const GSVertexSW& v);
#endif
void PrintStats() {m_ds_map.PrintStats();}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GPUScanlineEnvironment.h"
#include "Renderers/Common/GSFunctionMap.h"
using namespace Xbyak;
class GPUDrawScanlineCodeGenerator : public GSCodeGenerator
{
void operator = (const GPUDrawScanlineCodeGenerator&);
GPUScanlineSelector m_sel;
GPUScanlineLocalData& m_local;
void Generate();
void Init();
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(void* param, uint32 key, void* code, size_t maxsize);
static GSVector4i m_test[8];
alignas(32) static const uint16 m_dither[4][16];
static void InitVectors();
};

View File

@ -1,75 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GPU.h"
class alignas(32) 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));
}
float GetFPS()
{
return STATUS.ISPAL ? 50.0f : 59.94f;
}
};

View File

@ -1,670 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GPULocalMemory.h"
#include "GSdx.h"
GSVector4i GPULocalMemory::m_xxxa;
GSVector4i GPULocalMemory::m_xxbx;
GSVector4i GPULocalMemory::m_xgxx;
GSVector4i GPULocalMemory::m_rxxx;
#define VM_REAL_SIZE ((1 << (12 + 11)) * sizeof(uint16))
#define VM_ALLOC_SIZE (VM_REAL_SIZE * 2)
#define TEX_ALLOC_SIZE (256 * 256 * (1 + 1 + 4) * 32)
void GPULocalMemory::InitVectors()
{
m_xxxa = GSVector4i(0x00008000);
m_xxbx = GSVector4i(0x00007c00);
m_xgxx = GSVector4i(0x000003e0);
m_rxxx = GSVector4i(0x0000001f);
}
GPULocalMemory::GPULocalMemory()
{
m_scale.x = std::min<int>(std::max<int>(theApp.GetConfigI("scale_x"), 0), 2);
m_scale.y = std::min<int>(std::max<int>(theApp.GetConfigI("scale_y"), 0), 2);
//
int size = VM_REAL_SIZE;
m_vm = (uint16*)vmalloc(VM_ALLOC_SIZE, false);
memset(m_vm, 0, size);
//
m_clut.buff = m_vm + size;
m_clut.dirty = true;
//
size = TEX_ALLOC_SIZE;
m_texture.buff[0] = (uint8*)vmalloc(size, false);
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()
{
vmfree(m_vm, VM_ALLOC_SIZE);
vmfree(m_texture.buff[0], TEX_ALLOC_SIZE);
}
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 = std::min(r.bottom, 512), j = 0; y < ye; y += 256, j++)
{
if(r.top >= y + 256) continue;
for(int x = 0, xe = std::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);
}
}
#include "Renderers/SW/GSTextureSW.h"
void GPULocalMemory::SaveBMP(const std::string& fn, 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;
GSTextureSW t(GSTexture::Offscreen, r.width(), r.height());
GSTexture::GSMap m;
if(t.Map(m, NULL))
{
int pitch = GetWidth();
const uint16* RESTRICT src = GetPixelAddress(r.left, r.top);
const uint16* RESTRICT clut = GetCLUT(tp, cx, cy);
uint8* RESTRICT dst = m.bits;
uint16* RESTRICT buff = (uint16*)_aligned_malloc(pitch * sizeof(uint16), 32);
uint32* RESTRICT buff32 = (uint32*)_aligned_malloc(pitch * sizeof(uint32), 32);
for(int j = r.top; j < r.bottom; j++, src += pitch, dst += m.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);
}
memcpy(dst, buff32, r.width() << 2);
}
_aligned_free(buff);
_aligned_free(buff32);
t.Unmap();
t.Save(fn);
}
}

View File

@ -1,86 +0,0 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GPU.h"
#include "GSVector.h"
class GPULocalMemory
{
static GSVector4i m_xxxa;
static GSVector4i m_xxbx;
static GSVector4i m_xgxx;
static 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:
static void InitVectors();
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 std::string& fn, const GSVector4i& r, int tp, int cx, int cy);
};

View File

@ -1,278 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GPURenderer.h"
#include "GSdx.h"
#ifdef _WIN32
std::map<HWND, GPURenderer*> GPURenderer::m_wnd2gpu;
#endif
GPURenderer::GPURenderer(GSDevice* dev)
: m_dev(dev)
{
m_filter = theApp.GetConfigI("filter");
m_dither = theApp.GetConfigI("dithering");
m_aspectratio = theApp.GetConfigI("AspectRatio");
m_vsync = theApp.GetConfigI("vsync");
m_fxaa = theApp.GetConfigB("fxaa");
m_shaderfx = theApp.GetConfigB("shaderfx");
m_scale = m_mem.GetScale();
m_shadeboost = theApp.GetConfigB("ShadeBoost");
#ifdef _WIN32
m_hWnd = NULL;
m_wndproc = NULL;
m_wnd = std::make_shared<GSWndDX>();
#endif
}
GPURenderer::~GPURenderer()
{
#ifdef _WIN32
if(m_wndproc)
{
SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_wndproc);
m_wnd2gpu.erase(m_hWnd);
}
#endif
}
bool GPURenderer::Create(void* hWnd)
{
#ifdef _WIN32
// TODO: move subclassing inside GSWnd::Attach
m_hWnd = (HWND)hWnd;
m_wndproc = (WNDPROC)GetWindowLongPtr(m_hWnd, GWLP_WNDPROC);
SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc);
if(!m_wnd->Attach(m_hWnd))
{
return false;
}
m_wnd2gpu[m_hWnd] = this;
SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW);
#endif
m_wnd->Show();
if(!m_dev->Create(m_wnd))
{
return false;
}
m_dev->SetVSync(m_vsync);
Reset();
return true;
}
bool GPURenderer::Merge()
{
GSTexture* st[3] = {GetOutput(), NULL, 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);
GSRegPMODE PMODE = {0};
PMODE.u32[0] = 0xFFFFFFFF;
GSRegEXTBUF EXTBUF = {0};
m_dev->Merge(st, sr, dr, s, PMODE, EXTBUF, GSVector4(0, 0, 0, 1));
if(m_shadeboost)
{
m_dev->ShadeBoost();
}
if (m_shaderfx)
{
m_dev->ExternalFX();
}
if(m_fxaa)
{
m_dev->FXAA();
}
return true;
}
void GPURenderer::VSync()
{
GSPerfMonAutoTimer pmat(&m_perfmon);
m_perfmon.Put(GSPerfMon::Frame);
// m_env.STATUS.LCF = ~m_env.STATUS.LCF; // ?
#ifdef _WIN32
if(!IsWindow(m_hWnd)) return;
#endif
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;
std::string s = format(
"%lld | %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));
}
m_wnd->SetWindowText(s.c_str());
}
GSVector4i r = m_wnd->GetClientRect();
m_dev->Present(r.fit(m_aspectratio), 0);
}
bool GPURenderer::MakeSnapshot(const std::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;
}
#ifdef _WIN32
LRESULT CALLBACK GPURenderer::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
auto 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;
theApp.SetConfig("filter", m_filter);
return 0;
case VK_END:
m_dither = m_dither ? 0 : 1;
theApp.SetConfig("dithering", m_dither);
return 0;
case VK_NEXT:
m_aspectratio = (m_aspectratio + 1) % 3;
theApp.SetConfig("AspectRatio", m_aspectratio);
return 0;
case VK_PRIOR:
m_fxaa = !m_fxaa;
theApp.SetConfig("fxaa", m_fxaa);
return 0;
case VK_HOME:
m_shaderfx = !m_shaderfx;
theApp.SetConfig("shaderfx", m_shaderfx);
return 0;
}
}
return CallWindowProc(m_wndproc, m_hWnd, message, wParam, lParam);
}
#endif

View File

@ -1,202 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GPUState.h"
#include "Renderers/Common/GSVertexList.h"
#include "Renderers/Common/GSDevice.h"
#ifdef _WIN32
#include "Window/GSWndDX.h"
#endif
class GPURenderer : public GPUState
{
bool Merge();
protected:
GSDevice* m_dev;
int m_filter;
int m_dither;
int m_aspectratio;
int m_vsync;
bool m_shaderfx;
bool m_fxaa;
bool m_shadeboost;
GSVector2i m_scale;
virtual void ResetDevice() {}
virtual GSTexture* GetOutput() = 0;
#ifdef _WIN32
HWND m_hWnd;
WNDPROC m_wndproc;
static std::map<HWND, GPURenderer*> m_wnd2gpu;
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
#endif
std::shared_ptr<GSWnd> m_wnd;
public:
GPURenderer(GSDevice* dev);
virtual ~GPURenderer();
virtual bool Create(void* hWnd);
virtual void VSync();
virtual bool MakeSnapshot(const std::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();
GPURenderer::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.left, r.top, r.right, r.bottom).c_str(), m_env.STATUS.TP, r, false);
}
*/
Draw();
m_count = 0;
//Dump("dc", false);
}
}
void GrowVertexBuffer()
{
int maxcount = std::max<int>(m_maxcount * 3 / 2, 10000);
Vertex* vertices = (Vertex*)_aligned_malloc(sizeof(Vertex) * maxcount, 32);
if(vertices == NULL)
{
printf("GSdx: failed to allocate %d bytes for verticles.\n", (int)sizeof(Vertex) * maxcount);
throw GSDXError();
}
if(m_vertices != NULL)
{
memcpy(vertices, m_vertices, sizeof(Vertex) * m_maxcount);
_aligned_free(m_vertices);
}
m_vertices = vertices;
m_maxcount = 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_vertices(NULL)
, m_count(0)
, m_maxcount(0)
{
}
virtual ~GPURendererT()
{
if(m_vertices) _aligned_free(m_vertices);
}
};

View File

@ -1,205 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GPURendererSW.h"
//#include "GSdx.h"
GPURendererSW::GPURendererSW(GSDevice* dev, int threads)
: GPURendererT<GSVertexSW>(dev)
, m_texture(NULL)
{
m_output = (uint32*)_aligned_malloc(m_mem.GetWidth() * m_mem.GetHeight() * sizeof(uint32), 32);
m_rl = GSRasterizerList::Create<GPUDrawScanline>(threads, &m_perfmon);
}
GPURendererSW::~GPURendererSW()
{
delete m_texture;
delete m_rl;
_aligned_free(m_output);
}
void GPURendererSW::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()))
{
m_mem.ReadFrame32(r, m_output, !!m_env.STATUS.ISRGB24);
m_texture->Update(r.rsize(), m_output, m_mem.GetWidth() * sizeof(uint32));
}
return m_texture;
}
void GPURendererSW::Draw()
{
GPUDrawScanline::SharedData* sd = new GPUDrawScanline::SharedData();
std::shared_ptr<GSRasterizerData> data(sd);
GPUScanlineGlobalData& gd = sd->global;
const GPUDrawingEnvironment& env = m_env;
gd.sel.key = 0;
gd.sel.iip = env.PRIM.IIP;
gd.sel.me = env.STATUS.ME;
if(env.PRIM.ABE)
{
gd.sel.abe = env.PRIM.ABE;
gd.sel.abr = env.STATUS.ABR;
}
gd.sel.tge = env.PRIM.TGE;
if(env.PRIM.TME)
{
gd.sel.tme = env.PRIM.TME;
gd.sel.tlu = env.STATUS.TP < 2;
gd.sel.twin = (env.TWIN.u32 & 0xfffff) != 0;
gd.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;}
gd.tex = t;
gd.clut = (uint16*)_aligned_malloc(sizeof(uint16) * 256, 32);
memcpy(gd.clut, m_mem.GetCLUT(env.STATUS.TP, env.CLUT.X, env.CLUT.Y), sizeof(uint16) * (env.STATUS.TP == 0 ? 16 : 256));
gd.twin = GSVector4i(env.TWIN.TWW, env.TWIN.TWH, env.TWIN.TWX, env.TWIN.TWY);
}
gd.sel.dtd = m_dither ? env.STATUS.DTD : 0;
gd.sel.md = env.STATUS.MD;
gd.sel.sprite = env.PRIM.TYPE == GPU_SPRITE;
gd.sel.scalex = m_mem.GetScale().x;
gd.vm = m_mem.GetPixelAddress(0, 0);
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 = std::min((int)(m_env.DRAREABR.X + 1) << m_scale.x, m_mem.GetWidth());
data->scissor.bottom = std::min((int)(m_env.DRAREABR.Y + 1) << m_scale.y, m_mem.GetHeight());
data->buff = (uint8*)_aligned_malloc(sizeof(GSVertexSW) * m_count, 32);
data->vertex = (GSVertexSW*)data->buff;
data->vertex_count = m_count;
memcpy(data->vertex, m_vertices, sizeof(GSVertexSW) * m_count);
data->frame = m_perfmon.GetFrame();
int prims = 0;
switch(env.PRIM.TYPE)
{
case GPU_POLYGON: data->primclass = GS_TRIANGLE_CLASS; prims = data->vertex_count / 3; break;
case GPU_LINE: data->primclass = GS_LINE_CLASS; prims = data->vertex_count / 2; break;
case GPU_SPRITE: data->primclass = GS_SPRITE_CLASS; prims = data->vertex_count / 2; break;
default: __assume(0);
}
// TODO: VertexTrace
GSVector4 tl(+1e10f);
GSVector4 br(-1e10f);
GSVertexSW* v = data->vertex;
for(int i = 0, j = data->vertex_count; i < j; i++)
{
GSVector4 p = v[i].p;
tl = tl.min(p);
br = br.max(p);
}
data->bbox = GSVector4i(tl.xyxy(br));
GSVector4i r = data->bbox.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);
m_rl->Queue(data);
m_rl->Sync();
m_perfmon.Put(GSPerfMon::Draw, 1);
m_perfmon.Put(GSPerfMon::Prim, prims);
m_perfmon.Put(GSPerfMon::Fillrate, m_rl->GetPixels());
}
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 u = m_v.UV.X;
int v = m_v.UV.Y;
GSVector4 pt(x, y, u, v);
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(DrawingKick(count))
{
// TODO
m_count += count;
}
}

View File

@ -1,42 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GPURenderer.h"
#include "GPUDrawScanline.h"
class GPURendererSW : public GPURendererT<GSVertexSW>
{
protected:
IRasterizer* m_rl;
GSTexture* m_texture;
uint32* m_output;
void ResetDevice();
GSTexture* GetOutput();
void VertexKick();
void Draw();
public:
GPURendererSW(GSDevice* dev, int threads);
virtual ~GPURendererSW();
};

View File

@ -1,78 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 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() const {return key;}
};
struct alignas(32) GPUScanlineGlobalData
{
GPUScanlineSelector sel;
void* vm;
const void* tex;
uint16* clut;
GSVector4i twin; // TWW, TWH, TWX, TWY
};
struct alignas(32) GPUScanlineLocalData
{
const GPUScanlineGlobalData* gd;
struct {GSVector4i u, v;} twin[3];
struct {GSVector4i s, t, r, g, b, _pad[3];} d;
struct {GSVector4i st, c;} d8;
struct {GSVector4i s, t, r, b, g, uf, vf, dither, fd, test;} temp;
};

View File

@ -1,126 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSdx.h"
#include "GSUtil.h"
#include "resource.h"
#include "GPU.h"
#include "GPUSettingsDlg.h"
GPUSettingsDlg::GPUSettingsDlg()
: GSDialog(IDD_GPUCONFIG)
{
}
void GPUSettingsDlg::OnInit()
{
__super::OnInit();
// FIXME: Someone can fix this to use D3D11 or OGL Device, D3D9 is no longer supported.
ComboBoxAppend(IDC_RESOLUTION, "Please select...");
ComboBoxInit(IDC_RENDERER, theApp.m_gpu_renderers, theApp.GetConfigI("Renderer"));
ComboBoxInit(IDC_FILTER, theApp.m_gpu_filter, theApp.GetConfigI("filter"));
ComboBoxInit(IDC_DITHERING, theApp.m_gpu_dithering, theApp.GetConfigI("dithering"));
ComboBoxInit(IDC_ASPECTRATIO, theApp.m_gpu_aspectratio, theApp.GetConfigI("AspectRatio"));
ComboBoxInit(IDC_SCALE, theApp.m_gpu_scale, theApp.GetConfigI("scale_x") | (theApp.GetConfigI("scale_y") << 2));
CheckDlgButton(m_hWnd, IDC_WINDOWED, theApp.GetConfigB("windowed"));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfigI("extrathreads"), 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_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("extrathreads", (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))
{
GPURendererType renderer = static_cast<GPURendererType>(i);
bool dx11 = renderer == GPURendererType::D3D11_SW;
bool null = renderer == GPURendererType::NULL_Renderer;
ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO11), dx11 ? SW_SHOW : SW_HIDE);
ShowWindow(GetDlgItem(m_hWnd, IDC_NULL), null ? SW_SHOW : SW_HIDE);
EnableWindow(GetDlgItem(m_hWnd, IDC_RESOLUTION), false);
EnableWindow(GetDlgItem(m_hWnd, IDC_RESOLUTION_TEXT), false);
EnableWindow(GetDlgItem(m_hWnd, IDC_FILTER), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_FILTER_TEXT), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_DITHERING), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_DITHERING_TEXT), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_ASPECTRATIO), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_ASPECTRATIO_TEXT), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_SCALE), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_SCALE_TEXT), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS_TEXT), dx11);
EnableWindow(GetDlgItem(m_hWnd, IDC_SWTHREADS_EDIT), dx11);
}
}

View File

@ -1,37 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "Window/GSDialog.h"
#include "Window/GSSetting.h"
class GPUSettingsDlg : public GSDialog
{
void UpdateControls();
protected:
void OnInit();
bool OnCommand(HWND hWnd, UINT id, UINT code);
public:
GPUSettingsDlg();
};

View File

@ -1,236 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
// TODO: x64
#include "stdafx.h"
#include "GPUSetupPrimCodeGenerator.h"
#include "Renderers/SW/GSVertexSW.h"
using namespace Xbyak;
static const int _args = 0;
static const int _vertex = _args + 4;
static const int _index = _args + 8;
static const int _dscan = _args + 12;
GPUSetupPrimCodeGenerator::GPUSetupPrimCodeGenerator(void* param, uint32 key, void* code, size_t maxsize)
: GSCodeGenerator(code, maxsize)
, m_local(*(GPUScanlineLocalData*)param)
{
m_sel.key = key;
Generate();
}
void GPUSetupPrimCodeGenerator::Generate()
{
if(m_sel.tme && !m_sel.twin)
{
pcmpeqd(xmm0, xmm0);
if(m_sel.sprite)
{
// t = (GSVector4i(vertices[1].t) >> 8) - GSVector4i::x00000001();
mov(ecx, ptr[esp + _index]);
mov(ecx, ptr[ecx + sizeof(uint32) * 1]);
shl(ecx, 6); // * sizeof(GSVertexSW)
add(ecx, ptr[esp + _vertex]);
cvttps2dq(xmm1, ptr[ecx + offsetof(GSVertexSW, t)]);
psrld(xmm1, 8);
psrld(xmm0, 31);
psubd(xmm1, xmm0);
// t = t.ps32(t);
// t = t.upl16(t);
packssdw(xmm1, xmm1);
punpcklwd(xmm1, xmm1);
// m_local.twin[2].u = t.xxxx();
// m_local.twin[2].v = t.yyyy();
pshufd(xmm2, xmm1, _MM_SHUFFLE(0, 0, 0, 0));
pshufd(xmm3, xmm1, _MM_SHUFFLE(1, 1, 1, 1));
movdqa(ptr[&m_local.twin[2].u], xmm2);
movdqa(ptr[&m_local.twin[2].v], xmm3);
}
else
{
// TODO: not really needed
// m_local.twin[2].u = GSVector4i::x00ff();
// m_local.twin[2].v = GSVector4i::x00ff();
psrlw(xmm0, 8);
movdqa(ptr[&m_local.twin[2].u], xmm0);
movdqa(ptr[&m_local.twin[2].v], xmm0);
}
}
if(m_sel.tme || m_sel.iip && m_sel.tfx != 3)
{
mov(edx, dword[esp + _dscan]);
for(int i = 0; i < 3; i++)
{
movaps(Xmm(5 + i), ptr[&m_shift[i]]);
}
// GSVector4 dt = dscan.t;
// GSVector4 dc = dscan.c;
movaps(xmm4, ptr[edx + offsetof(GSVertexSW, c)]);
movaps(xmm3, ptr[edx + offsetof(GSVertexSW, t)]);
// 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_sel.tme)
{
// m_local.d8.st = dtc8.upl16(dtc8);
movdqa(xmm0, xmm1);
punpcklwd(xmm0, xmm0);
movdqa(ptr[&m_local.d8.st], xmm0);
}
if(m_sel.iip && m_sel.tfx != 3)
{
// m_local.d8.c = dtc8.uph16(dtc8);
punpckhwd(xmm1, xmm1);
movdqa(ptr[&m_local.d8.c], xmm1);
}
// xmm3 = dt
// xmm4 = dc
// xmm6 = ps0123
// xmm7 = ps4567
// xmm0, xmm1, xmm2, xmm5 = free
if(m_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_local.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(ptr[&m_local.d.s], xmm3);
// m_local.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(ptr[&m_local.d.t], xmm0);
}
// xmm4 = dc
// xmm6 = ps0123
// xmm7 = ps4567
// xmm0, xmm1, zmm2, xmm3, xmm5 = free
if(m_sel.iip && m_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_local.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(ptr[&m_local.d.r], xmm4);
// m_local.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(ptr[&m_local.d.g], xmm0);
// m_local.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(ptr[&m_local.d.b], xmm1);
}
}
ret();
}
GSVector4 GPUSetupPrimCodeGenerator::m_shift[3];
void GPUSetupPrimCodeGenerator::InitVectors()
{
GSVector4 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),
};
for (size_t n = 0; n < countof(shift); ++n)
m_shift[n] = shift[n];
}

View File

@ -1,42 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GPUScanlineEnvironment.h"
#include "Renderers/Common/GSFunctionMap.h"
class GPUSetupPrimCodeGenerator : public GSCodeGenerator
{
void operator = (const GPUSetupPrimCodeGenerator&);
GPUScanlineSelector m_sel;
GPUScanlineLocalData& m_local;
void Generate();
public:
GPUSetupPrimCodeGenerator(void* param, uint32 key, void* code, size_t maxsize);
static GSVector4 m_shift[3];
static void InitVectors();
};

View File

@ -1,805 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 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(size_t 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();
}
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++)
{
// TODO: sse
int y0 = v[i + 0].XY.Y;
int y1 = v[i + 1].XY.Y;
int y2 = v[i + 2].XY.Y;
if(std::abs(y0 - y1) >= 512
|| std::abs(y0 - y2) >= 512
|| std::abs(y1 - y2) >= 512)
{
continue;
}
int x0 = v[i + 0].XY.X;
int x1 = v[i + 1].XY.X;
int x2 = v[i + 2].XY.X;
if(std::abs(x0 - x1) >= 1024
|| std::abs(x0 - x2) >= 1024
|| std::abs(x1 - x2) >= 1024)
{
continue;
}
//
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 & 0xf000f000) == 0x50005000)
{
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;
if(w > 0 && h > 0)
{
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)
{
switch(r->PACKET.OPTION)
{
case 1: // draw mode setting
if(((m_env.STATUS.u32 ^ r->MODE.u32) & 0x7ff) != 0)
{
Flush();
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
if(((m_env.TWIN.u32 ^ r->TWIN.u32) & 0xfffff) != 0)
{
Flush();
m_env.TWIN = r->TWIN;
}
return 1;
case 3: // set drawing area top left
if(((m_env.DRAREATL.u32 ^ r->DRAREA.u32) & 0xfffff) != 0)
{
Flush();
m_env.DRAREATL = r->DRAREA;
}
return 1;
case 4: // set drawing area bottom right
if(((m_env.DRAREABR.u32 ^ r->DRAREA.u32) & 0xfffff) != 0)
{
Flush();
m_env.DRAREABR = r->DRAREA;
}
return 1;
case 5: // drawing offset
if(((m_env.DROFF.u32 ^ r->DROFF.u32) & 0x3fffff) != 0)
{
Flush();
m_env.DROFF = r->DROFF;
}
return 1;
case 6: // mask setting
if(m_env.STATUS.MD != r->MASK.MD || m_env.STATUS.ME != r->MASK.ME)
{
Flush();
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, 32);
cur = 0;
}
GPUState::Buffer::~Buffer()
{
_aligned_free(buff);
}
void GPUState::Buffer::Reserve(int size)
{
if(size > maxbytes)
{
int new_maxbytes = (maxbytes + size + 1023) & ~1023;
uint8* new_buff = (uint8*)_aligned_malloc(new_maxbytes, 32);
if(buff != NULL)
{
memcpy(new_buff, buff, maxbytes);
_aligned_free(buff);
}
maxbytes = new_maxbytes;
buff = new_buff;
}
}
void GPUState::Buffer::Append(const uint8* src, int size)
{
Reserve(bytes + (int)size);
memcpy(&buff[bytes], src, size);
bytes += size;
}
void GPUState::Buffer::Remove(int size)
{
ASSERT(size <= bytes);
if(size < bytes)
{
memmove(&buff[0], &buff[size], bytes - size);
bytes -= size;
}
else
{
bytes = 0;
}
#ifdef DEBUG
memset(&buff[bytes], 0xff, maxbytes - bytes);
#endif
}
void GPUState::Buffer::RemoveAll()
{
bytes = 0;
}

View File

@ -1,145 +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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 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<32>
{
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;
bool dump_enable = false;
void Dump(const std::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)
if(!dump_enable)
return;
if(inc) s_n++;
//if(s_n < 86) return;
int dir = 1;
#ifdef DEBUG
dir = 2;
#endif
std::string path = format("c:\\temp%d\\%04d_%s.bmp", dir, s_n, s.c_str());
m_mem.SaveBMP(path, r, TP, m_env.CLUT.X, m_env.CLUT.Y);
}
void Dump(const std::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() = default;
virtual void Reset();
virtual void Flush();
virtual void FlushPrim() = 0;
virtual void ResetPrim() = 0;
virtual void VertexKick() = 0;
virtual void Invalidate(const GSVector4i& r);
void WriteData(const uint8* mem, uint32 size);
void ReadData(uint8* mem, uint32 size);
void WriteStatus(uint32 status);
uint32 ReadStatus();
void Freeze(GPUFreezeData* data);
void Defrost(const GPUFreezeData* data);
};

View File

@ -1,51 +0,0 @@
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GPU.h"
#include "GSVector.h"
#pragma pack(push, 1)
struct alignas(32) GPUVertex
{
union
{
struct
{
GPURegRGB RGB;
GPURegXY XY;
GPURegXY UV;
};
struct {__m128i m128i;};
struct {__m128 m128;};
};
GPUVertex() {memset(this, 0, sizeof(*this));}
};
struct GPUVertexNull
{
};
#pragma pack(pop)

View File

@ -46,17 +46,6 @@
#define IDC_SWTHREADS 2063 #define IDC_SWTHREADS 2063
#define IDC_SWTHREADS_EDIT 2064 #define IDC_SWTHREADS_EDIT 2064
#define IDC_AUTO_FLUSH_SW 2065 #define IDC_AUTO_FLUSH_SW 2065
// PSX:
#define IDD_GPUCONFIG 2070
#define IDC_ASPECTRATIO 2071
#define IDC_ASPECTRATIO_TEXT 2072
#define IDC_DITHERING 2073
#define IDC_DITHERING_TEXT 2074
#define IDC_WINDOWED 2075
#define IDC_RESOLUTION 2076
#define IDC_RESOLUTION_TEXT 2077
#define IDC_SCALE 2078
#define IDC_SCALE_TEXT 2079
// Capture: // Capture:
#define IDD_CAPTURE 2090 #define IDD_CAPTURE 2090
#define IDC_FILENAME 2091 #define IDC_FILENAME 2091