From 6c916151ab0f924be3e58eca3756d40e31bc42a6 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Fri, 26 Dec 2008 11:23:59 +0000 Subject: [PATCH] Split out the shader caches into their own files. The goal is to eventually be able to move the "Managers" to VideoCommon. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1681 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/x64Emitter.h | 4 +- .../Plugin_VideoOGL/Plugin_VideoOGL.vcproj | 24 + .../Plugin_VideoOGL/Src/PixelShaderCache.cpp | 223 ++++++++++ .../Plugin_VideoOGL/Src/PixelShaderCache.h | 63 +++ .../Src/PixelShaderManager.cpp | 195 +------- .../Plugin_VideoOGL/Src/PixelShaderManager.h | 45 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 1 + Source/Plugins/Plugin_VideoOGL/Src/SConscript | 4 +- .../Plugin_VideoOGL/Src/TextureConverter.cpp | 2 +- .../Plugin_VideoOGL/Src/TextureMngr.cpp | 3 +- .../Plugin_VideoOGL/Src/VertexManager.cpp | 2 + .../Plugin_VideoOGL/Src/VertexShaderCache.cpp | 175 ++++++++ .../Plugin_VideoOGL/Src/VertexShaderCache.h | 59 +++ .../Src/VertexShaderManager.cpp | 416 ++---------------- .../Plugin_VideoOGL/Src/VertexShaderManager.h | 47 +- Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 2 + 16 files changed, 607 insertions(+), 658 deletions(-) create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h diff --git a/Source/Core/Common/Src/x64Emitter.h b/Source/Core/Common/Src/x64Emitter.h index 963ef7159c..363a18a8f7 100644 --- a/Source/Core/Common/Src/x64Emitter.h +++ b/Source/Core/Common/Src/x64Emitter.h @@ -285,7 +285,9 @@ public: void JMP(OpArg arg); void JMPptr(const OpArg &arg); void JMPself(); //infinite loop! - +#ifdef CALL +#undef CALL +#endif void CALL(const void *fnptr); void CALLptr(OpArg arg); diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj index a133f3f58e..ab6ada4211 100644 --- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj +++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj @@ -792,10 +792,26 @@ RelativePath=".\Src\VertexManager.h" > + + + + + + + + @@ -844,6 +860,14 @@ RelativePath=".\Src\TextureMngr.h" > + + + + diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp new file mode 100644 index 0000000000..8cf1e3bf57 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -0,0 +1,223 @@ +// 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 "Profiler.h" + +#include "GLUtil.h" + +#include +#include + +#include + +#include "Statistics.h" +#include "Config.h" +#include "ImageWrite.h" +#include "Common.h" +#include "Render.h" +#include "VertexShader.h" +#include "PixelShaderCache.h" +#include "PixelShaderManager.h" + +static int s_nMaxPixelInstructions; +static GLuint s_ColorMatrixProgram = 0; +PixelShaderCache::PSCache PixelShaderCache::pshaders; +PIXELSHADERUID PixelShaderCache::s_curuid; + +static FRAGMENTSHADER* pShaderLast = NULL; + +void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4) +{ + glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f1, f2, f3, f4); +} + +void SetPSConstant4fv(int const_number, const float *f) +{ + glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f); +} + +void PixelShaderCache::Init() +{ + GL_REPORT_ERRORD(); + + glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions); + + int maxinst, maxattribs; + glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&maxinst); + glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, (GLint *)&maxattribs); + ERROR_LOG("pixel max_alu=%d, max_inst=%d, max_attrib=%d\n", s_nMaxPixelInstructions, maxinst, maxattribs); + + char pmatrixprog[1024]; + sprintf(pmatrixprog, "!!ARBfp1.0" + "TEMP R0;\n" + "TEMP R1;\n" + "TEX R0, fragment.texcoord[0], texture[0], RECT;\n" + "DP4 R1.w, R0, program.env[%d];\n" + "DP4 R1.z, R0, program.env[%d];\n" + "DP4 R1.x, R0, program.env[%d];\n" + "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); + + GLenum err = GL_NO_ERROR; + GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) { + ERROR_LOG("Failed to create color matrix fragment program\n"); + glDeleteProgramsARB(1, &s_ColorMatrixProgram); + s_ColorMatrixProgram = 0; + } +} + +void PixelShaderCache::Shutdown() +{ + glDeleteProgramsARB(1, &s_ColorMatrixProgram); + s_ColorMatrixProgram = 0; + PSCache::iterator iter = pshaders.begin(); + for (; iter != pshaders.end(); iter++) + iter->second.Destroy(); + pshaders.clear(); +} + +GLuint PixelShaderCache::GetColorMatrixProgram() +{ + return s_ColorMatrixProgram; +} + + +FRAGMENTSHADER* PixelShaderCache::GetShader() +{ + DVSTARTPROFILE(); + PIXELSHADERUID uid; + u32 zbufrender = (Renderer::GetZBufferTarget() && bpmem.zmode.updateenable) ? 1 : 0; + u32 zBufRenderToCol0 = Renderer::GetRenderMode() != Renderer::RM_Normal; + GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), zbufrender, zBufRenderToCol0); + + PSCache::iterator iter = pshaders.find(uid); + + if (iter != pshaders.end()) { + iter->second.frameCount = frameCount; + PSCacheEntry &entry = iter->second; + if (&entry.shader != pShaderLast) + { + pShaderLast = &entry.shader; + } + return pShaderLast; + } + + PSCacheEntry& newentry = pshaders[uid]; + char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), + Renderer::GetZBufferTarget() != 0, + Renderer::GetRenderMode() != Renderer::RM_Normal); + +#if defined(_DEBUG) || defined(DEBUGFAST) + 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++); + + SaveData(szTemp, code); + } +#endif + + // printf("Compiling pixel shader. size = %i\n", strlen(code)); + if (!code || !CompilePixelShader(newentry.shader, code)) { + ERROR_LOG("failed to create pixel shader\n"); + return NULL; + } + + //Make an entry in the table + newentry.frameCount = frameCount; + + pShaderLast = &newentry.shader; + INCSTAT(stats.numPixelShadersCreated); + SETSTAT(stats.numPixelShadersAlive, pshaders.size()); + return pShaderLast; +} + +void PixelShaderCache::Cleanup() +{ + PSCache::iterator iter = pshaders.begin(); + while (iter != pshaders.end()) { + PSCacheEntry &entry = iter->second; + if (entry.frameCount < frameCount - 400) { + entry.Destroy(); +#ifdef _WIN32 + iter = pshaders.erase(iter); +#else + pshaders.erase(iter++); // (this is gcc standard!) +#endif + } + else + iter++; + } + SETSTAT(stats.numPixelShadersAlive,(int)pshaders.size()); +} + +bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram) +{ + char stropt[64]; + sprintf(stropt, "MaxLocalParams=32,NumInstructionSlots=%d", s_nMaxPixelInstructions); + const char* opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; + CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts); + if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { + ERROR_LOG("Failed to create ps %s:\n", cgGetLastListing(g_cgcontext)); + ERROR_LOG(pstrprogram); + return false; + } + + char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); + char *plocal = strstr(pcompiledprog, "program.local"); + while (plocal != NULL) { + const char* penv = " program.env"; + memcpy(plocal, penv, 13); + plocal = strstr(plocal+13, "program.local"); + } + + if (Renderer::IsUsingATIDrawBuffers()) { + // sometimes compilation can use ARB_draw_buffers, which would fail for ATI cards + // replace the three characters ARB with ATI. TODO - check whether this is fixed in modern ATI drivers. + char* poptions = strstr(pcompiledprog, "ARB_draw_buffers"); + if (poptions != NULL) { + poptions[0] = 'A'; + poptions[1] = 'T'; + poptions[2] = 'I'; + } + } + + glGenProgramsARB( 1, &ps.glprogid ); + glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, ps.glprogid ); + glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); + + GLenum err = GL_NO_ERROR; + GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) { + ERROR_LOG(pstrprogram); + ERROR_LOG(pcompiledprog); + } + + cgDestroyProgram(tempprog); + // printf("Compiled pixel shader %i\n", ps.glprogid); + +#if defined(_DEBUG) || defined(DEBUGFAST) + ps.strprog = pstrprogram; +#endif + return true; +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h new file mode 100644 index 0000000000..a2c3ef85c0 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h @@ -0,0 +1,63 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include "BPMemory.h" +#include "PixelShader.h" + +struct FRAGMENTSHADER +{ + FRAGMENTSHADER() : glprogid(0) { } + GLuint glprogid; // opengl program id +#if defined(_DEBUG) || defined(DEBUGFAST) + std::string strprog; +#endif +}; + +class PixelShaderCache +{ + struct PSCacheEntry + { + FRAGMENTSHADER shader; + int frameCount; + PSCacheEntry() : frameCount(0) {} + ~PSCacheEntry() {} + void Destroy() { + // printf("Destroying ps %i\n", shader.glprogid); + glDeleteProgramsARB(1, &shader.glprogid); + shader.glprogid = 0; + } + }; + + typedef std::map PSCache; + + static PSCache pshaders; + + static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written) + +public: + static void Init(); + static void Cleanup(); + static void Shutdown(); + + static FRAGMENTSHADER* GetShader(); + static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram); + + static GLuint GetColorMatrixProgram(); +}; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp index 3eafc15be8..b04c7a06c0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp @@ -15,29 +15,18 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "Common.h" #include "Globals.h" #include "Profiler.h" -#include "GLUtil.h" - -#include -#include - #include #include "Statistics.h" #include "Config.h" -#include "ImageWrite.h" -#include "Common.h" + #include "Render.h" -#include "VertexShader.h" #include "PixelShaderManager.h" -PixelShaderCache::PSCache PixelShaderCache::pshaders; -PIXELSHADERUID PixelShaderCache::s_curuid; - -static FRAGMENTSHADER* pShaderLast = NULL; -static int s_nMaxPixelInstructions; static int s_nColorsChanged[2]; // 0 - regular colors, 1 - k colors static int s_nIndTexMtxChanged = 0; static bool s_bAlphaChanged; @@ -56,181 +45,6 @@ static u32 s_texturemask = 0; static int maptocoord[8]; // indexed by texture map, holds the texcoord associated with the map static u32 maptocoord_mask = 0; - -static GLuint s_ColorMatrixProgram = 0; - -void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4) { - glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f1, f2, f3, f4); -} - -void SetPSConstant4fv(int const_number, const float *f) { - glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f); -} - -void PixelShaderCache::Init() -{ - GL_REPORT_ERRORD(); - - glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions); - - int maxinst, maxattribs; - glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&maxinst); - glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, (GLint *)&maxattribs); - ERROR_LOG("pixel max_alu=%d, max_inst=%d, max_attrib=%d\n", s_nMaxPixelInstructions, maxinst, maxattribs); - - char pmatrixprog[1024]; - sprintf(pmatrixprog, "!!ARBfp1.0" - "TEMP R0;\n" - "TEMP R1;\n" - "TEX R0, fragment.texcoord[0], texture[0], RECT;\n" - "DP4 R1.w, R0, program.env[%d];\n" - "DP4 R1.z, R0, program.env[%d];\n" - "DP4 R1.x, R0, program.env[%d];\n" - "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); - - GLenum err = GL_NO_ERROR; - GL_REPORT_ERROR(); - if (err != GL_NO_ERROR) { - ERROR_LOG("Failed to create color matrix fragment program\n"); - glDeleteProgramsARB(1, &s_ColorMatrixProgram); - s_ColorMatrixProgram = 0; - } -} - -void PixelShaderCache::Shutdown() -{ - glDeleteProgramsARB(1, &s_ColorMatrixProgram); - s_ColorMatrixProgram = 0; - PSCache::iterator iter = pshaders.begin(); - for (; iter != pshaders.end(); iter++) - iter->second.Destroy(); - pshaders.clear(); -} - -FRAGMENTSHADER* PixelShaderCache::GetShader() -{ - DVSTARTPROFILE(); - PIXELSHADERUID uid; - u32 zbufrender = (Renderer::GetZBufferTarget() && bpmem.zmode.updateenable) ? 1 : 0; - u32 zBufRenderToCol0 = Renderer::GetRenderMode() != Renderer::RM_Normal; - GetPixelShaderId(uid, s_texturemask, zbufrender, zBufRenderToCol0); - - PSCache::iterator iter = pshaders.find(uid); - - if (iter != pshaders.end()) { - iter->second.frameCount = frameCount; - PSCacheEntry &entry = iter->second; - if (&entry.shader != pShaderLast) - { - pShaderLast = &entry.shader; - } - return pShaderLast; - } - - PSCacheEntry& newentry = pshaders[uid]; - char *code = GeneratePixelShader(s_texturemask, - Renderer::GetZBufferTarget() != 0, - Renderer::GetRenderMode() != Renderer::RM_Normal); - -#if defined(_DEBUG) || defined(DEBUGFAST) - 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++); - - SaveData(szTemp, code); - } -#endif - - // printf("Compiling pixel shader. size = %i\n", strlen(code)); - if (!code || !CompilePixelShader(newentry.shader, code)) { - ERROR_LOG("failed to create pixel shader\n"); - return NULL; - } - - //Make an entry in the table - newentry.frameCount = frameCount; - - pShaderLast = &newentry.shader; - INCSTAT(stats.numPixelShadersCreated); - SETSTAT(stats.numPixelShadersAlive, pshaders.size()); - return pShaderLast; -} - -void PixelShaderCache::Cleanup() -{ - PSCache::iterator iter = pshaders.begin(); - while (iter != pshaders.end()) { - PSCacheEntry &entry = iter->second; - if (entry.frameCount < frameCount - 400) { - entry.Destroy(); -#ifdef _WIN32 - iter = pshaders.erase(iter); -#else - pshaders.erase(iter++); // (this is gcc standard!) -#endif - } - else - iter++; - } - SETSTAT(stats.numPixelShadersAlive,(int)pshaders.size()); -} - -bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram) -{ - char stropt[64]; - sprintf(stropt, "MaxLocalParams=32,NumInstructionSlots=%d", s_nMaxPixelInstructions); - const char* opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; - CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts); - if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { - ERROR_LOG("Failed to create ps %s:\n", cgGetLastListing(g_cgcontext)); - ERROR_LOG(pstrprogram); - return false; - } - - char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); - char *plocal = strstr(pcompiledprog, "program.local"); - while (plocal != NULL) { - const char* penv = " program.env"; - memcpy(plocal, penv, 13); - plocal = strstr(plocal+13, "program.local"); - } - - if (Renderer::IsUsingATIDrawBuffers()) { - // sometimes compilation can use ARB_draw_buffers, which would fail for ATI cards - // replace the three characters ARB with ATI. TODO - check whether this is fixed in modern ATI drivers. - char* poptions = strstr(pcompiledprog, "ARB_draw_buffers"); - if (poptions != NULL) { - poptions[0] = 'A'; - poptions[1] = 'T'; - poptions[2] = 'I'; - } - } - - glGenProgramsARB( 1, &ps.glprogid ); - glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, ps.glprogid ); - glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); - - GLenum err = GL_NO_ERROR; - GL_REPORT_ERROR(); - if (err != GL_NO_ERROR) { - ERROR_LOG(pstrprogram); - ERROR_LOG(pcompiledprog); - } - - cgDestroyProgram(tempprog); - // printf("Compiled pixel shader %i\n", ps.glprogid); - -#if defined(_DEBUG) || defined(DEBUGFAST) - ps.strprog = pstrprogram; -#endif - return true; -} void PixelShaderManager::Init() { @@ -531,8 +345,7 @@ void PixelShaderManager::SetColorMatrix(const float* pmatrix, const float* pfCon SetPSConstant4fv(C_COLORMATRIX+4, pfConstAdd); } -GLuint PixelShaderManager::GetColorMatrixProgram() +u32 PixelShaderManager::GetTextureMask() { - return s_ColorMatrixProgram; + return s_texturemask; } - diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.h index f1ea587f1a..5b08ac25b2 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.h @@ -18,51 +18,9 @@ #ifndef _PIXELSHADERMANAGER_H #define _PIXELSHADERMANAGER_H -#include -#include - #include "BPMemory.h" #include "PixelShader.h" -struct FRAGMENTSHADER -{ - FRAGMENTSHADER() : glprogid(0) { } - GLuint glprogid; // opengl program id -#if defined(_DEBUG) || defined(DEBUGFAST) - std::string strprog; -#endif -}; - -class PixelShaderCache -{ - struct PSCacheEntry - { - FRAGMENTSHADER shader; - int frameCount; - PSCacheEntry() : frameCount(0) {} - ~PSCacheEntry() {} - void Destroy() { - // printf("Destroying ps %i\n", shader.glprogid); - glDeleteProgramsARB(1, &shader.glprogid); - shader.glprogid = 0; - } - }; - - typedef std::map PSCache; - - static PSCache pshaders; - - static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written) - -public: - static void Init(); - static void Cleanup(); - static void Shutdown(); - - static FRAGMENTSHADER* GetShader(); - static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram); -}; - void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4); void SetPSConstant4fv(int const_number, const float *f); @@ -96,7 +54,8 @@ public: static void SetTexDimsChanged(int texmapid); static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd); - static GLuint GetColorMatrixProgram(); + + static u32 GetTextureMask(); }; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index b08e196d8c..a52201a590 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -38,6 +38,7 @@ #include "TextureMngr.h" #include "rasterfont.h" #include "VertexShader.h" +#include "PixelShaderCache.h" #include "PixelShaderManager.h" #include "VertexLoaderManager.h" #include "VertexLoader.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/SConscript b/Source/Plugins/Plugin_VideoOGL/Src/SConscript index 3b1ab4f102..278a1ddf37 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/SConscript +++ b/Source/Plugins/Plugin_VideoOGL/Src/SConscript @@ -14,7 +14,6 @@ files = [ 'Globals.cpp', 'Config.cpp', 'memcpy_amd.cpp', - 'PixelShaderManager.cpp', 'rasterfont.cpp', 'Render.cpp', 'TextureMngr.cpp', @@ -27,7 +26,10 @@ files = [ 'VertexLoader_Position.cpp', 'VertexLoader_TextCoord.cpp', 'VertexLoaderManager.cpp', + 'PixelShaderManager.cpp', 'VertexShaderManager.cpp', + 'PixelShaderCache.cpp', + 'VertexShaderCache.cpp', 'TextureConverter.cpp', 'XFB.cpp', ] diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index f52e9a8dc0..c32e415208 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -16,7 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "TextureConverter.h" -#include "PixelShaderManager.h" +#include "PixelShaderCache.h" #include "VertexShaderManager.h" #include "Globals.h" #include "GLUtil.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index e8d027fb07..23efba2430 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -40,6 +40,7 @@ #include "BPStructs.h" #include "TextureDecoder.h" #include "TextureMngr.h" +#include "PixelShaderCache.h" #include "PixelShaderManager.h" #include "VertexShaderManager.h" @@ -578,7 +579,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool glViewport(0, 0, w, h); glEnable(GL_FRAGMENT_PROGRAM_ARB); - glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, PixelShaderManager::GetColorMatrixProgram()); + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, PixelShaderCache::GetColorMatrixProgram()); PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation GL_REPORT_ERRORD(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 00361aca26..edb5cce746 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -11,7 +11,9 @@ #include "ImageWrite.h" #include "BPMemory.h" #include "TextureMngr.h" +#include "PixelShaderCache.h" #include "PixelShaderManager.h" +#include "VertexShaderCache.h" #include "VertexShaderManager.h" #include "VertexShader.h" #include "VertexLoader.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp new file mode 100644 index 0000000000..f776893fd8 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -0,0 +1,175 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include + +#include "Globals.h" +#include "Profiler.h" +#include "Config.h" +#include "Statistics.h" + +#include "GLUtil.h" + +#include +#include + +#include "Render.h" +#include "VertexShader.h" +#include "VertexShaderManager.h" +#include "VertexShaderCache.h" +#include "VertexManager.h" +#include "VertexLoader.h" +#include "XFMemory.h" + +VertexShaderCache::VSCache VertexShaderCache::vshaders; + +static VERTEXSHADER *pShaderLast = NULL; +static int s_nMaxVertexInstructions; + +void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4) +{ + glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, const_number, f1, f2, f3, f4); +} + +void SetVSConstant4fv(int const_number, const float *f) +{ + glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f); +} + + +void VertexShaderCache::Init() +{ + glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions); +} + +void VertexShaderCache::Shutdown() +{ + for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); iter++) + iter->second.Destroy(); + vshaders.clear(); +} + + +VERTEXSHADER* VertexShaderCache::GetShader(u32 components) +{ + DVSTARTPROFILE(); + VERTEXSHADERUID uid; + u32 zbufrender = (bpmem.ztex2.op == ZTEXTURE_ADD) || Renderer::GetZBufferTarget() != 0; + GetVertexShaderId(uid, components, zbufrender); + + VSCache::iterator iter = vshaders.find(uid); + + if (iter != vshaders.end()) { + iter->second.frameCount = frameCount; + VSCacheEntry &entry = iter->second; + if (&entry.shader != pShaderLast) { + pShaderLast = &entry.shader; + } + return pShaderLast; + } + + VSCacheEntry& entry = vshaders[uid]; + const char *code = GenerateVertexShader(components, Renderer::GetZBufferTarget() != 0); + +#if defined(_DEBUG) || defined(DEBUGFAST) + if (g_Config.iLog & CONF_SAVESHADERS && code) { + static int counter = 0; + char szTemp[MAX_PATH]; + sprintf(szTemp, "%s/vs_%04i.txt", g_Config.texDumpPath, counter++); + + SaveData(szTemp, code); + } +#endif + + if (!code || !VertexShaderCache::CompileVertexShader(entry.shader, code)) { + ERROR_LOG("failed to create vertex shader\n"); + return NULL; + } + + //Make an entry in the table + entry.frameCount = frameCount; + pShaderLast = &entry.shader; + INCSTAT(stats.numVertexShadersCreated); + SETSTAT(stats.numVertexShadersAlive, vshaders.size()); + return pShaderLast; +} + +void VertexShaderCache::Cleanup() +{ + VSCache::iterator iter = vshaders.begin(); + while (iter != vshaders.end()) { + VSCacheEntry &entry = iter->second; + if (entry.frameCount < frameCount - 200) { + entry.Destroy(); +#ifdef _WIN32 + iter = vshaders.erase(iter); +#else + vshaders.erase(iter++); +#endif + } + else { + ++iter; + } + } + + SETSTAT(stats.numVertexShadersAlive, vshaders.size()); +} + +bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram) +{ + char stropt[64]; + sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions); + const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; + CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts); + if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { + ERROR_LOG("Failed to load vs %s:\n", cgGetLastListing(g_cgcontext)); + ERROR_LOG(pstrprogram); + return false; + } + + //ERROR_LOG(pstrprogram); + //ERROR_LOG("id: %d\n", g_Config.iSaveTargetId); + + char* pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); + char* plocal = strstr(pcompiledprog, "program.local"); + + while (plocal != NULL) { + const char* penv = " program.env"; + memcpy(plocal, penv, 13); + plocal = strstr(plocal+13, "program.local"); + } + + glGenProgramsARB(1, &vs.glprogid); + glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vs.glprogid); + glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); + + GLenum err = GL_NO_ERROR; + GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) { + ERROR_LOG(pstrprogram); + ERROR_LOG(pcompiledprog); + } + + cgDestroyProgram(tempprog); + // printf("Compiled vertex shader %i\n", vs.glprogid); + +#if defined(_DEBUG) || defined(DEBUGFAST) + vs.strprog = pstrprogram; +#endif + + return true; +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h new file mode 100644 index 0000000000..eb93a3d543 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h @@ -0,0 +1,59 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include "BPMemory.h" +#include "VertexShader.h" + +struct VERTEXSHADER +{ + VERTEXSHADER() : glprogid(0) {} + GLuint glprogid; // opengl program id + +#if defined(_DEBUG) || defined(DEBUGFAST) + std::string strprog; +#endif +}; + +class VertexShaderCache +{ + struct VSCacheEntry + { + VERTEXSHADER shader; + int frameCount; + VSCacheEntry() : frameCount(0) {} + void Destroy() { + // printf("Destroying vs %i\n", shader.glprogid); + glDeleteProgramsARB(1, &shader.glprogid); + shader.glprogid = 0; + } + }; + + typedef std::map VSCache; + + static VSCache vshaders; + +public: + static void Init(); + static void Cleanup(); + static void Shutdown(); + + static VERTEXSHADER* GetShader(u32 components); + static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram); +}; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp index 47938f5482..b21a0b7d1c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.cpp @@ -15,36 +15,22 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "Common.h" #include "Globals.h" #include "Profiler.h" -#include "Config.h" -#include "GLUtil.h" - -#include -#include - -#include +#include #include "Statistics.h" -#include "ImageWrite.h" +#include "Config.h" + #include "Render.h" #include "VertexShader.h" #include "VertexShaderManager.h" #include "VertexManager.h" #include "VertexLoader.h" -#include "BPMemory.h" #include "XFMemory.h" -VertexShaderCache::VSCache VertexShaderCache::vshaders; - -static VERTEXSHADER *pShaderLast = NULL; - -static float GC_ALIGNED16(g_fProjectionMatrix[16]); - -// Internal Variables -static int s_nMaxVertexInstructions; - static float s_fMaterials[16]; // track changes @@ -55,13 +41,6 @@ static int nNormalMatricesChanged[2]; // min,max static int nPostTransformMatricesChanged[2]; // min,max static int nLightsChanged[2]; // min,max -void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4) { - glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, const_number, f1, f2, f3, f4); -} - -void SetVSConstant4fv(int const_number, const float *f) { - glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f); -} void VertexShaderManager::Init() { @@ -77,133 +56,11 @@ void VertexShaderManager::Init() memset(xfmem, 0, sizeof(xfmem)); } -void VertexShaderCache::Init() -{ - glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions); -} - -void VertexShaderCache::Shutdown() -{ - for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); iter++) - iter->second.Destroy(); - vshaders.clear(); -} - void VertexShaderManager::Shutdown() { } -VERTEXSHADER* VertexShaderCache::GetShader(u32 components) -{ - DVSTARTPROFILE(); - VERTEXSHADERUID uid; - u32 zbufrender = (bpmem.ztex2.op == ZTEXTURE_ADD) || Renderer::GetZBufferTarget() != 0; - GetVertexShaderId(uid, components, zbufrender); - - VSCache::iterator iter = vshaders.find(uid); - - if (iter != vshaders.end()) { - iter->second.frameCount = frameCount; - VSCacheEntry &entry = iter->second; - if (&entry.shader != pShaderLast) { - pShaderLast = &entry.shader; - } - return pShaderLast; - } - - VSCacheEntry& entry = vshaders[uid]; - const char *code = GenerateVertexShader(components, Renderer::GetZBufferTarget() != 0); - -#if defined(_DEBUG) || defined(DEBUGFAST) - if (g_Config.iLog & CONF_SAVESHADERS && code) { - static int counter = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%s/vs_%04i.txt", g_Config.texDumpPath, counter++); - - SaveData(szTemp, code); - } -#endif - - if (!code || !VertexShaderCache::CompileVertexShader(entry.shader, code)) { - ERROR_LOG("failed to create vertex shader\n"); - return NULL; - } - - //Make an entry in the table - entry.frameCount = frameCount; - pShaderLast = &entry.shader; - INCSTAT(stats.numVertexShadersCreated); - SETSTAT(stats.numVertexShadersAlive, vshaders.size()); - return pShaderLast; -} - -void VertexShaderCache::Cleanup() -{ - VSCache::iterator iter = vshaders.begin(); - while (iter != vshaders.end()) { - VSCacheEntry &entry = iter->second; - if (entry.frameCount < frameCount - 200) { - entry.Destroy(); -#ifdef _WIN32 - iter = vshaders.erase(iter); -#else - vshaders.erase(iter++); -#endif - } - else { - ++iter; - } - } - - SETSTAT(stats.numVertexShadersAlive, vshaders.size()); -} - -bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram) -{ - char stropt[64]; - sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions); - const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; - CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts); - if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { - ERROR_LOG("Failed to load vs %s:\n", cgGetLastListing(g_cgcontext)); - ERROR_LOG(pstrprogram); - return false; - } - - //ERROR_LOG(pstrprogram); - //ERROR_LOG("id: %d\n", g_Config.iSaveTargetId); - - char* pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); - char* plocal = strstr(pcompiledprog, "program.local"); - - while (plocal != NULL) { - const char* penv = " program.env"; - memcpy(plocal, penv, 13); - plocal = strstr(plocal+13, "program.local"); - } - - glGenProgramsARB(1, &vs.glprogid); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vs.glprogid); - glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); - - GLenum err = GL_NO_ERROR; - GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) { - ERROR_LOG(pstrprogram); - ERROR_LOG(pcompiledprog); - } - - cgDestroyProgram(tempprog); - // printf("Compiled vertex shader %i\n", vs.glprogid); - -#if defined(_DEBUG) || defined(DEBUGFAST) - vs.strprog = pstrprogram; -#endif - - return true; -} - // ======================================================================================= // Syncs the shader constant buffers with xfmem // ---------------- @@ -416,6 +273,7 @@ void VertexShaderManager::SetConstants() if (bProjectionChanged) { bProjectionChanged = false; + static float GC_ALIGNED16(g_fProjectionMatrix[16]); if (xfregs.rawProjection[6] == 0) { g_fProjectionMatrix[0] = xfregs.rawProjection[0]; @@ -616,234 +474,38 @@ void VertexShaderManager::SetProjection(float* _pProjection, int constantIndex) bProjectionChanged = true; } -float* VertexShaderManager::GetPosNormalMat() +void VertexShaderManager::SetMaterialColor(int index, u32 data) { - return (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4; -} - - -// LoadXFReg 0x10 -void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData) -{ - u32 address = baseAddress; - for (int i = 0; i < (int)transferSize; i++) - { - address = baseAddress + i; - - // Setup a Matrix - if (address < 0x1000) - { - VertexManager::Flush(); - VertexShaderManager::InvalidateXFRange(address, address + transferSize); - //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize); - - u32* p1 = &xfmem[address]; - memcpy_gc(p1, &pData[i], transferSize*4); - i += transferSize; - } - else if (address<0x2000) - { - u32 data = pData[i]; - switch (address) - { - case 0x1000: // error - break; - case 0x1001: // diagnostics - break; - case 0x1002: // internal state 0 - break; - case 0x1003: // internal state 1 - break; - case 0x1004: // xf_clock - break; - case 0x1005: // clipdisable - if (data & 1) { // disable clipping detection - } - if (data & 2) { // disable trivial rejection - } - if (data & 4) { // disable cpoly clipping acceleration - } - break; - case 0x1006: //SetGPMetric - break; - case 0x1008: //__GXXfVtxSpecs, wrote 0004 - xfregs.hostinfo = *(INVTXSPEC*)&data; - break; - case 0x1009: //GXSetNumChans (no) - if ((u32)xfregs.nNumChans != (data&3)) { - VertexManager::Flush(); - xfregs.nNumChans = data&3; - } - break; - case 0x100a: //GXSetChanAmbientcolor - if (xfregs.colChans[0].ambColor != data) { - VertexManager::Flush(); - nMaterialsChanged |= 1; - xfregs.colChans[0].ambColor = data; - s_fMaterials[0] = ((data>>24)&0xFF)/255.0f; - s_fMaterials[1] = ((data>>16)&0xFF)/255.0f; - s_fMaterials[2] = ((data>>8)&0xFF)/255.0f; - s_fMaterials[3] = ((data)&0xFF)/255.0f; - } - break; - case 0x100b: //GXSetChanAmbientcolor - if (xfregs.colChans[1].ambColor != data) { - VertexManager::Flush(); - nMaterialsChanged |= 2; - xfregs.colChans[1].ambColor = data; - s_fMaterials[4] = ((data>>24)&0xFF)/255.0f; - s_fMaterials[5] = ((data>>16)&0xFF)/255.0f; - s_fMaterials[6] = ((data>>8)&0xFF)/255.0f; - s_fMaterials[7] = ((data)&0xFF)/255.0f; - } - break; - case 0x100c: //GXSetChanMatcolor (rgba) - if (xfregs.colChans[0].matColor != data) { - VertexManager::Flush(); - nMaterialsChanged |= 4; - xfregs.colChans[0].matColor = data; - s_fMaterials[8] = ((data>>24)&0xFF)/255.0f; - s_fMaterials[9] = ((data>>16)&0xFF)/255.0f; - s_fMaterials[10] = ((data>>8)&0xFF)/255.0f; - s_fMaterials[11] = ((data)&0xFF)/255.0f; - } - break; - case 0x100d: //GXSetChanMatcolor (rgba) - if (xfregs.colChans[1].matColor != data) { - VertexManager::Flush(); - nMaterialsChanged |= 8; - xfregs.colChans[1].matColor = data; - s_fMaterials[12] = ((data>>24)&0xFF)/255.0f; - s_fMaterials[13] = ((data>>16)&0xFF)/255.0f; - s_fMaterials[14] = ((data>>8)&0xFF)/255.0f; - s_fMaterials[15] = ((data)&0xFF)/255.0f; - } - break; - - case 0x100e: // color0 - if (xfregs.colChans[0].color.hex != (data&0x7fff) ) { - VertexManager::Flush(); - xfregs.colChans[0].color.hex = data; - } - break; - case 0x100f: // color1 - if (xfregs.colChans[1].color.hex != (data&0x7fff) ) { - VertexManager::Flush(); - xfregs.colChans[1].color.hex = data; - } - break; - case 0x1010: // alpha0 - if (xfregs.colChans[0].alpha.hex != (data&0x7fff) ) { - VertexManager::Flush(); - xfregs.colChans[0].alpha.hex = data; - } - break; - case 0x1011: // alpha1 - if (xfregs.colChans[1].alpha.hex != (data&0x7fff) ) { - VertexManager::Flush(); - xfregs.colChans[1].alpha.hex = data; - } - break; - case 0x1012: // dual tex transform - if (xfregs.bEnableDualTexTransform != (data & 1)) { - VertexManager::Flush(); - xfregs.bEnableDualTexTransform = data & 1; - } - break; - - case 0x1013: - case 0x1014: - case 0x1015: - case 0x1016: - case 0x1017: - DEBUG_LOG("xf addr: %x=%x\n", address, data); - break; - case 0x1018: - //_assert_msg_(GX_XF, 0, "XF matrixindex0"); - VertexShaderManager::SetTexMatrixChangedA(data); //? - break; - case 0x1019: - //_assert_msg_(GX_XF, 0, "XF matrixindex1"); - VertexShaderManager::SetTexMatrixChangedB(data); //? - break; - - case 0x101a: - VertexManager::Flush(); - VertexShaderManager::SetViewport((float*)&pData[i]); - i += 6; - break; - - case 0x101c: // paper mario writes 16777216.0f, 1677721.75 - break; - case 0x101f: // paper mario writes 16777216.0f, 5033165.0f - break; - - case 0x1020: - VertexManager::Flush(); - VertexShaderManager::SetProjection((float*)&pData[i]); - i += 7; - return; - - case 0x103f: // GXSetNumTexGens - if ((u32)xfregs.numTexGens != data) { - VertexManager::Flush(); - xfregs.numTexGens = data; - } - break; - - case 0x1040: xfregs.texcoords[0].texmtxinfo.hex = data; break; - case 0x1041: xfregs.texcoords[1].texmtxinfo.hex = data; break; - case 0x1042: xfregs.texcoords[2].texmtxinfo.hex = data; break; - case 0x1043: xfregs.texcoords[3].texmtxinfo.hex = data; break; - case 0x1044: xfregs.texcoords[4].texmtxinfo.hex = data; break; - case 0x1045: xfregs.texcoords[5].texmtxinfo.hex = data; break; - case 0x1046: xfregs.texcoords[6].texmtxinfo.hex = data; break; - case 0x1047: xfregs.texcoords[7].texmtxinfo.hex = data; break; - - case 0x1048: - case 0x1049: - case 0x104a: - case 0x104b: - case 0x104c: - case 0x104d: - case 0x104e: - case 0x104f: - DEBUG_LOG("xf addr: %x=%x\n", address, data); - break; - case 0x1050: xfregs.texcoords[0].postmtxinfo.hex = data; break; - case 0x1051: xfregs.texcoords[1].postmtxinfo.hex = data; break; - case 0x1052: xfregs.texcoords[2].postmtxinfo.hex = data; break; - case 0x1053: xfregs.texcoords[3].postmtxinfo.hex = data; break; - case 0x1054: xfregs.texcoords[4].postmtxinfo.hex = data; break; - case 0x1055: xfregs.texcoords[5].postmtxinfo.hex = data; break; - case 0x1056: xfregs.texcoords[6].postmtxinfo.hex = data; break; - case 0x1057: xfregs.texcoords[7].postmtxinfo.hex = data; break; - - default: - DEBUG_LOG("xf addr: %x=%x\n", address, data); - break; - } - } - else if (address >= 0x4000) - { - // MessageBox(NULL, "1", "1", MB_OK); - //4010 __GXSetGenMode - } - } -} - -// TODO - verify that it is correct. Seems to work, though. -void LoadIndexedXF(u32 val, int array) -{ - int index = val >> 16; - int address = val & 0xFFF; //check mask - int size = ((val >> 12) & 0xF) + 1; - //load stuff from array to address in xf mem - - VertexManager::Flush(); - VertexShaderManager::InvalidateXFRange(address, address+size); - //PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address+size); - - for (int i = 0; i < size; i++) - xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array]*index + i*4); -} + // TODO: collapse + switch (index) + { + case 0: + nMaterialsChanged |= 1; + s_fMaterials[0] = ((data>>24)&0xFF)/255.0f; + s_fMaterials[1] = ((data>>16)&0xFF)/255.0f; + s_fMaterials[2] = ((data>>8)&0xFF)/255.0f; + s_fMaterials[3] = ((data)&0xFF)/255.0f; + break; + case 1: + nMaterialsChanged |= 2; + s_fMaterials[4] = ((data>>24)&0xFF)/255.0f; + s_fMaterials[5] = ((data>>16)&0xFF)/255.0f; + s_fMaterials[6] = ((data>>8)&0xFF)/255.0f; + s_fMaterials[7] = ((data)&0xFF)/255.0f; + break; + case 2: + nMaterialsChanged |= 4; + s_fMaterials[8] = ((data>>24)&0xFF)/255.0f; + s_fMaterials[9] = ((data>>16)&0xFF)/255.0f; + s_fMaterials[10] = ((data>>8)&0xFF)/255.0f; + s_fMaterials[11] = ((data)&0xFF)/255.0f; + break; + case 3: + nMaterialsChanged |= 8; + s_fMaterials[12] = ((data>>24)&0xFF)/255.0f; + s_fMaterials[13] = ((data>>16)&0xFF)/255.0f; + s_fMaterials[14] = ((data>>8)&0xFF)/255.0f; + s_fMaterials[15] = ((data)&0xFF)/255.0f; + break; + } +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.h index bad21a6e74..30275d2641 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderManager.h @@ -18,49 +18,8 @@ #ifndef _VERTEXSHADERMANAGER_H #define _VERTEXSHADERMANAGER_H -#include -#include - -#include "GLUtil.h" #include "VertexShader.h" -struct VERTEXSHADER -{ - VERTEXSHADER() : glprogid(0) {} - GLuint glprogid; // opengl program id - -#if defined(_DEBUG) || defined(DEBUGFAST) - std::string strprog; -#endif -}; - -class VertexShaderCache -{ - struct VSCacheEntry - { - VERTEXSHADER shader; - int frameCount; - VSCacheEntry() : frameCount(0) {} - void Destroy() { - // printf("Destroying vs %i\n", shader.glprogid); - glDeleteProgramsARB(1, &shader.glprogid); - shader.glprogid = 0; - } - }; - - typedef std::map VSCache; - - static VSCache vshaders; - -public: - static void Init(); - static void Cleanup(); - static void Shutdown(); - - static VERTEXSHADER* GetShader(u32 components); - static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram); -}; - // The non-API dependent parts. class VertexShaderManager { @@ -77,8 +36,10 @@ public: static void InvalidateXFRange(int start, int end); static void SetTexMatrixChangedA(u32 Value); static void SetTexMatrixChangedB(u32 Value); - - static float* GetPosNormalMat(); + static void SetMaterialColor(int index, u32 data); }; +void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4); +void SetVSConstant4fv(int const_number, const float *f); + #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index d61571f947..777a1f1a9b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -38,7 +38,9 @@ #include "VertexLoader.h" #include "VertexLoaderManager.h" #include "VertexManager.h" +#include "PixelShaderCache.h" #include "PixelShaderManager.h" +#include "VertexShaderCache.h" #include "VertexShaderManager.h" #include "XFB.h" #include "XFBConvert.h"