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:
authorClément Foucault <foucault.clem@gmail.com>2019-01-17 20:33:08 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-01-17 21:48:00 +0300
commite3b3b3207682233978dac5b06aef6748dcc0367c (patch)
tree34adba542c21f2c983b072e4d7330ce64b55a6b1 /source/blender/draw/intern
parentdc7e492989408038c89b5283ec5710b98457696f (diff)
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.
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/draw_manager.c13
-rw-r--r--source/blender/draw/intern/draw_manager.h16
-rw-r--r--source/blender/draw/intern/draw_manager_data.c22
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c6
4 files changed, 48 insertions, 9 deletions
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);