glthread: add a packed version of DrawElementsUserBuf

The reduces the call size by 24 bytes.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27350>
This commit is contained in:
Marek Olšák 2024-01-09 03:48:00 -05:00 committed by Marge Bot
parent c566df8b39
commit 24f14f8daa
5 changed files with 115 additions and 16 deletions

View file

@ -12944,6 +12944,10 @@
<param name="cmd" type="const GLvoid *"/> <!-- struct marshal_cmd_DrawElementsUserBuf -->
</function>
<function name="DrawElementsUserBufPacked" es1="1.0" es2="2.0" marshal="custom">
<param name="cmd" type="const GLvoid *"/> <!-- struct marshal_cmd_DrawElementsUserBufPacked -->
</function>
<function name="MultiDrawArraysUserBuf" es1="1.0" es2="2.0" marshal="custom">
</function>

View file

@ -1705,6 +1705,7 @@ offsets = {
"DrawElementsInstancedBaseVertexBaseInstanceDrawID": 1669,
"InternalInvalidateFramebufferAncillaryMESA": 1670,
"DrawElementsPacked": 1671,
"DrawElementsUserBufPacked": 1672,
}
functions = [

View file

@ -1973,6 +1973,40 @@ _mesa_DrawElementsUserBuf(const GLvoid *ptr)
ctx->DrawID = 0;
}
/**
* 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_DrawElementsUserBufPacked(const GLvoid *ptr)
{
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
_mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter &
ctx->Array._DrawVAO->_EnabledWithMapMode);
if (ctx->NewState)
_mesa_update_state(ctx);
const struct marshal_cmd_DrawElementsUserBufPacked *cmd =
(const struct marshal_cmd_DrawElementsUserBufPacked *)ptr;
const GLenum mode = cmd->mode;
const GLsizei count = cmd->count;
const GLenum type = _mesa_decode_index_type(cmd->type);
if (!_mesa_is_no_error_enabled(ctx) &&
!_mesa_validate_DrawElements(ctx, mode, count, type))
return;
struct gl_buffer_object *index_bo =
cmd->index_buffer ? cmd->index_buffer : ctx->Array.VAO->IndexBufferObj;
const GLvoid *indices = (void*)(uintptr_t)cmd->indices;
_mesa_validated_drawrangeelements(ctx, index_bo, mode, false, 0, ~0,
count, type, indices, 0, 1, 0);
}
/**
* Inner support for both _mesa_MultiDrawElements() and

View file

@ -724,6 +724,28 @@ _mesa_unmarshal_DrawElementsUserBuf(struct gl_context *ctx,
return cmd->num_slots;
}
uint32_t
_mesa_unmarshal_DrawElementsUserBufPacked(struct gl_context *ctx,
const struct marshal_cmd_DrawElementsUserBufPacked *restrict cmd)
{
const GLuint user_buffer_mask = cmd->user_buffer_mask;
/* Bind uploaded buffers if needed. */
if (user_buffer_mask) {
struct gl_buffer_object **buffers = (struct gl_buffer_object **)(cmd + 1);
const int *offsets = (const int *)(buffers + util_bitcount(user_buffer_mask));
_mesa_InternalBindVertexBuffers(ctx, buffers, offsets, user_buffer_mask);
}
/* Draw. */
CALL_DrawElementsUserBufPacked(ctx->Dispatch.Current, (cmd));
struct gl_buffer_object *index_buffer = cmd->index_buffer;
_mesa_reference_buffer_object(ctx, &index_buffer, NULL);
return cmd->num_slots;
}
static inline bool
should_convert_to_begin_end(struct gl_context *ctx, unsigned count,
unsigned num_upload_vertices,
@ -923,25 +945,45 @@ draw_elements(GLuint drawid, GLenum mode, GLsizei count, GLenum type,
unsigned num_buffers = util_bitcount(user_buffer_mask);
int buffers_size = num_buffers * sizeof(buffers[0]);
int offsets_size = num_buffers * sizeof(int);
int cmd_size = sizeof(struct marshal_cmd_DrawElementsUserBuf) +
buffers_size + offsets_size;
struct marshal_cmd_DrawElementsUserBuf *cmd;
char *variable_data;
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsUserBuf, cmd_size);
cmd->num_slots = align(cmd_size, 8) / 8;
cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */
cmd->type = encode_index_type(type);
cmd->count = count;
cmd->indices = indices;
cmd->instance_count = instance_count;
cmd->basevertex = basevertex;
cmd->baseinstance = baseinstance;
cmd->user_buffer_mask = user_buffer_mask;
cmd->index_buffer = index_buffer;
cmd->drawid = drawid;
if (instance_count == 1 && basevertex == 0 && baseinstance == 0 &&
drawid == 0 && (count & 0xffff) == count &&
(uintptr_t)indices <= UINT32_MAX) {
int cmd_size = sizeof(struct marshal_cmd_DrawElementsUserBufPacked) +
buffers_size + offsets_size;
struct marshal_cmd_DrawElementsUserBufPacked *cmd;
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsUserBufPacked, cmd_size);
cmd->num_slots = align(cmd_size, 8) / 8;
cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */
cmd->type = encode_index_type(type);
cmd->count = count; /* truncated */
cmd->indices = (uintptr_t)indices; /* truncated */
cmd->user_buffer_mask = user_buffer_mask;
cmd->index_buffer = index_buffer;
variable_data = (char*)(cmd + 1);
} else {
int cmd_size = sizeof(struct marshal_cmd_DrawElementsUserBuf) +
buffers_size + offsets_size;
struct marshal_cmd_DrawElementsUserBuf *cmd;
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsUserBuf, cmd_size);
cmd->num_slots = align(cmd_size, 8) / 8;
cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */
cmd->type = encode_index_type(type);
cmd->count = count;
cmd->indices = indices;
cmd->instance_count = instance_count;
cmd->basevertex = basevertex;
cmd->baseinstance = baseinstance;
cmd->user_buffer_mask = user_buffer_mask;
cmd->index_buffer = index_buffer;
cmd->drawid = drawid;
variable_data = (char*)(cmd + 1);
}
if (user_buffer_mask) {
char *variable_data = (char*)(cmd + 1);
memcpy(variable_data, buffers, buffers_size);
variable_data += buffers_size;
memcpy(variable_data, offsets, offsets_size);
@ -1927,6 +1969,12 @@ _mesa_marshal_DrawElementsUserBuf(const GLvoid *cmd)
unreachable("should never end up here");
}
void GLAPIENTRY
_mesa_marshal_DrawElementsUserBufPacked(const GLvoid *cmd)
{
unreachable("should never end up here");
}
void GLAPIENTRY
_mesa_marshal_MultiDrawArraysUserBuf(void)
{

View file

@ -76,6 +76,18 @@ struct marshal_cmd_DrawElementsUserBuf
struct gl_buffer_object *index_buffer;
};
struct marshal_cmd_DrawElementsUserBufPacked
{
struct marshal_cmd_base cmd_base;
GLenum8 mode;
GLindextype type;
uint16_t num_slots;
GLushort count;
GLuint user_buffer_mask;
GLuint indices;
struct gl_buffer_object *index_buffer;
};
static inline void *
_mesa_glthread_allocate_command(struct gl_context *ctx,
uint16_t cmd_id,