xref: /aosp_15_r20/external/mesa3d/src/mesa/main/glthread_list.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2020 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "c99_alloca.h"
25 
26 #include "main/glthread_marshal.h"
27 #include "main/dispatch.h"
28 
29 struct marshal_cmd_CallList
30 {
31    struct marshal_cmd_base cmd_base;
32    uint16_t num_slots;
33    GLuint num;
34    GLuint list[];
35 };
36 
37 uint32_t
_mesa_unmarshal_CallList(struct gl_context * ctx,const struct marshal_cmd_CallList * restrict cmd)38 _mesa_unmarshal_CallList(struct gl_context *ctx,
39                          const struct marshal_cmd_CallList *restrict cmd)
40 {
41    const GLuint num = cmd->num;
42 
43    if (cmd->num_slots == sizeof(*cmd) / 8) {
44       CALL_CallList(ctx->Dispatch.Current, (num));
45    } else {
46       CALL_CallLists(ctx->Dispatch.Current, (num, GL_UNSIGNED_INT, cmd->list));
47    }
48 
49    return cmd->num_slots;
50 }
51 
52 void GLAPIENTRY
_mesa_marshal_CallList(GLuint list)53 _mesa_marshal_CallList(GLuint list)
54 {
55    GET_CURRENT_CONTEXT(ctx);
56    struct glthread_state *glthread = &ctx->GLThread;
57    struct marshal_cmd_CallList *last = glthread->LastCallList;
58 
59    _mesa_glthread_CallList(ctx, list);
60 
61    /* If the last call is CallList and there is enough space to append another list... */
62    if (last &&
63        _mesa_glthread_call_is_last(glthread, &last->cmd_base, last->num_slots) &&
64        glthread->used + 1 <= MARSHAL_MAX_CMD_SIZE / 8) {
65       STATIC_ASSERT(sizeof(*last) == 8);
66 
67       /* Add the list to the last call. */
68       if (last->num_slots > sizeof(*last) / 8) {
69          last->list[last->num++] = list;
70          if (last->num % 2 == 1) {
71             last->num_slots++;
72             glthread->used++;
73          }
74       } else {
75          /* Initially, num contains the first list. After we increase cmd_size,
76           * num contains the number of lists and list[] contains the lists.
77           */
78          last->list[0] = last->num;
79          last->list[1] = list;
80          last->num = 2;
81          last->num_slots++;
82          glthread->used++;
83       }
84       assert(align(sizeof(*last) + last->num * 4, 8) / 8 == last->num_slots);
85       return;
86    }
87 
88    int cmd_size = sizeof(struct marshal_cmd_CallList);
89    struct marshal_cmd_CallList *cmd;
90    cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_CallList, cmd_size);
91    cmd->num_slots = align(cmd_size, 8) / 8;
92    cmd->num = list;
93 
94    glthread->LastCallList = cmd;
95 }
96