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-09-14 00:02:45 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-09-14 00:03:10 +0300
commitfd5c1972cd5c8a826c0d40effb0e2d367389666a (patch)
tree6a093944267ff888e9fb4323bac22d52468ab7ec /source/blender/draw/intern/draw_manager_exec.c
parentc80564ef9f557fadd235b87533b24d126e2138c9 (diff)
Revert "DRW: Refactor to support draw call batching"
This reverts commit ce34a6b0d727bbde6ae373afa8ec6c42bc8980ce.
Diffstat (limited to 'source/blender/draw/intern/draw_manager_exec.c')
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c687
1 files changed, 173 insertions, 514 deletions
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 6bb11a7d4ce..1dcaf39fc19 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -36,41 +36,16 @@
# include "GPU_select.h"
#endif
+#ifdef USE_GPU_SELECT
void DRW_select_load_id(uint id)
{
-#ifdef USE_GPU_SELECT
BLI_assert(G.f & G_FLAG_PICKSEL);
DST.select_id = id;
-#endif
}
+#endif
#define DEBUG_UBO_BINDING
-typedef struct DRWCommandsState {
- GPUBatch *batch;
- int resource_chunk;
- int base_inst;
- int inst_count;
- int v_first;
- int v_count;
- bool neg_scale;
- /* Resource location. */
- int obmats_loc;
- int obinfos_loc;
- int baseinst_loc;
- int chunkid_loc;
- /* Legacy matrix support. */
- int obmat_loc;
- int obinv_loc;
- int mvp_loc;
- /* Selection ID state. */
- GPUVertBuf *select_buf;
- uint select_id;
- /* Drawing State */
- DRWState drw_state_enabled;
- DRWState drw_state_disabled;
-} DRWCommandsState;
-
/* -------------------------------------------------------------------- */
/** \name Draw State (DRW_state)
* \{ */
@@ -432,10 +407,9 @@ void DRW_state_reset(void)
/** \name Culling (DRW_culling)
* \{ */
-static bool draw_call_is_culled(const DRWResourceHandle *handle, DRWView *view)
+static bool draw_call_is_culled(DRWCall *call, DRWView *view)
{
- DRWCullingState *culling = DRW_memblock_elem_from_handle(DST.vmempool->cullstates, handle);
- return (culling->mask & view->culling_mask) != 0;
+ return (call->state->culling->mask & view->culling_mask) != 0;
}
/* Set active view for rendering. */
@@ -614,96 +588,66 @@ static void draw_compute_culling(DRWView *view)
/** \name Draw (DRW_draw)
* \{ */
-BLI_INLINE void draw_legacy_matrix_update(DRWShadingGroup *shgroup,
- DRWResourceHandle *handle,
- float obmat_loc,
- float obinv_loc,
- float mvp_loc)
+static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call)
{
- /* Still supported for compatibility with gpu_shader_* but should be forbidden. */
- DRWObjectMatrix *ob_mats = DRW_memblock_elem_from_handle(DST.vmempool->obmats, handle);
- if (obmat_loc != -1) {
- GPU_shader_uniform_vector(shgroup->shader, obmat_loc, 16, 1, (float *)ob_mats->model);
+ BLI_assert(call);
+ DRWCallState *state = call->state;
+
+ if (shgroup->model != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)state->model);
+ }
+ if (shgroup->modelinverse != -1) {
+ GPU_shader_uniform_vector(
+ shgroup->shader, shgroup->modelinverse, 16, 1, (float *)state->modelinverse);
+ }
+ if (shgroup->objectinfo != -1) {
+ float infos[4];
+ infos[0] = state->ob_index;
+ // infos[1]; /* UNUSED. */
+ infos[2] = state->ob_random;
+ infos[3] = (state->flag & DRW_CALL_NEGSCALE) ? -1.0f : 1.0f;
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 4, 1, (float *)infos);
+ }
+ if (shgroup->objectcolor != -1) {
+ GPU_shader_uniform_vector(
+ shgroup->shader, shgroup->objectcolor, 4, 1, (float *)state->ob_color);
}
- if (obinv_loc != -1) {
- GPU_shader_uniform_vector(shgroup->shader, obinv_loc, 16, 1, (float *)ob_mats->modelinverse);
+ if (shgroup->orcotexfac != -1) {
+ GPU_shader_uniform_vector(
+ shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)state->orcotexfac);
}
/* Still supported for compatibility with gpu_shader_* but should be forbidden
* and is slow (since it does not cache the result). */
- if (mvp_loc != -1) {
+ if (shgroup->modelviewprojection != -1) {
float mvp[4][4];
- mul_m4_m4m4(mvp, DST.view_active->storage.persmat, ob_mats->model);
- GPU_shader_uniform_vector(shgroup->shader, mvp_loc, 16, 1, (float *)mvp);
+ mul_m4_m4m4(mvp, DST.view_active->storage.persmat, state->model);
+ GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewprojection, 16, 1, (float *)mvp);
}
}
-BLI_INLINE void draw_geometry_bind(DRWShadingGroup *shgroup, GPUBatch *geom)
-{
- /* XXX hacking #GPUBatch. we don't want to call glUseProgram! (huge performance loss) */
- if (DST.batch) {
- DST.batch->program_in_use = false;
- }
-
- DST.batch = geom;
-
- GPU_batch_program_set_no_use(
- geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
-
- geom->program_in_use = true; /* XXX hacking #GPUBatch */
-
- GPU_batch_bind(geom);
-}
-
BLI_INLINE void draw_geometry_execute(DRWShadingGroup *shgroup,
GPUBatch *geom,
- int vert_first,
- int vert_count,
- int inst_first,
- int inst_count,
- int baseinst_loc)
+ uint vert_first,
+ uint vert_count,
+ uint inst_first,
+ uint inst_count)
{
- /* inst_count can be -1. */
- inst_count = max_ii(0, inst_count);
-
- if (baseinst_loc != -1) {
- /* Fallback when ARB_shader_draw_parameters is not supported. */
- GPU_shader_uniform_vector_int(shgroup->shader, baseinst_loc, 1, 1, (int *)&inst_first);
- /* Avoids VAO reconfiguration on older hardware. (see GPU_batch_draw_advanced) */
- inst_first = 0;
- }
-
/* bind vertex array */
if (DST.batch != geom) {
- draw_geometry_bind(shgroup, geom);
+ DST.batch = geom;
+
+ 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 #GPUBatch. we don't want to call glUseProgram! (huge performance loss) */
+ geom->program_in_use = true;
+
GPU_batch_draw_advanced(geom, vert_first, vert_count, inst_first, inst_count);
-}
-BLI_INLINE void draw_indirect_call(DRWShadingGroup *shgroup, DRWCommandsState *state)
-{
- if (state->inst_count == 0) {
- return;
- }
- if (state->baseinst_loc == -1) {
- /* bind vertex array */
- if (DST.batch != state->batch) {
- GPU_draw_list_submit(DST.draw_list);
- draw_geometry_bind(shgroup, state->batch);
- }
- GPU_draw_list_command_add(
- DST.draw_list, state->v_first, state->v_count, state->base_inst, state->inst_count);
- }
- /* Fallback when unsupported */
- else {
- draw_geometry_execute(shgroup,
- state->batch,
- state->v_first,
- state->v_count,
- state->base_inst,
- state->inst_count,
- state->baseinst_loc);
- }
+ geom->program_in_use = false; /* XXX hacking #GPUBatch */
}
enum {
@@ -775,9 +719,6 @@ static void bind_ubo(GPUUniformBuffer *ubo, char bind_type)
/* UBO isn't bound yet. Find an empty slot and bind it. */
idx = get_empty_slot_index(DST.RST.bound_ubo_slots);
- /* [0..1] are reserved ubo slots. */
- idx += 2;
-
if (idx < GPU_max_ubo_binds()) {
GPUUniformBuffer **gpu_ubo_slot = &DST.RST.bound_ubos[idx];
/* Unbind any previous UBO. */
@@ -797,13 +738,10 @@ static void bind_ubo(GPUUniformBuffer *ubo, char bind_type)
}
}
else {
- BLI_assert(idx < 64);
/* This UBO slot was released but the UBO is
* still bound here. Just flag the slot again. */
BLI_assert(DST.RST.bound_ubos[idx] == ubo);
}
- /* Remove offset for flag bitfield. */
- idx -= 2;
set_bound_flags(&DST.RST.bound_ubo_slots, &DST.RST.bound_ubo_slots_persist, idx, bind_type);
}
@@ -847,12 +785,8 @@ static bool ubo_bindings_validate(DRWShadingGroup *shgroup)
printf("Trying to draw with missing UBO binding.\n");
valid = false;
}
-
- DRWPass *parent_pass = DRW_memblock_elem_from_handle(DST.vmempool->passes,
- &shgroup->pass_handle);
-
printf("Pass : %s, Shader : %s, Block : %s\n",
- parent_pass->name,
+ shgroup->pass_parent->name,
shgroup->shader->name,
blockname);
}
@@ -884,330 +818,119 @@ static void release_ubo_slots(bool with_persist)
}
}
-static void draw_update_uniforms(DRWShadingGroup *shgroup,
- DRWCommandsState *state,
- bool *use_tfeedback)
+static void draw_update_uniforms(DRWShadingGroup *shgroup)
{
- for (DRWUniformChunk *unichunk = shgroup->uniforms; unichunk; unichunk = unichunk->next) {
- DRWUniform *uni = unichunk->uniforms;
- for (int i = 0; i < unichunk->uniform_used; i++, uni++) {
- GPUTexture *tex;
- GPUUniformBuffer *ubo;
- 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;
- }
- }
- const void *data = uni->pvalue;
- if (ELEM(uni->type, DRW_UNIFORM_INT_COPY, DRW_UNIFORM_FLOAT_COPY)) {
- data = uni->fvalue;
- }
- switch (uni->type) {
- case DRW_UNIFORM_INT_COPY:
- case DRW_UNIFORM_INT:
- GPU_shader_uniform_vector_int(
- shgroup->shader, uni->location, uni->length, uni->arraysize, data);
- break;
- case DRW_UNIFORM_FLOAT_COPY:
- case DRW_UNIFORM_FLOAT:
- GPU_shader_uniform_vector(
- shgroup->shader, uni->location, uni->length, uni->arraysize, data);
- break;
- case DRW_UNIFORM_TEXTURE:
- tex = (GPUTexture *)uni->pvalue;
- BLI_assert(tex);
- bind_texture(tex, BIND_TEMP);
- GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
- break;
- case DRW_UNIFORM_TEXTURE_PERSIST:
- tex = (GPUTexture *)uni->pvalue;
- BLI_assert(tex);
- bind_texture(tex, BIND_PERSIST);
- GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
- break;
- case DRW_UNIFORM_TEXTURE_REF:
- tex = *((GPUTexture **)uni->pvalue);
- BLI_assert(tex);
- bind_texture(tex, BIND_TEMP);
- GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
- break;
- case DRW_UNIFORM_BLOCK:
- ubo = (GPUUniformBuffer *)uni->pvalue;
- bind_ubo(ubo, BIND_TEMP);
- GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
- break;
- case DRW_UNIFORM_BLOCK_PERSIST:
- ubo = (GPUUniformBuffer *)uni->pvalue;
- bind_ubo(ubo, BIND_PERSIST);
- GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
- break;
- case DRW_UNIFORM_BLOCK_OBMATS:
- state->obmats_loc = uni->location;
- ubo = DST.vmempool->matrices_ubo[0];
- GPU_uniformbuffer_bind(ubo, 0);
- GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
- break;
- case DRW_UNIFORM_BLOCK_OBINFOS:
- state->obinfos_loc = uni->location;
- ubo = DST.vmempool->obinfos_ubo[0];
- GPU_uniformbuffer_bind(ubo, 1);
- GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
- break;
- case DRW_UNIFORM_RESOURCE_CHUNK:
- state->chunkid_loc = uni->location;
- GPU_shader_uniform_int(shgroup->shader, uni->location, 0);
- break;
- case DRW_UNIFORM_TFEEDBACK_TARGET:
- BLI_assert(data && (*use_tfeedback == false));
- *use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
- ((GPUVertBuf *)data)->vbo_id);
- break;
- /* Legacy/Fallback support. */
- case DRW_UNIFORM_BASE_INSTANCE:
- state->baseinst_loc = uni->location;
- break;
- case DRW_UNIFORM_MODEL_MATRIX:
- state->obmat_loc = uni->location;
- break;
- case DRW_UNIFORM_MODEL_MATRIX_INVERSE:
- state->obinv_loc = uni->location;
- break;
- case DRW_UNIFORM_MODELVIEWPROJECTION_MATRIX:
- state->mvp_loc = uni->location;
- break;
+ for (DRWUniform *uni = shgroup->uniforms; uni; uni = uni->next) {
+ GPUTexture *tex;
+ GPUUniformBuffer *ubo;
+ 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;
}
}
- }
-
- BLI_assert(ubo_bindings_validate(shgroup));
-}
-
-BLI_INLINE void draw_select_buffer(DRWShadingGroup *shgroup,
- DRWCommandsState *state,
- GPUBatch *batch,
- const DRWResourceHandle *handle)
-{
- const bool is_instancing = (batch->inst != NULL);
- int start = 0;
- int count = 1;
- int tot = is_instancing ? batch->inst->vertex_len : batch->verts[0]->vertex_len;
- /* Hack : get "vbo" data without actually drawing. */
- int *select_id = (void *)state->select_buf->data;
-
- /* Batching */
- if (!is_instancing) {
- /* FIXME: Meh a bit nasty. */
- if (batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_TRIS)) {
- count = 3;
- }
- else if (batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_LINES)) {
- count = 2;
- }
- }
-
- while (start < tot) {
- GPU_select_load_id(select_id[start]);
- if (is_instancing) {
- draw_geometry_execute(shgroup, batch, 0, 0, start, count, state->baseinst_loc);
+ const void *data = uni->pvalue;
+ if (ELEM(uni->type, DRW_UNIFORM_INT_COPY, DRW_UNIFORM_FLOAT_COPY)) {
+ data = uni->fvalue;
}
- else {
- draw_geometry_execute(
- shgroup, batch, start, count, DRW_handle_id_get(handle), 0, state->baseinst_loc);
+ switch (uni->type) {
+ case DRW_UNIFORM_INT_COPY:
+ case DRW_UNIFORM_INT:
+ GPU_shader_uniform_vector_int(
+ shgroup->shader, uni->location, uni->length, uni->arraysize, data);
+ break;
+ case DRW_UNIFORM_FLOAT_COPY:
+ case DRW_UNIFORM_FLOAT:
+ GPU_shader_uniform_vector(
+ shgroup->shader, uni->location, uni->length, uni->arraysize, data);
+ break;
+ case DRW_UNIFORM_TEXTURE:
+ tex = (GPUTexture *)uni->pvalue;
+ BLI_assert(tex);
+ bind_texture(tex, BIND_TEMP);
+ GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
+ break;
+ case DRW_UNIFORM_TEXTURE_PERSIST:
+ tex = (GPUTexture *)uni->pvalue;
+ BLI_assert(tex);
+ bind_texture(tex, BIND_PERSIST);
+ GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
+ break;
+ case DRW_UNIFORM_TEXTURE_REF:
+ tex = *((GPUTexture **)uni->pvalue);
+ BLI_assert(tex);
+ bind_texture(tex, BIND_TEMP);
+ GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
+ break;
+ case DRW_UNIFORM_BLOCK:
+ ubo = (GPUUniformBuffer *)uni->pvalue;
+ bind_ubo(ubo, BIND_TEMP);
+ GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
+ break;
+ case DRW_UNIFORM_BLOCK_PERSIST:
+ ubo = (GPUUniformBuffer *)uni->pvalue;
+ bind_ubo(ubo, BIND_PERSIST);
+ GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
+ break;
}
- start += count;
}
-}
-
-typedef struct DRWCommandIterator {
- int cmd_index;
- DRWCommandChunk *curr_chunk;
-} DRWCommandIterator;
-static void draw_command_iter_begin(DRWCommandIterator *iter, DRWShadingGroup *shgroup)
-{
- iter->curr_chunk = shgroup->cmd.first;
- iter->cmd_index = 0;
-}
-
-static DRWCommand *draw_command_iter_step(DRWCommandIterator *iter, eDRWCommandType *cmd_type)
-{
- if (iter->curr_chunk) {
- if (iter->cmd_index == iter->curr_chunk->command_len) {
- iter->curr_chunk = iter->curr_chunk->next;
- iter->cmd_index = 0;
- }
- if (iter->curr_chunk) {
- *cmd_type = command_type_get(iter->curr_chunk->command_type, iter->cmd_index);
- if (iter->cmd_index < iter->curr_chunk->command_used) {
- return iter->curr_chunk->commands + iter->cmd_index++;
- }
- }
- }
- return NULL;
+ BLI_assert(ubo_bindings_validate(shgroup));
}
-static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHandle *handle)
+BLI_INLINE bool draw_select_do_call(DRWShadingGroup *shgroup, DRWCall *call)
{
- /* Front face is not a resource but it is inside the resource handle. */
- bool neg_scale = DRW_handle_negative_scale_get(handle);
- if (neg_scale != state->neg_scale) {
- glFrontFace((neg_scale) ? GL_CW : GL_CCW);
- state->neg_scale = neg_scale;
+#ifdef USE_GPU_SELECT
+ if ((G.f & G_FLAG_PICKSEL) == 0) {
+ return false;
}
-
- int chunk = DRW_handle_chunk_get(handle);
- if (state->resource_chunk != chunk) {
- if (state->chunkid_loc != -1) {
- GPU_shader_uniform_int(NULL, state->chunkid_loc, chunk);
- }
- if (state->obmats_loc != -1) {
- GPU_uniformbuffer_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
- GPU_uniformbuffer_bind(DST.vmempool->matrices_ubo[chunk], 0);
- }
- if (state->obinfos_loc != -1) {
- GPU_uniformbuffer_unbind(DST.vmempool->obinfos_ubo[state->resource_chunk]);
- GPU_uniformbuffer_bind(DST.vmempool->obinfos_ubo[chunk], 1);
+ if (call->inst_selectid != NULL) {
+ const bool is_instancing = (call->inst_count != 0);
+ uint start = 0;
+ uint count = 1;
+ uint tot = is_instancing ? call->inst_count : call->vert_count;
+ /* Hack : get vbo data without actually drawing. */
+ GPUVertBufRaw raw;
+ GPU_vertbuf_attr_get_raw_data(call->inst_selectid, 0, &raw);
+ int *select_id = GPU_vertbuf_raw_step(&raw);
+
+ /* Batching */
+ if (!is_instancing) {
+ /* FIXME: Meh a bit nasty. */
+ if (call->batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_TRIS)) {
+ count = 3;
+ }
+ else if (call->batch->gl_prim_type == convert_prim_type_to_gl(GPU_PRIM_LINES)) {
+ count = 2;
+ }
}
- state->resource_chunk = chunk;
- }
-}
-
-static void draw_call_batching_flush(DRWShadingGroup *shgroup, DRWCommandsState *state)
-{
- draw_indirect_call(shgroup, state);
- GPU_draw_list_submit(DST.draw_list);
-
- state->batch = NULL;
- state->inst_count = 0;
- state->base_inst = -1;
-}
-
-static void draw_call_single_do(DRWShadingGroup *shgroup,
- DRWCommandsState *state,
- GPUBatch *batch,
- DRWResourceHandle handle,
- int vert_first,
- int vert_count,
- int inst_count)
-{
- draw_call_batching_flush(shgroup, state);
-
- draw_call_resource_bind(state, &handle);
- /* TODO This is Legacy. Need to be removed. */
- if (state->obmats_loc == -1 &&
- (state->obmat_loc != -1 || state->obinv_loc != -1 || state->mvp_loc != -1)) {
- draw_legacy_matrix_update(
- shgroup, &handle, state->obmat_loc, state->obinv_loc, state->mvp_loc);
- }
-
- if (G.f & G_FLAG_PICKSEL) {
- if (state->select_buf != NULL) {
- draw_select_buffer(shgroup, state, batch, &handle);
- return;
- }
- else {
- GPU_select_load_id(state->select_id);
+ while (start < tot) {
+ GPU_select_load_id(select_id[start]);
+ 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;
}
-
- draw_geometry_execute(shgroup,
- batch,
- vert_first,
- vert_count,
- DRW_handle_id_get(&handle),
- inst_count,
- state->baseinst_loc);
-}
-
-static void draw_call_batching_start(DRWCommandsState *state)
-{
- state->neg_scale = false;
- state->resource_chunk = 0;
- state->base_inst = 0;
- state->inst_count = 0;
- state->v_first = 0;
- state->v_count = 0;
- state->batch = NULL;
-
- state->select_id = -1;
- state->select_buf = NULL;
-}
-
-static void draw_call_batching_do(DRWShadingGroup *shgroup,
- DRWCommandsState *state,
- DRWCommandDraw *call)
-{
- /* If any condition requires to interupt the merging. */
- bool neg_scale = DRW_handle_negative_scale_get(&call->handle);
- int chunk = DRW_handle_chunk_get(&call->handle);
- int id = DRW_handle_id_get(&call->handle);
- if ((state->neg_scale != neg_scale) || /* Need to change state. */
- (state->resource_chunk != chunk) || /* Need to change UBOs. */
- (state->batch != call->batch) /* Need to change VAO. */
- ) {
- draw_call_batching_flush(shgroup, state);
-
- state->batch = call->batch;
- state->v_first = (call->batch->elem) ? call->batch->elem->index_start : 0;
- state->v_count = (call->batch->elem) ? call->batch->elem->index_len :
- call->batch->verts[0]->vertex_len;
- state->inst_count = 1;
- state->base_inst = id;
-
- draw_call_resource_bind(state, &call->handle);
-
- GPU_draw_list_init(DST.draw_list, state->batch);
- }
- /* Is the id consecutive? */
- else if (id != state->base_inst + state->inst_count) {
- /* We need to add a draw command for the pending instances. */
- draw_indirect_call(shgroup, state);
- state->inst_count = 1;
- state->base_inst = id;
- }
- /* We avoid a drawcall by merging with the precedent
- * drawcall using instancing. */
else {
- state->inst_count++;
- }
-}
-
-/* Flush remaining pending drawcalls. */
-static void draw_call_batching_finish(DRWShadingGroup *shgroup, DRWCommandsState *state)
-{
- draw_call_batching_flush(shgroup, state);
-
- /* Reset state */
- if (state->neg_scale) {
- glFrontFace(GL_CCW);
- }
- if (state->obmats_loc != -1) {
- GPU_uniformbuffer_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
- }
- if (state->obinfos_loc != -1) {
- GPU_uniformbuffer_unbind(DST.vmempool->obinfos_ubo[state->resource_chunk]);
+ GPU_select_load_id(call->select_id);
+ return false;
}
+#else
+ return false;
+#endif
}
static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
{
BLI_assert(shgroup->shader);
- DRWCommandsState state = {
- .obmats_loc = -1,
- .obinfos_loc = -1,
- .baseinst_loc = -1,
- .chunkid_loc = -1,
- .obmat_loc = -1,
- .obinv_loc = -1,
- .mvp_loc = -1,
- .drw_state_enabled = 0,
- .drw_state_disabled = 0,
- };
-
const bool shader_changed = (DST.shader != shgroup->shader);
bool use_tfeedback = false;
@@ -1217,115 +940,56 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
GPU_shader_bind(shgroup->shader);
DST.shader = shgroup->shader;
- /* XXX hacking gawain */
- if (DST.batch) {
- DST.batch->program_in_use = false;
- }
DST.batch = NULL;
}
+ if (shgroup->tfeedback_target != NULL) {
+ use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
+ shgroup->tfeedback_target->vbo_id);
+ }
+
release_ubo_slots(shader_changed);
release_texture_slots(shader_changed);
- draw_update_uniforms(shgroup, &state, &use_tfeedback);
+ drw_state_set((pass_state & shgroup->state_extra_disable) | shgroup->state_extra);
+ drw_stencil_set(shgroup->stencil_mask);
- drw_state_set(pass_state);
+ draw_update_uniforms(shgroup);
/* Rendering Calls */
{
- DRWCommandIterator iter;
- DRWCommand *cmd;
- eDRWCommandType cmd_type;
-
- draw_command_iter_begin(&iter, shgroup);
-
- draw_call_batching_start(&state);
-
- while ((cmd = draw_command_iter_step(&iter, &cmd_type))) {
-
- switch (cmd_type) {
- case DRW_CMD_DRWSTATE:
- case DRW_CMD_STENCIL:
- draw_call_batching_flush(shgroup, &state);
- break;
- case DRW_CMD_DRAW:
- case DRW_CMD_DRAW_PROCEDURAL:
- case DRW_CMD_DRAW_INSTANCE:
- if (draw_call_is_culled(&cmd->instance.handle, DST.view_active)) {
- continue;
- }
- break;
- default:
- break;
+ bool prev_neg_scale = false;
+ int callid = 0;
+ for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
+
+ if (draw_call_is_culled(call, DST.view_active)) {
+ continue;
}
- switch (cmd_type) {
- case DRW_CMD_CLEAR:
- GPU_framebuffer_clear(
-#ifndef NDEBUG
- GPU_framebuffer_active_get(),
-#else
- NULL,
-#endif
- cmd->clear.clear_channels,
- (float[4]){cmd->clear.r / 255.0f,
- cmd->clear.g / 255.0f,
- cmd->clear.b / 255.0f,
- cmd->clear.a / 255.0f},
- cmd->clear.depth,
- cmd->clear.stencil);
- break;
- case DRW_CMD_DRWSTATE:
- state.drw_state_enabled |= cmd->state.enable;
- state.drw_state_disabled |= cmd->state.disable;
- drw_state_set((pass_state & ~state.drw_state_disabled) | state.drw_state_enabled);
- break;
- case DRW_CMD_STENCIL:
- drw_stencil_set(cmd->stencil.mask);
- break;
- case DRW_CMD_SELECTID:
- state.select_id = cmd->select_id.select_id;
- state.select_buf = cmd->select_id.select_buf;
- break;
- case DRW_CMD_DRAW:
- if (!USE_BATCHING || state.obmats_loc == -1 || (G.f & G_FLAG_PICKSEL)) {
- draw_call_single_do(shgroup, &state, cmd->draw.batch, cmd->draw.handle, 0, 0, 0);
- }
- else {
- draw_call_batching_do(shgroup, &state, &cmd->draw);
- }
- break;
- case DRW_CMD_DRAW_PROCEDURAL:
- draw_call_single_do(shgroup,
- &state,
- cmd->procedural.batch,
- cmd->procedural.handle,
- 0,
- cmd->procedural.vert_count,
- 1);
- break;
- case DRW_CMD_DRAW_INSTANCE:
- draw_call_single_do(shgroup,
- &state,
- cmd->instance.batch,
- cmd->instance.handle,
- 0,
- 0,
- cmd->instance.inst_count);
- break;
- case DRW_CMD_DRAW_RANGE:
- draw_call_single_do(shgroup,
- &state,
- cmd->range.batch,
- (DRWResourceHandle)0,
- cmd->range.vert_first,
- cmd->range.vert_count,
- 1);
- break;
+ /* XXX small exception/optimisation for outline rendering. */
+ if (shgroup->callid != -1) {
+ GPU_shader_uniform_vector_int(shgroup->shader, shgroup->callid, 1, 1, &callid);
+ callid += 1;
}
- }
- draw_call_batching_finish(shgroup, &state);
+ /* Negative scale objects */
+ bool neg_scale = call->state->flag & DRW_CALL_NEGSCALE;
+ if (neg_scale != prev_neg_scale) {
+ glFrontFace((neg_scale) ? GL_CW : GL_CCW);
+ prev_neg_scale = neg_scale;
+ }
+
+ draw_geometry_prepare(shgroup, call);
+
+ if (draw_select_do_call(shgroup, call)) {
+ continue;
+ }
+
+ draw_geometry_execute(
+ shgroup, call->batch, call->vert_first, call->vert_count, 0, call->inst_count);
+ }
+ /* Reset state */
+ glFrontFace(GL_CCW);
}
if (use_tfeedback) {
@@ -1401,11 +1065,6 @@ static void drw_draw_pass_ex(DRWPass *pass,
DST.shader = NULL;
}
- if (DST.batch) {
- DST.batch->program_in_use = false;
- DST.batch = NULL;
- }
-
/* HACK: Rasterized discard can affect clear commands which are not
* part of a DRWPass (as of now). So disable rasterized discard here
* if it has been enabled. */