From 24f14f8daac2268fc650c81ad4c666fb7f21d09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 9 Jan 2024 03:48:00 -0500 Subject: [PATCH] glthread: add a packed version of DrawElementsUserBuf The reduces the call size by 24 bytes. Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/mapi/glapi/gen/gl_API.xml | 4 ++ src/mapi/glapi/gen/static_data.py | 1 + src/mesa/main/draw.c | 34 +++++++++++++ src/mesa/main/glthread_draw.c | 80 ++++++++++++++++++++++++------- src/mesa/main/glthread_marshal.h | 12 +++++ 5 files changed, 115 insertions(+), 16 deletions(-) diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml index 24f97e0f7f6..22362d3081f 100644 --- a/src/mapi/glapi/gen/gl_API.xml +++ b/src/mapi/glapi/gen/gl_API.xml @@ -12944,6 +12944,10 @@ + + + + diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py index 9c4ce55f6b4..f4f1f4bf0f5 100644 --- a/src/mapi/glapi/gen/static_data.py +++ b/src/mapi/glapi/gen/static_data.py @@ -1705,6 +1705,7 @@ offsets = { "DrawElementsInstancedBaseVertexBaseInstanceDrawID": 1669, "InternalInvalidateFramebufferAncillaryMESA": 1670, "DrawElementsPacked": 1671, + "DrawElementsUserBufPacked": 1672, } functions = [ diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index 764c1284ecd..26a074dd2e7 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -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 diff --git a/src/mesa/main/glthread_draw.c b/src/mesa/main/glthread_draw.c index 9fc41c81393..1bef35b0d71 100644 --- a/src/mesa/main/glthread_draw.c +++ b/src/mesa/main/glthread_draw.c @@ -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) { diff --git a/src/mesa/main/glthread_marshal.h b/src/mesa/main/glthread_marshal.h index f8e0bb6d391..5084301ebbf 100644 --- a/src/mesa/main/glthread_marshal.h +++ b/src/mesa/main/glthread_marshal.h @@ -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,