summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2020-10-30 09:50:50 -0400
committerMarge Bot <eric+marge@anholt.net>2020-11-18 01:41:24 +0000
commit238ee7b801cf3f861871d7b7849c25e180da5894 (patch)
tree93ac80c1c32431c66991778cfd637163876c8239 /src/mesa
parentc77409a87e46a526cd2256439188deaf0ee2d4e2 (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.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c52
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_primitive_restart.c2
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c4
-rw-r--r--src/mesa/main/dd.h27
-rw-r--r--src/mesa/main/draw.c22
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c3
-rw-r--r--src/mesa/state_tracker/st_draw.c43
-rw-r--r--src/mesa/state_tracker/st_draw.h4
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c5
-rw-r--r--src/mesa/tnl/t_draw.c4
-rw-r--r--src/mesa/tnl/tnl.h3
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c3
-rw-r--r--src/mesa/vbo/vbo_primitive_restart.c6
-rw-r--r--src/mesa/vbo/vbo_save_draw.c2
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);
}
}