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 +// Abstracts the (few) differences between dynamically loading DLLs under Windows +// and .so / .dylib under Linux/MacOSX. class DynamicLibrary { - public: +public: + DynamicLibrary(); + int Load(const char *filename); + int Unload(); + void *Get(const char *funcname) const; + bool IsLoaded() const { return library != 0; } - 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; +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); + } + + va_end(args); + return ret; } -bool DefaultMsgHandler(const char* caption, const char* text, - bool yes_no) { - +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; -public: - NativeVertexFormat(); - ~NativeVertexFormat(); +protected: + NativeVertexFormat() {} - void Initialize(const PortableVertexDeclaration &vtx_decl); - void SetupVertexPointers() const; +public: + virtual ~NativeVertexFormat() {} + + virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0; + virtual void SetupVertexPointers() const = 0; + + 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 @@ -1201,6 +1201,10 @@ RelativePath=".\Src\DecodedVArray.h" > + + @@ -1273,6 +1277,14 @@ RelativePath=".\Src\PixelShader.h" > + + + + @@ -1281,14 +1293,6 @@ RelativePath=".\Src\Render.h" > - - - - @@ -1317,6 +1321,14 @@ RelativePath=".\Src\VertexShader.h" > + + + + 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 similarity index 67% rename from Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.cpp rename to 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 similarity index 68% rename from Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.h rename to 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 -#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 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 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 +#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 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 + +#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 + +#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 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 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 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); }