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.
This commit is contained in:
parent
55780d9866
commit
60319e25f2
Notes:
blender-bot
2023-02-14 11:42:40 +01:00
Referenced by issue #67951, you cannot select bones individually Referenced by issue #65066, Armature and bone selection is broken on macOS
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 GPU_TRACK_INDEX_RANGE
|
||||
GLenum index_type = el->gl_index_type;
|
||||
GLint base_index = el->base_index;
|
||||
#else
|
||||
GLenum index_type = GL_UNSIGNED_INT;
|
||||
GLint base_index = 0;
|
||||
#endif
|
||||
void *v_first_ofs = elem_offset(el, v_first);
|
||||
|
||||
if (el->use_prim_restart) {
|
||||
primitive_restart_enable(el);
|
||||
}
|
||||
|
||||
if (batch->elem) {
|
||||
const GPUIndexBuf *el = batch->elem;
|
||||
|
||||
if (el->use_prim_restart) {
|
||||
primitive_restart_enable(el);
|
||||
}
|
||||
#if GPU_TRACK_INDEX_RANGE
|
||||
if (GLEW_ARB_base_instance) {
|
||||
glDrawElementsInstancedBaseVertexBaseInstance(
|
||||
batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index, i_first);
|
||||
}
|
||||
else {
|
||||
glDrawElementsInstancedBaseVertex(
|
||||
batch->gl_prim_type, el->index_len, el->gl_index_type, 0, v_count, el->base_index);
|
||||
#else
|
||||
glDrawElementsInstanced(batch->gl_prim_type, el->index_len, GL_UNSIGNED_INT, 0, v_count);
|
||||
#endif
|
||||
if (el->use_prim_restart) {
|
||||
primitive_restart_disable();
|
||||
}
|
||||
batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index);
|
||||
}
|
||||
else {
|
||||
glDrawArraysInstanced(batch->gl_prim_type, 0, batch->verts[0]->vertex_len, v_count);
|
||||
|
||||
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. */
|
||||
|
|
Loading…
Reference in New Issue