just a bunch of random code cleanup i did on the train bored, plus a d3d implementation of NativeVertexFormat which isn't actually used yet.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1658 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
3fd665502e
commit
dcc48d6c41
|
@ -24,6 +24,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
#include "DynamicLibrary.h"
|
#include "DynamicLibrary.h"
|
||||||
|
|
||||||
|
@ -32,7 +33,6 @@ DynamicLibrary::DynamicLibrary()
|
||||||
library = 0;
|
library = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string GetLastErrorAsString()
|
std::string GetLastErrorAsString()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -64,13 +64,11 @@ std::string GetLastErrorAsString()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loading means loading the dll with LoadLibrary() to get an instance to the dll.
|
||||||
// ------------------------------------------------------------------
|
// This is done when Dolphin is started to determine which dlls are good, and
|
||||||
/* Loading means loading the dll with LoadLibrary() to get an instance to the dll.
|
// before opening the Config and Debugging windows from Plugin.cpp and
|
||||||
This is done when Dolphin is started to determine which dlls are good, and
|
// before opening the dll for running the emulation in Video_...cpp in Core.
|
||||||
before opening the Config and Debugging windows from Plugin.cpp and
|
// Since this is fairly slow, TODO: think about implementing some sort of cache.
|
||||||
before opening the dll for running the emulation in Video_...cpp in Core. */
|
|
||||||
// -----------------------
|
|
||||||
int DynamicLibrary::Load(const char* filename)
|
int DynamicLibrary::Load(const char* filename)
|
||||||
{
|
{
|
||||||
if (!filename || strlen(filename) == 0)
|
if (!filename || strlen(filename) == 0)
|
||||||
|
@ -80,7 +78,6 @@ int DynamicLibrary::Load(const char* filename)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
LOG(MASTER_LOG, "Trying to load library %s", filename);
|
LOG(MASTER_LOG, "Trying to load library %s", filename);
|
||||||
|
|
||||||
if (IsLoaded())
|
if (IsLoaded())
|
||||||
{
|
{
|
||||||
LOG(MASTER_LOG, "Trying to load already loaded library %s", filename);
|
LOG(MASTER_LOG, "Trying to load already loaded library %s", filename);
|
||||||
|
@ -93,9 +90,17 @@ int DynamicLibrary::Load(const char* filename)
|
||||||
library = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
|
library = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!library) {
|
if (!library)
|
||||||
|
{
|
||||||
LOG(MASTER_LOG, "Error loading DLL %s: %s", filename, GetLastErrorAsString().c_str());
|
LOG(MASTER_LOG, "Error loading DLL %s: %s", filename, GetLastErrorAsString().c_str());
|
||||||
|
if (File::Exists(filename))
|
||||||
|
{
|
||||||
|
PanicAlert("Error loading DLL %s: %s\n\nAre you missing SDL.DLL or another file that this plugin may depend on?", filename, GetLastErrorAsString().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PanicAlert("Error loading DLL %s: %s\n", filename, GetLastErrorAsString().c_str());
|
PanicAlert("Error loading DLL %s: %s\n", filename, GetLastErrorAsString().c_str());
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,20 +113,16 @@ int DynamicLibrary::Unload()
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
if (!IsLoaded()) {
|
if (!IsLoaded()) {
|
||||||
LOG(MASTER_LOG, "Error unloading DLL %s: not loaded", library_file.c_str());
|
|
||||||
PanicAlert("Error unloading DLL %s: not loaded", library_file.c_str());
|
PanicAlert("Error unloading DLL %s: not loaded", library_file.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
retval = FreeLibrary(library);
|
retval = FreeLibrary(library);
|
||||||
#else
|
#else
|
||||||
retval = dlclose(library)?0:1;
|
retval = dlclose(library)?0:1;
|
||||||
#endif
|
#endif
|
||||||
if (!retval) {
|
if (!retval) {
|
||||||
LOG(MASTER_LOG, "Error unloading DLL %s: %s", library_file.c_str(),
|
|
||||||
GetLastErrorAsString().c_str());
|
|
||||||
PanicAlert("Error unloading DLL %s: %s", library_file.c_str(),
|
PanicAlert("Error unloading DLL %s: %s", library_file.c_str(),
|
||||||
GetLastErrorAsString().c_str());
|
GetLastErrorAsString().c_str());
|
||||||
}
|
}
|
||||||
|
@ -135,8 +136,8 @@ void* DynamicLibrary::Get(const char* funcname) const
|
||||||
void* retval;
|
void* retval;
|
||||||
if (!library)
|
if (!library)
|
||||||
{
|
{
|
||||||
LOG(MASTER_LOG, "Can't find function %s - Library not loaded.");
|
|
||||||
PanicAlert("Can't find function %s - Library not loaded.");
|
PanicAlert("Can't find function %s - Library not loaded.");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
retval = GetProcAddress(library, funcname);
|
retval = GetProcAddress(library, funcname);
|
||||||
|
|
|
@ -24,16 +24,16 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
// Abstracts the (few) differences between dynamically loading DLLs under Windows
|
||||||
|
// and .so / .dylib under Linux/MacOSX.
|
||||||
class DynamicLibrary
|
class DynamicLibrary
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DynamicLibrary();
|
DynamicLibrary();
|
||||||
int Load(const char *filename);
|
int Load(const char *filename);
|
||||||
int Unload();
|
int Unload();
|
||||||
void *Get(const char *funcname) const;
|
void *Get(const char *funcname) const;
|
||||||
|
bool IsLoaded() const { return library != 0; }
|
||||||
bool IsLoaded() const {return(library != 0);}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string library_file;
|
std::string library_file;
|
||||||
|
|
|
@ -24,13 +24,13 @@ bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no);
|
||||||
|
|
||||||
static MsgAlertHandler msg_handler = DefaultMsgHandler;
|
static MsgAlertHandler msg_handler = DefaultMsgHandler;
|
||||||
|
|
||||||
void RegisterMsgAlertHandler(MsgAlertHandler handler) {
|
void RegisterMsgAlertHandler(MsgAlertHandler handler)
|
||||||
|
{
|
||||||
msg_handler = handler;
|
msg_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MsgAlert(const char* caption, bool yes_no,
|
bool MsgAlert(const char* caption, bool yes_no, const char* format, ...)
|
||||||
const char* format, ...) {
|
{
|
||||||
|
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
va_list args;
|
va_list args;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
@ -40,7 +40,8 @@ bool MsgAlert(const char* caption, bool yes_no,
|
||||||
|
|
||||||
LOG(MASTER_LOG, "%s: %s", caption, buffer);
|
LOG(MASTER_LOG, "%s: %s", caption, buffer);
|
||||||
|
|
||||||
if (msg_handler) {
|
if (msg_handler)
|
||||||
|
{
|
||||||
ret = msg_handler(caption, buffer, yes_no);
|
ret = msg_handler(caption, buffer, yes_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,9 +49,8 @@ bool MsgAlert(const char* caption, bool yes_no,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefaultMsgHandler(const char* caption, const char* text,
|
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no)
|
||||||
bool yes_no) {
|
{
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (yes_no)
|
if (yes_no)
|
||||||
return IDYES == MessageBox(0, text, caption,
|
return IDYES == MessageBox(0, text, caption,
|
||||||
|
|
|
@ -74,7 +74,7 @@ CEXIIPL::CEXIIPL() :
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PanicAlert("Error: failed to load font_ansi.bin. Fonts may bug");
|
PanicAlert("Error: failed to load font_ansi.bin.\nFonts in a few games may not work, or crash the game.");
|
||||||
}
|
}
|
||||||
|
|
||||||
pStream = fopen(FONT_SJIS_FILE, "rb");
|
pStream = fopen(FONT_SJIS_FILE, "rb");
|
||||||
|
@ -89,7 +89,8 @@ CEXIIPL::CEXIIPL() :
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PanicAlert("Error: failed to load font_sjis.bin. Fonts may bug");
|
// Heh, BIOS fonts don't really work in JAP games anyway ... we get bogus characters.
|
||||||
|
PanicAlert("Error: failed to load font_sjis.bin.\nFonts in a few Japanese games may not work or crash the game.");
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(m_pIPL, iplver, sizeof(iplver));
|
memcpy(m_pIPL, iplver, sizeof(iplver));
|
||||||
|
@ -120,7 +121,6 @@ CEXIIPL::~CEXIIPL()
|
||||||
if (m_count > 0)
|
if (m_count > 0)
|
||||||
{
|
{
|
||||||
m_szBuffer[m_count] = 0x00;
|
m_szBuffer[m_count] = 0x00;
|
||||||
//MessageBox(NULL, m_szBuffer, "last message", MB_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pIPL != NULL)
|
if (m_pIPL != NULL)
|
||||||
|
@ -130,19 +130,19 @@ CEXIIPL::~CEXIIPL()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRAM
|
// SRAM
|
||||||
FILE* pStream = NULL;
|
FILE *file = fopen(Core::GetStartupParameter().m_strSRAM.c_str(), "wb");
|
||||||
pStream = fopen(Core::GetStartupParameter().m_strSRAM.c_str(), "wb");
|
if (file)
|
||||||
if (pStream != NULL)
|
|
||||||
{
|
{
|
||||||
fwrite(m_SRAM, 1, 64, pStream);
|
fwrite(m_SRAM, 1, 64, file);
|
||||||
fclose(pStream);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEXIIPL::SetCS(int _iCS)
|
void CEXIIPL::SetCS(int _iCS)
|
||||||
{
|
{
|
||||||
if (_iCS)
|
if (_iCS)
|
||||||
{ // cs transition to high
|
{
|
||||||
|
// cs transition to high
|
||||||
m_uPosition = 0;
|
m_uPosition = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
||||||
int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0];
|
int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0];
|
||||||
if (accessType == 8) //Rule out DEP
|
if (accessType == 8) //Rule out DEP
|
||||||
{
|
{
|
||||||
if (PowerPC::state == PowerPC::CPU_POWERDOWN)
|
return (DWORD)EXCEPTION_CONTINUE_SEARCH;
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
|
||||||
MessageBox(0, _T("Tried to execute code that's not marked executable. This is likely a JIT bug.\n"), 0, 0);
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Where in the x86 code are we?
|
//Where in the x86 code are we?
|
||||||
|
|
|
@ -58,7 +58,7 @@ CPluginManager::~CPluginManager()
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// Create list of avaliable plugins
|
// Create list of available plugins
|
||||||
// -------------
|
// -------------
|
||||||
void CPluginManager::ScanForPlugins(wxWindow* _wxWindow)
|
void CPluginManager::ScanForPlugins(wxWindow* _wxWindow)
|
||||||
{
|
{
|
||||||
|
@ -148,7 +148,8 @@ void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, bool Type,
|
||||||
if (Type)
|
if (Type)
|
||||||
{
|
{
|
||||||
//Common::CPlugin::Debug((HWND)_Parent);
|
//Common::CPlugin::Debug((HWND)_Parent);
|
||||||
if(!PluginVideo::IsLoaded()) PluginVideo::LoadPlugin(_rFilename);
|
if (!PluginVideo::IsLoaded())
|
||||||
|
PluginVideo::LoadPlugin(_rFilename);
|
||||||
PluginVideo::Debug((HWND)_Parent, Show);
|
PluginVideo::Debug((HWND)_Parent, Show);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -162,7 +163,6 @@ void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, bool Type,
|
||||||
//m_DllDebugger(NULL);
|
//m_DllDebugger(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// Get dll info
|
// Get dll info
|
||||||
// -------------
|
// -------------
|
||||||
|
@ -179,6 +179,9 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
|
||||||
|
|
||||||
Common::CPlugin::Release();
|
Common::CPlugin::Release();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
The DLL loading code provides enough error messages already. Possibly make some return codes
|
||||||
|
and handle messages here instead?
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!File::Exists(_rFileName)) {
|
if (!File::Exists(_rFileName)) {
|
||||||
|
@ -186,7 +189,7 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
|
||||||
} else {
|
} else {
|
||||||
PanicAlert("Failed to load plugin %s - unknown error.\n", _rFileName);
|
PanicAlert("Failed to load plugin %s - unknown error.\n", _rFileName);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,14 +89,16 @@ struct PortableVertexDeclaration
|
||||||
// all the data loading code must always be made compatible.
|
// all the data loading code must always be made compatible.
|
||||||
class NativeVertexFormat
|
class NativeVertexFormat
|
||||||
{
|
{
|
||||||
u8* m_compiledCode;
|
protected:
|
||||||
PortableVertexDeclaration vtx_decl;
|
NativeVertexFormat() {}
|
||||||
public:
|
|
||||||
NativeVertexFormat();
|
|
||||||
~NativeVertexFormat();
|
|
||||||
|
|
||||||
void Initialize(const PortableVertexDeclaration &vtx_decl);
|
public:
|
||||||
void SetupVertexPointers() const;
|
virtual ~NativeVertexFormat() {}
|
||||||
|
|
||||||
|
virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0;
|
||||||
|
virtual void SetupVertexPointers() const = 0;
|
||||||
|
|
||||||
|
static NativeVertexFormat *Create();
|
||||||
|
|
||||||
// TODO: move these in under private:
|
// TODO: move these in under private:
|
||||||
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.
|
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.
|
||||||
|
|
|
@ -20,8 +20,16 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
|
// This must be called once before calling the two conversion functions
|
||||||
|
// below.
|
||||||
void InitXFBConvTables();
|
void InitXFBConvTables();
|
||||||
|
|
||||||
|
// These implementations could likely be made considerably faster by
|
||||||
|
// reducing precision so that intermediate calculations are done in
|
||||||
|
// 15-bit precision instead of 32-bit. However, this would complicate
|
||||||
|
// the code and since we have a GPU implementation too, there really
|
||||||
|
// isn't much point.
|
||||||
|
|
||||||
// Converts 4:2:2 YUV (YUYV) data to 32-bit RGBA data.
|
// Converts 4:2:2 YUV (YUYV) data to 32-bit RGBA data.
|
||||||
void ConvertFromXFB(u32 *dst, const u8* _pXFB, int width, int height);
|
void ConvertFromXFB(u32 *dst, const u8* _pXFB, int width, int height);
|
||||||
|
|
||||||
|
|
|
@ -1201,6 +1201,10 @@
|
||||||
RelativePath=".\Src\DecodedVArray.h"
|
RelativePath=".\Src\DecodedVArray.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\NativeVertexFormat.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\OpcodeDecoding.cpp"
|
RelativePath=".\Src\OpcodeDecoding.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1273,6 +1277,14 @@
|
||||||
RelativePath=".\Src\PixelShader.h"
|
RelativePath=".\Src\PixelShader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\PixelShaderManager.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\PixelShaderManager.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\Render.cpp"
|
RelativePath=".\Src\Render.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1281,14 +1293,6 @@
|
||||||
RelativePath=".\Src\Render.h"
|
RelativePath=".\Src\Render.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\Src\ShaderManager.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\ShaderManager.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\TextureCache.cpp"
|
RelativePath=".\Src\TextureCache.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1317,6 +1321,14 @@
|
||||||
RelativePath=".\Src\VertexShader.h"
|
RelativePath=".\Src\VertexShader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\VertexShaderManager.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\VertexShaderManager.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="D3D"
|
Name="D3D"
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
|
||||||
|
// 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, version 2.0.
|
||||||
|
|
||||||
|
// 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 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "D3DBase.h"
|
||||||
|
|
||||||
|
#include "Profiler.h"
|
||||||
|
#include "x64Emitter.h"
|
||||||
|
#include "ABI.h"
|
||||||
|
#include "MemoryUtil.h"
|
||||||
|
#include "VertexShader.h"
|
||||||
|
|
||||||
|
#include "CPMemory.h"
|
||||||
|
#include "NativeVertexFormat.h"
|
||||||
|
|
||||||
|
|
||||||
|
class D3DVertexFormat : public NativeVertexFormat
|
||||||
|
{
|
||||||
|
PortableVertexDeclaration vtx_decl;
|
||||||
|
LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
D3DVertexFormat();
|
||||||
|
~D3DVertexFormat();
|
||||||
|
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||||
|
virtual void SetupVertexPointers() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
NativeVertexFormat *NativeVertexFormat::Create()
|
||||||
|
{
|
||||||
|
return new D3DVertexFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DVertexFormat::D3DVertexFormat() : d3d_decl(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DVertexFormat::~D3DVertexFormat()
|
||||||
|
{
|
||||||
|
if (d3d_decl)
|
||||||
|
{
|
||||||
|
d3d_decl->Release();
|
||||||
|
d3d_decl = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
D3DDECLTYPE VarToD3D(VarType t)
|
||||||
|
{
|
||||||
|
static const D3DDECLTYPE lookup[5] =
|
||||||
|
{
|
||||||
|
D3DDECLTYPE_UBYTE4, D3DDECLTYPE_UBYTE4, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT3,
|
||||||
|
};
|
||||||
|
return lookup[t];
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Ban signed bytes as normals - not likely that ATI supports them natively.
|
||||||
|
// We probably won't see much of a speed loss, and any speed loss will be regained anyway
|
||||||
|
// when we finally compile display lists.
|
||||||
|
|
||||||
|
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||||
|
{
|
||||||
|
D3DVERTEXELEMENT9 *elems = new D3DVERTEXELEMENT9[32];
|
||||||
|
memset(elems, 0, sizeof(D3DVERTEXELEMENT9) * 32);
|
||||||
|
|
||||||
|
// There's only one stream and it's 0, so the above memset takes care of that - no need to set Stream.
|
||||||
|
// Same for method.
|
||||||
|
|
||||||
|
// So, here we go. First position:
|
||||||
|
int elem_idx = 0;
|
||||||
|
elems[elem_idx].Offset = 0; // Positions are always first, at position 0.
|
||||||
|
elems[elem_idx].Type = D3DDECLTYPE_FLOAT3;
|
||||||
|
elems[elem_idx].Usage = D3DDECLUSAGE_POSITION;
|
||||||
|
++elem_idx;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (_vtx_decl.normal_offset[i] >= 0)
|
||||||
|
{
|
||||||
|
elems[elem_idx].Offset = _vtx_decl.normal_offset[i];
|
||||||
|
elems[elem_idx].Type = VarToD3D(_vtx_decl.normal_gl_type);
|
||||||
|
elems[elem_idx].Usage = D3DDECLUSAGE_NORMAL;
|
||||||
|
elems[elem_idx].UsageIndex = i;
|
||||||
|
++elem_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
if (_vtx_decl.color_offset[i] >= 0)
|
||||||
|
{
|
||||||
|
elems[elem_idx].Offset = _vtx_decl.color_offset[i];
|
||||||
|
elems[elem_idx].Type = VarToD3D(_vtx_decl.color_gl_type);
|
||||||
|
elems[elem_idx].Usage = D3DDECLUSAGE_COLOR;
|
||||||
|
elems[elem_idx].UsageIndex = i;
|
||||||
|
++elem_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (_vtx_decl.texcoord_offset[i] >= 0)
|
||||||
|
{
|
||||||
|
elems[elem_idx].Offset = _vtx_decl.texcoord_offset[i];
|
||||||
|
elems[elem_idx].Type = VarToD3D(_vtx_decl.texcoord_gl_type[i]);
|
||||||
|
elems[elem_idx].Usage = D3DDECLUSAGE_TEXCOORD;
|
||||||
|
elems[elem_idx].UsageIndex = i;
|
||||||
|
++elem_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vtx_decl.posmtx_offset != -1)
|
||||||
|
{
|
||||||
|
// glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)vtx_decl.posmtx_offset);
|
||||||
|
elems[elem_idx].Offset = _vtx_decl.posmtx_offset;
|
||||||
|
elems[elem_idx].Usage = D3DDECLUSAGE_BLENDINDICES;
|
||||||
|
elems[elem_idx].UsageIndex = 0;
|
||||||
|
++elem_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(D3D::dev->CreateVertexDeclaration(elems, &d3d_decl)))
|
||||||
|
{
|
||||||
|
PanicAlert("Failed to create D3D vertex declaration!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3DVertexFormat::SetupVertexPointers() const
|
||||||
|
{
|
||||||
|
D3D::dev->SetVertexDeclaration(d3d_decl);
|
||||||
|
}
|
|
@ -33,7 +33,8 @@
|
||||||
#include "TransformEngine.h"
|
#include "TransformEngine.h"
|
||||||
#include "OpcodeDecoding.h"
|
#include "OpcodeDecoding.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "ShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
|
#include "PixelShaderManager.h"
|
||||||
|
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
#include "XFStructs.h"
|
#include "XFStructs.h"
|
||||||
|
|
|
@ -19,12 +19,14 @@
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "ShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
|
|
||||||
|
|
||||||
|
PShaderCache::PSCache PShaderCache::pshaders;
|
||||||
|
|
||||||
//I hope we don't get too many hash collisions :p
|
//I hope we don't get too many hash collisions :p
|
||||||
//all these magic numbers are primes, it should help a bit
|
//all these magic numbers are primes, it should help a bit
|
||||||
tevhash GetCurrentTEV()
|
tevhash GetCurrentTEV()
|
||||||
|
@ -53,9 +55,6 @@ tevhash GetCurrentTEV()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PShaderCache::PSCache PShaderCache::pshaders;
|
|
||||||
VShaderCache::VSCache VShaderCache::vshaders;
|
|
||||||
|
|
||||||
void PShaderCache::Init()
|
void PShaderCache::Init()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -133,86 +132,3 @@ void PShaderCache::Cleanup()
|
||||||
}
|
}
|
||||||
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
|
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VShaderCache::Init()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void VShaderCache::Shutdown()
|
|
||||||
{
|
|
||||||
VSCache::iterator iter = vshaders.begin();
|
|
||||||
for (; iter != vshaders.end(); iter++)
|
|
||||||
iter->second.Destroy();
|
|
||||||
vshaders.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void VShaderCache::SetShader()
|
|
||||||
{
|
|
||||||
static LPDIRECT3DVERTEXSHADER9 shader = NULL;
|
|
||||||
if (D3D::GetShaderVersion() < 2)
|
|
||||||
return; // we are screwed
|
|
||||||
|
|
||||||
if (shader) {
|
|
||||||
//D3D::dev->SetVertexShader(shader);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LPDIRECT3DVERTEXSHADER9 lastShader = 0;
|
|
||||||
DVSTARTPROFILE();
|
|
||||||
|
|
||||||
tevhash currentHash = GetCurrentTEV();
|
|
||||||
|
|
||||||
VSCache::iterator iter;
|
|
||||||
iter = vshaders.find(currentHash);
|
|
||||||
|
|
||||||
if (iter != vshaders.end())
|
|
||||||
{
|
|
||||||
iter->second.frameCount=frameCount;
|
|
||||||
VSCacheEntry &entry = iter->second;
|
|
||||||
if (!lastShader || entry.shader != lastShader)
|
|
||||||
{
|
|
||||||
D3D::dev->SetVertexShader(entry.shader);
|
|
||||||
lastShader = entry.shader;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *code = GenerateVertexShader();
|
|
||||||
shader = D3D::CompileVShader(code, int(strlen(code)));
|
|
||||||
if (shader)
|
|
||||||
{
|
|
||||||
//Make an entry in the table
|
|
||||||
VSCacheEntry entry;
|
|
||||||
entry.shader = shader;
|
|
||||||
entry.frameCount=frameCount;
|
|
||||||
vshaders[currentHash] = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D::dev->SetVertexShader(shader);
|
|
||||||
|
|
||||||
INCSTAT(stats.numVertexShadersCreated);
|
|
||||||
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void VShaderCache::Cleanup()
|
|
||||||
{
|
|
||||||
for (VSCache::iterator iter=vshaders.begin(); iter!=vshaders.end();)
|
|
||||||
{
|
|
||||||
VSCacheEntry &entry = iter->second;
|
|
||||||
if (entry.frameCount < frameCount - 30)
|
|
||||||
{
|
|
||||||
entry.Destroy();
|
|
||||||
iter = vshaders.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
|
||||||
}
|
|
|
@ -15,7 +15,8 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#pragma once
|
#ifndef _PIXELSHADERMANAGER_H
|
||||||
|
#define _PIXELSHADERMANAGER_H
|
||||||
|
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
|
|
||||||
|
@ -27,7 +28,6 @@ typedef u32 tevhash;
|
||||||
|
|
||||||
tevhash GetCurrentTEV();
|
tevhash GetCurrentTEV();
|
||||||
|
|
||||||
|
|
||||||
class PShaderCache
|
class PShaderCache
|
||||||
{
|
{
|
||||||
struct PSCacheEntry
|
struct PSCacheEntry
|
||||||
|
@ -61,37 +61,4 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _PIXELSHADERMANAGER_H
|
||||||
class VShaderCache
|
|
||||||
{
|
|
||||||
struct VSCacheEntry
|
|
||||||
{
|
|
||||||
LPDIRECT3DVERTEXSHADER9 shader;
|
|
||||||
//CGVShader shader;
|
|
||||||
int frameCount;
|
|
||||||
VSCacheEntry()
|
|
||||||
{
|
|
||||||
shader=0;
|
|
||||||
frameCount=0;
|
|
||||||
}
|
|
||||||
void Destroy()
|
|
||||||
{
|
|
||||||
if (shader)
|
|
||||||
shader->Release();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<tevhash,VSCacheEntry> VSCache;
|
|
||||||
|
|
||||||
static VSCache vshaders;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void Init();
|
|
||||||
static void Cleanup();
|
|
||||||
static void Shutdown();
|
|
||||||
static void SetShader();
|
|
||||||
};
|
|
||||||
|
|
||||||
void InitCG();
|
|
||||||
void ShutdownCG();
|
|
|
@ -29,7 +29,8 @@
|
||||||
#include "XFStructs.h"
|
#include "XFStructs.h"
|
||||||
#include "D3DPostprocess.h"
|
#include "D3DPostprocess.h"
|
||||||
#include "D3DUtil.h"
|
#include "D3DUtil.h"
|
||||||
#include "ShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
|
#include "PixelShaderManager.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "EmuWindow.h"
|
#include "EmuWindow.h"
|
||||||
|
@ -171,7 +172,8 @@ void Renderer::ReinitView()
|
||||||
xScale = width/640.0f;
|
xScale = width/640.0f;
|
||||||
yScale = height/480.0f;
|
yScale = height/480.0f;
|
||||||
|
|
||||||
RECT rc = {
|
RECT rc =
|
||||||
|
{
|
||||||
(LONG)(m_x*xScale), (LONG)(m_y*yScale), (LONG)(m_width*xScale), (LONG)(m_height*yScale)
|
(LONG)(m_x*xScale), (LONG)(m_y*yScale), (LONG)(m_width*xScale), (LONG)(m_height*yScale)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -198,24 +200,24 @@ void Renderer::SwapBuffers(void)
|
||||||
{
|
{
|
||||||
char st[2048];
|
char st[2048];
|
||||||
char *p = st;
|
char *p = st;
|
||||||
p+=sprintf(p,"Num textures created: %i\n",stats.numTexturesCreated);
|
p+=sprintf(p,"textures created: %i\n",stats.numTexturesCreated);
|
||||||
p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive);
|
p+=sprintf(p,"textures alive: %i\n",stats.numTexturesAlive);
|
||||||
p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated);
|
p+=sprintf(p,"pshaders created: %i\n",stats.numPixelShadersCreated);
|
||||||
p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive);
|
p+=sprintf(p,"pshaders alive: %i\n",stats.numPixelShadersAlive);
|
||||||
p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated);
|
p+=sprintf(p,"vshaders created: %i\n",stats.numVertexShadersCreated);
|
||||||
p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive);
|
p+=sprintf(p,"vshaders alive: %i\n",stats.numVertexShadersAlive);
|
||||||
p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled);
|
p+=sprintf(p,"dlists called: %i\n",stats.numDListsCalled);
|
||||||
p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated);
|
p+=sprintf(p,"dlists created: %i\n",stats.numDListsCreated);
|
||||||
p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive);
|
p+=sprintf(p,"dlists alive: %i\n",stats.numDListsAlive);
|
||||||
p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims);
|
p+=sprintf(p,"primitives: %i\n",stats.thisFrame.numPrims);
|
||||||
p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
|
p+=sprintf(p,"primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
|
||||||
p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims);
|
p+=sprintf(p,"primitives (DL): %i\n",stats.thisFrame.numDLPrims);
|
||||||
p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads);
|
p+=sprintf(p,"XF loads: %i\n",stats.thisFrame.numXFLoads);
|
||||||
p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
|
p+=sprintf(p,"XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
|
||||||
p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads);
|
p+=sprintf(p,"CP loads: %i\n",stats.thisFrame.numCPLoads);
|
||||||
p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
|
p+=sprintf(p,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
|
||||||
p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads);
|
p+=sprintf(p,"BP loads: %i\n",stats.thisFrame.numBPLoads);
|
||||||
p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
|
p+=sprintf(p,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
|
||||||
|
|
||||||
D3D::font.DrawTextScaled(0,30,20,20,0.0f,0xFF00FFFF,st,false);
|
D3D::font.DrawTextScaled(0,30,20,20,0.0f,0xFF00FFFF,st,false);
|
||||||
|
|
||||||
|
@ -280,15 +282,6 @@ void Renderer::SwapBuffers(void)
|
||||||
D3D::font.SetRenderStates(); //compatibility with low end cards
|
D3D::font.SetRenderStates(); //compatibility with low end cards
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Flush(void)
|
|
||||||
{
|
|
||||||
// render the rest of the vertex buffer
|
|
||||||
//only to be used for debugging purposes
|
|
||||||
//D3D::EndFrame();
|
|
||||||
|
|
||||||
//D3D::BeginFrame(false,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::SetViewport(float* _Viewport)
|
void Renderer::SetViewport(float* _Viewport)
|
||||||
{
|
{
|
||||||
Viewport* pViewport = (Viewport*)_Viewport;
|
Viewport* pViewport = (Viewport*)_Viewport;
|
||||||
|
|
|
@ -44,15 +44,13 @@ public:
|
||||||
static void Init(SVideoInitialize &_VideoInitialize);
|
static void Init(SVideoInitialize &_VideoInitialize);
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
// initialize opengl standard values (like view port)
|
|
||||||
static void Initialize(void);
|
static void Initialize(void);
|
||||||
|
|
||||||
// must be called if the window size has changed
|
// must be called if the window size has changed
|
||||||
static void ReinitView(void);
|
static void ReinitView(void);
|
||||||
//
|
|
||||||
// --- Render Functions ---
|
|
||||||
//
|
|
||||||
static void SwapBuffers(void);
|
static void SwapBuffers(void);
|
||||||
static void Flush(void);
|
|
||||||
static float GetXScale() {return xScale;}
|
static float GetXScale() {return xScale;}
|
||||||
static float GetYScale() {return yScale;}
|
static float GetYScale() {return yScale;}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@
|
||||||
#include "IndexGenerator.h"
|
#include "IndexGenerator.h"
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
#include "XFStructs.h"
|
#include "XFStructs.h"
|
||||||
#include "ShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
|
#include "PixelShaderManager.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
using namespace D3D;
|
using namespace D3D;
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
|
||||||
|
// 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, version 2.0.
|
||||||
|
|
||||||
|
// 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 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "D3DBase.h"
|
||||||
|
#include "Statistics.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Profiler.h"
|
||||||
|
#include "VertexShaderManager.h"
|
||||||
|
#include "VertexLoader.h"
|
||||||
|
#include "BPMemory.h"
|
||||||
|
#include "XFMemory.h"
|
||||||
|
|
||||||
|
VShaderCache::VSCache VShaderCache::vshaders;
|
||||||
|
|
||||||
|
void VShaderCache::Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VShaderCache::Shutdown()
|
||||||
|
{
|
||||||
|
VSCache::iterator iter = vshaders.begin();
|
||||||
|
for (; iter != vshaders.end(); iter++)
|
||||||
|
iter->second.Destroy();
|
||||||
|
vshaders.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VShaderCache::SetShader()
|
||||||
|
{
|
||||||
|
static LPDIRECT3DVERTEXSHADER9 shader = NULL;
|
||||||
|
if (D3D::GetShaderVersion() < 2)
|
||||||
|
return; // we are screwed
|
||||||
|
|
||||||
|
if (shader) {
|
||||||
|
//D3D::dev->SetVertexShader(shader);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPDIRECT3DVERTEXSHADER9 lastShader = 0;
|
||||||
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
|
u32 currentHash = 0x1337; // GetCurrentTEV();
|
||||||
|
|
||||||
|
VSCache::iterator iter;
|
||||||
|
iter = vshaders.find(currentHash);
|
||||||
|
|
||||||
|
if (iter != vshaders.end())
|
||||||
|
{
|
||||||
|
iter->second.frameCount=frameCount;
|
||||||
|
VSCacheEntry &entry = iter->second;
|
||||||
|
if (!lastShader || entry.shader != lastShader)
|
||||||
|
{
|
||||||
|
D3D::dev->SetVertexShader(entry.shader);
|
||||||
|
lastShader = entry.shader;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *code = GenerateVertexShader();
|
||||||
|
shader = D3D::CompileVShader(code, int(strlen(code)));
|
||||||
|
if (shader)
|
||||||
|
{
|
||||||
|
//Make an entry in the table
|
||||||
|
VSCacheEntry entry;
|
||||||
|
entry.shader = shader;
|
||||||
|
entry.frameCount=frameCount;
|
||||||
|
vshaders[currentHash] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D::dev->SetVertexShader(shader);
|
||||||
|
|
||||||
|
INCSTAT(stats.numVertexShadersCreated);
|
||||||
|
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void VShaderCache::Cleanup()
|
||||||
|
{
|
||||||
|
for (VSCache::iterator iter=vshaders.begin(); iter!=vshaders.end();)
|
||||||
|
{
|
||||||
|
VSCacheEntry &entry = iter->second;
|
||||||
|
if (entry.frameCount < frameCount - 30)
|
||||||
|
{
|
||||||
|
entry.Destroy();
|
||||||
|
iter = vshaders.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
|
||||||
|
// 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, version 2.0.
|
||||||
|
|
||||||
|
// 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 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#ifndef _VERTEXSHADERMANAGER_H
|
||||||
|
#define _VERTEXSHADERMANAGER_H
|
||||||
|
|
||||||
|
#include "D3DBase.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "PixelShader.h"
|
||||||
|
#include "VertexShader.h"
|
||||||
|
|
||||||
|
class VShaderCache
|
||||||
|
{
|
||||||
|
struct VSCacheEntry
|
||||||
|
{
|
||||||
|
LPDIRECT3DVERTEXSHADER9 shader;
|
||||||
|
int frameCount;
|
||||||
|
VSCacheEntry()
|
||||||
|
{
|
||||||
|
shader = 0;
|
||||||
|
frameCount = 0;
|
||||||
|
}
|
||||||
|
void Destroy()
|
||||||
|
{
|
||||||
|
if (shader)
|
||||||
|
shader->Release();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<u32, VSCacheEntry> VSCache;
|
||||||
|
|
||||||
|
static VSCache vshaders;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void Init();
|
||||||
|
static void Cleanup();
|
||||||
|
static void Shutdown();
|
||||||
|
static void SetShader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _VERTEXSHADERMANAGER_H
|
|
@ -140,7 +140,6 @@ void UpdateFPSDisplay(const char *text)
|
||||||
char temp[512];
|
char temp[512];
|
||||||
sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text);
|
sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text);
|
||||||
OpenGL_SetWindowText(temp);
|
OpenGL_SetWindowText(temp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
|
|
|
@ -38,6 +38,17 @@
|
||||||
#define DEBUG_LOG(...)
|
#define DEBUG_LOG(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
EFB_WIDTH = 640,
|
||||||
|
EFB_HEIGHT = 528,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
XFB_WIDTH = 640,
|
||||||
|
XFB_HEIGHT = 480, // 528 is max height ... ? or 538?
|
||||||
|
// TODO: figure out what to do with PAL
|
||||||
|
};
|
||||||
|
|
||||||
void DebugLog(const char* _fmt, ...);
|
void DebugLog(const char* _fmt, ...);
|
||||||
void __Log(const char *format, ...);
|
void __Log(const char *format, ...);
|
||||||
void __Log(int type, const char *format, ...);
|
void __Log(int type, const char *format, ...);
|
||||||
|
|
|
@ -48,7 +48,25 @@ DECLARE_IMPORT(glColorPointer);
|
||||||
DECLARE_IMPORT(glTexCoordPointer);
|
DECLARE_IMPORT(glTexCoordPointer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NativeVertexFormat::NativeVertexFormat()
|
class GLVertexFormat : public NativeVertexFormat
|
||||||
|
{
|
||||||
|
u8 *m_compiledCode;
|
||||||
|
PortableVertexDeclaration vtx_decl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GLVertexFormat();
|
||||||
|
~GLVertexFormat();
|
||||||
|
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||||
|
virtual void SetupVertexPointers() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
NativeVertexFormat *NativeVertexFormat::Create()
|
||||||
|
{
|
||||||
|
return new GLVertexFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
GLVertexFormat::GLVertexFormat()
|
||||||
{
|
{
|
||||||
#ifdef USE_JIT
|
#ifdef USE_JIT
|
||||||
m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false);
|
m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false);
|
||||||
|
@ -58,7 +76,7 @@ NativeVertexFormat::NativeVertexFormat()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeVertexFormat::~NativeVertexFormat()
|
GLVertexFormat::~GLVertexFormat()
|
||||||
{
|
{
|
||||||
#ifdef USE_JIT
|
#ifdef USE_JIT
|
||||||
FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE);
|
FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE);
|
||||||
|
@ -72,7 +90,7 @@ inline GLuint VarToGL(VarType t)
|
||||||
return lookup[t];
|
return lookup[t];
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||||
{
|
{
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
|
||||||
|
@ -148,7 +166,7 @@ void NativeVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||||
this->vtx_decl = _vtx_decl;
|
this->vtx_decl = _vtx_decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeVertexFormat::SetupVertexPointers() const {
|
void GLVertexFormat::SetupVertexPointers() const {
|
||||||
// Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to
|
// Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to
|
||||||
// get around type checking errors, and call it.
|
// get around type checking errors, and call it.
|
||||||
#ifdef USE_JIT
|
#ifdef USE_JIT
|
||||||
|
|
|
@ -43,17 +43,17 @@
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
#include "XFB.h"
|
#include "XFB.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "Logging/Logging.h" // for Logging()
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
#include "Debugger/Debugger.h" // for the CDebugger class
|
#include "Debugger/Debugger.h" // for the CDebugger class
|
||||||
#endif
|
#endif
|
||||||
#include "Logging/Logging.h" // for Logging()
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "OS/Win32.h"
|
#include "OS/Win32.h"
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
//#define USE_AA
|
|
||||||
#define AA_AMMOUNT 16
|
|
||||||
struct MESSAGE
|
struct MESSAGE
|
||||||
{
|
{
|
||||||
MESSAGE() {}
|
MESSAGE() {}
|
||||||
|
@ -63,31 +63,39 @@ struct MESSAGE
|
||||||
};
|
};
|
||||||
|
|
||||||
CGcontext g_cgcontext;
|
CGcontext g_cgcontext;
|
||||||
CGprofile g_cgvProf, g_cgfProf;
|
CGprofile g_cgvProf;
|
||||||
|
CGprofile g_cgfProf;
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
extern CDebugger* m_frame; // the debugging class
|
extern CDebugger* m_frame; // the debugging class
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int g_MaxTexWidth = 0, g_MaxTexHeight = 0;
|
|
||||||
static RasterFont* s_pfont = NULL;
|
static RasterFont* s_pfont = NULL;
|
||||||
static std::list<MESSAGE> s_listMsgs;
|
static std::list<MESSAGE> s_listMsgs;
|
||||||
|
|
||||||
static bool s_bFullscreen = false;
|
static bool s_bFullscreen = false;
|
||||||
static bool s_bOutputCgErrors = true;
|
static bool s_bOutputCgErrors = true;
|
||||||
|
|
||||||
static int nZBufferRender = 0; // if > 0, then using zbuffer render
|
static int nZBufferRender = 0; // if > 0, then use zbuffer render, and count down.
|
||||||
static u32 s_uFramebuffer = 0;
|
|
||||||
static u32 s_RenderTargets[1] = {0}, s_DepthTarget = 0, s_ZBufferTarget = 0;
|
// A framebuffer is a set of render targets: a color and a z buffer. They can be either RenderBuffers or Textures.
|
||||||
|
static GLuint s_uFramebuffer = 0;
|
||||||
|
|
||||||
|
// The size of these should be a (not necessarily even) multiple of the EFB size, 640x528, but isn't.
|
||||||
|
static GLuint s_RenderTarget = 0;
|
||||||
|
static GLuint s_DepthTarget = 0;
|
||||||
|
static GLuint s_ZBufferTarget = 0;
|
||||||
|
|
||||||
|
static bool s_bATIDrawBuffers = false;
|
||||||
|
static bool s_bHaveStencilBuffer = false;
|
||||||
|
|
||||||
static bool s_bATIDrawBuffers = false, s_bHaveStencilBuffer = false;
|
|
||||||
static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal;
|
static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal;
|
||||||
static int s_nCurTarget = 0;
|
|
||||||
bool g_bBlendLogicOp = false;
|
bool g_bBlendLogicOp = false;
|
||||||
|
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
|
||||||
void HandleCgError(CGcontext ctx, CGerror err, void *appdata);
|
void HandleCgError(CGcontext ctx, CGerror err, void *appdata);
|
||||||
|
|
||||||
bool Renderer::Create2()
|
bool Renderer::Init()
|
||||||
{
|
{
|
||||||
bool bSuccess = true;
|
bool bSuccess = true;
|
||||||
GLenum err = GL_NO_ERROR;
|
GLenum err = GL_NO_ERROR;
|
||||||
|
@ -154,8 +162,11 @@ bool Renderer::Create2()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// check the max texture width and height
|
// check the max texture width and height
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&g_MaxTexWidth);
|
GLint max_texture_size;
|
||||||
g_MaxTexHeight = g_MaxTexWidth;
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&max_texture_size);
|
||||||
|
if (max_texture_size < 1024) {
|
||||||
|
ERROR_LOG("GL_MAX_TEXTURE_SIZE too small at %i - must be at least 1024", max_texture_size);
|
||||||
|
}
|
||||||
|
|
||||||
GL_REPORT_ERROR();
|
GL_REPORT_ERROR();
|
||||||
if (err != GL_NO_ERROR) bSuccess = false;
|
if (err != GL_NO_ERROR) bSuccess = false;
|
||||||
|
@ -171,13 +182,16 @@ bool Renderer::Create2()
|
||||||
_assert_(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT);
|
_assert_(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
|
||||||
|
|
||||||
|
// The size of the framebuffer targets should really NOT be the size of the OpenGL viewport.
|
||||||
|
// The EFB is larger than 640x480 - in fact, it's 640x528, give or take a couple of lines.
|
||||||
|
// So the below is wrong.
|
||||||
int nBackbufferWidth = (int)OpenGL_GetWidth();
|
int nBackbufferWidth = (int)OpenGL_GetWidth();
|
||||||
int nBackbufferHeight = (int)OpenGL_GetHeight();
|
int nBackbufferHeight = (int)OpenGL_GetHeight();
|
||||||
|
|
||||||
// create the framebuffer targets
|
// Create the framebuffer target
|
||||||
glGenTextures(ARRAYSIZE(s_RenderTargets), (GLuint *)s_RenderTargets);
|
glGenTextures(1, (GLuint *)&s_RenderTarget);
|
||||||
for(u32 i = 0; i < ARRAYSIZE(s_RenderTargets); ++i) {
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[i]);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
|
||||||
// initialize to default
|
// initialize to default
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, nBackbufferWidth, nBackbufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, nBackbufferWidth, nBackbufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
@ -189,18 +203,11 @@ bool Renderer::Create2()
|
||||||
}
|
}
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
#ifdef USE_AA
|
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_RenderTargets[i]);
|
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, AA_AMMOUNT, GL_RGBA, nBackbufferWidth, nBackbufferHeight);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
s_nCurTarget = 0;
|
|
||||||
|
|
||||||
GL_REPORT_ERROR();
|
GL_REPORT_ERROR();
|
||||||
|
|
||||||
int nMaxMRT = 0;
|
int nMaxMRT = 0;
|
||||||
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, (GLint *)&nMaxMRT);
|
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, (GLint *)&nMaxMRT);
|
||||||
|
|
||||||
if (nMaxMRT > 1) {
|
if (nMaxMRT > 1) {
|
||||||
// create zbuffer target
|
// create zbuffer target
|
||||||
glGenTextures(1, (GLuint *)&s_ZBufferTarget);
|
glGenTextures(1, (GLuint *)&s_ZBufferTarget);
|
||||||
|
@ -216,20 +223,12 @@ bool Renderer::Create2()
|
||||||
}
|
}
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
#ifdef USE_AA
|
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_ZBufferTarget);
|
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, AA_AMMOUNT, GL_RGBA, nBackbufferWidth, nBackbufferHeight);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the depth buffer
|
// create the depth buffer
|
||||||
glGenRenderbuffersEXT(1, (GLuint *)&s_DepthTarget);
|
glGenRenderbuffersEXT(1, (GLuint *)&s_DepthTarget);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget);
|
||||||
#ifdef USE_AA
|
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, AA_AMMOUNT, GL_DEPTH24_STENCIL8_EXT, nBackbufferWidth, nBackbufferHeight);
|
|
||||||
#else
|
|
||||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, nBackbufferWidth, nBackbufferHeight);
|
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, nBackbufferWidth, nBackbufferHeight);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (glGetError() != GL_NO_ERROR) {
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nBackbufferWidth, nBackbufferHeight);
|
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nBackbufferWidth, nBackbufferHeight);
|
||||||
|
@ -241,15 +240,9 @@ bool Renderer::Create2()
|
||||||
GL_REPORT_ERROR();
|
GL_REPORT_ERROR();
|
||||||
|
|
||||||
// set as render targets
|
// set as render targets
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[s_nCurTarget], 0 );
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget, 0);
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget);
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget);
|
||||||
|
|
||||||
#ifdef USE_AA
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_RenderTargets[s_nCurTarget]);
|
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_RenderTargets[s_nCurTarget]);
|
|
||||||
|
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget);
|
|
||||||
#endif
|
|
||||||
GL_REPORT_ERROR();
|
GL_REPORT_ERROR();
|
||||||
|
|
||||||
if (s_ZBufferTarget != 0) {
|
if (s_ZBufferTarget != 0) {
|
||||||
|
@ -278,9 +271,6 @@ bool Renderer::Create2()
|
||||||
|
|
||||||
s_pfont = new RasterFont();
|
s_pfont = new RasterFont();
|
||||||
|
|
||||||
SetAA(g_Config.iMultisampleMode);
|
|
||||||
GL_REPORT_ERROR();
|
|
||||||
|
|
||||||
// load the effect, find the best profiles (if any)
|
// load the effect, find the best profiles (if any)
|
||||||
if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) {
|
if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) {
|
||||||
ERROR_LOG("arbvp1 not supported\n");
|
ERROR_LOG("arbvp1 not supported\n");
|
||||||
|
@ -292,7 +282,7 @@ bool Renderer::Create2()
|
||||||
}
|
}
|
||||||
|
|
||||||
g_cgvProf = cgGLGetLatestProfile(CG_GL_VERTEX);
|
g_cgvProf = cgGLGetLatestProfile(CG_GL_VERTEX);
|
||||||
g_cgfProf = cgGLGetLatestProfile(CG_GL_FRAGMENT);//CG_PROFILE_ARBFP1;
|
g_cgfProf = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
||||||
cgGLSetOptimalOptions(g_cgvProf);
|
cgGLSetOptimalOptions(g_cgvProf);
|
||||||
cgGLSetOptimalOptions(g_cgfProf);
|
cgGLSetOptimalOptions(g_cgfProf);
|
||||||
|
|
||||||
|
@ -317,10 +307,9 @@ bool Renderer::Create2()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//glEnable(GL_POLYGON_OFFSET_FILL);
|
s_RenderMode = Renderer::RM_Normal;
|
||||||
//glEnable(GL_POLYGON_OFFSET_LINE);
|
|
||||||
//glPolygonOffset(0, 1);
|
if (!InitializeGL())
|
||||||
if (!Initialize())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
XFB_Init();
|
XFB_Init();
|
||||||
|
@ -334,26 +323,25 @@ void Renderer::Shutdown(void)
|
||||||
|
|
||||||
XFB_Shutdown();
|
XFB_Shutdown();
|
||||||
|
|
||||||
if (g_cgcontext != 0) {
|
if (g_cgcontext) {
|
||||||
cgDestroyContext(g_cgcontext);
|
cgDestroyContext(g_cgcontext);
|
||||||
g_cgcontext = 0;
|
g_cgcontext = 0;
|
||||||
}
|
}
|
||||||
|
if (s_RenderTarget) {
|
||||||
if (s_RenderTargets[0]) {
|
glDeleteTextures(1, &s_RenderTarget);
|
||||||
glDeleteTextures(ARRAYSIZE(s_RenderTargets), (GLuint *)s_RenderTargets);
|
s_RenderTarget = 0;
|
||||||
memset(s_RenderTargets, 0, sizeof(s_RenderTargets));
|
|
||||||
}
|
}
|
||||||
if (s_DepthTarget) {
|
if (s_DepthTarget) {
|
||||||
glDeleteRenderbuffersEXT(1, (GLuint *)&s_DepthTarget); s_DepthTarget = 0;
|
glDeleteRenderbuffersEXT(1, &s_DepthTarget);
|
||||||
|
s_DepthTarget = 0;
|
||||||
}
|
}
|
||||||
if (s_uFramebuffer != 0) {
|
if (s_uFramebuffer) {
|
||||||
glDeleteFramebuffersEXT( 1, (GLuint *)&s_uFramebuffer);
|
glDeleteFramebuffersEXT(1, &s_uFramebuffer);
|
||||||
s_uFramebuffer = 0;
|
s_uFramebuffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Renderer::InitializeGL()
|
||||||
bool Renderer::Initialize()
|
|
||||||
{
|
{
|
||||||
glStencilFunc(GL_ALWAYS, 0, 0);
|
glStencilFunc(GL_ALWAYS, 0, 0);
|
||||||
glBlendFunc(GL_ONE, GL_ONE);
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
|
@ -394,8 +382,6 @@ bool Renderer::Initialize()
|
||||||
glClientActiveTexture(GL_TEXTURE0);
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
|
||||||
s_RenderMode = Renderer::RM_Normal;
|
|
||||||
|
|
||||||
GLenum err = GL_NO_ERROR;
|
GLenum err = GL_NO_ERROR;
|
||||||
GL_REPORT_ERROR();
|
GL_REPORT_ERROR();
|
||||||
|
|
||||||
|
@ -455,11 +441,6 @@ void Renderer::RenderText(const char* pstr, int left, int top, u32 color)
|
||||||
s_pfont->printMultilineText(pstr, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight,0,nBackbufferWidth,nBackbufferHeight);
|
s_pfont->printMultilineText(pstr, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight,0,nBackbufferWidth,nBackbufferHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetAA(int aa)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::ReinitView(int nNewWidth, int nNewHeight)
|
void Renderer::ReinitView(int nNewWidth, int nNewHeight)
|
||||||
{
|
{
|
||||||
int oldscreen = s_bFullscreen;
|
int oldscreen = s_bFullscreen;
|
||||||
|
@ -499,6 +480,7 @@ void Renderer::ReinitView(int nNewWidth, int nNewHeight)
|
||||||
OpenGL_SetSize(nNewWidth > 16 ? nNewWidth : 16,
|
OpenGL_SetSize(nNewWidth > 16 ? nNewWidth : 16,
|
||||||
nNewHeight > 16 ? nNewHeight : 16);
|
nNewHeight > 16 ? nNewHeight : 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Renderer::GetTargetWidth()
|
int Renderer::GetTargetWidth()
|
||||||
{
|
{
|
||||||
return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth());
|
return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth());
|
||||||
|
@ -514,24 +496,32 @@ bool Renderer::CanBlendLogicOp()
|
||||||
return g_bBlendLogicOp;
|
return g_bBlendLogicOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetRenderTarget(u32 targ)
|
void Renderer::SetRenderTarget(GLuint targ)
|
||||||
{
|
{
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, targ!=0?targ:s_RenderTargets[s_nCurTarget], 0 );
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,
|
||||||
|
targ != 0 ? targ : s_RenderTarget, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetDepthTarget(u32 targ)
|
void Renderer::SetDepthTarget(GLuint targ)
|
||||||
{
|
{
|
||||||
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, targ != 0 ? targ : s_DepthTarget );
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
|
||||||
|
targ != 0 ? targ : s_DepthTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetFramebuffer(u32 fb)
|
void Renderer::SetFramebuffer(GLuint fb)
|
||||||
{
|
{
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : s_uFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
|
||||||
|
fb != 0 ? fb : s_uFramebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Renderer::GetRenderTarget()
|
GLuint Renderer::GetRenderTarget()
|
||||||
{
|
{
|
||||||
return s_RenderTargets[s_nCurTarget];
|
return s_RenderTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint Renderer::GetZBufferTarget()
|
||||||
|
{
|
||||||
|
return nZBufferRender > 0 ? s_ZBufferTarget : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::ResetGLState()
|
void Renderer::ResetGLState()
|
||||||
|
@ -571,8 +561,6 @@ void Renderer::SetColorMask()
|
||||||
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
|
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
|
||||||
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
|
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
|
||||||
// case 0x52 > SetScissorRect()
|
// case 0x52 > SetScissorRect()
|
||||||
// ---------------
|
// ---------------
|
||||||
|
@ -581,7 +569,6 @@ void Renderer::SetColorMask()
|
||||||
// bpmem.scissorTL.x, y = 342x342
|
// bpmem.scissorTL.x, y = 342x342
|
||||||
// bpmem.scissorBR.x, y = 981x821
|
// bpmem.scissorBR.x, y = 981x821
|
||||||
// Renderer::GetTargetHeight() = the fixed ini file setting
|
// Renderer::GetTargetHeight() = the fixed ini file setting
|
||||||
// ---------------
|
|
||||||
bool Renderer::SetScissorRect()
|
bool Renderer::SetScissorRect()
|
||||||
{
|
{
|
||||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
||||||
|
@ -624,7 +611,6 @@ bool Renderer::SetScissorRect()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Renderer::IsUsingATIDrawBuffers()
|
bool Renderer::IsUsingATIDrawBuffers()
|
||||||
{
|
{
|
||||||
return s_bATIDrawBuffers;
|
return s_bATIDrawBuffers;
|
||||||
|
@ -670,14 +656,17 @@ void Renderer::FlushZBufferAlphaToTarget()
|
||||||
glStencilFunc(GL_EQUAL, 1, 0xff);
|
glStencilFunc(GL_EQUAL, 1, 0xff);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
|
||||||
|
// TODO: This code should not have to bother with stretchtofit checking -
|
||||||
|
// all necessary scale initialization should be done elsewhere.
|
||||||
|
// TODO: Investigate BlitFramebufferEXT.
|
||||||
if (g_Config.bStretchToFit)
|
if (g_Config.bStretchToFit)
|
||||||
{
|
{
|
||||||
//TODO: Do Correctly in a bit
|
//TODO: Do Correctly in a bit
|
||||||
float FactorW = (float)640 / (float)OpenGL_GetWidth();
|
float FactorW = 640.f / (float)OpenGL_GetWidth();
|
||||||
float FactorH = (float)480 / (float)OpenGL_GetHeight();
|
float FactorH = 480.f / (float)OpenGL_GetHeight();
|
||||||
|
|
||||||
float Max = (FactorW < FactorH) ? FactorH : FactorW;
|
float Max = (FactorW < FactorH) ? FactorH : FactorW;
|
||||||
float Temp = 1 / Max;
|
float Temp = 1.0f / Max;
|
||||||
FactorW *= Temp;
|
FactorW *= Temp;
|
||||||
FactorH *= Temp;
|
FactorH *= Temp;
|
||||||
|
|
||||||
|
@ -686,8 +675,7 @@ void Renderer::FlushZBufferAlphaToTarget()
|
||||||
glTexCoord2f(0, (float)GetTargetHeight()); glVertex2f(-FactorW,FactorH);
|
glTexCoord2f(0, (float)GetTargetHeight()); glVertex2f(-FactorW,FactorH);
|
||||||
glTexCoord2f((float)GetTargetWidth(), (float)GetTargetHeight()); glVertex2f(FactorW,FactorH);
|
glTexCoord2f((float)GetTargetWidth(), (float)GetTargetHeight()); glVertex2f(FactorW,FactorH);
|
||||||
glTexCoord2f((float)GetTargetWidth(), 0); glVertex2f(FactorW,-FactorH);
|
glTexCoord2f((float)GetTargetWidth(), 0); glVertex2f(FactorW,-FactorH);
|
||||||
|
glEnd();
|
||||||
__Log("%d, %d", FactorW, FactorH);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -696,8 +684,8 @@ void Renderer::FlushZBufferAlphaToTarget()
|
||||||
glTexCoord2f(0, (float)(GetTargetHeight())); glVertex2f(-1,1);
|
glTexCoord2f(0, (float)(GetTargetHeight())); glVertex2f(-1,1);
|
||||||
glTexCoord2f((float)(GetTargetWidth()), (float)(GetTargetHeight())); glVertex2f(1,1);
|
glTexCoord2f((float)(GetTargetWidth()), (float)(GetTargetHeight())); glVertex2f(1,1);
|
||||||
glTexCoord2f((float)(GetTargetWidth()), 0); glVertex2f(1,-1);
|
glTexCoord2f((float)(GetTargetWidth()), 0); glVertex2f(1,-1);
|
||||||
}
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
@ -774,11 +762,6 @@ Renderer::RenderMode Renderer::GetRenderMode()
|
||||||
return s_RenderMode;
|
return s_RenderMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Renderer::GetZBufferTarget()
|
|
||||||
{
|
|
||||||
return nZBufferRender > 0 ? s_ZBufferTarget : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::Swap(const TRectangle& rc)
|
void Renderer::Swap(const TRectangle& rc)
|
||||||
{
|
{
|
||||||
OpenGL_Update(); // just updates the render window position and the backbuffer size
|
OpenGL_Update(); // just updates the render window position and the backbuffer size
|
||||||
|
@ -787,22 +770,27 @@ void Renderer::Swap(const TRectangle& rc)
|
||||||
|
|
||||||
Renderer::SetRenderMode(Renderer::RM_Normal);
|
Renderer::SetRenderMode(Renderer::RM_Normal);
|
||||||
|
|
||||||
// render to the real buffer now
|
#if 0
|
||||||
#ifdef USE_AA
|
// Not working?
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_RenderTargets[0]);
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer);
|
||||||
|
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||||
|
glBlitFramebufferEXT(0, 0, 640, 480, 0, 0, OpenGL_GetWidth(), OpenGL_GetHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
// render to the real buffer now
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer
|
||||||
#endif
|
|
||||||
glViewport(OpenGL_GetXoff(), OpenGL_GetYoff(), (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight());
|
glViewport(OpenGL_GetXoff(), OpenGL_GetYoff(), (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight());
|
||||||
|
|
||||||
ResetGLState();
|
ResetGLState();
|
||||||
|
|
||||||
// texture map s_RenderTargets[s_curtarget] onto the main buffer
|
// texture map s_RenderTargets[s_curtarget] onto the main buffer
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[s_nCurTarget]);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
|
||||||
TextureMngr::EnableTexRECT(0);
|
TextureMngr::EnableTexRECT(0);
|
||||||
// disable all other stages
|
// disable all other stages
|
||||||
for(int i = 1; i < 8; ++i) TextureMngr::DisableStage(i);
|
for (int i = 1; i < 8; ++i)
|
||||||
|
TextureMngr::DisableStage(i);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
@ -822,12 +810,6 @@ void Renderer::Swap(const TRectangle& rc)
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
|
|
||||||
RestoreGLState();
|
RestoreGLState();
|
||||||
#ifdef USE_AA
|
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_RenderTargets[s_nCurTarget]);
|
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
|
||||||
glBlitFramebufferEXT(0, 0, nBackbufferWidth, nBackbufferHeight, 0, 0, nBackbufferWidth, nBackbufferHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
|
||||||
#endif
|
#endif
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
@ -854,40 +836,37 @@ void Renderer::SwapBuffers()
|
||||||
// Write logging data to debugger
|
// Write logging data to debugger
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
if (m_frame)
|
if (m_frame)
|
||||||
{
|
|
||||||
Logging(0);
|
Logging(0);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (g_Config.bOverlayStats) {
|
if (g_Config.bOverlayStats) {
|
||||||
char st[2048];
|
char st[2048];
|
||||||
char *p = st;
|
char *p = st;
|
||||||
if (g_Config.bShowFPS)
|
if (g_Config.bShowFPS)
|
||||||
p+=sprintf(p, "FPS: %d\n", s_fps); // So it shows up before the stats and doesn't make anyting ugly
|
p+=sprintf(p, "FPS: %d\n", s_fps); // So it shows up before the stats and doesn't make anyting ugly
|
||||||
p+=sprintf(p,"Num textures created: %i\n",stats.numTexturesCreated);
|
p+=sprintf(p,"textures created: %i\n",stats.numTexturesCreated);
|
||||||
p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive);
|
p+=sprintf(p,"textures alive: %i\n",stats.numTexturesAlive);
|
||||||
p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated);
|
p+=sprintf(p,"pshaders created: %i\n",stats.numPixelShadersCreated);
|
||||||
p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive);
|
p+=sprintf(p,"pshaders alive: %i\n",stats.numPixelShadersAlive);
|
||||||
p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated);
|
p+=sprintf(p,"vshaders created: %i\n",stats.numVertexShadersCreated);
|
||||||
p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive);
|
p+=sprintf(p,"vshaders alive: %i\n",stats.numVertexShadersAlive);
|
||||||
p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled);
|
p+=sprintf(p,"dlists called: %i\n",stats.numDListsCalled);
|
||||||
p+=sprintf(p,"Num dlists called (frame): %i\n",stats.thisFrame.numDListsCalled);
|
p+=sprintf(p,"dlists called(f): %i\n",stats.thisFrame.numDListsCalled);
|
||||||
// not used.
|
// not used.
|
||||||
//p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated);
|
//p+=sprintf(p,"dlists created: %i\n",stats.numDListsCreated);
|
||||||
//p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive);
|
//p+=sprintf(p,"dlists alive: %i\n",stats.numDListsAlive);
|
||||||
//p+=sprintf(p,"Num strip joins: %i\n",stats.numJoins);
|
//p+=sprintf(p,"strip joins: %i\n",stats.numJoins);
|
||||||
p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims);
|
p+=sprintf(p,"primitives: %i\n",stats.thisFrame.numPrims);
|
||||||
p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
|
p+=sprintf(p,"primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
|
||||||
p+=sprintf(p,"Num buffer splits: %i\n",stats.thisFrame.numBufferSplits);
|
p+=sprintf(p,"buffer splits: %i\n",stats.thisFrame.numBufferSplits);
|
||||||
p+=sprintf(p,"Num draw calls: %i\n",stats.thisFrame.numDrawCalls);
|
p+=sprintf(p,"draw calls: %i\n",stats.thisFrame.numDrawCalls);
|
||||||
p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims);
|
p+=sprintf(p,"primitives (DL): %i\n",stats.thisFrame.numDLPrims);
|
||||||
p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads);
|
p+=sprintf(p,"XF loads: %i\n",stats.thisFrame.numXFLoads);
|
||||||
p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
|
p+=sprintf(p,"XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
|
||||||
p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads);
|
p+=sprintf(p,"CP loads: %i\n",stats.thisFrame.numCPLoads);
|
||||||
p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
|
p+=sprintf(p,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
|
||||||
p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads);
|
p+=sprintf(p,"BP loads: %i\n",stats.thisFrame.numBPLoads);
|
||||||
p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
|
p+=sprintf(p,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
|
||||||
p+=sprintf(p,"Num vertex loaders: %i\n",stats.numVertexLoaders);
|
p+=sprintf(p,"vertex loaders: %i\n",stats.numVertexLoaders);
|
||||||
|
|
||||||
|
|
||||||
std::string text = st;
|
std::string text = st;
|
||||||
VertexLoaderManager::AppendListToString(&text);
|
VertexLoaderManager::AppendListToString(&text);
|
||||||
|
@ -928,13 +907,14 @@ void Renderer::SwapBuffers()
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
//clean out old stuff from caches
|
//clean out old stuff from caches
|
||||||
frameCount++;
|
|
||||||
PixelShaderMngr::Cleanup();
|
PixelShaderMngr::Cleanup();
|
||||||
TextureMngr::Cleanup();
|
TextureMngr::Cleanup();
|
||||||
|
|
||||||
|
frameCount++;
|
||||||
// New frame
|
// New frame
|
||||||
stats.ResetFrame();
|
stats.ResetFrame();
|
||||||
|
|
||||||
|
// Render to the framebuffer.
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
|
||||||
|
|
||||||
if (nZBufferRender > 0) {
|
if (nZBufferRender > 0) {
|
||||||
|
|
|
@ -15,6 +15,55 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
// How the non-true-XFB mode COULD work:
|
||||||
|
//
|
||||||
|
// The game renders to the EFB:
|
||||||
|
//
|
||||||
|
// ----------------------+
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | | efb_height
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | - - - - - - - - - - |
|
||||||
|
// | |
|
||||||
|
// +---------------------+
|
||||||
|
// efb_width
|
||||||
|
//
|
||||||
|
// At XFB blit time, the top 640-xxx X XXX part of the above buffer (size dotted below),
|
||||||
|
// should be stretch blitted into the inner rectangle of the window:
|
||||||
|
// +-----------------------------------------+
|
||||||
|
// | | | |
|
||||||
|
// | | . | |
|
||||||
|
// | | | |
|
||||||
|
// | | . | |
|
||||||
|
// | | | |
|
||||||
|
// | | . | | OpenGL_Height()
|
||||||
|
// | | | |
|
||||||
|
// | | . | |
|
||||||
|
// | | - - - - - - - - - - | |
|
||||||
|
// | | \ | |
|
||||||
|
// +-------+---------------------------------+
|
||||||
|
// OpenGL_Width()
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// efb_width and efb_height can even be adjusted so that the last blit will result
|
||||||
|
// in a 1:1 rather than a stretch. That would require creating a bigger efb from the
|
||||||
|
// start though.
|
||||||
|
//
|
||||||
|
// The above is not how it works today.
|
||||||
|
|
||||||
|
/*
|
||||||
|
int win_w = OpenGL_Width();
|
||||||
|
int win_h = OpenGL_Height();
|
||||||
|
|
||||||
|
int blit_w_640 = last_xfb_specified_width;
|
||||||
|
int blit_h_640 = last_xfb_specified_height;
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef GCOGL_RENDER
|
#ifndef GCOGL_RENDER
|
||||||
#define GCOGL_RENDER
|
#define GCOGL_RENDER
|
||||||
|
|
||||||
|
@ -37,20 +86,19 @@ public:
|
||||||
{
|
{
|
||||||
RM_Normal=0, // normal target as color0, ztarget as color1
|
RM_Normal=0, // normal target as color0, ztarget as color1
|
||||||
RM_ZBufferOnly, // zbuffer as color0
|
RM_ZBufferOnly, // zbuffer as color0
|
||||||
RM_ZBufferAlpha // zbuffer as color0, also will dump alpha info to regular target once mode is switched
|
RM_ZBufferAlpha, // zbuffer as color0, also will dump alpha info to regular target once mode is switched
|
||||||
// use stencil buffer to indicate what pixels were written
|
// use stencil buffer to indicate what pixels were written
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool Create2();
|
static bool Init();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
// initialize opengl standard values (like viewport)
|
// initialize opengl standard values (like viewport)
|
||||||
static bool Initialize();
|
static bool InitializeGL();
|
||||||
|
|
||||||
static void AddMessage(const char* str, u32 ms);
|
static void AddMessage(const char* str, u32 ms);
|
||||||
static void ProcessMessages(); // draw the current messages on the screen
|
static void ProcessMessages(); // draw the current messages on the screen
|
||||||
static void RenderText(const char* pstr, int left, int top, u32 color);
|
static void RenderText(const char* pstr, int left, int top, u32 color);
|
||||||
static void SetAA(int aa); // sets the anti-aliasing level
|
|
||||||
|
|
||||||
static void ReinitView(int nNewWidth, int nNewHeight);
|
static void ReinitView(int nNewWidth, int nNewHeight);
|
||||||
|
|
||||||
|
@ -65,7 +113,7 @@ public:
|
||||||
static bool HaveStencilBuffer();
|
static bool HaveStencilBuffer();
|
||||||
|
|
||||||
static void SetZBufferRender(); // sets rendering of the zbuffer using MRTs
|
static void SetZBufferRender(); // sets rendering of the zbuffer using MRTs
|
||||||
static u32 GetZBufferTarget();
|
static GLuint GetZBufferTarget();
|
||||||
|
|
||||||
static void SetColorMask();
|
static void SetColorMask();
|
||||||
static bool SetScissorRect();
|
static bool SetScissorRect();
|
||||||
|
@ -73,10 +121,12 @@ public:
|
||||||
static void SetRenderMode(RenderMode mode);
|
static void SetRenderMode(RenderMode mode);
|
||||||
static RenderMode GetRenderMode();
|
static RenderMode GetRenderMode();
|
||||||
|
|
||||||
static void SetRenderTarget(u32 targ); // if targ is 0, sets to original render target
|
static void SetRenderTarget(GLuint targ); // if targ is 0, sets to original render target
|
||||||
static void SetDepthTarget(u32 targ);
|
static void SetDepthTarget(GLuint targ);
|
||||||
static void SetFramebuffer(u32 fb);
|
|
||||||
static u32 GetRenderTarget();
|
static void SetFramebuffer(GLuint fb);
|
||||||
|
|
||||||
|
static GLuint GetRenderTarget();
|
||||||
|
|
||||||
// Finish up the current frame, print some stats
|
// Finish up the current frame, print some stats
|
||||||
static void Swap(const TRectangle& rc);
|
static void Swap(const TRectangle& rc);
|
||||||
|
|
|
@ -120,7 +120,7 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr)
|
||||||
m_numLoadedVertices = 0;
|
m_numLoadedVertices = 0;
|
||||||
m_VertexSize = 0;
|
m_VertexSize = 0;
|
||||||
m_numPipelineStages = 0;
|
m_numPipelineStages = 0;
|
||||||
m_NativeFmt = new NativeVertexFormat();
|
m_NativeFmt = NativeVertexFormat::Create();
|
||||||
loop_counter = 0;
|
loop_counter = 0;
|
||||||
VertexLoader_Normal::Init();
|
VertexLoader_Normal::Init();
|
||||||
|
|
||||||
|
|
|
@ -348,6 +348,7 @@ void VertexShaderMngr::SetConstants()
|
||||||
// [3] = xorig + width/2 + 342
|
// [3] = xorig + width/2 + 342
|
||||||
// [4] = yorig + height/2 + 342
|
// [4] = yorig + height/2 + 342
|
||||||
// [5] = 16777215 * farz
|
// [5] = 16777215 * farz
|
||||||
|
|
||||||
/*INFO_LOG("view: topleft=(%f,%f), wh=(%f,%f), z=(%f,%f)\n",
|
/*INFO_LOG("view: topleft=(%f,%f), wh=(%f,%f), z=(%f,%f)\n",
|
||||||
rawViewport[3]-rawViewport[0]-342, rawViewport[4]+rawViewport[1]-342,
|
rawViewport[3]-rawViewport[0]-342, rawViewport[4]+rawViewport[1]-342,
|
||||||
2 * rawViewport[0], 2 * rawViewport[1],
|
2 * rawViewport[0], 2 * rawViewport[1],
|
||||||
|
@ -363,6 +364,7 @@ void VertexShaderMngr::SetConstants()
|
||||||
int overfl;
|
int overfl;
|
||||||
int xoffs = 0, yoffs = 0;
|
int xoffs = 0, yoffs = 0;
|
||||||
int wid, hei, actualWid, actualHei;
|
int wid, hei, actualWid, actualHei;
|
||||||
|
|
||||||
int winw = OpenGL_GetWidth();
|
int winw = OpenGL_GetWidth();
|
||||||
int winh = OpenGL_GetHeight();
|
int winh = OpenGL_GetHeight();
|
||||||
float ratio = (float)winw / (float)winh / fourThree;
|
float ratio = (float)winw / (float)winh / fourThree;
|
||||||
|
@ -421,6 +423,7 @@ void VertexShaderMngr::SetConstants()
|
||||||
Renderer::GetTargetHeight()-((int)(xfregs.rawViewport[4]-xfregs.rawViewport[1]-342-scissorYOff)) * MValueY,
|
Renderer::GetTargetHeight()-((int)(xfregs.rawViewport[4]-xfregs.rawViewport[1]-342-scissorYOff)) * MValueY,
|
||||||
abs((int)(2 * xfregs.rawViewport[0])) * MValueX, abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
|
abs((int)(2 * xfregs.rawViewport[0])) * MValueX, abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f);
|
glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
#define XFB_USE_SHADERS 1
|
#define XFB_USE_SHADERS 1
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
XFB_WIDTH = 640,
|
|
||||||
XFB_HEIGHT = 480, // 528 is max height.
|
|
||||||
XFB_BUF_HEIGHT = 538, //480,
|
XFB_BUF_HEIGHT = 538, //480,
|
||||||
// TODO: figure out what to do with PAL
|
// TODO: figure out what to do with PAL
|
||||||
};
|
};
|
||||||
|
@ -145,10 +143,9 @@ void XFB_Shutdown()
|
||||||
void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt)
|
void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt)
|
||||||
{
|
{
|
||||||
Renderer::SetRenderMode(Renderer::RM_Normal);
|
Renderer::SetRenderMode(Renderer::RM_Normal);
|
||||||
|
|
||||||
Renderer::ResetGLState();
|
Renderer::ResetGLState();
|
||||||
|
|
||||||
// switch to XFB frame buffer
|
// Switch to XFB frame buffer.
|
||||||
Renderer::SetFramebuffer(s_xfbFrameBuffer);
|
Renderer::SetFramebuffer(s_xfbFrameBuffer);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);
|
||||||
|
|
|
@ -262,8 +262,8 @@ void Video_DoState(unsigned char **ptr, int mode) {
|
||||||
void Video_Prepare(void)
|
void Video_Prepare(void)
|
||||||
{
|
{
|
||||||
OpenGL_MakeCurrent();
|
OpenGL_MakeCurrent();
|
||||||
if (!Renderer::Create2()) {
|
if (!Renderer::Init()) {
|
||||||
g_VideoInitialize.pLog("Renderer::Create2 failed\n", TRUE);
|
g_VideoInitialize.pLog("Renderer::Create failed\n", TRUE);
|
||||||
PanicAlert("Can't create opengl renderer. You might be missing some required opengl extensions, check the logs for more info");
|
PanicAlert("Can't create opengl renderer. You might be missing some required opengl extensions, check the logs for more info");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue