xref: /aosp_15_r20/external/mesa3d/src/mesa/main/glthread_varray.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2020 Advanced Micro Devices, Inc.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker /* This implements vertex array state tracking for glthread. It's separate
25*61046927SAndroid Build Coastguard Worker  * from the rest of Mesa. Only minimum functionality is implemented here
26*61046927SAndroid Build Coastguard Worker  * to serve glthread.
27*61046927SAndroid Build Coastguard Worker  */
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker #include "main/glthread.h"
30*61046927SAndroid Build Coastguard Worker #include "main/glformats.h"
31*61046927SAndroid Build Coastguard Worker #include "main/mtypes.h"
32*61046927SAndroid Build Coastguard Worker #include "main/hash.h"
33*61046927SAndroid Build Coastguard Worker #include "main/dispatch.h"
34*61046927SAndroid Build Coastguard Worker #include "main/varray.h"
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker static unsigned
element_size(union gl_vertex_format_user format)37*61046927SAndroid Build Coastguard Worker element_size(union gl_vertex_format_user format)
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker    return _mesa_bytes_per_vertex_attrib(format.Size, format.Type);
40*61046927SAndroid Build Coastguard Worker }
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker static void
init_attrib(struct glthread_attrib * attrib,int index,int size,GLenum type)43*61046927SAndroid Build Coastguard Worker init_attrib(struct glthread_attrib *attrib, int index, int size, GLenum type)
44*61046927SAndroid Build Coastguard Worker {
45*61046927SAndroid Build Coastguard Worker    attrib->Format = MESA_PACK_VFORMAT(type, size, 0, 0, 0);
46*61046927SAndroid Build Coastguard Worker    attrib->ElementSize = element_size(attrib->Format);
47*61046927SAndroid Build Coastguard Worker    attrib->RelativeOffset = 0;
48*61046927SAndroid Build Coastguard Worker    attrib->BufferIndex = index;
49*61046927SAndroid Build Coastguard Worker    attrib->Stride = attrib->ElementSize;
50*61046927SAndroid Build Coastguard Worker    attrib->Divisor = 0;
51*61046927SAndroid Build Coastguard Worker    attrib->EnabledAttribCount = 0;
52*61046927SAndroid Build Coastguard Worker    attrib->Pointer = NULL;
53*61046927SAndroid Build Coastguard Worker }
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_reset_vao(struct glthread_vao * vao)56*61046927SAndroid Build Coastguard Worker _mesa_glthread_reset_vao(struct glthread_vao *vao)
57*61046927SAndroid Build Coastguard Worker {
58*61046927SAndroid Build Coastguard Worker    vao->CurrentElementBufferName = 0;
59*61046927SAndroid Build Coastguard Worker    vao->UserEnabled = 0;
60*61046927SAndroid Build Coastguard Worker    vao->Enabled = 0;
61*61046927SAndroid Build Coastguard Worker    vao->BufferEnabled = 0;
62*61046927SAndroid Build Coastguard Worker    vao->UserPointerMask = 0;
63*61046927SAndroid Build Coastguard Worker    vao->NonNullPointerMask = 0;
64*61046927SAndroid Build Coastguard Worker    vao->NonZeroDivisorMask = 0;
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(vao->Attrib); i++) {
67*61046927SAndroid Build Coastguard Worker       switch (i) {
68*61046927SAndroid Build Coastguard Worker       case VERT_ATTRIB_NORMAL:
69*61046927SAndroid Build Coastguard Worker          init_attrib(&vao->Attrib[i], i, 3, GL_FLOAT);
70*61046927SAndroid Build Coastguard Worker          break;
71*61046927SAndroid Build Coastguard Worker       case VERT_ATTRIB_COLOR1:
72*61046927SAndroid Build Coastguard Worker          init_attrib(&vao->Attrib[i], i, 3, GL_FLOAT);
73*61046927SAndroid Build Coastguard Worker          break;
74*61046927SAndroid Build Coastguard Worker       case VERT_ATTRIB_FOG:
75*61046927SAndroid Build Coastguard Worker          init_attrib(&vao->Attrib[i], i, 1, GL_FLOAT);
76*61046927SAndroid Build Coastguard Worker          break;
77*61046927SAndroid Build Coastguard Worker       case VERT_ATTRIB_COLOR_INDEX:
78*61046927SAndroid Build Coastguard Worker          init_attrib(&vao->Attrib[i], i, 1, GL_FLOAT);
79*61046927SAndroid Build Coastguard Worker          break;
80*61046927SAndroid Build Coastguard Worker       case VERT_ATTRIB_EDGEFLAG:
81*61046927SAndroid Build Coastguard Worker          init_attrib(&vao->Attrib[i], i, 1, GL_UNSIGNED_BYTE);
82*61046927SAndroid Build Coastguard Worker          break;
83*61046927SAndroid Build Coastguard Worker       case VERT_ATTRIB_POINT_SIZE:
84*61046927SAndroid Build Coastguard Worker          init_attrib(&vao->Attrib[i], i, 1, GL_FLOAT);
85*61046927SAndroid Build Coastguard Worker          break;
86*61046927SAndroid Build Coastguard Worker       default:
87*61046927SAndroid Build Coastguard Worker          init_attrib(&vao->Attrib[i], i, 4, GL_FLOAT);
88*61046927SAndroid Build Coastguard Worker          break;
89*61046927SAndroid Build Coastguard Worker       }
90*61046927SAndroid Build Coastguard Worker    }
91*61046927SAndroid Build Coastguard Worker }
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker static struct glthread_vao *
lookup_vao(struct gl_context * ctx,GLuint id)94*61046927SAndroid Build Coastguard Worker lookup_vao(struct gl_context *ctx, GLuint id)
95*61046927SAndroid Build Coastguard Worker {
96*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
97*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao;
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker    assert(id != 0);
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    if (glthread->LastLookedUpVAO &&
102*61046927SAndroid Build Coastguard Worker        glthread->LastLookedUpVAO->Name == id) {
103*61046927SAndroid Build Coastguard Worker       vao = glthread->LastLookedUpVAO;
104*61046927SAndroid Build Coastguard Worker    } else {
105*61046927SAndroid Build Coastguard Worker       vao = _mesa_HashLookupLocked(&glthread->VAOs, id);
106*61046927SAndroid Build Coastguard Worker       if (!vao)
107*61046927SAndroid Build Coastguard Worker          return NULL;
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker       glthread->LastLookedUpVAO = vao;
110*61046927SAndroid Build Coastguard Worker    }
111*61046927SAndroid Build Coastguard Worker 
112*61046927SAndroid Build Coastguard Worker    return vao;
113*61046927SAndroid Build Coastguard Worker }
114*61046927SAndroid Build Coastguard Worker 
115*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_BindVertexArray(struct gl_context * ctx,GLuint id)116*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindVertexArray(struct gl_context *ctx, GLuint id)
117*61046927SAndroid Build Coastguard Worker {
118*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker    if (id == 0) {
121*61046927SAndroid Build Coastguard Worker       glthread->CurrentVAO = &glthread->DefaultVAO;
122*61046927SAndroid Build Coastguard Worker    } else {
123*61046927SAndroid Build Coastguard Worker       struct glthread_vao *vao = lookup_vao(ctx, id);
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker       if (vao)
126*61046927SAndroid Build Coastguard Worker          glthread->CurrentVAO = vao;
127*61046927SAndroid Build Coastguard Worker    }
128*61046927SAndroid Build Coastguard Worker }
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DeleteVertexArrays(struct gl_context * ctx,GLsizei n,const GLuint * ids)131*61046927SAndroid Build Coastguard Worker _mesa_glthread_DeleteVertexArrays(struct gl_context *ctx,
132*61046927SAndroid Build Coastguard Worker                                   GLsizei n, const GLuint *ids)
133*61046927SAndroid Build Coastguard Worker {
134*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
135*61046927SAndroid Build Coastguard Worker 
136*61046927SAndroid Build Coastguard Worker    if (!ids)
137*61046927SAndroid Build Coastguard Worker       return;
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < n; i++) {
140*61046927SAndroid Build Coastguard Worker       /* IDs equal to 0 should be silently ignored. */
141*61046927SAndroid Build Coastguard Worker       if (!ids[i])
142*61046927SAndroid Build Coastguard Worker          continue;
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker       struct glthread_vao *vao = lookup_vao(ctx, ids[i]);
145*61046927SAndroid Build Coastguard Worker       if (!vao)
146*61046927SAndroid Build Coastguard Worker          continue;
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker       /* If the array object is currently bound, the spec says "the binding
149*61046927SAndroid Build Coastguard Worker        * for that object reverts to zero and the default vertex array
150*61046927SAndroid Build Coastguard Worker        * becomes current."
151*61046927SAndroid Build Coastguard Worker        */
152*61046927SAndroid Build Coastguard Worker       if (glthread->CurrentVAO == vao)
153*61046927SAndroid Build Coastguard Worker          glthread->CurrentVAO = &glthread->DefaultVAO;
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker       if (glthread->LastLookedUpVAO == vao)
156*61046927SAndroid Build Coastguard Worker          glthread->LastLookedUpVAO = NULL;
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker       /* The ID is immediately freed for re-use */
159*61046927SAndroid Build Coastguard Worker       _mesa_HashRemoveLocked(&glthread->VAOs, vao->Name);
160*61046927SAndroid Build Coastguard Worker       free(vao);
161*61046927SAndroid Build Coastguard Worker    }
162*61046927SAndroid Build Coastguard Worker }
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_GenVertexArrays(struct gl_context * ctx,GLsizei n,GLuint * arrays)165*61046927SAndroid Build Coastguard Worker _mesa_glthread_GenVertexArrays(struct gl_context *ctx,
166*61046927SAndroid Build Coastguard Worker                                GLsizei n, GLuint *arrays)
167*61046927SAndroid Build Coastguard Worker {
168*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker    if (!arrays)
171*61046927SAndroid Build Coastguard Worker       return;
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker    /* The IDs have been generated at this point. Create VAOs for glthread. */
174*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < n; i++) {
175*61046927SAndroid Build Coastguard Worker       GLuint id = arrays[i];
176*61046927SAndroid Build Coastguard Worker       struct glthread_vao *vao;
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker       vao = calloc(1, sizeof(*vao));
179*61046927SAndroid Build Coastguard Worker       if (!vao)
180*61046927SAndroid Build Coastguard Worker          continue; /* Is that all we can do? */
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker       vao->Name = id;
183*61046927SAndroid Build Coastguard Worker       _mesa_glthread_reset_vao(vao);
184*61046927SAndroid Build Coastguard Worker       _mesa_HashInsertLocked(&glthread->VAOs, id, vao);
185*61046927SAndroid Build Coastguard Worker    }
186*61046927SAndroid Build Coastguard Worker }
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker /* If vaobj is NULL, use the currently-bound VAO. */
189*61046927SAndroid Build Coastguard Worker static inline struct glthread_vao *
get_vao(struct gl_context * ctx,const GLuint * vaobj)190*61046927SAndroid Build Coastguard Worker get_vao(struct gl_context *ctx, const GLuint *vaobj)
191*61046927SAndroid Build Coastguard Worker {
192*61046927SAndroid Build Coastguard Worker    if (vaobj)
193*61046927SAndroid Build Coastguard Worker       return lookup_vao(ctx, *vaobj);
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker    return ctx->GLThread.CurrentVAO;
196*61046927SAndroid Build Coastguard Worker }
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker static void
update_primitive_restart(struct gl_context * ctx)199*61046927SAndroid Build Coastguard Worker update_primitive_restart(struct gl_context *ctx)
200*61046927SAndroid Build Coastguard Worker {
201*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
202*61046927SAndroid Build Coastguard Worker 
203*61046927SAndroid Build Coastguard Worker    glthread->_PrimitiveRestart = glthread->PrimitiveRestart ||
204*61046927SAndroid Build Coastguard Worker                                  glthread->PrimitiveRestartFixedIndex;
205*61046927SAndroid Build Coastguard Worker    glthread->_RestartIndex[0] =
206*61046927SAndroid Build Coastguard Worker       _mesa_get_prim_restart_index(glthread->PrimitiveRestartFixedIndex,
207*61046927SAndroid Build Coastguard Worker                                    glthread->RestartIndex, 1);
208*61046927SAndroid Build Coastguard Worker    glthread->_RestartIndex[1] =
209*61046927SAndroid Build Coastguard Worker       _mesa_get_prim_restart_index(glthread->PrimitiveRestartFixedIndex,
210*61046927SAndroid Build Coastguard Worker                                    glthread->RestartIndex, 2);
211*61046927SAndroid Build Coastguard Worker    glthread->_RestartIndex[3] =
212*61046927SAndroid Build Coastguard Worker       _mesa_get_prim_restart_index(glthread->PrimitiveRestartFixedIndex,
213*61046927SAndroid Build Coastguard Worker                                    glthread->RestartIndex, 4);
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker 
216*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_set_prim_restart(struct gl_context * ctx,GLenum cap,bool value)217*61046927SAndroid Build Coastguard Worker _mesa_glthread_set_prim_restart(struct gl_context *ctx, GLenum cap, bool value)
218*61046927SAndroid Build Coastguard Worker {
219*61046927SAndroid Build Coastguard Worker    switch (cap) {
220*61046927SAndroid Build Coastguard Worker    case GL_PRIMITIVE_RESTART:
221*61046927SAndroid Build Coastguard Worker       ctx->GLThread.PrimitiveRestart = value;
222*61046927SAndroid Build Coastguard Worker       break;
223*61046927SAndroid Build Coastguard Worker    case GL_PRIMITIVE_RESTART_FIXED_INDEX:
224*61046927SAndroid Build Coastguard Worker       ctx->GLThread.PrimitiveRestartFixedIndex = value;
225*61046927SAndroid Build Coastguard Worker       break;
226*61046927SAndroid Build Coastguard Worker    }
227*61046927SAndroid Build Coastguard Worker 
228*61046927SAndroid Build Coastguard Worker    update_primitive_restart(ctx);
229*61046927SAndroid Build Coastguard Worker }
230*61046927SAndroid Build Coastguard Worker 
231*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_PrimitiveRestartIndex(struct gl_context * ctx,GLuint index)232*61046927SAndroid Build Coastguard Worker _mesa_glthread_PrimitiveRestartIndex(struct gl_context *ctx, GLuint index)
233*61046927SAndroid Build Coastguard Worker {
234*61046927SAndroid Build Coastguard Worker    ctx->GLThread.RestartIndex = index;
235*61046927SAndroid Build Coastguard Worker    update_primitive_restart(ctx);
236*61046927SAndroid Build Coastguard Worker }
237*61046927SAndroid Build Coastguard Worker 
238*61046927SAndroid Build Coastguard Worker static inline void
enable_buffer(struct glthread_vao * vao,unsigned binding_index)239*61046927SAndroid Build Coastguard Worker enable_buffer(struct glthread_vao *vao, unsigned binding_index)
240*61046927SAndroid Build Coastguard Worker {
241*61046927SAndroid Build Coastguard Worker    int attrib_count = ++vao->Attrib[binding_index].EnabledAttribCount;
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker    if (attrib_count == 1)
244*61046927SAndroid Build Coastguard Worker       vao->BufferEnabled |= 1 << binding_index;
245*61046927SAndroid Build Coastguard Worker    else if (attrib_count == 2)
246*61046927SAndroid Build Coastguard Worker       vao->BufferInterleaved |= 1 << binding_index;
247*61046927SAndroid Build Coastguard Worker }
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker static inline void
disable_buffer(struct glthread_vao * vao,unsigned binding_index)250*61046927SAndroid Build Coastguard Worker disable_buffer(struct glthread_vao *vao, unsigned binding_index)
251*61046927SAndroid Build Coastguard Worker {
252*61046927SAndroid Build Coastguard Worker    int attrib_count = --vao->Attrib[binding_index].EnabledAttribCount;
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker    if (attrib_count == 0)
255*61046927SAndroid Build Coastguard Worker       vao->BufferEnabled &= ~(1 << binding_index);
256*61046927SAndroid Build Coastguard Worker    else if (attrib_count == 1)
257*61046927SAndroid Build Coastguard Worker       vao->BufferInterleaved &= ~(1 << binding_index);
258*61046927SAndroid Build Coastguard Worker    else
259*61046927SAndroid Build Coastguard Worker       assert(attrib_count >= 0);
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_ClientState(struct gl_context * ctx,GLuint * vaobj,gl_vert_attrib attrib,bool enable)263*61046927SAndroid Build Coastguard Worker _mesa_glthread_ClientState(struct gl_context *ctx, GLuint *vaobj,
264*61046927SAndroid Build Coastguard Worker                            gl_vert_attrib attrib, bool enable)
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker    /* The primitive restart client state uses a special value. */
267*61046927SAndroid Build Coastguard Worker    if (attrib == VERT_ATTRIB_PRIMITIVE_RESTART_NV) {
268*61046927SAndroid Build Coastguard Worker       ctx->GLThread.PrimitiveRestart = enable;
269*61046927SAndroid Build Coastguard Worker       update_primitive_restart(ctx);
270*61046927SAndroid Build Coastguard Worker       return;
271*61046927SAndroid Build Coastguard Worker    }
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker    if (attrib >= VERT_ATTRIB_MAX)
274*61046927SAndroid Build Coastguard Worker       return;
275*61046927SAndroid Build Coastguard Worker 
276*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao = get_vao(ctx, vaobj);
277*61046927SAndroid Build Coastguard Worker    if (!vao)
278*61046927SAndroid Build Coastguard Worker       return;
279*61046927SAndroid Build Coastguard Worker 
280*61046927SAndroid Build Coastguard Worker    const unsigned attrib_bit = 1u << attrib;
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker    if (enable && !(vao->UserEnabled & attrib_bit)) {
283*61046927SAndroid Build Coastguard Worker       vao->UserEnabled |= attrib_bit;
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker       /* The generic0 attribute supersedes the position attribute. We need to
286*61046927SAndroid Build Coastguard Worker        * update BufferBindingEnabled accordingly.
287*61046927SAndroid Build Coastguard Worker        */
288*61046927SAndroid Build Coastguard Worker       if (attrib == VERT_ATTRIB_POS) {
289*61046927SAndroid Build Coastguard Worker          if (!(vao->UserEnabled & VERT_BIT_GENERIC0))
290*61046927SAndroid Build Coastguard Worker             enable_buffer(vao, vao->Attrib[VERT_ATTRIB_POS].BufferIndex);
291*61046927SAndroid Build Coastguard Worker       } else {
292*61046927SAndroid Build Coastguard Worker          enable_buffer(vao, vao->Attrib[attrib].BufferIndex);
293*61046927SAndroid Build Coastguard Worker 
294*61046927SAndroid Build Coastguard Worker          if (attrib == VERT_ATTRIB_GENERIC0 && vao->UserEnabled & VERT_BIT_POS)
295*61046927SAndroid Build Coastguard Worker             disable_buffer(vao, vao->Attrib[VERT_ATTRIB_POS].BufferIndex);
296*61046927SAndroid Build Coastguard Worker       }
297*61046927SAndroid Build Coastguard Worker    } else if (!enable && (vao->UserEnabled & attrib_bit)) {
298*61046927SAndroid Build Coastguard Worker       vao->UserEnabled &= ~attrib_bit;
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker       /* The generic0 attribute supersedes the position attribute. We need to
301*61046927SAndroid Build Coastguard Worker        * update BufferBindingEnabled accordingly.
302*61046927SAndroid Build Coastguard Worker        */
303*61046927SAndroid Build Coastguard Worker       if (attrib == VERT_ATTRIB_POS) {
304*61046927SAndroid Build Coastguard Worker          if (!(vao->UserEnabled & VERT_BIT_GENERIC0))
305*61046927SAndroid Build Coastguard Worker             disable_buffer(vao, vao->Attrib[VERT_ATTRIB_POS].BufferIndex);
306*61046927SAndroid Build Coastguard Worker       } else {
307*61046927SAndroid Build Coastguard Worker          disable_buffer(vao, vao->Attrib[attrib].BufferIndex);
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker          if (attrib == VERT_ATTRIB_GENERIC0 && vao->UserEnabled & VERT_BIT_POS)
310*61046927SAndroid Build Coastguard Worker             enable_buffer(vao, vao->Attrib[VERT_ATTRIB_POS].BufferIndex);
311*61046927SAndroid Build Coastguard Worker       }
312*61046927SAndroid Build Coastguard Worker    }
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker    /* The generic0 attribute supersedes the position attribute. */
315*61046927SAndroid Build Coastguard Worker    vao->Enabled = vao->UserEnabled;
316*61046927SAndroid Build Coastguard Worker    if (vao->Enabled & VERT_BIT_GENERIC0)
317*61046927SAndroid Build Coastguard Worker       vao->Enabled &= ~VERT_BIT_POS;
318*61046927SAndroid Build Coastguard Worker }
319*61046927SAndroid Build Coastguard Worker 
320*61046927SAndroid Build Coastguard Worker static void
set_attrib_binding(struct glthread_state * glthread,struct glthread_vao * vao,gl_vert_attrib attrib,unsigned new_binding_index)321*61046927SAndroid Build Coastguard Worker set_attrib_binding(struct glthread_state *glthread, struct glthread_vao *vao,
322*61046927SAndroid Build Coastguard Worker                    gl_vert_attrib attrib, unsigned new_binding_index)
323*61046927SAndroid Build Coastguard Worker {
324*61046927SAndroid Build Coastguard Worker    unsigned old_binding_index = vao->Attrib[attrib].BufferIndex;
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker    if (old_binding_index != new_binding_index) {
327*61046927SAndroid Build Coastguard Worker       vao->Attrib[attrib].BufferIndex = new_binding_index;
328*61046927SAndroid Build Coastguard Worker 
329*61046927SAndroid Build Coastguard Worker       if (vao->Enabled & (1u << attrib)) {
330*61046927SAndroid Build Coastguard Worker          /* Update BufferBindingEnabled. */
331*61046927SAndroid Build Coastguard Worker          enable_buffer(vao, new_binding_index);
332*61046927SAndroid Build Coastguard Worker          disable_buffer(vao, old_binding_index);
333*61046927SAndroid Build Coastguard Worker       }
334*61046927SAndroid Build Coastguard Worker    }
335*61046927SAndroid Build Coastguard Worker }
336*61046927SAndroid Build Coastguard Worker 
_mesa_glthread_AttribDivisor(struct gl_context * ctx,const GLuint * vaobj,gl_vert_attrib attrib,GLuint divisor)337*61046927SAndroid Build Coastguard Worker void _mesa_glthread_AttribDivisor(struct gl_context *ctx, const GLuint *vaobj,
338*61046927SAndroid Build Coastguard Worker                                   gl_vert_attrib attrib, GLuint divisor)
339*61046927SAndroid Build Coastguard Worker {
340*61046927SAndroid Build Coastguard Worker    if (attrib >= VERT_ATTRIB_MAX)
341*61046927SAndroid Build Coastguard Worker       return;
342*61046927SAndroid Build Coastguard Worker 
343*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao = get_vao(ctx, vaobj);
344*61046927SAndroid Build Coastguard Worker    if (!vao)
345*61046927SAndroid Build Coastguard Worker       return;
346*61046927SAndroid Build Coastguard Worker 
347*61046927SAndroid Build Coastguard Worker    vao->Attrib[attrib].Divisor = divisor;
348*61046927SAndroid Build Coastguard Worker 
349*61046927SAndroid Build Coastguard Worker    set_attrib_binding(&ctx->GLThread, vao, attrib, attrib);
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker    if (divisor)
352*61046927SAndroid Build Coastguard Worker       vao->NonZeroDivisorMask |= 1u << attrib;
353*61046927SAndroid Build Coastguard Worker    else
354*61046927SAndroid Build Coastguard Worker       vao->NonZeroDivisorMask &= ~(1u << attrib);
355*61046927SAndroid Build Coastguard Worker }
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker static void
attrib_pointer(struct glthread_state * glthread,struct glthread_vao * vao,GLuint buffer,gl_vert_attrib attrib,union gl_vertex_format_user format,GLsizei stride,const void * pointer)358*61046927SAndroid Build Coastguard Worker attrib_pointer(struct glthread_state *glthread, struct glthread_vao *vao,
359*61046927SAndroid Build Coastguard Worker                GLuint buffer, gl_vert_attrib attrib,
360*61046927SAndroid Build Coastguard Worker                union gl_vertex_format_user format, GLsizei stride,
361*61046927SAndroid Build Coastguard Worker                const void *pointer)
362*61046927SAndroid Build Coastguard Worker {
363*61046927SAndroid Build Coastguard Worker    if (attrib >= VERT_ATTRIB_MAX)
364*61046927SAndroid Build Coastguard Worker       return;
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker    unsigned elem_size = element_size(format);
367*61046927SAndroid Build Coastguard Worker 
368*61046927SAndroid Build Coastguard Worker    vao->Attrib[attrib].Format = format;
369*61046927SAndroid Build Coastguard Worker    vao->Attrib[attrib].ElementSize = elem_size;
370*61046927SAndroid Build Coastguard Worker    vao->Attrib[attrib].Stride = stride ? stride : elem_size;
371*61046927SAndroid Build Coastguard Worker    vao->Attrib[attrib].Pointer = pointer;
372*61046927SAndroid Build Coastguard Worker    vao->Attrib[attrib].RelativeOffset = 0;
373*61046927SAndroid Build Coastguard Worker 
374*61046927SAndroid Build Coastguard Worker    set_attrib_binding(glthread, vao, attrib, attrib);
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker    if (buffer != 0)
377*61046927SAndroid Build Coastguard Worker       vao->UserPointerMask &= ~(1u << attrib);
378*61046927SAndroid Build Coastguard Worker    else
379*61046927SAndroid Build Coastguard Worker       vao->UserPointerMask |= 1u << attrib;
380*61046927SAndroid Build Coastguard Worker 
381*61046927SAndroid Build Coastguard Worker    if (pointer)
382*61046927SAndroid Build Coastguard Worker       vao->NonNullPointerMask |= 1u << attrib;
383*61046927SAndroid Build Coastguard Worker    else
384*61046927SAndroid Build Coastguard Worker       vao->NonNullPointerMask &= ~(1u << attrib);
385*61046927SAndroid Build Coastguard Worker }
386*61046927SAndroid Build Coastguard Worker 
387*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_AttribPointer(struct gl_context * ctx,gl_vert_attrib attrib,union gl_vertex_format_user format,GLsizei stride,const void * pointer)388*61046927SAndroid Build Coastguard Worker _mesa_glthread_AttribPointer(struct gl_context *ctx, gl_vert_attrib attrib,
389*61046927SAndroid Build Coastguard Worker                              union gl_vertex_format_user format,
390*61046927SAndroid Build Coastguard Worker                              GLsizei stride, const void *pointer)
391*61046927SAndroid Build Coastguard Worker {
392*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
393*61046927SAndroid Build Coastguard Worker 
394*61046927SAndroid Build Coastguard Worker    attrib_pointer(glthread, glthread->CurrentVAO,
395*61046927SAndroid Build Coastguard Worker                   glthread->CurrentArrayBufferName,
396*61046927SAndroid Build Coastguard Worker                   attrib, format, stride, pointer);
397*61046927SAndroid Build Coastguard Worker }
398*61046927SAndroid Build Coastguard Worker 
399*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DSAAttribPointer(struct gl_context * ctx,GLuint vaobj,GLuint buffer,gl_vert_attrib attrib,union gl_vertex_format_user format,GLsizei stride,GLintptr offset)400*61046927SAndroid Build Coastguard Worker _mesa_glthread_DSAAttribPointer(struct gl_context *ctx, GLuint vaobj,
401*61046927SAndroid Build Coastguard Worker                                 GLuint buffer, gl_vert_attrib attrib,
402*61046927SAndroid Build Coastguard Worker                                 union gl_vertex_format_user format,
403*61046927SAndroid Build Coastguard Worker                                 GLsizei stride, GLintptr offset)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
406*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao;
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker    vao = lookup_vao(ctx, vaobj);
409*61046927SAndroid Build Coastguard Worker    if (!vao)
410*61046927SAndroid Build Coastguard Worker       return;
411*61046927SAndroid Build Coastguard Worker 
412*61046927SAndroid Build Coastguard Worker    attrib_pointer(glthread, vao, buffer, attrib, format, stride,
413*61046927SAndroid Build Coastguard Worker                   (const void*)offset);
414*61046927SAndroid Build Coastguard Worker }
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker static void
attrib_format(struct glthread_state * glthread,struct glthread_vao * vao,GLuint attribindex,union gl_vertex_format_user format,GLuint relativeoffset)417*61046927SAndroid Build Coastguard Worker attrib_format(struct glthread_state *glthread, struct glthread_vao *vao,
418*61046927SAndroid Build Coastguard Worker               GLuint attribindex, union gl_vertex_format_user format,
419*61046927SAndroid Build Coastguard Worker               GLuint relativeoffset)
420*61046927SAndroid Build Coastguard Worker {
421*61046927SAndroid Build Coastguard Worker    if (attribindex >= VERT_ATTRIB_GENERIC_MAX)
422*61046927SAndroid Build Coastguard Worker       return;
423*61046927SAndroid Build Coastguard Worker 
424*61046927SAndroid Build Coastguard Worker    unsigned elem_size = element_size(format);
425*61046927SAndroid Build Coastguard Worker 
426*61046927SAndroid Build Coastguard Worker    unsigned i = VERT_ATTRIB_GENERIC(attribindex);
427*61046927SAndroid Build Coastguard Worker    vao->Attrib[i].Format = format;
428*61046927SAndroid Build Coastguard Worker    vao->Attrib[i].ElementSize = elem_size;
429*61046927SAndroid Build Coastguard Worker    vao->Attrib[i].RelativeOffset = relativeoffset;
430*61046927SAndroid Build Coastguard Worker }
431*61046927SAndroid Build Coastguard Worker 
432*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_AttribFormat(struct gl_context * ctx,GLuint attribindex,union gl_vertex_format_user format,GLuint relativeoffset)433*61046927SAndroid Build Coastguard Worker _mesa_glthread_AttribFormat(struct gl_context *ctx, GLuint attribindex,
434*61046927SAndroid Build Coastguard Worker                             union gl_vertex_format_user format,
435*61046927SAndroid Build Coastguard Worker                             GLuint relativeoffset)
436*61046927SAndroid Build Coastguard Worker {
437*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
438*61046927SAndroid Build Coastguard Worker 
439*61046927SAndroid Build Coastguard Worker    attrib_format(glthread, glthread->CurrentVAO, attribindex, format,
440*61046927SAndroid Build Coastguard Worker                  relativeoffset);
441*61046927SAndroid Build Coastguard Worker }
442*61046927SAndroid Build Coastguard Worker 
443*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DSAAttribFormat(struct gl_context * ctx,GLuint vaobj,GLuint attribindex,union gl_vertex_format_user format,GLuint relativeoffset)444*61046927SAndroid Build Coastguard Worker _mesa_glthread_DSAAttribFormat(struct gl_context *ctx, GLuint vaobj,
445*61046927SAndroid Build Coastguard Worker                                GLuint attribindex,
446*61046927SAndroid Build Coastguard Worker                                union gl_vertex_format_user format,
447*61046927SAndroid Build Coastguard Worker                                GLuint relativeoffset)
448*61046927SAndroid Build Coastguard Worker {
449*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
450*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao = lookup_vao(ctx, vaobj);
451*61046927SAndroid Build Coastguard Worker 
452*61046927SAndroid Build Coastguard Worker    if (vao)
453*61046927SAndroid Build Coastguard Worker       attrib_format(glthread, vao, attribindex, format, relativeoffset);
454*61046927SAndroid Build Coastguard Worker }
455*61046927SAndroid Build Coastguard Worker 
456*61046927SAndroid Build Coastguard Worker static void
bind_vertex_buffer(struct glthread_state * glthread,struct glthread_vao * vao,GLuint bindingindex,GLuint buffer,GLintptr offset,GLsizei stride)457*61046927SAndroid Build Coastguard Worker bind_vertex_buffer(struct glthread_state *glthread, struct glthread_vao *vao,
458*61046927SAndroid Build Coastguard Worker                    GLuint bindingindex, GLuint buffer, GLintptr offset,
459*61046927SAndroid Build Coastguard Worker                    GLsizei stride)
460*61046927SAndroid Build Coastguard Worker {
461*61046927SAndroid Build Coastguard Worker    if (bindingindex >= VERT_ATTRIB_GENERIC_MAX)
462*61046927SAndroid Build Coastguard Worker       return;
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker    unsigned i = VERT_ATTRIB_GENERIC(bindingindex);
465*61046927SAndroid Build Coastguard Worker    vao->Attrib[i].Pointer = (const void*)offset;
466*61046927SAndroid Build Coastguard Worker    vao->Attrib[i].Stride = stride;
467*61046927SAndroid Build Coastguard Worker 
468*61046927SAndroid Build Coastguard Worker    if (buffer != 0)
469*61046927SAndroid Build Coastguard Worker       vao->UserPointerMask &= ~(1u << i);
470*61046927SAndroid Build Coastguard Worker    else
471*61046927SAndroid Build Coastguard Worker       vao->UserPointerMask |= 1u << i;
472*61046927SAndroid Build Coastguard Worker 
473*61046927SAndroid Build Coastguard Worker    if (offset)
474*61046927SAndroid Build Coastguard Worker       vao->NonNullPointerMask |= 1u << i;
475*61046927SAndroid Build Coastguard Worker    else
476*61046927SAndroid Build Coastguard Worker       vao->NonNullPointerMask &= ~(1u << i);
477*61046927SAndroid Build Coastguard Worker }
478*61046927SAndroid Build Coastguard Worker 
479*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_VertexBuffer(struct gl_context * ctx,GLuint bindingindex,GLuint buffer,GLintptr offset,GLsizei stride)480*61046927SAndroid Build Coastguard Worker _mesa_glthread_VertexBuffer(struct gl_context *ctx, GLuint bindingindex,
481*61046927SAndroid Build Coastguard Worker                             GLuint buffer, GLintptr offset, GLsizei stride)
482*61046927SAndroid Build Coastguard Worker {
483*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
484*61046927SAndroid Build Coastguard Worker 
485*61046927SAndroid Build Coastguard Worker    bind_vertex_buffer(glthread, glthread->CurrentVAO, bindingindex, buffer,
486*61046927SAndroid Build Coastguard Worker                       offset, stride);
487*61046927SAndroid Build Coastguard Worker }
488*61046927SAndroid Build Coastguard Worker 
489*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DSAVertexBuffer(struct gl_context * ctx,GLuint vaobj,GLuint bindingindex,GLuint buffer,GLintptr offset,GLsizei stride)490*61046927SAndroid Build Coastguard Worker _mesa_glthread_DSAVertexBuffer(struct gl_context *ctx, GLuint vaobj,
491*61046927SAndroid Build Coastguard Worker                                GLuint bindingindex, GLuint buffer,
492*61046927SAndroid Build Coastguard Worker                                GLintptr offset, GLsizei stride)
493*61046927SAndroid Build Coastguard Worker {
494*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
495*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao = lookup_vao(ctx, vaobj);
496*61046927SAndroid Build Coastguard Worker 
497*61046927SAndroid Build Coastguard Worker    if (vao)
498*61046927SAndroid Build Coastguard Worker       bind_vertex_buffer(glthread, vao, bindingindex, buffer, offset, stride);
499*61046927SAndroid Build Coastguard Worker }
500*61046927SAndroid Build Coastguard Worker 
501*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DSAVertexBuffers(struct gl_context * ctx,GLuint vaobj,GLuint first,GLsizei count,const GLuint * buffers,const GLintptr * offsets,const GLsizei * strides)502*61046927SAndroid Build Coastguard Worker _mesa_glthread_DSAVertexBuffers(struct gl_context *ctx, GLuint vaobj,
503*61046927SAndroid Build Coastguard Worker                                 GLuint first, GLsizei count,
504*61046927SAndroid Build Coastguard Worker                                 const GLuint *buffers,
505*61046927SAndroid Build Coastguard Worker                                 const GLintptr *offsets,
506*61046927SAndroid Build Coastguard Worker                                 const GLsizei *strides)
507*61046927SAndroid Build Coastguard Worker {
508*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
509*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao;
510*61046927SAndroid Build Coastguard Worker 
511*61046927SAndroid Build Coastguard Worker    vao = lookup_vao(ctx, vaobj);
512*61046927SAndroid Build Coastguard Worker    if (!vao)
513*61046927SAndroid Build Coastguard Worker       return;
514*61046927SAndroid Build Coastguard Worker 
515*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < count; i++) {
516*61046927SAndroid Build Coastguard Worker       bind_vertex_buffer(glthread, vao, first + i, buffers[i], offsets[i],
517*61046927SAndroid Build Coastguard Worker                          strides[i]);
518*61046927SAndroid Build Coastguard Worker    }
519*61046927SAndroid Build Coastguard Worker }
520*61046927SAndroid Build Coastguard Worker 
521*61046927SAndroid Build Coastguard Worker static void
binding_divisor(struct glthread_state * glthread,struct glthread_vao * vao,GLuint bindingindex,GLuint divisor)522*61046927SAndroid Build Coastguard Worker binding_divisor(struct glthread_state *glthread, struct glthread_vao *vao,
523*61046927SAndroid Build Coastguard Worker                 GLuint bindingindex, GLuint divisor)
524*61046927SAndroid Build Coastguard Worker {
525*61046927SAndroid Build Coastguard Worker    if (bindingindex >= VERT_ATTRIB_GENERIC_MAX)
526*61046927SAndroid Build Coastguard Worker       return;
527*61046927SAndroid Build Coastguard Worker 
528*61046927SAndroid Build Coastguard Worker    unsigned i = VERT_ATTRIB_GENERIC(bindingindex);
529*61046927SAndroid Build Coastguard Worker    vao->Attrib[i].Divisor = divisor;
530*61046927SAndroid Build Coastguard Worker 
531*61046927SAndroid Build Coastguard Worker    if (divisor)
532*61046927SAndroid Build Coastguard Worker       vao->NonZeroDivisorMask |= 1u << i;
533*61046927SAndroid Build Coastguard Worker    else
534*61046927SAndroid Build Coastguard Worker       vao->NonZeroDivisorMask &= ~(1u << i);
535*61046927SAndroid Build Coastguard Worker }
536*61046927SAndroid Build Coastguard Worker 
537*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_BindingDivisor(struct gl_context * ctx,GLuint bindingindex,GLuint divisor)538*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindingDivisor(struct gl_context *ctx, GLuint bindingindex,
539*61046927SAndroid Build Coastguard Worker                               GLuint divisor)
540*61046927SAndroid Build Coastguard Worker {
541*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
542*61046927SAndroid Build Coastguard Worker 
543*61046927SAndroid Build Coastguard Worker    binding_divisor(glthread, glthread->CurrentVAO, bindingindex, divisor);
544*61046927SAndroid Build Coastguard Worker }
545*61046927SAndroid Build Coastguard Worker 
546*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DSABindingDivisor(struct gl_context * ctx,GLuint vaobj,GLuint bindingindex,GLuint divisor)547*61046927SAndroid Build Coastguard Worker _mesa_glthread_DSABindingDivisor(struct gl_context *ctx, GLuint vaobj,
548*61046927SAndroid Build Coastguard Worker                                  GLuint bindingindex, GLuint divisor)
549*61046927SAndroid Build Coastguard Worker {
550*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
551*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao = lookup_vao(ctx, vaobj);
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker    if (vao)
554*61046927SAndroid Build Coastguard Worker       binding_divisor(glthread, vao, bindingindex, divisor);
555*61046927SAndroid Build Coastguard Worker }
556*61046927SAndroid Build Coastguard Worker 
557*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_AttribBinding(struct gl_context * ctx,GLuint attribindex,GLuint bindingindex)558*61046927SAndroid Build Coastguard Worker _mesa_glthread_AttribBinding(struct gl_context *ctx, GLuint attribindex,
559*61046927SAndroid Build Coastguard Worker                              GLuint bindingindex)
560*61046927SAndroid Build Coastguard Worker {
561*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
562*61046927SAndroid Build Coastguard Worker 
563*61046927SAndroid Build Coastguard Worker    if (attribindex >= VERT_ATTRIB_GENERIC_MAX ||
564*61046927SAndroid Build Coastguard Worker        bindingindex >= VERT_ATTRIB_GENERIC_MAX)
565*61046927SAndroid Build Coastguard Worker       return;
566*61046927SAndroid Build Coastguard Worker 
567*61046927SAndroid Build Coastguard Worker    set_attrib_binding(glthread, glthread->CurrentVAO,
568*61046927SAndroid Build Coastguard Worker                       VERT_ATTRIB_GENERIC(attribindex),
569*61046927SAndroid Build Coastguard Worker                       VERT_ATTRIB_GENERIC(bindingindex));
570*61046927SAndroid Build Coastguard Worker }
571*61046927SAndroid Build Coastguard Worker 
572*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DSAAttribBinding(struct gl_context * ctx,GLuint vaobj,GLuint attribindex,GLuint bindingindex)573*61046927SAndroid Build Coastguard Worker _mesa_glthread_DSAAttribBinding(struct gl_context *ctx, GLuint vaobj,
574*61046927SAndroid Build Coastguard Worker                                 GLuint attribindex, GLuint bindingindex)
575*61046927SAndroid Build Coastguard Worker {
576*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
577*61046927SAndroid Build Coastguard Worker 
578*61046927SAndroid Build Coastguard Worker    if (attribindex >= VERT_ATTRIB_GENERIC_MAX ||
579*61046927SAndroid Build Coastguard Worker        bindingindex >= VERT_ATTRIB_GENERIC_MAX)
580*61046927SAndroid Build Coastguard Worker       return;
581*61046927SAndroid Build Coastguard Worker 
582*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao = lookup_vao(ctx, vaobj);
583*61046927SAndroid Build Coastguard Worker    if (vao) {
584*61046927SAndroid Build Coastguard Worker       set_attrib_binding(glthread, vao,
585*61046927SAndroid Build Coastguard Worker                          VERT_ATTRIB_GENERIC(attribindex),
586*61046927SAndroid Build Coastguard Worker                          VERT_ATTRIB_GENERIC(bindingindex));
587*61046927SAndroid Build Coastguard Worker    }
588*61046927SAndroid Build Coastguard Worker }
589*61046927SAndroid Build Coastguard Worker 
590*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DSAElementBuffer(struct gl_context * ctx,GLuint vaobj,GLuint buffer)591*61046927SAndroid Build Coastguard Worker _mesa_glthread_DSAElementBuffer(struct gl_context *ctx, GLuint vaobj,
592*61046927SAndroid Build Coastguard Worker                                 GLuint buffer)
593*61046927SAndroid Build Coastguard Worker {
594*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao = lookup_vao(ctx, vaobj);
595*61046927SAndroid Build Coastguard Worker 
596*61046927SAndroid Build Coastguard Worker    if (vao)
597*61046927SAndroid Build Coastguard Worker       vao->CurrentElementBufferName = buffer;
598*61046927SAndroid Build Coastguard Worker }
599*61046927SAndroid Build Coastguard Worker 
600*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_PushClientAttrib(struct gl_context * ctx,GLbitfield mask,bool set_default)601*61046927SAndroid Build Coastguard Worker _mesa_glthread_PushClientAttrib(struct gl_context *ctx, GLbitfield mask,
602*61046927SAndroid Build Coastguard Worker                                 bool set_default)
603*61046927SAndroid Build Coastguard Worker {
604*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
605*61046927SAndroid Build Coastguard Worker 
606*61046927SAndroid Build Coastguard Worker    if (glthread->ClientAttribStackTop >= MAX_CLIENT_ATTRIB_STACK_DEPTH)
607*61046927SAndroid Build Coastguard Worker       return;
608*61046927SAndroid Build Coastguard Worker 
609*61046927SAndroid Build Coastguard Worker    struct glthread_client_attrib *top =
610*61046927SAndroid Build Coastguard Worker       &glthread->ClientAttribStack[glthread->ClientAttribStackTop];
611*61046927SAndroid Build Coastguard Worker 
612*61046927SAndroid Build Coastguard Worker    if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
613*61046927SAndroid Build Coastguard Worker       top->VAO = *glthread->CurrentVAO;
614*61046927SAndroid Build Coastguard Worker       top->CurrentArrayBufferName = glthread->CurrentArrayBufferName;
615*61046927SAndroid Build Coastguard Worker       top->ClientActiveTexture = glthread->ClientActiveTexture;
616*61046927SAndroid Build Coastguard Worker       top->RestartIndex = glthread->RestartIndex;
617*61046927SAndroid Build Coastguard Worker       top->PrimitiveRestart = glthread->PrimitiveRestart;
618*61046927SAndroid Build Coastguard Worker       top->PrimitiveRestartFixedIndex = glthread->PrimitiveRestartFixedIndex;
619*61046927SAndroid Build Coastguard Worker       top->Valid = true;
620*61046927SAndroid Build Coastguard Worker    } else {
621*61046927SAndroid Build Coastguard Worker       top->Valid = false;
622*61046927SAndroid Build Coastguard Worker    }
623*61046927SAndroid Build Coastguard Worker 
624*61046927SAndroid Build Coastguard Worker    glthread->ClientAttribStackTop++;
625*61046927SAndroid Build Coastguard Worker 
626*61046927SAndroid Build Coastguard Worker    if (set_default)
627*61046927SAndroid Build Coastguard Worker       _mesa_glthread_ClientAttribDefault(ctx, mask);
628*61046927SAndroid Build Coastguard Worker }
629*61046927SAndroid Build Coastguard Worker 
630*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_PopClientAttrib(struct gl_context * ctx)631*61046927SAndroid Build Coastguard Worker _mesa_glthread_PopClientAttrib(struct gl_context *ctx)
632*61046927SAndroid Build Coastguard Worker {
633*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
634*61046927SAndroid Build Coastguard Worker 
635*61046927SAndroid Build Coastguard Worker    if (glthread->ClientAttribStackTop == 0)
636*61046927SAndroid Build Coastguard Worker       return;
637*61046927SAndroid Build Coastguard Worker 
638*61046927SAndroid Build Coastguard Worker    glthread->ClientAttribStackTop--;
639*61046927SAndroid Build Coastguard Worker 
640*61046927SAndroid Build Coastguard Worker    struct glthread_client_attrib *top =
641*61046927SAndroid Build Coastguard Worker       &glthread->ClientAttribStack[glthread->ClientAttribStackTop];
642*61046927SAndroid Build Coastguard Worker 
643*61046927SAndroid Build Coastguard Worker    if (!top->Valid)
644*61046927SAndroid Build Coastguard Worker       return;
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker    /* Popping a delete VAO is an error. */
647*61046927SAndroid Build Coastguard Worker    struct glthread_vao *vao = NULL;
648*61046927SAndroid Build Coastguard Worker    if (top->VAO.Name) {
649*61046927SAndroid Build Coastguard Worker       vao = lookup_vao(ctx, top->VAO.Name);
650*61046927SAndroid Build Coastguard Worker       if (!vao)
651*61046927SAndroid Build Coastguard Worker          return;
652*61046927SAndroid Build Coastguard Worker    }
653*61046927SAndroid Build Coastguard Worker 
654*61046927SAndroid Build Coastguard Worker    /* Restore states. */
655*61046927SAndroid Build Coastguard Worker    glthread->CurrentArrayBufferName = top->CurrentArrayBufferName;
656*61046927SAndroid Build Coastguard Worker    glthread->ClientActiveTexture = top->ClientActiveTexture;
657*61046927SAndroid Build Coastguard Worker    glthread->RestartIndex = top->RestartIndex;
658*61046927SAndroid Build Coastguard Worker    glthread->PrimitiveRestart = top->PrimitiveRestart;
659*61046927SAndroid Build Coastguard Worker    glthread->PrimitiveRestartFixedIndex = top->PrimitiveRestartFixedIndex;
660*61046927SAndroid Build Coastguard Worker 
661*61046927SAndroid Build Coastguard Worker    if (!vao)
662*61046927SAndroid Build Coastguard Worker       vao = &glthread->DefaultVAO;
663*61046927SAndroid Build Coastguard Worker 
664*61046927SAndroid Build Coastguard Worker    assert(top->VAO.Name == vao->Name);
665*61046927SAndroid Build Coastguard Worker    *vao = top->VAO; /* Copy all fields. */
666*61046927SAndroid Build Coastguard Worker    glthread->CurrentVAO = vao;
667*61046927SAndroid Build Coastguard Worker }
668*61046927SAndroid Build Coastguard Worker 
669*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_ClientAttribDefault(struct gl_context * ctx,GLbitfield mask)670*61046927SAndroid Build Coastguard Worker _mesa_glthread_ClientAttribDefault(struct gl_context *ctx, GLbitfield mask)
671*61046927SAndroid Build Coastguard Worker {
672*61046927SAndroid Build Coastguard Worker    struct glthread_state *glthread = &ctx->GLThread;
673*61046927SAndroid Build Coastguard Worker 
674*61046927SAndroid Build Coastguard Worker    if (!(mask & GL_CLIENT_VERTEX_ARRAY_BIT))
675*61046927SAndroid Build Coastguard Worker       return;
676*61046927SAndroid Build Coastguard Worker 
677*61046927SAndroid Build Coastguard Worker    glthread->CurrentArrayBufferName = 0;
678*61046927SAndroid Build Coastguard Worker    glthread->ClientActiveTexture = 0;
679*61046927SAndroid Build Coastguard Worker    glthread->RestartIndex = 0;
680*61046927SAndroid Build Coastguard Worker    glthread->PrimitiveRestart = false;
681*61046927SAndroid Build Coastguard Worker    glthread->PrimitiveRestartFixedIndex = false;
682*61046927SAndroid Build Coastguard Worker    glthread->CurrentVAO = &glthread->DefaultVAO;
683*61046927SAndroid Build Coastguard Worker    _mesa_glthread_reset_vao(glthread->CurrentVAO);
684*61046927SAndroid Build Coastguard Worker }
685*61046927SAndroid Build Coastguard Worker 
686*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_InterleavedArrays(struct gl_context * ctx,GLenum format,GLsizei stride,const GLvoid * pointer)687*61046927SAndroid Build Coastguard Worker _mesa_glthread_InterleavedArrays(struct gl_context *ctx, GLenum format,
688*61046927SAndroid Build Coastguard Worker                                  GLsizei stride, const GLvoid *pointer)
689*61046927SAndroid Build Coastguard Worker {
690*61046927SAndroid Build Coastguard Worker    struct gl_interleaved_layout layout;
691*61046927SAndroid Build Coastguard Worker    unsigned tex = VERT_ATTRIB_TEX(ctx->GLThread.ClientActiveTexture);
692*61046927SAndroid Build Coastguard Worker 
693*61046927SAndroid Build Coastguard Worker    if (stride < 0 || !_mesa_get_interleaved_layout(format, &layout))
694*61046927SAndroid Build Coastguard Worker       return;
695*61046927SAndroid Build Coastguard Worker 
696*61046927SAndroid Build Coastguard Worker    if (!stride)
697*61046927SAndroid Build Coastguard Worker       stride = layout.defstride;
698*61046927SAndroid Build Coastguard Worker 
699*61046927SAndroid Build Coastguard Worker    _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_EDGEFLAG, false);
700*61046927SAndroid Build Coastguard Worker    _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_COLOR_INDEX, false);
701*61046927SAndroid Build Coastguard Worker    /* XXX also disable secondary color and generic arrays? */
702*61046927SAndroid Build Coastguard Worker 
703*61046927SAndroid Build Coastguard Worker    /* Texcoords */
704*61046927SAndroid Build Coastguard Worker    if (layout.tflag) {
705*61046927SAndroid Build Coastguard Worker       _mesa_glthread_ClientState(ctx, NULL, tex, true);
706*61046927SAndroid Build Coastguard Worker       _mesa_glthread_AttribPointer(ctx, tex,
707*61046927SAndroid Build Coastguard Worker                                    MESA_PACK_VFORMAT(GL_FLOAT, layout.tcomps,
708*61046927SAndroid Build Coastguard Worker                                                      0, 0, 0),
709*61046927SAndroid Build Coastguard Worker                                    stride, (GLubyte *)pointer + layout.toffset);
710*61046927SAndroid Build Coastguard Worker    } else {
711*61046927SAndroid Build Coastguard Worker       _mesa_glthread_ClientState(ctx, NULL, tex, false);
712*61046927SAndroid Build Coastguard Worker    }
713*61046927SAndroid Build Coastguard Worker 
714*61046927SAndroid Build Coastguard Worker    /* Color */
715*61046927SAndroid Build Coastguard Worker    if (layout.cflag) {
716*61046927SAndroid Build Coastguard Worker       _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_COLOR0, true);
717*61046927SAndroid Build Coastguard Worker       _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_COLOR0,
718*61046927SAndroid Build Coastguard Worker                                    MESA_PACK_VFORMAT(layout.ctype, layout.ccomps,
719*61046927SAndroid Build Coastguard Worker                                                      1, 0, 0),
720*61046927SAndroid Build Coastguard Worker                                    stride, (GLubyte *)pointer + layout.coffset);
721*61046927SAndroid Build Coastguard Worker    } else {
722*61046927SAndroid Build Coastguard Worker       _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_COLOR0, false);
723*61046927SAndroid Build Coastguard Worker    }
724*61046927SAndroid Build Coastguard Worker 
725*61046927SAndroid Build Coastguard Worker    /* Normals */
726*61046927SAndroid Build Coastguard Worker    if (layout.nflag) {
727*61046927SAndroid Build Coastguard Worker       _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_NORMAL, true);
728*61046927SAndroid Build Coastguard Worker       _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_NORMAL,
729*61046927SAndroid Build Coastguard Worker                                    MESA_PACK_VFORMAT(GL_FLOAT, 3, 1, 0, 0),
730*61046927SAndroid Build Coastguard Worker                                    stride, (GLubyte *) pointer + layout.noffset);
731*61046927SAndroid Build Coastguard Worker    } else {
732*61046927SAndroid Build Coastguard Worker       _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_NORMAL, false);
733*61046927SAndroid Build Coastguard Worker    }
734*61046927SAndroid Build Coastguard Worker 
735*61046927SAndroid Build Coastguard Worker    /* Vertices */
736*61046927SAndroid Build Coastguard Worker    _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_POS, true);
737*61046927SAndroid Build Coastguard Worker    _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_POS,
738*61046927SAndroid Build Coastguard Worker                                 MESA_PACK_VFORMAT(GL_FLOAT, layout.vcomps,
739*61046927SAndroid Build Coastguard Worker                                                   0, 0, 0),
740*61046927SAndroid Build Coastguard Worker                                 stride, (GLubyte *) pointer + layout.voffset);
741*61046927SAndroid Build Coastguard Worker }
742*61046927SAndroid Build Coastguard Worker 
743*61046927SAndroid Build Coastguard Worker static void
unbind_uploaded_vbos(void * _vao,void * _ctx)744*61046927SAndroid Build Coastguard Worker unbind_uploaded_vbos(void *_vao, void *_ctx)
745*61046927SAndroid Build Coastguard Worker {
746*61046927SAndroid Build Coastguard Worker    struct gl_context *ctx = _ctx;
747*61046927SAndroid Build Coastguard Worker    struct gl_vertex_array_object *vao = _vao;
748*61046927SAndroid Build Coastguard Worker 
749*61046927SAndroid Build Coastguard Worker    assert(ctx->API != API_OPENGL_CORE);
750*61046927SAndroid Build Coastguard Worker 
751*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(vao->BufferBinding); i++) {
752*61046927SAndroid Build Coastguard Worker       if (vao->BufferBinding[i].BufferObj &&
753*61046927SAndroid Build Coastguard Worker           vao->BufferBinding[i].BufferObj->GLThreadInternal) {
754*61046927SAndroid Build Coastguard Worker          /* We don't need to restore the user pointer because it's never
755*61046927SAndroid Build Coastguard Worker           * overwritten. When we bind a VBO internally, the user pointer
756*61046927SAndroid Build Coastguard Worker           * in gl_array_attribute::Ptr becomes ignored and unchanged.
757*61046927SAndroid Build Coastguard Worker           */
758*61046927SAndroid Build Coastguard Worker          _mesa_bind_vertex_buffer(ctx, vao, i, NULL, 0,
759*61046927SAndroid Build Coastguard Worker                                   vao->BufferBinding[i].Stride, false, false);
760*61046927SAndroid Build Coastguard Worker       }
761*61046927SAndroid Build Coastguard Worker    }
762*61046927SAndroid Build Coastguard Worker }
763*61046927SAndroid Build Coastguard Worker 
764*61046927SAndroid Build Coastguard Worker /* Unbind VBOs in all VAOs that glthread bound for non-VBO vertex uploads
765*61046927SAndroid Build Coastguard Worker  * to restore original states.
766*61046927SAndroid Build Coastguard Worker  */
767*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_unbind_uploaded_vbos(struct gl_context * ctx)768*61046927SAndroid Build Coastguard Worker _mesa_glthread_unbind_uploaded_vbos(struct gl_context *ctx)
769*61046927SAndroid Build Coastguard Worker {
770*61046927SAndroid Build Coastguard Worker    assert(ctx->API != API_OPENGL_CORE);
771*61046927SAndroid Build Coastguard Worker 
772*61046927SAndroid Build Coastguard Worker    /* Iterate over all VAOs. */
773*61046927SAndroid Build Coastguard Worker    _mesa_HashWalk(&ctx->Array.Objects, unbind_uploaded_vbos, ctx);
774*61046927SAndroid Build Coastguard Worker    unbind_uploaded_vbos(ctx->Array.DefaultVAO, ctx);
775*61046927SAndroid Build Coastguard Worker }
776