mesa: add compat profile support for ARB_multi_draw_indirect

v2: add missing ARB_base_instance support

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
Timothy Arceri 2018-06-25 10:32:58 +10:00
parent 103b8f11d6
commit d2caa37741
2 changed files with 76 additions and 3 deletions

View file

@ -88,7 +88,7 @@ EXT(ARB_invalidate_subdata , dummy_true
EXT(ARB_map_buffer_alignment , dummy_true , GLL, GLC, x , x , 2011)
EXT(ARB_map_buffer_range , ARB_map_buffer_range , GLL, GLC, x , x , 2008)
EXT(ARB_multi_bind , dummy_true , GLL, GLC, x , x , 2013)
EXT(ARB_multi_draw_indirect , ARB_draw_indirect , x , GLC, x , x , 2012)
EXT(ARB_multi_draw_indirect , ARB_draw_indirect , GLL, GLC, x , x , 2012)
EXT(ARB_multisample , dummy_true , GLL, x , x , x , 1994)
EXT(ARB_multitexture , dummy_true , GLL, x , x , x , 1998)
EXT(ARB_occlusion_query , ARB_occlusion_query , GLL, x , x , x , 2001)

View file

@ -1749,7 +1749,38 @@ vbo_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
/* If <stride> is zero, the array elements are treated as tightly packed. */
if (stride == 0)
stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
stride = sizeof(DrawArraysIndirectCommand);
/* From the ARB_draw_indirect spec:
*
* "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
* compatibility profile, this indicates that DrawArraysIndirect and
* DrawElementsIndirect are to source their arguments directly from the
* pointer passed as their <indirect> parameters."
*/
if (ctx->API == API_OPENGL_COMPAT &&
!_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
"glMultiDrawArraysIndirect"))
return;
const ubyte *ptr = (const ubyte *) indirect;
for (unsigned i = 0; i < primcount; i++) {
DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr;
vbo_exec_DrawArraysInstancedBaseInstance(mode, cmd->first,
cmd->count, cmd->primCount,
cmd->baseInstance);
if (stride == 0) {
ptr += sizeof(DrawArraysIndirectCommand);
} else {
ptr += stride;
}
}
return;
}
FLUSH_FOR_DRAW(ctx);
@ -1788,7 +1819,49 @@ vbo_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type,
/* If <stride> is zero, the array elements are treated as tightly packed. */
if (stride == 0)
stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
stride = sizeof(DrawElementsIndirectCommand);
/* From the ARB_draw_indirect spec:
*
* "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
* compatibility profile, this indicates that DrawArraysIndirect and
* DrawElementsIndirect are to source their arguments directly from the
* pointer passed as their <indirect> parameters."
*/
if (ctx->API == API_OPENGL_COMPAT &&
!_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
/*
* Unlike regular DrawElementsInstancedBaseVertex commands, the indices
* may not come from a client array and must come from an index buffer.
* If no element array buffer is bound, an INVALID_OPERATION error is
* generated.
*/
if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMultiDrawElementsIndirect(no buffer bound "
"to GL_ELEMENT_ARRAY_BUFFER)");
return;
}
if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
"glMultiDrawArraysIndirect"))
return;
const ubyte *ptr = (const ubyte *) indirect;
for (unsigned i = 0; i < primcount; i++) {
vbo_exec_DrawElementsIndirect(mode, type, ptr);
if (stride == 0) {
ptr += sizeof(DrawElementsIndirectCommand);
} else {
ptr += stride;
}
}
return;
}
FLUSH_FOR_DRAW(ctx);