mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-12 19:50:33 +01:00
vbo: Flesh out implementation of indirect draws
Based on part of Patch 2 of Christoph Bumiller's ARB_draw_indirect series. Signed-off-by: Chris Forbes <chrisf@ijw.co.nz> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
parent
aadbb0f275
commit
5a798e73b5
1 changed files with 218 additions and 0 deletions
|
|
@ -1569,6 +1569,166 @@ 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].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,
|
||||
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(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;
|
||||
}
|
||||
|
||||
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;
|
||||
prim[0].is_indirect = 1;
|
||||
|
||||
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(primcount, sizeof(*prim));
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
@ -1576,12 +1736,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
|
||||
|
|
@ -1589,6 +1770,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
|
||||
|
|
@ -1596,6 +1795,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue