diff options
-rw-r--r-- | source/blender/blenkernel/BKE_global.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader.c | 61 | ||||
-rw-r--r-- | source/creator/creator_args.c | 3 |
3 files changed, 66 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index ce8de456697..45a0a765ce1 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -143,10 +143,11 @@ enum { G_DEBUG_GPU_MEM = (1 << 15), /* gpu memory in status bar */ G_DEBUG_GPU = (1 << 16), /* gpu debug */ G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...)*/ + G_DEBUG_GPU_SHADERS = (1 << 18), /* GLSL shaders */ }; #define G_DEBUG_ALL (G_DEBUG | G_DEBUG_FFMPEG | G_DEBUG_PYTHON | G_DEBUG_EVENTS | G_DEBUG_WM | G_DEBUG_JOBS | \ - G_DEBUG_FREESTYLE | G_DEBUG_DEPSGRAPH | G_DEBUG_GPU_MEM | G_DEBUG_IO) + G_DEBUG_FREESTYLE | G_DEBUG_DEPSGRAPH | G_DEBUG_GPU_MEM | G_DEBUG_IO | G_DEBUG_GPU_SHADERS) /* G.fileflags */ diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index b579f87698c..d43b2f257e8 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -30,7 +30,9 @@ #include "BLI_utildefines.h" #include "BLI_math_base.h" #include "BLI_math_vector.h" +#include "BLI_path_util.h" +#include "BKE_appdir.h" #include "BKE_global.h" #include "GPU_compositing.h" @@ -259,6 +261,53 @@ GPUShader *GPU_shader_create(const char *vertexcode, GPU_SHADER_FLAGS_NONE); } +#define DEBUG_SHADER_NONE "" +#define DEBUG_SHADER_VERTEX "vert" +#define DEBUG_SHADER_FRAGMENT "frag" +#define DEBUG_SHADER_GEOMETRY "geom" + +/** + * Dump GLSL shaders to disk + * + * This is used for profiling shader performance externally and debug if shader code is correct. + * If called with no code, it simply bumps the shader index, so different shaders for the same + * program share the same index. + */ +static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension) +{ + if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) { + return; + } + + /* We use the same shader index for shaders in the same program. + * So we call this function once before calling for the invidual shaders. */ + static int shader_index = 0; + if (code == NULL) { + shader_index++; + BLI_assert(STREQ(DEBUG_SHADER_NONE, extension)); + return; + } + + /* Determine the full path of the new shader. */ + char shader_path[FILE_MAX]; + + char file_name[512] = {'\0'}; + sprintf(file_name, "%04d.%s", shader_index, extension); + + BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name); + + /* Write shader to disk. */ + FILE *f = fopen(shader_path, "w"); + if (f == NULL) { + printf("Error writing to file: %s\n", shader_path); + } + for (int j = 0; j < num_shaders; j++) { + fprintf(f, "%s", code[j]); + } + fclose(f); + printf("Shader file written to disk: %s\n", shader_path); +} + GPUShader *GPU_shader_create_ex(const char *vertexcode, const char *fragcode, const char *geocode, @@ -290,6 +339,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, return NULL; shader = MEM_callocN(sizeof(GPUShader), "GPUShader"); + gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE); if (vertexcode) shader->vertex = glCreateShader(GL_VERTEX_SHADER); @@ -327,6 +377,8 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, if (defines) source[num_source++] = defines; source[num_source++] = vertexcode; + gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX); + glAttachShader(shader->program, shader->vertex); glShaderSource(shader->vertex, num_source, source, NULL); @@ -366,6 +418,8 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, if (libcode) source[num_source++] = libcode; source[num_source++] = fragcode; + gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT); + glAttachShader(shader->program, shader->fragment); glShaderSource(shader->fragment, num_source, source, NULL); @@ -392,6 +446,8 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, if (defines) source[num_source++] = defines; source[num_source++] = geocode; + gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY); + glAttachShader(shader->program, shader->geometry); glShaderSource(shader->geometry, num_source, source, NULL); @@ -452,6 +508,11 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, return shader; } +#undef DEBUG_SHADER_GEOMETRY +#undef DEBUG_SHADER_FRAGMENT +#undef DEBUG_SHADER_VERTEX +#undef DEBUG_SHADER_NONE + void GPU_shader_bind(GPUShader *shader) { GPU_ASSERT_NO_GL_ERRORS("Pre Shader Bind"); diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 971c2e84780..4f2185cae96 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -567,6 +567,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo BLI_argsPrintArgDoc(ba, "--debug-depsgraph-no-threads"); BLI_argsPrintArgDoc(ba, "--debug-gpumem"); + BLI_argsPrintArgDoc(ba, "--debug-gpu-shaders"); BLI_argsPrintArgDoc(ba, "--debug-wm"); BLI_argsPrintArgDoc(ba, "--debug-all"); BLI_argsPrintArgDoc(ba, "--debug-io"); @@ -2022,6 +2023,8 @@ void main_args_setup(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) CB_EX(arg_handle_debug_mode_generic_set, depsgraph_pretty), (void *)G_DEBUG_DEPSGRAPH_PRETTY); BLI_argsAdd(ba, 1, NULL, "--debug-gpumem", CB_EX(arg_handle_debug_mode_generic_set, gpumem), (void *)G_DEBUG_GPU_MEM); + BLI_argsAdd(ba, 1, NULL, "--debug-gpu-shaders", + CB_EX(arg_handle_debug_mode_generic_set, gpumem), (void *)G_DEBUG_GPU_SHADERS); BLI_argsAdd(ba, 1, NULL, "--enable-new-depsgraph", CB(arg_handle_depsgraph_use_new), NULL); BLI_argsAdd(ba, 1, NULL, "--enable-new-basic-shader-glsl", CB(arg_handle_basic_shader_glsl_use_new), NULL); |