Commit 238ee7b8 authored by Marek Olšák's avatar Marek Olšák Committed by Marge Bot

mesa: add Driver.DrawTransformFeedback

to remove some overhead from Driver.Draw.
Reviewed-by: Pierre-Eric Pelloux-Prayer's avatarPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <!7441>
parent c77409a8
......@@ -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;
......
......@@ -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;
}
......
......@@ -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 );
......
......@@ -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,
......
......@@ -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);
......
......@@ -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);
/*@}*/
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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);
......
......@@ -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.
*/
......
......@@ -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]);
......
......@@ -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)
......
......@@ -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) {
......
......@@ -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);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment