From 9939f20a499b4201ab4ebdc0d0e8dde01f78637a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 31 Jan 2024 01:18:32 -0500 Subject: [PATCH] glthread: execute small glDrawPixels asynchronously Compute the image size and copy the image into the batch. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/mapi/glapi/gen/gl_API.xml | 3 +- src/mesa/main/glthread_pixels.c | 73 +++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml index 01f1598f851..d12d33364ac 100644 --- a/src/mapi/glapi/gen/gl_API.xml +++ b/src/mapi/glapi/gen/gl_API.xml @@ -2682,8 +2682,7 @@ - + diff --git a/src/mesa/main/glthread_pixels.c b/src/mesa/main/glthread_pixels.c index c8fed4bb7db..bceef8081dd 100644 --- a/src/mesa/main/glthread_pixels.c +++ b/src/mesa/main/glthread_pixels.c @@ -9,6 +9,7 @@ #include "main/image.h" #define MAX_BITMAP_BYTE_SIZE 4096 +#define MAX_DRAWPIX_BYTE_SIZE 4096 struct marshal_cmd_Bitmap { @@ -87,3 +88,75 @@ _mesa_marshal_Bitmap(GLsizei width, GLsizei height, GLfloat xorig, CALL_Bitmap(ctx->Dispatch.Current, (width, height, xorig, yorig, xmove, ymove, bitmap)); } + +struct marshal_cmd_DrawPixels +{ + struct marshal_cmd_base cmd_base; + uint16_t num_slots; + GLenum16 format; + GLenum16 type; + GLsizei width; + GLsizei height; + GLvoid *pixels; +}; + +uint32_t +_mesa_unmarshal_DrawPixels(struct gl_context *ctx, + const struct marshal_cmd_DrawPixels *restrict cmd) +{ + CALL_DrawPixels(ctx->Dispatch.Current, + (cmd->width, cmd->height, cmd->format, cmd->type, + cmd->pixels)); + return cmd->num_slots; +} + +void GLAPIENTRY +_mesa_marshal_DrawPixels(GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + int cmd_size = sizeof(struct marshal_cmd_DrawPixels); + + /* If not building a display list... */ + if (!ctx->GLThread.ListMode) { + /* PBO */ + if (!_mesa_glthread_has_no_unpack_buffer(ctx)) { + struct marshal_cmd_DrawPixels *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawPixels, + cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->format = MIN2(format, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->width = width; + cmd->height = height; + cmd->pixels = (void *)pixels; + return; + } + + /* A negative stride is unimplemented (it inverts the offset). */ + if (!ctx->Unpack.Invert) { + size_t image_size = + (size_t)_mesa_image_row_stride(&ctx->GLThread.Unpack, + width, format, type) * height; + + /* If the image is small enough, copy it into the batch. */ + if (image_size <= MAX_DRAWPIX_BYTE_SIZE) { + struct marshal_cmd_DrawPixels *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawPixels, + cmd_size + image_size); + cmd->num_slots = align(cmd_size + image_size, 8) / 8; + cmd->format = MIN2(format, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->width = width; + cmd->height = height; + cmd->pixels = cmd + 1; + memcpy(cmd->pixels, pixels, image_size); + return; + } + } + } + + _mesa_glthread_finish_before(ctx, "DrawPixels"); + CALL_DrawPixels(ctx->Dispatch.Current, + (width, height, format, type, pixels)); +}