From bac85342672a265735316049ecf36b74e1f2a852 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Tue, 18 Dec 2018 22:47:05 -0500 Subject: [PATCH] st/mesa: allow glDrawElements to work with GL_SELECT feedback Not sure if this ever worked, but the current logic for setting the min/max index is definitely wrong for indexed draws. While we're at it, bring in all the usual logic from the non-indirect drawing path. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109086 Signed-off-by: Ilia Mirkin Reviewed-by: Brian Paul Reviewed-by: Roland Scheidegger --- src/mesa/state_tracker/st_draw.c | 2 + src/mesa/state_tracker/st_draw_feedback.c | 63 ++++++++++++++--------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 9600b1569d5..0a190bd8ba8 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -160,6 +160,8 @@ prepare_draw(struct st_context *st, struct gl_context *ctx) * This function gets plugged into the VBO module and is called when * we have something to render. * Basically, translate the information into the format expected by gallium. + * + * Try to keep this logic in sync with st_feedback_draw_vbo. */ static void st_draw_vbo(struct gl_context *ctx, diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 6ec6d5c16f4..b83f63811dd 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -84,31 +84,10 @@ set_feedback_vertex_format(struct gl_context *ctx) } -/** - * Helper for drawing current vertex arrays. - */ -static void -draw_arrays(struct draw_context *draw, unsigned mode, - unsigned start, unsigned count) -{ - struct pipe_draw_info info; - - util_draw_init_info(&info); - - info.mode = mode; - info.start = start; - info.count = count; - info.min_index = start; - info.max_index = start + count - 1; - - draw_vbo(draw, &info); -} - - /** * Called by VBO to draw arrays when in selection or feedback mode and * to implement glRasterPos. - * This is very much like the normal draw_vbo() function above. + * This function mirrors the normal st_draw_vbo(). * Look at code refactoring some day. */ void @@ -136,10 +115,18 @@ st_feedback_draw_vbo(struct gl_context *ctx, struct pipe_transfer *ib_transfer = NULL; GLuint i; const void *mapped_indices = NULL; + struct pipe_draw_info info; if (!draw) return; + /* Initialize pipe_draw_info. */ + info.primitive_restart = false; + info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; + info.indirect = NULL; + info.count_from_stream_output = NULL; + info.restart_index = 0; + st_flush_bitmap_cache(st); st_invalidate_readpix_cache(st); @@ -213,9 +200,23 @@ st_feedback_draw_vbo(struct gl_context *ctx, mapped_indices = ib->ptr; } + info.index_size = ib->index_size; + info.min_index = min_index; + info.max_index = max_index; + info.has_user_indices = true; + info.index.user = mapped_indices; + draw_set_indexes(draw, (ubyte *) mapped_indices, index_size, ~0); + + if (ctx->Array._PrimitiveRestart) { + info.primitive_restart = true; + info.restart_index = _mesa_primitive_restart_index(ctx, info.index_size); + } + } else { + info.index_size = 0; + info.has_user_indices = false; } /* set the constant buffer */ @@ -226,7 +227,23 @@ st_feedback_draw_vbo(struct gl_context *ctx, /* draw here */ for (i = 0; i < nr_prims; i++) { - draw_arrays(draw, prims[i].mode, start + prims[i].start, prims[i].count); + info.count = prims[i].count; + + if (!info.count) + continue; + + info.mode = prims[i].mode; + info.start = start + prims[i].start; + info.start_instance = prims[i].base_instance; + info.instance_count = prims[i].num_instances; + info.index_bias = prims[i].basevertex; + info.drawid = prims[i].draw_id; + if (!ib) { + info.min_index = info.start; + info.max_index = info.start + info.count - 1; + } + + draw_vbo(draw, &info); } -- 2.30.2