This commit is contained in:
Ryan Houdek 2011-12-02 18:26:15 -06:00 committed by Sonicadvance1
parent 3943840d5c
commit 34c7b3fd73
4 changed files with 164 additions and 140 deletions

View File

@ -51,6 +51,7 @@ PIXELSHADERUID PixelShaderCache::last_uid;
void(*pSetPSConstant4f)(unsigned int, float, float, float, float); void(*pSetPSConstant4f)(unsigned int, float, float, float, float);
void(*pSetPSConstant4fv)(unsigned int, const float*); void(*pSetPSConstant4fv)(unsigned int, const float*);
void(*pSetMultiPSConstant4fv)(unsigned int, unsigned int, const float*); void(*pSetMultiPSConstant4fv)(unsigned int, unsigned int, const float*);
bool (*pCompilePixelShader)(FRAGMENTSHADER&, const char*);
GLuint PixelShaderCache::GetDepthMatrixProgram() GLuint PixelShaderCache::GetDepthMatrixProgram()
{ {
@ -77,12 +78,14 @@ void PixelShaderCache::Init()
pSetPSConstant4f = SetGLSLPSConstant4f; pSetPSConstant4f = SetGLSLPSConstant4f;
pSetPSConstant4fv = SetGLSLPSConstant4fv; pSetPSConstant4fv = SetGLSLPSConstant4fv;
pSetMultiPSConstant4fv = SetMultiGLSLPSConstant4fv; pSetMultiPSConstant4fv = SetMultiGLSLPSConstant4fv;
pCompilePixelShader = CompileGLSLPixelShader;
} }
else else
{ {
pSetPSConstant4f = SetCGPSConstant4f; pSetPSConstant4f = SetCGPSConstant4f;
pSetPSConstant4fv = SetCGPSConstant4fv; pSetPSConstant4fv = SetCGPSConstant4fv;
pSetMultiPSConstant4fv = SetMultiCGPSConstant4fv; pSetMultiPSConstant4fv = SetMultiCGPSConstant4fv;
pCompilePixelShader = CompileCGPixelShader;
} }
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions); 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) bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
{ {
GLenum err = GL_REPORT_ERROR(); return pCompilePixelShader(ps, pstrprogram);
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;
} }
//Disable Fragment programs and reset the selected Program //Disable Fragment programs and reset the selected Program
@ -370,6 +294,10 @@ void PixelShaderCache::SetCurrentShader(GLuint Shader)
} }
} }
// GLSL Specific // GLSL Specific
bool CompileGLSLPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
{
return false;
}
void PixelShaderCache::SetPSSampler(const char * name, unsigned int Tex) void PixelShaderCache::SetPSSampler(const char * name, unsigned int Tex)
{ {
PROGRAMSHADER tmp = ProgramShaderCache::GetShaderProgram(); PROGRAMSHADER tmp = ProgramShaderCache::GetShaderProgram();
@ -440,6 +368,87 @@ void SetMultiGLSLPSConstant4fv(unsigned int const_number, unsigned int count, co
} }
} }
// CG Specific // 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) void SetCGPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{ {
float f[4] = { f1, f2, f3, 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 SetGLSLPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
void SetGLSLPSConstant4fv(unsigned int const_number, const float *f); void SetGLSLPSConstant4fv(unsigned int const_number, const float *f);
void SetMultiGLSLPSConstant4fv(unsigned int const_number, unsigned int count, const float *f); void SetMultiGLSLPSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
bool CompileGLSLPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
//CG Specific //CG Specific
void SetCGPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4); void SetCGPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
void SetCGPSConstant4fv(unsigned int const_number, const float *f); void SetCGPSConstant4fv(unsigned int const_number, const float *f);
void SetMultiCGPSConstant4fv(unsigned int const_number, unsigned int count, const float *f); void SetMultiCGPSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
bool CompileCGPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
} // namespace OGL } // namespace OGL
#endif // _PIXELSHADERCACHE_H_ #endif // _PIXELSHADERCACHE_H_

