summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorhrydgard <hrydgard@gmail.com>2008-12-25 15:56:36 +0000
committerhrydgard <hrydgard@gmail.com>2008-12-25 15:56:36 +0000
commitdcc48d6c417192dec95aa0d0562d6cc2f3cfa18a (patch)
treef64ccb07691d1df7c508403421655d882086b49d /Source
parent3fd665502e7956ebd97391c0f4cc907d70358968 (diff)
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
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Common/Src/DynamicLibrary.cpp41
-rw-r--r--Source/Core/Common/Src/DynamicLibrary.h26
-rw-r--r--Source/Core/Common/Src/MsgHandler.cpp58
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp18
-rw-r--r--Source/Core/Core/Src/MemTools.cpp5
-rw-r--r--Source/Core/DolphinWX/Src/PluginManager.cpp13
-rw-r--r--Source/Core/VideoCommon/Src/NativeVertexFormat.h14
-rw-r--r--Source/Core/VideoCommon/Src/XFBConvert.h8
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj20
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp145
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp3
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/PixelShaderManager.cpp (renamed from Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.cpp)352
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/PixelShaderManager.h (renamed from Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.h)161
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/Render.cpp53
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/Render.h18
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp3
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/VertexShaderManager.cpp110
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/VertexShaderManager.h57
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp4
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp11
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/Globals.h11
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp26
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/Render.cpp350
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/Render.h74
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp2
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp15
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp17
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/main.cpp4
28 files changed, 944 insertions, 675 deletions
diff --git a/Source/Core/Common/Src/DynamicLibrary.cpp b/Source/Core/Common/Src/DynamicLibrary.cpp
index 84d9816f1d..b3c7faf728 100644
--- a/Source/Core/Common/Src/DynamicLibrary.cpp
+++ b/Source/Core/Common/Src/DynamicLibrary.cpp
@@ -24,6 +24,7 @@
#endif
#include "Common.h"
+#include "FileUtil.h"
#include "StringUtil.h"
#include "DynamicLibrary.h"
@@ -32,11 +33,10 @@ DynamicLibrary::DynamicLibrary()
library = 0;
}
-
std::string GetLastErrorAsString()
{
#ifdef _WIN32
- LPVOID lpMsgBuf = 0;
+ LPVOID lpMsgBuf = 0;
DWORD error = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
@@ -64,13 +64,11 @@ std::string GetLastErrorAsString()
#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
- before opening the Config and Debugging windows from Plugin.cpp and
- before opening the dll for running the emulation in Video_...cpp in Core. */
-// -----------------------
+// 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
+// before opening the Config and Debugging windows from Plugin.cpp and
+// before opening the dll for running the emulation in Video_...cpp in Core.
+// Since this is fairly slow, TODO: think about implementing some sort of cache.
int DynamicLibrary::Load(const char* filename)
{
if (!filename || strlen(filename) == 0)
@@ -80,7 +78,6 @@ int DynamicLibrary::Load(const char* filename)
return 0;
}
LOG(MASTER_LOG, "Trying to load library %s", filename);
-
if (IsLoaded())
{
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);
#endif
- if (!library) {
+ if (!library)
+ {
LOG(MASTER_LOG, "Error loading DLL %s: %s", filename, GetLastErrorAsString().c_str());
- PanicAlert("Error loading DLL %s: %s\n", 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());
+ }
return 0;
}
@@ -108,11 +113,9 @@ int DynamicLibrary::Unload()
{
int retval;
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());
return 0;
}
-
#ifdef _WIN32
retval = FreeLibrary(library);
@@ -120,8 +123,6 @@ int DynamicLibrary::Unload()
retval = dlclose(library)?0:1;
#endif
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(),
GetLastErrorAsString().c_str());
}
@@ -135,8 +136,8 @@ void* DynamicLibrary::Get(const char* funcname) const
void* retval;
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
retval = GetProcAddress(library, funcname);
@@ -145,8 +146,8 @@ void* DynamicLibrary::Get(const char* funcname) const
#endif
if (!retval) {
- LOG(MASTER_LOG, "Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
- PanicAlert("Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
+ LOG(MASTER_LOG, "Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
+ PanicAlert("Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
}
return retval;
diff --git a/Source/Core/Common/Src/DynamicLibrary.h b/Source/Core/Common/Src/DynamicLibrary.h
index 86718b4ce2..5dd47b8575 100644
--- a/Source/Core/Common/Src/DynamicLibrary.h
+++ b/Source/Core/Common/Src/DynamicLibrary.h
@@ -24,23 +24,23 @@
#include <string>
+// Abstracts the (few) differences between dynamically loading DLLs under Windows
+// and .so / .dylib under Linux/MacOSX.
class DynamicLibrary
{
- public:
-
- DynamicLibrary();
- int Load(const char* filename);
- int Unload();
- void* Get(const char* funcname) const;
-
- bool IsLoaded() const {return(library != 0);}
-
- private:
- std::string library_file;
+public:
+ DynamicLibrary();
+ int Load(const char *filename);
+ int Unload();
+ void *Get(const char *funcname) const;
+ bool IsLoaded() const { return library != 0; }
+
+private:
+ std::string library_file;
#ifdef _WIN32
- HINSTANCE library;
+ HINSTANCE library;
#else
- void* library;
+ void *library;
#endif
};
diff --git a/Source/Core/Common/Src/MsgHandler.cpp b/Source/Core/Common/Src/MsgHandler.cpp
index 9485c31b23..c3a9cae59d 100644
--- a/Source/Core/Common/Src/MsgHandler.cpp
+++ b/Source/Core/Common/Src/MsgHandler.cpp
@@ -24,44 +24,44 @@ bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no);
static MsgAlertHandler msg_handler = DefaultMsgHandler;
-void RegisterMsgAlertHandler(MsgAlertHandler handler) {
- msg_handler = handler;
+void RegisterMsgAlertHandler(MsgAlertHandler handler)
+{
+ msg_handler = handler;
}
-bool MsgAlert(const char* caption, bool yes_no,
- const char* format, ...) {
-
- char buffer[2048];
- va_list args;
- bool ret = false;
+bool MsgAlert(const char* caption, bool yes_no, const char* format, ...)
+{
+ char buffer[2048];
+ va_list args;
+ bool ret = false;
- va_start(args, format);
- CharArrayFromFormatV(buffer, 2048, format, args);
+ va_start(args, format);
+ CharArrayFromFormatV(buffer, 2048, format, args);
- LOG(MASTER_LOG, "%s: %s", caption, buffer);
+ LOG(MASTER_LOG, "%s: %s", caption, buffer);
- if (msg_handler) {
- ret = msg_handler(caption, buffer, yes_no);
- }
-
- va_end(args);
- return ret;
-}
+ if (msg_handler)
+ {
+ ret = msg_handler(caption, buffer, yes_no);
+ }
-bool DefaultMsgHandler(const char* caption, const char* text,
- bool yes_no) {
+ va_end(args);
+ return ret;
+}
+bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no)
+{
#ifdef _WIN32
- if (yes_no)
- return IDYES == MessageBox(0, text, caption,
- MB_ICONQUESTION | MB_YESNO);
- else {
- MessageBox(0, text, caption, MB_ICONWARNING);
- return true;
- }
+ if (yes_no)
+ return IDYES == MessageBox(0, text, caption,
+ MB_ICONQUESTION | MB_YESNO);
+ else {
+ MessageBox(0, text, caption, MB_ICONWARNING);
+ return true;
+ }
#else
- printf("%s\n", text);
- return true;
+ printf("%s\n", text);
+ return true;
#endif
}
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp b/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp
index efe4713876..73c4f075e2 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp
+++ b/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp
@@ -74,7 +74,7 @@ CEXIIPL::CEXIIPL() :
}
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");
@@ -89,7 +89,8 @@ CEXIIPL::CEXIIPL() :
}
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));
@@ -120,7 +121,6 @@ CEXIIPL::~CEXIIPL()
if (m_count > 0)
{
m_szBuffer[m_count] = 0x00;
- //MessageBox(NULL, m_szBuffer, "last message", MB_OK);
}
if (m_pIPL != NULL)
@@ -130,19 +130,19 @@ CEXIIPL::~CEXIIPL()
}
// SRAM
- FILE* pStream = NULL;
- pStream = fopen(Core::GetStartupParameter().m_strSRAM.c_str(), "wb");
- if (pStream != NULL)
+ FILE *file = fopen(Core::GetStartupParameter().m_strSRAM.c_str(), "wb");
+ if (file)
{
- fwrite(m_SRAM, 1, 64, pStream);
- fclose(pStream);
+ fwrite(m_SRAM, 1, 64, file);
+ fclose(file);
}
}
void CEXIIPL::SetCS(int _iCS)
{
if (_iCS)
- { // cs transition to high
+ {
+ // cs transition to high
m_uPosition = 0;
}
}
diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/MemTools.cpp
index e217fb52e3..c46f76b88c 100644
--- a/Source/Core/Core/Src/MemTools.cpp
+++ b/Source/Core/Core/Src/MemTools.cpp
@@ -63,10 +63,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0];
if (accessType == 8) //Rule out DEP
{
- if (PowerPC::state == PowerPC::CPU_POWERDOWN)
- 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;
+ return (DWORD)EXCEPTION_CONTINUE_SEARCH;
}
//Where in the x86 code are we?
diff --git a/Source/Core/DolphinWX/Src/PluginManager.cpp b/Source/Core/DolphinWX/Src/PluginManager.cpp
index fd235905cc..ac9a9ddbab 100644
--- a/Source/Core/DolphinWX/Src/PluginManager.cpp
+++ b/Source/Core/DolphinWX/Src/PluginManager.cpp
@@ -58,7 +58,7 @@ CPluginManager::~CPluginManager()
// ----------------------------------------
-// Create list of avaliable plugins
+// Create list of available plugins
// -------------
void CPluginManager::ScanForPlugins(wxWindow* _wxWindow)
{
@@ -145,10 +145,11 @@ void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, bool Type,
//int ret = PluginVideo::LoadPlugin(_rFilename);
//int ret = PluginDSP::LoadPlugin(_rFilename);
- if(Type)
+ if (Type)
{
//Common::CPlugin::Debug((HWND)_Parent);
- if(!PluginVideo::IsLoaded()) PluginVideo::LoadPlugin(_rFilename);
+ if (!PluginVideo::IsLoaded())
+ PluginVideo::LoadPlugin(_rFilename);
PluginVideo::Debug((HWND)_Parent, Show);
}
else
@@ -162,7 +163,6 @@ void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, bool Type,
//m_DllDebugger(NULL);
}
-
// ----------------------------------------
// Get dll info
// -------------
@@ -179,6 +179,9 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
Common::CPlugin::Release();
}
+ /*
+ The DLL loading code provides enough error messages already. Possibly make some return codes
+ and handle messages here instead?
else
{
if (!File::Exists(_rFileName)) {
@@ -186,7 +189,7 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
} else {
PanicAlert("Failed to load plugin %s - unknown error.\n", _rFileName);
}
- }
+ }*/
}
diff --git a/Source/Core/VideoCommon/Src/NativeVertexFormat.h b/Source/Core/VideoCommon/Src/NativeVertexFormat.h
index bcfb9fd95d..bad74a8b63 100644
--- a/Source/Core/VideoCommon/Src/NativeVertexFormat.h
+++ b/Source/Core/VideoCommon/Src/NativeVertexFormat.h
@@ -89,14 +89,16 @@ struct PortableVertexDeclaration
// all the data loading code must always be made compatible.
class NativeVertexFormat
{
- u8* m_compiledCode;
- PortableVertexDeclaration vtx_decl;
+protected:
+ NativeVertexFormat() {}
+
public:
- NativeVertexFormat();
- ~NativeVertexFormat();
+ virtual ~NativeVertexFormat() {}
+
+ virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0;
+ virtual void SetupVertexPointers() const = 0;
- void Initialize(const PortableVertexDeclaration &vtx_decl);
- void SetupVertexPointers() const;
+ static NativeVertexFormat *Create();
// TODO: move these in under private:
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.
diff --git a/Source/Core/VideoCommon/Src/XFBConvert.h b/Source/Core/VideoCommon/Src/XFBConvert.h
index f1a41a245e..a1b6a5704a 100644
--- a/Source/Core/VideoCommon/Src/XFBConvert.h
+++ b/Source/Core/VideoCommon/Src/XFBConvert.h
@@ -20,8 +20,16 @@
#include "Common.h"
+// This must be called once before calling the two conversion functions
+// below.
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.
void ConvertFromXFB(u32 *dst, const u8* _pXFB, int width, int height);
diff --git a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj
index d53351498e..0b7dab0c32 100644
--- a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj
+++ b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj
@@ -1202,6 +1202,10 @@
>
</File>
<File
+ RelativePath=".\Src\NativeVertexFormat.cpp"
+ >
+ </File>
+ <File
RelativePath=".\Src\OpcodeDecoding.cpp"
>
</File>
@@ -1274,19 +1278,19 @@
>
</File>
<File
- RelativePath=".\Src\Render.cpp"
+ RelativePath=".\Src\PixelShaderManager.cpp"
>
</File>
<File
- RelativePath=".\Src\Render.h"
+ RelativePath=".\Src\PixelShaderManager.h"
>
</File>
<File
- RelativePath=".\Src\ShaderManager.cpp"
+ RelativePath=".\Src\Render.cpp"
>
</File>
<File
- RelativePath=".\Src\ShaderManager.h"
+ RelativePath=".\Src\Render.h"
>
</File>
<File
@@ -1317,6 +1321,14 @@
RelativePath=".\Src\VertexShader.h"
>
</File>
+ <File
+ RelativePath=".\Src\VertexShaderManager.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Src\VertexShaderManager.h"
+ >
+ </File>
</Filter>
<Filter
Name="D3D"
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp
new file mode 100644
index 0000000000..0ac4d985c8
--- /dev/null
+++ b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp
@@ -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);
+} \ No newline at end of file
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp b/Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp
index 78fa115044..b78a020db8 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp
@@ -33,7 +33,8 @@
#include "TransformEngine.h"
#include "OpcodeDecoding.h"
#include "TextureCache.h"
-#include "ShaderManager.h"
+#include "VertexShaderManager.h"
+#include "PixelShaderManager.h"
#include "BPStructs.h"
#include "XFStructs.h"
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderManager.cpp
index af7d36f191..f174591cf5 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderManager.cpp
@@ -1,218 +1,134 @@
-// 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 "Statistics.h"
-#include "Utils.h"
-#include "Profiler.h"
-#include "ShaderManager.h"
-#include "VertexLoader.h"
-#include "BPMemory.h"
-#include "XFMemory.h"
-
-
-//I hope we don't get too many hash collisions :p
-//all these magic numbers are primes, it should help a bit
-tevhash GetCurrentTEV()
-{
- u32 hash = bpmem.genMode.numindstages + bpmem.genMode.numtevstages*11 + bpmem.genMode.numtexgens*8*17;
- for (int i = 0; i < (int)bpmem.genMode.numtevstages+1; i++)
- {
- hash = _rotl(hash,3) ^ (bpmem.combiners[i].colorC.hex*13);
- hash = _rotl(hash,7) ^ ((bpmem.combiners[i].alphaC.hex&0xFFFFFFFC)*3);
- hash = _rotl(hash,9) ^ xfregs.texcoords[i].texmtxinfo.projection*451;
- }
- for (int i = 0; i < (int)bpmem.genMode.numtevstages/2+1; i++)
- {
- hash = _rotl(hash,13) ^ (bpmem.tevorders[i].hex*7);
- }
- for (int i = 0; i < 8; i++)
- {
- hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap1;
- hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap2;
- }
- hash ^= bpmem.dstalpha.enable ^ 0xc0debabe;
- hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp0*7;
- hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp1*13;
- hash = _rotl(hash,4) ^ bpmem.alphaFunc.logic*11;
- return hash;
-}
-
-
-PShaderCache::PSCache PShaderCache::pshaders;
-VShaderCache::VSCache VShaderCache::vshaders;
-
-void PShaderCache::Init()
-{
-
-}
-
-
-void PShaderCache::Shutdown()
-{
- PSCache::iterator iter = pshaders.begin();
- for (;iter!=pshaders.end();iter++)
- iter->second.Destroy();
- pshaders.clear();
-}
-
-
-void PShaderCache::SetShader()
-{
- if (D3D::GetShaderVersion() < 2)
- return; // we are screwed
-
- static LPDIRECT3DPIXELSHADER9 lastShader = 0;
- DVSTARTPROFILE();
-
- tevhash currentHash = GetCurrentTEV();
-
- PSCache::iterator iter;
- iter = pshaders.find(currentHash);
-
- if (iter != pshaders.end())
- {
- iter->second.frameCount = frameCount;
- PSCacheEntry &entry = iter->second;
- if (!lastShader || entry.shader != lastShader)
- {
- D3D::dev->SetPixelShader(entry.shader);
- lastShader = entry.shader;
- }
- return;
- }
-
- const char *code = GeneratePixelShader();
- LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePShader(code, int(strlen(code)));
- if (shader)
- {
- //Make an entry in the table
- PSCacheEntry newentry;
- newentry.shader = shader;
- newentry.frameCount = frameCount;
- pshaders[currentHash] = newentry;
- }
-
- D3D::dev->SetPixelShader(shader);
-
- INCSTAT(stats.numPixelShadersCreated);
- SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
-}
-
-void PShaderCache::Cleanup()
-{
- PSCache::iterator iter;
- iter = pshaders.begin();
-
- while (iter != pshaders.end())
- {
- PSCacheEntry &entry = iter->second;
- if (entry.frameCount < frameCount-30)
- {
- entry.Destroy();
- iter = pshaders.erase(iter);
- }
- else
- {
- iter++;
- }
- }
- 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());
-}
+// 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 "Statistics.h"
+#include "Utils.h"
+#include "Profiler.h"
+#include "PixelShaderManager.h"
+#include "VertexLoader.h"
+#include "BPMemory.h"
+#include "XFMemory.h"
+
+
+PShaderCache::PSCache PShaderCache::pshaders;
+
+//I hope we don't get too many hash collisions :p
+//all these magic numbers are primes, it should help a bit
+tevhash GetCurrentTEV()
+{
+ u32 hash = bpmem.genMode.numindstages + bpmem.genMode.numtevstages*11 + bpmem.genMode.numtexgens*8*17;
+ for (int i = 0; i < (int)bpmem.genMode.numtevstages+1; i++)
+ {
+ hash = _rotl(hash,3) ^ (bpmem.combiners[i].colorC.hex*13);
+ hash = _rotl(hash,7) ^ ((bpmem.combiners[i].alphaC.hex&0xFFFFFFFC)*3);
+ hash = _rotl(hash,9) ^ xfregs.texcoords[i].texmtxinfo.projection*451;
+ }
+ for (int i = 0; i < (int)bpmem.genMode.numtevstages/2+1; i++)
+ {
+ hash = _rotl(hash,13) ^ (bpmem.tevorders[i].hex*7);
+ }
+ for (int i = 0; i < 8; i++)
+ {
+ hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap1;
+ hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap2;
+ }
+ hash ^= bpmem.dstalpha.enable ^ 0xc0debabe;
+ hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp0*7;
+ hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp1*13;
+ hash = _rotl(hash,4) ^ bpmem.alphaFunc.logic*11;
+ return hash;
+}
+
+
+void PShaderCache::Init()
+{
+
+}
+
+
+void PShaderCache::Shutdown()
+{
+ PSCache::iterator iter = pshaders.begin();
+ for (;iter!=pshaders.end();iter++)
+ iter->second.Destroy();
+ pshaders.clear();
+}
+
+
+void PShaderCache::SetShader()
+{
+ if (D3D::GetShaderVersion() < 2)
+ return; // we are screwed
+
+ static LPDIRECT3DPIXELSHADER9 lastShader = 0;
+ DVSTARTPROFILE();
+
+ tevhash currentHash = GetCurrentTEV();
+
+ PSCache::iterator iter;
+ iter = pshaders.find(currentHash);
+
+ if (iter != pshaders.end())
+ {
+ iter->second.frameCount = frameCount;
+ PSCacheEntry &entry = iter->second;
+ if (!lastShader || entry.shader != lastShader)
+ {
+ D3D::dev->SetPixelShader(entry.shader);
+ lastShader = entry.shader;
+ }
+ return;
+ }
+
+ const char *code = GeneratePixelShader();
+ LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePShader(code, int(strlen(code)));
+ if (shader)
+ {
+ //Make an entry in the table
+ PSCacheEntry newentry;
+ newentry.shader = shader;
+ newentry.frameCount = frameCount;
+ pshaders[currentHash] = newentry;
+ }
+
+ D3D::dev->SetPixelShader(shader);
+
+ INCSTAT(stats.numPixelShadersCreated);
+ SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
+}
+
+void PShaderCache::Cleanup()
+{
+ PSCache::iterator iter;
+ iter = pshaders.begin();
+
+ while (iter != pshaders.end())
+ {
+ PSCacheEntry &entry = iter->second;
+ if (entry.frameCount < frameCount-30)
+ {
+ entry.Destroy();
+ iter = pshaders.erase(iter);
+ }
+ else
+ {
+ iter++;
+ }
+ }
+ SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
+}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderManager.h
index 9b067bdab3..ef8e780fe8 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderManager.h
@@ -1,97 +1,64 @@
-// 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/
-
-#pragma once
-
-#include "D3DBase.h"
-
-#include <map>
-#include "PixelShader.h"
-#include "VertexShader.h"
-
-typedef u32 tevhash;
-
-tevhash GetCurrentTEV();
-
-
-class PShaderCache
-{
- struct PSCacheEntry
- {
- LPDIRECT3DPIXELSHADER9 shader;
- //CGPShader shader;
-
- int frameCount;
- PSCacheEntry()
- {
- shader=0;
- frameCount=0;
- }
- void Destroy()
- {
- if (shader)
- shader->Release();
- }
- };
-
-
- typedef std::map<tevhash,PSCacheEntry> PSCache;
-
- static PSCache pshaders;
-
-public:
- static void Init();
- static void Cleanup();
- static void Shutdown();
- static void SetShader();
-};
-
-
-
-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(); \ No newline at end of file
+// 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 _PIXELSHADERMANAGER_H
+#define _PIXELSHADERMANAGER_H
+
+#include "D3DBase.h"
+
+#include <map>
+#include "PixelShader.h"
+#include "VertexShader.h"
+
+typedef u32 tevhash;
+
+tevhash GetCurrentTEV();
+
+class PShaderCache
+{
+ struct PSCacheEntry
+ {
+ LPDIRECT3DPIXELSHADER9 shader;
+ //CGPShader shader;
+
+ int frameCount;
+ PSCacheEntry()
+ {
+ shader = 0;
+ frameCount = 0;
+ }
+ void Destroy()
+ {
+ if (shader)
+ shader->Release();
+ }
+ };
+
+
+ typedef std::map<tevhash, PSCacheEntry> PSCache;
+
+ static PSCache pshaders;
+
+public:
+ static void Init();
+ static void Cleanup();
+ static void Shutdown();
+ static void SetShader();
+};
+
+
+#endif // _PIXELSHADERMANAGER_H
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
index 9fd39be812..fc9fb46757 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
@@ -29,7 +29,8 @@
#include "XFStructs.h"
#include "D3DPostprocess.h"
#include "D3DUtil.h"
-#include "ShaderManager.h"
+#include "VertexShaderManager.h"
+#include "PixelShaderManager.h"
#include "TextureCache.h"
#include "Utils.h"
#include "EmuWindow.h"
@@ -171,7 +172,8 @@ void Renderer::ReinitView()
xScale = width/640.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)
};
}
@@ -198,24 +200,24 @@ void Renderer::SwapBuffers(void)
{
char st[2048];
char *p = st;
- p+=sprintf(p,"Num textures created: %i\n",stats.numTexturesCreated);
- p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive);
- p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated);
- p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive);
- p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated);
- p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive);
- p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled);
- p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated);
- p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive);
- p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims);
- p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
- p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims);
- p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads);
- p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
- p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads);
- p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
- p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads);
- p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
+ p+=sprintf(p,"textures created: %i\n",stats.numTexturesCreated);
+ p+=sprintf(p,"textures alive: %i\n",stats.numTexturesAlive);
+ p+=sprintf(p,"pshaders created: %i\n",stats.numPixelShadersCreated);
+ p+=sprintf(p,"pshaders alive: %i\n",stats.numPixelShadersAlive);
+ p+=sprintf(p,"vshaders created: %i\n",stats.numVertexShadersCreated);
+ p+=sprintf(p,"vshaders alive: %i\n",stats.numVertexShadersAlive);
+ p+=sprintf(p,"dlists called: %i\n",stats.numDListsCalled);
+ p+=sprintf(p,"dlists created: %i\n",stats.numDListsCreated);
+ p+=sprintf(p,"dlists alive: %i\n",stats.numDListsAlive);
+ p+=sprintf(p,"primitives: %i\n",stats.thisFrame.numPrims);
+ p+=sprintf(p,"primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
+ p+=sprintf(p,"primitives (DL): %i\n",stats.thisFrame.numDLPrims);
+ p+=sprintf(p,"XF loads: %i\n",stats.thisFrame.numXFLoads);
+ p+=sprintf(p,"XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
+ p+=sprintf(p,"CP loads: %i\n",stats.thisFrame.numCPLoads);
+ p+=sprintf(p,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
+ p+=sprintf(p,"BP loads: %i\n",stats.thisFrame.numBPLoads);
+ p+=sprintf(p,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
D3D::font.DrawTextScaled(0,30,20,20,0.0f,0xFF00FFFF,st,false);
@@ -270,7 +272,7 @@ void Renderer::SwapBuffers(void)
u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB;
// clearColor |= 0x003F003F;
// D3D::BeginFrame(true,clearColor,1.0f);
- D3D::BeginFrame(false,clearColor,1.0f);
+ D3D::BeginFrame(false, clearColor, 1.0f);
// D3D::EnableAlphaToCoverage();
Postprocess::BeginFrame();
@@ -280,15 +282,6 @@ void Renderer::SwapBuffers(void)
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)
{
Viewport* pViewport = (Viewport*)_Viewport;
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h
index d7086efdf3..0f3db82d84 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/Render.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.h
@@ -44,17 +44,15 @@ public:
static void Init(SVideoInitialize &_VideoInitialize);
static void Shutdown();
- // initialize opengl standard values (like view port)
static void Initialize(void);
+
// must be called if the window size has changed
static void ReinitView(void);
- //
- // --- Render Functions ---
- //
+
static void SwapBuffers(void);
- static void Flush(void);
- static float GetXScale(){return xScale;}
- static float GetYScale(){return yScale;}
+
+ static float GetXScale() {return xScale;}
+ static float GetYScale() {return yScale;}
static void SetScissorBox(RECT &rc);
static void SetViewport(float* _Viewport);
@@ -108,8 +106,8 @@ public:
* @param pVertexStreamZeroData User memory pointer to the vertex data.
* @param VertexStreamZeroStride The number of bytes of data for each vertex.
*/
- static void DrawPrimitiveUP( D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount,
- const void* pVertexStreamZeroData, UINT VertexStreamZeroStride );
+ static void DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount,
+ const void* pVertexStreamZeroData, UINT VertexStreamZeroStride);
/**
* Renders a sequence of non indexed, geometric primitives of the specified type from the current set of data input streams.
@@ -117,7 +115,7 @@ public:
* @param StartVertex Index of the first vertex to load.
* @param PrimitiveCount Number of primitives to render.
*/
- static void DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount );
+ static void DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);
};
#endif // __H_RENDER__
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
index f36840f44a..b5204337b8 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
@@ -27,7 +27,8 @@
#include "IndexGenerator.h"
#include "BPStructs.h"
#include "XFStructs.h"
-#include "ShaderManager.h"
+#include "VertexShaderManager.h"
+#include "PixelShaderManager.h"
#include "Utils.h"
using namespace D3D;
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderManager.cpp
new file mode 100644
index 0000000000..616881a523
--- /dev/null
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderManager.cpp
@@ -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());
+}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderManager.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderManager.h
new file mode 100644
index 0000000000..6bfee5cafe
--- /dev/null
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderManager.h
@@ -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
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp
index 113b62a99e..5635e909dd 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp
@@ -461,12 +461,12 @@ void BPWritten(int addr, int changes, int newval)
}
else {
// EFB to XFB
- if(g_Config.bUseXFB)
+ if (g_Config.bUseXFB)
{
// the number of lines copied is determined by the y scale * source efb height
float yScale = bpmem.dispcopyyscale / 256.0f;
float xfbLines = bpmem.copyTexSrcWH.y + 1.0f * yScale;
- XFB_Write(Memory_GetPtr(bpmem.copyTexDest<<5), multirc, (bpmem.copyMipMapStrideChannels << 4), (int)xfbLines);
+ XFB_Write(Memory_GetPtr(bpmem.copyTexDest << 5), multirc, (bpmem.copyMipMapStrideChannels << 4), (int)xfbLines);
}
else
{
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
index a7b27246ab..4fa1d00f81 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
@@ -140,7 +140,6 @@ void UpdateFPSDisplay(const char *text)
char temp[512];
sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text);
OpenGL_SetWindowText(temp);
-
}
// =======================================================================================
@@ -148,9 +147,9 @@ void UpdateFPSDisplay(const char *text)
bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight)
{
int _twidth, _theight;
- if(g_Config.bFullscreen)
+ if (g_Config.bFullscreen)
{
- if(strlen(g_Config.iFSResolution) > 1)
+ if (strlen(g_Config.iFSResolution) > 1)
{
sscanf(g_Config.iFSResolution, "%dx%d", &_twidth, &_theight);
}
@@ -162,7 +161,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
}
else // Going Windowed
{
- if(strlen(g_Config.iWindowedRes) > 1)
+ if (strlen(g_Config.iWindowedRes) > 1)
{
sscanf(g_Config.iWindowedRes, "%dx%d", &_twidth, &_theight);
}
@@ -189,7 +188,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
float FactorH = 480.0f / (float)nBackbufferHeight;
float Max = (FactorW < FactorH) ? FactorH : FactorW;
- if(g_Config.bStretchToFit)
+ if (g_Config.bStretchToFit)
{
MValueX = 1.0f / FactorW;
MValueY = 1.0f / FactorH;
@@ -608,7 +607,7 @@ void OpenGL_Update()
int height = rcWindow.bottom - rcWindow.top;
if (EmuWindow::GetParentWnd() != 0)
- ::MoveWindow(EmuWindow::GetWnd(), 0,0,width,height, FALSE);
+ ::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
nBackbufferWidth = width;
nBackbufferHeight = height;
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h
index a59f43df43..8c2e485680 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h
@@ -38,6 +38,17 @@
#define DEBUG_LOG(...)
#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 __Log(const char *format, ...);
void __Log(int type, const char *format, ...);
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp
index 3243092dab..dc87424c1e 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp
@@ -48,7 +48,25 @@ DECLARE_IMPORT(glColorPointer);
DECLARE_IMPORT(glTexCoordPointer);
#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
m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false);
@@ -58,7 +76,7 @@ NativeVertexFormat::NativeVertexFormat()
#endif
}
-NativeVertexFormat::~NativeVertexFormat()
+GLVertexFormat::~GLVertexFormat()
{
#ifdef USE_JIT
FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE);
@@ -72,7 +90,7 @@ inline GLuint VarToGL(VarType t)
return lookup[t];
}
-void NativeVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
+void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{
using namespace Gen;
@@ -148,7 +166,7 @@ void NativeVertexFormat::Initialize(const PortableVertexDeclaration &_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
// get around type checking errors, and call it.
#ifdef USE_JIT
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
index 896b2b24ae..54eba2667c 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
@@ -43,17 +43,17 @@
#include "VertexLoader.h"
#include "XFB.h"
#include "Timer.h"
+#include "Logging/Logging.h" // for Logging()
+
#if defined(HAVE_WX) && HAVE_WX
#include "Debugger/Debugger.h" // for the CDebugger class
#endif
-#include "Logging/Logging.h" // for Logging()
#ifdef _WIN32
#include "OS/Win32.h"
#else
#endif
-//#define USE_AA
-#define AA_AMMOUNT 16
+
struct MESSAGE
{
MESSAGE() {}
@@ -63,31 +63,39 @@ struct MESSAGE
};
CGcontext g_cgcontext;
-CGprofile g_cgvProf, g_cgfProf;
+CGprofile g_cgvProf;
+CGprofile g_cgfProf;
+
#if defined(HAVE_WX) && HAVE_WX
extern CDebugger* m_frame; // the debugging class
#endif
-static int g_MaxTexWidth = 0, g_MaxTexHeight = 0;
static RasterFont* s_pfont = NULL;
static std::list<MESSAGE> s_listMsgs;
+
static bool s_bFullscreen = false;
static bool s_bOutputCgErrors = true;
-static int nZBufferRender = 0; // if > 0, then using zbuffer render
-static u32 s_uFramebuffer = 0;
-static u32 s_RenderTargets[1] = {0}, s_DepthTarget = 0, s_ZBufferTarget = 0;
+static int nZBufferRender = 0; // if > 0, then use zbuffer render, and count down.
+
+// 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 int s_nCurTarget = 0;
bool g_bBlendLogicOp = false;
-
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;
GLenum err = GL_NO_ERROR;
@@ -96,16 +104,16 @@ bool Renderer::Create2()
cgSetErrorHandler(HandleCgError, NULL);
// fill the opengl extension map
- const char* ptoken = (const char*)glGetString( GL_EXTENSIONS );
+ const char* ptoken = (const char*)glGetString(GL_EXTENSIONS);
if (ptoken == NULL) return false;
__Log("Supported OpenGL Extensions:\n");
__Log(ptoken); // write to the log file
__Log("\n");
- if( strstr(ptoken, "GL_EXT_blend_logic_op") != NULL )
+ if (strstr(ptoken, "GL_EXT_blend_logic_op") != NULL)
g_bBlendLogicOp = true;
- if( strstr(ptoken, "ATI_draw_buffers") != NULL && strstr(ptoken, "ARB_draw_buffers") == NULL)
+ if (strstr(ptoken, "ATI_draw_buffers") != NULL && strstr(ptoken, "ARB_draw_buffers") == NULL)
//Checks if it ONLY has the ATI_draw_buffers extension, some have both
s_bATIDrawBuffers = true;
@@ -154,8 +162,11 @@ bool Renderer::Create2()
#endif
// check the max texture width and height
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&g_MaxTexWidth);
- g_MaxTexHeight = g_MaxTexWidth;
+ GLint max_texture_size;
+ 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();
if (err != GL_NO_ERROR) bSuccess = false;
@@ -163,44 +174,40 @@ bool Renderer::Create2()
if (glDrawBuffers == NULL && !GLEW_ARB_draw_buffers)
glDrawBuffers = glDrawBuffersARB;
- glGenFramebuffersEXT( 1, (GLuint *)&s_uFramebuffer);
+ glGenFramebuffersEXT(1, (GLuint *)&s_uFramebuffer);
if (s_uFramebuffer == 0) {
ERROR_LOG("failed to create the renderbuffer\n");
}
- _assert_( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT );
- glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, s_uFramebuffer );
+ _assert_(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT);
+ 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 nBackbufferHeight = (int)OpenGL_GetHeight();
- // create the framebuffer targets
- glGenTextures(ARRAYSIZE(s_RenderTargets), (GLuint *)s_RenderTargets);
- for(u32 i = 0; i < ARRAYSIZE(s_RenderTargets); ++i) {
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[i]);
- // initialize to default
- 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_T, GL_CLAMP_TO_EDGE);
- if( glGetError() != GL_NO_ERROR) {
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
- GL_REPORT_ERROR();
- }
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_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
+ // Create the framebuffer target
+ glGenTextures(1, (GLuint *)&s_RenderTarget);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
+ // initialize to default
+ 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_T, GL_CLAMP_TO_EDGE);
+ if (glGetError() != GL_NO_ERROR) {
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ GL_REPORT_ERROR();
}
- s_nCurTarget = 0;
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GL_REPORT_ERROR();
int nMaxMRT = 0;
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, (GLint *)&nMaxMRT);
-
if (nMaxMRT > 1) {
// create zbuffer target
glGenTextures(1, (GLuint *)&s_ZBufferTarget);
@@ -209,27 +216,19 @@ bool Renderer::Create2()
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- if( glGetError() != GL_NO_ERROR) {
+ if (glGetError() != GL_NO_ERROR) {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
GL_REPORT_ERROR();
}
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_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
- glGenRenderbuffersEXT( 1, (GLuint *)&s_DepthTarget);
+ glGenRenderbuffersEXT(1, (GLuint *)&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);
- #endif
if (glGetError() != GL_NO_ERROR) {
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nBackbufferWidth, nBackbufferHeight);
@@ -241,24 +240,18 @@ bool Renderer::Create2()
GL_REPORT_ERROR();
// set as render targets
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[s_nCurTarget], 0 );
- 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]);
-
+ 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);
- #endif
- GL_REPORT_ERROR();
+
+ GL_REPORT_ERROR();
if (s_ZBufferTarget != 0) {
// test to make sure it works
- glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, 0);
bool bFailed = glGetError() != GL_NO_ERROR || glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT;
- glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
- if( bFailed ) {
+ if (bFailed) {
glDeleteTextures(1, (GLuint *)&s_ZBufferTarget);
s_ZBufferTarget = 0;
}
@@ -267,7 +260,7 @@ bool Renderer::Create2()
if (s_ZBufferTarget == 0)
ERROR_LOG("disabling ztarget mrt feature (max mrt=%d)\n", nMaxMRT);
- //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget );
+ //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
nZBufferRender = 0;
@@ -278,9 +271,6 @@ bool Renderer::Create2()
s_pfont = new RasterFont();
- SetAA(g_Config.iMultisampleMode);
- GL_REPORT_ERROR();
-
// load the effect, find the best profiles (if any)
if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) {
ERROR_LOG("arbvp1 not supported\n");
@@ -292,7 +282,7 @@ bool Renderer::Create2()
}
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_cgfProf);
@@ -305,22 +295,21 @@ bool Renderer::Create2()
__Log("max program env parameters: vert=%d, frag=%d\n", nenvvertparams, nenvfragparams);
__Log("max program address register parameters: vert=%d, frag=%d\n", naddrregisters[0], naddrregisters[1]);
- if( nenvvertparams < 238 )
+ if (nenvvertparams < 238)
ERROR_LOG("not enough vertex shader environment constants!!\n");
#ifndef _DEBUG
cgGLSetDebugMode(GL_FALSE);
#endif
- if( cgGetError() != CG_NO_ERROR ) {
+ if (cgGetError() != CG_NO_ERROR) {
ERROR_LOG("cg error\n");
return false;
}
- //glEnable(GL_POLYGON_OFFSET_FILL);
- //glEnable(GL_POLYGON_OFFSET_LINE);
- //glPolygonOffset(0, 1);
- if (!Initialize())
+ s_RenderMode = Renderer::RM_Normal;
+
+ if (!InitializeGL())
return false;
XFB_Init();
@@ -334,26 +323,25 @@ void Renderer::Shutdown(void)
XFB_Shutdown();
- if (g_cgcontext != 0) {
+ if (g_cgcontext) {
cgDestroyContext(g_cgcontext);
g_cgcontext = 0;
}
-
- if (s_RenderTargets[0]) {
- glDeleteTextures(ARRAYSIZE(s_RenderTargets), (GLuint *)s_RenderTargets);
- memset(s_RenderTargets, 0, sizeof(s_RenderTargets));
+ if (s_RenderTarget) {
+ glDeleteTextures(1, &s_RenderTarget);
+ s_RenderTarget = 0;
}
if (s_DepthTarget) {
- glDeleteRenderbuffersEXT(1, (GLuint *)&s_DepthTarget); s_DepthTarget = 0;
+ glDeleteRenderbuffersEXT(1, &s_DepthTarget);
+ s_DepthTarget = 0;
}
- if (s_uFramebuffer != 0) {
- glDeleteFramebuffersEXT( 1, (GLuint *)&s_uFramebuffer);
+ if (s_uFramebuffer) {
+ glDeleteFramebuffersEXT(1, &s_uFramebuffer);
s_uFramebuffer = 0;
}
}
-
-bool Renderer::Initialize()
+bool Renderer::InitializeGL()
{
glStencilFunc(GL_ALWAYS, 0, 0);
glBlendFunc(GL_ONE, GL_ONE);
@@ -394,8 +382,6 @@ bool Renderer::Initialize()
glClientActiveTexture(GL_TEXTURE0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- s_RenderMode = Renderer::RM_Normal;
-
GLenum err = GL_NO_ERROR;
GL_REPORT_ERROR();
@@ -439,7 +425,7 @@ void Renderer::ProcessMessages()
}
}
- if(!wasEnabled) glDisable(GL_BLEND);
+ if (!wasEnabled) glDisable(GL_BLEND);
}
void Renderer::RenderText(const char* pstr, int left, int top, u32 color)
@@ -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);
}
-void Renderer::SetAA(int aa)
-{
-
-}
-
void Renderer::ReinitView(int nNewWidth, int nNewHeight)
{
int oldscreen = s_bFullscreen;
@@ -467,7 +448,7 @@ void Renderer::ReinitView(int nNewWidth, int nNewHeight)
OpenGL_Shutdown();
int oldwidth = (int)OpenGL_GetWidth(),
oldheight = (int)OpenGL_GetHeight();
- if (!OpenGL_Create(g_VideoInitialize, nNewWidth, nNewHeight)) {//nNewWidth&~7, nNewHeight&~7) ) {
+ if (!OpenGL_Create(g_VideoInitialize, nNewWidth, nNewHeight)) {//nNewWidth&~7, nNewHeight&~7)) {
ERROR_LOG("Failed to recreate, reverting to old settings\n");
if (!OpenGL_Create(g_VideoInitialize, oldwidth, oldheight)) {
g_VideoInitialize.pSysMessage("Failed to revert, exiting...\n");
@@ -487,7 +468,7 @@ void Renderer::ReinitView(int nNewWidth, int nNewHeight)
RECT rcdesktop;
GetWindowRect(GetDesktopWindow(), &rcdesktop);
- SetWindowLong( EmuWindow::GetWnd(), GWL_STYLE, EmuWindow::g_winstyle );
+ SetWindowLong(EmuWindow::GetWnd(), GWL_STYLE, EmuWindow::g_winstyle);
SetWindowPos(EmuWindow::GetWnd(), HWND_TOP, ((rcdesktop.right-rcdesktop.left)-(rc.right-rc.left))/2,
((rcdesktop.bottom-rcdesktop.top)-(rc.bottom-rc.top))/2,
rc.right-rc.left, rc.bottom-rc.top, SWP_SHOWWINDOW);
@@ -499,39 +480,48 @@ void Renderer::ReinitView(int nNewWidth, int nNewHeight)
OpenGL_SetSize(nNewWidth > 16 ? nNewWidth : 16,
nNewHeight > 16 ? nNewHeight : 16);
}
+
int Renderer::GetTargetWidth()
{
- return (g_Config.bStretchToFit?640:(int)OpenGL_GetWidth());
+ return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth());
}
int Renderer::GetTargetHeight()
{
- return (g_Config.bStretchToFit?480:(int)OpenGL_GetHeight());
+ return (g_Config.bStretchToFit ? 480 : (int)OpenGL_GetHeight());
}
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()
@@ -554,7 +544,7 @@ void Renderer::RestoreGLState()
if (bpmem.genMode.cullmode > 0) glEnable(GL_CULL_FACE);
if (bpmem.zmode.testenable) glEnable(GL_DEPTH_TEST);
if (bpmem.blendmode.blendenable) glEnable(GL_BLEND);
- if(bpmem.zmode.updateenable) glDepthMask(GL_TRUE);
+ if (bpmem.zmode.updateenable) glDepthMask(GL_TRUE);
glEnable(GL_VERTEX_PROGRAM_ARB);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
@@ -571,8 +561,6 @@ void Renderer::SetColorMask()
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
}
-
-// =======================================================================================
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
// case 0x52 > SetScissorRect()
// ---------------
@@ -581,7 +569,6 @@ void Renderer::SetColorMask()
// bpmem.scissorTL.x, y = 342x342
// bpmem.scissorBR.x, y = 981x821
// Renderer::GetTargetHeight() = the fixed ini file setting
-// ---------------
bool Renderer::SetScissorRect()
{
int xoff = bpmem.scissorOffset.x * 2 - 342;
@@ -610,11 +597,11 @@ bool Renderer::SetScissorRect()
xoff, yoff
);*/
- if (rc_right >= rc_left && rc_bottom >= rc_top )
+ if (rc_right >= rc_left && rc_bottom >= rc_top)
{
glScissor(
(int)rc_left, // x = 0
- Renderer::GetTargetHeight()-(int)(rc_bottom), // y = 0
+ Renderer::GetTargetHeight() - (int)(rc_bottom), // y = 0
(int)(rc_right-rc_left), // y = 0
(int)(rc_bottom-rc_top) // y = 0
);
@@ -624,7 +611,6 @@ bool Renderer::SetScissorRect()
return false;
}
-
bool Renderer::IsUsingATIDrawBuffers()
{
return s_bATIDrawBuffers;
@@ -662,7 +648,7 @@ void Renderer::FlushZBufferAlphaToTarget()
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget);
TextureMngr::EnableTexRECT(0);
// disable all other stages
- for(int i = 1; i < 8; ++i)
+ for (int i = 1; i < 8; ++i)
TextureMngr::DisableStage(i);
GL_REPORT_ERRORD();
@@ -670,14 +656,17 @@ void Renderer::FlushZBufferAlphaToTarget()
glStencilFunc(GL_EQUAL, 1, 0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- if(g_Config.bStretchToFit)
+ // 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)
{
//TODO: Do Correctly in a bit
- float FactorW = (float)640 / (float)OpenGL_GetWidth();
- float FactorH = (float)480 / (float)OpenGL_GetHeight();
+ float FactorW = 640.f / (float)OpenGL_GetWidth();
+ float FactorH = 480.f / (float)OpenGL_GetHeight();
float Max = (FactorW < FactorH) ? FactorH : FactorW;
- float Temp = 1 / Max;
+ float Temp = 1.0f / Max;
FactorW *= Temp;
FactorH *= Temp;
@@ -686,8 +675,7 @@ void Renderer::FlushZBufferAlphaToTarget()
glTexCoord2f(0, (float)GetTargetHeight()); glVertex2f(-FactorW,FactorH);
glTexCoord2f((float)GetTargetWidth(), (float)GetTargetHeight()); glVertex2f(FactorW,FactorH);
glTexCoord2f((float)GetTargetWidth(), 0); glVertex2f(FactorW,-FactorH);
-
- __Log("%d, %d", FactorW, FactorH);
+ glEnd();
}
else
{
@@ -696,8 +684,8 @@ void Renderer::FlushZBufferAlphaToTarget()
glTexCoord2f(0, (float)(GetTargetHeight())); glVertex2f(-1,1);
glTexCoord2f((float)(GetTargetWidth()), (float)(GetTargetHeight())); glVertex2f(1,1);
glTexCoord2f((float)(GetTargetWidth()), 0); glVertex2f(1,-1);
+ glEnd();
}
- glEnd();
GL_REPORT_ERRORD();
@@ -715,7 +703,7 @@ void Renderer::SetRenderMode(RenderMode mode)
if (mode == RM_Normal) {
// flush buffers
- if( s_RenderMode == RM_ZBufferAlpha ) {
+ if (s_RenderMode == RM_ZBufferAlpha) {
FlushZBufferAlphaToTarget();
glDisable(GL_STENCIL_TEST);
}
@@ -728,7 +716,7 @@ void Renderer::SetRenderMode(RenderMode mode)
// setup buffers
_assert_(GetZBufferTarget() && bpmem.zmode.updateenable);
- if( mode == RM_ZBufferAlpha ) {
+ if (mode == RM_ZBufferAlpha) {
glEnable(GL_STENCIL_TEST);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
@@ -744,7 +732,7 @@ void Renderer::SetRenderMode(RenderMode mode)
_assert_(GetZBufferTarget());
_assert_(s_bHaveStencilBuffer);
- if( mode == RM_ZBufferOnly ) {
+ if (mode == RM_ZBufferOnly) {
// flush and remove stencil
_assert_(s_RenderMode==RM_ZBufferAlpha);
FlushZBufferAlphaToTarget();
@@ -755,7 +743,7 @@ void Renderer::SetRenderMode(RenderMode mode)
GL_REPORT_ERRORD();
}
else {
- _assert_(mode == RM_ZBufferAlpha&&s_RenderMode==RM_ZBufferOnly);
+ _assert_(mode == RM_ZBufferAlpha && s_RenderMode == RM_ZBufferOnly);
// setup stencil
glEnable(GL_STENCIL_TEST);
@@ -774,11 +762,6 @@ Renderer::RenderMode Renderer::GetRenderMode()
return s_RenderMode;
}
-u32 Renderer::GetZBufferTarget()
-{
- return nZBufferRender > 0 ? s_ZBufferTarget : 0;
-}
-
void Renderer::Swap(const TRectangle& rc)
{
OpenGL_Update(); // just updates the render window position and the backbuffer size
@@ -787,30 +770,35 @@ void Renderer::Swap(const TRectangle& rc)
Renderer::SetRenderMode(Renderer::RM_Normal);
- // render to the real buffer now
- #ifdef USE_AA
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_RenderTargets[0]);
- #else
- glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch to the backbuffer
- #endif
- glViewport(OpenGL_GetXoff(),OpenGL_GetYoff() , (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight());
+#if 0
+ // Not working?
+ 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
+ // render to the real buffer now
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer
+ glViewport(OpenGL_GetXoff(), OpenGL_GetYoff(), (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight());
ResetGLState();
// texture map s_RenderTargets[s_curtarget] onto the main buffer
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[s_nCurTarget]);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
TextureMngr::EnableTexRECT(0);
// 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();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(-1,-1);
- glTexCoord2f(0, (float)GetTargetHeight()); glVertex2f(-1,1);
- glTexCoord2f((float)GetTargetWidth(), (float)GetTargetHeight()); glVertex2f(1,1);
- glTexCoord2f((float)GetTargetWidth(), 0); glVertex2f(1,-1);
+ glTexCoord2f(0, 0); glVertex2f(-1,-1);
+ glTexCoord2f(0, (float)GetTargetHeight()); glVertex2f(-1,1);
+ glTexCoord2f((float)GetTargetWidth(), (float)GetTargetHeight()); glVertex2f(1,1);
+ glTexCoord2f((float)GetTargetWidth(), 0); glVertex2f(1,-1);
glEnd();
if (g_Config.bWireFrame)
@@ -822,14 +810,8 @@ void Renderer::Swap(const TRectangle& rc)
SwapBuffers();
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
- GL_REPORT_ERRORD();
+#endif
+ GL_REPORT_ERRORD();
g_Config.iSaveTargetId = 0;
@@ -844,7 +826,7 @@ void Renderer::SwapBuffers()
static int s_fps;
static unsigned long lasttime;
++fpscount;
- if( timeGetTime() - lasttime > 1000 )
+ if (timeGetTime() - lasttime > 1000)
{
lasttime = timeGetTime();
s_fps = fpscount;
@@ -853,41 +835,38 @@ void Renderer::SwapBuffers()
// Write logging data to debugger
#if defined(HAVE_WX) && HAVE_WX
- if(m_frame)
- {
+ if (m_frame)
Logging(0);
- }
#endif
if (g_Config.bOverlayStats) {
char st[2048];
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,"Num textures created: %i\n",stats.numTexturesCreated);
- p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive);
- p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated);
- p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive);
- p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated);
- p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive);
- p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled);
- p+=sprintf(p,"Num dlists called (frame): %i\n",stats.thisFrame.numDListsCalled);
+ p+=sprintf(p,"textures created: %i\n",stats.numTexturesCreated);
+ p+=sprintf(p,"textures alive: %i\n",stats.numTexturesAlive);
+ p+=sprintf(p,"pshaders created: %i\n",stats.numPixelShadersCreated);
+ p+=sprintf(p,"pshaders alive: %i\n",stats.numPixelShadersAlive);
+ p+=sprintf(p,"vshaders created: %i\n",stats.numVertexShadersCreated);
+ p+=sprintf(p,"vshaders alive: %i\n",stats.numVertexShadersAlive);
+ p+=sprintf(p,"dlists called: %i\n",stats.numDListsCalled);
+ p+=sprintf(p,"dlists called(f): %i\n",stats.thisFrame.numDListsCalled);
// not used.
- //p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated);
- //p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive);
- //p+=sprintf(p,"Num strip joins: %i\n",stats.numJoins);
- p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims);
- p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
- p+=sprintf(p,"Num buffer splits: %i\n",stats.thisFrame.numBufferSplits);
- p+=sprintf(p,"Num draw calls: %i\n",stats.thisFrame.numDrawCalls);
- p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims);
- p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads);
- p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
- p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads);
- p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
- p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads);
- p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
- p+=sprintf(p,"Num vertex loaders: %i\n",stats.numVertexLoaders);
-
+ //p+=sprintf(p,"dlists created: %i\n",stats.numDListsCreated);
+ //p+=sprintf(p,"dlists alive: %i\n",stats.numDListsAlive);
+ //p+=sprintf(p,"strip joins: %i\n",stats.numJoins);
+ p+=sprintf(p,"primitives: %i\n",stats.thisFrame.numPrims);
+ p+=sprintf(p,"primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
+ p+=sprintf(p,"buffer splits: %i\n",stats.thisFrame.numBufferSplits);
+ p+=sprintf(p,"draw calls: %i\n",stats.thisFrame.numDrawCalls);
+ p+=sprintf(p,"primitives (DL): %i\n",stats.thisFrame.numDLPrims);
+ p+=sprintf(p,"XF loads: %i\n",stats.thisFrame.numXFLoads);
+ p+=sprintf(p,"XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
+ p+=sprintf(p,"CP loads: %i\n",stats.thisFrame.numCPLoads);
+ p+=sprintf(p,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
+ p+=sprintf(p,"BP loads: %i\n",stats.thisFrame.numBPLoads);
+ p+=sprintf(p,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
+ p+=sprintf(p,"vertex loaders: %i\n",stats.numVertexLoaders);
std::string text = st;
VertexLoaderManager::AppendListToString(&text);
@@ -896,7 +875,7 @@ void Renderer::SwapBuffers()
}
else
{
- if(g_Config.bShowFPS)
+ if (g_Config.bShowFPS)
{
char strfps[25];
sprintf(strfps, "%d\n", s_fps);
@@ -928,14 +907,15 @@ void Renderer::SwapBuffers()
GL_REPORT_ERRORD();
//clean out old stuff from caches
- frameCount++;
PixelShaderMngr::Cleanup();
TextureMngr::Cleanup();
+ frameCount++;
// New frame
stats.ResetFrame();
-
- glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, s_uFramebuffer );
+
+ // Render to the framebuffer.
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
if (nZBufferRender > 0) {
if (--nZBufferRender == 0) {
@@ -962,7 +942,7 @@ bool Renderer::SaveRenderTarget(const char* filename, int jpeg)
if (bflip) {
// swap scanlines
std::vector<u32> scanline(nBackbufferWidth);
- for(int i = 0; i < nBackbufferHeight/2; ++i) {
+ for (int i = 0; i < nBackbufferHeight/2; ++i) {
memcpy(&scanline[0], &data[i*nBackbufferWidth], nBackbufferWidth*4);
memcpy(&data[i*nBackbufferWidth], &data[(nBackbufferHeight-i-1)*nBackbufferWidth], nBackbufferWidth*4);
memcpy(&data[(nBackbufferHeight-i-1)*nBackbufferWidth], &scanline[0], nBackbufferWidth*4);
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h
index f80e58e1e3..9de2f3ee98 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h
@@ -15,6 +15,55 @@
// Official SVN repository and contact information can be found at
// 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
#define GCOGL_RENDER
@@ -35,22 +84,21 @@ class Renderer
public:
enum RenderMode
{
- RM_Normal=0, // normal target as color0, ztarget as color1
- RM_ZBufferOnly, // zbuffer as color 0
- 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
+ RM_Normal=0, // normal target as color0, ztarget as color1
+ RM_ZBufferOnly, // zbuffer as color0
+ 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
};
- static bool Create2();
+ static bool Init();
static void Shutdown();
// initialize opengl standard values (like viewport)
- static bool Initialize();
+ static bool InitializeGL();
static void AddMessage(const char* str, u32 ms);
static void ProcessMessages(); // draw the current messages on the screen
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);
@@ -65,7 +113,7 @@ public:
static bool HaveStencilBuffer();
static void SetZBufferRender(); // sets rendering of the zbuffer using MRTs
- static u32 GetZBufferTarget();
+ static GLuint GetZBufferTarget();
static void SetColorMask();
static bool SetScissorRect();
@@ -73,10 +121,12 @@ public:
static void SetRenderMode(RenderMode mode);
static RenderMode GetRenderMode();
- static void SetRenderTarget(u32 targ); // if targ is 0, sets to original render target
- static void SetDepthTarget(u32 targ);
- static void SetFramebuffer(u32 fb);
- static u32 GetRenderTarget();
+ static void SetRenderTarget(GLuint targ); // if targ is 0, sets to original render target
+ static void SetDepthTarget(GLuint targ);
+
+ static void SetFramebuffer(GLuint fb);
+
+ static GLuint GetRenderTarget();
// Finish up the current frame, print some stats
static void Swap(const TRectangle& rc);
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp
index 8207794088..c1a2193d82 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp
@@ -120,7 +120,7 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr)
m_numLoadedVertices = 0;
m_VertexSize = 0;
m_numPipelineStages = 0;
- m_NativeFmt = new NativeVertexFormat();
+ m_NativeFmt = NativeVertexFormat::Create();
loop_counter = 0;
VertexLoader_Normal::Init();
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp
index 709ae7e3de..21c68ed86d 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp
@@ -344,10 +344,11 @@ void VertexShaderMngr::SetConstants()
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
// [0] = width/2
// [1] = height/2
- // [2] = 16777215 * (farz-nearz)
+ // [2] = 16777215 * (farz - nearz)
// [3] = xorig + width/2 + 342
// [4] = yorig + height/2 + 342
// [5] = 16777215 * farz
+
/*INFO_LOG("view: topleft=(%f,%f), wh=(%f,%f), z=(%f,%f)\n",
rawViewport[3]-rawViewport[0]-342, rawViewport[4]+rawViewport[1]-342,
2 * rawViewport[0], 2 * rawViewport[1],
@@ -363,9 +364,10 @@ void VertexShaderMngr::SetConstants()
int overfl;
int xoffs = 0, yoffs = 0;
int wid, hei, actualWid, actualHei;
+
int winw = OpenGL_GetWidth();
int winh = OpenGL_GetHeight();
- float ratio = (float)winw / (float)winh / fourThree;
+ float ratio = (float)winw / (float)winh / fourThree;
if (g_Config.bKeepAR)
{
// Check if height or width is the limiting factor
@@ -421,6 +423,7 @@ void VertexShaderMngr::SetConstants()
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);
}
+
glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f);
}
@@ -448,11 +451,11 @@ void VertexShaderMngr::SetConstants()
g_fProjectionMatrix[11] = -(0.0f - xfregs.rawProjection[5]);
// Before R945 Hack
- if(g_Config.bProjectionHax1 && !g_Config.bProjectionHax2)
+ if (g_Config.bProjectionHax1 && !g_Config.bProjectionHax2)
g_fProjectionMatrix[11] = -(1.0f - xfregs.rawProjection[5]);
// R844 Hack
- if(!g_Config.bProjectionHax1 && g_Config.bProjectionHax2)
+ if (!g_Config.bProjectionHax1 && g_Config.bProjectionHax2)
g_fProjectionMatrix[11] = xfregs.rawProjection[5];
//--------------------------------
@@ -802,9 +805,9 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
}
break;
case 0x1012: // dual tex transform
- if (xfregs.bEnableDualTexTransform != (data&1)) {
+ if (xfregs.bEnableDualTexTransform != (data & 1)) {
VertexManager::Flush();
- xfregs.bEnableDualTexTransform = data&1;
+ xfregs.bEnableDualTexTransform = data & 1;
}
break;
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp b/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp
index 68aadb3849..ed04413a38 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp
@@ -30,8 +30,6 @@
#define XFB_USE_SHADERS 1
enum {
- XFB_WIDTH = 640,
- XFB_HEIGHT = 480, // 528 is max height.
XFB_BUF_HEIGHT = 538, //480,
// TODO: figure out what to do with PAL
};
@@ -121,7 +119,7 @@ void XFB_Init()
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, XFB_WIDTH, XFB_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, xfb_buffer);
// used to render EFB
- glGenFramebuffersEXT( 1, &s_xfbFrameBuffer);
+ glGenFramebuffersEXT(1, &s_xfbFrameBuffer);
glGenRenderbuffersEXT(1, &s_xfbRenderBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, nBackbufferWidth, nBackbufferHeight);
@@ -145,10 +143,9 @@ void XFB_Shutdown()
void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt)
{
Renderer::SetRenderMode(Renderer::RM_Normal);
-
Renderer::ResetGLState();
- // switch to XFB frame buffer
+ // Switch to XFB frame buffer.
Renderer::SetFramebuffer(s_xfbFrameBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);
@@ -172,7 +169,7 @@ void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt)
GL_REPORT_ERRORD();
int width = sourceRc.right - sourceRc.left;
- int height = sourceRc.bottom - sourceRc.top;
+ int height = sourceRc.bottom - sourceRc.top;
glReadPixels(sourceRc.left, sourceRc.top, width, height, GL_RGBA, GL_UNSIGNED_BYTE, efb_buffer);
GL_REPORT_ERRORD();
@@ -215,10 +212,10 @@ void XFB_Draw(u8 *xfb_in_ram, u32 width, u32 height, s32 yOffset)
GL_REPORT_ERRORD();
glBegin(GL_QUADS);
- glTexCoord2f(width, height + yOffset); glVertex2f(1,-1);
- glTexCoord2f(width, 0 + yOffset); glVertex2f(1,1);
- glTexCoord2f(0, 0 + yOffset); glVertex2f(-1,1);
- glTexCoord2f(0, height + yOffset); glVertex2f(-1,-1);
+ glTexCoord2f(width, height + yOffset); glVertex2f( 1,-1);
+ glTexCoord2f(width, 0 + yOffset); glVertex2f( 1, 1);
+ glTexCoord2f(0, 0 + yOffset); glVertex2f(-1, 1);
+ glTexCoord2f(0, height + yOffset); glVertex2f(-1,-1);
glEnd();
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp
index ed852179a7..60d743304e 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp
@@ -262,8 +262,8 @@ void Video_DoState(unsigned char **ptr, int mode) {
void Video_Prepare(void)
{
OpenGL_MakeCurrent();
- if (!Renderer::Create2()) {
- g_VideoInitialize.pLog("Renderer::Create2 failed\n", TRUE);
+ if (!Renderer::Init()) {
+ 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");
exit(1);
}