summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-12-31 14:11:07 -0500
committerIlia Mirkin <[email protected]>2016-01-07 18:38:46 -0500
commit2860f20859454b38ce44e4e3377c036e67c20ae7 (patch)
treee948551771c994833dafa9188e809ab140736fb9 /src/mesa/state_tracker
parentd67b9ba9a1af18306aa68f16ee1b9bbc124da42e (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]>
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_context.c2
-rw-r--r--src/mesa/state_tracker/st_context.h1
-rw-r--r--src/mesa/state_tracker/st_draw.c90
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 */