View File

@ -50,6 +50,7 @@ void (*pSetVSConstant4f)(unsigned int, float, float, float, float);
void (*pSetVSConstant4fv)(unsigned int, const float*); void (*pSetVSConstant4fv)(unsigned int, const float*);
void (*pSetMultiVSConstant4fv)(unsigned int, unsigned int, const float*); void (*pSetMultiVSConstant4fv)(unsigned int, unsigned int, const float*);
void (*pSetMultiVSConstant3fv)(unsigned int, unsigned int, const float*); void (*pSetMultiVSConstant3fv)(unsigned int, unsigned int, const float*);
bool (*pCompileVertexShader)(VERTEXSHADER&, const char*);
void VertexShaderCache::Init() void VertexShaderCache::Init()
{ {
@ -64,6 +65,7 @@ void VertexShaderCache::Init()
pSetVSConstant4fv = SetGLSLVSConstant4fv; pSetVSConstant4fv = SetGLSLVSConstant4fv;
pSetMultiVSConstant4fv = SetMultiGLSLVSConstant4fv; pSetMultiVSConstant4fv = SetMultiGLSLVSConstant4fv;
pSetMultiVSConstant3fv = SetMultiGLSLVSConstant3fv; pSetMultiVSConstant3fv = SetMultiGLSLVSConstant3fv;
pCompileVertexShader = CompileGLSLVertexShader;
} }
else else
{ {
@ -71,6 +73,7 @@ void VertexShaderCache::Init()
pSetVSConstant4fv = SetCGVSConstant4fv; pSetVSConstant4fv = SetCGVSConstant4fv;
pSetMultiVSConstant4fv = SetMultiCGVSConstant4fv; pSetMultiVSConstant4fv = SetMultiCGVSConstant4fv;
pSetMultiVSConstant3fv = SetMultiCGVSConstant3fv; pSetMultiVSConstant3fv = SetMultiCGVSConstant3fv;
pCompileVertexShader = CompileGLSLVertexShader;
} }
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions); 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) bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram)
{ {
// Reset GL error before compiling shaders. Yeah, we need to investigate the causes of these. return pCompileVertexShader(vs, pstrprogram);
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;
} }
void VertexShaderCache::DisableShader() void VertexShaderCache::DisableShader()
@ -234,6 +178,10 @@ void VertexShaderCache::SetCurrentShader(GLuint Shader)
} }
} }
// GLSL Specific // 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) void SetVSConstant4fvByName(const char * name, unsigned int offset, const float *f, const unsigned int count = 1)
{ {
PROGRAMSHADER tmp = ProgramShaderCache::GetShaderProgram(); PROGRAMSHADER tmp = ProgramShaderCache::GetShaderProgram();
@ -315,6 +263,69 @@ void SetMultiGLSLVSConstant3fv(unsigned int const_number, unsigned int count, co
} }
// CG Specific // 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) 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); 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 SetGLSLVSConstant4fv(unsigned int const_number, const float *f);
void SetMultiGLSLVSConstant4fv(unsigned int const_number, unsigned int count, 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); void SetMultiGLSLVSConstant3fv(unsigned int const_number, unsigned int count, const float *f);
bool CompileGLSLVertexShader(VERTEXSHADER& vs, const char* pstrprogram);
// CG Specific // CG Specific
void SetCGVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4); void SetCGVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
void SetCGVSConstant4fv(unsigned int const_number, const float *f); void SetCGVSConstant4fv(unsigned int const_number, const float *f);
void SetMultiCGVSConstant4fv(unsigned int const_number, unsigned int count, 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); void SetMultiCGVSConstant3fv(unsigned int const_number, unsigned int count, const float *f);
bool CompileCGVertexShader(VERTEXSHADER& vs, const char* pstrprogram);
} // namespace OGL } // namespace OGL
#endif // _VERTEXSHADERCACHE_H_ #endif // _VERTEXSHADERCACHE_H_