glthread: convert (Multi)DrawIndirect into direct if user buffers are present
so that user buffers are uploaded without syncing. Now glthread fully handles non-VBO uploads, so that we can disable user buffer codepaths in st/mesa. Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20624>
This commit is contained in:
@@ -8,16 +8,12 @@
|
||||
<enum name="DRAW_INDIRECT_BUFFER" value="0x8F3F"/>
|
||||
<enum name="DRAW_INDIRECT_BUFFER_BINDING" value="0x8F43"/>
|
||||
|
||||
<function name="DrawArraysIndirect" es2="3.1" exec="dlist"
|
||||
marshal="async"
|
||||
marshal_sync="_mesa_glthread_has_non_vbo_vertices_or_indirect(ctx)">
|
||||
<function name="DrawArraysIndirect" es2="3.1" exec="dlist" marshal="custom">
|
||||
<param name="mode" type="GLenum"/>
|
||||
<param name="indirect" type="const GLvoid *"/>
|
||||
</function>
|
||||
|
||||
<function name="DrawElementsIndirect" es2="3.1" exec="dlist"
|
||||
marshal="async"
|
||||
marshal_sync="_mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(ctx)">
|
||||
<function name="DrawElementsIndirect" es2="3.1" exec="dlist" marshal="custom">
|
||||
<param name="mode" type="GLenum"/>
|
||||
<param name="type" type="GLenum"/>
|
||||
<param name="indirect" type="const GLvoid *"/>
|
||||
@@ -28,16 +24,14 @@
|
||||
|
||||
<category name="GL_ARB_multi_draw_indirect" number="133">
|
||||
|
||||
<function name="MultiDrawArraysIndirect" marshal="async" exec="dlist"
|
||||
marshal_sync="_mesa_glthread_has_non_vbo_vertices_or_indirect(ctx)">
|
||||
<function name="MultiDrawArraysIndirect" marshal="custom" exec="dlist">
|
||||
<param name="mode" type="GLenum"/>
|
||||
<param name="indirect" type="const GLvoid *"/>
|
||||
<param name="primcount" type="GLsizei"/>
|
||||
<param name="stride" type="GLsizei"/>
|
||||
</function>
|
||||
|
||||
<function name="MultiDrawElementsIndirect" marshal="async" exec="dlist"
|
||||
marshal_sync="_mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(ctx)">
|
||||
<function name="MultiDrawElementsIndirect" marshal="custom" exec="dlist">
|
||||
<param name="mode" type="GLenum"/>
|
||||
<param name="type" type="GLenum"/>
|
||||
<param name="indirect" type="const GLvoid *"/>
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
<enum name="PARAMETER_BUFFER_ARB" value="0x80EE"/>
|
||||
<enum name="PARAMETER_BUFFER_BINDING_ARB" value="0x80EF"/>
|
||||
|
||||
<function name="MultiDrawArraysIndirectCountARB"
|
||||
marshal_sync="_mesa_glthread_has_non_vbo_vertices(ctx)">
|
||||
<function name="MultiDrawArraysIndirectCountARB" marshal="custom">
|
||||
<param name="mode" type="GLenum"/>
|
||||
<param name="indirect" type="GLintptr"/>
|
||||
<param name="drawcount" type="GLintptr"/>
|
||||
@@ -18,8 +17,7 @@
|
||||
</function>
|
||||
|
||||
<!-- Use "...has_non_vbo_vertices", because indices always come from a buffer object. -->
|
||||
<function name="MultiDrawElementsIndirectCountARB"
|
||||
marshal_sync="_mesa_glthread_has_non_vbo_vertices(ctx)">
|
||||
<function name="MultiDrawElementsIndirectCountARB" marshal="custom">
|
||||
<param name="mode" type="GLenum"/>
|
||||
<param name="type" type="GLenum"/>
|
||||
<param name="indirect" type="GLintptr"/>
|
||||
|
||||
@@ -1331,6 +1331,426 @@ _mesa_marshal_MultiModeDrawElementsIBM(const GLenum *mode,
|
||||
}
|
||||
}
|
||||
|
||||
static const void *
|
||||
map_draw_indirect_params(struct gl_context *ctx, GLintptr offset,
|
||||
unsigned count, unsigned stride)
|
||||
{
|
||||
struct gl_buffer_object *obj = ctx->DrawIndirectBuffer;
|
||||
|
||||
if (!obj)
|
||||
return (void*)offset;
|
||||
|
||||
return _mesa_bufferobj_map_range(ctx, offset,
|
||||
MIN2((size_t)count * stride, obj->Size),
|
||||
GL_MAP_READ_BIT, obj, MAP_INTERNAL);
|
||||
}
|
||||
|
||||
static void
|
||||
unmap_draw_indirect_params(struct gl_context *ctx)
|
||||
{
|
||||
if (ctx->DrawIndirectBuffer)
|
||||
_mesa_bufferobj_unmap(ctx, ctx->DrawIndirectBuffer, MAP_INTERNAL);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
read_draw_indirect_count(struct gl_context *ctx, GLintptr offset)
|
||||
{
|
||||
unsigned result = 0;
|
||||
|
||||
if (ctx->ParameterBuffer) {
|
||||
_mesa_bufferobj_get_subdata(ctx, offset, sizeof(result), &result,
|
||||
ctx->ParameterBuffer);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
lower_draw_arrays_indirect(struct gl_context *ctx, GLenum mode,
|
||||
GLintptr indirect, GLsizei stride,
|
||||
unsigned draw_count)
|
||||
{
|
||||
/* If <stride> is zero, the elements are tightly packed. */
|
||||
if (stride == 0)
|
||||
stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
|
||||
|
||||
const uint32_t *params =
|
||||
map_draw_indirect_params(ctx, indirect, draw_count, stride);
|
||||
|
||||
for (unsigned i = 0; i < draw_count; i++) {
|
||||
draw_arrays(i, mode,
|
||||
params[i * stride / 4 + 2],
|
||||
params[i * stride / 4 + 0],
|
||||
params[i * stride / 4 + 1],
|
||||
params[i * stride / 4 + 3], false);
|
||||
}
|
||||
|
||||
unmap_draw_indirect_params(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
lower_draw_elements_indirect(struct gl_context *ctx, GLenum mode, GLenum type,
|
||||
GLintptr indirect, GLsizei stride,
|
||||
unsigned draw_count)
|
||||
{
|
||||
/* If <stride> is zero, the elements are tightly packed. */
|
||||
if (stride == 0)
|
||||
stride = 5 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
|
||||
|
||||
const uint32_t *params =
|
||||
map_draw_indirect_params(ctx, indirect, draw_count, stride);
|
||||
|
||||
for (unsigned i = 0; i < draw_count; i++) {
|
||||
draw_elements(i, mode,
|
||||
params[i * stride / 4 + 0],
|
||||
type,
|
||||
(GLvoid*)((uintptr_t)params[i * stride / 4 + 2] *
|
||||
get_index_size(type)),
|
||||
params[i * stride / 4 + 1],
|
||||
params[i * stride / 4 + 3],
|
||||
params[i * stride / 4 + 4],
|
||||
false, 0, 0, false);
|
||||
}
|
||||
unmap_draw_indirect_params(ctx);
|
||||
}
|
||||
|
||||
struct marshal_cmd_DrawArraysIndirect
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLenum16 mode;
|
||||
const GLvoid * indirect;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
_mesa_unmarshal_DrawArraysIndirect(struct gl_context *ctx,
|
||||
const struct marshal_cmd_DrawArraysIndirect *cmd)
|
||||
{
|
||||
GLenum mode = cmd->mode;
|
||||
const GLvoid * indirect = cmd->indirect;
|
||||
|
||||
CALL_DrawArraysIndirect(ctx->CurrentServerDispatch, (mode, indirect));
|
||||
|
||||
const unsigned cmd_size =
|
||||
(align(sizeof(struct marshal_cmd_DrawArraysIndirect), 8) / 8);
|
||||
assert(cmd_size == cmd->cmd_base.cmd_size);
|
||||
return cmd_size;
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_marshal_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
|
||||
unsigned user_buffer_mask =
|
||||
_mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled;
|
||||
|
||||
if (ctx->GLThread.draw_always_async ||
|
||||
!ctx->GLThread.CurrentDrawIndirectBufferName ||
|
||||
!user_buffer_mask) {
|
||||
int cmd_size = sizeof(struct marshal_cmd_DrawArraysIndirect);
|
||||
struct marshal_cmd_DrawArraysIndirect *cmd;
|
||||
|
||||
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawArraysIndirect, cmd_size);
|
||||
cmd->mode = MIN2(mode, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->indirect = indirect;
|
||||
return;
|
||||
}
|
||||
|
||||
_mesa_glthread_finish_before(ctx, "DrawArraysIndirect");
|
||||
lower_draw_arrays_indirect(ctx, mode, (GLintptr)indirect, 0, 1);
|
||||
}
|
||||
|
||||
struct marshal_cmd_DrawElementsIndirect
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLenum16 mode;
|
||||
GLenum16 type;
|
||||
const GLvoid * indirect;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
_mesa_unmarshal_DrawElementsIndirect(struct gl_context *ctx,
|
||||
const struct marshal_cmd_DrawElementsIndirect *cmd)
|
||||
{
|
||||
GLenum mode = cmd->mode;
|
||||
GLenum type = cmd->type;
|
||||
const GLvoid * indirect = cmd->indirect;
|
||||
|
||||
CALL_DrawElementsIndirect(ctx->CurrentServerDispatch, (mode, type, indirect));
|
||||
|
||||
const unsigned cmd_size =
|
||||
(align(sizeof(struct marshal_cmd_DrawElementsIndirect), 8) / 8);
|
||||
assert(cmd_size == cmd->cmd_base.cmd_size);
|
||||
return cmd_size;
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_marshal_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
|
||||
unsigned user_buffer_mask =
|
||||
_mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled;
|
||||
|
||||
if (ctx->GLThread.draw_always_async || !is_index_type_valid(type) ||
|
||||
!ctx->GLThread.CurrentDrawIndirectBufferName ||
|
||||
!vao->CurrentElementBufferName || !user_buffer_mask) {
|
||||
int cmd_size = sizeof(struct marshal_cmd_DrawElementsIndirect);
|
||||
struct marshal_cmd_DrawElementsIndirect *cmd;
|
||||
|
||||
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsIndirect, cmd_size);
|
||||
cmd->mode = MIN2(mode, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->indirect = indirect;
|
||||
return;
|
||||
}
|
||||
|
||||
_mesa_glthread_finish_before(ctx, "DrawElementsIndirect");
|
||||
lower_draw_elements_indirect(ctx, mode, type, (GLintptr)indirect, 0, 1);
|
||||
}
|
||||
|
||||
struct marshal_cmd_MultiDrawArraysIndirect
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLenum16 mode;
|
||||
GLsizei primcount;
|
||||
GLsizei stride;
|
||||
const GLvoid * indirect;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
_mesa_unmarshal_MultiDrawArraysIndirect(struct gl_context *ctx,
|
||||
const struct marshal_cmd_MultiDrawArraysIndirect *cmd)
|
||||
{
|
||||
GLenum mode = cmd->mode;
|
||||
const GLvoid * indirect = cmd->indirect;
|
||||
GLsizei primcount = cmd->primcount;
|
||||
GLsizei stride = cmd->stride;
|
||||
|
||||
CALL_MultiDrawArraysIndirect(ctx->CurrentServerDispatch,
|
||||
(mode, indirect, primcount, stride));
|
||||
|
||||
const unsigned cmd_size =
|
||||
(align(sizeof(struct marshal_cmd_MultiDrawArraysIndirect), 8) / 8);
|
||||
assert(cmd_size == cmd->cmd_base.cmd_size);
|
||||
return cmd_size;
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_marshal_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
|
||||
GLsizei primcount, GLsizei stride)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
|
||||
unsigned user_buffer_mask =
|
||||
_mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled;
|
||||
|
||||
if (ctx->GLThread.draw_always_async ||
|
||||
!ctx->GLThread.CurrentDrawIndirectBufferName ||
|
||||
!user_buffer_mask) {
|
||||
int cmd_size = sizeof(struct marshal_cmd_MultiDrawArraysIndirect);
|
||||
struct marshal_cmd_MultiDrawArraysIndirect *cmd;
|
||||
|
||||
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawArraysIndirect,
|
||||
cmd_size);
|
||||
cmd->mode = MIN2(mode, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->indirect = indirect;
|
||||
cmd->primcount = primcount;
|
||||
cmd->stride = stride;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Lower the draw to direct due to non-VBO vertex arrays. */
|
||||
_mesa_glthread_finish_before(ctx, "MultiDrawArraysIndirect");
|
||||
lower_draw_arrays_indirect(ctx, mode, (GLintptr)indirect, stride, primcount);
|
||||
}
|
||||
|
||||
struct marshal_cmd_MultiDrawElementsIndirect
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLenum16 mode;
|
||||
GLenum16 type;
|
||||
GLsizei primcount;
|
||||
GLsizei stride;
|
||||
const GLvoid * indirect;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
_mesa_unmarshal_MultiDrawElementsIndirect(struct gl_context *ctx,
|
||||
const struct marshal_cmd_MultiDrawElementsIndirect *cmd)
|
||||
{
|
||||
GLenum mode = cmd->mode;
|
||||
GLenum type = cmd->type;
|
||||
const GLvoid * indirect = cmd->indirect;
|
||||
GLsizei primcount = cmd->primcount;
|
||||
GLsizei stride = cmd->stride;
|
||||
|
||||
CALL_MultiDrawElementsIndirect(ctx->CurrentServerDispatch,
|
||||
(mode, type, indirect, primcount, stride));
|
||||
|
||||
const unsigned cmd_size =
|
||||
(align(sizeof(struct marshal_cmd_MultiDrawElementsIndirect), 8) / 8);
|
||||
assert(cmd_size == cmd->cmd_base.cmd_size);
|
||||
return cmd_size;
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_marshal_MultiDrawElementsIndirect(GLenum mode, GLenum type,
|
||||
const GLvoid *indirect,
|
||||
GLsizei primcount, GLsizei stride)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
|
||||
unsigned user_buffer_mask =
|
||||
_mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled;
|
||||
|
||||
if (ctx->GLThread.draw_always_async || !is_index_type_valid(type) ||
|
||||
!ctx->GLThread.CurrentDrawIndirectBufferName ||
|
||||
!vao->CurrentElementBufferName || !user_buffer_mask) {
|
||||
int cmd_size = sizeof(struct marshal_cmd_MultiDrawElementsIndirect);
|
||||
struct marshal_cmd_MultiDrawElementsIndirect *cmd;
|
||||
|
||||
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawElementsIndirect,
|
||||
cmd_size);
|
||||
cmd->mode = MIN2(mode, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->indirect = indirect;
|
||||
cmd->primcount = primcount;
|
||||
cmd->stride = stride;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Lower the draw to direct due to non-VBO vertex arrays. */
|
||||
_mesa_glthread_finish_before(ctx, "MultiDrawElementsIndirect");
|
||||
lower_draw_elements_indirect(ctx, mode, type, (GLintptr)indirect, stride,
|
||||
primcount);
|
||||
}
|
||||
|
||||
struct marshal_cmd_MultiDrawArraysIndirectCountARB
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLenum16 mode;
|
||||
GLsizei maxdrawcount;
|
||||
GLsizei stride;
|
||||
GLintptr indirect;
|
||||
GLintptr drawcount;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
_mesa_unmarshal_MultiDrawArraysIndirectCountARB(struct gl_context *ctx,
|
||||
const struct marshal_cmd_MultiDrawArraysIndirectCountARB *cmd)
|
||||
{
|
||||
GLenum mode = cmd->mode;
|
||||
GLintptr indirect = cmd->indirect;
|
||||
GLintptr drawcount = cmd->drawcount;
|
||||
GLsizei maxdrawcount = cmd->maxdrawcount;
|
||||
GLsizei stride = cmd->stride;
|
||||
|
||||
CALL_MultiDrawArraysIndirectCountARB(ctx->CurrentServerDispatch,
|
||||
(mode, indirect, drawcount,
|
||||
maxdrawcount, stride));
|
||||
|
||||
const unsigned cmd_size =
|
||||
(align(sizeof(struct marshal_cmd_MultiDrawArraysIndirectCountARB), 8) / 8);
|
||||
assert(cmd_size == cmd->cmd_base.cmd_size);
|
||||
return cmd_size;
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_marshal_MultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect,
|
||||
GLintptr drawcount,
|
||||
GLsizei maxdrawcount,
|
||||
GLsizei stride)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
|
||||
unsigned user_buffer_mask =
|
||||
_mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled;
|
||||
|
||||
if (ctx->GLThread.draw_always_async || !user_buffer_mask ||
|
||||
!ctx->GLThread.CurrentDrawIndirectBufferName) {
|
||||
int cmd_size =
|
||||
sizeof(struct marshal_cmd_MultiDrawArraysIndirectCountARB);
|
||||
struct marshal_cmd_MultiDrawArraysIndirectCountARB *cmd =
|
||||
_mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawArraysIndirectCountARB,
|
||||
cmd_size);
|
||||
|
||||
cmd->mode = MIN2(mode, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->indirect = indirect;
|
||||
cmd->drawcount = drawcount;
|
||||
cmd->maxdrawcount = maxdrawcount;
|
||||
cmd->stride = stride;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Lower the draw to direct due to non-VBO vertex arrays. */
|
||||
_mesa_glthread_finish_before(ctx, "MultiDrawArraysIndirectCountARB");
|
||||
lower_draw_arrays_indirect(ctx, mode, indirect, stride,
|
||||
read_draw_indirect_count(ctx, drawcount));
|
||||
}
|
||||
|
||||
struct marshal_cmd_MultiDrawElementsIndirectCountARB
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLenum16 mode;
|
||||
GLenum16 type;
|
||||
GLsizei maxdrawcount;
|
||||
GLsizei stride;
|
||||
GLintptr indirect;
|
||||
GLintptr drawcount;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
_mesa_unmarshal_MultiDrawElementsIndirectCountARB(struct gl_context *ctx,
|
||||
const struct marshal_cmd_MultiDrawElementsIndirectCountARB *cmd)
|
||||
{
|
||||
GLenum mode = cmd->mode;
|
||||
GLenum type = cmd->type;
|
||||
GLintptr indirect = cmd->indirect;
|
||||
GLintptr drawcount = cmd->drawcount;
|
||||
GLsizei maxdrawcount = cmd->maxdrawcount;
|
||||
GLsizei stride = cmd->stride;
|
||||
|
||||
CALL_MultiDrawElementsIndirectCountARB(ctx->CurrentServerDispatch, (mode, type, indirect, drawcount, maxdrawcount, stride));
|
||||
|
||||
const unsigned cmd_size = (align(sizeof(struct marshal_cmd_MultiDrawElementsIndirectCountARB), 8) / 8);
|
||||
assert(cmd_size == cmd->cmd_base.cmd_size);
|
||||
return cmd_size;
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_marshal_MultiDrawElementsIndirectCountARB(GLenum mode, GLenum type,
|
||||
GLintptr indirect,
|
||||
GLintptr drawcount,
|
||||
GLsizei maxdrawcount,
|
||||
GLsizei stride)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
|
||||
unsigned user_buffer_mask =
|
||||
_mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled;
|
||||
|
||||
if (ctx->GLThread.draw_always_async || !user_buffer_mask ||
|
||||
!ctx->GLThread.CurrentDrawIndirectBufferName ||
|
||||
!is_index_type_valid(type)) {
|
||||
int cmd_size = sizeof(struct marshal_cmd_MultiDrawElementsIndirectCountARB);
|
||||
struct marshal_cmd_MultiDrawElementsIndirectCountARB *cmd =
|
||||
_mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawElementsIndirectCountARB, cmd_size);
|
||||
|
||||
cmd->mode = MIN2(mode, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->indirect = indirect;
|
||||
cmd->drawcount = drawcount;
|
||||
cmd->maxdrawcount = maxdrawcount;
|
||||
cmd->stride = stride;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Lower the draw to direct due to non-VBO vertex arrays. */
|
||||
_mesa_glthread_finish_before(ctx, "MultiDrawElementsIndirectCountARB");
|
||||
lower_draw_elements_indirect(ctx, mode, type, indirect, stride,
|
||||
read_draw_indirect_count(ctx, drawcount));
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_marshal_DrawArrays(GLenum mode, GLint first, GLsizei count)
|
||||
{
|
||||
|
||||
@@ -94,39 +94,6 @@ _mesa_glthread_has_no_unpack_buffer(const struct gl_context *ctx)
|
||||
return ctx->GLThread.CurrentPixelUnpackBufferName == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_mesa_glthread_has_non_vbo_vertices(const struct gl_context *ctx)
|
||||
{
|
||||
const struct glthread_state *glthread = &ctx->GLThread;
|
||||
const struct glthread_vao *vao = glthread->CurrentVAO;
|
||||
|
||||
return ctx->API != API_OPENGL_CORE &&
|
||||
(vao->UserPointerMask & vao->BufferEnabled);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_mesa_glthread_has_non_vbo_vertices_or_indirect(const struct gl_context *ctx)
|
||||
{
|
||||
const struct glthread_state *glthread = &ctx->GLThread;
|
||||
const struct glthread_vao *vao = glthread->CurrentVAO;
|
||||
|
||||
return ctx->API != API_OPENGL_CORE &&
|
||||
(glthread->CurrentDrawIndirectBufferName == 0 ||
|
||||
(vao->UserPointerMask & vao->BufferEnabled));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(const struct gl_context *ctx)
|
||||
{
|
||||
const struct glthread_state *glthread = &ctx->GLThread;
|
||||
struct glthread_vao *vao = glthread->CurrentVAO;
|
||||
|
||||
return ctx->API != API_OPENGL_CORE &&
|
||||
(glthread->CurrentDrawIndirectBufferName == 0 ||
|
||||
vao->CurrentElementBufferName == 0 ||
|
||||
(vao->UserPointerMask & vao->BufferEnabled));
|
||||
}
|
||||
|
||||
static inline void
|
||||
_mesa_glthread_update_draw_always_async(struct gl_context *ctx)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user