1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright 2024 Advanced Micro Devices, Inc.
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker */
6*61046927SAndroid Build Coastguard Worker
7*61046927SAndroid Build Coastguard Worker #include "main/glthread_marshal.h"
8*61046927SAndroid Build Coastguard Worker #include "main/dispatch.h"
9*61046927SAndroid Build Coastguard Worker #include "main/image.h"
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #define MAX_BITMAP_BYTE_SIZE 4096
12*61046927SAndroid Build Coastguard Worker #define MAX_DRAWPIX_BYTE_SIZE 4096
13*61046927SAndroid Build Coastguard Worker
14*61046927SAndroid Build Coastguard Worker struct marshal_cmd_Bitmap
15*61046927SAndroid Build Coastguard Worker {
16*61046927SAndroid Build Coastguard Worker struct marshal_cmd_base cmd_base;
17*61046927SAndroid Build Coastguard Worker uint16_t num_slots;
18*61046927SAndroid Build Coastguard Worker GLsizei width;
19*61046927SAndroid Build Coastguard Worker GLsizei height;
20*61046927SAndroid Build Coastguard Worker GLfloat xorig;
21*61046927SAndroid Build Coastguard Worker GLfloat yorig;
22*61046927SAndroid Build Coastguard Worker GLfloat xmove;
23*61046927SAndroid Build Coastguard Worker GLfloat ymove;
24*61046927SAndroid Build Coastguard Worker GLubyte *bitmap;
25*61046927SAndroid Build Coastguard Worker };
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_Bitmap(struct gl_context * ctx,const struct marshal_cmd_Bitmap * restrict cmd)28*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_Bitmap(struct gl_context *ctx,
29*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_Bitmap *restrict cmd)
30*61046927SAndroid Build Coastguard Worker {
31*61046927SAndroid Build Coastguard Worker CALL_Bitmap(ctx->Dispatch.Current,
32*61046927SAndroid Build Coastguard Worker (cmd->width, cmd->height, cmd->xorig, cmd->yorig, cmd->xmove,
33*61046927SAndroid Build Coastguard Worker cmd->ymove, cmd->bitmap));
34*61046927SAndroid Build Coastguard Worker return cmd->num_slots;
35*61046927SAndroid Build Coastguard Worker }
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_Bitmap(GLsizei width,GLsizei height,GLfloat xorig,GLfloat yorig,GLfloat xmove,GLfloat ymove,const GLubyte * bitmap)38*61046927SAndroid Build Coastguard Worker _mesa_marshal_Bitmap(GLsizei width, GLsizei height, GLfloat xorig,
39*61046927SAndroid Build Coastguard Worker GLfloat yorig, GLfloat xmove, GLfloat ymove,
40*61046927SAndroid Build Coastguard Worker const GLubyte *bitmap)
41*61046927SAndroid Build Coastguard Worker {
42*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
43*61046927SAndroid Build Coastguard Worker int cmd_size = sizeof(struct marshal_cmd_Bitmap);
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker /* If not building a display list... */
46*61046927SAndroid Build Coastguard Worker if (!ctx->GLThread.ListMode) {
47*61046927SAndroid Build Coastguard Worker /* PBO path or bitmap == NULL (which means xmove/ymove only move the raster
48*61046927SAndroid Build Coastguard Worker * pos.
49*61046927SAndroid Build Coastguard Worker */
50*61046927SAndroid Build Coastguard Worker if (!bitmap || _mesa_glthread_has_unpack_buffer(ctx)) {
51*61046927SAndroid Build Coastguard Worker struct marshal_cmd_Bitmap *cmd =
52*61046927SAndroid Build Coastguard Worker _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_Bitmap,
53*61046927SAndroid Build Coastguard Worker cmd_size);
54*61046927SAndroid Build Coastguard Worker cmd->num_slots = align(cmd_size, 8) / 8;
55*61046927SAndroid Build Coastguard Worker cmd->width = width;
56*61046927SAndroid Build Coastguard Worker cmd->height = height;
57*61046927SAndroid Build Coastguard Worker cmd->xorig = xorig;
58*61046927SAndroid Build Coastguard Worker cmd->yorig = yorig;
59*61046927SAndroid Build Coastguard Worker cmd->xmove = xmove;
60*61046927SAndroid Build Coastguard Worker cmd->ymove = ymove;
61*61046927SAndroid Build Coastguard Worker cmd->bitmap = (GLubyte *)bitmap;
62*61046927SAndroid Build Coastguard Worker return;
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker size_t bitmap_size =
66*61046927SAndroid Build Coastguard Worker (size_t)_mesa_image_row_stride(&ctx->GLThread.Unpack, width,
67*61046927SAndroid Build Coastguard Worker GL_COLOR_INDEX, GL_BITMAP) * height;
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker /* If the bitmap is small enough, copy it into the batch. */
70*61046927SAndroid Build Coastguard Worker if (bitmap_size <= MAX_BITMAP_BYTE_SIZE) {
71*61046927SAndroid Build Coastguard Worker struct marshal_cmd_Bitmap *cmd =
72*61046927SAndroid Build Coastguard Worker _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_Bitmap,
73*61046927SAndroid Build Coastguard Worker cmd_size + bitmap_size);
74*61046927SAndroid Build Coastguard Worker cmd->num_slots = align(cmd_size + bitmap_size, 8) / 8;
75*61046927SAndroid Build Coastguard Worker cmd->width = width;
76*61046927SAndroid Build Coastguard Worker cmd->height = height;
77*61046927SAndroid Build Coastguard Worker cmd->xorig = xorig;
78*61046927SAndroid Build Coastguard Worker cmd->yorig = yorig;
79*61046927SAndroid Build Coastguard Worker cmd->xmove = xmove;
80*61046927SAndroid Build Coastguard Worker cmd->ymove = ymove;
81*61046927SAndroid Build Coastguard Worker cmd->bitmap = (GLubyte *)(cmd + 1);
82*61046927SAndroid Build Coastguard Worker memcpy(cmd->bitmap, bitmap, bitmap_size);
83*61046927SAndroid Build Coastguard Worker return;
84*61046927SAndroid Build Coastguard Worker }
85*61046927SAndroid Build Coastguard Worker }
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker _mesa_glthread_finish_before(ctx, "Bitmap");
88*61046927SAndroid Build Coastguard Worker CALL_Bitmap(ctx->Dispatch.Current,
89*61046927SAndroid Build Coastguard Worker (width, height, xorig, yorig, xmove, ymove, bitmap));
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker struct marshal_cmd_DrawPixels
93*61046927SAndroid Build Coastguard Worker {
94*61046927SAndroid Build Coastguard Worker struct marshal_cmd_base cmd_base;
95*61046927SAndroid Build Coastguard Worker uint16_t num_slots;
96*61046927SAndroid Build Coastguard Worker GLenum16 format;
97*61046927SAndroid Build Coastguard Worker GLenum16 type;
98*61046927SAndroid Build Coastguard Worker GLsizei width;
99*61046927SAndroid Build Coastguard Worker GLsizei height;
100*61046927SAndroid Build Coastguard Worker GLvoid *pixels;
101*61046927SAndroid Build Coastguard Worker };
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_DrawPixels(struct gl_context * ctx,const struct marshal_cmd_DrawPixels * restrict cmd)104*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_DrawPixels(struct gl_context *ctx,
105*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_DrawPixels *restrict cmd)
106*61046927SAndroid Build Coastguard Worker {
107*61046927SAndroid Build Coastguard Worker CALL_DrawPixels(ctx->Dispatch.Current,
108*61046927SAndroid Build Coastguard Worker (cmd->width, cmd->height, cmd->format, cmd->type,
109*61046927SAndroid Build Coastguard Worker cmd->pixels));
110*61046927SAndroid Build Coastguard Worker return cmd->num_slots;
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_DrawPixels(GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)114*61046927SAndroid Build Coastguard Worker _mesa_marshal_DrawPixels(GLsizei width, GLsizei height, GLenum format,
115*61046927SAndroid Build Coastguard Worker GLenum type, const GLvoid *pixels)
116*61046927SAndroid Build Coastguard Worker {
117*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
118*61046927SAndroid Build Coastguard Worker int cmd_size = sizeof(struct marshal_cmd_DrawPixels);
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker /* If not building a display list... */
121*61046927SAndroid Build Coastguard Worker if (!ctx->GLThread.ListMode) {
122*61046927SAndroid Build Coastguard Worker /* PBO */
123*61046927SAndroid Build Coastguard Worker if (_mesa_glthread_has_unpack_buffer(ctx)) {
124*61046927SAndroid Build Coastguard Worker struct marshal_cmd_DrawPixels *cmd =
125*61046927SAndroid Build Coastguard Worker _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawPixels,
126*61046927SAndroid Build Coastguard Worker cmd_size);
127*61046927SAndroid Build Coastguard Worker cmd->num_slots = align(cmd_size, 8) / 8;
128*61046927SAndroid Build Coastguard Worker cmd->format = MIN2(format, 0xffff); /* clamped to 0xffff (invalid enum) */
129*61046927SAndroid Build Coastguard Worker cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */
130*61046927SAndroid Build Coastguard Worker cmd->width = width;
131*61046927SAndroid Build Coastguard Worker cmd->height = height;
132*61046927SAndroid Build Coastguard Worker cmd->pixels = (void *)pixels;
133*61046927SAndroid Build Coastguard Worker return;
134*61046927SAndroid Build Coastguard Worker }
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker /* A negative stride is unimplemented (it inverts the offset). */
137*61046927SAndroid Build Coastguard Worker if (!ctx->Unpack.Invert) {
138*61046927SAndroid Build Coastguard Worker size_t image_size =
139*61046927SAndroid Build Coastguard Worker (size_t)_mesa_image_row_stride(&ctx->GLThread.Unpack,
140*61046927SAndroid Build Coastguard Worker width, format, type) * height;
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker /* If the image is small enough, copy it into the batch. */
143*61046927SAndroid Build Coastguard Worker if (image_size <= MAX_DRAWPIX_BYTE_SIZE) {
144*61046927SAndroid Build Coastguard Worker struct marshal_cmd_DrawPixels *cmd =
145*61046927SAndroid Build Coastguard Worker _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawPixels,
146*61046927SAndroid Build Coastguard Worker cmd_size + image_size);
147*61046927SAndroid Build Coastguard Worker cmd->num_slots = align(cmd_size + image_size, 8) / 8;
148*61046927SAndroid Build Coastguard Worker cmd->format = MIN2(format, 0xffff); /* clamped to 0xffff (invalid enum) */
149*61046927SAndroid Build Coastguard Worker cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */
150*61046927SAndroid Build Coastguard Worker cmd->width = width;
151*61046927SAndroid Build Coastguard Worker cmd->height = height;
152*61046927SAndroid Build Coastguard Worker cmd->pixels = cmd + 1;
153*61046927SAndroid Build Coastguard Worker memcpy(cmd->pixels, pixels, image_size);
154*61046927SAndroid Build Coastguard Worker return;
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker }
157*61046927SAndroid Build Coastguard Worker }
158*61046927SAndroid Build Coastguard Worker
159*61046927SAndroid Build Coastguard Worker _mesa_glthread_finish_before(ctx, "DrawPixels");
160*61046927SAndroid Build Coastguard Worker CALL_DrawPixels(ctx->Dispatch.Current,
161*61046927SAndroid Build Coastguard Worker (width, height, format, type, pixels));
162*61046927SAndroid Build Coastguard Worker }
163