From: Mathias Fröhlich <mathias.froehl...@web.de>
Marek, you mean with the below patch as the 9-th change in the series? I would like to keep that change seprarate from #3 since patch #3 just moves the already existing impelentation to the driver_functions level using the exactly identical implementation except calling into struct driver_functions instead of the vbo module draw function. Also I do not want to call just blindly into alloca with possibly large counts. So, the implementation uses an upper bound when to use malloc instead of alloca. Ok, with that? best Mathias Avoid using malloc in the draw path of mesa. Since the draw_count is a user api input, fall back to malloc if the amount of consumed stack space may get too high. Signed-off-by: Mathias Fröhlich <mathias.froehl...@web.de> --- src/mesa/vbo/vbo_context.c | 70 +++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index b8c28ceffb..06b8f820ee 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -233,25 +233,17 @@ _vbo_DestroyContext(struct gl_context *ctx) } -void -_vbo_draw_indirect(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_draw_count_buffer, - GLsizeiptr indirect_draw_count_offset, - const struct _mesa_index_buffer *ib) +static void +draw_indirect(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_draw_count_buffer, + GLsizeiptr indirect_draw_count_offset, + const struct _mesa_index_buffer *ib, + struct _mesa_prim *space) { - struct _mesa_prim *prim; - - prim = calloc(draw_count, sizeof(*prim)); - if (prim == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDraw%sIndirect%s", - (draw_count > 1) ? "Multi" : "", - ib ? "Elements" : "Arrays", - indirect_data ? "CountARB" : ""); - return; - } + struct _mesa_prim *prim = space; prim[0].begin = 1; prim[draw_count - 1].end = 1; @@ -266,10 +258,42 @@ _vbo_draw_indirect(struct gl_context *ctx, GLuint mode, /* This should always be true at this time */ assert(indirect_data == ctx->DrawIndirectBuffer); - ctx->Driver.Draw(ctx, prim, draw_count, - ib, false, 0, ~0, - NULL, 0, - indirect_data); + ctx->Driver.Draw(ctx, prim, draw_count, ib, false, 0u, ~0u, + NULL, 0, indirect_data); +} + - free(prim); +void +_vbo_draw_indirect(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_draw_count_buffer, + GLsizeiptr indirect_draw_count_offset, + const struct _mesa_index_buffer *ib) +{ + /* Use alloca for the prim space if we are somehow in bounds. */ + if (draw_count*sizeof(struct _mesa_prim) < 1024) { + struct _mesa_prim *space = alloca(draw_count*sizeof(struct _mesa_prim)); + memset(space, 0, draw_count*sizeof(struct _mesa_prim)); + + draw_indirect(ctx, mode, indirect_data, indirect_offset, draw_count, + stride, indirect_draw_count_buffer, + indirect_draw_count_offset, ib, space); + } else { + struct _mesa_prim *space = calloc(draw_count, sizeof(struct _mesa_prim)); + if (space == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDraw%sIndirect%s", + (draw_count > 1) ? "Multi" : "", + ib ? "Elements" : "Arrays", + indirect_data ? "CountARB" : ""); + return; + } + + draw_indirect(ctx, mode, indirect_data, indirect_offset, draw_count, + stride, indirect_draw_count_buffer, + indirect_draw_count_offset, ib, space); + + free(space); + } } -- 2.14.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev