I've inherited a fair amount of sillyness from the original patches... sorry, I'll clean that up.
On Wed, Nov 20, 2013 at 9:15 AM, Ian Romanick <i...@freedesktop.org> wrote: > With the issues below fixed, > > Reviewed-by: Ian Romanick <ian.d.roman...@intel.com> > > On 11/09/2013 01:02 AM, Chris Forbes wrote: >> Based on part of Patch 2 of Christoph Bumiller's ARB_draw_indirect series. >> >> Signed-off-by: Chris Forbes <chr...@ijw.co.nz> >> --- >> src/mesa/vbo/vbo_exec_array.c | 216 >> ++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 216 insertions(+) >> >> diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c >> index 4ea10ee..1c6b8b3 100644 >> --- a/src/mesa/vbo/vbo_exec_array.c >> +++ b/src/mesa/vbo/vbo_exec_array.c >> @@ -1564,6 +1564,164 @@ vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum >> mode, GLuint name, >> vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount); >> } >> >> +static void >> +vbo_validated_drawarraysindirect(struct gl_context *ctx, >> + GLenum mode, const GLvoid *indirect) >> +{ >> + struct vbo_context *vbo = vbo_context(ctx); >> + struct vbo_exec_context *exec = &vbo->exec; >> + struct _mesa_prim prim[1]; >> + >> + vbo_bind_arrays(ctx); >> + >> + memset(prim, 0, sizeof(prim)); >> + prim[0].begin = 1; >> + prim[0].end = 1; >> + prim[0].mode = mode; >> + 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 deafeat 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, >> + ctx->DrawIndirectBuffer); >> + >> + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) >> + _mesa_flush(ctx); >> +} >> + >> +static void >> +vbo_validated_multidrawarraysindirect(struct gl_context *ctx, >> + GLenum mode, >> + const GLvoid *indirect, >> + GLsizei primcount, GLsizei stride) >> +{ >> + struct vbo_context *vbo = vbo_context(ctx); >> + struct vbo_exec_context *exec = &vbo->exec; >> + struct _mesa_prim *prim; >> + GLsizei i; >> + GLsizeiptr offset = (GLsizeiptr)indirect; >> + >> + if (primcount == 0) >> + return; >> + prim = calloc(1, primcount * sizeof(*prim)); > > prim = calloc(primcount, sizeof(*prim)); > > because primcount could be 0x7fffffff, and that would overflow on 32-bit > leading to sadness. calloc will do the right thing. > >> + if (prim == NULL) { >> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawArraysIndirect"); >> + return; >> + } >> + >> + vbo_bind_arrays(ctx); >> + >> + memset(prim, 0, primcount * sizeof(*prim)); > > But you used calloc. :( > >> + 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; >> + } >> + >> + check_buffers_are_unmapped(exec->array.inputs); >> + vbo->draw_prims(ctx, prim, primcount, >> + NULL, GL_TRUE, 0, ~0, >> + NULL, >> + ctx->DrawIndirectBuffer); >> + >> + free(prim); >> + >> + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) >> + _mesa_flush(ctx); >> +} >> + >> +static void >> +vbo_validated_drawelementsindirect(struct gl_context *ctx, >> + GLenum mode, GLenum type, >> + const GLvoid *indirect) >> +{ >> + struct vbo_context *vbo = vbo_context(ctx); >> + struct vbo_exec_context *exec = &vbo->exec; >> + struct _mesa_index_buffer ib; >> + struct _mesa_prim prim[1]; >> + >> + vbo_bind_arrays(ctx); >> + >> + ib.count = 0; /* unknown */ >> + ib.type = type; >> + ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; >> + 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; >> + >> + check_buffers_are_unmapped(exec->array.inputs); >> + vbo->draw_prims(ctx, prim, 1, >> + &ib, GL_TRUE, 0, ~0, >> + NULL, >> + ctx->DrawIndirectBuffer); >> + >> + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) >> + _mesa_flush(ctx); >> +} >> + >> +static void >> +vbo_validated_multidrawelementsindirect(struct gl_context *ctx, >> + GLenum mode, GLenum type, >> + const GLvoid *indirect, >> + GLsizei primcount, GLsizei stride) >> +{ >> + struct vbo_context *vbo = vbo_context(ctx); >> + struct vbo_exec_context *exec = &vbo->exec; >> + struct _mesa_index_buffer ib; >> + struct _mesa_prim *prim; >> + GLsizei i; >> + GLsizeiptr offset = (GLsizeiptr)indirect; >> + >> + if (primcount == 0) >> + return; >> + prim = calloc(1, primcount * sizeof(*prim)); > > Same here. > >> + if (prim == NULL) { >> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElementsIndirect"); >> + return; >> + } >> + >> + vbo_bind_arrays(ctx); >> + >> + /* NOTE: ElementArrayBufferObj is guaranteed to be a VBO. */ >> + >> + ib.count = 0; /* unknown */ >> + ib.type = type; >> + ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; >> + ib.ptr = NULL; >> + >> + memset(prim, 0, primcount * sizeof(*prim)); > > Same here. > >> + 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; >> + } >> + >> + check_buffers_are_unmapped(exec->array.inputs); >> + vbo->draw_prims(ctx, prim, primcount, >> + &ib, GL_TRUE, 0, ~0, >> + NULL, >> + ctx->DrawIndirectBuffer); >> + >> + free(prim); >> + >> + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) >> + _mesa_flush(ctx); >> +} >> + >> /** >> * Like [Multi]DrawArrays/Elements, but they take most arguments from >> * a buffer object. >> @@ -1571,12 +1729,33 @@ vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum >> mode, GLuint name, >> static void GLAPIENTRY >> vbo_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) >> { >> + GET_CURRENT_CONTEXT(ctx); >> + >> + if (MESA_VERBOSE & VERBOSE_DRAW) >> + _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n", >> + _mesa_lookup_enum_by_nr(mode), indirect); >> + >> + if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect)) >> + return; >> + >> + vbo_validated_drawarraysindirect(ctx, mode, indirect); >> } >> >> static void GLAPIENTRY >> vbo_exec_DrawElementsIndirect(GLenum mode, GLenum type, >> const GLvoid *indirect) >> { >> + GET_CURRENT_CONTEXT(ctx); >> + >> + if (MESA_VERBOSE & VERBOSE_DRAW) >> + _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n", >> + _mesa_lookup_enum_by_nr(mode), >> + _mesa_lookup_enum_by_nr(type), indirect); >> + >> + if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect)) >> + return; >> + >> + vbo_validated_drawelementsindirect(ctx, mode, type, indirect); >> } >> >> static void GLAPIENTRY >> @@ -1584,6 +1763,24 @@ vbo_exec_MultiDrawArraysIndirect(GLenum mode, >> const GLvoid *indirect, >> GLsizei primcount, GLsizei stride) >> { >> + GET_CURRENT_CONTEXT(ctx); >> + >> + if (MESA_VERBOSE & VERBOSE_DRAW) >> + _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n", >> + _mesa_lookup_enum_by_nr(mode), indirect, primcount, >> stride); >> + >> + /* If <stride> is zero, the array elements are treated as tightly >> packed. */ >> + if (stride == 0) >> + stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ >> + >> + if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, >> + indirect, >> + primcount, stride)) >> + return; >> + >> + vbo_validated_multidrawarraysindirect(ctx, mode, >> + indirect, >> + primcount, stride); >> } >> >> static void GLAPIENTRY >> @@ -1591,6 +1788,25 @@ vbo_exec_MultiDrawElementsIndirect(GLenum mode, >> GLenum type, >> const GLvoid *indirect, >> GLsizei primcount, GLsizei stride) >> { >> + GET_CURRENT_CONTEXT(ctx); >> + >> + if (MESA_VERBOSE & VERBOSE_DRAW) >> + _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n", >> + _mesa_lookup_enum_by_nr(mode), >> + _mesa_lookup_enum_by_nr(type), indirect, primcount, >> stride); >> + >> + /* If <stride> is zero, the array elements are treated as tightly >> packed. */ >> + if (stride == 0) >> + stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */ >> + >> + if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, >> + indirect, >> + primcount, stride)) >> + return; >> + >> + vbo_validated_multidrawelementsindirect(ctx, mode, type, >> + indirect, >> + primcount, stride); >> } >> >> /** >> > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev