From 3306bcdc8960273dcc9fecb27e5fc64e17d760bf Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 21 Apr 2008 23:35:49 -0400 Subject: [PATCH] Push parsed shaders through GLSL compiler to see what breaks. Multithreading is a real pain. --HG-- branch : trunk --- CMakeLists.txt | 15 +++++- finderrors.c | 135 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a083dd12..953196a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,9 +8,22 @@ ENDIF(CMAKE_COMPILER_IS_GNUCC) # testparse uses this when I'm looking at memory usage patterns. #ADD_DEFINITIONS(-DMOJOSHADER_DEBUG_MALLOC=1) +FIND_PACKAGE(SDL) +IF(SDL_FOUND) + INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR}) + ADD_DEFINITIONS(-DFINDERRORS_COMPILE_SHADERS=1) + IF(APPLE) + ADD_DEFINITIONS(-I/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers) + FIND_LIBRARY(OPENGL_LIBRARY OpenGL) + MARK_AS_ADVANCED(OPENGL_LIBRARY) + SET(EXTRA_LIBS ${OPENGL_LIBRARY}) + + ENDIF(APPLE) +ENDIF(SDL_FOUND) + ADD_EXECUTABLE(testparse testparse.c mojoshader.c) ADD_EXECUTABLE(finderrors finderrors.c mojoshader.c) -TARGET_LINK_LIBRARIES(finderrors pthread) +TARGET_LINK_LIBRARIES(finderrors pthread ${SDL_LIBRARY} ${EXTRA_LIBS}) # End of CMakeLists.txt ... diff --git a/finderrors.c b/finderrors.c index 82ade499..fe53f2ae 100644 --- a/finderrors.c +++ b/finderrors.c @@ -6,9 +6,18 @@ #include #include #include +#include #include "mojoshader.h" +#define FINDERRORS_COMPILE_SHADERS 1 + +#if FINDERRORS_COMPILE_SHADERS +#include "SDL.h" +#include +#include +#endif + static const char *profile = NULL; static volatile int die_threads = 0; static pthread_mutex_t grab_mutex; @@ -16,11 +25,13 @@ static pthread_mutex_t report_mutex; typedef struct ShaderBytecode { - char *name; + void *name; + void *data; struct ShaderBytecode *next; } ShaderBytecode; static volatile ShaderBytecode *gbytecode = NULL; +static volatile ShaderBytecode *gparsed = NULL; static void report(const char *fmt, ...) { @@ -32,6 +43,53 @@ static void report(const char *fmt, ...) va_end(ap); } // report + +static int compile_shader(const char *fname, const MOJOSHADER_parseData *pd) +{ + int retval = 1; + + #if FINDERRORS_COMPILE_SHADERS + const GLenum shader_type = (pd->shader_type == MOJOSHADER_TYPE_PIXEL) ? GL_FRAGMENT_SHADER_ARB : GL_VERTEX_SHADER_ARB; + GLint shaderlen = (GLint) pd->output_len; + GLhandleARB program = glCreateProgramObjectARB(); + GLhandleARB shader = glCreateShaderObjectARB(shader_type); + GLint ok = 0; + GLcharARB err[1024]; + GLsizei len = 0; + + retval = 0; + + glShaderSourceARB(shader, 1, (const GLcharARB **) &pd->output, &shaderlen); + glCompileShaderARB(shader); + glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &ok); + if (!ok) + { + glGetInfoLogARB(shader, sizeof (err), &len, err); + printf("FAIL: %s glsl compile: %s\n", fname, err); + } // if + else + { + glAttachObjectARB(program, shader); + glLinkProgramARB(program); + glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &ok); + if (!ok) + { + glGetInfoLogARB(program, sizeof (err), &len, err); + printf("FAIL: %s glsl link: %s\n", fname, err); + } // if + else + { + retval = 1; + } // else + } // else + glDeleteObjectARB(shader); + glDeleteObjectARB(program); + #endif + + return retval; +} // compile_shader + + static void *worker(void *unused) { unsigned char buf[1024 * 256]; @@ -51,7 +109,7 @@ static void *worker(void *unused) if (my_bytecode == NULL) break; - const char *fname = my_bytecode->name; + const char *fname = (const char *) my_bytecode->name; FILE *io = fopen(fname, "rb"); if (io == NULL) report("FAIL: %s fopen() failed.\n", fname); @@ -62,19 +120,13 @@ static void *worker(void *unused) if (rc == -1) report("FAIL: %s %s\n", fname, strerror(errno)); else - { - const MOJOSHADER_parseData *pd; - pd = MOJOSHADER_parse(profile, buf, rc, 0, 0, 0); - if (pd->error != NULL) - report("FAIL: %s %s\n", fname, pd->error); - else - report("PASS: %s\n", fname); - MOJOSHADER_freeParseData(pd); - } // else - } // else + my_bytecode->data = (void *) MOJOSHADER_parse(profile, buf, rc, 0, 0, 0); - free(my_bytecode->name); - free(my_bytecode); + pthread_mutex_lock(&grab_mutex); + my_bytecode->next = (ShaderBytecode *) gparsed; + gparsed = my_bytecode; + pthread_mutex_unlock(&grab_mutex); + } // else } // while return NULL; @@ -97,8 +149,9 @@ static int do_dir(const char *dname) total++; bytecode = (ShaderBytecode *) malloc(sizeof (ShaderBytecode)); - bytecode->name = (char *) malloc(strlen(dent->d_name) + dirlen); - sprintf(bytecode->name, "%s/%s", dname, dent->d_name); + bytecode->data = NULL; + bytecode->name = malloc(strlen(dent->d_name) + dirlen); + sprintf((char *) bytecode->name, "%s/%s", dname, dent->d_name); bytecode->next = (ShaderBytecode *) gbytecode; gbytecode = bytecode; } // while @@ -124,6 +177,11 @@ int main(int argc, char **argv) pthread_t workers[MAX_WORKERS]; int total = 0; + #if FINDERRORS_COMPILE_SHADERS + SDL_Init(SDL_INIT_VIDEO); + SDL_SetVideoMode(640, 480, 0, SDL_OPENGL); + #endif + pthread_mutex_init(&grab_mutex, NULL); pthread_mutex_init(&report_mutex, NULL); @@ -138,11 +196,56 @@ int main(int argc, char **argv) for (i = 0; i < MAX_WORKERS; i++) pthread_create(&workers[i], NULL, worker, NULL); + while (1) + { + ShaderBytecode *my_bytecode = NULL; + pthread_mutex_lock(&grab_mutex); + if (gparsed != NULL) + { + my_bytecode = (ShaderBytecode *) gparsed; + gparsed = gparsed->next; + } // if + pthread_mutex_unlock(&grab_mutex); + + if (my_bytecode == NULL) + { + if (gbytecode == NULL) + break; + else + { + usleep(10000); + continue; + } // else + } // if + + const MOJOSHADER_parseData *pd = (const MOJOSHADER_parseData *) + my_bytecode->data; + const char *fname = my_bytecode->name; + if (pd != NULL) + { + if (pd->error != NULL) + report("FAIL: %s %s\n", fname, pd->error); + else + { + if (compile_shader(fname, pd)) + report("PASS: %s\n", fname); + } // else + MOJOSHADER_freeParseData(pd); + } // if + + free(my_bytecode->name); + free(my_bytecode); + } // while + for (i = 0; i < MAX_WORKERS; i++) pthread_join(workers[i], NULL); pthread_mutex_destroy(&report_mutex); pthread_mutex_destroy(&grab_mutex); + + #if FINDERRORS_COMPILE_SHADERS + SDL_Quit(); + #endif } // else return 0;