From aaaa22c775f484922ccac705de41dd892e2aff4d Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Mon, 25 Apr 2016 16:09:21 -0700 Subject: [PATCH] vbo: Return INVALID_OPERATION during draw with a mapped buffer MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fixes the OpenGLES 3.1 CTS: * ESEXT-CTS.draw_elements_base_vertex_tests.invalid_mapped_bos Because this is triggering the error message after the normal API validation phase, we don't have the API function name available, and therefore we generate an error message without the draw call name: Mesa: User error: GL_INVALID_OPERATION in draw call (vertex buffers are mapped) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95142 Signed-off-by: Jordan Justen Reviewed-by: Kenneth Graunke Reviewed-by: Marek Olšák --- src/mesa/vbo/vbo.h | 4 +- src/mesa/vbo/vbo_exec_array.c | 85 +++++++++++++++++------------------ 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 6494aa518a2..939a3a6f224 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -197,9 +197,7 @@ void vbo_set_draw_func(struct gl_context *ctx, vbo_draw_func func); void vbo_set_indirect_draw_func(struct gl_context *ctx, vbo_indirect_draw_func func); -void vbo_check_buffers_are_unmapped(struct gl_context *ctx); - -void vbo_bind_arrays(struct gl_context *ctx); +bool vbo_bind_arrays(struct gl_context *ctx); size_t vbo_count_tessellated_primitives(GLenum mode, GLuint count, diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 40cf3fff126..2d35f5a43ac 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -43,22 +43,22 @@ /** * All vertex buffers should be in an unmapped state when we're about - * to draw. This debug function checks that. + * to draw. */ -static void -check_buffers_are_unmapped(const struct gl_client_array **inputs) +static bool +check_input_buffers_are_unmapped(const struct gl_client_array **inputs) { -#ifdef DEBUG GLuint i; for (i = 0; i < VERT_ATTRIB_MAX; i++) { if (inputs[i]) { struct gl_buffer_object *obj = inputs[i]->BufferObj; - assert(!_mesa_check_disallowed_mapping(obj)); - (void) obj; + if (_mesa_check_disallowed_mapping(obj)) + return false; } } -#endif + + return true; } @@ -66,15 +66,15 @@ check_buffers_are_unmapped(const struct gl_client_array **inputs) * A debug function that may be called from other parts of Mesa as * needed during debugging. */ -void -vbo_check_buffers_are_unmapped(struct gl_context *ctx) +static bool +check_buffers_are_unmapped(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; + /* check the current vertex arrays */ - check_buffers_are_unmapped(exec->array.inputs); - /* check the current glBegin/glVertex/glEnd-style VBO */ - assert(!_mesa_check_disallowed_mapping(exec->vtx.bufferobj)); + return !_mesa_check_disallowed_mapping(exec->vtx.bufferobj) && + check_input_buffers_are_unmapped(exec->array.inputs); } @@ -395,7 +395,7 @@ recalculate_input_bindings(struct gl_context *ctx) * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state * validation must be done after this call. */ -void +bool vbo_bind_arrays(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); @@ -421,6 +421,14 @@ vbo_bind_arrays(struct gl_context *ctx) exec->validating = GL_FALSE; } } + + if (!check_buffers_are_unmapped(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "draw call (vertex buffers are mapped)"); + return false; + } else { + return true; + } } /** @@ -434,10 +442,10 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, GLsizei count, GLuint numInstances, GLuint baseInstance) { struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; struct _mesa_prim prim[2]; - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; /* init most fields to zero */ memset(prim, 0, sizeof(prim)); @@ -483,7 +491,6 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, if (primCount > 0) { /* draw one or two prims */ - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, prim, primCount, NULL, GL_TRUE, start, start + count - 1, NULL, 0, NULL); } @@ -493,7 +500,6 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, prim[0].start = start; prim[0].count = count; - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, prim, 1, NULL, GL_TRUE, start, start + count - 1, NULL, 0, NULL); @@ -785,11 +791,11 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, GLuint baseInstance) { 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); + if (!vbo_bind_arrays(ctx)) + return; ib.count = count; ib.type = type; @@ -840,7 +846,6 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, * for the latter case elsewhere. */ - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, prim, 1, &ib, index_bounds_valid, start, end, NULL, 0, NULL); @@ -1117,7 +1122,6 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, const GLint *basevertex) { struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; struct _mesa_index_buffer ib; struct _mesa_prim *prim; unsigned int index_type_size = vbo_sizeof_ib_type(type); @@ -1134,7 +1138,8 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, return; } - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; min_index_ptr = (uintptr_t)indices[0]; max_index_ptr = 0; @@ -1201,7 +1206,6 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, prim[i].basevertex = 0; } - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, prim, primcount, &ib, false, ~0, ~0, NULL, 0, NULL); } else { @@ -1231,7 +1235,6 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, else prim[0].basevertex = 0; - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, prim, 1, &ib, false, ~0, ~0, NULL, 0, NULL); } @@ -1301,7 +1304,8 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, return; } - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; /* init most fields to zero */ memset(prim, 0, sizeof(prim)); @@ -1316,7 +1320,6 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, * (like in DrawArrays), but we have no way to know how many vertices * will be rendered. */ - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, prim, 1, NULL, GL_TRUE, 0, 0, obj, stream, NULL); @@ -1397,11 +1400,10 @@ 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; - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, (GLsizeiptr)indirect, 1 /* draw_count */, 16 /* stride */, @@ -1418,15 +1420,14 @@ vbo_validated_multidrawarraysindirect(struct gl_context *ctx, GLsizei primcount, GLsizei stride) { struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; GLsizeiptr offset = (GLsizeiptr)indirect; if (primcount == 0) return; - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, offset, primcount, stride, @@ -1442,17 +1443,16 @@ vbo_validated_drawelementsindirect(struct gl_context *ctx, const GLvoid *indirect) { struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; struct _mesa_index_buffer ib; - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; ib.count = 0; /* unknown */ ib.type = type; ib.obj = ctx->Array.VAO->IndexBufferObj; ib.ptr = NULL; - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, (GLsizeiptr)indirect, 1 /* draw_count */, 20 /* stride */, @@ -1470,14 +1470,14 @@ vbo_validated_multidrawelementsindirect(struct gl_context *ctx, GLsizei primcount, GLsizei stride) { struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; struct _mesa_index_buffer ib; GLsizeiptr offset = (GLsizeiptr)indirect; if (primcount == 0) return; - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ @@ -1486,7 +1486,6 @@ vbo_validated_multidrawelementsindirect(struct gl_context *ctx, ib.obj = ctx->Array.VAO->IndexBufferObj; ib.ptr = NULL; - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, offset, primcount, stride, @@ -1593,15 +1592,14 @@ vbo_validated_multidrawarraysindirectcount(struct gl_context *ctx, GLsizei stride) { struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; GLsizeiptr offset = indirect; if (maxdrawcount == 0) return; - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, offset, maxdrawcount, stride, @@ -1621,14 +1619,14 @@ vbo_validated_multidrawelementsindirectcount(struct gl_context *ctx, GLsizei stride) { struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; struct _mesa_index_buffer ib; GLsizeiptr offset = (GLsizeiptr)indirect; if (maxdrawcount == 0) return; - vbo_bind_arrays(ctx); + if (!vbo_bind_arrays(ctx)) + return; /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ @@ -1637,7 +1635,6 @@ vbo_validated_multidrawelementsindirectcount(struct gl_context *ctx, ib.obj = ctx->Array.VAO->IndexBufferObj; ib.ptr = NULL; - check_buffers_are_unmapped(exec->array.inputs); vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, offset, maxdrawcount, stride, -- 2.30.2