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