diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-01-17 20:33:08 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-01-17 21:48:00 +0300 |
commit | e3b3b3207682233978dac5b06aef6748dcc0367c (patch) | |
tree | 34adba542c21f2c983b072e4d7330ce64b55a6b1 | |
parent | dc7e492989408038c89b5283ec5710b98457696f (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.
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 13 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.h | 16 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 22 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader.c | 13 |
5 files changed, 49 insertions, 21 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); 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) |