[Bf-blender-cvs] [e3b3b320768] master: DRW: Use name buffer to request uniform location before drawing.

Clément Foucault noreply at git.blender.org
Thu Jan 17 19:49:26 CET 2019


Commit: e3b3b3207682233978dac5b06aef6748dcc0367c
Author: Clément Foucault
Date:   Thu Jan 17 18:33:08 2019 +0100
Branches: master
https://developer.blender.org/rBe3b3b3207682233978dac5b06aef6748dcc0367c

DRW: Use name buffer to request uniform location before drawing.

This is in order to avoid GL call during the "cache creation" phase and
support multithreading.

===================================================================

M	source/blender/draw/intern/draw_manager.c
M	source/blender/draw/intern/draw_manager.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/intern/draw_manager_exec.c
M	source/blender/gpu/intern/gpu_shader.c

===================================================================

diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 7ba73c28c0c..871c42a6bae 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -103,6 +103,17 @@ extern struct GPUUniformBuffer *view_ubo; /* draw_manager_exec.c */
 static void drw_state_prepare_clean_for_draw(DRWManager *dst)
 {
 	memset(dst, 0x0, offsetof(DRWManager, gl_context));
+
+	/* Maybe not the best place for this. */
+	if (!DST.uniform_names.buffer) {
+		DST.uniform_names.buffer = MEM_callocN(DRW_UNIFORM_BUFFER_NAME, "Name Buffer");
+		DST.uniform_names.buffer_len = DRW_UNIFORM_BUFFER_NAME;
+	}
+	else if (DST.uniform_names.buffer_len > DRW_UNIFORM_BUFFER_NAME) {
+		DST.uniform_names.buffer = MEM_reallocN(DST.uniform_names.buffer, DRW_UNIFORM_BUFFER_NAME);
+		DST.uniform_names.buffer_len = DRW_UNIFORM_BUFFER_NAME;
+	}
+	DST.uniform_names.buffer_ofs = 0;
 }
 
 /* This function is used to reset draw manager to a state
@@ -2616,6 +2627,8 @@ void DRW_engines_free(void)
 	MEM_SAFE_FREE(DST.RST.bound_ubos);
 	MEM_SAFE_FREE(DST.RST.bound_ubo_slots);
 
+	MEM_SAFE_FREE(DST.uniform_names.buffer);
+
 	DRW_opengl_context_disable();
 }
 
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index ce0f961c016..c442921af8f 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -46,6 +46,10 @@
 /* Use draw manager to call GPU_select, see: DRW_draw_select_loop */
 #define USE_GPU_SELECT
 
+#define DRW_DEBUG_USE_UNIFORM_NAME 0
+#define DRW_UNIFORM_BUFFER_NAME 64
+#define DRW_UNIFORM_BUFFER_NAME_INC 1024
+
 /* ------------ Profiling --------------- */
 
 #define USE_PROFILE
@@ -186,8 +190,6 @@ typedef enum {
 	DRW_UNIFORM_BLOCK_PERSIST
 } DRWUniformType;
 
-#define MAX_UNIFORM_NAME 13
-
 struct DRWUniform {
 	DRWUniform *next; /* single-linked list */
 	union {
@@ -197,13 +199,11 @@ struct DRWUniform {
 		float fvalue;
 		int ivalue;
 	};
+	int name_ofs; /* name offset in name buffer. */
 	int location;
 	char type; /* DRWUniformType */
 	char length; /* cannot be more than 16 */
 	char arraysize; /* cannot be more than 16 too */
-#ifndef NDEBUG
-	char name[MAX_UNIFORM_NAME];
-#endif
 };
 
 typedef enum {
@@ -402,6 +402,12 @@ typedef struct DRWManager {
 		DRWDebugLine *lines;
 		DRWDebugSphere *spheres;
 	} debug;
+
+	struct {
+		char *buffer;
+		uint buffer_len;
+		uint buffer_ofs;
+	} uniform_names;
 } DRWManager;
 
 extern DRWManager DST; /* TODO : get rid of this and allow multithreaded rendering */
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 6584b6953d5..0df1603a860 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -134,10 +134,24 @@ static void drw_shgroup_uniform(DRWShadingGroup *shgroup, const char *name,
 
 	drw_shgroup_uniform_create_ex(shgroup, location, type, value, length, arraysize);
 
-#ifndef NDEBUG
-	/* Save uniform name to easily identify it when debugging. */
-	BLI_strncpy(shgroup->uniforms->name, name, MAX_UNIFORM_NAME);
-#endif
+	/* If location is -2, the uniform has not yet been queried.
+	 * We save the name for query just before drawing. */
+	if (location == -2 || DRW_DEBUG_USE_UNIFORM_NAME) {
+		int ofs = DST.uniform_names.buffer_ofs;
+		int max_len = DST.uniform_names.buffer_len - ofs;
+		size_t len = strlen(name) + 1;
+
+		if (len >= max_len) {
+			DST.uniform_names.buffer_len += DRW_UNIFORM_BUFFER_NAME_INC;
+			DST.uniform_names.buffer = MEM_reallocN(DST.uniform_names.buffer, DST.uniform_names.buffer_len);
+		}
+
+		char *dst = DST.uniform_names.buffer + ofs;
+		memcpy(dst, name, len); /* Copies NULL terminator. */
+
+		DST.uniform_names.buffer_ofs += len;
+		shgroup->uniforms->name_ofs = ofs;
+	}
 }
 
 void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index a428fde6f00..1f1ccc7a66e 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -1050,6 +1050,12 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
 
 	/* Binding Uniform */
 	for (DRWUniform *uni = shgroup->uniforms; uni; uni = uni->next) {
+		if (uni->location == -2) {
+			uni->location = GPU_shader_get_uniform_ensure(shgroup->shader, DST.uniform_names.buffer + uni->name_ofs);
+			if (uni->location == -1) {
+				continue;
+			}
+		}
 		switch (uni->type) {
 			case DRW_UNIFORM_SHORT_TO_INT:
 				val = (int)*((short *)uni->pvalue);
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 31a85800754..0c1ea0d97d5 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -563,18 +563,7 @@ int GPU_shader_get_uniform(GPUShader *shader, const char *name)
 {
 	BLI_assert(shader && shader->program);
 	const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name);
-#if 1 /* Remove this when we have transitionned all uniforms. */
-	if (uniform == NULL) {
-#  ifndef NDEBUG
-		printf("Uniform \"%s\" needs to be added to shader interface after shader creation.\n", name);
-#  endif
-		/* Fallback to avoid issues. */
-		return GPU_shader_get_uniform_ensure(shader, name);
-	}
-#else
-	BLI_assert(uniform);
-#endif
-	return uniform->location;
+	return uniform ? uniform->location : -2;
 }
 
 int GPU_shader_get_uniform_ensure(GPUShader *shader, const char *name)



More information about the Bf-blender-cvs mailing list