diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-05-22 12:31:49 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-05-22 14:29:05 +0300 |
commit | 60319e25f246128f51009c2f3bb731e4218bd008 (patch) | |
tree | a1b9b9a9127f09f2e1644fa4ab79e898ae05e6cc /source/blender | |
parent | 55780d9866ec9ab93f7f25f2ada41ae5d6e9dabb (diff) |
GPU: Refactor GPU_batch_draw_range_ex
Rename it to GPU_batch_draw_advanced and use base instance when possible.
Also add GPU_batch_bind to bind the vao independantly of drawing commands.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 6 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 31 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 4 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_knife.c | 5 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_draw.c | 5 | ||||
-rw-r--r-- | source/blender/gpu/GPU_batch.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_batch.c | 127 |
7 files changed, 87 insertions, 95 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 54d6752784a..cabf6849e43 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -365,7 +365,8 @@ void DRW_transform_none(GPUTexture *tex) GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); GPU_batch_program_use_begin(geom); - GPU_batch_draw_range_ex(geom, 0, 0, false); + GPU_batch_bind(geom); + GPU_batch_draw_advanced(geom, 0, 0, 0, 0); GPU_batch_program_use_end(geom); GPU_texture_unbind(tex); @@ -456,7 +457,8 @@ void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool /* avoid gpuMatrix calls */ GPU_batch_program_use_begin(geom); - GPU_batch_draw_range_ex(geom, 0, 0, false); + GPU_batch_bind(geom); + GPU_batch_draw_advanced(geom, 0, 0, 0, 0); GPU_batch_program_use_end(geom); } diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index dfffc62872d..05356740041 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -587,16 +587,23 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call) } } -static void draw_geometry_execute( - DRWShadingGroup *shgroup, GPUBatch *geom, uint start, uint count, bool draw_instance) +static void draw_geometry_execute(DRWShadingGroup *shgroup, + GPUBatch *geom, + uint vert_first, + uint vert_count, + uint inst_first, + uint inst_count) { - /* step 2 : bind vertex array & draw */ + /* bind vertex array */ GPU_batch_program_set_no_use( geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader)); + + GPU_batch_bind(geom); + /* XXX hacking gawain. we don't want to call glUseProgram! (huge performance loss) */ geom->program_in_use = true; - GPU_batch_draw_range_ex(geom, start, count, draw_instance); + GPU_batch_draw_advanced(geom, vert_first, vert_count, inst_first, inst_count); geom->program_in_use = false; /* XXX hacking gawain */ } @@ -859,7 +866,12 @@ BLI_INLINE bool draw_select_do_call(DRWShadingGroup *shgroup, DRWCall *call) while (start < tot) { GPU_select_load_id(select_id[start]); - draw_geometry_execute(shgroup, call->batch, start, count, is_instancing); + if (is_instancing) { + draw_geometry_execute(shgroup, call->batch, 0, 0, start, count); + } + else { + draw_geometry_execute(shgroup, call->batch, start, count, 0, 0); + } start += count; } return true; @@ -930,13 +942,8 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) continue; } - /* TODO revisit when DRW_SHG_INSTANCE and the like is gone. */ - if (call->inst_count == 0) { - draw_geometry_execute(shgroup, call->batch, call->vert_first, call->vert_count, false); - } - else { - draw_geometry_execute(shgroup, call->batch, 0, call->inst_count, true); - } + draw_geometry_execute( + shgroup, call->batch, call->vert_first, call->vert_count, 0, call->inst_count); } /* Reset state */ glFrontFace(GL_CCW); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 594793371ae..e31646f9fdb 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1261,7 +1261,9 @@ void UI_widgetbase_draw_cache_flush(void) (float *)g_widget_base_batch.params); GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GPU_matrix_bind(batch->interface); - GPU_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true); + GPU_batch_bind(batch); + GPU_batch_draw_advanced(batch, 0, 0, 0, g_widget_base_batch.count); + GPU_batch_program_use_end(batch); } g_widget_base_batch.count = 0; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index e45c15b3e53..976dbe01a22 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1156,19 +1156,20 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); + GPU_batch_bind(batch); /* draw any snapped verts first */ rgba_uchar_to_float(fcol, kcd->colors.point_a); GPU_batch_uniform_4fv(batch, "color", fcol); GPU_matrix_bind(batch->interface); GPU_point_size(11); - GPU_batch_draw_range_ex(batch, 0, v - 1, false); + GPU_batch_draw_advanced(batch, 0, v - 1, 0, 0); /* now draw the rest */ rgba_uchar_to_float(fcol, kcd->colors.curpoint_a); GPU_batch_uniform_4fv(batch, "color", fcol); GPU_point_size(7); - GPU_batch_draw_range_ex(batch, vs + 1, kcd->totlinehit - (vs + 1), false); + GPU_batch_draw_advanced(batch, vs + 1, kcd->totlinehit - (vs + 1), 0, 0); GPU_batch_program_use_end(batch); GPU_batch_discard(batch); diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 3a5aead3d44..7f9b90f4496 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -246,6 +246,7 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph) bool prev_ma_match = (mpoly->mat_nr == (eval_ob->actcol - 1)); GPU_matrix_bind(geom->interface); + GPU_batch_bind(geom); /* TODO(fclem): If drawcall count becomes a problem in the future * we can use multi draw indirect drawcalls for this. @@ -254,7 +255,7 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph) bool ma_match = (mpoly->mat_nr == (eval_ob->actcol - 1)); if (ma_match != prev_ma_match) { if (ma_match == false) { - GPU_batch_draw_range_ex(geom, draw_start, idx - draw_start, false); + GPU_batch_draw_advanced(geom, draw_start, idx - draw_start, 0, 0); } else { draw_start = idx; @@ -264,7 +265,7 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph) prev_ma_match = ma_match; } if (prev_ma_match == true) { - GPU_batch_draw_range_ex(geom, draw_start, idx - draw_start, false); + GPU_batch_draw_advanced(geom, draw_start, idx - draw_start, 0, 0); } GPU_batch_program_use_end(geom); diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index c48d49b5948..3b0d72831c0 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -148,8 +148,10 @@ void GPU_batch_uniform_mat4(GPUBatch *, const char *name, const float data[4][4] void GPU_batch_draw(GPUBatch *); +/* Needs to be called before GPU_batch_draw_advanced. */ +void GPU_batch_bind(GPUBatch *); /* This does not bind/unbind shader and does not call GPU_matrix_bind() */ -void GPU_batch_draw_range_ex(GPUBatch *, int v_first, int v_count, bool force_instance); +void GPU_batch_draw_advanced(GPUBatch *, int v_first, int v_count, int i_first, int i_count); /* Does not even need batch */ void GPU_draw_primitive(GPUPrimType, int v_count); diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index 76a250a55c7..933bcb2ed8e 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -577,10 +577,14 @@ static void *elem_offset(const GPUIndexBuf *el, int v_first) else if (el->index_type == GPU_INDEX_U16) { return (GLushort *)0 + v_first; } - else { #endif - return (GLuint *)0 + v_first; - } + return (GLuint *)0 + v_first; +} + +/* Use when drawing with GPU_batch_draw_advanced */ +void GPU_batch_bind(GPUBatch *batch) +{ + glBindVertexArray(batch->vao_id); } void GPU_batch_draw(GPUBatch *batch) @@ -592,103 +596,76 @@ void GPU_batch_draw(GPUBatch *batch) GPU_batch_program_use_begin(batch); GPU_matrix_bind(batch->interface); // external call. - GPU_batch_draw_range_ex(batch, 0, 0, false); + GPU_batch_bind(batch); + GPU_batch_draw_advanced(batch, 0, 0, 0, 0); GPU_batch_program_use_end(batch); } -void GPU_batch_draw_range_ex(GPUBatch *batch, int v_first, int v_count, bool force_instance) +void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_first, int i_count) { #if TRUST_NO_ONE - assert(!(force_instance && (batch->inst == NULL)) || - v_count > 0); // we cannot infer length if force_instance + BLI_assert(batch->program_in_use); + /* TODO could assert that VAO is bound. */ #endif - const bool do_instance = (force_instance || batch->inst); - - // If using offset drawing, use the default VAO and redo bindings. - if (v_first != 0 && do_instance) { - glBindVertexArray(GPU_vao_default()); - batch_update_program_bindings(batch, v_first); + if (v_count == 0) { + v_count = (batch->elem) ? batch->elem->index_len : batch->verts[0]->vertex_len; } - else { - glBindVertexArray(batch->vao_id); + if (i_count == 0) { + i_count = (batch->inst) ? batch->inst->vertex_len : 1; } - if (do_instance) { - /* Infer length if vertex count is not given */ - if (v_count == 0) { - v_count = batch->inst->vertex_len; + if (!GLEW_ARB_base_instance) { + if (i_first > 0 && i_count > 0) { + /* If using offset drawing with instancing, we must + * use the default VAO and redo bindings. */ + glBindVertexArray(GPU_vao_default()); + batch_update_program_bindings(batch, v_first); } + else { + /* Previous call could have bind the default vao + * see above. */ + glBindVertexArray(batch->vao_id); + } + } - if (batch->elem) { - const GPUIndexBuf *el = batch->elem; - - if (el->use_prim_restart) { - primitive_restart_enable(el); - } + if (batch->elem) { + const GPUIndexBuf *el = batch->elem; #if GPU_TRACK_INDEX_RANGE - glDrawElementsInstancedBaseVertex( - batch->gl_prim_type, el->index_len, el->gl_index_type, 0, v_count, el->base_index); + GLenum index_type = el->gl_index_type; + GLint base_index = el->base_index; #else - glDrawElementsInstanced(batch->gl_prim_type, el->index_len, GL_UNSIGNED_INT, 0, v_count); + GLenum index_type = GL_UNSIGNED_INT; + GLint base_index = 0; #endif - if (el->use_prim_restart) { - primitive_restart_disable(); - } + void *v_first_ofs = elem_offset(el, v_first); + + if (el->use_prim_restart) { + primitive_restart_enable(el); + } + + if (GLEW_ARB_base_instance) { + glDrawElementsInstancedBaseVertexBaseInstance( + batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index, i_first); } else { - glDrawArraysInstanced(batch->gl_prim_type, 0, batch->verts[0]->vertex_len, v_count); + glDrawElementsInstancedBaseVertex( + batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index); + } + + if (el->use_prim_restart) { + primitive_restart_disable(); } } else { - /* Infer length if vertex count is not given */ - if (v_count == 0) { - v_count = (batch->elem) ? batch->elem->index_len : batch->verts[0]->vertex_len; - } - - if (batch->elem) { - const GPUIndexBuf *el = batch->elem; - - if (el->use_prim_restart) { - primitive_restart_enable(el); - } - - void *v_first_ofs = elem_offset(el, v_first); - -#if GPU_TRACK_INDEX_RANGE - if (el->base_index) { - glDrawRangeElementsBaseVertex(batch->gl_prim_type, - el->min_index, - el->max_index, - v_count, - el->gl_index_type, - v_first_ofs, - el->base_index); - } - else { - glDrawRangeElements(batch->gl_prim_type, - el->min_index, - el->max_index, - v_count, - el->gl_index_type, - v_first_ofs); - } -#else - glDrawElements(batch->gl_prim_type, v_count, GL_UNSIGNED_INT, v_first_ofs); -#endif - if (el->use_prim_restart) { - primitive_restart_disable(); - } + if (GLEW_ARB_base_instance) { + glDrawArraysInstancedBaseInstance(batch->gl_prim_type, v_first, v_count, i_count, i_first); } else { - glDrawArrays(batch->gl_prim_type, v_first, v_count); + glDrawArraysInstanced(batch->gl_prim_type, v_first, v_count, i_count); } } - - /* Performance hog if you are drawing with the same vao multiple time. - * Only activate for debugging. */ - // glBindVertexArray(0); } /* just draw some vertices and let shader place them where we want. */ |