diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 37e65e2c88..b972581aa8 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -51,6 +51,7 @@ PIXELSHADERUID PixelShaderCache::last_uid; void(*pSetPSConstant4f)(unsigned int, float, float, float, float); void(*pSetPSConstant4fv)(unsigned int, const float*); void(*pSetMultiPSConstant4fv)(unsigned int, unsigned int, const float*); +bool (*pCompilePixelShader)(FRAGMENTSHADER&, const char*); GLuint PixelShaderCache::GetDepthMatrixProgram() { @@ -77,12 +78,14 @@ void PixelShaderCache::Init() pSetPSConstant4f = SetGLSLPSConstant4f; pSetPSConstant4fv = SetGLSLPSConstant4fv; pSetMultiPSConstant4fv = SetMultiGLSLPSConstant4fv; + pCompilePixelShader = CompileGLSLPixelShader; } else { pSetPSConstant4f = SetCGPSConstant4f; pSetPSConstant4fv = SetCGPSConstant4fv; pSetMultiPSConstant4fv = SetMultiCGPSConstant4fv; + pCompilePixelShader = CompileCGPixelShader; } glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions); @@ -262,86 +265,7 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram) { - GLenum err = GL_REPORT_ERROR(); - if (err != GL_NO_ERROR) - { - ERROR_LOG(VIDEO, "glError %08x before PS!", err); - } - -#if defined HAVE_CG && HAVE_CG - char stropt[128]; - sprintf(stropt, "MaxLocalParams=224,NumInstructionSlots=%d", s_nMaxPixelInstructions); - const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; - CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts); - - // handle errors - if (!cgIsProgram(tempprog)) - { - cgDestroyProgram(tempprog); - - static int num_failures = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%sbad_ps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); - file << pstrprogram; - file.close(); - - PanicAlert("Failed to compile pixel shader!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%d):\n%s", - szTemp, - g_cgfProf, - cgGetLastListing(g_cgcontext)); - - return false; - } - - // handle warnings - if (cgGetError() != CG_NO_ERROR) - { - WARN_LOG(VIDEO, "Warnings on compile ps %s:", cgGetLastListing(g_cgcontext)); - WARN_LOG(VIDEO, "%s", pstrprogram); - } - - // This looks evil - we modify the program through the const char * we got from cgGetProgramString! - // It SHOULD not have any nasty side effects though - but you never know... - 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, &ps.glprogid); - SetCurrentShader(ps.glprogid); - glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); - - err = GL_REPORT_ERROR(); - if (err != GL_NO_ERROR) - { - GLint error_pos, native_limit; - glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos); - glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native_limit); - // Error occur - if (error_pos != -1) { - const char *program_error = (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB); - char line[256]; - strncpy(line, (const char *)pcompiledprog + error_pos, 255); - line[255] = 0; - ERROR_LOG(VIDEO, "Error at %i: %s", error_pos, program_error); - ERROR_LOG(VIDEO, "Line dump: \n%s", line); - } else if (native_limit != -1) { - ERROR_LOG(VIDEO, "Hit limit? %i", native_limit); - // TODO - } - ERROR_LOG(VIDEO, "%s", pstrprogram); - ERROR_LOG(VIDEO, "%s", pcompiledprog); - } - - cgDestroyProgram(tempprog); -#endif - - return true; + return pCompilePixelShader(ps, pstrprogram); } //Disable Fragment programs and reset the selected Program @@ -370,6 +294,10 @@ void PixelShaderCache::SetCurrentShader(GLuint Shader) } } // GLSL Specific +bool CompileGLSLPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram) +{ + return false; +} void PixelShaderCache::SetPSSampler(const char * name, unsigned int Tex) { PROGRAMSHADER tmp = ProgramShaderCache::GetShaderProgram(); @@ -440,6 +368,87 @@ void SetMultiGLSLPSConstant4fv(unsigned int const_number, unsigned int count, co } } // CG Specific + +bool CompileCGPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram) +{ + GLenum err = GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) + { + ERROR_LOG(VIDEO, "glError %08x before PS!", err); + } + +#if defined HAVE_CG && HAVE_CG + CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", NULL); + + // handle errors + if (!cgIsProgram(tempprog)) + { + cgDestroyProgram(tempprog); + + static int num_failures = 0; + char szTemp[MAX_PATH]; + sprintf(szTemp, "bad_ps_%04i.txt", num_failures++); + std::ofstream file(szTemp); + file << pstrprogram; + file.close(); + + PanicAlert("Failed to compile pixel shader %d!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%d):\n%s", + num_failures - 1, szTemp, + g_cgfProf, + cgGetLastListing(g_cgcontext)); + + return false; + } + + // handle warnings + if (cgGetError() != CG_NO_ERROR) + { + WARN_LOG(VIDEO, "Warnings on compile ps %s:", cgGetLastListing(g_cgcontext)); + WARN_LOG(VIDEO, "%s", pstrprogram); + } + + // This looks evil - we modify the program through the const char * we got from cgGetProgramString! + // It SHOULD not have any nasty side effects though - but you never know... + 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, &ps.glprogid); + PixelShaderCache::SetCurrentShader(ps.glprogid); + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); + + err = GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) + { + GLint error_pos, native_limit; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos); + glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native_limit); + // Error occur + if (error_pos != -1) { + const char *program_error = (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB); + char line[256]; + strncpy(line, (const char *)pcompiledprog + error_pos, 255); + line[255] = 0; + ERROR_LOG(VIDEO, "Error at %i: %s", error_pos, program_error); + ERROR_LOG(VIDEO, "Line dump: \n%s", line); + } else if (native_limit != -1) { + ERROR_LOG(VIDEO, "Hit limit? %i", native_limit); + // TODO + } + ERROR_LOG(VIDEO, "%s", pstrprogram); + ERROR_LOG(VIDEO, "%s", pcompiledprog); + } + + cgDestroyProgram(tempprog); +#endif + + return true; +} void SetCGPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { float f[4] = { f1, f2, f3, f4 }; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h index 9d61d7229a..429af249f1 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h @@ -91,11 +91,13 @@ public: void SetGLSLPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4); void SetGLSLPSConstant4fv(unsigned int const_number, const float *f); void SetMultiGLSLPSConstant4fv(unsigned int const_number, unsigned int count, const float *f); +bool CompileGLSLPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram); //CG Specific void SetCGPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4); void SetCGPSConstant4fv(unsigned int const_number, const float *f); void SetMultiCGPSConstant4fv(unsigned int const_number, unsigned int count, const float *f); +bool CompileCGPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram); } // namespace OGL #endif // _PIXELSHADERCACHE_H_ diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index 82db873e85..eb4f56522e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -50,6 +50,7 @@ void (*pSetVSConstant4f)(unsigned int, float, float, float, float); void (*pSetVSConstant4fv)(unsigned int, const float*); void (*pSetMultiVSConstant4fv)(unsigned int, unsigned int, const float*); void (*pSetMultiVSConstant3fv)(unsigned int, unsigned int, const float*); +bool (*pCompileVertexShader)(VERTEXSHADER&, const char*); void VertexShaderCache::Init() { @@ -64,6 +65,7 @@ void VertexShaderCache::Init() pSetVSConstant4fv = SetGLSLVSConstant4fv; pSetMultiVSConstant4fv = SetMultiGLSLVSConstant4fv; pSetMultiVSConstant3fv = SetMultiGLSLVSConstant3fv; + pCompileVertexShader = CompileGLSLVertexShader; } else { @@ -71,6 +73,7 @@ void VertexShaderCache::Init() pSetVSConstant4fv = SetCGVSConstant4fv; pSetMultiVSConstant4fv = SetMultiCGVSConstant4fv; pSetMultiVSConstant3fv = SetMultiCGVSConstant3fv; + pCompileVertexShader = CompileGLSLVertexShader; } glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions); @@ -147,66 +150,7 @@ VERTEXSHADER* VertexShaderCache::SetShader(u32 components) bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram) { - // Reset GL error before compiling shaders. Yeah, we need to investigate the causes of these. - GLenum err = GL_REPORT_ERROR(); - if (err != GL_NO_ERROR) - { - ERROR_LOG(VIDEO, "glError %08x before VS!", err); - } - -#if defined HAVE_CG && HAVE_CG - CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", NULL); - if (!cgIsProgram(tempprog)) { - static int num_failures = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "bad_vs_%04i.txt", num_failures++); - std::ofstream file(szTemp); - file << pstrprogram; - file.close(); - - PanicAlert("Failed to compile vertex shader %d!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%d):\n%s", - num_failures - 1, szTemp, - g_cgfProf, - cgGetLastListing(g_cgcontext)); - - cgDestroyProgram(tempprog); - ERROR_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext)); - ERROR_LOG(VIDEO, "%s", pstrprogram); - return false; - } - - if (cgGetError() != CG_NO_ERROR) - { - WARN_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext)); - WARN_LOG(VIDEO, "%s", pstrprogram); - } - - // This looks evil - we modify the program through the const char * we got from cgGetProgramString! - // It SHOULD not have any nasty side effects though - but you never know... - 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); - SetCurrentShader(vs.glprogid); - - glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); - err = GL_REPORT_ERROR(); - if (err != GL_NO_ERROR) { - ERROR_LOG(VIDEO, "%s", pstrprogram); - ERROR_LOG(VIDEO, "%s", pcompiledprog); - } - - cgDestroyProgram(tempprog); -#endif - - if (g_ActiveConfig.bEnableShaderDebugging) - vs.strprog = pstrprogram; - - return true; + return pCompileVertexShader(vs, pstrprogram); } void VertexShaderCache::DisableShader() @@ -234,6 +178,10 @@ void VertexShaderCache::SetCurrentShader(GLuint Shader) } } // GLSL Specific +bool CompileGLSLVertexShader(VERTEXSHADER& vs, const char* pstrprogram) +{ + return false; +} void SetVSConstant4fvByName(const char * name, unsigned int offset, const float *f, const unsigned int count = 1) { PROGRAMSHADER tmp = ProgramShaderCache::GetShaderProgram(); @@ -315,6 +263,69 @@ void SetMultiGLSLVSConstant3fv(unsigned int const_number, unsigned int count, co } // CG Specific +bool CompileCGVertexShader(VERTEXSHADER& vs, const char* pstrprogram) +{ + // Reset GL error before compiling shaders. Yeah, we need to investigate the causes of these. + GLenum err = GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) + { + ERROR_LOG(VIDEO, "glError %08x before VS!", err); + } + +#if defined HAVE_CG && HAVE_CG + CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", NULL); + if (!cgIsProgram(tempprog)) { + static int num_failures = 0; + char szTemp[MAX_PATH]; + sprintf(szTemp, "bad_vs_%04i.txt", num_failures++); + std::ofstream file(szTemp); + file << pstrprogram; + file.close(); + + PanicAlert("Failed to compile vertex shader %d!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%d):\n%s", + num_failures - 1, szTemp, + g_cgfProf, + cgGetLastListing(g_cgcontext)); + + cgDestroyProgram(tempprog); + ERROR_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext)); + ERROR_LOG(VIDEO, "%s", pstrprogram); + return false; + } + + if (cgGetError() != CG_NO_ERROR) + { + WARN_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext)); + WARN_LOG(VIDEO, "%s", pstrprogram); + } + + // This looks evil - we modify the program through the const char * we got from cgGetProgramString! + // It SHOULD not have any nasty side effects though - but you never know... + 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); + VertexShaderCache::SetCurrentShader(vs.glprogid); + + glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); + err = GL_REPORT_ERROR(); + if (err != GL_NO_ERROR) { + ERROR_LOG(VIDEO, "%s", pstrprogram); + ERROR_LOG(VIDEO, "%s", pcompiledprog); + } + + cgDestroyProgram(tempprog); +#endif + + if (g_ActiveConfig.bEnableShaderDebugging) + vs.strprog = pstrprogram; + + return true; +} void SetCGVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, const_number, f1, f2, f3, f4); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h index e398a801ff..fc08cc4efd 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h @@ -75,12 +75,14 @@ void SetGLSLVSConstant4f(unsigned int const_number, float f1, float f2, float f3 void SetGLSLVSConstant4fv(unsigned int const_number, const float *f); void SetMultiGLSLVSConstant4fv(unsigned int const_number, unsigned int count, const float *f); void SetMultiGLSLVSConstant3fv(unsigned int const_number, unsigned int count, const float *f); +bool CompileGLSLVertexShader(VERTEXSHADER& vs, const char* pstrprogram); // CG Specific void SetCGVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4); void SetCGVSConstant4fv(unsigned int const_number, const float *f); void SetMultiCGVSConstant4fv(unsigned int const_number, unsigned int count, const float *f); void SetMultiCGVSConstant3fv(unsigned int const_number, unsigned int count, const float *f); +bool CompileCGVertexShader(VERTEXSHADER& vs, const char* pstrprogram); } // namespace OGL #endif // _VERTEXSHADERCACHE_H_