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