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-05-22 12:31:49 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-05-22 14:29:05 +0300
commit60319e25f246128f51009c2f3bb731e4218bd008 (patch)
treea1b9b9a9127f09f2e1644fa4ab79e898ae05e6cc /source/blender
parent55780d9866ec9ab93f7f25f2ada41ae5d6e9dabb (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.c6
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c31
-rw-r--r--source/blender/editors/interface/interface_widgets.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c5
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c5
-rw-r--r--source/blender/gpu/GPU_batch.h4
-rw-r--r--source/blender/gpu/intern/gpu_batch.c127
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. */