mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 13:58:04 +02:00
glthread: rewrite glBindBuffer packing
We always reserved space for a doubled glBindBuffer call, occupying 2 slots. Thanks to the removal of cmd_size, we can finally represent glBindBuffer in only 1 slot, so do that. This saves space if there is only 1 glBindBuffer call. The combining of back-to-back BindBuffer calls is preserved by keeping track of 2 last BindBuffer calls. 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:
parent
1f9b554839
commit
5925a864b5
3 changed files with 41 additions and 47 deletions
|
|
@ -347,7 +347,8 @@ glthread_finalize_batch(struct glthread_state *glthread,
|
|||
glthread->used = 0;
|
||||
|
||||
glthread->LastCallList = NULL;
|
||||
glthread->LastBindBuffer = NULL;
|
||||
glthread->LastBindBuffer1 = NULL;
|
||||
glthread->LastBindBuffer2 = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -274,7 +274,8 @@ struct glthread_state
|
|||
|
||||
/** The last added call of the given function. */
|
||||
struct marshal_cmd_CallList *LastCallList;
|
||||
struct marshal_cmd_BindBuffer *LastBindBuffer;
|
||||
struct marshal_cmd_BindBuffer *LastBindBuffer1;
|
||||
struct marshal_cmd_BindBuffer *LastBindBuffer2;
|
||||
|
||||
/** Global mutex update info. */
|
||||
unsigned GlobalLockUpdateBatchCounter;
|
||||
|
|
|
|||
|
|
@ -213,33 +213,18 @@ _mesa_glthread_BindBuffer(struct gl_context *ctx, GLenum target, GLuint buffer)
|
|||
}
|
||||
}
|
||||
|
||||
/* This can hold up to 2 BindBuffer calls. This is used to eliminate
|
||||
* duplicated BindBuffer calls, which are plentiful in viewperf2020/catia.
|
||||
* In this example, the first 2 calls are eliminated by glthread by keeping
|
||||
* track of the last 2 BindBuffer calls and overwriting them if the target
|
||||
* matches.
|
||||
*
|
||||
* glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
* glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
* glBindBuffer(GL_ARRAY_BUFFER, 6);
|
||||
* glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 7);
|
||||
*/
|
||||
struct marshal_cmd_BindBuffer
|
||||
{
|
||||
struct marshal_cmd_base cmd_base;
|
||||
GLenum16 target[2];
|
||||
GLuint buffer[2];
|
||||
GLenum16 target;
|
||||
GLuint buffer;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
_mesa_unmarshal_BindBuffer(struct gl_context *ctx,
|
||||
const struct marshal_cmd_BindBuffer *restrict cmd)
|
||||
{
|
||||
CALL_BindBuffer(ctx->Dispatch.Current, (cmd->target[0], cmd->buffer[0]));
|
||||
|
||||
if (cmd->target[1])
|
||||
CALL_BindBuffer(ctx->Dispatch.Current, (cmd->target[1], cmd->buffer[1]));
|
||||
|
||||
CALL_BindBuffer(ctx->Dispatch.Current, (cmd->target, cmd->buffer));
|
||||
return align(sizeof(struct marshal_cmd_BindBuffer), 8) / 8;
|
||||
}
|
||||
|
||||
|
|
@ -247,46 +232,53 @@ void GLAPIENTRY
|
|||
_mesa_marshal_BindBuffer(GLenum target, GLuint buffer)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct glthread_state *glthread = &ctx->GLThread;
|
||||
struct marshal_cmd_BindBuffer *last = glthread->LastBindBuffer;
|
||||
int cmd_size = sizeof(struct marshal_cmd_BindBuffer);
|
||||
|
||||
_mesa_glthread_BindBuffer(ctx, target, buffer);
|
||||
|
||||
/* If the last call is BindBuffer... */
|
||||
if (_mesa_glthread_call_is_last(glthread, &last->cmd_base,
|
||||
struct glthread_state *glthread = &ctx->GLThread;
|
||||
struct marshal_cmd_BindBuffer *last1 = glthread->LastBindBuffer1;
|
||||
struct marshal_cmd_BindBuffer *last2 = glthread->LastBindBuffer2;
|
||||
int cmd_size = sizeof(struct marshal_cmd_BindBuffer);
|
||||
|
||||
/* Eliminate duplicated BindBuffer calls, which are plentiful
|
||||
* in viewperf2020/catia. In this example, the first 2 calls are eliminated
|
||||
* by glthread by keeping track of the last 2 BindBuffer calls and
|
||||
* overwriting them if the target matches.
|
||||
*
|
||||
* glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
* glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
* glBindBuffer(GL_ARRAY_BUFFER, 6);
|
||||
* glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 7);
|
||||
*
|
||||
* If the last call is BindBuffer...
|
||||
* last2 is more recent. last1 is before last2.
|
||||
*/
|
||||
if (_mesa_glthread_call_is_last(glthread, &last2->cmd_base,
|
||||
align(cmd_size, 8) / 8)) {
|
||||
/* If the target is in the last call and unbinding the buffer, overwrite
|
||||
* the buffer ID there.
|
||||
*
|
||||
* We can't optimize out binding non-zero buffers because binding also
|
||||
* creates the GL objects (like glCreateBuffers), which can't be skipped.
|
||||
*/
|
||||
if (target == last->target[0] && !last->buffer[0]) {
|
||||
last->buffer[0] = buffer;
|
||||
return;
|
||||
}
|
||||
if (target == last->target[1] && !last->buffer[1]) {
|
||||
last->buffer[1] = buffer;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the last call has an unused buffer field, add this call to it. */
|
||||
if (last->target[1] == 0) {
|
||||
last->target[1] = MIN2(target, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
last->buffer[1] = buffer;
|
||||
if (target == last2->target) {
|
||||
/* We can't overwrite binding non-zero buffers because binding also
|
||||
* creates the GL objects (like glCreateBuffers), which can't be skipped.
|
||||
*/
|
||||
if (!last2->buffer) {
|
||||
last2->buffer = buffer;
|
||||
return;
|
||||
}
|
||||
} else if (last1 + 1 == last2 && target == last1->target &&
|
||||
!last1->buffer) {
|
||||
last1->buffer = buffer;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct marshal_cmd_BindBuffer *cmd =
|
||||
_mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BindBuffer, cmd_size);
|
||||
cmd->target = MIN2(target, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->buffer = buffer;
|
||||
|
||||
cmd->target[0] = MIN2(target, 0xffff); /* clamped to 0xffff (invalid enum) */
|
||||
cmd->target[1] = 0;
|
||||
cmd->buffer[0] = buffer;
|
||||
|
||||
glthread->LastBindBuffer = cmd;
|
||||
glthread->LastBindBuffer1 = last2;
|
||||
glthread->LastBindBuffer2 = cmd;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue