xref: /aosp_15_r20/external/mesa3d/src/mesa/main/glthread_draw_unroll.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
5  * Copyright (C) 2022 Advanced Micro Devices, Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 /* This lowers glDrawElementsBaseVertex into glBegin/glEnd draws.
27  *
28  * It's used by glthread when uploading non-VBO vertex arrays would take too
29  * much time due to small numbers of vertices per draw where indices have very
30  * large differences. (e.g. indices {0, 1000000} normally cause us to upload
31  * (1000000 * stride) bytes to draw 2 vertices) This helps performance for
32  * such pathological cases.
33  */
34 
35 #include "context.h"
36 #include "glthread_marshal.h"
37 #include "vbo/vbo_util.h"
38 #include "util/half_float.h"
39 
40 #define FIXED_TO_FLOAT(x) \
41    (int32_t)(CLAMP((x), -65536.0f, 65535.0f) * (double)0x10000)
42 
43 #define UNPACK_RGB10A2_USCALED(x) { \
44    (x) & 0x3ff, \
45    ((x) >> 10) & 0x3ff, \
46    ((x) >> 20) & 0x3ff, \
47    ((x) >> 30) & 0x3 \
48 }
49 
50 #define UNPACK_RGB10A2_SSCALED(x) { \
51    conv_i10_to_i((x) & 0x3ff),         \
52    conv_i10_to_i(((x) >> 10) & 0x3ff), \
53    conv_i10_to_i(((x) >> 20) & 0x3ff), \
54    conv_i2_to_i(((x) >> 30) & 0x3) \
55 }
56 
57 #define UNPACK_RGB10A2_UNORM(x) { \
58    conv_ui10_to_norm_float((x) & 0x3ff), \
59    conv_ui10_to_norm_float(((x) >> 10) & 0x3ff), \
60    conv_ui10_to_norm_float(((x) >> 20) & 0x3ff), \
61    conv_ui2_to_norm_float(((x) >> 30) & 0x3) \
62 }
63 
64 #define UNPACK_RGB10A2_SNORM(x) { \
65    conv_i10_to_norm_float(ctx, (x) & 0x3ff), \
66    conv_i10_to_norm_float(ctx, ((x) >> 10) & 0x3ff), \
67    conv_i10_to_norm_float(ctx, ((x) >> 20) & 0x3ff), \
68    conv_i2_to_norm_float(ctx, ((x) >> 30) & 0x3) \
69 }
70 
71 #define UNPACK_BGR10A2_USCALED(x) { \
72    ((x) >> 20) & 0x3ff, \
73    ((x) >> 10) & 0x3ff, \
74    (x) & 0x3ff, \
75    ((x) >> 30) & 0x3 \
76 }
77 
78 #define UNPACK_BGR10A2_SSCALED(x) { \
79    conv_i10_to_i(((x) >> 20) & 0x3ff), \
80    conv_i10_to_i(((x) >> 10) & 0x3ff), \
81    conv_i10_to_i((x) & 0x3ff),         \
82    conv_i2_to_i(((x) >> 30) & 0x3) \
83 }
84 
85 #define UNPACK_BGR10A2_UNORM(x) { \
86    conv_ui10_to_norm_float(((x) >> 20) & 0x3ff), \
87    conv_ui10_to_norm_float(((x) >> 10) & 0x3ff), \
88    conv_ui10_to_norm_float((x) & 0x3ff), \
89    conv_ui2_to_norm_float(((x) >> 30) & 0x3) \
90 }
91 
92 #define UNPACK_BGR10A2_SNORM(x) { \
93    conv_i10_to_norm_float(ctx, ((x) >> 20) & 0x3ff), \
94    conv_i10_to_norm_float(ctx, ((x) >> 10) & 0x3ff), \
95    conv_i10_to_norm_float(ctx, (x) & 0x3ff), \
96    conv_i2_to_norm_float(ctx, ((x) >> 30) & 0x3) \
97 }
98 
99 #define UNPACK_BGRA8_UNORM(x) { \
100    UBYTE_TO_FLOAT(((x) >> 16) & 0xff), \
101    UBYTE_TO_FLOAT(((x) >> 8) & 0xff), \
102    UBYTE_TO_FLOAT((x) & 0xff), \
103    UBYTE_TO_FLOAT(((x) >> 24) & 0xff) \
104 }
105 
106 #define TEMPLATE_FUNC1(t, src, type, dst, conv) \
107    static void _mesa_wrapped_VertexAttrib##t##1##src(GLuint index, type *v) \
108    { \
109       _mesa_marshal_VertexAttrib##t##1##dst(index, conv(v[0])); \
110    }
111 
112 #define TEMPLATE_FUNC2(t, src, type, dst, conv) \
113    static void _mesa_wrapped_VertexAttrib##t##2##src(GLuint index, type *v) \
114    { \
115       _mesa_marshal_VertexAttrib##t##2##dst(index, conv(v[0]), conv(v[1])); \
116    }
117 
118 #define TEMPLATE_FUNC3(t, src, type, dst, conv) \
119    static void _mesa_wrapped_VertexAttrib##t##3##src(GLuint index, type *v) \
120    { \
121       _mesa_marshal_VertexAttrib##t##3##dst(index, conv(v[0]), conv(v[1]), \
122                                              conv(v[2])); \
123    }
124 
125 #define TEMPLATE_FUNC4(t, src, type, dst, conv) \
126    static void _mesa_wrapped_VertexAttrib##t##4##src(GLuint index, type *v) \
127    { \
128       _mesa_marshal_VertexAttrib##t##4##dst(index, conv(v[0]), conv(v[1]), \
129                                             conv(v[2]), conv(v[3])); \
130    }
131 
132 #define SCALED false
133 #define NORMALIZED true
134 
135 #define TEMPLATE_FUNCP(n, src, type, normalized) \
136    static void _mesa_wrapped_VertexAttribP##n##src(GLuint index, GLuint *v) \
137    { \
138       _mesa_marshal_VertexAttribP##n##ui(index, type, normalized, v[0]); \
139    }
140 
141 #define TEMPLATE_FUNCUP(n, src, dst, unpack) \
142    static void _mesa_wrapped_VertexAttribP##n##src(GLuint index, GLuint *v) \
143    { \
144       float fv[n] = unpack(v[0]); \
145       _mesa_marshal_VertexAttrib##n##dst(index, fv); \
146    }
147 
148 #define TEMPLATE_FUNCUP_CTX(n, src, dst, unpack) \
149    static void _mesa_wrapped_VertexAttribP##n##src(GLuint index, GLuint *v) \
150    { \
151       GET_CURRENT_CONTEXT(ctx); \
152       float fv[n] = unpack(v[0]); \
153       _mesa_marshal_VertexAttrib##n##dst(index, fv); \
154    }
155 
156 #define TEMPLATE_FUNC_ALL3(t, src, type, dst, conv) \
157    TEMPLATE_FUNC1(t, src, type, dst, conv) \
158    TEMPLATE_FUNC2(t, src, type, dst, conv) \
159    TEMPLATE_FUNC3(t, src, type, dst, conv)
160 
161 #define TEMPLATE_FUNC_ALL4(t, src, type, dst, conv) \
162    TEMPLATE_FUNC_ALL3(t, src, type, dst, conv) \
163    TEMPLATE_FUNC4(t, src, type, dst, conv)
164 
165 /* We use NV attributes because they can set all non-generic attributes. */
166 
167 /* Define VertexAttrib wrappers using template macros. */
168 TEMPLATE_FUNC_ALL4(, bvNV, GLbyte, sNV, )
169 TEMPLATE_FUNC_ALL4(, NbvNV, GLbyte, fNV, BYTE_TO_FLOAT)
170 TEMPLATE_FUNC_ALL4(, ubvNV, GLubyte, sNV, )
171 TEMPLATE_FUNC_ALL3(, NubvNV, GLubyte, fNV, UBYTE_TO_FLOAT) /* TODO: use VertexAttrib4ubNV */
172 
173 TEMPLATE_FUNC_ALL3(, bv, GLbyte, s, )                     /* TODO: use VertexAttrib4bv */
174 TEMPLATE_FUNC_ALL3(, Nbv, GLbyte, fARB, BYTE_TO_FLOAT)    /* TODO: use VertexAttrib4Nb */
175 TEMPLATE_FUNC_ALL3(, ubv, GLubyte, s, )                   /* TODO: use VertexAttrib4ubv */
176 TEMPLATE_FUNC_ALL3(, Nubv, GLubyte, fARB, UBYTE_TO_FLOAT) /* TODO: use VertexAttrib4Nub */
177 TEMPLATE_FUNC_ALL3(I, bv, GLbyte, iEXT, )                 /* TODO: use VertexAttribI4bv */
178 TEMPLATE_FUNC_ALL3(I, ubv, GLubyte, uiEXT, )              /* TODO: use VertexAttribI4ubv */
179 
180 TEMPLATE_FUNC_ALL4(, NsvNV, GLshort, fNV, SHORT_TO_FLOAT)
181 TEMPLATE_FUNC_ALL4(, usvNV, GLushort, fNV, )
182 TEMPLATE_FUNC_ALL4(, NusvNV, GLushort, fNV, USHORT_TO_FLOAT)
183 
184 TEMPLATE_FUNC_ALL3(, Nsv, GLshort, fARB, SHORT_TO_FLOAT)  /* TODO: use VertexAttrib4Nsv */
185 TEMPLATE_FUNC_ALL3(, usv, GLushort, fARB, )               /* TODO: use VertexAttrib4usv */
186 TEMPLATE_FUNC_ALL3(, Nusv, GLushort, fARB, USHORT_TO_FLOAT) /* TODO: use VertexAttrib4Nusv */
187 TEMPLATE_FUNC_ALL3(I, sv, GLshort, iEXT, )                /* TODO: use VertexAttribI4sv */
188 TEMPLATE_FUNC_ALL3(I, usv, GLushort, uiEXT, )             /* TODO: use VertexAttribI4usv */
189 
190 TEMPLATE_FUNC_ALL4(, ivNV, GLint, fNV, )
191 TEMPLATE_FUNC_ALL4(, NivNV, GLint, fNV, INT_TO_FLOAT)
192 TEMPLATE_FUNC_ALL4(, uivNV, GLuint, fNV, )
193 TEMPLATE_FUNC_ALL4(, NuivNV, GLuint, fNV, UINT_TO_FLOAT)
194 
195 TEMPLATE_FUNC_ALL3(, iv, GLint, fARB, )
196 TEMPLATE_FUNC_ALL3(, Niv, GLint, fARB, INT_TO_FLOAT)
197 TEMPLATE_FUNC_ALL3(, uiv, GLuint, fARB, )
198 TEMPLATE_FUNC_ALL3(, Nuiv, GLuint, fARB, UINT_TO_FLOAT)
199 
200 TEMPLATE_FUNC_ALL4(, xvNV, GLfixed, fNV, FIXED_TO_FLOAT)
201 TEMPLATE_FUNC_ALL4(, xv, GLfixed, fARB, FIXED_TO_FLOAT)
202 
203 TEMPLATE_FUNC_ALL4(, hv, GLhalf, fARB, _mesa_half_to_float)
204 
205 TEMPLATE_FUNC2(L, ui64v, GLuint64, d, UINT64_AS_DOUBLE)
206 TEMPLATE_FUNC3(L, ui64v, GLuint64, d, UINT64_AS_DOUBLE)
207 TEMPLATE_FUNC4(L, ui64v, GLuint64, d, UINT64_AS_DOUBLE)
208 
209 TEMPLATE_FUNCP(4, _rgb10a2_sscaled, GL_INT_2_10_10_10_REV, SCALED)
210 TEMPLATE_FUNCP(4, _rgb10a2_snorm, GL_INT_2_10_10_10_REV, NORMALIZED)
211 TEMPLATE_FUNCP(4, _rgb10a2_uscaled, GL_UNSIGNED_INT_2_10_10_10_REV, SCALED)
212 TEMPLATE_FUNCP(4, _rgb10a2_unorm, GL_UNSIGNED_INT_2_10_10_10_REV, NORMALIZED)
213 TEMPLATE_FUNCP(3, _rg11b10_float, GL_UNSIGNED_INT_10F_11F_11F_REV, SCALED)
214 
215 TEMPLATE_FUNCUP(4, NV_rgb10a2_uscaled, fvNV, UNPACK_RGB10A2_USCALED)
216 TEMPLATE_FUNCUP(4, NV_rgb10a2_sscaled, fvNV, UNPACK_RGB10A2_SSCALED)
217 TEMPLATE_FUNCUP(4, NV_rgb10a2_unorm, fvNV, UNPACK_RGB10A2_UNORM)
218 TEMPLATE_FUNCUP_CTX(4, NV_rgb10a2_snorm, fvNV, UNPACK_RGB10A2_SNORM)
219 
220 TEMPLATE_FUNCUP(4, NV_bgr10a2_uscaled, fvNV, UNPACK_BGR10A2_USCALED)
221 TEMPLATE_FUNCUP(4, NV_bgr10a2_sscaled, fvNV, UNPACK_BGR10A2_SSCALED)
222 TEMPLATE_FUNCUP(4, NV_bgr10a2_unorm, fvNV, UNPACK_BGR10A2_UNORM)
223 TEMPLATE_FUNCUP_CTX(4, NV_bgr10a2_snorm, fvNV, UNPACK_BGR10A2_SNORM)
224 TEMPLATE_FUNCUP(4, NV_bgra8_unorm, fvNV, UNPACK_BGRA8_UNORM)
225 
226 TEMPLATE_FUNCUP(4, _bgr10a2_uscaled, fvARB, UNPACK_BGR10A2_USCALED)
227 TEMPLATE_FUNCUP(4, _bgr10a2_sscaled, fvARB, UNPACK_BGR10A2_SSCALED)
228 TEMPLATE_FUNCUP(4, _bgr10a2_unorm, fvARB, UNPACK_BGR10A2_UNORM)
229 TEMPLATE_FUNCUP_CTX(4, _bgr10a2_snorm, fvARB, UNPACK_BGR10A2_SNORM)
230 TEMPLATE_FUNCUP(4, _bgra8_unorm, fvARB, UNPACK_BGRA8_UNORM)
231 
232 typedef void (GLAPIENTRY *attrib_func)(GLuint indx, const void *data);
233 
234 /* indexing: [gltype & 0x3f][normalized][size - 1] */
235 static const attrib_func legacy_rgba_attrib_funcs[][2][4] = {
236    { /* GL_BYTE */
237       {
238          (attrib_func)_mesa_wrapped_VertexAttrib1bvNV,
239          (attrib_func)_mesa_wrapped_VertexAttrib2bvNV,
240          (attrib_func)_mesa_wrapped_VertexAttrib3bvNV,
241          (attrib_func)_mesa_wrapped_VertexAttrib4bvNV,
242       },
243       {
244          (attrib_func)_mesa_wrapped_VertexAttrib1NbvNV,
245          (attrib_func)_mesa_wrapped_VertexAttrib2NbvNV,
246          (attrib_func)_mesa_wrapped_VertexAttrib3NbvNV,
247          (attrib_func)_mesa_wrapped_VertexAttrib4NbvNV,
248       },
249    },
250    { /* GL_UNSIGNED_BYTE */
251       {
252          (attrib_func)_mesa_wrapped_VertexAttrib1ubvNV,
253          (attrib_func)_mesa_wrapped_VertexAttrib2ubvNV,
254          (attrib_func)_mesa_wrapped_VertexAttrib3ubvNV,
255          (attrib_func)_mesa_wrapped_VertexAttrib4ubvNV,
256       },
257       {
258          (attrib_func)_mesa_wrapped_VertexAttrib1NubvNV,
259          (attrib_func)_mesa_wrapped_VertexAttrib2NubvNV,
260          (attrib_func)_mesa_wrapped_VertexAttrib3NubvNV,
261          (attrib_func)_mesa_marshal_VertexAttrib4ubvNV, /* always normalized */
262       },
263    },
264    { /* GL_SHORT */
265       {
266          (attrib_func)_mesa_marshal_VertexAttrib1svNV,
267          (attrib_func)_mesa_marshal_VertexAttrib2svNV,
268          (attrib_func)_mesa_marshal_VertexAttrib3svNV,
269          (attrib_func)_mesa_marshal_VertexAttrib4svNV,
270       },
271       {
272          (attrib_func)_mesa_wrapped_VertexAttrib1NsvNV,
273          (attrib_func)_mesa_wrapped_VertexAttrib2NsvNV,
274          (attrib_func)_mesa_wrapped_VertexAttrib3NsvNV,
275          (attrib_func)_mesa_wrapped_VertexAttrib4NsvNV,
276       },
277    },
278    { /* GL_UNSIGNED_SHORT */
279       {
280          (attrib_func)_mesa_wrapped_VertexAttrib1usvNV,
281          (attrib_func)_mesa_wrapped_VertexAttrib2usvNV,
282          (attrib_func)_mesa_wrapped_VertexAttrib3usvNV,
283          (attrib_func)_mesa_wrapped_VertexAttrib4usvNV,
284       },
285       {
286          (attrib_func)_mesa_wrapped_VertexAttrib1NusvNV,
287          (attrib_func)_mesa_wrapped_VertexAttrib2NusvNV,
288          (attrib_func)_mesa_wrapped_VertexAttrib3NusvNV,
289          (attrib_func)_mesa_wrapped_VertexAttrib4NusvNV,
290       },
291    },
292    { /* GL_INT */
293       {
294          (attrib_func)_mesa_wrapped_VertexAttrib1ivNV,
295          (attrib_func)_mesa_wrapped_VertexAttrib2ivNV,
296          (attrib_func)_mesa_wrapped_VertexAttrib3ivNV,
297          (attrib_func)_mesa_wrapped_VertexAttrib4ivNV,
298       },
299       {
300          (attrib_func)_mesa_wrapped_VertexAttrib1NivNV,
301          (attrib_func)_mesa_wrapped_VertexAttrib2NivNV,
302          (attrib_func)_mesa_wrapped_VertexAttrib3NivNV,
303          (attrib_func)_mesa_wrapped_VertexAttrib4NivNV,
304       },
305    },
306    { /* GL_UNSIGNED_INT */
307       {
308          (attrib_func)_mesa_wrapped_VertexAttrib1uivNV,
309          (attrib_func)_mesa_wrapped_VertexAttrib2uivNV,
310          (attrib_func)_mesa_wrapped_VertexAttrib3uivNV,
311          (attrib_func)_mesa_wrapped_VertexAttrib4uivNV,
312       },
313       {
314          (attrib_func)_mesa_wrapped_VertexAttrib1NuivNV,
315          (attrib_func)_mesa_wrapped_VertexAttrib2NuivNV,
316          (attrib_func)_mesa_wrapped_VertexAttrib3NuivNV,
317          (attrib_func)_mesa_wrapped_VertexAttrib4NuivNV,
318        },
319    },
320    { /* GL_FLOAT */
321       {
322          (attrib_func)_mesa_marshal_VertexAttrib1fvNV,
323          (attrib_func)_mesa_marshal_VertexAttrib2fvNV,
324          (attrib_func)_mesa_marshal_VertexAttrib3fvNV,
325          (attrib_func)_mesa_marshal_VertexAttrib4fvNV,
326       },
327       {
328          (attrib_func)_mesa_marshal_VertexAttrib1fvNV,
329          (attrib_func)_mesa_marshal_VertexAttrib2fvNV,
330          (attrib_func)_mesa_marshal_VertexAttrib3fvNV,
331          (attrib_func)_mesa_marshal_VertexAttrib4fvNV,
332       },
333    },
334    {{0}}, /* GL_2_BYTES */
335    {{0}}, /* GL_3_BYTES */
336    {{0}}, /* GL_4_BYTES */
337    { /* GL_DOUBLE */
338       {
339          (attrib_func)_mesa_marshal_VertexAttrib1dvNV,
340          (attrib_func)_mesa_marshal_VertexAttrib2dvNV,
341          (attrib_func)_mesa_marshal_VertexAttrib3dvNV,
342          (attrib_func)_mesa_marshal_VertexAttrib4dvNV,
343       },
344       {
345          (attrib_func)_mesa_marshal_VertexAttrib1dvNV,
346          (attrib_func)_mesa_marshal_VertexAttrib2dvNV,
347          (attrib_func)_mesa_marshal_VertexAttrib3dvNV,
348          (attrib_func)_mesa_marshal_VertexAttrib4dvNV,
349       },
350    },
351    { /* GL_HALF_FLOAT */
352       {
353          (attrib_func)_mesa_marshal_VertexAttrib1hvNV,
354          (attrib_func)_mesa_marshal_VertexAttrib2hvNV,
355          (attrib_func)_mesa_marshal_VertexAttrib3hvNV,
356          (attrib_func)_mesa_marshal_VertexAttrib4hvNV,
357       },
358       {
359          (attrib_func)_mesa_marshal_VertexAttrib1hvNV,
360          (attrib_func)_mesa_marshal_VertexAttrib2hvNV,
361          (attrib_func)_mesa_marshal_VertexAttrib3hvNV,
362          (attrib_func)_mesa_marshal_VertexAttrib4hvNV,
363       },
364    },
365    { /* GL_FIXED */
366       {
367          (attrib_func)_mesa_wrapped_VertexAttrib1xvNV,
368          (attrib_func)_mesa_wrapped_VertexAttrib2xvNV,
369          (attrib_func)_mesa_wrapped_VertexAttrib3xvNV,
370          (attrib_func)_mesa_wrapped_VertexAttrib4xvNV,
371       },
372       {
373          (attrib_func)_mesa_wrapped_VertexAttrib1xvNV,
374          (attrib_func)_mesa_wrapped_VertexAttrib2xvNV,
375          (attrib_func)_mesa_wrapped_VertexAttrib3xvNV,
376          (attrib_func)_mesa_wrapped_VertexAttrib4xvNV,
377       },
378    },
379    {{0}}, /* unused (13) */
380    {{0}}, /* unused (14) */
381    {{0}}, /* unused (15) */
382    {{0}}, /* unused (16) */
383    {{0}}, /* unused (17) */
384    {{0}}, /* unused (18) */
385    {{0}}, /* unused (19) */
386    {{0}}, /* unused (20) */
387    {{0}}, /* unused (21) */
388    {{0}}, /* unused (22) */
389    {{0}}, /* unused (23) */
390    {{0}}, /* unused (24) */
391    {{0}}, /* unused (25) */
392    {{0}}, /* unused (26) */
393    {{0}}, /* unused (27) */
394    {{0}}, /* unused (28) */
395    {{0}}, /* unused (29) */
396    {{0}}, /* unused (30) */
397    { /* GL_INT_2_10_10_10_REV */
398       {
399          0,
400          0,
401          0,
402          (attrib_func)_mesa_wrapped_VertexAttribP4NV_rgb10a2_sscaled,
403       },
404       {
405          0,
406          0,
407          0,
408          (attrib_func)_mesa_wrapped_VertexAttribP4NV_rgb10a2_snorm,
409       },
410    },
411    {{0}}, /* unused (32) */
412    { /* GL_HALF_FLOAT_OES */
413       {
414          (attrib_func)_mesa_marshal_VertexAttrib1hvNV,
415          (attrib_func)_mesa_marshal_VertexAttrib2hvNV,
416          (attrib_func)_mesa_marshal_VertexAttrib3hvNV,
417          (attrib_func)_mesa_marshal_VertexAttrib4hvNV,
418       },
419       {
420          (attrib_func)_mesa_marshal_VertexAttrib1hvNV,
421          (attrib_func)_mesa_marshal_VertexAttrib2hvNV,
422          (attrib_func)_mesa_marshal_VertexAttrib3hvNV,
423          (attrib_func)_mesa_marshal_VertexAttrib4hvNV,
424       },
425    },
426    {{0}}, /* unused (34) */
427    {{0}}, /* unused (35) */
428    {{0}}, /* unused (36) */
429    {{0}}, /* unused (37) */
430    {{0}}, /* unused (38) */
431    {{0}}, /* unused (39) */
432    { /* GL_UNSIGNED_INT_2_10_10_10_REV */
433       {
434          0,
435          0,
436          0,
437          (attrib_func)_mesa_wrapped_VertexAttribP4NV_rgb10a2_uscaled,
438       },
439       {
440          0,
441          0,
442          0,
443          (attrib_func)_mesa_wrapped_VertexAttribP4NV_rgb10a2_unorm,
444       },
445    },
446 };
447 
448 /* indexing: [type & 0x3][normalized] */
449 static const attrib_func legacy_bgra_attrib_funcs[4][2] = {
450    { /* GL_UNSIGNED_INT_2_10_10_10_REV */
451       (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgr10a2_uscaled,
452       (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgr10a2_unorm,
453    },
454    { /* GL_UNSIGNED_BYTE */
455       0,
456       (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgra8_unorm,
457    },
458    {0}, /* unused (2) */
459    { /* GL_INT_2_10_10_10_REV */
460       (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgr10a2_sscaled,
461       (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgr10a2_snorm,
462    }
463 };
464 
465 /* indexing: [(gltype & 0x3f) | (double << 5)][integer*2 + normalized][size - 1] */
466 static const attrib_func generic_rgba_attrib_funcs[][4][4] = {
467    { /* GL_BYTE */
468       {
469          (attrib_func)_mesa_wrapped_VertexAttrib1bv,
470          (attrib_func)_mesa_wrapped_VertexAttrib2bv,
471          (attrib_func)_mesa_wrapped_VertexAttrib3bv,
472          (attrib_func)_mesa_marshal_VertexAttrib4bv,
473       },
474       {
475          (attrib_func)_mesa_wrapped_VertexAttrib1Nbv,
476          (attrib_func)_mesa_wrapped_VertexAttrib2Nbv,
477          (attrib_func)_mesa_wrapped_VertexAttrib3Nbv,
478          (attrib_func)_mesa_marshal_VertexAttrib4Nbv,
479       },
480       {
481          (attrib_func)_mesa_wrapped_VertexAttribI1bv,
482          (attrib_func)_mesa_wrapped_VertexAttribI2bv,
483          (attrib_func)_mesa_wrapped_VertexAttribI3bv,
484          (attrib_func)_mesa_marshal_VertexAttribI4bv,
485       },
486    },
487    { /* GL_UNSIGNED_BYTE */
488       {
489          (attrib_func)_mesa_wrapped_VertexAttrib1ubv,
490          (attrib_func)_mesa_wrapped_VertexAttrib2ubv,
491          (attrib_func)_mesa_wrapped_VertexAttrib3ubv,
492          (attrib_func)_mesa_marshal_VertexAttrib4ubv,
493       },
494       {
495          (attrib_func)_mesa_wrapped_VertexAttrib1Nubv,
496          (attrib_func)_mesa_wrapped_VertexAttrib2Nubv,
497          (attrib_func)_mesa_wrapped_VertexAttrib3Nubv,
498          (attrib_func)_mesa_marshal_VertexAttrib4Nubv,
499       },
500       {
501          (attrib_func)_mesa_wrapped_VertexAttribI1ubv,
502          (attrib_func)_mesa_wrapped_VertexAttribI2ubv,
503          (attrib_func)_mesa_wrapped_VertexAttribI3ubv,
504          (attrib_func)_mesa_marshal_VertexAttribI4ubv,
505       },
506    },
507    { /* GL_SHORT */
508       {
509          (attrib_func)_mesa_marshal_VertexAttrib1sv,
510          (attrib_func)_mesa_marshal_VertexAttrib2sv,
511          (attrib_func)_mesa_marshal_VertexAttrib3sv,
512          (attrib_func)_mesa_marshal_VertexAttrib4sv,
513       },
514       {
515          (attrib_func)_mesa_wrapped_VertexAttrib1Nsv,
516          (attrib_func)_mesa_wrapped_VertexAttrib2Nsv,
517          (attrib_func)_mesa_wrapped_VertexAttrib3Nsv,
518          (attrib_func)_mesa_marshal_VertexAttrib4Nsv,
519       },
520       {
521          (attrib_func)_mesa_wrapped_VertexAttribI1sv,
522          (attrib_func)_mesa_wrapped_VertexAttribI2sv,
523          (attrib_func)_mesa_wrapped_VertexAttribI3sv,
524          (attrib_func)_mesa_marshal_VertexAttribI4sv,
525       },
526    },
527    { /* GL_UNSIGNED_SHORT */
528       {
529          (attrib_func)_mesa_wrapped_VertexAttrib1usv,
530          (attrib_func)_mesa_wrapped_VertexAttrib2usv,
531          (attrib_func)_mesa_wrapped_VertexAttrib3usv,
532          (attrib_func)_mesa_marshal_VertexAttrib4usv,
533       },
534       {
535          (attrib_func)_mesa_wrapped_VertexAttrib1Nusv,
536          (attrib_func)_mesa_wrapped_VertexAttrib2Nusv,
537          (attrib_func)_mesa_wrapped_VertexAttrib3Nusv,
538          (attrib_func)_mesa_marshal_VertexAttrib4Nusv,
539       },
540       {
541          (attrib_func)_mesa_wrapped_VertexAttribI1usv,
542          (attrib_func)_mesa_wrapped_VertexAttribI2usv,
543          (attrib_func)_mesa_wrapped_VertexAttribI3usv,
544          (attrib_func)_mesa_marshal_VertexAttribI4usv,
545       },
546    },
547    { /* GL_INT */
548       {
549          (attrib_func)_mesa_wrapped_VertexAttrib1iv,
550          (attrib_func)_mesa_wrapped_VertexAttrib2iv,
551          (attrib_func)_mesa_wrapped_VertexAttrib3iv,
552          (attrib_func)_mesa_marshal_VertexAttrib4iv,
553       },
554       {
555          (attrib_func)_mesa_wrapped_VertexAttrib1Niv,
556          (attrib_func)_mesa_wrapped_VertexAttrib2Niv,
557          (attrib_func)_mesa_wrapped_VertexAttrib3Niv,
558          (attrib_func)_mesa_marshal_VertexAttrib4Niv,
559       },
560       {
561          (attrib_func)_mesa_marshal_VertexAttribI1iv,
562          (attrib_func)_mesa_marshal_VertexAttribI2ivEXT,
563          (attrib_func)_mesa_marshal_VertexAttribI3ivEXT,
564          (attrib_func)_mesa_marshal_VertexAttribI4ivEXT,
565       },
566    },
567    { /* GL_UNSIGNED_INT */
568       {
569          (attrib_func)_mesa_wrapped_VertexAttrib1uiv,
570          (attrib_func)_mesa_wrapped_VertexAttrib2uiv,
571          (attrib_func)_mesa_wrapped_VertexAttrib3uiv,
572          (attrib_func)_mesa_marshal_VertexAttrib4uiv,
573       },
574       {
575          (attrib_func)_mesa_wrapped_VertexAttrib1Nuiv,
576          (attrib_func)_mesa_wrapped_VertexAttrib2Nuiv,
577          (attrib_func)_mesa_wrapped_VertexAttrib3Nuiv,
578          (attrib_func)_mesa_marshal_VertexAttrib4Nuiv,
579       },
580       {
581          (attrib_func)_mesa_marshal_VertexAttribI1uiv,
582          (attrib_func)_mesa_marshal_VertexAttribI2uivEXT,
583          (attrib_func)_mesa_marshal_VertexAttribI3uivEXT,
584          (attrib_func)_mesa_marshal_VertexAttribI4uivEXT,
585       },
586    },
587    { /* GL_FLOAT */
588       {
589          (attrib_func)_mesa_marshal_VertexAttrib1fvARB,
590          (attrib_func)_mesa_marshal_VertexAttrib2fvARB,
591          (attrib_func)_mesa_marshal_VertexAttrib3fvARB,
592          (attrib_func)_mesa_marshal_VertexAttrib4fvARB,
593       },
594       {
595          (attrib_func)_mesa_marshal_VertexAttrib1fvARB,
596          (attrib_func)_mesa_marshal_VertexAttrib2fvARB,
597          (attrib_func)_mesa_marshal_VertexAttrib3fvARB,
598          (attrib_func)_mesa_marshal_VertexAttrib4fvARB,
599       },
600    },
601    {{0}}, /* GL_2_BYTES */
602    {{0}}, /* GL_3_BYTES */
603    {{0}}, /* GL_4_BYTES */
604    { /* GL_DOUBLE */
605       {
606          (attrib_func)_mesa_marshal_VertexAttrib1dv,
607          (attrib_func)_mesa_marshal_VertexAttrib2dv,
608          (attrib_func)_mesa_marshal_VertexAttrib3dv,
609          (attrib_func)_mesa_marshal_VertexAttrib4dv,
610       },
611       {
612          (attrib_func)_mesa_marshal_VertexAttrib1dv,
613          (attrib_func)_mesa_marshal_VertexAttrib2dv,
614          (attrib_func)_mesa_marshal_VertexAttrib3dv,
615          (attrib_func)_mesa_marshal_VertexAttrib4dv,
616       },
617    },
618    { /* GL_HALF_FLOAT */
619       {
620          (attrib_func)_mesa_wrapped_VertexAttrib1hv,
621          (attrib_func)_mesa_wrapped_VertexAttrib2hv,
622          (attrib_func)_mesa_wrapped_VertexAttrib3hv,
623          (attrib_func)_mesa_wrapped_VertexAttrib4hv,
624       },
625       {
626          (attrib_func)_mesa_wrapped_VertexAttrib1hv,
627          (attrib_func)_mesa_wrapped_VertexAttrib2hv,
628          (attrib_func)_mesa_wrapped_VertexAttrib3hv,
629          (attrib_func)_mesa_wrapped_VertexAttrib4hv,
630       },
631    },
632    { /* GL_FIXED */
633        {
634          (attrib_func)_mesa_wrapped_VertexAttrib1xv,
635          (attrib_func)_mesa_wrapped_VertexAttrib2xv,
636          (attrib_func)_mesa_wrapped_VertexAttrib3xv,
637          (attrib_func)_mesa_wrapped_VertexAttrib4xv,
638       },
639       {
640          (attrib_func)_mesa_wrapped_VertexAttrib1xv,
641          (attrib_func)_mesa_wrapped_VertexAttrib2xv,
642          (attrib_func)_mesa_wrapped_VertexAttrib3xv,
643          (attrib_func)_mesa_wrapped_VertexAttrib4xv,
644       },
645    },
646    {{0}}, /* unused (13) */
647    {{0}}, /* unused (14) */
648    {{0}}, /* unused (15) */
649    {{0}}, /* unused (16) */
650    {{0}}, /* unused (17) */
651    {{0}}, /* unused (18) */
652    {{0}}, /* unused (19) */
653    {{0}}, /* unused (20) */
654    {{0}}, /* unused (21) */
655    {{0}}, /* unused (22) */
656    {{0}}, /* unused (23) */
657    {{0}}, /* unused (24) */
658    {{0}}, /* unused (25) */
659    {{0}}, /* unused (26) */
660    {{0}}, /* unused (27) */
661    {{0}}, /* unused (28) */
662    {{0}}, /* unused (29) */
663    {{0}}, /* unused (30) */
664    { /* GL_INT_2_10_10_10_REV */
665       {
666          0,
667          0,
668          0,
669          (attrib_func)_mesa_wrapped_VertexAttribP4_rgb10a2_sscaled,
670       },
671       {
672          0,
673          0,
674          0,
675          (attrib_func)_mesa_wrapped_VertexAttribP4_rgb10a2_snorm,
676       },
677    },
678    {{0}}, /* unused (32) */
679    { /* GL_HALF_FLOAT_OES */
680       {
681          (attrib_func)_mesa_wrapped_VertexAttrib1hv,
682          (attrib_func)_mesa_wrapped_VertexAttrib2hv,
683          (attrib_func)_mesa_wrapped_VertexAttrib3hv,
684          (attrib_func)_mesa_wrapped_VertexAttrib4hv,
685       },
686       {
687          (attrib_func)_mesa_wrapped_VertexAttrib1hv,
688          (attrib_func)_mesa_wrapped_VertexAttrib2hv,
689          (attrib_func)_mesa_wrapped_VertexAttrib3hv,
690          (attrib_func)_mesa_wrapped_VertexAttrib4hv,
691       },
692    },
693    {{0}}, /* unused (34) */
694    {{0}}, /* unused (35) */
695    {{0}}, /* unused (36) */
696    {{0}}, /* unused (37) */
697    {{0}}, /* unused (38) */
698    {{0}}, /* unused (39) */
699    { /* GL_UNSIGNED_INT_2_10_10_10_REV */
700       {
701          0,
702          0,
703          0,
704          (attrib_func)_mesa_wrapped_VertexAttribP4_rgb10a2_uscaled,
705       },
706       {
707          0,
708          0,
709          0,
710          (attrib_func)_mesa_wrapped_VertexAttribP4_rgb10a2_unorm,
711       },
712    },
713    {{0}}, /* unused (41) */
714    { /* GL_DOUBLE | (doubles << 5) (real double) */
715       {
716          (attrib_func)_mesa_marshal_VertexAttribL1dv,
717          (attrib_func)_mesa_marshal_VertexAttribL2dv,
718          (attrib_func)_mesa_marshal_VertexAttribL3dv,
719          (attrib_func)_mesa_marshal_VertexAttribL4dv,
720       },
721    },
722    {{0}}, /* unused (43) */
723    {{0}}, /* unused (44) */
724    {{0}}, /* unused (45) */
725    {{0}}, /* unused (46) */
726    { /* GL_UNSIGNED_INT64_ARB | (doubles << 5) (doubles is always true) */
727      {0},
728      {0},
729      {
730         (attrib_func)_mesa_marshal_VertexAttribL1ui64vARB,
731         (attrib_func)_mesa_wrapped_VertexAttribL2ui64v,
732         (attrib_func)_mesa_wrapped_VertexAttribL3ui64v,
733         (attrib_func)_mesa_wrapped_VertexAttribL4ui64v,
734      },
735    },
736    {{0}}, /* unused (48) */
737    {{0}}, /* unused (49) */
738    {{0}}, /* unused (50) */
739    {{0}}, /* unused (51) */
740    {{0}}, /* unused (52) */
741    {{0}}, /* unused (53) */
742    {{0}}, /* unused (54) */
743    {{0}}, /* unused (55) */
744    {{0}}, /* unused (56) */
745    {{0}}, /* unused (57) */
746    {{0}}, /* unused (58) */
747    { /* GL_UNSIGNED_INT_10F_11F_11F_REV */
748       {
749          0,
750          0,
751          (attrib_func)_mesa_wrapped_VertexAttribP3_rg11b10_float,
752          0
753       },
754       {
755          0,
756          0,
757          (attrib_func)_mesa_wrapped_VertexAttribP3_rg11b10_float,
758          0
759       },
760    },
761 };
762 
763 /* indexing: [type & 0x3][normalized] */
764 static const attrib_func generic_bgra_attrib_funcs[4][2] = {
765    { /* GL_UNSIGNED_INT_2_10_10_10_REV */
766       (attrib_func)_mesa_wrapped_VertexAttribP4_bgr10a2_uscaled,
767       (attrib_func)_mesa_wrapped_VertexAttribP4_bgr10a2_unorm,
768    },
769    { /* GL_UNSIGNED_BYTE */
770       0,
771       (attrib_func)_mesa_wrapped_VertexAttribP4_bgra8_unorm,
772    },
773    {0}, /* unused (2) */
774    { /* GL_INT_2_10_10_10_REV */
775       (attrib_func)_mesa_wrapped_VertexAttribP4_bgr10a2_sscaled,
776       (attrib_func)_mesa_wrapped_VertexAttribP4_bgr10a2_snorm,
777    }
778 };
779 
780 /*
781  * Return VertexAttrib*NV function pointer matching the provided vertex format.
782  */
783 static inline attrib_func
get_legacy_func(union gl_vertex_format_user format)784 get_legacy_func(union gl_vertex_format_user format)
785 {
786    if (format.Bgra)
787       return legacy_bgra_attrib_funcs[format.Type & 0x3][format.Normalized];
788 
789    int type = format.Type & 0x3f;
790 
791    assert(type < ARRAY_SIZE(legacy_rgba_attrib_funcs));
792    return legacy_rgba_attrib_funcs[type][format.Normalized][format.Size - 1];
793 }
794 
795 /*
796  * Return VertexAttrib*ARB function pointer matching the provided vertex format.
797  */
798 static inline attrib_func
get_generic_func(union gl_vertex_format_user format)799 get_generic_func(union gl_vertex_format_user format)
800 {
801    if (format.Bgra)
802       return generic_bgra_attrib_funcs[format.Type & 0x3][format.Normalized];
803 
804    int type = (format.Type & 0x3f) | ((int)format.Doubles << 5);
805    int mod = format.Integer * 2 + format.Normalized;
806 
807    assert(type < ARRAY_SIZE(generic_rgba_attrib_funcs));
808    return generic_rgba_attrib_funcs[type][mod][format.Size - 1];
809 }
810 
811 static inline const uint8_t *
attrib_addr(const struct glthread_vao * vao,const struct glthread_attrib * array)812 attrib_addr(const struct glthread_vao *vao,
813             const struct glthread_attrib *array)
814 {
815    return (const uint8_t*)vao->Attrib[array->BufferIndex].Pointer +
816           array->RelativeOffset;
817 }
818 
819 static inline unsigned
attrib_stride(const struct glthread_vao * vao,const struct glthread_attrib * array)820 attrib_stride(const struct glthread_vao *vao,
821               const struct glthread_attrib *array)
822 {
823    return vao->Attrib[array->BufferIndex].Stride;
824 }
825 
826 struct attrib_info {
827    attrib_func marshal; /* glVertex4fv, etc. */
828    const uint8_t *ptr;  /* vertex array pointer at the first vertex */
829    uint16_t stride;
830    uint8_t attrib;      /* VERT_ATTRIB_* */
831 };
832 
833 /**
834  * Convert glDrawElements into glBegin/End.
835  *
836  * We use this when we need to upload non-VBO vertices and the vertex range
837  * to upload is much greater than the draw vertex count, which would cause
838  * the upload to take too much time. We can get better performance if we
839  * read each vertex from user memory and push it through glBegin/End.
840  *
841  * This assumes: No buffer objects, no instancing, no primitive restart.
842  */
843 void
_mesa_glthread_UnrollDrawElements(struct gl_context * ctx,GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLint basevertex)844 _mesa_glthread_UnrollDrawElements(struct gl_context *ctx,
845                                   GLenum mode, GLsizei count, GLenum type,
846                                   const GLvoid *indices, GLint basevertex)
847 {
848    /* First gather all glVertex(Attrib) function pointers and attribute
849     * information, and then execute them between glBegin/End for every vertex.
850     */
851    const struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
852    struct attrib_info attribs[VERT_ATTRIB_MAX];
853    unsigned num_attribs = 0;
854 
855    /* Gather glColor, glTexCoord etc. functions for non-generic attributes. */
856    GLbitfield mask = (VERT_BIT_FF_ALL & ~VERT_BIT_POS) & vao->Enabled;
857    while (mask) {
858       const gl_vert_attrib attrib = u_bit_scan(&mask);
859       struct attrib_info *info = &attribs[num_attribs];
860       const struct glthread_attrib *attr = &vao->Attrib[attrib];
861 
862       info->marshal = get_legacy_func(attr->Format);
863       info->attrib = attrib;
864       info->ptr = attrib_addr(vao, attr);
865       info->stride = attrib_stride(vao, attr);
866       num_attribs++;
867    }
868 
869    /* Gather glVertexAttrib functions for generic attributes. */
870    mask = (VERT_BIT_GENERIC_ALL & ~VERT_BIT_GENERIC0) & vao->Enabled;
871    while (mask) {
872       const gl_vert_attrib attrib = u_bit_scan(&mask);
873       struct attrib_info *info = &attribs[num_attribs];
874       const struct glthread_attrib *attr = &vao->Attrib[attrib];
875 
876       info->marshal = get_generic_func(attr->Format);
877       info->attrib = attrib - VERT_ATTRIB_GENERIC0;
878       info->ptr = attrib_addr(vao, attr);
879       info->stride = attrib_stride(vao, attr);
880       num_attribs++;
881    }
882 
883    /* Finally, vertex position. */
884    if (vao->Enabled & VERT_BIT_GENERIC0) {
885       struct attrib_info *info = &attribs[num_attribs];
886       const struct glthread_attrib *attr =
887             &vao->Attrib[VERT_ATTRIB_GENERIC0];
888 
889       info->marshal = get_generic_func(attr->Format);
890       info->attrib = 0;
891       info->ptr = attrib_addr(vao, attr);
892       info->stride = attrib_stride(vao, attr);
893       num_attribs++;
894    } else if (vao->Enabled & VERT_BIT_POS) {
895       struct attrib_info *info = &attribs[num_attribs];
896       const struct glthread_attrib *attr =
897             &vao->Attrib[VERT_ATTRIB_POS];
898 
899       info->marshal = get_legacy_func(attr->Format);
900       info->attrib = VERT_ATTRIB_POS;
901       info->ptr = attrib_addr(vao, attr);
902       info->stride = attrib_stride(vao, attr);
903       num_attribs++;
904    }
905 
906    /* Convert the draw into glBegin/End. */
907    _mesa_marshal_Begin(mode);
908 
909    switch (type) {
910    case GL_UNSIGNED_BYTE: {
911       const uint8_t *ub = indices;
912       for (int i = 0; i < count; i++) {
913          for (unsigned a = 0; a < num_attribs; a++) {
914             struct attrib_info *info = &attribs[a];
915             unsigned index = ub[i] + basevertex;
916 
917             info->marshal(info->attrib, info->ptr + info->stride * index);
918          }
919       }
920       break;
921    }
922    case GL_UNSIGNED_SHORT: {
923       const uint16_t *us = indices;
924       for (int i = 0; i < count; i++) {
925          for (unsigned a = 0; a < num_attribs; a++) {
926             struct attrib_info *info = &attribs[a];
927             unsigned index = us[i] + basevertex;
928 
929             info->marshal(info->attrib, info->ptr + info->stride * index);
930          }
931       }
932       break;
933    }
934    case GL_UNSIGNED_INT: {
935       const uint32_t *ui = indices;
936       for (int i = 0; i < count; i++) {
937          for (unsigned a = 0; a < num_attribs; a++) {
938             struct attrib_info *info = &attribs[a];
939             unsigned index = ui[i] + basevertex;
940 
941             info->marshal(info->attrib, info->ptr + info->stride * index);
942          }
943       }
944       break;
945    }
946    }
947 
948    _mesa_marshal_End();
949 }
950