mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 13:48:06 +02:00
glthread: rewrite CallList merging and do it in the app thread
This looks simpler and hopefully faster, but it may just move the overhead to the app thread. Acked-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18199>
This commit is contained in:
parent
6f8cbbfce2
commit
3cb96b18f6
4 changed files with 57 additions and 52 deletions
|
|
@ -244,6 +244,8 @@ _mesa_glthread_flush_batch(struct gl_context *ctx)
|
|||
if (false) {
|
||||
glthread_unmarshal_batch(next, NULL, 0);
|
||||
_glapi_set_dispatch(ctx->CurrentClientDispatch);
|
||||
|
||||
glthread->LastCallList = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +258,8 @@ _mesa_glthread_flush_batch(struct gl_context *ctx)
|
|||
glthread->next = (glthread->next + 1) % MARSHAL_MAX_BATCHES;
|
||||
glthread->next_batch = &glthread->batches[glthread->next];
|
||||
glthread->used = 0;
|
||||
|
||||
glthread->LastCallList = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -293,6 +297,8 @@ _mesa_glthread_finish(struct gl_context *ctx)
|
|||
next->used = glthread->used;
|
||||
glthread->used = 0;
|
||||
|
||||
glthread->LastCallList = NULL;
|
||||
|
||||
/* Since glthread_unmarshal_batch changes the dispatch to direct,
|
||||
* restore it after it's done.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -240,6 +240,9 @@ struct glthread_state
|
|||
GLuint CurrentDrawFramebuffer;
|
||||
GLuint CurrentReadFramebuffer;
|
||||
GLuint CurrentProgram;
|
||||
|
||||
/** The last added call of the given function. */
|
||||
struct marshal_cmd_CallList *LastCallList;
|
||||
};
|
||||
|
||||
void _mesa_glthread_init(struct gl_context *ctx);
|
||||
|
|
|
|||
|
|
@ -26,66 +26,68 @@
|
|||
#include "main/glthread_marshal.h"
|
||||
#include "main/dispatch.h"
|
||||
|
||||
struct marshal_cmd_CallList
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLuint num;
|
||||
GLuint list[];
|
||||
};
|
||||
|
||||
uint32_t
|
||||
_mesa_unmarshal_CallList(struct gl_context *ctx, const struct marshal_cmd_CallList *cmd, const uint64_t *last)
|
||||
{
|
||||
const GLuint list = cmd->list;
|
||||
uint64_t *ptr = (uint64_t *) cmd;
|
||||
const unsigned cmd_size = align(sizeof(*cmd), 8) / 8;
|
||||
const GLuint num = cmd->num;
|
||||
|
||||
assert(cmd_size == cmd->cmd_base.cmd_size);
|
||||
ptr += cmd_size;
|
||||
|
||||
if (ptr < last) {
|
||||
const struct marshal_cmd_base *next =
|
||||
(const struct marshal_cmd_base *)ptr;
|
||||
|
||||
/* If the 'next' is also a DISPATCH_CMD_CallList, we transform 'cmd' and 'next' in a CALL_CallLists.
|
||||
* If the following commands are also CallList they're including in the CallLists we're building.
|
||||
*/
|
||||
if (next->cmd_id == DISPATCH_CMD_CallList) {
|
||||
const int max_list_count = 2048;
|
||||
struct marshal_cmd_CallList *next_callist = (struct marshal_cmd_CallList *) next;
|
||||
uint32_t *lists = alloca(max_list_count * sizeof(uint32_t));
|
||||
|
||||
lists[0] = cmd->list;
|
||||
lists[1] = next_callist->list;
|
||||
|
||||
int count = 2;
|
||||
|
||||
assert(cmd_size == next_callist->cmd_base.cmd_size);
|
||||
ptr += cmd_size;
|
||||
|
||||
while (ptr < last && count < max_list_count) {
|
||||
next = (const struct marshal_cmd_base *)ptr;
|
||||
if (next->cmd_id == DISPATCH_CMD_CallList) {
|
||||
next_callist = (struct marshal_cmd_CallList *) next;
|
||||
lists[count++] = next_callist->list;
|
||||
assert(cmd_size == next_callist->cmd_base.cmd_size);
|
||||
ptr += cmd_size;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CALL_CallLists(ctx->CurrentServerDispatch, (count, GL_UNSIGNED_INT, lists));
|
||||
|
||||
return (uint32_t) (ptr - (uint64_t*)cmd);
|
||||
}
|
||||
if (cmd->cmd_base.cmd_size == sizeof(*cmd) / 8) {
|
||||
CALL_CallList(ctx->CurrentServerDispatch, (num));
|
||||
} else {
|
||||
CALL_CallLists(ctx->CurrentServerDispatch, (num, GL_UNSIGNED_INT, cmd->list));
|
||||
}
|
||||
|
||||
CALL_CallList(ctx->CurrentServerDispatch, (list));
|
||||
return cmd_size;
|
||||
return cmd->cmd_base.cmd_size;
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_marshal_CallList(GLuint list)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct glthread_state *glthread = &ctx->GLThread;
|
||||
struct marshal_cmd_CallList *last = glthread->LastCallList;
|
||||
|
||||
_mesa_glthread_CallList(ctx, list);
|
||||
|
||||
/* If the last call is CallList and there is enough space to append another list... */
|
||||
if (last &&
|
||||
(uint64_t*)last + last->cmd_base.cmd_size ==
|
||||
&glthread->next_batch->buffer[glthread->used] &&
|
||||
glthread->used + 1 <= MARSHAL_MAX_CMD_SIZE / 8) {
|
||||
STATIC_ASSERT(sizeof(*last) == 8);
|
||||
|
||||
/* Add the list to the last call. */
|
||||
if (last->cmd_base.cmd_size > sizeof(*last) / 8) {
|
||||
last->list[last->num++] = list;
|
||||
if (last->num % 2 == 1) {
|
||||
last->cmd_base.cmd_size++;
|
||||
glthread->used++;
|
||||
}
|
||||
} else {
|
||||
/* Initially, num contains the first list. After we increase cmd_size,
|
||||
* num contains the number of lists and list[] contains the lists.
|
||||
*/
|
||||
last->list[0] = last->num;
|
||||
last->list[1] = list;
|
||||
last->num = 2;
|
||||
last->cmd_base.cmd_size++;
|
||||
glthread->used++;
|
||||
}
|
||||
assert(align(sizeof(*last) + last->num * 4, 8) / 8 == last->cmd_base.cmd_size);
|
||||
return;
|
||||
}
|
||||
|
||||
int cmd_size = sizeof(struct marshal_cmd_CallList);
|
||||
struct marshal_cmd_CallList *cmd;
|
||||
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_CallList, cmd_size);
|
||||
cmd->list = list;
|
||||
cmd->num = list;
|
||||
|
||||
_mesa_glthread_CallList(ctx, list);
|
||||
glthread->LastCallList = cmd;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -865,10 +865,4 @@ _mesa_glthread_DeleteFramebuffers(struct gl_context *ctx, GLsizei n,
|
|||
}
|
||||
}
|
||||
|
||||
struct marshal_cmd_CallList
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLuint list;
|
||||
};
|
||||
|
||||
#endif /* MARSHAL_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue