diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 8ead49dbc3d..6df84ada4d3 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -12944,6 +12944,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c
index 464d6bb5911..6f8b28a7d43 100644
--- a/src/mesa/main/draw.c
+++ b/src/mesa/main/draw.c
@@ -1589,7 +1589,9 @@ dump_element_buffer(struct gl_context *ctx, GLenum type)
* we've validated buffer bounds, etc.
*/
static void
-_mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
+_mesa_validated_drawrangeelements(struct gl_context *ctx,
+ struct gl_buffer_object *index_bo,
+ GLenum mode,
bool index_bounds_valid,
GLuint start, GLuint end,
GLsizei count, GLenum type,
@@ -1611,7 +1613,6 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
struct pipe_draw_info info;
struct pipe_draw_start_count_bias draw;
unsigned index_size_shift = get_index_size_shift(type);
- struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj;
if (index_bo && !indices_aligned(index_size_shift, indices))
return;
@@ -1785,7 +1786,8 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
end = ~0;
}
- _mesa_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
+ _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj,
+ mode, index_bounds_valid, start, end,
count, type, indices, basevertex, 1, 0);
}
@@ -1819,7 +1821,8 @@ _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
!_mesa_validate_DrawElements(ctx, mode, count, type))
return;
- _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
+ _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj,
+ mode, false, 0, ~0,
count, type, indices, 0, 1, 0);
}
@@ -1841,7 +1844,8 @@ _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
!_mesa_validate_DrawElements(ctx, mode, count, type))
return;
- _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
+ _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj,
+ mode, false, 0, ~0,
count, type, indices, basevertex, 1, 0);
}
@@ -1864,7 +1868,8 @@ _mesa_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
numInstances))
return;
- _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
+ _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj,
+ mode, false, 0, ~0,
count, type, indices, 0, numInstances, 0);
}
@@ -1889,7 +1894,8 @@ _mesa_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count,
numInstances))
return;
- _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
+ _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj,
+ mode, false, 0, ~0,
count, type, indices,
basevertex, numInstances, 0);
}
@@ -1916,7 +1922,8 @@ _mesa_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count,
numInstances))
return;
- _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
+ _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj,
+ mode, false, 0, ~0,
count, type, indices, 0, numInstances,
baseInstance);
}
@@ -1945,7 +1952,40 @@ _mesa_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
numInstances))
return;
- _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
+ _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj,
+ mode, false, 0, ~0,
+ count, type, indices, basevertex,
+ numInstances, baseInstance);
+}
+
+/**
+ * Same as glDrawElementsInstancedBaseVertexBaseInstance, but the index
+ * buffer is set by the indexBuf parameter instead of using the bound
+ * GL_ELEMENT_ARRAY_BUFFER if indexBuf != NULL.
+ */
+void GLAPIENTRY
+_mesa_DrawElementsUserBuf(GLintptr indexBuf, GLenum mode,
+ GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei numInstances,
+ GLint basevertex, GLuint baseInstance)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_FOR_DRAW(ctx);
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (!_mesa_is_no_error_enabled(ctx) &&
+ !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
+ numInstances))
+ return;
+
+ struct gl_buffer_object *index_bo =
+ indexBuf ? (struct gl_buffer_object*)indexBuf :
+ ctx->Array.VAO->IndexBufferObj;
+
+ _mesa_validated_drawrangeelements(ctx, index_bo,
+ mode, false, 0, ~0,
count, type, indices, basevertex,
numInstances, baseInstance);
}
diff --git a/src/mesa/main/glthread_draw.c b/src/mesa/main/glthread_draw.c
index 688a1a47bbe..16319652789 100644
--- a/src/mesa/main/glthread_draw.c
+++ b/src/mesa/main/glthread_draw.c
@@ -775,7 +775,6 @@ _mesa_unmarshal_DrawElementsUserBuf(struct gl_context *ctx,
const struct marshal_cmd_DrawElementsUserBuf *cmd)
{
const GLuint user_buffer_mask = cmd->user_buffer_mask;
- struct gl_buffer_object *index_buffer = cmd->index_buffer;
const struct glthread_attrib_binding *buffers =
(const struct glthread_attrib_binding *)(cmd + 1);
@@ -784,9 +783,6 @@ _mesa_unmarshal_DrawElementsUserBuf(struct gl_context *ctx,
_mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask,
false);
}
- if (index_buffer) {
- _mesa_InternalBindElementBuffer(ctx, index_buffer);
- }
/* Draw. */
const GLenum mode = cmd->mode;
@@ -796,16 +792,15 @@ _mesa_unmarshal_DrawElementsUserBuf(struct gl_context *ctx,
const GLsizei instance_count = cmd->instance_count;
const GLint basevertex = cmd->basevertex;
const GLuint baseinstance = cmd->baseinstance;
+ struct gl_buffer_object *index_buffer = cmd->index_buffer;
- CALL_DrawElementsInstancedBaseVertexBaseInstance(ctx->CurrentServerDispatch,
- (mode, count, type, indices,
- instance_count, basevertex,
- baseinstance));
+ CALL_DrawElementsUserBuf(ctx->CurrentServerDispatch,
+ ((GLintptr)index_buffer, mode, count, type,
+ indices, instance_count, basevertex,
+ baseinstance));
+ _mesa_reference_buffer_object(ctx, &index_buffer, NULL);
/* Restore states. */
- if (index_buffer) {
- _mesa_InternalBindElementBuffer(ctx, NULL);
- }
if (user_buffer_mask) {
_mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask,
true);
@@ -1428,7 +1423,10 @@ _mesa_marshal_DrawArraysUserBuf(void)
}
void GLAPIENTRY
-_mesa_marshal_DrawElementsUserBuf(void)
+_mesa_marshal_DrawElementsUserBuf(GLintptr indexBuf, GLenum mode,
+ GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei numInstances,
+ GLint basevertex, GLuint baseInstance)
{
unreachable("should never end up here");
}
@@ -1451,12 +1449,6 @@ _mesa_DrawArraysUserBuf(void)
unreachable("should never end up here");
}
-void GLAPIENTRY
-_mesa_DrawElementsUserBuf(void)
-{
- unreachable("should never end up here");
-}
-
void GLAPIENTRY
_mesa_MultiDrawArraysUserBuf(void)
{