diff options
author | Ilia Mirkin <[email protected]> | 2015-12-31 14:11:07 -0500 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2016-01-07 18:38:46 -0500 |
commit | 2860f20859454b38ce44e4e3377c036e67c20ae7 (patch) | |
tree | e948551771c994833dafa9188e809ab140736fb9 | |
parent | d67b9ba9a1af18306aa68f16ee1b9bbc124da42e (diff) |
st/mesa: add support for new mesa indirect draw interface
This shifts all indirect draws to go through the new function. If the
driver doesn't have support for multi draws, we break those up and
perform N draws. Otherwise, we pass everything through for just a single
draw call.
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 1 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 90 |
3 files changed, 84 insertions, 9 deletions
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index e12c1663d3f..87193a9d478 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -267,6 +267,8 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED); st->has_half_float_packing = screen->get_param(screen, PIPE_CAP_TGSI_PACK_HALF_FLOAT); + st->has_multi_draw_indirect = + screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT); /* GL limits and extensions */ st_init_limits(st->pipe->screen, &ctx->Const, &ctx->Extensions); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 91b0f975f3f..9db5f11beb5 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -102,6 +102,7 @@ struct st_context boolean force_persample_in_shader; boolean has_shareable_shaders; boolean has_half_float_packing; + boolean has_multi_draw_indirect; /** * If a shader can be created when we get its source. diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index d7a97169bc2..03788f33468 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -252,13 +252,7 @@ st_draw_vbo(struct gl_context *ctx, } } - if (indirect) { - info.indirect = st_buffer_object(indirect)->buffer; - - /* Primitive restart is not handled by the VBO module in this case. */ - info.primitive_restart = ctx->Array._PrimitiveRestart; - info.restart_index = ctx->Array.RestartIndex; - } + assert(!indirect); /* do actual drawing */ for (i = 0; i < nr_prims; i++) { @@ -274,7 +268,6 @@ st_draw_vbo(struct gl_context *ctx, info.min_index = info.start; info.max_index = info.start + info.count - 1; } - info.indirect_offset = prims[i].indirect_offset; if (ST_DEBUG & DEBUG_DRAW) { debug_printf("st/draw: mode %s start %u count %u indexed %d\n", @@ -284,7 +277,7 @@ st_draw_vbo(struct gl_context *ctx, info.indexed); } - if (info.count_from_stream_output || info.indirect) { + if (info.count_from_stream_output) { cso_draw_vbo(st->cso_context, &info); } else if (info.primitive_restart) { @@ -301,6 +294,84 @@ st_draw_vbo(struct gl_context *ctx, } } +static void +st_indirect_draw_vbo(struct gl_context *ctx, + GLuint mode, + struct gl_buffer_object *indirect_data, + GLsizeiptr indirect_offset, + unsigned draw_count, + unsigned stride, + struct gl_buffer_object *indirect_params, + GLsizeiptr indirect_params_offset, + const struct _mesa_index_buffer *ib) +{ + struct st_context *st = st_context(ctx); + struct pipe_index_buffer ibuffer = {0}; + struct pipe_draw_info info; + + /* Mesa core state should have been validated already */ + assert(ctx->NewState == 0x0); + assert(stride); + + /* Validate state. */ + if (st->dirty.st || ctx->NewDriverState) { + st_validate_state(st); + } + + if (st->vertex_array_out_of_memory) { + return; + } + + util_draw_init_info(&info); + + if (ib) { + if (!setup_index_buffer(st, ib, &ibuffer)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDrawElementsIndirect%s", + (draw_count > 1) ? "Multi" : "", + indirect_params ? "CountARB" : ""); + return; + } + + info.indexed = TRUE; + } + + info.mode = translate_prim(ctx, mode); + info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; + info.indirect = st_buffer_object(indirect_data)->buffer; + info.indirect_offset = indirect_offset; + + /* Primitive restart is not handled by the VBO module in this case. */ + info.primitive_restart = ctx->Array._PrimitiveRestart; + info.restart_index = ctx->Array.RestartIndex; + + if (ST_DEBUG & DEBUG_DRAW) { + debug_printf("st/draw indirect: mode %s drawcount %d indexed %d\n", + u_prim_name(info.mode), + draw_count, + info.indexed); + } + + if (!st->has_multi_draw_indirect) { + int i; + + assert(!indirect_params); + info.indirect_count = 1; + for (i = 0; i < draw_count; i++) { + info.drawid = i; + cso_draw_vbo(st->cso_context, &info); + info.indirect_offset += stride; + } + } else { + info.indirect_count = draw_count; + info.indirect_stride = stride; + if (indirect_params) { + info.indirect_params = st_buffer_object(indirect_params)->buffer; + info.indirect_params_offset = indirect_params_offset; + } + cso_draw_vbo(st->cso_context, &info); + } +} + void st_init_draw(struct st_context *st) @@ -308,6 +379,7 @@ st_init_draw(struct st_context *st) struct gl_context *ctx = st->ctx; vbo_set_draw_func(ctx, st_draw_vbo); + vbo_set_indirect_draw_func(ctx, st_indirect_draw_vbo); st->draw = draw_create(st->pipe); /* for selection/feedback */ |