diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h index 1280b3dc30..1d38fcccaa 100644 --- a/Source/Core/Common/Src/Common.h +++ b/Source/Core/Common/Src/Common.h @@ -49,10 +49,12 @@ #endif #ifdef _WIN32 -#ifdef _WIN32 + +// By default, MS' stdio implementation does not support 64-bit offsets. +// This little hack fixes that, keeping the code portable to linux where fseek and fread +// do support 64-bit offsets in modern distributions. #define fseek _fseeki64 #define ftell _ftelli64 -#endif #define POSIX 0 #define NOMINMAX @@ -128,11 +130,9 @@ typedef union _LARGE_INTEGER #undef max template -inline T min(const T& a, const T& b) {return(a > b ? b : a);} - - +inline T min(const T& a, const T& b) {return a > b ? b : a;} template -inline T max(const T& a, const T& b) {return(a > b ? a : b);} +inline T max(const T& a, const T& b) {return a > b ? a : b;} // Byte ordering diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp index bd9eb34dd3..a06b55836e 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp @@ -158,11 +158,11 @@ bool CFileSystemGCWii::InitFileSystem() { if (Read32(0x18) == 0x5D1C9EA3) { - m_OffsetShift = 2; + m_OffsetShift = 2; // Wii file system } else if (Read32(0x1c) == 0xC2339F3D) { - m_OffsetShift = 0; + m_OffsetShift = 0; // GC file system } else { @@ -206,8 +206,6 @@ bool CFileSystemGCWii::InitFileSystem() return true; } -// __________________________________________________________________________________________________ -// // Changed this stuff from C++ string to C strings for speed in debug mode. Doesn't matter in release, but // std::string is SLOW in debug mode. size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, u64 _NameTableOffset) @@ -248,5 +246,4 @@ size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _ return CurrentIndex; } -} // namespace - +} // namespace diff --git a/Source/Core/VideoCommon/Src/DataReader.h b/Source/Core/VideoCommon/Src/DataReader.h index 09623a5c69..3f465a46e5 100644 --- a/Source/Core/VideoCommon/Src/DataReader.h +++ b/Source/Core/VideoCommon/Src/DataReader.h @@ -18,11 +18,8 @@ #ifndef _DATAREADER_H #define _DATAREADER_H - extern u8* g_pVideoData; - - inline u8 DataPeek8(u32 _uOffset) { return g_pVideoData[_uOffset]; @@ -46,14 +43,14 @@ inline u8 DataReadU8() inline u16 DataReadU16() { u16 tmp = Common::swap16(*(u16*)g_pVideoData); - g_pVideoData+=2; + g_pVideoData += 2; return tmp; } inline u32 DataReadU32() { u32 tmp = Common::swap32(*(u32*)g_pVideoData); - g_pVideoData+=4; + g_pVideoData += 4; return tmp; } @@ -61,7 +58,7 @@ inline float DataReadF32() { union {u32 i; float f;} temp; temp.i = Common::swap32(*(u32*)g_pVideoData); - g_pVideoData+=4; + g_pVideoData += 4; float tmp = temp.f; return tmp; } @@ -77,4 +74,3 @@ inline void DataSkip(u32 skip) } #endif - diff --git a/Source/Core/VideoCommon/Src/Profiler.cpp b/Source/Core/VideoCommon/Src/Profiler.cpp index 9c7a543c77..b66a4d32d2 100644 --- a/Source/Core/VideoCommon/Src/Profiler.cpp +++ b/Source/Core/VideoCommon/Src/Profiler.cpp @@ -15,20 +15,14 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "Common.h" +// Simple profiler +#include "Common.h" #include "Profiler.h" - -//////////////////// -// Small profiler // -//////////////////// #include #include #include -using namespace std; - -int g_bWriteProfile=0; #ifdef _WIN32 @@ -45,7 +39,14 @@ int g_bWriteProfile=0; #pragma intrinsic(__rdtsc) #endif -static u64 luPerfFreq=0; +// Globals +static u64 luPerfFreq = 0; +#ifdef DVPROFILE +int g_bWriteProfile = 1; +#else +int g_bWriteProfile = 1; +#endif + inline u64 GET_PROFILE_TIME() { #if defined (_MSC_VER) && _MSC_VER >= 1400 @@ -57,11 +58,10 @@ inline u64 GET_PROFILE_TIME() #endif } #else -static u64 luPerfFreq=1000000; +static u64 luPerfFreq = 1000000; #define GET_PROFILE_TIME() //GetCpuTick() #endif - struct DVPROFSTRUCT; struct DVPROFSTRUCT @@ -70,25 +70,27 @@ struct DVPROFSTRUCT { DATA(u64 time, u32 user = 0) : dwTime(time), dwUserData(user) {} DATA() : dwTime(0), dwUserData(0) {} - + u64 dwTime; u32 dwUserData; }; ~DVPROFSTRUCT() { - list::iterator it = listpChild.begin(); - while(it != listpChild.end() ) { - delete *it; *it = NULL; + std::list::iterator it = listpChild.begin(); + while (it != listpChild.end()) { + delete *it; + *it = NULL; ++it; } } - list listTimes; // before DVProfEnd is called, contains the global time it started - // after DVProfEnd is called, contains the time it lasted - // the list contains all the tracked times + // before DVProfEnd is called, contains the global time it started + // after DVProfEnd is called, contains the time it lasted + // the list contains all the tracked times + std::list listTimes; + char pname[256]; - - list listpChild; // other profilers called during this profiler period + std::list listpChild; // other profilers called during this profiler period }; struct DVPROFTRACK @@ -98,13 +100,19 @@ struct DVPROFTRACK DVPROFSTRUCT* pprof; }; -list g_listCurTracking; // the current profiling functions, the back element is the - // one that will first get popped off the list when DVProfEnd is called - // the pointer is an element in DVPROFSTRUCT::listTimes -list g_listProfilers; // the current profilers, note that these are the parents - // any profiler started during the time of another is held in - // DVPROFSTRUCT::listpChild -list g_listAllProfilers; // ignores the hierarchy, pointer to elements in g_listProfilers +// the current profiling functions, the back element is the +// one that will first get popped off the list when DVProfEnd is called +// the pointer is an element in DVPROFSTRUCT::listTimes +static std::list g_listCurTracking; + +// the current profilers, note that these are the parents +// any profiler started during the time of another is held in +// DVPROFSTRUCT::listpChild +static std::list g_listProfilers; + +// ignores the hierarchy, pointer to elements in g_listProfilers +static std::list g_listAllProfilers; + void DVProfRegister(const char *pname) { @@ -123,7 +131,7 @@ void DVProfRegister(const char *pname) } #endif - list::iterator it = g_listAllProfilers.begin(); + std::list::iterator it = g_listAllProfilers.begin(); // while(it != g_listAllProfilers.end() ) { // @@ -191,19 +199,15 @@ struct DVTIMEINFO u64 uInclusive, uExclusive; }; -map mapAggregateTimes; +std::map mapAggregateTimes; -u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident) +u64 DVProfWriteStruct(FILE* f, const DVPROFSTRUCT* p, int ident) { fprintf(f, "%*s%s - ", ident, "", p->pname); - - list::iterator ittime = p->listTimes.begin(); - + std::list::const_iterator ittime = p->listTimes.begin(); u64 utime = 0; - - while(ittime != p->listTimes.end() ) { + while (ittime != p->listTimes.end()) { utime += ittime->dwTime; - if (ittime->dwUserData) fprintf(f, "time: %d, user: 0x%8.8x", (u32)ittime->dwTime, ittime->dwUserData); else @@ -212,9 +216,9 @@ u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident) } // yes this is necessary, maps have problems with constructors on their type - map::iterator ittimes = mapAggregateTimes.find(p->pname); + std::map::iterator ittimes = mapAggregateTimes.find(p->pname); if (ittimes == mapAggregateTimes.end()) { - ittimes = mapAggregateTimes.insert(map::value_type(p->pname, DVTIMEINFO())).first; + ittimes = mapAggregateTimes.insert(std::map::value_type(p->pname, DVTIMEINFO())).first; ittimes->second.uExclusive = 0; ittimes->second.uInclusive = 0; } @@ -223,11 +227,10 @@ u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident) fprintf(f, "\n"); - list::iterator itprof = p->listpChild.begin(); + std::list::const_iterator itprof = p->listpChild.begin(); u64 uex = utime; - while(itprof != p->listpChild.end() ) { - + while (itprof != p->listpChild.end()) { uex -= DVProfWriteStruct(f, *itprof, ident+4); ++itprof; } @@ -247,38 +250,35 @@ void DVProfWrite(const char* pfilename, u32 frames) // pop back any unused mapAggregateTimes.clear(); - list::iterator it = g_listProfilers.begin(); + std::list::iterator it = g_listProfilers.begin(); - while(it != g_listProfilers.end() ) { + while (it != g_listProfilers.end() ) { DVProfWriteStruct(f, &(*it), 0); ++it; } - { - map::iterator iter; - fprintf(f, "\n\n-------------------------------------------------------------------\n\n"); + std::map::const_iterator iter; + fprintf(f, "\n\n-------------------------------------------------------------------\n\n"); - u64 uTotal[2] = {0}; - double fiTotalTime[2]; + u64 uTotal[2] = {0}; + double fiTotalTime[2]; - for(iter = mapAggregateTimes.begin(); iter != mapAggregateTimes.end(); ++iter) { - uTotal[0] += iter->second.uExclusive; - uTotal[1] += iter->second.uInclusive; - } - - fprintf(f, "total times (%d): ex: %Lu ", frames, 1000000*uTotal[0]/(luPerfFreq*(u64)frames)); - fprintf(f, "inc: %Lu\n", 1000000 * uTotal[1]/(luPerfFreq*(u64)frames)); - - fiTotalTime[0] = 1.0 / (double)uTotal[0]; - fiTotalTime[1] = 1.0 / (double)uTotal[1]; - - // output the combined times - for(iter = mapAggregateTimes.begin(); iter != mapAggregateTimes.end(); ++iter) { - fprintf(f, "%s - ex: %f inc: %f\n", iter->first.c_str(), (float)((double)iter->second.uExclusive * fiTotalTime[0]), - (float)((double)iter->second.uInclusive * fiTotalTime[1])); - } + for (iter = mapAggregateTimes.begin(); iter != mapAggregateTimes.end(); ++iter) { + uTotal[0] += iter->second.uExclusive; + uTotal[1] += iter->second.uInclusive; } + fprintf(f, "total times (%d): ex: %Lu ", frames, 1000000 * uTotal[0] / (luPerfFreq*(u64)frames)); + fprintf(f, "inc: %Lu\n", 1000000 * uTotal[1]/(luPerfFreq*(u64)frames)); + + fiTotalTime[0] = 1.0 / (double)uTotal[0]; + fiTotalTime[1] = 1.0 / (double)uTotal[1]; + + // output the combined times + for (iter = mapAggregateTimes.begin(); iter != mapAggregateTimes.end(); ++iter) { + fprintf(f, "%s - ex: %f inc: %f\n", iter->first.c_str(), (float)((double)iter->second.uExclusive * fiTotalTime[0]), + (float)((double)iter->second.uInclusive * fiTotalTime[1])); + } fclose(f); } diff --git a/Source/Core/VideoCommon/Src/Profiler.h b/Source/Core/VideoCommon/Src/Profiler.h index 561ee7aa13..5cc8d55cd1 100644 --- a/Source/Core/VideoCommon/Src/Profiler.h +++ b/Source/Core/VideoCommon/Src/Profiler.h @@ -21,17 +21,23 @@ #ifndef _PROFILER_H #define _PROFILER_H +#include + +#include "Common.h" + // #define DVPROFILE // comment out to disable profiling extern int g_bWriteProfile; // global variable to enable/disable profiling (if DVPROFILE is defined) -// IMPORTANT: For every Register there must be an End +// IMPORTANT: For every Register there must be an End. Use the below DVProfileFunc utility class for safety. void DVProfRegister(const char* pname); // first checks if this profiler exists in g_listProfilers void DVProfEnd(u32 dwUserData); -void DVProfWrite(const char* pfilename, u32 frames = 0); -void DVProfClear(); // clears all the profi lers -#if defined(DVPROFILE) && (defined(_WIN32)||defined(WIN32)) +void DVProfWrite(const char* pfilename, u32 frames = 0); +void DVProfGenReport(std::string *report); +void DVProfClear(); // clears all the profilers + +#if defined(DVPROFILE) && defined(_WIN32) #ifdef _MSC_VER diff --git a/Source/Core/VideoCommon/VideoCommon.vcproj b/Source/Core/VideoCommon/VideoCommon.vcproj index bc489c85af..ce0a0a536c 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcproj +++ b/Source/Core/VideoCommon/VideoCommon.vcproj @@ -490,6 +490,14 @@ AssemblerOutput="4" /> + + + + + + + + + + + diff --git a/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.cpp b/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.cpp index 7bd1f0cdbd..30e1a4731b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.cpp @@ -19,6 +19,7 @@ #include "Globals.h" #include "Common.h" +#include "Profiler.h" #include "BPStructs.h" #include "OpcodeDecoding.h" #include "TextureCache.h" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.h b/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.h index 99a20f7f68..cc493276ea 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.h @@ -23,7 +23,6 @@ #include "BPMemory.h" void BPInit(); -//bool BPWritten(int addr, int changes); void LoadBPReg(u32 value0); void ActivateTextures(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp b/Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp index 38a16cf49a..00397e7b37 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/OpcodeDecoding.cpp @@ -28,6 +28,7 @@ #include "D3DBase.h" #include "Common.h" +#include "Profiler.h" #include "Globals.h" #include "VertexHandler.h" #include "TransformEngine.h" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.cpp index 70e7936380..3277c1ae44 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/ShaderManager.cpp @@ -17,6 +17,7 @@ #include "D3DBase.h" #include "Utils.h" +#include "Profiler.h" #include "Globals.h" #include "ShaderManager.h" #include "VertexLoader.h" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TransformEngine.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TransformEngine.cpp index 66a64cbfca..74fabafae0 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TransformEngine.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TransformEngine.cpp @@ -18,6 +18,7 @@ #include #include "Common.h" +#include "Profiler.h" #include "Globals.h" #include "Vec3.h" #include "TransformEngine.h" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Utils.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Utils.cpp index fe0c9e83ab..75cca658b7 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Utils.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Utils.cpp @@ -43,274 +43,3 @@ LRESULT CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM /*lPar } return FALSE; } - - -//////////////////// -// Small profiler // -//////////////////// -#include -#include -#include -using namespace std; - -int g_bWriteProfile=0; - -#ifdef _WIN32 - -#if defined (_MSC_VER) && _MSC_VER >= 1400 -#define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set -#define _interlockedbittestandreset workaround_ms_header_bug_platform_sdk6_reset -#define _interlockedbittestandset64 workaround_ms_header_bug_platform_sdk6_set64 -#define _interlockedbittestandreset64 workaround_ms_header_bug_platform_sdk6_reset64 -#include -#undef _interlockedbittestandset -#undef _interlockedbittestandreset -#undef _interlockedbittestandset64 -#undef _interlockedbittestandreset64 -#pragma intrinsic(__rdtsc) -#endif - -static u64 luPerfFreq=0; -inline u64 GET_PROFILE_TIME() -{ -#if defined (_MSC_VER) && _MSC_VER >= 1400 - return __rdtsc(); -#else - LARGE_INTEGER lu; - QueryPerformanceCounter(&lu); - return lu.QuadPart; -#endif -} -#else -static u64 luPerfFreq = 1000000; -#define GET_PROFILE_TIME() //GetCpuTick() -#endif - - -struct DVPROFSTRUCT; - -struct DVPROFSTRUCT -{ - struct DATA - { - DATA(u64 time, u32 user = 0) : dwTime(time), dwUserData(user) {} - DATA() : dwTime(0), dwUserData(0) {} - - u64 dwTime; - u32 dwUserData; - }; - - ~DVPROFSTRUCT() { - list::iterator it = listpChild.begin(); - while(it != listpChild.end() ) { - delete *it; *it = NULL; - ++it; - } - } - - list listTimes; // before DVProfEnd is called, contains the global time it started - // after DVProfEnd is called, contains the time it lasted - // the list contains all the tracked times - char pname[256]; - - list listpChild; // other profilers called during this profiler period -}; - -struct DVPROFTRACK -{ - u32 dwUserData; - DVPROFSTRUCT::DATA* pdwTime; - DVPROFSTRUCT* pprof; -}; - -list g_listCurTracking; // the current profiling functions, the back element is the - // one that will first get popped off the list when DVProfEnd is called - // the pointer is an element in DVPROFSTRUCT::listTimes -list g_listProfilers; // the current profilers, note that these are the parents - // any profiler started during the time of another is held in - // DVPROFSTRUCT::listpChild -list g_listAllProfilers; // ignores the hierarchy, pointer to elements in g_listProfilers - -void DVProfRegister(char* pname) -{ - if( !g_bWriteProfile ) - return; - -#ifdef _WIN32 - if( luPerfFreq <= 1 ) { -#if defined (_MSC_VER) && _MSC_VER >= 1400 - luPerfFreq = 1000000; -#else - LARGE_INTEGER temp; - QueryPerformanceFrequency(&temp); - luPerfFreq = temp.QuadPart; -#endif - } -#endif - - list::iterator it = g_listAllProfilers.begin(); - -// while(it != g_listAllProfilers.end() ) { -// -// if( _tcscmp(pname, (*it)->pname) == 0 ) { -// (*it)->listTimes.push_back(timeGetTime()); -// DVPROFTRACK dvtrack; -// dvtrack.pdwTime = &(*it)->listTimes.back(); -// dvtrack.pprof = *it; -// g_listCurTracking.push_back(dvtrack); -// return; -// } -// -// ++it; -// } - - // else add in a new profiler to the appropriate parent profiler - DVPROFSTRUCT* pprof = NULL; - - if( g_listCurTracking.size() > 0 ) { - assert( g_listCurTracking.back().pprof != NULL ); - g_listCurTracking.back().pprof->listpChild.push_back(new DVPROFSTRUCT()); - pprof = g_listCurTracking.back().pprof->listpChild.back(); - } - else { - g_listProfilers.push_back(DVPROFSTRUCT()); - pprof = &g_listProfilers.back(); - } - - strncpy(pprof->pname, pname, 256); - - // setup the profiler for tracking - pprof->listTimes.push_back(DVPROFSTRUCT::DATA(GET_PROFILE_TIME())); - - DVPROFTRACK dvtrack; - dvtrack.pdwTime = &pprof->listTimes.back(); - dvtrack.pprof = pprof; - dvtrack.dwUserData = 0; - - g_listCurTracking.push_back(dvtrack); - - // add to all profiler list - g_listAllProfilers.push_back(pprof); -} - -void DVProfEnd(u32 dwUserData) -{ - if( !g_bWriteProfile ) - return; - if( g_listCurTracking.size() == 0 ) - return; - - DVPROFTRACK dvtrack = g_listCurTracking.back(); - - assert( dvtrack.pdwTime != NULL && dvtrack.pprof != NULL ); - - dvtrack.pdwTime->dwTime = GET_PROFILE_TIME()- dvtrack.pdwTime->dwTime; - dvtrack.pdwTime->dwUserData= dwUserData; - - g_listCurTracking.pop_back(); -} - -struct DVTIMEINFO -{ - DVTIMEINFO() : uInclusive(0), uExclusive(0) {} - u64 uInclusive, uExclusive; -}; - -map mapAggregateTimes; - -u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident) -{ - fprintf(f, "%*s%s - ", ident, "", p->pname); - - list::iterator ittime = p->listTimes.begin(); - - u64 utime = 0; - - while(ittime != p->listTimes.end() ) { - utime += ittime->dwTime; - - if( ittime->dwUserData ) - fprintf(f, "time: %d, user: 0x%8.8x", (u32)ittime->dwTime, ittime->dwUserData); - else - fprintf(f, "time: %d", (u32)ittime->dwTime); - ++ittime; - } - - // yes this is necessary, maps have problems with constructors on their type - map::iterator ittimes = mapAggregateTimes.find(p->pname); - if( ittimes == mapAggregateTimes.end() ) { - ittimes = mapAggregateTimes.insert(map::value_type(p->pname, DVTIMEINFO())).first; - ittimes->second.uExclusive = 0; - ittimes->second.uInclusive = 0; - } - - ittimes->second.uInclusive += utime; - - fprintf(f, "\n"); - - list::iterator itprof = p->listpChild.begin(); - - u64 uex = utime; - while(itprof != p->listpChild.end() ) { - - uex -= DVProfWriteStruct(f, *itprof, ident+4); - ++itprof; - } - - if( uex > utime ) { - uex = 0; - } - - ittimes->second.uExclusive += uex; - return utime; -} - -void DVProfWrite(char* pfilename, u32 frames) -{ - assert( pfilename != NULL ); - FILE* f = fopen(pfilename, "w"); - - // pop back any unused - mapAggregateTimes.clear(); - list::iterator it = g_listProfilers.begin(); - - while(it != g_listProfilers.end() ) { - DVProfWriteStruct(f, &(*it), 0); - ++it; - } - - { - map::iterator it; - fprintf(f, "\n\n-------------------------------------------------------------------\n\n"); - - u64 uTotal[2] = {0}; - double fiTotalTime[2]; - - for(it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it) { - uTotal[0] += it->second.uExclusive; - uTotal[1] += it->second.uInclusive; - } - - fprintf(f, "total times (%d): ex: %Lu ", frames, 1000000*uTotal[0]/(luPerfFreq*(u64)frames)); - fprintf(f, "inc: %Lu\n", 1000000 * uTotal[1]/(luPerfFreq*(u64)frames)); - - fiTotalTime[0] = 1.0 / (double)uTotal[0]; - fiTotalTime[1] = 1.0 / (double)uTotal[1]; - - // output the combined times - for(it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it) { - fprintf(f, "%s - ex: %f inc: %f\n", it->first.c_str(), (float)((double)it->second.uExclusive * fiTotalTime[0]), - (float)((double)it->second.uInclusive * fiTotalTime[1])); - } - } - - - fclose(f); -} - -void DVProfClear() -{ - g_listCurTracking.clear(); - g_listProfilers.clear(); - g_listAllProfilers.clear(); -} diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Utils.h b/Source/Plugins/Plugin_VideoDX9/Src/Utils.h index 3ddd531620..bbd1fc64c3 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Utils.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/Utils.h @@ -60,54 +60,4 @@ inline float Memory_Read_Float(u32 _uAddress) return *(float*)&uTemp; } -//// -// profiling -/// - -extern int g_bWriteProfile; // global variable to enable/disable profiling (if DVPROFILE is defined) - -// IMPORTANT: For every Register there must be an End -void DVProfRegister(char* pname); // first checks if this profiler exists in g_listProfilers -void DVProfEnd(u32 dwUserData); -void DVProfWrite(char* pfilename, u32 frames = 0); -void DVProfClear(); // clears all the profilers - -// #define DVPROFILE // comment out to disable profiling - -#if defined(DVPROFILE) && (defined(_WIN32)||defined(WIN32)) - -#ifdef _MSC_VER - -#ifndef __PRETTY_FUNCTION__ -#define __PRETTY_FUNCTION__ __FUNCTION__ -#endif - -#endif - -#define DVSTARTPROFILE() DVProfileFunc _pf(__PRETTY_FUNCTION__); - -class DVProfileFunc -{ -public: - u32 dwUserData; - DVProfileFunc(char* pname) { DVProfRegister(pname); dwUserData = 0; } - DVProfileFunc(char* pname, u32 dwUserData) : dwUserData(dwUserData) { DVProfRegister(pname); } - ~DVProfileFunc() { DVProfEnd(dwUserData); } -}; - -#else - -#define DVSTARTPROFILE() - -class DVProfileFunc -{ -public: - u32 dwUserData; - __forceinline DVProfileFunc(char* pname) {} - __forceinline DVProfileFunc(char* pname, u32 dwUserData) { } - ~DVProfileFunc() {} -}; - -#endif - #endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexHandler.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexHandler.cpp index e8e1589920..b07014f31b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexHandler.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexHandler.cpp @@ -18,6 +18,7 @@ #include "D3DBase.h" #include "Common.h" +#include "Profiler.h" #include "Globals.h" #include "VertexHandler.h" #include "OpcodeDecoding.h" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexLoader.cpp index ee6125e44f..98878567af 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexLoader.cpp @@ -20,6 +20,7 @@ #include "x64Emitter.h" #include "Common.h" +#include "Profiler.h" #include "VertexHandler.h" #include "VertexLoader.h" #include "XFStructs.h" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/XFStructs.cpp b/Source/Plugins/Plugin_VideoDX9/Src/XFStructs.cpp index 0059de7514..4b7b17abbe 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/XFStructs.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/XFStructs.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "stdafx.h" +#include "Profiler.h" #include "XFStructs.h" #include "Render.h" #include "main.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj index 3eb405d4c0..719465d0df 100644 --- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj +++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj @@ -1,7 +1,7 @@ + + + + + + + + diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp index 997d57cdb1..96877fa2d0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp @@ -22,6 +22,7 @@ #include "Profiler.h" #include "VertexLoader.h" +#include "VertexManager.h" #include "BPStructs.h" #include "Render.h" @@ -65,18 +66,13 @@ void BPInit() } -// ======================================================================================= -// Called att the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > -// LoadBPReg() -// --------------- +// Called att the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg void BPWritten(int addr, int changes, int newval) { - DVSTARTPROFILE(); - //static int count = 0; //ERROR_LOG("(%d) %x: %x\n", count++, addr, newval); - switch(addr) + switch (addr) { case BPMEM_GENMODE: if (changes) { @@ -139,7 +135,7 @@ void BPWritten(int addr, int changes, int newval) glDepthMask(GL_FALSE); } - if( !bpmem.zmode.updateenable ) + if (!bpmem.zmode.updateenable) Renderer::SetRenderMode(Renderer::RM_Normal); } break; @@ -165,12 +161,11 @@ void BPWritten(int addr, int changes, int newval) case BPMEM_LINEPTWIDTH: { - float fratio = VertexShaderMngr::rawViewport[0] != 0 ? (float)Renderer::GetTargetWidth()/640.0f : 1.0f; - if( bpmem.lineptwidth.linesize > 0 ) { - glLineWidth((float)bpmem.lineptwidth.linesize*fratio/6.0f); // scale by ratio of widths - } - if( bpmem.lineptwidth.pointsize > 0 ) - glPointSize((float)bpmem.lineptwidth.pointsize*fratio/6.0f); + float fratio = VertexShaderMngr::rawViewport[0] != 0 ? (float)Renderer::GetTargetWidth() / 640.0f : 1.0f; + if (bpmem.lineptwidth.linesize > 0) + glLineWidth((float)bpmem.lineptwidth.linesize * fratio / 6.0f); // scale by ratio of widths + if (bpmem.lineptwidth.pointsize > 0) + glPointSize((float)bpmem.lineptwidth.pointsize * fratio / 6.0f); break; } @@ -197,9 +192,9 @@ void BPWritten(int addr, int changes, int newval) } else glDisable(GL_BLEND); } - if( changes & 2 ) { - if( Renderer::CanBlendLogicOp() ) { - if( bpmem.blendmode.logicopenable ) { + if (changes & 2) { + if (Renderer::CanBlendLogicOp()) { + if (bpmem.blendmode.logicopenable) { glEnable(GL_COLOR_LOGIC_OP); PanicAlert("Logic Op Blend : %i", bpmem.blendmode.logicmode); glLogicOp(glLogicOpCodes[bpmem.blendmode.logicmode]); @@ -207,7 +202,7 @@ void BPWritten(int addr, int changes, int newval) else glDisable(GL_COLOR_LOGIC_OP); } //else { - // if( bpmem.blendmode.logicopenable ) { + // if (bpmem.blendmode.logicopenable) { // switch(bpmem.blendmode.logicmode) { // case 0: // clear dst to 0 // glEnable(GL_BLEND); @@ -254,13 +249,13 @@ void BPWritten(int addr, int changes, int newval) //if (bpmem.blendmode.dither) glEnable(GL_DITHER); //else glDisable(GL_DITHER); } - if( changes & 0xFE0) { - if( !bpmem.blendmode.subtract ) + if (changes & 0xFE0) { + if (!bpmem.blendmode.subtract) glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]); } if (changes & 0x800) { glBlendEquation(bpmem.blendmode.subtract?GL_FUNC_REVERSE_SUBTRACT:GL_FUNC_ADD); - if( bpmem.blendmode.subtract ) + if (bpmem.blendmode.subtract) glBlendFunc(GL_ONE, GL_ONE); else glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]); @@ -351,8 +346,8 @@ void BPWritten(int addr, int changes, int newval) if (changes) { VertexManager::Flush(); ((u32*)&bpmem)[addr] = newval; - if( !SetScissorRect() ) { - if( addr == BPMEM_SCISSORBR ) + if (!SetScissorRect()) { + if (addr == BPMEM_SCISSORBR ) ERROR_LOG("bad scissor!\n"); } } @@ -392,6 +387,154 @@ void BPWritten(int addr, int changes, int newval) PixelShaderMngr::SetTevKSelChanged(addr-0xf6); } break; + case 0x45: //GXSetDrawDone + VertexManager::Flush(); + switch (newval & 0xFF) + { + case 0x02: + g_VideoInitialize.pSetPEFinish(); // may generate interrupt + DebugLog("GXSetDrawDone SetPEFinish (value: 0x%02X)", (newval & 0xFFFF)); + break; + + default: + DebugLog("GXSetDrawDone ??? (value 0x%02X)", (newval & 0xFFFF)); + break; + } + break; + + case BPMEM_PE_TOKEN_ID: + g_VideoInitialize.pSetPEToken(static_cast(newval & 0xFFFF), FALSE); + DebugLog("SetPEToken 0x%04x", (newval & 0xFFFF)); + break; + + case BPMEM_PE_TOKEN_INT_ID: + g_VideoInitialize.pSetPEToken(static_cast(newval & 0xFFFF), TRUE); + DebugLog("SetPEToken + INT 0x%04x", (newval & 0xFFFF)); + break; + + case 0x67: // set gp metric? + break; + + case 0x52: + { + DVProfileFunc _pf("LoadBPReg:swap"); + VertexManager::Flush(); + + ((u32*)&bpmem)[addr] = newval; + TRectangle rc = { + (int)(bpmem.copyTexSrcXY.x), + (int)(bpmem.copyTexSrcXY.y), + (int)((bpmem.copyTexSrcXY.x + bpmem.copyTexSrcWH.x + 1)), + (int)((bpmem.copyTexSrcXY.y + bpmem.copyTexSrcWH.y + 1)) + }; + //Need another rc here to get it to scale. + TRectangle multirc = { + (int)(bpmem.copyTexSrcXY.x * MValueX), + (int)(bpmem.copyTexSrcXY.y * MValueY), + (int)((bpmem.copyTexSrcXY.x * MValueX + (bpmem.copyTexSrcWH.x + 1) * MValueX)), + (int)((bpmem.copyTexSrcXY.y * MValueY + (bpmem.copyTexSrcWH.y + 1) * MValueY)) + }; + + UPE_Copy PE_copy; + PE_copy.Hex = bpmem.triggerEFBCopy; + + if (PE_copy.copy_to_xfb == 0) { + // EFB to texture + // for some reason it sets bpmem.zcontrol.pixel_format to PIXELFMT_Z24 every time a zbuffer format is given as a dest to GXSetTexCopyDst + TextureMngr::CopyRenderTargetToTexture(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0, + (PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, &rc); + } + else { + // EFB to XFB + if(g_Config.bUseXFB) + { + XFB_Write(Memory_GetPtr(bpmem.copyTexDest<<5), multirc, (bpmem.copyMipMapStrideChannels << 4), bpmem.copyTexSrcWH.y + 1, bpmem.dispcopyyscale/256.0f); + } + else + { + Renderer::Swap(multirc); + } + g_VideoInitialize.pCopiedToXFB(); + } + + // clearing + if (PE_copy.clear) { + // clear color + Renderer::SetRenderMode(Renderer::RM_Normal); + + u32 nRestoreZBufferTarget = Renderer::GetZBufferTarget(); + + glViewport(0, 0, Renderer::GetTargetWidth(), Renderer::GetTargetHeight()); + + // Always set the scissor in case it was set by the game and has not been reset + glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom), + (multirc.right - multirc.left), (multirc.bottom - multirc.top)); + + VertexShaderMngr::SetViewportChanged(); + + // since clear operations use the source rectangle, have to do regular renders (glClear clears the entire buffer) + if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate || bpmem.zmode.updateenable) { + + GLbitfield bits = 0; + if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate) { + u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB; + glClearColor(((clearColor>>16)&0xff)*(1/255.0f),((clearColor>>8)&0xff)*(1/255.0f), + ((clearColor>>0)&0xff)*(1/255.0f),((clearColor>>24)&0xff)*(1/255.0f)); + bits |= GL_COLOR_BUFFER_BIT; + } + + if (bpmem.zmode.updateenable) { + glClearDepth((float)(bpmem.clearZValue&0xFFFFFF) / float(0xFFFFFF)); + bits |= GL_DEPTH_BUFFER_BIT; + } + + if (nRestoreZBufferTarget ) + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // don't clear ztarget here + + glClear(bits); + } + + if (bpmem.zmode.updateenable && nRestoreZBufferTarget) { // have to clear the target zbuffer + + glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); + GL_REPORT_ERRORD(); + + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + + // red should probably be the LSB + glClearColor(((bpmem.clearZValue>>0)&0xff)*(1/255.0f),((bpmem.clearZValue>>8)&0xff)*(1/255.0f), + ((bpmem.clearZValue>>16)&0xff)*(1/255.0f), 0); + glClear(GL_COLOR_BUFFER_BIT); + SetColorMask(); + GL_REPORT_ERRORD(); + } + + if (nRestoreZBufferTarget) { + // restore target + GLenum s_drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT}; + glDrawBuffers(2, s_drawbuffers); + } + + SetScissorRect(); // reset the scissor rect + } + } + break; + + case 0x65: //GXLoadTlut + { + DVProfileFunc _pf("LoadBPReg:GXLoadTlut"); + VertexManager::Flush(); + ((u32*)&bpmem)[addr] = newval; + + u32 tlutTMemAddr = (newval&0x3FF)<<9; + u32 tlutXferCount = (newval&0x1FFC00)>>5; + //do the transfer!! + memcpy_gc(texMem + tlutTMemAddr, g_VideoInitialize.pGetMemoryPointer((bpmem.tlutXferSrc&0xFFFFF)<<5), tlutXferCount); + // TODO(ector) : kill all textures that use this palette + // Not sure if it's a good idea, though. For now, we hash texture palettes + } + break; + default: switch(addr & 0xFC) //texture sampler filter @@ -490,7 +633,7 @@ void BPWritten(int addr, int changes, int newval) break; case 0x30: - if( changes ) { + if (changes) { VertexManager::Flush(); ((u32*)&bpmem)[addr] = newval; PixelShaderMngr::SetTexDimsChanged((addr>>1)&0x7); @@ -591,37 +734,35 @@ bool SetScissorRect() int xoff = bpmem.scissorOffset.x * 2 - 342; int yoff = bpmem.scissorOffset.y * 2 - 342; - RECT rc; + int rc_left = bpmem.scissorTL.x - xoff - 342; // left = 0 + rc_left *= MValueX; + if (rc_left < 0) rc_left = 0; - rc.left = bpmem.scissorTL.x - xoff - 342; // left = 0 - rc.left *= MValueX; - if (rc.left < 0) rc.left = 0; - - rc.top = bpmem.scissorTL.y - yoff - 342; // right = 0 - rc.top *= MValueY; - if (rc.top < 0) rc.top = 0; + int rc_top = bpmem.scissorTL.y - yoff - 342; // right = 0 + rc_top *= MValueY; + if (rc_top < 0) rc_top = 0; - rc.right = bpmem.scissorBR.x - xoff - 342; // right = 640 - rc.right *= MValueX; - if (rc.right > 640 * MValueX) rc.right = 640 * MValueX; + int rc_right = bpmem.scissorBR.x - xoff - 342; // right = 640 + rc_right *= MValueX; + if (rc_right > 640 * MValueX) rc_right = 640 * MValueX; - rc.bottom = bpmem.scissorBR.y - yoff - 342; // bottom = 480 - rc.bottom *= MValueY; - if (rc.bottom > 480 * MValueY) rc.bottom = 480 * MValueY; + int rc_bottom = bpmem.scissorBR.y - yoff - 342; // bottom = 480 + rc_bottom *= MValueY; + if (rc_bottom > 480 * MValueY) rc_bottom = 480 * MValueY; /*__Log("Scissor: lt=(%d,%d), rb=(%d,%d,%i), off=(%d,%d)\n", - rc.left, rc.top, - rc.right, rc.bottom, Renderer::GetTargetHeight(), + rc_left, rc_top, + rc_right, rc_bottom, Renderer::GetTargetHeight(), xoff, yoff );*/ - if( rc.right>=rc.left && rc.bottom>=rc.top ) + if (rc_right >= rc_left && rc_bottom >= rc_top ) { glScissor( - rc.left, // x = 0 - Renderer::GetTargetHeight()-(rc.bottom), // y = 0 - (rc.right-rc.left), // y = 0 - (rc.bottom-rc.top) // y = 0 + rc_left, // x = 0 + Renderer::GetTargetHeight()-(rc_bottom), // y = 0 + (rc_right-rc_left), // y = 0 + (rc_bottom-rc_top) // y = 0 ); return true; } @@ -630,183 +771,38 @@ bool SetScissorRect() } -// ======================================================================================= // Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg() -// --------------- void LoadBPReg(u32 value0) { DVSTARTPROFILE(); - //handle the mask register int opcode = value0 >> 24; int oldval = ((u32*)&bpmem)[opcode]; - int newval = (((u32*)&bpmem)[opcode] & ~bpmem.bpMask) | (value0 & bpmem.bpMask); + int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask); int changes = (oldval ^ newval) & 0xFFFFFF; //reset the mask register if (opcode != 0xFE) bpmem.bpMask = 0xFFFFFF; - - switch (opcode) - { - case 0x45: //GXSetDrawDone - VertexManager::Flush(); - switch (value0 & 0xFF) - { - case 0x02: - g_VideoInitialize.pSetPEFinish(); // may generate interrupt - DebugLog("GXSetDrawDone SetPEFinish (value: 0x%02X)", (value0 & 0xFFFF)); - break; - - default: - DebugLog("GXSetDrawDone ??? (value 0x%02X)", (value0 & 0xFFFF)); - break; - } - break; - - case BPMEM_PE_TOKEN_ID: - g_VideoInitialize.pSetPEToken(static_cast(value0 & 0xFFFF), FALSE); - DebugLog("SetPEToken 0x%04x", (value0 & 0xFFFF)); - break; - - case BPMEM_PE_TOKEN_INT_ID: - g_VideoInitialize.pSetPEToken(static_cast(value0 & 0xFFFF), TRUE); - DebugLog("SetPEToken + INT 0x%04x", (value0 & 0xFFFF)); - break; - - case 0x67: // set gp metric? - break; - - case 0x52: - { - DVProfileFunc _pf("LoadBPReg:swap"); - VertexManager::Flush(); - - ((u32*)&bpmem)[opcode] = newval; - TRectangle rc = { - (int)(bpmem.copyTexSrcXY.x), - (int)(bpmem.copyTexSrcXY.y), - (int)((bpmem.copyTexSrcXY.x + bpmem.copyTexSrcWH.x + 1)), - (int)((bpmem.copyTexSrcXY.y + bpmem.copyTexSrcWH.y + 1)) - }; - //Need another rc here to get it to scale. - TRectangle multirc = { - (int)(bpmem.copyTexSrcXY.x * MValueX), - (int)(bpmem.copyTexSrcXY.y * MValueY), - (int)((bpmem.copyTexSrcXY.x * MValueX + (bpmem.copyTexSrcWH.x + 1) * MValueX)), - (int)((bpmem.copyTexSrcXY.y * MValueY + (bpmem.copyTexSrcWH.y + 1) * MValueY)) - }; - - UPE_Copy PE_copy; - PE_copy.Hex = bpmem.triggerEFBCopy; - - if (PE_copy.copy_to_xfb == 0) { - // EFB to texture - // for some reason it sets bpmem.zcontrol.pixel_format to PIXELFMT_Z24 every time a zbuffer format is given as a dest to GXSetTexCopyDst - TextureMngr::CopyRenderTargetToTexture(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0, - (PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, &rc); - } - else { - // EFB to XFB - if(g_Config.bUseXFB) - { - XFB_Write(Memory_GetPtr(bpmem.copyTexDest<<5), multirc, (bpmem.copyMipMapStrideChannels << 4), bpmem.copyTexSrcWH.y + 1, bpmem.dispcopyyscale/256.0f); - } - else - { - Renderer::Swap(multirc); - } - g_VideoInitialize.pCopiedToXFB(); - } - - // clearing - if (PE_copy.clear) { - // clear color - Renderer::SetRenderMode(Renderer::RM_Normal); - - u32 nRestoreZBufferTarget = Renderer::GetZBufferTarget(); - - glViewport(0, 0, Renderer::GetTargetWidth(), Renderer::GetTargetHeight()); - - // Always set the scissor in case it was set by the game and has not been reset - glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom), - (multirc.right - multirc.left), (multirc.bottom - multirc.top)); - - VertexShaderMngr::SetViewportChanged(); - - // since clear operations use the source rectangle, have to do regular renders (glClear clears the entire buffer) - if( bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate || bpmem.zmode.updateenable ) { - - GLbitfield bits = 0; - if( bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate ) { - u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB; - glClearColor(((clearColor>>16)&0xff)*(1/255.0f),((clearColor>>8)&0xff)*(1/255.0f), - ((clearColor>>0)&0xff)*(1/255.0f),((clearColor>>24)&0xff)*(1/255.0f)); - bits |= GL_COLOR_BUFFER_BIT; - } - - if( bpmem.zmode.updateenable ) { - glClearDepth((float)(bpmem.clearZValue&0xFFFFFF) / float(0xFFFFFF)); - bits |= GL_DEPTH_BUFFER_BIT; - } - - if( nRestoreZBufferTarget ) - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // don't clear ztarget here - - glClear(bits); - } - - if (bpmem.zmode.updateenable && nRestoreZBufferTarget ) { // have to clear the target zbuffer - - glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); - GL_REPORT_ERRORD(); - - glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); - - // red should probably be the LSB - glClearColor(((bpmem.clearZValue>>0)&0xff)*(1/255.0f),((bpmem.clearZValue>>8)&0xff)*(1/255.0f), - ((bpmem.clearZValue>>16)&0xff)*(1/255.0f), 0); - glClear(GL_COLOR_BUFFER_BIT); - SetColorMask(); - GL_REPORT_ERRORD(); - } - - if( nRestoreZBufferTarget ) { - // restore target - GLenum s_drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT}; - glDrawBuffers(2, s_drawbuffers); - } - - SetScissorRect(); // reset the scissor rect - } - } - break; - - case 0x65: //GXLoadTlut - { - DVProfileFunc _pf("LoadBPReg:GXLoadTlut"); - VertexManager::Flush(); - ((u32*)&bpmem)[opcode] = newval; - - u32 tlutTMemAddr = (value0&0x3FF)<<9; - u32 tlutXferCount = (value0&0x1FFC00)>>5; - //do the transfer!! - memcpy_gc(texMem + tlutTMemAddr, g_VideoInitialize.pGetMemoryPointer((bpmem.tlutXferSrc&0xFFFFF)<<5), tlutXferCount); - // TODO(ector) : kill all textures that use this palette - // Not sure if it's a good idea, though. For now, we hash texture palettes - } - break; - } - //notify the video handling so it can update render states BPWritten(opcode, changes, newval); - //((u32*)&bpmem)[opcode] = newval; } -// ======================================================================================= -// Never called? -// --------------- +// Never called? Should probably be called when loading a saved state. +// Needs testing though. void BPReload() { - for (int i=0; i<254; i++) - BPWritten(i, 0xFFFFFF, ((u32*)&bpmem)[i]); + for (int i = 0; i < 254; i++) + { + switch (i) { + case 0x65: + case 0x45: //GXSetDrawDone + case BPMEM_PE_TOKEN_ID: + case BPMEM_PE_TOKEN_INT_ID: + case 0x67: // set gp metric? + case 0x52: + break; + default: + BPWritten(i, 0xFFFFFF, ((u32*)&bpmem)[i]); + } + } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.h b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.h index 6b1273db39..ee38278cd6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.h @@ -21,7 +21,6 @@ #include "BPMemory.h" void BPInit(); -//bool BPWritten(int addr, int changes); void LoadBPReg(u32 value0); void SetColorMask(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.cpp index 8c3a48bf1a..e53822513c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.cpp @@ -1,23 +1,19 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// -// Licensetype: GNU General Public License (GPL) -// +// 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 "../Globals.h" #include "Debugger.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.h b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.h index 1aa78ddb38..0f41efd669 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.h @@ -1,23 +1,19 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// -// Licensetype: GNU General Public License (GPL) -// +// 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 __CDebugger_h__ #define __CDebugger_h__ diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/PBView.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/PBView.cpp index ea09ca83d4..485bb630ef 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/PBView.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/PBView.cpp @@ -15,10 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ - -// --------------------------------------------------------------------------------------- -// includes -// ----------------- #include "../Globals.h" #include "PBView.h" @@ -27,24 +23,11 @@ #include #include - - -// --------------------------------------------------------------------------------------- -// external declarations -// ----------------- extern const char* GetGRPName(unsigned int index); - -// --------------------------------------------------------------------------------------- -// No buttons or events so far -// ----------------- BEGIN_EVENT_TABLE(CPBView, wxListCtrl) END_EVENT_TABLE() - -// ======================================================================================= -// The main wxListCtrl -// ------------- CPBView::CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : wxListCtrl(parent, id, pos, size, style) { @@ -54,7 +37,6 @@ CPBView::CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, cons for (int i = 0; i < 1; i++) { - // Print values from 0 to 63 char buffer [33]; sprintf(buffer, "%02i", i); @@ -72,18 +54,14 @@ CPBView::CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, cons Refresh(); } - -void -CPBView::Update() +void CPBView::Update() { Refresh(); } - -bool -CPBView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem) +bool CPBView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem) { bool Result = false; @@ -135,13 +113,11 @@ CPBView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem) rPainDC.DrawText(text, 10, 4); #endif - return(true); + return true; } else { // what does this mean? - return(Result); + return Result; } } - - diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/PBView.h b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/PBView.h index 62a3e31ffd..e9429f3b75 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/PBView.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/PBView.h @@ -23,25 +23,17 @@ #include "Common.h" -class CPBView - : public wxListCtrl +class CPBView : public wxListCtrl { - public: +public: + CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + void Update(); + u32 m_CachedRegs[10][10]; - CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style); - - void Update(); - - u32 m_CachedRegs[10][10]; - - - private: - - DECLARE_EVENT_TABLE() - - bool m_CachedRegHasChanged[64]; - - virtual bool MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem); +private: + DECLARE_EVENT_TABLE() + bool m_CachedRegHasChanged[64]; + virtual bool MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem); }; #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLInit.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLInit.cpp index 8c9450493c..480dd929c9 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLInit.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLInit.cpp @@ -19,9 +19,18 @@ #include "IniFile.h" #include "svnrev.h" +#include "Render.h" + #if defined(_WIN32) #include "OS/Win32.h" +#else +struct RECT +{ + int left, top; + int right, bottom; +}; #endif + #include "GLInit.h" #ifndef USE_SDL @@ -33,16 +42,12 @@ // Handles OpenGL and the window - -// --------------------------------------------------------------------------------------- // externals -// ------------- int gleft, gright, gtop, gbottom; int nBackbufferWidth, nBackbufferHeight; // screen width int nXoff, nYoff; // screen offset float AR; // aspect ratio - #ifndef _WIN32 GLWindow GLWin; #endif @@ -104,7 +109,6 @@ BOOL Callback_PeekMessages() #endif } - void UpdateFPSDisplay(const char *text) { char temp[512]; @@ -116,10 +120,8 @@ void UpdateFPSDisplay(const char *text) } - // ======================================================================================= // Create window. Called from main.cpp -// ---------------- bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight) { int _twidth, _theight; @@ -186,7 +188,6 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight //sprintf(buff, "%i %i %d %d %d", nBackbufferWidth, nBackbufferHeight, Max, MValueX, MValueY); //MessageBox(0, buff, "", 0); - #if USE_SDL //init sdl video if (SDL_Init(SDL_INIT_VIDEO) < 0) { @@ -236,7 +237,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. - if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) + if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) g_Config.bFullscreen = false; @@ -619,7 +620,7 @@ void OpenGL_Update() float Max = (FactorW < FactorH) ? FactorH : FactorW; AR = (float)nBackbufferWidth / (float)nBackbufferHeight; - if(g_Config.bStretchToFit && g_Config.renderToMainframe) + if (g_Config.bStretchToFit && g_Config.renderToMainframe) { MValueX = 1; MValueY = 1; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp index d765e0b567..50089b1a0b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp @@ -15,7 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ - #include #include #include @@ -30,8 +29,6 @@ #include "IniFile.h" #include -float MValueX, MValueY; // Since it can Stretch to fit Window, we need two different multiplication values// -int frameCount; Config g_Config; Statistics stats; @@ -52,10 +49,6 @@ void Config::Load() IniFile iniFile; iniFile.Load("gfx_opengl.ini"); - iniFile.Get("Hardware", "Adapter", &iAdapter, 0); - if (iAdapter == -1) - iAdapter = 0; - // get resolution iniFile.Get("Hardware", "WindowedRes", &temp, 0); if(temp.empty()) @@ -71,7 +64,6 @@ void Config::Load() iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false); - iniFile.Get("Settings", "Postprocess", &iPostprocessEffect, 0); iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0); iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0); iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0); @@ -81,7 +73,7 @@ void Config::Load() iMultisampleMode = 1; std::string s; iniFile.Get("Settings", "TexDumpPath", &s, 0); - if( s.size() < sizeof(texDumpPath) ) + if (s.size() < sizeof(texDumpPath) ) strcpy(texDumpPath, s.c_str()); else { strncpy(texDumpPath, s.c_str(), sizeof(texDumpPath)-1); @@ -102,7 +94,6 @@ void Config::Save() { IniFile iniFile; iniFile.Load("gfx_opengl.ini"); - iniFile.Set("Hardware", "Adapter", iAdapter); iniFile.Set("Hardware", "WindowedRes", iWindowedRes); iniFile.Set("Hardware", "FullscreenRes", iFSResolution); iniFile.Set("Hardware", "Fullscreen", bFullscreen); @@ -110,7 +101,6 @@ void Config::Save() iniFile.Set("Settings", "ShowFPS", bShowFPS); iniFile.Set("Settings", "OverlayStats", bOverlayStats); - iniFile.Set("Settings", "Postprocess", iPostprocessEffect); iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel); iniFile.Set("Settings", "DumpTextures", bDumpTextures); iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors); @@ -129,93 +119,19 @@ void Config::Save() iniFile.Save("gfx_opengl.ini"); } -#if defined(_MSC_VER) -#pragma pack(push, 1) -#endif - -struct TGA_HEADER -{ - u8 identsize; // size of ID field that follows 18 u8 header (0 usually) - u8 colourmaptype; // type of colour map 0=none, 1=has palette - u8 imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed - - s16 colourmapstart; // first colour map entry in palette - s16 colourmaplength; // number of colours in palette - u8 colourmapbits; // number of bits per palette entry 15,16,24,32 - - s16 xstart; // image x origin - s16 ystart; // image y origin - s16 width; // image width in pixels - s16 height; // image height in pixels - u8 bits; // image bits per pixel 8,16,24,32 - u8 descriptor; // image descriptor bits (vh flip bits) - - // pixel data follows header - - -}; -#if defined(_MSC_VER) -#pragma pack(pop) -#endif - -bool SaveTGA(const char* filename, int width, int height, void* pdata) -{ - TGA_HEADER hdr; - FILE* f = fopen(filename, "wb"); - if (f == NULL) - return false; - - _assert_( sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18 ); - - memset(&hdr, 0, sizeof(hdr)); - hdr.imagetype = 2; - hdr.bits = 32; - hdr.width = width; - hdr.height = height; - hdr.descriptor |= 8|(1<<5); // 8bit alpha, flip vertical - - fwrite(&hdr, sizeof(hdr), 1, f); - fwrite(pdata, width*height*4, 1, f); - fclose(f); - return true; -} - -bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height) -{ - GL_REPORT_ERRORD(); - std::vector data(width*height); - glBindTexture(textarget, tex); - glGetTexImage(textarget, 0, GL_BGRA, GL_UNSIGNED_BYTE, &data[0]); - GLenum err; - GL_REPORT_ERROR(); - if (err != GL_NO_ERROR) { - return false; - } - - return SaveTGA(filename, width, height, &data[0]); -} - -bool SaveData(const char* filename, const char* data) -{ - FILE* f = fopen(filename, "wb"); - if (f == NULL) - return false; - - fwrite(data, strlen(data), 1, f); - fclose(f); - return true; -} - - #ifdef _WIN32 + // The one for Linux is in Linux/Linux.cpp static HANDLE hConsole = NULL; -void OpenConsole() { + +void OpenConsole() +{ COORD csize; CONSOLE_SCREEN_BUFFER_INFO csbiInfo; SMALL_RECT srect; - if (hConsole) return; + if (hConsole) + return; AllocConsole(); SetConsoleTitle("Opengl Plugin Output"); @@ -234,18 +150,18 @@ void OpenConsole() { hConsole = GetStdHandle(STD_OUTPUT_HANDLE); } -void CloseConsole() { - if (hConsole == NULL) return; - FreeConsole(); hConsole = NULL; +void CloseConsole() +{ + if (hConsole == NULL) + return; + FreeConsole(); + hConsole = NULL; } #endif - - static FILE* pfLog = NULL; void __Log(const char *fmt, ...) { - char* Msg = (char*)alloca(strlen(fmt)+512); va_list ap; @@ -255,9 +171,10 @@ void __Log(const char *fmt, ...) g_VideoInitialize.pLog(Msg, FALSE); - if( pfLog == NULL ) pfLog = fopen("Logs/oglgfx.txt", "w"); + if (pfLog == NULL) + pfLog = fopen("Logs/oglgfx.txt", "w"); - if( pfLog != NULL ) + if (pfLog != NULL) fwrite(Msg, strlen(Msg), 1, pfLog); #ifdef _WIN32 DWORD tmp; @@ -265,12 +182,10 @@ void __Log(const char *fmt, ...) #else //printf("%s", Msg); #endif - } void __Log(int type, const char *fmt, ...) { - char* Msg = (char*)alloca(strlen(fmt)+512); va_list ap; @@ -284,5 +199,4 @@ void __Log(int type, const char *fmt, ...) DWORD tmp; WriteConsole(hConsole, Msg, (DWORD)strlen(Msg), &tmp, 0); #endif - } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h index 34842e0194..851bf1b3f0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h @@ -67,17 +67,8 @@ inline unsigned long timeGetTime() return (unsigned long)(t.time*1000+t.millitm); } -struct RECT -{ - int left, top; - int right, bottom; -}; - #endif // linux basic definitions -#include -#include - #ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils #define GL_DEPTH_STENCIL_EXT 0x84F9 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA @@ -85,8 +76,6 @@ struct RECT #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 #endif -extern float MValueX, MValueY; - #define ERROR_LOG __Log #if defined(_DEBUG) || defined(DEBUGFAST) @@ -107,11 +96,6 @@ extern float MValueX, MValueY; #define GL_REPORT_ERRORD() #endif -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#endif - -extern int frameCount; #define CONF_LOG 1 #define CONF_PRIMLOG 2 @@ -145,19 +129,11 @@ struct Config bool bDumpTextures; char texDumpPath[280]; - //currently unused: int iLog; // CONF_ bits int iSaveTargetId; - int iAdapter; - char psProfile[16]; - char vsProfile[16]; - int iPostprocessEffect; + + //currently unused: int iCompileDLsLevel; - bool bPreUpscale; - int iPreUpscaleFilter; - bool bTruform; - int iTruformLevel; - bool bOldCard; bool bWireFrame; bool bShowShaderErrors; }; @@ -199,7 +175,6 @@ struct Statistics int numDLPrims; int numPrims; int numShaderChanges; - int numBadCommands; //hope this always is zero ;) int numDListsCalled; }; @@ -226,11 +201,6 @@ void __Log(const char *format, ...); void __Log(int type, const char *format, ...); void HandleGLError(); -void InitLUTs(); -bool SaveTGA(const char* filename, int width, int height, void* pdata); -bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height); -bool SaveData(const char* filename, const char* pdata); - #if defined(_MSC_VER) && !defined(__x86_64__) && !defined(_M_X64) void * memcpy_amd(void *dest, const void *src, size_t n); unsigned char memcmp_mmx(const void* src1, const void* src2, int cmpsize); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ImageWrite.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ImageWrite.cpp new file mode 100644 index 0000000000..7e349a8dde --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/ImageWrite.cpp @@ -0,0 +1,97 @@ +// 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 "Globals.h" + +#include + +#include "ImageWrite.h" + +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif + +struct TGA_HEADER +{ + u8 identsize; // size of ID field that follows 18 u8 header (0 usually) + u8 colourmaptype; // type of colour map 0=none, 1=has palette + u8 imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + + s16 colourmapstart; // first colour map entry in palette + s16 colourmaplength; // number of colours in palette + u8 colourmapbits; // number of bits per palette entry 15,16,24,32 + + s16 xstart; // image x origin + s16 ystart; // image y origin + s16 width; // image width in pixels + s16 height; // image height in pixels + u8 bits; // image bits per pixel 8,16,24,32 + u8 descriptor; // image descriptor bits (vh flip bits) + + // pixel data follows header +}; + +#if defined(_MSC_VER) +#pragma pack(pop) +#endif + +bool SaveTGA(const char* filename, int width, int height, void* pdata) +{ + TGA_HEADER hdr; + FILE* f = fopen(filename, "wb"); + if (f == NULL) + return false; + + _assert_(sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18); + + memset(&hdr, 0, sizeof(hdr)); + hdr.imagetype = 2; + hdr.bits = 32; + hdr.width = width; + hdr.height = height; + hdr.descriptor |= 8|(1<<5); // 8bit alpha, flip vertical + + fwrite(&hdr, sizeof(hdr), 1, f); + fwrite(pdata, width * height * 4, 1, f); + fclose(f); + return true; +} + +bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height) +{ + GL_REPORT_ERRORD(); + std::vector data(width * height); + glBindTexture(textarget, tex); + glGetTexImage(textarget, 0, GL_BGRA, GL_UNSIGNED_BYTE, &data[0]); + GLenum err; + GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) + { + return false; + } + return SaveTGA(filename, width, height, &data[0]); +} + +bool SaveData(const char* filename, const char* data) +{ + FILE *f = fopen(filename, "wb"); + if (!f) + return false; + fwrite(data, strlen(data), 1, f); + fclose(f); + return true; +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ImageWrite.h b/Source/Plugins/Plugin_VideoOGL/Src/ImageWrite.h new file mode 100644 index 0000000000..468cff6074 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/ImageWrite.h @@ -0,0 +1,25 @@ +// 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 _IMAGEWRITE_H +#define _IMAGEWRITE_H + +bool SaveTGA(const char* filename, int width, int height, void* pdata); +bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height); +bool SaveData(const char* filename, const char* pdata); + +#endif // _IMAGEWRITE_H \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoOGL/Src/OpcodeDecoding.cpp b/Source/Plugins/Plugin_VideoOGL/Src/OpcodeDecoding.cpp index 793468e1bc..bcc6bd14fa 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/OpcodeDecoding.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/OpcodeDecoding.cpp @@ -28,8 +28,8 @@ #include "Profiler.h" #include "OpcodeDecoding.h" #include "VertexLoader.h" +#include "VertexManager.h" #include "VertexShaderManager.h" -#include "TextureMngr.h" #include "BPStructs.h" #include "Fifo.h" @@ -84,7 +84,7 @@ void ExecuteDisplayList(u32 address, u32 size) bool FifoCommandRunnable(void) { - u32 iBufferSize = (u32)(FAKE_GetFifoEndPtr()-g_pVideoData); + u32 iBufferSize = (u32)(FAKE_GetFifoEndPtr() - g_pVideoData); if (iBufferSize == 0) return false; // can't peek diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShader.cpp index 774645b8ab..9c29c502fe 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShader.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShader.cpp @@ -40,7 +40,7 @@ void WrapNonPow2Tex(char* &p, const char* var, int texmap, u32 texture_mask); void WriteAlphaCompare(char *&p, int num, int comp); bool WriteAlphaTest(char *&p); -const float epsilon = 1.0f/255.0f; +const float epsilon8bit = 1.0f / 255.0f; static const char *tevKSelTableC[] = // KCSEL { @@ -281,8 +281,8 @@ char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool bRende int numTexgen = bpmem.genMode.numtexgens; char *p = text; - WRITE(p,"//Pixel Shader for TEV stages\n"); - WRITE(p,"//%i TEV stages, %i texgens, %i IND stages\n", + WRITE(p, "//Pixel Shader for TEV stages\n"); + WRITE(p, "//%i TEV stages, %i texgens, %i IND stages\n", numStages,numTexgen,bpmem.genMode.numindstages); bool bRenderZ = has_zbuffer_target && bpmem.zmode.updateenable; @@ -293,24 +293,24 @@ char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool bRende assert( !bRenderZToCol0 || bRenderZ ); int ztexcoord = -1; - if( bInputZ ) + if (bInputZ) ztexcoord = numTexgen == 0 ? 0 : numTexgen-1; int nIndirectStagesUsed = 0; - if( bpmem.genMode.numindstages > 0 ) { - for(int i = 0; i < numStages; ++i) { - if( bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages ) { + if (bpmem.genMode.numindstages > 0) { + for (int i = 0; i < numStages; ++i) { + if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) { nIndirectStagesUsed |= 1<= 1.0f )\n", bpmem.tevind[n].bt, + WRITE(p, "if (indtex%d.%s >= 1.0f )\n", bpmem.tevind[n].bt, tevIndAlphaSel[bpmem.tevind[n].bs]); WRITE(p, " alphabump = 1.0f;\n"); WRITE(p, "else\n"); @@ -493,21 +493,21 @@ void WriteStage(char *&p, int n, u32 texture_mask) // bias WRITE(p, "float3 indtevcrd%d = indtex%d;\n", n, bpmem.tevind[n].bt); WRITE(p, "indtevcrd%d.xy *= %s;\n", n, tevIndFmtScale[bpmem.tevind[n].fmt]); - if( bpmem.tevind[n].bias != ITB_NONE ) + if (bpmem.tevind[n].bias != ITB_NONE ) WRITE(p, "indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]); // multiply by offset matrix and scale - if( bpmem.tevind[n].mid != 0 ) { - if( bpmem.tevind[n].mid <= 3 ) { + if (bpmem.tevind[n].mid != 0) { + if (bpmem.tevind[n].mid <= 3) { int mtxidx = 2*(bpmem.tevind[n].mid-1); WRITE(p, "float2 indtevtrans%d = float2(dot("I_INDTEXMTX"[%d].xyz, indtevcrd%d), dot("I_INDTEXMTX"[%d].xyz, indtevcrd%d));\n", n, mtxidx, n, mtxidx+1, n); } - else if( bpmem.tevind[n].mid <= 5 ) { // s matrix + else if (bpmem.tevind[n].mid <= 5) { // s matrix int mtxidx = 2*(bpmem.tevind[n].mid-5); WRITE(p, "float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.xx;\n", n, mtxidx, texcoord, n); } - else if( bpmem.tevind[n].mid <= 9 ) { // t matrix + else if (bpmem.tevind[n].mid <= 9) { // t matrix int mtxidx = 2*(bpmem.tevind[n].mid-9); WRITE(p, "float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n); } @@ -522,12 +522,12 @@ void WriteStage(char *&p, int n, u32 texture_mask) } // wrapping - if( !bpmem.tevorders[n/2].getEnable(n&1) || (texture_mask & (1< %s.%s) ? %s : float3(0.0f,0.0f,0.0f));\n", - tevCInputTable[cc.d],tevCInputTable2[cc.a], cmp==TEVCMP_R8_GT?"r":"rgb", tevCInputTable2[cc.b], cmp==TEVCMP_R8_GT?"r":"rgb", tevCInputTable[cc.c]); + WRITE(p, " %s + ((%s.%s > %s.%s) ? %s : float3(0.0f,0.0f,0.0f));\n", + tevCInputTable[cc.d], tevCInputTable2[cc.a], cmp==TEVCMP_R8_GT?"r":"rgb", tevCInputTable2[cc.b], cmp==TEVCMP_R8_GT?"r":"rgb", tevCInputTable[cc.c]); break; case TEVCMP_R8_EQ: case TEVCMP_RGB8_EQ: - WRITE(p," %s + (abs(%s.r - %s.r)<%f ? %s : float3(0.0f,0.0f,0.0f));\n", - tevCInputTable[cc.d],tevCInputTable2[cc.a], tevCInputTable2[cc.b],epsilon,tevCInputTable[cc.c]); + WRITE(p, " %s + (abs(%s.r - %s.r)<%f ? %s : float3(0.0f,0.0f,0.0f));\n", + tevCInputTable[cc.d], tevCInputTable2[cc.a], tevCInputTable2[cc.b], epsilon8bit, tevCInputTable[cc.c]); break; case TEVCMP_GR16_GT: // 16 bit compares: 255*g+r (probably used for ztextures, so make sure in ztextures, g is the most significant byte) case TEVCMP_BGR24_GT: // 24 bit compares: 255*255*b+255*g+r - WRITE(p," %s + (( dot(%s.rgb-%s.rgb, comp%s) > 0) ? %s : float3(0.0f,0.0f,0.0f));\n", - tevCInputTable[cc.d],tevCInputTable2[cc.a], tevCInputTable2[cc.b], cmp==TEVCMP_GR16_GT?"16":"24", tevCInputTable[cc.c]); + WRITE(p, " %s + (( dot(%s.rgb-%s.rgb, comp%s) > 0) ? %s : float3(0.0f,0.0f,0.0f));\n", + tevCInputTable[cc.d], tevCInputTable2[cc.a], tevCInputTable2[cc.b], cmp==TEVCMP_GR16_GT?"16":"24", tevCInputTable[cc.c]); break; case TEVCMP_GR16_EQ: case TEVCMP_BGR24_EQ: - WRITE(p," %s + (abs(dot(%s.rgb - %s.rgb, comp%s))<%f ? %s : float3(0.0f,0.0f,0.0f));\n", - tevCInputTable[cc.d],tevCInputTable2[cc.a], tevCInputTable2[cc.b],cmp==TEVCMP_GR16_GT?"16":"24",epsilon,tevCInputTable[cc.c]); + WRITE(p, " %s + (abs(dot(%s.rgb - %s.rgb, comp%s))<%f ? %s : float3(0.0f,0.0f,0.0f));\n", + tevCInputTable[cc.d], tevCInputTable2[cc.a], tevCInputTable2[cc.b], cmp==TEVCMP_GR16_GT?"16":"24", epsilon8bit, tevCInputTable[cc.c]); break; default: - WRITE(p,"float3(0.0f,0.0f,0.0f);\n"); + WRITE(p, "float3(0.0f,0.0f,0.0f);\n"); break; } } - if( cc.clamp ) + if (cc.clamp) WRITE(p, "%s = clamp(%s,0.0f,1.0f);\n", tevCOutputTable[cc.dest],tevCOutputTable[cc.dest]); // combine the alpha channel - WRITE(p,"%s= ", tevAOutputTable[ac.dest]); + WRITE(p, "%s= ", tevAOutputTable[ac.dest]); if (ac.bias != 3) { // if not compare //normal alpha combiner goes here - WRITE(p," %s*(%s%s",tevScaleTable[ac.shift],tevAInputTable[ac.d],tevOpTable[ac.op]); - WRITE(p,"lerp(%s,%s,%s) %s)\n", + WRITE(p, " %s*(%s%s",tevScaleTable[ac.shift],tevAInputTable[ac.d],tevOpTable[ac.op]); + WRITE(p, "lerp(%s,%s,%s) %s)\n", tevAInputTable[ac.a],tevAInputTable[ac.b], tevAInputTable[ac.c],tevBiasTable[ac.bias]); } @@ -718,34 +718,34 @@ void WriteStage(char *&p, int n, u32 texture_mask) switch(cmp) { case TEVCMP_R8_GT: case TEVCMP_A8_GT: - WRITE(p," %s + ((%s.%s > %s.%s) ? %s : 0)\n", + WRITE(p, " %s + ((%s.%s > %s.%s) ? %s : 0)\n", tevAInputTable[ac.d],tevAInputTable2[ac.a], cmp==TEVCMP_R8_GT?"r":"a", tevAInputTable2[ac.b], cmp==TEVCMP_R8_GT?"r":"a", tevAInputTable[ac.c]); break; case TEVCMP_R8_EQ: case TEVCMP_A8_EQ: - WRITE(p," %s + (abs(%s.r - %s.r)<%f ? %s : 0)\n", - tevAInputTable[ac.d],tevAInputTable2[ac.a], tevAInputTable2[ac.b],epsilon,tevAInputTable[ac.c]); + WRITE(p, " %s + (abs(%s.r - %s.r)<%f ? %s : 0)\n", + tevAInputTable[ac.d],tevAInputTable2[ac.a], tevAInputTable2[ac.b],epsilon8bit,tevAInputTable[ac.c]); break; case TEVCMP_GR16_GT: // 16 bit compares: 255*g+r (probably used for ztextures, so make sure in ztextures, g is the most significant byte) case TEVCMP_BGR24_GT: // 24 bit compares: 255*255*b+255*g+r - WRITE(p," %s + (( dot(%s.rgb-%s.rgb, comp%s) > 0) ? %s : 0)\n", + WRITE(p, " %s + (( dot(%s.rgb-%s.rgb, comp%s) > 0) ? %s : 0)\n", tevAInputTable[ac.d],tevAInputTable2[ac.a], tevAInputTable2[ac.b], cmp==TEVCMP_GR16_GT?"16":"24", tevAInputTable[ac.c]); break; case TEVCMP_GR16_EQ: case TEVCMP_BGR24_EQ: - WRITE(p," %s + (abs(dot(%s.rgb - %s.rgb, comp%s))<%f ? %s : 0)\n", - tevAInputTable[ac.d],tevAInputTable2[ac.a], tevAInputTable2[ac.b],cmp==TEVCMP_GR16_GT?"16":"24",epsilon,tevAInputTable[ac.c]); + WRITE(p, " %s + (abs(dot(%s.rgb - %s.rgb, comp%s))<%f ? %s : 0)\n", + tevAInputTable[ac.d],tevAInputTable2[ac.a], tevAInputTable2[ac.b],cmp==TEVCMP_GR16_GT?"16":"24",epsilon8bit,tevAInputTable[ac.c]); break; default: - WRITE(p,"0)\n"); + WRITE(p, "0)\n"); break; } } - WRITE(p,";\n"); + WRITE(p, ";\n"); - if( ac.clamp ) + if (ac.clamp) WRITE(p, "%s = clamp(%s,0.0f,1.0f);\n", tevAOutputTable[ac.dest],tevAOutputTable[ac.dest]); WRITE(p, "\n"); } @@ -756,14 +756,14 @@ void WrapNonPow2Tex(char* &p, const char* var, int texmap, u32 texture_mask) bool bwraps = !!(texture_mask & (0x100< %s)",alphaRef[num]); break; - case ALPHACMP_LESS: WRITE(p,"(prev.a >= %s - %f)",alphaRef[num],epsilon*0.5f);break; - case ALPHACMP_GEQUAL: WRITE(p,"(prev.a < %s)",alphaRef[num]); break; - case ALPHACMP_GREATER: WRITE(p,"(prev.a <= %s + %f)",alphaRef[num],epsilon*0.5f);break; - case ALPHACMP_EQUAL: WRITE(p,"(abs(prev.a-%s)>%f)",alphaRef[num],epsilon*2); break; - case ALPHACMP_NEQUAL: WRITE(p,"(abs(prev.a-%s)<%f)",alphaRef[num],epsilon*2); break; + case ALPHACMP_ALWAYS: WRITE(p, "(false)"); break; + case ALPHACMP_NEVER: WRITE(p, "(true)"); break; + case ALPHACMP_LEQUAL: WRITE(p, "(prev.a > %s)",alphaRef[num]); break; + case ALPHACMP_LESS: WRITE(p, "(prev.a >= %s - %f)",alphaRef[num],epsilon8bit*0.5f);break; + case ALPHACMP_GEQUAL: WRITE(p, "(prev.a < %s)",alphaRef[num]); break; + case ALPHACMP_GREATER: WRITE(p, "(prev.a <= %s + %f)",alphaRef[num],epsilon8bit*0.5f);break; + case ALPHACMP_EQUAL: WRITE(p, "(abs(prev.a-%s)>%f)",alphaRef[num],epsilon8bit*2); break; + case ALPHACMP_NEQUAL: WRITE(p, "(abs(prev.a-%s)<%f)",alphaRef[num],epsilon8bit*2); break; } } @@ -808,13 +808,13 @@ bool WriteAlphaTest(char *&p) break; case 2: // xor if ( (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS) ) return true; - if ( (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER) ) { + if ( (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) { WRITE(p, "discard;\n"); return false; } break; case 3: // xnor - if ( (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS) ) { + if ( (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS)) { WRITE(p, "discard;\n"); return false; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp index b8695c8afc..d21b576eef 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp @@ -18,6 +18,9 @@ #include "Globals.h" #include "Profiler.h" +#include +#include + #include #include "Common.h" @@ -65,7 +68,7 @@ void PixelShaderMngr::Init() s_nIndTexMtxChanged = 15; s_bAlphaChanged = s_bZBiasChanged = s_bIndTexScaleChanged = true; GL_REPORT_ERRORD(); - for(int i = 0; i < 8; ++i) maptocoord[i] = -1; + for (int i = 0; i < 8; ++i) maptocoord[i] = -1; maptocoord_mask = 0; memset(lastRGBAfull, 0, sizeof(lastRGBAfull)); @@ -87,14 +90,13 @@ void PixelShaderMngr::Init() "DP4 R1.y, R0, program.env[%d];\n" "ADD result.color, R1, program.env[%d];\n" "END\n", C_COLORMATRIX+3, C_COLORMATRIX+2, C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+4); - glGenProgramsARB( 1, &s_ColorMatrixProgram ); - glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, s_ColorMatrixProgram ); - - glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog); + glGenProgramsARB(1, &s_ColorMatrixProgram); + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, s_ColorMatrixProgram); + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog); - GLenum err=GL_NO_ERROR; + GLenum err = GL_NO_ERROR; GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) { + if (err != GL_NO_ERROR) { ERROR_LOG("Failed to create color matrix fragment program\n"); glDeleteProgramsARB(1, &s_ColorMatrixProgram); s_ColorMatrixProgram = 0; @@ -136,7 +138,7 @@ FRAGMENTSHADER* PixelShaderMngr::GetShader() Renderer::GetRenderMode() != Renderer::RM_Normal); #ifdef _DEBUG - if( g_Config.iLog & CONF_SAVESHADERS && code ) { + if (g_Config.iLog & CONF_SAVESHADERS && code) { static int counter = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%s/ps_%04i.txt", g_Config.texDumpPath, counter++); @@ -163,7 +165,7 @@ FRAGMENTSHADER* PixelShaderMngr::GetShader() void PixelShaderMngr::Cleanup() { PSCache::iterator iter = pshaders.begin(); - while(iter != pshaders.end()) { + while (iter != pshaders.end()) { PSCacheEntry &entry = iter->second; if (entry.frameCount < frameCount - 200) { entry.Destroy(); @@ -196,16 +198,16 @@ bool PixelShaderMngr::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpro char* pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); char* plocal = strstr(pcompiledprog, "program.local"); - while( plocal != NULL ) { + while ( plocal != NULL) { const char* penv = " program.env"; memcpy(plocal, penv, 13); plocal = strstr(plocal+13, "program.local"); } - if( Renderer::IsUsingATIDrawBuffers() ) { + if (Renderer::IsUsingATIDrawBuffers()) { // sometimes compilation can use ARB_draw_buffers, which would fail for ATI cards char* poptions = strstr(pcompiledprog, "ARB_draw_buffers"); - if( poptions != NULL ) { + if (poptions != NULL) { poptions[0] = 'A'; poptions[1] = 'T'; poptions[2] = 'I'; @@ -220,7 +222,7 @@ bool PixelShaderMngr::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpro GLenum err = GL_NO_ERROR; GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) { + if (err != GL_NO_ERROR) { ERROR_LOG(pstrprogram); ERROR_LOG(pcompiledprog); } @@ -236,12 +238,12 @@ bool PixelShaderMngr::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpro void PixelShaderMngr::SetConstants(FRAGMENTSHADER& ps) { - for(int i = 0; i < 2; ++i) { - if( s_nColorsChanged[i] ) { + for (int i = 0; i < 2; ++i) { + if (s_nColorsChanged[i]) { int baseind = i?C_KCOLORS:C_COLORS; - for(int j = 0; j < 4; ++j) { - if( s_nColorsChanged[i] & (1<>8)&0xff)/255.0f, 0, ((lastAlpha>>16)&0xff)/255.0f); } - if( s_bZBiasChanged ) { + if (s_bZBiasChanged) { u32 bits; float ffrac = 255.0f/256.0f; float ftemp[4]; - switch(bpmem.ztex2.type) { + switch (bpmem.ztex2.type) { case 0: bits = 8; ftemp[0] = ffrac/(256.0f*256.0f); ftemp[1] = ffrac/256.0f; ftemp[2] = ffrac; ftemp[3] = 0; @@ -309,10 +311,10 @@ void PixelShaderMngr::SetConstants(FRAGMENTSHADER& ps) } // indirect incoming texture scales, update all! - if( s_bIndTexScaleChanged ) { + if (s_bIndTexScaleChanged) { float f[8]; - for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) { + for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) { int srctexmap = bpmem.tevindref.getTexMap(i); int texcoord = bpmem.tevindref.getTexCoord(i); TCoordInfo& tc = bpmem.texcoords[texcoord]; @@ -325,17 +327,19 @@ void PixelShaderMngr::SetConstants(FRAGMENTSHADER& ps) SetPSConstant4fv(C_INDTEXSCALE, f); - if( bpmem.genMode.numindstages > 2 ) + if (bpmem.genMode.numindstages > 2) SetPSConstant4fv(C_INDTEXSCALE+1, &f[4]); s_bIndTexScaleChanged = false; } - if( s_nIndTexMtxChanged ) { - for(int i = 0; i < 3; ++i) { - if( s_nIndTexMtxChanged & (1<= 0 ) { + if (s_texturemask & (1<= 0) { TCoordInfo& tc = bpmem.texcoords[maptocoord[texid]]; fdims[0] = (float)(lastTexDims[texid]&0xffff); fdims[1] = (float)((lastTexDims[texid]>>16)&0xfff); @@ -373,7 +377,7 @@ void PixelShaderMngr::SetPSTextureDims(int texid) } } else { - if( maptocoord[texid] >= 0 ) { + if (maptocoord[texid] >= 0) { TCoordInfo& tc = bpmem.texcoords[maptocoord[texid]]; fdims[0] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[texid]&0xffff); fdims[1] = (float)(tc.t.scale_minus_1+1)/(float)((lastTexDims[texid]>>16)&0xfff); @@ -394,20 +398,22 @@ void PixelShaderMngr::SetPSTextureDims(int texid) void PixelShaderMngr::SetColorChanged(int type, int num) { - int r=bpmem.tevregs[num].low.a, a=bpmem.tevregs[num].low.b; - int b=bpmem.tevregs[num].high.a, g=bpmem.tevregs[num].high.b; - float* pf = &lastRGBAfull[type][num][0]; - pf[0] = (float)r/255.0f; - pf[1] = (float)g/255.0f; - pf[2] = (float)b/255.0f; - pf[3] = (float)a/255.0f; + int r = bpmem.tevregs[num].low.a; + int a = bpmem.tevregs[num].low.b; + int b = bpmem.tevregs[num].high.a; + int g = bpmem.tevregs[num].high.b; + float *pf = &lastRGBAfull[type][num][0]; + pf[0] = (float)r / 255.0f; + pf[1] = (float)g / 255.0f; + pf[2] = (float)b / 255.0f; + pf[3] = (float)a / 255.0f; s_nColorsChanged[type] |= 1 << num; PRIM_LOG("pixel %scolor%d: %f %f %f %f\n", type?"k":"", num, pf[0], pf[1], pf[2], pf[3]); } void PixelShaderMngr::SetAlpha(const AlphaFunc& alpha) { - if( (alpha.hex&0xffff) != lastAlpha ) { + if ((alpha.hex&0xffff) != lastAlpha) { lastAlpha = (lastAlpha&~0xffff)|(alpha.hex&0xffff); s_bAlphaChanged = true; } @@ -415,7 +421,7 @@ void PixelShaderMngr::SetAlpha(const AlphaFunc& alpha) void PixelShaderMngr::SetDestAlpha(const ConstantAlpha& alpha) { - if( alpha.alpha != (lastAlpha>>16) ) { + if (alpha.alpha != (lastAlpha>>16)) { lastAlpha = (lastAlpha&~0xff0000)|((alpha.hex&0xff)<<16); s_bAlphaChanged = true; } @@ -423,8 +429,8 @@ void PixelShaderMngr::SetDestAlpha(const ConstantAlpha& alpha) void PixelShaderMngr::SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt) { - u32 wh = width|(height<<16)|(wraps<<28)|(wrapt<<30); - if( lastTexDims[texmapid] != wh ) { + u32 wh = width | (height<<16) | (wraps<<28) | (wrapt<<30); + if (lastTexDims[texmapid] != wh) { lastTexDims[texmapid] = wh; s_nTexDimsChanged |= 1<>12; + if (bpmem.tevorders[i].hex&0x40000 ) val1 = (bpmem.tevorders[i].hex&0x3ff000)>>12; else val1 = (bpmem.tevorders[i].hex&0x380000)>>12; - switch(i % 3) { + switch (i % 3) { case 0: pcurvalue[0] = val0|(val1<<10); break; case 1: pcurvalue[0] |= val0<<20; pcurvalue[1] = val1; pcurvalue++; break; case 2: pcurvalue[1] |= (val0<<10)|(val1<<20); pcurvalue++; break; } } - if( (bpmem.genMode.numtevstages+1)&1 ) { // odd + if ((bpmem.genMode.numtevstages+1)&1) { // odd u32 val0; - if( bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x40 ) val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x3ff; + if (bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x40 ) val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x3ff; else val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x380; - switch(bpmem.genMode.numtevstages % 3) { + switch (bpmem.genMode.numtevstages % 3) { case 0: pcurvalue[0] = val0; break; case 1: pcurvalue[0] |= val0<<20; break; case 2: pcurvalue[1] |= (val0<<10); pcurvalue++; break; } } - if( (bpmem.genMode.numtevstages % 3) != 2 ) + if ((bpmem.genMode.numtevstages % 3) != 2 ) ++pcurvalue; uid.tevstages = (u32)(pcurvalue-&uid.values[0]-hdr); - for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) { + for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) { u32 val = bpmem.tevind[i].hex&0x1fffff; // 21 bits - switch(i%3) { + switch (i%3) { case 0: pcurvalue[0] = val; break; case 1: pcurvalue[0] |= val<<21; pcurvalue[1] = val>>11; ++pcurvalue; break; case 2: pcurvalue[0] |= val<<10; ++pcurvalue; break; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 2e8dc7aaf0..92dfca6a16 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -18,12 +18,16 @@ #include "Globals.h" #include +#include +#include + #ifdef _WIN32 #include #endif #include "GLInit.h" #include "Profiler.h" +#include "ImageWrite.h" #include "Render.h" #include "OpcodeDecoding.h" #include "BPStructs.h" @@ -67,6 +71,8 @@ static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal; static int s_nCurTarget = 0; bool g_bBlendLogicOp = false; +float MValueX, MValueY; // Since it can Stretch to fit Window, we need two different multiplication values +int frameCount; void HandleCgError(CGcontext ctx, CGerror err, void* appdata); @@ -371,13 +377,12 @@ void Renderer::ProcessMessages() { GLboolean wasEnabled = glIsEnabled(GL_BLEND); - if(!wasEnabled) glEnable(GL_BLEND); + if (!wasEnabled) glEnable(GL_BLEND); if (s_listMsgs.size() > 0) { int left = 25, top = 15; list::iterator it = s_listMsgs.begin(); - - while( it != s_listMsgs.end() ) + while (it != s_listMsgs.end()) { int time_left = (int)(it->dwTimeStamp - timeGetTime()); int alpha = 255; @@ -388,7 +393,7 @@ void Renderer::ProcessMessages() if(time_left<0) alpha=0; } - alpha<<=24; + alpha <<= 24; RenderText(it->str, left+1, top+1, 0x000000|alpha); RenderText(it->str, left, top, 0xffff30|alpha); @@ -761,7 +766,6 @@ void Renderer::SwapBuffers() //p+=sprintf(p,"Num strip joins: %i\n",stats.numJoins); p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims); p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims); - p+=sprintf(p,"Num bad commands: %i%s\n",stats.thisFrame.numBadCommands,stats.thisFrame.numBadCommands?"!!!":""); 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); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h index 4b37f10762..314606b05e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h @@ -20,9 +20,15 @@ #include "TextureMngr.h" +#include +#include + extern CGcontext g_cgcontext; extern CGprofile g_cgvProf, g_cgfProf; +extern float MValueX, MValueY; +extern int frameCount; + class Renderer { static void FlushZBufferAlphaToTarget(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/SConscript b/Source/Plugins/Plugin_VideoOGL/Src/SConscript index 809daf00f9..f23f605c70 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/SConscript +++ b/Source/Plugins/Plugin_VideoOGL/Src/SConscript @@ -18,6 +18,8 @@ files = [ 'rasterfont.cpp', 'Render.cpp', 'TextureMngr.cpp', + 'ImageWrite.cpp', + 'VertexManager.cpp', 'VertexLoader.cpp', 'VertexLoader_Normal.cpp', 'VertexShader.cpp', diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index 28a05410a2..039c3b8015 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -30,6 +30,7 @@ #endif #include "Profiler.h" +#include "ImageWrite.h" #include "Render.h" @@ -161,8 +162,8 @@ void TextureMngr::Cleanup() } std::map::iterator itdepth = mapDepthTargets.begin(); - while(itdepth != mapDepthTargets.end()) { - if( frameCount > 20 + itdepth->second.framecount) { + while (itdepth != mapDepthTargets.end()) { + if (frameCount > 20 + itdepth->second.framecount) { #ifdef _WIN32 itdepth = mapDepthTargets.erase(itdepth); #else diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp index 8d7500cabc..a5b13cd879 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp @@ -16,16 +16,19 @@ // http://code.google.com/p/dolphin-emu/ #include "Globals.h" + #include #include #include "Common.h" +#include "ImageWrite.h" #include "x64Emitter.h" #include "ABI.h" #include "Profiler.h" #include "StringUtil.h" #include "Render.h" +#include "VertexManager.h" #include "VertexLoader.h" #include "BPStructs.h" #include "DataReader.h" @@ -38,17 +41,7 @@ #include -#define MAX_BUFFER_SIZE 0x4000 - - -// internal state for loading vertices -static u32 s_prevvbstride, s_prevcomponents; // previous state set -static u8 *s_pBaseBufferPointer = NULL; -static GLuint s_vboBuffers[0x40] = {0}; -static int s_nCurVBOIndex = 0; // current free buffer -static GLenum s_prevprimitive = 0; // current primitive type -static vector< pair > s_vStoredPrimitives; // every element, mode and count to be passed to glDrawArrays -static void (*fnSetupVertexPointers)() = NULL; +extern void (*fnSetupVertexPointers)(); //these don't need to be saved static float posScale; @@ -62,11 +55,18 @@ static int colIndex; #define inline #endif +TVtxDesc VertexManager::s_GlobalVtxDesc; +float VertexManager::shiftLookup[32]; + + + // ============================================================================== // Direct // ============================================================================== -static u8 s_curposmtx, s_curtexmtx[8]; -static int s_texmtxwrite = 0, s_texmtxread = 0; +static u8 s_curposmtx; +static u8 s_curtexmtx[8]; +static int s_texmtxwrite = 0; +static int s_texmtxread = 0; void LOADERDECL PosMtx_ReadDirect_UByte(void* _p) { @@ -150,7 +150,7 @@ int VertexLoader::ComputeVertexSize() m_VtxDesc.Hex = VertexManager::GetVtxDesc().Hex; } - if( fnSetupVertexPointers != NULL && fnSetupVertexPointers == (void (*)())(void*)m_compiledCode ) + if (fnSetupVertexPointers != NULL && fnSetupVertexPointers == (void (*)())(void*)m_compiledCode) VertexManager::Flush(); m_AttrDirty = 1; @@ -258,7 +258,6 @@ int VertexLoader::ComputeVertexSize() return m_VertexSize; } - // Note the use of CallCdeclFunction3I etc. // This is a horrible hack that is necessary because Opengl32.dll is based way, way above the 32-bit address space // that is within reach of a CALL, and just doing &fn gives us these high uncallable addresses. So we want to grab @@ -519,8 +518,8 @@ void VertexLoader::ProcessFormat() ABI_RestoreStack(1 * 4); #endif #endif - if( m_components&(VB_HAS_TEXMTXIDX0< 0 ) + if (v-startv > 0) VertexManager::AddVertices(primitive, v-startv+extraverts); VertexManager::Flush(); - - switch( primitive ) { + // Why does this need to be so complicated? + switch (primitive) { case 3: // triangle strip, copy last two vertices - // a little trick since we have to keep track of signs - if( v & 1 ) { + if (v & 1) { memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-2*m_VBVertexStride, m_VBVertexStride); memcpy_gc(VertexManager::s_pCurBufferPointer+m_VBVertexStride, plastptr-m_VBVertexStride*2, 2*m_VBVertexStride); VertexManager::s_pCurBufferPointer += m_VBVertexStride*3; @@ -812,339 +809,19 @@ void VertexLoader::RunVertices(int primitive, int count) extraverts = 0; break; } - startv = v; } } - tcIndex = 0; colIndex = 0; s_texmtxwrite = s_texmtxread = 0; - - // int pred_size = m_VertexSize; - - //int start = GetBufferPosition(); - //if (!m_numPipelineStates) - // PanicAlert("trying to draw with no pipeline"); for (int i = 0; i < m_numPipelineStates; i++) m_PipelineStates[i](&m_VtxAttr); - //int end = GetBufferPosition(); - - //if (end - start != pred_size) { - // std::string vtx_summary; - // vtx_summary += StringFromFormat("Nrm d:%i f:%i e:%i 3:%i", m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements, m_VtxAttr.NormalIndex3); - // PanicAlert((vtx_summary + "\nWTF %i %i").c_str(), end - start, pred_size); - //} VertexManager::s_pCurBufferPointer += m_VBStridePad; PRIM_LOG("\n"); } - if( startv < count ) + if (startv < count) VertexManager::AddVertices(primitive, count-startv+extraverts); } - -/////////////////// -// VertexManager // -/////////////////// - -TVtxDesc VertexManager::s_GlobalVtxDesc; -u8* VertexManager::s_pCurBufferPointer=NULL; -float VertexManager::shiftLookup[32]; - -const GLenum c_primitiveType[8] = -{ - GL_QUADS, - 0, //nothing - GL_TRIANGLES, - GL_TRIANGLE_STRIP, - GL_TRIANGLE_FAN, - GL_LINES, - GL_LINE_STRIP, - GL_POINTS -}; - -bool VertexManager::Init() -{ - Destroy(); - - s_GlobalVtxDesc.Hex = 0; - s_prevcomponents = 0; - s_prevvbstride = 12; // just pos - s_prevprimitive = 0; - s_pBaseBufferPointer = (u8*)AllocateMemoryPages(MAX_BUFFER_SIZE); - s_pCurBufferPointer = s_pBaseBufferPointer; - - for (u32 i = 0; i < ARRAYSIZE(shiftLookup); i++) - shiftLookup[i] = 1.0f / float(1 << i); - - s_nCurVBOIndex = 0; - glGenBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers); - for (u32 i = 0; i < ARRAYSIZE(s_vboBuffers); ++i) { - glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[i]); - glBufferData(GL_ARRAY_BUFFER, MAX_BUFFER_SIZE, NULL, GL_STREAM_DRAW); - } - - glEnableClientState(GL_VERTEX_ARRAY); - fnSetupVertexPointers = NULL; - GL_REPORT_ERRORD(); - - return true; -} - -void VertexManager::Destroy() -{ - FreeMemoryPages(s_pBaseBufferPointer, MAX_BUFFER_SIZE); s_pBaseBufferPointer = s_pCurBufferPointer = NULL; - glDeleteBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers); - memset(s_vboBuffers, 0, sizeof(s_vboBuffers)); - - s_vStoredPrimitives.resize(0); - s_nCurVBOIndex = 0; - ResetBuffer(); -} - -void VertexManager::ResetBuffer() -{ - s_nCurVBOIndex = (s_nCurVBOIndex+1)%ARRAYSIZE(s_vboBuffers); - s_pCurBufferPointer = s_pBaseBufferPointer; - s_vStoredPrimitives.resize(0); -} - -void VertexManager::ResetComponents() -{ - s_prevcomponents = 0; - s_prevvbstride = 12; // just pos - s_prevprimitive = 0; - glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableVertexAttribArray(SHADER_NORM1_ATTRIB); - glDisableVertexAttribArray(SHADER_NORM2_ATTRIB); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_SECONDARY_COLOR_ARRAY); - for (int i = 0; i < 8; ++i) glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - -int VertexManager::GetRemainingSize() -{ - return MAX_BUFFER_SIZE - (int)(s_pCurBufferPointer-s_pBaseBufferPointer); -} - -void VertexManager::AddVertices(int primitive, int numvertices) -{ - _assert_( numvertices > 0 ); - - ADDSTAT(stats.thisFrame.numPrims, numvertices); - s_vStoredPrimitives.push_back(pair(c_primitiveType[primitive], numvertices)); - -#ifdef _DEBUG - static const char *sprims[8] = {"quads", "nothing", "tris", "tstrip", "tfan", "lines", "lstrip", "points"}; - PRIM_LOG("prim: %s, c=%d\n", sprims[primitive], numvertices); -#endif -} - -void VertexManager::Flush() -{ - if (s_vStoredPrimitives.size() == 0) - return; - - _assert_( fnSetupVertexPointers != NULL ); - _assert_( s_pCurBufferPointer != s_pBaseBufferPointer ); - -#ifdef _DEBUG - PRIM_LOG("frame%d:\ncomps=0x%x, texgen=%d, numchan=%d, dualtex=%d, ztex=%d, proj=%d, cole=%d, alpe=%d, ze=%d\n", g_Config.iSaveTargetId, s_prevcomponents, xfregs.numTexGens, - xfregs.nNumChans, (int)xfregs.bEnableDualTexTransform, bpmem.ztex2.op, VertexShaderMngr::rawProjection[6]==0, - bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, bpmem.zmode.updateenable); - for(int i = 0; i < xfregs.nNumChans; ++i) { - LitChannel* ch = &xfregs.colChans[i].color; - PRIM_LOG("colchan%d: matsrc=%d, light=0x%x, ambsrc=%d, diffunc=%d, attfunc=%d\n", i, ch->matsource, ch->GetFullLightMask(), ch->ambsource, ch->diffusefunc, ch->attnfunc); - ch = &xfregs.colChans[i].alpha; - PRIM_LOG("alpchan%d: matsrc=%d, light=0x%x, ambsrc=%d, diffunc=%d, attfunc=%d\n", i, ch->matsource, ch->GetFullLightMask(), ch->ambsource, ch->diffusefunc, ch->attnfunc); - } - for(int i = 0; i < xfregs.numTexGens; ++i) { - TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo; - if( tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP ) tinfo.hex &= 0x7ff; - if( tinfo.texgentype != XF_TEXGEN_REGULAR ) tinfo.projection = 0; - - PRIM_LOG("txgen%d: proj=%d, input=%d, gentype=%d, srcrow=%d, embsrc=%d, emblght=%d, postmtx=%d, postnorm=%d\n", - i, tinfo.projection, tinfo.inputform, tinfo.texgentype, tinfo.sourcerow, tinfo.embosssourceshift, tinfo.embosslightshift, - xfregs.texcoords[i].postmtxinfo.index, xfregs.texcoords[i].postmtxinfo.normalize); - } - - PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphafunc=0x%x\n", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages, - bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alphaFunc.hex>>16)&0xff); -#endif - - DVSTARTPROFILE(); - - GL_REPORT_ERRORD(); - - glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]); - glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer-s_pBaseBufferPointer, s_pBaseBufferPointer, GL_STREAM_DRAW); - GL_REPORT_ERRORD(); - - // setup the pointers - fnSetupVertexPointers(); - GL_REPORT_ERRORD(); - - // set the textures - { - DVProfileFunc _pf("VertexManager::Flush:textures"); - - u32 usedtextures = 0; - for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages+1; ++i) { - if( bpmem.tevorders[i/2].getEnable(i&1) ) - usedtextures |= 1< 0 ) { - for(u32 i = 0; i < (u32)bpmem.genMode.numtevstages+1; ++i) { - if( bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages ) { - usedtextures |= 1<>2]; - TextureMngr::TCacheEntry* tentry = TextureMngr::Load(i, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, - tex.texImage0[i&3].width+1, tex.texImage0[i&3].height+1, - tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format); - - if( tentry != NULL ) { - // texture loaded fine, set dims for pixel shader - if( tentry->isNonPow2 ) { - PixelShaderMngr::SetTexDims(i, tentry->w, tentry->h, tentry->mode.wrap_s, tentry->mode.wrap_t); - nonpow2tex |= 1<mode.wrap_s > 0 ) nonpow2tex |= 1<<(8+i); - if( tentry->mode.wrap_t > 0 ) nonpow2tex |= 1<<(16+i); - TextureMngr::EnableTexRECT(i); - } - // if texture is power of two, set to ones (since don't need scaling) - else - { - PixelShaderMngr::SetTexDims(i, tentry->w, tentry->h, 0, 0); - TextureMngr::EnableTex2D(i); - } - - if( g_Config.iLog & CONF_PRIMLOG ) { - // save the textures - char strfile[255]; - sprintf(strfile, "frames/tex%.3d_%d.tga", g_Config.iSaveTargetId, i); - SaveTexture(strfile, tentry->isNonPow2?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D, tentry->texture, tentry->w, tentry->h); - } - } - else { - ERROR_LOG("error loading tex\n"); - TextureMngr::DisableStage(i); // disable since won't be used - } - } - else { - TextureMngr::DisableStage(i); // disable since won't be used - } - } - - PixelShaderMngr::SetTexturesUsed(nonpow2tex); - } - - FRAGMENTSHADER* ps = PixelShaderMngr::GetShader(); - VERTEXSHADER* vs = VertexShaderMngr::GetShader(s_prevcomponents); - _assert_( ps != NULL && vs != NULL ); - - bool bRestoreBuffers = false; - if( Renderer::GetZBufferTarget() ) { - if( bpmem.zmode.updateenable ) { - if( !bpmem.blendmode.colorupdate ) { - Renderer::SetRenderMode(bpmem.blendmode.alphaupdate?Renderer::RM_ZBufferAlpha:Renderer::RM_ZBufferOnly); - } - } - else { - Renderer::SetRenderMode(Renderer::RM_Normal); - // remove temporarily - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - bRestoreBuffers = true; - } - } - else - Renderer::SetRenderMode(Renderer::RM_Normal); - - // set global constants - VertexShaderMngr::SetConstants(*vs); - PixelShaderMngr::SetConstants(*ps); - - // finally bind - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vs->glprogid); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ps->glprogid); - - PRIM_LOG("\n"); - - int offset = 0; - vector< pair >::iterator it; - for (it = s_vStoredPrimitives.begin(); it != s_vStoredPrimitives.end(); ++it) { - glDrawArrays(it->first, offset, it->second); - offset += it->second; - } - -#ifdef _DEBUG - if( g_Config.iLog & CONF_PRIMLOG ) { - // save the shaders - char strfile[255]; - sprintf(strfile, "frames/ps%.3d.txt", g_Config.iSaveTargetId); - std::ofstream fps(strfile); - fps << ps->strprog.c_str(); - sprintf(strfile, "frames/vs%.3d.txt", g_Config.iSaveTargetId); - ofstream fvs(strfile); - fvs << vs->strprog.c_str(); - } - - if( g_Config.iLog & CONF_SAVETARGETS ) { - char str[128]; - sprintf(str, "frames/targ%.3d.tga", g_Config.iSaveTargetId); - Renderer::SaveRenderTarget(str, 0); - } -#endif - g_Config.iSaveTargetId++; - - GL_REPORT_ERRORD(); - - if( bRestoreBuffers ) { - GLenum s_drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT}; - glDrawBuffers(2, s_drawbuffers); - SetColorMask(); - } - - ResetBuffer(); -} - -void VertexManager::LoadCPReg(u32 SubCmd, u32 Value) -{ - switch (SubCmd & 0xF0) - { - case 0x30: - VertexShaderMngr::SetTexMatrixChangedA(Value); - break; - case 0x40: - VertexShaderMngr::SetTexMatrixChangedB(Value); - break; - - case 0x50: - s_GlobalVtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits - s_GlobalVtxDesc.Hex |= Value; - break; - case 0x60: - s_GlobalVtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits - s_GlobalVtxDesc.Hex |= (u64)Value << 17; - break; - - case 0x70: g_VertexLoaders[SubCmd & 7].SetVAT_group0(Value); _assert_((SubCmd & 0x0F) < 8); break; - case 0x80: g_VertexLoaders[SubCmd & 7].SetVAT_group1(Value); _assert_((SubCmd & 0x0F) < 8); break; - case 0x90: g_VertexLoaders[SubCmd & 7].SetVAT_group2(Value); _assert_((SubCmd & 0x0F) < 8); break; - - case 0xA0: arraybases[SubCmd & 0xF] = Value & 0xFFFFFFFF; break; - case 0xB0: arraystrides[SubCmd & 0xF] = Value & 0xFF; break; - } -} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h index c19220a6cf..c5fc7bbb77 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h @@ -32,7 +32,8 @@ using namespace std; #define LOADERDECL __cdecl typedef void (LOADERDECL *TPipelineFunction)(void*); -/// Use to manage loading and setting vertex buffer data for OpenGL +// There are 8 of these. Most games only use the first, and just reconfigure it all the time +// as needed, unfortunately. class VertexLoader { public: @@ -97,10 +98,10 @@ private: //common for all loaders TVtxDesc m_VtxDesc; - // seup the pipeline with this vertex fmt void SetupColor(int num, int _iMode, int _iFormat, int _iElements); void SetupTexCoord(int num, int _iMode, int _iFormat, int _iElements, int _iFrac); + // The 3 possible values (0, 1, 2) should be documented here. int m_AttrDirty; public: @@ -124,7 +125,7 @@ public: void SetVAT_group0(u32 _group0) { - if ((m_group0.Hex&~0x3e0001f0) != (_group0&~0x3e0001f0)) { + if ((m_group0.Hex & ~0x3e0001f0) != (_group0 & ~0x3e0001f0)) { m_AttrDirty = 2; } m_group0.Hex = _group0; @@ -147,7 +148,7 @@ public: void SetVAT_group1(u32 _group1) { - if ((m_group1.Hex&~0x7c3e1f0) != (_group1&~0x7c3e1f0)) { + if ((m_group1.Hex & ~0x7c3e1f0) != (_group1 & ~0x7c3e1f0)) { m_AttrDirty = 2; } m_group1.Hex = _group1; @@ -168,7 +169,7 @@ public: void SetVAT_group2(u32 _group2) { - if ((m_group2.Hex&~0xf87c3e1f) != (_group2&~0xf87c3e1f)) { + if ((m_group2.Hex & ~0xf87c3e1f) != (_group2 & ~0xf87c3e1f)) { m_AttrDirty = 2; } m_group2.Hex = _group2; @@ -186,38 +187,6 @@ public: }; }; -/// Methods to manage and cache the global state of vertex streams and flushing streams -/// Also handles processing the CP registers -class VertexManager -{ - static TVtxDesc s_GlobalVtxDesc; - -public: - enum Collection - { - C_NOTHING=0, - C_TRIANGLES=1, - C_LINES=2, - C_POINTS=3 - }; - - static bool Init(); - static void Destroy(); - - static void ResetBuffer(); - static void ResetComponents(); - - static void AddVertices(int primitive, int numvertices); - static void Flush(); // flushes the current buffer - - static int GetRemainingSize(); - static TVtxDesc &GetVtxDesc() {return s_GlobalVtxDesc; } - - static void LoadCPReg(u32 SubCmd, u32 Value); - - static u8* s_pCurBufferPointer; - static float shiftLookup[32]; -}; - extern VertexLoader g_VertexLoaders[8]; + #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader_Normal.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader_Normal.cpp index c8f00848e6..c792c59478 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader_Normal.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader_Normal.cpp @@ -15,11 +15,9 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -//__________________________________________________________________________________________________ -// F|RES 2003-2005 -// #include "Globals.h" #include "VertexLoader.h" +#include "VertexManager.h" #include "VertexLoader_Normal.h" #define LOG_NORM8() PRIM_LOG("norm: %f %f %f, ", ((s8*)VertexManager::s_pCurBufferPointer)[-3]/127.0f, ((s8*)VertexManager::s_pCurBufferPointer)[-2]/127.0f, ((s8*)VertexManager::s_pCurBufferPointer)[-1]/127.0f); @@ -30,9 +28,7 @@ u8 VertexLoader_Normal::m_sizeTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_EL TPipelineFunction VertexLoader_Normal::m_funcTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS]; bool VertexLoader_Normal::index3; -// __________________________________________________________________________________________________ -// Init -// + void VertexLoader_Normal::Init(void) { // size table diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp new file mode 100644 index 0000000000..b28423c31e --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -0,0 +1,325 @@ +#include "Globals.h" + +#include "MemoryUtil.h" +#include "Profiler.h" +#include "Render.h" +#include "ImageWrite.h" +#include "BPMemory.h" +#include "TextureMngr.h" +#include "PixelShaderManager.h" +#include "VertexShaderManager.h" +#include "VertexLoader.h" +#include "VertexManager.h" + +#define MAX_BUFFER_SIZE 0x4000 + +static GLuint s_vboBuffers[0x40] = {0}; +static int s_nCurVBOIndex = 0; // current free buffer +static GLenum s_prevprimitive = 0; // current primitive type +static u8 *s_pBaseBufferPointer = NULL; +static vector< pair > s_vStoredPrimitives; // every element, mode and count to be passed to glDrawArrays + +u8* VertexManager::s_pCurBufferPointer = NULL; +u32 VertexManager::s_prevvbstride; +u32 VertexManager::s_prevcomponents; // previous state set + + +const GLenum c_primitiveType[8] = +{ + GL_QUADS, + 0, //nothing + GL_TRIANGLES, + GL_TRIANGLE_STRIP, + GL_TRIANGLE_FAN, + GL_LINES, + GL_LINE_STRIP, + GL_POINTS +}; + +// internal state for loading vertices +void (*fnSetupVertexPointers)() = NULL; + +bool VertexManager::Init() +{ + Destroy(); + + s_GlobalVtxDesc.Hex = 0; + s_prevcomponents = 0; + s_prevvbstride = 12; // just pos + s_prevprimitive = 0; + s_pBaseBufferPointer = (u8*)AllocateMemoryPages(MAX_BUFFER_SIZE); + s_pCurBufferPointer = s_pBaseBufferPointer; + + for (u32 i = 0; i < ARRAYSIZE(shiftLookup); i++) + shiftLookup[i] = 1.0f / float(1 << i); + + s_nCurVBOIndex = 0; + glGenBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers); + for (u32 i = 0; i < ARRAYSIZE(s_vboBuffers); ++i) { + glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[i]); + glBufferData(GL_ARRAY_BUFFER, MAX_BUFFER_SIZE, NULL, GL_STREAM_DRAW); + } + + glEnableClientState(GL_VERTEX_ARRAY); + fnSetupVertexPointers = NULL; + GL_REPORT_ERRORD(); + + return true; +} + +void VertexManager::Destroy() +{ + FreeMemoryPages(s_pBaseBufferPointer, MAX_BUFFER_SIZE); s_pBaseBufferPointer = s_pCurBufferPointer = NULL; + glDeleteBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers); + memset(s_vboBuffers, 0, sizeof(s_vboBuffers)); + + s_vStoredPrimitives.resize(0); + s_nCurVBOIndex = 0; + ResetBuffer(); +} + +void VertexManager::ResetBuffer() +{ + s_nCurVBOIndex = (s_nCurVBOIndex+1)%ARRAYSIZE(s_vboBuffers); + s_pCurBufferPointer = s_pBaseBufferPointer; + s_vStoredPrimitives.resize(0); +} + +void VertexManager::ResetComponents() +{ + s_prevcomponents = 0; + s_prevvbstride = 12; // just pos + s_prevprimitive = 0; + glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableVertexAttribArray(SHADER_NORM1_ATTRIB); + glDisableVertexAttribArray(SHADER_NORM2_ATTRIB); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_SECONDARY_COLOR_ARRAY); + for (int i = 0; i < 8; ++i) glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +int VertexManager::GetRemainingSize() +{ + return MAX_BUFFER_SIZE - (int)(s_pCurBufferPointer-s_pBaseBufferPointer); +} + +void VertexManager::AddVertices(int primitive, int numvertices) +{ + _assert_( numvertices > 0 ); + + ADDSTAT(stats.thisFrame.numPrims, numvertices); + s_vStoredPrimitives.push_back(pair(c_primitiveType[primitive], numvertices)); + +#ifdef _DEBUG + static const char *sprims[8] = {"quads", "nothing", "tris", "tstrip", "tfan", "lines", "lstrip", "points"}; + PRIM_LOG("prim: %s, c=%d\n", sprims[primitive], numvertices); +#endif +} + +void VertexManager::Flush() +{ + if (s_vStoredPrimitives.size() == 0) + return; + + _assert_( fnSetupVertexPointers != NULL ); + _assert_( s_pCurBufferPointer != s_pBaseBufferPointer ); + +#ifdef _DEBUG + PRIM_LOG("frame%d:\ncomps=0x%x, texgen=%d, numchan=%d, dualtex=%d, ztex=%d, proj=%d, cole=%d, alpe=%d, ze=%d\n", g_Config.iSaveTargetId, s_prevcomponents, xfregs.numTexGens, + xfregs.nNumChans, (int)xfregs.bEnableDualTexTransform, bpmem.ztex2.op, VertexShaderMngr::rawProjection[6]==0, + bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, bpmem.zmode.updateenable); + for (int i = 0; i < xfregs.nNumChans; ++i) { + LitChannel* ch = &xfregs.colChans[i].color; + PRIM_LOG("colchan%d: matsrc=%d, light=0x%x, ambsrc=%d, diffunc=%d, attfunc=%d\n", i, ch->matsource, ch->GetFullLightMask(), ch->ambsource, ch->diffusefunc, ch->attnfunc); + ch = &xfregs.colChans[i].alpha; + PRIM_LOG("alpchan%d: matsrc=%d, light=0x%x, ambsrc=%d, diffunc=%d, attfunc=%d\n", i, ch->matsource, ch->GetFullLightMask(), ch->ambsource, ch->diffusefunc, ch->attnfunc); + } + for (int i = 0; i < xfregs.numTexGens; ++i) { + TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo; + if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP ) tinfo.hex &= 0x7ff; + if (tinfo.texgentype != XF_TEXGEN_REGULAR ) tinfo.projection = 0; + + PRIM_LOG("txgen%d: proj=%d, input=%d, gentype=%d, srcrow=%d, embsrc=%d, emblght=%d, postmtx=%d, postnorm=%d\n", + i, tinfo.projection, tinfo.inputform, tinfo.texgentype, tinfo.sourcerow, tinfo.embosssourceshift, tinfo.embosslightshift, + xfregs.texcoords[i].postmtxinfo.index, xfregs.texcoords[i].postmtxinfo.normalize); + } + + PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphafunc=0x%x\n", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages, + bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alphaFunc.hex>>16)&0xff); +#endif + + DVSTARTPROFILE(); + + GL_REPORT_ERRORD(); + + glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]); + glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer-s_pBaseBufferPointer, s_pBaseBufferPointer, GL_STREAM_DRAW); + GL_REPORT_ERRORD(); + + // setup the pointers + fnSetupVertexPointers(); + GL_REPORT_ERRORD(); + + // set the textures + { + DVProfileFunc _pf("VertexManager::Flush:textures"); + + u32 usedtextures = 0; + for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) { + if (bpmem.tevorders[i/2].getEnable(i & 1)) + usedtextures |= 1< 0) { + for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) { + if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) { + usedtextures |= 1<>2]; + TextureMngr::TCacheEntry* tentry = TextureMngr::Load(i, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, + tex.texImage0[i&3].width+1, tex.texImage0[i&3].height+1, + tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format); + + if (tentry != NULL) { + // texture loaded fine, set dims for pixel shader + if (tentry->isNonPow2) { + PixelShaderMngr::SetTexDims(i, tentry->w, tentry->h, tentry->mode.wrap_s, tentry->mode.wrap_t); + nonpow2tex |= 1<mode.wrap_s > 0 ) nonpow2tex |= 1<<(8+i); + if (tentry->mode.wrap_t > 0 ) nonpow2tex |= 1<<(16+i); + TextureMngr::EnableTexRECT(i); + } + // if texture is power of two, set to ones (since don't need scaling) + else + { + PixelShaderMngr::SetTexDims(i, tentry->w, tentry->h, 0, 0); + TextureMngr::EnableTex2D(i); + } + if (g_Config.iLog & CONF_PRIMLOG) { + // save the textures + char strfile[255]; + sprintf(strfile, "frames/tex%.3d_%d.tga", g_Config.iSaveTargetId, i); + SaveTexture(strfile, tentry->isNonPow2?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D, tentry->texture, tentry->w, tentry->h); + } + } + else { + ERROR_LOG("error loading tex\n"); + TextureMngr::DisableStage(i); // disable since won't be used + } + } + else { + TextureMngr::DisableStage(i); // disable since won't be used + } + } + + PixelShaderMngr::SetTexturesUsed(nonpow2tex); + } + + FRAGMENTSHADER* ps = PixelShaderMngr::GetShader(); + VERTEXSHADER* vs = VertexShaderMngr::GetShader(s_prevcomponents); + _assert_( ps != NULL && vs != NULL ); + + bool bRestoreBuffers = false; + if (Renderer::GetZBufferTarget()) { + if (bpmem.zmode.updateenable) { + if (!bpmem.blendmode.colorupdate) { + Renderer::SetRenderMode(bpmem.blendmode.alphaupdate?Renderer::RM_ZBufferAlpha:Renderer::RM_ZBufferOnly); + } + } + else { + Renderer::SetRenderMode(Renderer::RM_Normal); + // remove temporarily + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + bRestoreBuffers = true; + } + } + else + Renderer::SetRenderMode(Renderer::RM_Normal); + + // set global constants + VertexShaderMngr::SetConstants(*vs); + PixelShaderMngr::SetConstants(*ps); + + // finally bind + glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vs->glprogid); + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ps->glprogid); + +#ifdef _DEBUG + PRIM_LOG("\n"); +#endif + + int offset = 0; + vector< pair >::iterator it; + for (it = s_vStoredPrimitives.begin(); it != s_vStoredPrimitives.end(); ++it) { + glDrawArrays(it->first, offset, it->second); + offset += it->second; + } + +#ifdef _DEBUG + if (g_Config.iLog & CONF_PRIMLOG) { + // save the shaders + char strfile[255]; + sprintf(strfile, "frames/ps%.3d.txt", g_Config.iSaveTargetId); + std::ofstream fps(strfile); + fps << ps->strprog.c_str(); + sprintf(strfile, "frames/vs%.3d.txt", g_Config.iSaveTargetId); + ofstream fvs(strfile); + fvs << vs->strprog.c_str(); + } + + if (g_Config.iLog & CONF_SAVETARGETS) { + char str[128]; + sprintf(str, "frames/targ%.3d.tga", g_Config.iSaveTargetId); + Renderer::SaveRenderTarget(str, 0); + } +#endif + g_Config.iSaveTargetId++; + + GL_REPORT_ERRORD(); + + if (bRestoreBuffers) { + GLenum s_drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT}; + glDrawBuffers(2, s_drawbuffers); + SetColorMask(); + } + + ResetBuffer(); +} + +void VertexManager::LoadCPReg(u32 SubCmd, u32 Value) +{ + switch (SubCmd & 0xF0) + { + case 0x30: + VertexShaderMngr::SetTexMatrixChangedA(Value); + break; + case 0x40: + VertexShaderMngr::SetTexMatrixChangedB(Value); + break; + + case 0x50: + s_GlobalVtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits + s_GlobalVtxDesc.Hex |= Value; + break; + case 0x60: + s_GlobalVtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits + s_GlobalVtxDesc.Hex |= (u64)Value << 17; + break; + + case 0x70: g_VertexLoaders[SubCmd & 7].SetVAT_group0(Value); _assert_((SubCmd & 0x0F) < 8); break; + case 0x80: g_VertexLoaders[SubCmd & 7].SetVAT_group1(Value); _assert_((SubCmd & 0x0F) < 8); break; + case 0x90: g_VertexLoaders[SubCmd & 7].SetVAT_group2(Value); _assert_((SubCmd & 0x0F) < 8); break; + + case 0xA0: arraybases[SubCmd & 0xF] = Value & 0xFFFFFFFF; break; + case 0xB0: arraystrides[SubCmd & 0xF] = Value & 0xFF; break; + } +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h new file mode 100644 index 0000000000..426fafa443 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -0,0 +1,60 @@ +// 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 _VERTEXMANAGER_H +#define _VERTEXMANAGER_H + +#include "CPMemory.h" + +// Methods to manage and cache the global state of vertex streams and flushing streams +// Also handles processing the CP registers +class VertexManager +{ + static TVtxDesc s_GlobalVtxDesc; + +public: + enum Collection + { + C_NOTHING=0, + C_TRIANGLES=1, + C_LINES=2, + C_POINTS=3 + }; + + static bool Init(); + static void Destroy(); + + static void ResetBuffer(); + static void ResetComponents(); + + static void AddVertices(int primitive, int numvertices); + static void Flush(); // flushes the current buffer + + static int GetRemainingSize(); + static TVtxDesc &GetVtxDesc() {return s_GlobalVtxDesc; } + + static void LoadCPReg(u32 SubCmd, u32 Value); + + // TODO - don't expose these like this. + static u32 s_prevvbstride; + static u32 s_prevcomponents; // previous state set + static u8* s_pCurBufferPointer; + static float shiftLookup[32]; +}; + +#endif // _VERTEXMANAGER_H \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.cpp index d96bee5b7d..f75d275c73 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.cpp @@ -40,17 +40,17 @@ char *GenerateVertexShader(u32 components, bool has_zbuffer_target) _assert_( bpmem.genMode.numcolchans == xfregs.nNumChans); u32 lightMask = 0; - if( xfregs.nNumChans > 0 ) - lightMask |= xfregs.colChans[0].color.GetFullLightMask() | xfregs.colChans[0].alpha.GetFullLightMask(); - if( xfregs.nNumChans > 1 ) + if (xfregs.nNumChans > 0) + lightMask |= xfregs.colChans[0].color.GetFullLightMask() | xfregs.colChans[0].alpha.GetFullLightMask(); + if (xfregs.nNumChans > 1) lightMask |= xfregs.colChans[1].color.GetFullLightMask() | xfregs.colChans[1].alpha.GetFullLightMask(); bool bOutputZ = bpmem.ztex2.op==ZTEXTURE_ADD || has_zbuffer_target; int ztexcoord = -1; char *p = text; - WRITE(p,"//Vertex Shader: comp:%x, \n", components); - WRITE(p,"typedef struct {\n" + WRITE(p, "//Vertex Shader: comp:%x, \n", components); + WRITE(p, "typedef struct {\n" " float4 T0, T1, T2;\n" " float4 N0, N1, N2;\n" "} s_"I_POSNORMALMATRIX";\n\n" @@ -89,25 +89,25 @@ char *GenerateVertexShader(u32 components, bool has_zbuffer_target) " float4 params;\n" // a, b, c, b_shift "} s_"I_FOGPARAMS";\n\n"); - WRITE(p,"struct VS_OUTPUT {\n"); - WRITE(p," float4 pos : POSITION;\n"); - WRITE(p," float4 colors[2] : COLOR0;\n"); + WRITE(p, "struct VS_OUTPUT {\n"); + WRITE(p, " float4 pos : POSITION;\n"); + WRITE(p, " float4 colors[2] : COLOR0;\n"); // if outputting Z, embed the Z coordinate in the w component of a texture coordinate // if number of tex gens occupies all the texture coordinates, use the last tex coord // otherwise use the next available tex coord for (int i = 0; i < xfregs.numTexGens; ++i) { - WRITE(p," float%d tex%d : TEXCOORD%d;\n", (i==(xfregs.numTexGens-1)&&bOutputZ)?4:3, i, i); + WRITE(p, " float%d tex%d : TEXCOORD%d;\n", (i==(xfregs.numTexGens-1)&&bOutputZ)?4:3, i, i); } if (bOutputZ && xfregs.numTexGens == 0) { ztexcoord = 0; - WRITE(p," float4 tex%d : TEXCOORD%d;\n", ztexcoord, ztexcoord); + WRITE(p, " float4 tex%d : TEXCOORD%d;\n", ztexcoord, ztexcoord); } else if (bOutputZ) ztexcoord = xfregs.numTexGens - 1; - WRITE(p,"};\n"); - WRITE(p,"\n"); + WRITE(p, "};\n"); + WRITE(p, "\n"); // uniforms @@ -123,152 +123,152 @@ char *GenerateVertexShader(u32 components, bool has_zbuffer_target) WRITE(p, "uniform s_"I_PROJECTION" "I_PROJECTION" : register(c%d);\n", C_PROJECTION); WRITE(p, "uniform s_"I_FOGPARAMS" "I_FOGPARAMS" : register(c%d);\n", C_FOGPARAMS); - WRITE(p,"VS_OUTPUT main(\n"); + WRITE(p, "VS_OUTPUT main(\n"); // inputs if (components & VertexLoader::VB_HAS_NRM0) - WRITE(p," float3 rawnorm0 : NORMAL,\n"); + WRITE(p, " float3 rawnorm0 : NORMAL,\n"); if (components & VertexLoader::VB_HAS_NRM1) - WRITE(p," float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); + WRITE(p, " float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); if (components & VertexLoader::VB_HAS_NRM2) - WRITE(p," float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); + WRITE(p, " float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); if (components & VertexLoader::VB_HAS_COL0) - WRITE(p," float4 color0 : COLOR0,\n"); + WRITE(p, " float4 color0 : COLOR0,\n"); if (components & VertexLoader::VB_HAS_COL1) - WRITE(p," float4 color1 : COLOR1,\n"); + WRITE(p, " float4 color1 : COLOR1,\n"); for (int i = 0; i < 8; ++i) { u32 hastexmtx = (components & (VertexLoader::VB_HAS_TEXMTXIDX0<= 32 ? (posmtx-32) : posmtx;\n"); - WRITE(p,"float3 N0 = "I_NORMALMATRICES".T[normidx].t.xyz, N1 = "I_NORMALMATRICES".T[normidx+1].t.xyz, N2 = "I_NORMALMATRICES".T[normidx+2].t.xyz;\n"); + WRITE(p, "float3 N0 = "I_NORMALMATRICES".T[normidx].t.xyz, N1 = "I_NORMALMATRICES".T[normidx+1].t.xyz, N2 = "I_NORMALMATRICES".T[normidx+2].t.xyz;\n"); } if (components & VertexLoader::VB_HAS_NRM0) - WRITE(p,"half3 _norm0 = half3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0));\n" - "half3 norm0 = normalize(_norm0);\n"); + WRITE(p, "half3 _norm0 = half3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0));\n" + "half3 norm0 = normalize(_norm0);\n"); if (components & VertexLoader::VB_HAS_NRM1) - WRITE(p,"half3 _norm1 = half3(dot(N0, rawnorm1), dot(N1, rawnorm1), dot(N2, rawnorm1));\n"); + WRITE(p, "half3 _norm1 = half3(dot(N0, rawnorm1), dot(N1, rawnorm1), dot(N2, rawnorm1));\n"); //"half3 norm1 = normalize(_norm1);\n"); if (components & VertexLoader::VB_HAS_NRM2) - WRITE(p,"half3 _norm2 = half3(dot(N0, rawnorm2), dot(N1, rawnorm2), dot(N2, rawnorm2));\n"); + WRITE(p, "half3 _norm2 = half3(dot(N0, rawnorm2), dot(N1, rawnorm2), dot(N2, rawnorm2));\n"); //"half3 norm2 = normalize(_norm2);\n"); } else { WRITE(p, "float4 pos = float4(dot("I_POSNORMALMATRIX".T0, rawpos), dot("I_POSNORMALMATRIX".T1, rawpos), dot("I_POSNORMALMATRIX".T2, rawpos), 1);\n"); if (components & VertexLoader::VB_HAS_NRM0) - WRITE(p,"half3 _norm0 = half3(dot("I_POSNORMALMATRIX".N0.xyz, rawnorm0), dot("I_POSNORMALMATRIX".N1.xyz, rawnorm0), dot("I_POSNORMALMATRIX".N2.xyz, rawnorm0));\n" - "half3 norm0 = normalize(_norm0);\n"); + WRITE(p, "half3 _norm0 = half3(dot("I_POSNORMALMATRIX".N0.xyz, rawnorm0), dot("I_POSNORMALMATRIX".N1.xyz, rawnorm0), dot("I_POSNORMALMATRIX".N2.xyz, rawnorm0));\n" + "half3 norm0 = normalize(_norm0);\n"); if (components & VertexLoader::VB_HAS_NRM1) - WRITE(p,"half3 _norm1 = half3(dot("I_POSNORMALMATRIX".N0.xyz, rawnorm1), dot("I_POSNORMALMATRIX".N1.xyz, rawnorm1), dot("I_POSNORMALMATRIX".N2.xyz, rawnorm1));\n"); + WRITE(p, "half3 _norm1 = half3(dot("I_POSNORMALMATRIX".N0.xyz, rawnorm1), dot("I_POSNORMALMATRIX".N1.xyz, rawnorm1), dot("I_POSNORMALMATRIX".N2.xyz, rawnorm1));\n"); //"half3 norm1 = normalize(_norm1);\n"); if (components & VertexLoader::VB_HAS_NRM2) - WRITE(p,"half3 _norm2 = half3(dot("I_POSNORMALMATRIX".N0.xyz, rawnorm2), dot("I_POSNORMALMATRIX".N1.xyz, rawnorm2), dot("I_POSNORMALMATRIX".N2.xyz, rawnorm2));\n"); + WRITE(p, "half3 _norm2 = half3(dot("I_POSNORMALMATRIX".N0.xyz, rawnorm2), dot("I_POSNORMALMATRIX".N1.xyz, rawnorm2), dot("I_POSNORMALMATRIX".N2.xyz, rawnorm2));\n"); //"half3 norm2 = normalize(_norm2);\n"); } if (!(components & VertexLoader::VB_HAS_NRM0)) - WRITE(p,"half3 _norm0 = half3(0,0,0), norm0= half3(0,0,0);\n"); + WRITE(p, "half3 _norm0 = half3(0,0,0), norm0= half3(0,0,0);\n"); - WRITE(p,"o.pos = float4(dot("I_PROJECTION".T0, pos), dot("I_PROJECTION".T1, pos), dot("I_PROJECTION".T2, pos), dot("I_PROJECTION".T3, pos));\n"); + WRITE(p, "o.pos = float4(dot("I_PROJECTION".T0, pos), dot("I_PROJECTION".T1, pos), dot("I_PROJECTION".T2, pos), dot("I_PROJECTION".T3, pos));\n"); WRITE(p, "half4 mat, lacc;\n" "half3 ldir, h;\n" "half dist, dist2, attn;\n"); // lights/colors - for (int j=0; j= 0 ) + if (ztexcoord >= 0 ) WRITE(p, "o.tex%d.w = o.pos.z/o.pos.w;\n", ztexcoord); -// if( bpmem.fog.c_proj_fsel.fsel != 0 ) { -// switch(bpmem.fog.c_proj_fsel.fsel) { +// if (bpmem.fog.c_proj_fsel.fsel != 0) { +// switch (bpmem.fog.c_proj_fsel.fsel) { // case 1: // linear // break; // case 4: // exp @@ -403,7 +403,7 @@ char *GenerateVertexShader(u32 components, bool has_zbuffer_target) // WRITE(p, "o.fog = o.pos.z/o.pos.w;\n"); // } - WRITE(p,"return o;\n}\n"); + WRITE(p, "return o;\n}\n"); return text; } @@ -412,12 +412,12 @@ char *GenerateVertexShader(u32 components, bool has_zbuffer_target) char* GenerateLightShader(char* p, int index, const LitChannel& chan, const char* dest, int coloralpha) { const char* swizzle = "xyzw"; - if( coloralpha == 1 ) swizzle = "xyz"; - else if( coloralpha == 2 ) swizzle = "w"; + if (coloralpha == 1 ) swizzle = "xyz"; + else if (coloralpha == 2 ) swizzle = "w"; - if( !(chan.attnfunc&1) ) { + if (!(chan.attnfunc&1)) { // atten disabled - switch(chan.diffusefunc) { + switch (chan.diffusefunc) { case LIGHTDIF_NONE: WRITE(p, "%s.%s += "I_LIGHTS".lights[%d].col.%s;\n", dest, swizzle, index, swizzle); break; @@ -433,20 +433,20 @@ char* GenerateLightShader(char* p, int index, const LitChannel& chan, const char else { // spec and spot WRITE(p, "ldir = "I_LIGHTS".lights[%d].pos.xyz - pos.xyz;\n", index); - if( chan.attnfunc == 3 ) { // spot + if (chan.attnfunc == 3) { // spot WRITE(p, "dist2 = dot(ldir, ldir);\n" "dist = sqrt(dist2);\n" "ldir = ldir / dist;\n" "attn = max(0.0f, dot(ldir, "I_LIGHTS".lights[%d].dir.xyz));\n",index); WRITE(p, "attn = max(0.0f, dot("I_LIGHTS".lights[%d].cosatt.xyz, half3(1, attn, attn*attn))) / dot("I_LIGHTS".lights[%d].distatt.xyz, half3(1,dist,dist2));\n", index, index); } - else if( chan.attnfunc == 1) { // specular + else if (chan.attnfunc == 1) { // specular WRITE(p, "attn = dot(norm0, "I_LIGHTS".lights[%d].pos.xyz) > 0 ? max(0.0f, dot(norm0, "I_LIGHTS".lights[%d].dir.xyz)) : 0;\n", index, index); WRITE(p, "ldir = half3(1,attn,attn*attn);\n"); WRITE(p, "attn = max(0.0f, dot("I_LIGHTS".lights[%d].cosatt.xyz, ldir)) / dot("I_LIGHTS".lights[%d].distatt.xyz, ldir);\n", index, index); } - switch(chan.diffusefunc) { + switch (chan.diffusefunc) { case LIGHTDIF_NONE: WRITE(p, "%s.%s += attn * "I_LIGHTS".lights[%d].col.%s;\n", dest, swizzle, index, swizzle); break; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp index 76769fafc9..9b905a7680 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp @@ -19,10 +19,16 @@ #include "Globals.h" #include "Profiler.h" + +#include +#include + #include + #include "Render.h" #include "VertexShader.h" #include "VertexShaderManager.h" +#include "VertexManager.h" #include "VertexLoader.h" #include "BPMemory.h" #include "XFMemory.h" @@ -177,7 +183,7 @@ bool VertexShaderMngr::CompileVertexShader(VERTEXSHADER& vs, const char* pstrpro char* pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); char* plocal = strstr(pcompiledprog, "program.local"); - while( plocal != NULL ) { + while (plocal != NULL) { const char* penv = " program.env"; memcpy(plocal, penv, 13); plocal = strstr(plocal+13, "program.local"); @@ -339,11 +345,8 @@ void VertexShaderMngr::SetConstants(VERTEXSHADER& vs) 2 * rawViewport[0], 2 * rawViewport[1], (rawViewport[5] - rawViewport[2]) / 16777215.0f, rawViewport[5] / 16777215.0f);*/ - // ======================================================================================= // Keep aspect ratio at 4:3 - // ------------- // rawViewport[0] = 320, rawViewport[1] = -240 - // ------------- int scissorXOff = bpmem.scissorOffset.x * 2 - 342; int scissorYOff = bpmem.scissorOffset.y * 2 - 342; float fourThree = 4.0f/3.0f; @@ -352,10 +355,10 @@ void VertexShaderMngr::SetConstants(VERTEXSHADER& vs) int overfl; int xoffs = 0; int yoffs = 0; int wid, hei, actualWid, actualHei; int winw = nBackbufferWidth; int winh = nBackbufferHeight; - if(g_Config.bKeepAR) + if (g_Config.bKeepAR) { // Check if height or width is the limiting factor - if(ratio > 1) // then we are to wide and have to limit the width + if (ratio > 1) // then we are to wide and have to limit the width { wAdj = ratio; hAdj = 1; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index b8d753da24..a84e1ea2a0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -27,6 +27,8 @@ #include "GUI/ConfigDlg.h" +#include "LookUpTables.h" +#include "ImageWrite.h" #include "Render.h" #include "GLInit.h" #include "Fifo.h" @@ -34,6 +36,7 @@ #include "TextureMngr.h" #include "BPStructs.h" #include "VertexLoader.h" +#include "VertexManager.h" #include "PixelShaderManager.h" #include "VertexShaderManager.h" #include "XFB.h" @@ -45,12 +48,9 @@ SVideoInitialize g_VideoInitialize; #define VERSION_STRING "0.1" - -// ======================================================================================= // Create debugging window. We can't use Show() here as usual because then DLL_PROCESS_DETACH will // be called immediately. And if we use ShowModal() we block the main video window from appearing. // So I've made a separate function called DoDllDebugger() that creates the window. -// ------------------- CDebugger* m_frame; void DllDebugger(HWND _hParent) { @@ -69,8 +69,6 @@ void DoDllDebugger() m_frame = new CDebugger(NULL); m_frame->Show(); } -// =================== - void GetDllInfo (PLUGIN_INFO* _PluginInfo) { @@ -101,7 +99,7 @@ void DllConfig(HWND _hParent) std::string resos[100]; int i = 0; - while(EnumDisplaySettings(NULL, iModeNum++, &dmi) != 0) + while (EnumDisplaySettings(NULL, iModeNum++, &dmi) != 0) { char szBuffer[100]; sprintf(szBuffer,"%dx%d", dmi.dmPelsWidth, dmi.dmPelsHeight); @@ -110,7 +108,7 @@ void DllConfig(HWND _hParent) //create a check loop to check every pointer of resos to see if the res is added or not int b = 0; bool resFound = false; - while(b < i && !resFound) + while (b < i && !resFound) { //is the res already added? resFound = (resos[b] == strBuffer); @@ -164,13 +162,10 @@ void DllConfig(HWND _hParent) XFree(modes); frame.ShowModal(); #else - //TODO - #endif } - void Video_Initialize(SVideoInitialize* _pVideoInitialize) { if (_pVideoInitialize == NULL) @@ -197,7 +192,6 @@ void Video_Initialize(SVideoInitialize* _pVideoInitialize) Renderer::AddMessage("Dolphin OpenGL Video Plugin v" VERSION_STRING ,5000); } - void Video_DoState(unsigned char **ptr, int mode) { // Clear all caches @@ -208,9 +202,7 @@ void Video_DoState(unsigned char **ptr, int mode) { //PanicAlert("Saving/Loading state from OpenGL"); } -// ======================================================================================= -// This is run after Video_Initialize() from the Core -// -------------- +// This is called after Video_Initialize() from the Core void Video_Prepare(void) { OpenGL_MakeCurrent(); @@ -230,8 +222,6 @@ void Video_Prepare(void) PixelShaderMngr::Init(); GL_REPORT_ERRORD(); } -// ============== - void Video_Shutdown(void) { @@ -255,7 +245,6 @@ void Video_EnterLoop() Fifo_EnterLoop(g_VideoInitialize); } - void DebugLog(const char* _fmt, ...) { #if defined(_DEBUG) || defined(DEBUGFAST) @@ -271,7 +260,6 @@ void DebugLog(const char* _fmt, ...) #endif } - bool ScreenShot(TCHAR *File) { char str[64]; @@ -292,7 +280,6 @@ bool ScreenShot(TCHAR *File) return false; } - BOOL Video_Screenshot(TCHAR* _szFilename) { if (ScreenShot(_szFilename)) @@ -301,7 +288,6 @@ BOOL Video_Screenshot(TCHAR* _szFilename) return FALSE; } - void Video_UpdateXFB(u8* _pXFB, u32 _dwWidth, u32 _dwHeight, s32 _dwYOffset) { if(g_Config.bUseXFB)