This commit is contained in:
Ryan Houdek 2011-12-02 18:26:15 -06:00
parent f8eb45637f
commit 49b6e4beed
4 changed files with 164 additions and 137 deletions

View File

@ -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,83 +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
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);
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
@ -367,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();
@ -437,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 };

View File

@ -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_

View File

@ -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);

View File

@ -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_