Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_global.h3
-rw-r--r--source/blender/gpu/intern/gpu_shader.c63
-rw-r--r--source/creator/creator_args.c3
3 files changed, 68 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 790c8051ace..80a8f750d20 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -128,10 +128,11 @@ enum {
G_DEBUG_DEPSGRAPH_NO_THREADS = (1 << 11), /* single threaded depsgraph */
G_DEBUG_GPU = (1 << 12), /* gpu debug */
G_DEBUG_IO = (1 << 13), /* IO Debugging (for Collada, ...)*/
+ G_DEBUG_GPU_SHADERS = (1 << 14), /* 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 5d5be2ec4ef..7e0848ec071 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -30,9 +30,13 @@
#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 "DNA_space_types.h"
+
#include "GPU_compositing.h"
#include "GPU_extensions.h"
#include "GPU_matrix.h"
@@ -267,6 +271,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,
@@ -288,6 +339,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
+ gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE);
if (vertexcode)
shader->vertex = glCreateShader(GL_VERTEX_SHADER);
@@ -325,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);
@@ -364,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);
@@ -390,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 +510,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)
{
BLI_assert(shader && shader->program);
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index 52a9165bbcb..c38f19397c3 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -548,6 +548,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");
@@ -1805,6 +1806,8 @@ void main_args_setup(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
CB_EX(arg_handle_debug_mode_generic_set, depsgraph_no_threads), (void *)G_DEBUG_DEPSGRAPH_NO_THREADS);
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, "--verbose", CB(arg_handle_verbosity_set), NULL);