glthread: execute small glDrawPixels asynchronously

Compute the image size and copy the image into the batch.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27490>
This commit is contained in:
Marek Olšák 2024-01-31 01:18:32 -05:00 committed by Marge Bot
parent b43b111b19
commit 9939f20a49
2 changed files with 74 additions and 2 deletions

View file

@ -2682,8 +2682,7 @@
<glx sop="111"/>
</function>
<function name="DrawPixels" deprecated="3.1" exec="dlist"
marshal="async" marshal_sync="_mesa_glthread_has_no_unpack_buffer(ctx)">
<function name="DrawPixels" deprecated="3.1" exec="dlist" marshal="custom">
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="format" type="GLenum"/>

View file

@ -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));
}