mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
mesa: move glMultiDrawArrays to vbo and fix error handling
When any count[i] is negative, we must skip all draws. Moving to vbo makes the subsequent change easier. v2: - provide the function in all contexts, including GLES - adjust validation accordingly to include the xfb check v3: - fix mix-up of pre- and post-xfb prim count (Nils Wallménius) Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
parent
756e9ebbdd
commit
42d5465b9b
6 changed files with 127 additions and 19 deletions
|
|
@ -10219,7 +10219,7 @@
|
|||
</category>
|
||||
|
||||
<category name="GL_EXT_multi_draw_arrays" number="148">
|
||||
<function name="MultiDrawArraysEXT" es1="1.0" es2="2.0" alias="MultiDrawArrays">
|
||||
<function name="MultiDrawArraysEXT" es1="1.0" es2="2.0" exec="dynamic" alias="MultiDrawArrays">
|
||||
<param name="mode" type="GLenum"/>
|
||||
<param name="first" type="const GLint *"/>
|
||||
<param name="count" type="const GLsizei *"/>
|
||||
|
|
|
|||
|
|
@ -921,6 +921,60 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called to error check the function parameters.
|
||||
*
|
||||
* Note that glMultiDrawArrays is not part of GLES, so there's limited scope
|
||||
* for sharing code with the validation of glDrawArrays.
|
||||
*/
|
||||
bool
|
||||
_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode,
|
||||
const GLsizei *count, GLsizei primcount)
|
||||
{
|
||||
int i;
|
||||
|
||||
FLUSH_CURRENT(ctx, 0);
|
||||
|
||||
if (!_mesa_valid_prim_mode(ctx, mode, "glMultiDrawArrays"))
|
||||
return false;
|
||||
|
||||
if (!check_valid_to_render(ctx, "glMultiDrawArrays"))
|
||||
return false;
|
||||
|
||||
if (primcount < 0) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawArrays(primcount=%d)",
|
||||
primcount);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < primcount; ++i) {
|
||||
if (count[i] < 0) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawArrays(count[%d]=%d)",
|
||||
i, count[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_xfb_remaining_prims_check(ctx)) {
|
||||
struct gl_transform_feedback_object *xfb_obj
|
||||
= ctx->TransformFeedback.CurrentObject;
|
||||
size_t xfb_prim_count = 0;
|
||||
|
||||
for (i = 0; i < primcount; ++i)
|
||||
xfb_prim_count += vbo_count_tessellated_primitives(mode, count[i], 1);
|
||||
|
||||
if (xfb_obj->GlesRemainingPrims < xfb_prim_count) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glMultiDrawArrays(exceeds transform feedback size)");
|
||||
return false;
|
||||
}
|
||||
xfb_obj->GlesRemainingPrims -= xfb_prim_count;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
_mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
|
||||
GLenum mode, GLsizei count, GLenum type,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name);
|
|||
extern GLboolean
|
||||
_mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count);
|
||||
|
||||
extern bool
|
||||
_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode,
|
||||
const GLsizei *count, GLsizei primcount);
|
||||
|
||||
extern GLboolean
|
||||
_mesa_validate_DrawElements(struct gl_context *ctx,
|
||||
GLenum mode, GLsizei count, GLenum type,
|
||||
|
|
|
|||
|
|
@ -1539,24 +1539,6 @@ _mesa_UnlockArraysEXT( void )
|
|||
}
|
||||
|
||||
|
||||
/* GL_EXT_multi_draw_arrays */
|
||||
void GLAPIENTRY
|
||||
_mesa_MultiDrawArrays( GLenum mode, const GLint *first,
|
||||
const GLsizei *count, GLsizei primcount )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLint i;
|
||||
|
||||
FLUSH_VERTICES(ctx, 0);
|
||||
|
||||
for (i = 0; i < primcount; i++) {
|
||||
if (count[i] > 0) {
|
||||
CALL_DrawArrays(ctx->CurrentClientDispatch, (mode, first[i], count[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* GL_IBM_multimode_draw_arrays */
|
||||
void GLAPIENTRY
|
||||
_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
|
||||
|
|
|
|||
|
|
@ -637,6 +637,38 @@ vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called from glMultiDrawArrays when in immediate mode.
|
||||
*/
|
||||
static void GLAPIENTRY
|
||||
vbo_exec_MultiDrawArrays(GLenum mode, const GLint *first,
|
||||
const GLsizei *count, GLsizei primcount)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLint i;
|
||||
|
||||
if (MESA_VERBOSE & VERBOSE_DRAW)
|
||||
_mesa_debug(ctx,
|
||||
"glMultiDrawArrays(%s, %p, %p, %d)\n",
|
||||
_mesa_enum_to_string(mode), first, count, primcount);
|
||||
|
||||
if (!_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount))
|
||||
return;
|
||||
|
||||
for (i = 0; i < primcount; i++) {
|
||||
if (count[i] > 0) {
|
||||
if (0)
|
||||
check_draw_arrays_data(ctx, first[i], count[i]);
|
||||
|
||||
vbo_draw_arrays(ctx, mode, first[i], count[i], 1, 0);
|
||||
|
||||
if (0)
|
||||
print_draw_arrays(ctx, mode, first[i], count[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Map GL_ELEMENT_ARRAY_BUFFER and print contents.
|
||||
|
|
@ -1641,6 +1673,7 @@ vbo_initialize_exec_dispatch(const struct gl_context *ctx,
|
|||
SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements);
|
||||
}
|
||||
|
||||
SET_MultiDrawArrays(exec, vbo_exec_MultiDrawArrays);
|
||||
SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements);
|
||||
|
||||
if (ctx->API == API_OPENGL_COMPAT) {
|
||||
|
|
|
|||
|
|
@ -1176,6 +1176,40 @@ _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
|||
}
|
||||
|
||||
|
||||
static void GLAPIENTRY
|
||||
_save_OBE_MultiDrawArrays(GLenum mode, const GLint *first,
|
||||
const GLsizei *count, GLsizei primcount)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLint i;
|
||||
|
||||
if (!_mesa_is_valid_prim_mode(ctx, mode)) {
|
||||
_mesa_compile_error(ctx, GL_INVALID_ENUM, "glMultiDrawArrays(mode)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (primcount < 0) {
|
||||
_mesa_compile_error(ctx, GL_INVALID_VALUE,
|
||||
"glMultiDrawArrays(primcount<0)");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < primcount; i++) {
|
||||
if (count[i] < 0) {
|
||||
_mesa_compile_error(ctx, GL_INVALID_VALUE,
|
||||
"glMultiDrawArrays(count[i]<0)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < primcount; i++) {
|
||||
if (count[i] > 0) {
|
||||
_save_OBE_DrawArrays(mode, first[i], count[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Could do better by copying the arrays and element list intact and
|
||||
* then emitting an indexed prim at runtime.
|
||||
*/
|
||||
|
|
@ -1484,6 +1518,7 @@ vbo_initialize_save_dispatch(const struct gl_context *ctx,
|
|||
struct _glapi_table *exec)
|
||||
{
|
||||
SET_DrawArrays(exec, _save_OBE_DrawArrays);
|
||||
SET_MultiDrawArrays(exec, _save_OBE_MultiDrawArrays);
|
||||
SET_DrawElements(exec, _save_OBE_DrawElements);
|
||||
SET_DrawElementsBaseVertex(exec, _save_OBE_DrawElementsBaseVertex);
|
||||
SET_DrawRangeElements(exec, _save_OBE_DrawRangeElements);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue