diff options
author | Marek Olšák <marek.olsak@amd.com> | 2020-10-30 09:50:50 -0400 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2020-11-18 01:41:24 +0000 |
commit | 238ee7b801cf3f861871d7b7849c25e180da5894 (patch) | |
tree | 93ac80c1c32431c66991778cfd637163876c8239 /src/mesa | |
parent | c77409a87e46a526cd2256439188deaf0ee2d4e2 (diff) |
mesa: add Driver.DrawTransformFeedback
to remove some overhead from Driver.Draw.
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7441>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/common/driverfuncs.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw.c | 52 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_primitive_restart.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c | 4 | ||||
-rw-r--r-- | src/mesa/main/dd.h | 27 | ||||
-rw-r--r-- | src/mesa/main/draw.c | 22 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_rasterpos.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 43 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.h | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw_feedback.c | 5 | ||||
-rw-r--r-- | src/mesa/tnl/t_draw.c | 4 | ||||
-rw-r--r-- | src/mesa/tnl/tnl.h | 3 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec_draw.c | 3 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_primitive_restart.c | 6 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_draw.c | 2 |
16 files changed, 111 insertions, 74 deletions
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 13dbd113a29..21771d2cfc6 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -122,6 +122,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) /* Draw functions */ driver->Draw = NULL; driver->DrawIndirect = NULL; + driver->DrawTransformFeedback = NULL; /* simple state commands */ driver->AlphaFunc = NULL; diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index cf4778e8abc..25162ca7825 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -1140,15 +1140,11 @@ brw_draw_prims(struct gl_context *ctx, GLuint min_index, GLuint max_index, GLuint num_instances, - GLuint base_instance, - struct gl_transform_feedback_object *gl_xfb_obj, - unsigned stream) + GLuint base_instance) { unsigned i; struct brw_context *brw = brw_context(ctx); int predicate_state = brw->predicate.state; - struct brw_transform_feedback_object *xfb_obj = - (struct brw_transform_feedback_object *) gl_xfb_obj; if (!brw_check_conditional_render(brw)) return; @@ -1169,7 +1165,7 @@ brw_draw_prims(struct gl_context *ctx, _swsetup_Wakeup(ctx); _tnl_wakeup(ctx); _tnl_draw(ctx, prims, nr_prims, ib, index_bounds_valid, min_index, - max_index, num_instances, base_instance, NULL, 0); + max_index, num_instances, base_instance); return; } @@ -1222,7 +1218,7 @@ brw_draw_prims(struct gl_context *ctx, } brw_draw_single_prim(ctx, &prims[i], i, ib != NULL, num_instances, - base_instance, xfb_obj, stream, + base_instance, NULL, 0, brw->draw.draw_indirect_offset + brw->draw.draw_indirect_stride * i); } @@ -1231,6 +1227,45 @@ brw_draw_prims(struct gl_context *ctx, brw->predicate.state = predicate_state; } +static void +brw_draw_transform_feedback(struct gl_context *ctx, GLenum mode, + unsigned num_instances, unsigned stream, + struct gl_transform_feedback_object *gl_xfb_obj) +{ + struct brw_context *brw = brw_context(ctx); + struct brw_transform_feedback_object *xfb_obj = + (struct brw_transform_feedback_object *) gl_xfb_obj; + + if (!brw_check_conditional_render(brw)) + return; + + /* Do GL_SELECT and GL_FEEDBACK rendering using swrast, even though it + * won't support all the extensions we support. + */ + if (ctx->RenderMode != GL_RENDER) { + perf_debug("%s render mode not supported in hardware\n", + _mesa_enum_to_string(ctx->RenderMode)); + /* swrast doesn't support DrawTransformFeedback. Nothing to do. */ + return; + } + + brw_prepare_drawing(ctx, NULL, false, 0, ~0); + + struct _mesa_prim prim; + memset(&prim, 0, sizeof(prim)); + prim.begin = 1; + prim.end = 1; + prim.mode = mode; + + /* Try drawing with the hardware, but don't do anything else if we can't + * manage it. swrast doesn't support our featureset, so we can't fall back + * to it. + */ + brw_draw_single_prim(ctx, &prim, 0, false, num_instances, 0, xfb_obj, + stream, 0); + brw_finish_drawing(ctx); +} + void brw_draw_indirect_prims(struct gl_context *ctx, GLuint mode, @@ -1274,7 +1309,7 @@ brw_draw_indirect_prims(struct gl_context *ctx, brw->draw.draw_indirect_data = indirect_data; - brw_draw_prims(ctx, prim, draw_count, ib, false, 0, ~0, 0, 0, NULL, 0); + brw_draw_prims(ctx, prim, draw_count, ib, false, 0, ~0, 0, 0); brw->draw.draw_indirect_data = NULL; free(prim); @@ -1286,6 +1321,7 @@ brw_init_draw_functions(struct dd_function_table *functions) /* Register our drawing function: */ functions->Draw = brw_draw_prims; + functions->DrawTransformFeedback = brw_draw_transform_feedback; functions->DrawIndirect = brw_draw_indirect_prims; } diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h index c2e7d26f3ca..9331d5468d2 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.h +++ b/src/mesa/drivers/dri/i965/brw_draw.h @@ -52,9 +52,7 @@ void brw_draw_prims(struct gl_context *ctx, GLuint min_index, GLuint max_index, GLuint num_instances, - GLuint base_instance, - struct gl_transform_feedback_object *unused_tfb_object, - unsigned stream); + GLuint base_instance); void brw_init_draw_functions(struct dd_function_table *functions); void brw_draw_init( struct brw_context *brw ); diff --git a/src/mesa/drivers/dri/i965/brw_primitive_restart.c b/src/mesa/drivers/dri/i965/brw_primitive_restart.c index e73f32720e1..a571123bcef 100644 --- a/src/mesa/drivers/dri/i965/brw_primitive_restart.c +++ b/src/mesa/drivers/dri/i965/brw_primitive_restart.c @@ -163,7 +163,7 @@ brw_handle_primitive_restart(struct gl_context *ctx, */ brw->prim_restart.enable_cut_index = true; brw_draw_prims(ctx, prims, nr_prims, ib, GL_FALSE, -1, -1, - num_instances, base_instance, NULL, 0); + num_instances, base_instance); brw->prim_restart.enable_cut_index = false; } else { /* Not all the primitive draw modes are supported by the cut index, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c index e6274d45cf4..9248d097119 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c @@ -546,9 +546,7 @@ TAG(vbo_draw)(struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index, - GLuint num_instances, GLuint base_instance, - UNUSED struct gl_transform_feedback_object *tfb_vertcount, - UNUSED unsigned stream) + GLuint num_instances, GLuint base_instance) { /* Borrow and update the inputs list from the tnl context */ const struct tnl_vertex_array* arrays = _tnl_bind_inputs(ctx); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 506a18240cc..ae30f2b1423 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -544,23 +544,13 @@ struct dd_function_table { * \param max_index highest vertex index used * \param num_instances instance count from ARB_draw_instanced * \param base_instance base instance from ARB_base_instance - * \param tfb_vertcount if non-null, indicates which transform feedback - * object has the vertex count. - * \param tfb_stream If called via DrawTransformFeedbackStream, specifies - * the vertex stream buffer from which to get the vertex - * count. - * \param indirect If any prims are indirect, this specifies the buffer - * to find the "DrawArrays/ElementsIndirectCommand" data. - * This may be deprecated in the future */ void (*Draw)(struct gl_context *ctx, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index, - GLuint num_instances, GLuint base_instance, - struct gl_transform_feedback_object *tfb_vertcount, - unsigned tfb_stream); + GLuint num_instances, GLuint base_instance); /** @@ -587,6 +577,21 @@ struct dd_function_table { struct gl_buffer_object *indirect_draw_count_buffer, GLsizeiptr indirect_draw_count_offset, const struct _mesa_index_buffer *ib); + + /** + * Driver implementation of glDrawTransformFeedback. + * + * \param mode Primitive type + * \param num_instances instance count from ARB_draw_instanced + * \param stream If called via DrawTransformFeedbackStream, specifies + * the vertex stream buffer from which to get the vertex + * count. + * \param tfb_vertcount if non-null, indicates which transform feedback + * object has the vertex count. + */ + void (*DrawTransformFeedback)(struct gl_context *ctx, GLenum mode, + unsigned num_instances, unsigned stream, + struct gl_transform_feedback_object *tfb_vertcount); /*@}*/ diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index 74a619e3022..0d7258eaa3b 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -366,7 +366,7 @@ _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_TRUE, start, start + count - 1, - numInstances, baseInstance, NULL, 0); + numInstances, baseInstance); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); @@ -729,8 +729,7 @@ _mesa_exec_MultiDrawArrays(GLenum mode, const GLint *first, prim[i].basevertex = 0; } - ctx->Driver.Draw(ctx, prim, primcount, NULL, GL_FALSE, 0, 0, 1, 0, - NULL, 0); + ctx->Driver.Draw(ctx, prim, primcount, NULL, GL_FALSE, 0, 0, 1, 0); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) _mesa_flush(ctx); @@ -890,7 +889,7 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, ctx->Driver.Draw(ctx, &prim, 1, &ib, index_bounds_valid, start, end, - numInstances, baseInstance, NULL, 0); + numInstances, baseInstance); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); @@ -1312,7 +1311,7 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } ctx->Driver.Draw(ctx, prim, primcount, &ib, - false, 0, ~0, 1, 0, NULL, 0); + false, 0, ~0, 1, 0); FREE_PRIMS(prim, primcount); } else { @@ -1337,7 +1336,7 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, else prim.basevertex = 0; - ctx->Driver.Draw(ctx, &prim, 1, &ib, false, 0, ~0, 1, 0, NULL, 0); + ctx->Driver.Draw(ctx, &prim, 1, &ib, false, 0, ~0, 1, 0); } } @@ -1412,8 +1411,6 @@ _mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode, struct gl_transform_feedback_object *obj, GLuint stream, GLuint numInstances) { - struct _mesa_prim prim; - FLUSH_FOR_DRAW(ctx); _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); @@ -1440,18 +1437,11 @@ _mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode, if (skip_validated_draw(ctx)) return; - /* init most fields to zero */ - memset(&prim, 0, sizeof(prim)); - prim.begin = 1; - prim.end = 1; - prim.mode = mode; - /* Maybe we should do some primitive splitting for primitive restart * (like in DrawArrays), but we have no way to know how many vertices * will be rendered. */ - ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, numInstances, 0, - obj, stream); + ctx->Driver.DrawTransformFeedback(ctx, mode, numInstances, stream, obj); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index c3684176071..691d5995109 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -260,8 +260,7 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4]) _mesa_set_draw_vao(ctx, rs->VAO, VERT_BIT_POS); /* Draw the point. */ - st_feedback_draw_vbo(ctx, &rs->prim, 1, NULL, GL_TRUE, 0, 1, 1, 0, - NULL, 0); + st_feedback_draw_vbo(ctx, &rs->prim, 1, NULL, GL_TRUE, 0, 1, 1, 0); /* restore draw's rasterization stage depending on rendermode */ if (ctx->RenderMode == GL_FEEDBACK) { diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 996d985510c..1745a8d1948 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -164,9 +164,7 @@ st_draw_vbo(struct gl_context *ctx, GLuint min_index, GLuint max_index, GLuint num_instances, - GLuint base_instance, - struct gl_transform_feedback_object *tfb_vertcount, - unsigned stream) + GLuint base_instance) { struct st_context *st = st_context(ctx); struct pipe_draw_info info; @@ -221,13 +219,6 @@ st_draw_vbo(struct gl_context *ctx, else { info.index_size = 0; info.has_user_indices = false; - - /* Transform feedback drawing is always non-indexed. */ - /* Set info.count_from_stream_output. */ - if (tfb_vertcount) { - if (!st_transform_feedback_draw_init(tfb_vertcount, stream, &info)) - return; - } } /* do actual drawing */ @@ -235,7 +226,7 @@ st_draw_vbo(struct gl_context *ctx, info.count = prims[i].count; /* Skip no-op draw calls. */ - if (!info.count && !tfb_vertcount) + if (!info.count) continue; info.mode = translate_prim(ctx, prims[i].mode); @@ -332,12 +323,42 @@ st_indirect_draw_vbo(struct gl_context *ctx, } } +static void +st_draw_transform_feedback(struct gl_context *ctx, GLenum mode, + unsigned num_instances, unsigned stream, + struct gl_transform_feedback_object *tfb_vertcount) +{ + struct st_context *st = st_context(ctx); + struct pipe_draw_info info; + + prepare_draw(st, ctx); + + util_draw_init_info(&info); + info.start = 0; /* index offset / index size */ + info.max_index = ~0u; /* so that u_vbuf can tell that it's unknown */ + info.mode = translate_prim(ctx, mode); + info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; + info.instance_count = num_instances; + + if (ST_DEBUG & DEBUG_DRAW) { + debug_printf("st/draw transform feedback: mode %s\n", + u_prim_name(info.mode)); + } + + /* Transform feedback drawing is always non-indexed. */ + /* Set info.count_from_stream_output. */ + if (!st_transform_feedback_draw_init(tfb_vertcount, stream, &info)) + return; + + cso_draw_vbo(st->cso_context, &info); +} void st_init_draw_functions(struct dd_function_table *functions) { functions->Draw = st_draw_vbo; functions->DrawIndirect = st_indirect_draw_vbo; + functions->DrawTransformFeedback = st_draw_transform_feedback; } diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h index d04277a2325..c87727d28f8 100644 --- a/src/mesa/state_tracker/st_draw.h +++ b/src/mesa/state_tracker/st_draw.h @@ -56,9 +56,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, GLuint min_index, GLuint max_index, GLuint num_instances, - GLuint base_instance, - struct gl_transform_feedback_object *tfb_vertcount, - unsigned stream); + GLuint base_instance); /** * When drawing with VBOs, the addresses specified with diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index a2abc9b4b33..9129162554c 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -101,9 +101,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, GLuint min_index, GLuint max_index, GLuint num_instances, - GLuint base_instance, - struct gl_transform_feedback_object *tfb_vertcount, - unsigned stream) + GLuint base_instance) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; @@ -126,7 +124,6 @@ st_feedback_draw_vbo(struct gl_context *ctx, 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); diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index e8b45af081c..cf23c01ba6d 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -631,9 +631,7 @@ _tnl_draw(struct gl_context *ctx, const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index, - GLuint num_instances, GLuint base_instance, - UNUSED struct gl_transform_feedback_object *tfb_vertcount, - UNUSED unsigned stream) + GLuint num_instances, GLuint base_instance) { /* Update TNLcontext::draw_arrays and return that pointer. */ diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h index 58503016a9b..5c87ab6a4b7 100644 --- a/src/mesa/tnl/tnl.h +++ b/src/mesa/tnl/tnl.h @@ -115,8 +115,7 @@ _tnl_draw(struct gl_context *ctx, const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index, - GLuint num_instances, GLuint base_instance, - struct gl_transform_feedback_object *tfb_vertcount, unsigned stream); + GLuint num_instances, GLuint base_instance); extern void _tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]); diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index b31c1f90156..ae14478c260 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -325,8 +325,7 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec) exec->vtx.vert_count); ctx->Driver.Draw(ctx, exec->vtx.prim, exec->vtx.prim_count, - NULL, GL_TRUE, 0, exec->vtx.vert_count - 1, 1, 0, - NULL, 0); + NULL, GL_TRUE, 0, exec->vtx.vert_count - 1, 1, 0); /* Get new storage -- unless asked not to. */ if (!persistent_mapping) diff --git a/src/mesa/vbo/vbo_primitive_restart.c b/src/mesa/vbo/vbo_primitive_restart.c index ff5df0c2e79..8dce7d67366 100644 --- a/src/mesa/vbo/vbo_primitive_restart.c +++ b/src/mesa/vbo/vbo_primitive_restart.c @@ -254,13 +254,11 @@ vbo_sw_primitive_restart(struct gl_context *ctx, (temp_prim.count == sub_prim->count)) { ctx->Driver.Draw(ctx, &temp_prim, 1, ib, GL_TRUE, sub_prim->min_index, sub_prim->max_index, - num_instances, base_instance, - NULL, 0); + num_instances, base_instance); } else { ctx->Driver.Draw(ctx, &temp_prim, 1, ib, GL_FALSE, -1, -1, - num_instances, base_instance, - NULL, 0); + num_instances, base_instance); } } if (sub_end_index >= end_index) { diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 5d0c6c54ed3..8df082fb0ab 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -213,7 +213,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) GLuint min_index = _vbo_save_get_min_index(node); GLuint max_index = _vbo_save_get_max_index(node); ctx->Driver.Draw(ctx, node->prims, node->prim_count, NULL, GL_TRUE, - min_index, max_index, 1, 0, NULL, 0); + min_index, max_index, 1, 0); } } |