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:
authorDalai Felinto <dfelinto@gmail.com>2017-09-27 19:03:00 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-09-27 19:03:00 +0300
commit16edfc516e97042afdc3e35d46ebafcca8cd1bd9 (patch)
tree15075f3904c400971c87fb2a51c3e6abf48ea701 /source/blender/gpu
parent32e453b4956e30c812f5ea60d902f3655da97def (diff)
--debug-gpu-shader: Dump GLSL shaders to disk
This is really convenient for development. Either for profiling the generated shaders or to check if the generated code is correct. It writes the shaders to the temporary blender session folder.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/intern/gpu_shader.c63
1 files changed, 63 insertions, 0 deletions
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);