[adding Ian and Ken, who may or may not be interested] I'd like to push this out in the next couple of days (along with my ARB_indirect_parameters series), but I'd really like to get an ack from someone on the Intel team that such an interface would be acceptable to them. You can see the full series at https://github.com/imirkin/mesa/commits/tmp4 (there have been a few very minor updates).
Thanks, -ilia On Fri, Jan 1, 2016 at 1:20 PM, Ilia Mirkin <imir...@alum.mit.edu> wrote: > Thanks! I'd also like to get an ack from someone on the Intel crew as > well to make sure this interface will work for them as well. > > On Fri, Jan 1, 2016 at 6:49 AM, Marek Olšák <mar...@gmail.com> wrote: >> Acked-by: Marek Olšák <marek.ol...@amd.com> >> >> On Thu, Dec 31, 2015 at 8:55 PM, Ilia Mirkin <imir...@alum.mit.edu> wrote: >>> This is optional for now in the transition period, but optimally all >>> backends that support indirect draws would switch over to it and we can >>> remove the support for indirect in the "regular" draw function. >>> >>> This should allow a backend to properly support ARB_multi_draw_indirect >>> and ARB_indirect_parameters. >>> >>> Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> >>> --- >>> src/mesa/vbo/vbo.h | 15 ++++ >>> src/mesa/vbo/vbo_context.c | 7 ++ >>> src/mesa/vbo/vbo_context.h | 6 ++ >>> src/mesa/vbo/vbo_exec_array.c | 166 >>> +++++++++++++++++++++++++----------------- >>> 4 files changed, 127 insertions(+), 67 deletions(-) >>> >>> diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h >>> index cef3b8c..0c63bf3 100644 >>> --- a/src/mesa/vbo/vbo.h >>> +++ b/src/mesa/vbo/vbo.h >>> @@ -110,6 +110,18 @@ typedef void (*vbo_draw_func)( struct gl_context *ctx, >>> struct gl_buffer_object *indirect); >>> >>> >>> +typedef void (*vbo_indirect_draw_func)( >>> + 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); >>> + >>> + >>> >>> >>> /* Utility function to cope with various constraints on tnl modules or >>> @@ -179,6 +191,9 @@ void vbo_always_unmap_buffers(struct gl_context *ctx); >>> >>> void vbo_set_draw_func(struct gl_context *ctx, vbo_draw_func func); >>> >>> +void vbo_set_indirect_draw_func(struct gl_context *ctx, >>> + vbo_indirect_draw_func func); >>> + >>> void vbo_check_buffers_are_unmapped(struct gl_context *ctx); >>> >>> void vbo_bind_arrays(struct gl_context *ctx); >>> diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c >>> index 5e1a760..8a196e7 100644 >>> --- a/src/mesa/vbo/vbo_context.c >>> +++ b/src/mesa/vbo/vbo_context.c >>> @@ -223,3 +223,10 @@ void vbo_set_draw_func(struct gl_context *ctx, >>> vbo_draw_func func) >>> vbo->draw_prims = func; >>> } >>> >>> + >>> +void vbo_set_indirect_draw_func(struct gl_context *ctx, >>> + vbo_indirect_draw_func func) >>> +{ >>> + struct vbo_context *vbo = vbo_context(ctx); >>> + vbo->draw_indirect_prims = func; >>> +} >>> diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h >>> index 6293a8b..11f9b17 100644 >>> --- a/src/mesa/vbo/vbo_context.h >>> +++ b/src/mesa/vbo/vbo_context.h >>> @@ -76,6 +76,12 @@ struct vbo_context { >>> * is responsible for initiating any fallback actions required: >>> */ >>> vbo_draw_func draw_prims; >>> + >>> + /* Optional callback for indirect draws. This allows multidraws to not >>> be >>> + * broken up, as well as for the actual count to be passed in as a >>> separate >>> + * indirect parameter. >>> + */ >>> + vbo_indirect_draw_func draw_indirect_prims; >>> }; >>> >>> >>> diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c >>> index 502b288..3da2d19 100644 >>> --- a/src/mesa/vbo/vbo_exec_array.c >>> +++ b/src/mesa/vbo/vbo_exec_array.c >>> @@ -1550,23 +1550,30 @@ vbo_validated_drawarraysindirect(struct gl_context >>> *ctx, >>> >>> vbo_bind_arrays(ctx); >>> >>> - memset(prim, 0, sizeof(prim)); >>> - prim[0].begin = 1; >>> - prim[0].end = 1; >>> - prim[0].mode = mode; >>> - prim[0].is_indirect = 1; >>> - prim[0].indirect_offset = (GLsizeiptr)indirect; >>> - >>> - /* NOTE: We do NOT want to handle primitive restart here, nor perform >>> any >>> - * other checks that require knowledge of the values in the command >>> buffer. >>> - * That would defeat the whole purpose of this function. >>> - */ >>> + if (vbo->draw_indirect_prims) { >>> + vbo->draw_indirect_prims(ctx, mode, >>> + ctx->DrawIndirectBuffer, >>> (GLsizeiptr)indirect, >>> + 1 /* primcount */, 0 /* stride */, >>> + NULL, 0, NULL); >>> + } else { >>> + memset(prim, 0, sizeof(prim)); >>> + prim[0].begin = 1; >>> + prim[0].end = 1; >>> + prim[0].mode = mode; >>> + prim[0].is_indirect = 1; >>> + prim[0].indirect_offset = (GLsizeiptr)indirect; >>> + >>> + /* NOTE: We do NOT want to handle primitive restart here, nor perform >>> + * any other checks that require knowledge of the values in the >>> command >>> + * buffer. That would defeat the whole purpose of this function. >>> + */ >>> >>> - check_buffers_are_unmapped(exec->array.inputs); >>> - vbo->draw_prims(ctx, prim, 1, >>> - NULL, GL_TRUE, 0, ~0, >>> - NULL, 0, >>> - ctx->DrawIndirectBuffer); >>> + check_buffers_are_unmapped(exec->array.inputs); >>> + vbo->draw_prims(ctx, prim, 1, >>> + NULL, GL_TRUE, 0, ~0, >>> + NULL, 0, >>> + ctx->DrawIndirectBuffer); >>> + } >>> >>> if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) >>> _mesa_flush(ctx); >>> @@ -1586,30 +1593,38 @@ vbo_validated_multidrawarraysindirect(struct >>> gl_context *ctx, >>> >>> if (primcount == 0) >>> return; >>> - prim = calloc(primcount, sizeof(*prim)); >>> - if (prim == NULL) { >>> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawArraysIndirect"); >>> - return; >>> - } >>> >>> vbo_bind_arrays(ctx); >>> >>> - prim[0].begin = 1; >>> - prim[primcount - 1].end = 1; >>> - for (i = 0; i < primcount; ++i, offset += stride) { >>> - prim[i].mode = mode; >>> - prim[i].indirect_offset = offset; >>> - prim[i].is_indirect = 1; >>> - prim[i].draw_id = i; >>> - } >>> + if (vbo->draw_indirect_prims) { >>> + vbo->draw_indirect_prims(ctx, mode, >>> + ctx->DrawIndirectBuffer, offset, >>> + primcount, stride, >>> + NULL, 0, NULL); >>> + } else { >>> + prim = calloc(primcount, sizeof(*prim)); >>> + if (prim == NULL) { >>> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawArraysIndirect"); >>> + return; >>> + } >>> >>> - check_buffers_are_unmapped(exec->array.inputs); >>> - vbo->draw_prims(ctx, prim, primcount, >>> - NULL, GL_TRUE, 0, ~0, >>> - NULL, 0, >>> - ctx->DrawIndirectBuffer); >>> + prim[0].begin = 1; >>> + prim[primcount - 1].end = 1; >>> + for (i = 0; i < primcount; ++i, offset += stride) { >>> + prim[i].mode = mode; >>> + prim[i].indirect_offset = offset; >>> + prim[i].is_indirect = 1; >>> + prim[i].draw_id = i; >>> + } >>> >>> - free(prim); >>> + check_buffers_are_unmapped(exec->array.inputs); >>> + vbo->draw_prims(ctx, prim, primcount, >>> + NULL, GL_TRUE, 0, ~0, >>> + NULL, 0, >>> + ctx->DrawIndirectBuffer); >>> + >>> + free(prim); >>> + } >>> >>> if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) >>> _mesa_flush(ctx); >>> @@ -1632,19 +1647,27 @@ vbo_validated_drawelementsindirect(struct >>> gl_context *ctx, >>> ib.obj = ctx->Array.VAO->IndexBufferObj; >>> ib.ptr = NULL; >>> >>> - memset(prim, 0, sizeof(prim)); >>> - prim[0].begin = 1; >>> - prim[0].end = 1; >>> - prim[0].mode = mode; >>> - prim[0].indexed = 1; >>> - prim[0].indirect_offset = (GLsizeiptr)indirect; >>> - prim[0].is_indirect = 1; >>> + if (vbo->draw_indirect_prims) { >>> + vbo->draw_indirect_prims(ctx, mode, >>> + ctx->DrawIndirectBuffer, >>> (GLsizeiptr)indirect, >>> + 1 /* primcount */, 0 /* stride */, >>> + NULL, 0, >>> + &ib); >>> + } else { >>> + memset(prim, 0, sizeof(prim)); >>> + prim[0].begin = 1; >>> + prim[0].end = 1; >>> + prim[0].mode = mode; >>> + prim[0].indexed = 1; >>> + prim[0].indirect_offset = (GLsizeiptr)indirect; >>> + prim[0].is_indirect = 1; >>> >>> - check_buffers_are_unmapped(exec->array.inputs); >>> - vbo->draw_prims(ctx, prim, 1, >>> - &ib, GL_TRUE, 0, ~0, >>> - NULL, 0, >>> - ctx->DrawIndirectBuffer); >>> + check_buffers_are_unmapped(exec->array.inputs); >>> + vbo->draw_prims(ctx, prim, 1, >>> + &ib, GL_TRUE, 0, ~0, >>> + NULL, 0, >>> + ctx->DrawIndirectBuffer); >>> + } >>> >>> if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) >>> _mesa_flush(ctx); >>> @@ -1665,11 +1688,6 @@ vbo_validated_multidrawelementsindirect(struct >>> gl_context *ctx, >>> >>> if (primcount == 0) >>> return; >>> - prim = calloc(primcount, sizeof(*prim)); >>> - if (prim == NULL) { >>> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElementsIndirect"); >>> - return; >>> - } >>> >>> vbo_bind_arrays(ctx); >>> >>> @@ -1680,23 +1698,37 @@ vbo_validated_multidrawelementsindirect(struct >>> gl_context *ctx, >>> ib.obj = ctx->Array.VAO->IndexBufferObj; >>> ib.ptr = NULL; >>> >>> - prim[0].begin = 1; >>> - prim[primcount - 1].end = 1; >>> - for (i = 0; i < primcount; ++i, offset += stride) { >>> - prim[i].mode = mode; >>> - prim[i].indexed = 1; >>> - prim[i].indirect_offset = offset; >>> - prim[i].is_indirect = 1; >>> - prim[i].draw_id = i; >>> - } >>> + if (vbo->draw_indirect_prims) { >>> + vbo->draw_indirect_prims(ctx, mode, >>> + ctx->DrawIndirectBuffer, offset, >>> + primcount, stride, >>> + NULL, 0, >>> + &ib); >>> + } else { >>> + prim = calloc(primcount, sizeof(*prim)); >>> + if (prim == NULL) { >>> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElementsIndirect"); >>> + return; >>> + } >>> >>> - check_buffers_are_unmapped(exec->array.inputs); >>> - vbo->draw_prims(ctx, prim, primcount, >>> - &ib, GL_TRUE, 0, ~0, >>> - NULL, 0, >>> - ctx->DrawIndirectBuffer); >>> + prim[0].begin = 1; >>> + prim[primcount - 1].end = 1; >>> + for (i = 0; i < primcount; ++i, offset += stride) { >>> + prim[i].mode = mode; >>> + prim[i].indexed = 1; >>> + prim[i].indirect_offset = offset; >>> + prim[i].is_indirect = 1; >>> + prim[i].draw_id = i; >>> + } >>> >>> - free(prim); >>> + check_buffers_are_unmapped(exec->array.inputs); >>> + vbo->draw_prims(ctx, prim, primcount, >>> + &ib, GL_TRUE, 0, ~0, >>> + NULL, 0, >>> + ctx->DrawIndirectBuffer); >>> + >>> + free(prim); >>> + } >>> >>> if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) >>> _mesa_flush(ctx); >>> -- >>> 2.4.10 >>> >>> _______________________________________________ >>> mesa-dev mailing list >>> mesa-dev@lists.freedesktop.org >>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev