fb4ac4d05de42e4d095c1cc019c8f79bfc475ef9
[mesa.git] / src / glx / indirect_vertex_array.c
1 /*
2 * (C) Copyright IBM Corporation 2004, 2005
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * IBM,
20 * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #include <inttypes.h>
27 #include <assert.h>
28 #include <string.h>
29
30 #include "glxclient.h"
31 #include "indirect.h"
32 #include <GL/glxproto.h>
33 #include "glxextensions.h"
34 #include "indirect_vertex_array.h"
35 #include "indirect_vertex_array_priv.h"
36
37 #define __GLX_PAD(n) (((n)+3) & ~3)
38
39 /**
40 * \file indirect_vertex_array.c
41 * Implement GLX protocol for vertex arrays and vertex buffer objects.
42 *
43 * The most important function in this fill is \c fill_array_info_cache.
44 * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
45 * in the DrawArrays protocol. Certain operations, such as enabling or
46 * disabling an array, can invalidate this cache. \c fill_array_info_cache
47 * fills-in this data. Additionally, it examines the enabled state and
48 * other factors to determine what "version" of DrawArrays protocoal can be
49 * used.
50 *
51 * Current, only two versions of DrawArrays protocol are implemented. The
52 * first version is the "none" protocol. This is the fallback when the
53 * server does not support GL 1.1 / EXT_vertex_arrays. It is implemented
54 * by sending batches of immediate mode commands that are equivalent to the
55 * DrawArrays protocol.
56 *
57 * The other protocol that is currently implemented is the "old" protocol.
58 * This is the GL 1.1 DrawArrays protocol. The only difference between GL
59 * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
60 * This protocol is called "old" because the ARB is in the process of
61 * defining a new protocol, which will probably be called wither "new" or
62 * "vbo", to support multiple texture coordinate arrays, generic attributes,
63 * and vertex buffer objects.
64 *
65 * \author Ian Romanick <ian.d.romanick@intel.com>
66 */
67
68 static void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count);
69 static void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count);
70
71 static void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
72 const GLvoid * indices);
73 static void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
74 const GLvoid * indices);
75
76
77 static GLubyte *emit_element_none(GLubyte * dst,
78 const struct array_state_vector *arrays,
79 unsigned index);
80 static GLubyte *emit_element_old(GLubyte * dst,
81 const struct array_state_vector *arrays,
82 unsigned index);
83 static struct array_state *get_array_entry(const struct array_state_vector
84 *arrays, GLenum key,
85 unsigned index);
86 static void fill_array_info_cache(struct array_state_vector *arrays);
87 static GLboolean validate_mode(struct glx_context * gc, GLenum mode);
88 static GLboolean validate_count(struct glx_context * gc, GLsizei count);
89 static GLboolean validate_type(struct glx_context * gc, GLenum type);
90
91
92 /**
93 * Table of sizes, in bytes, of a GL types. All of the type enums are be in
94 * the range 0x1400 - 0x140F. That includes types added by extensions (i.e.,
95 * \c GL_HALF_FLOAT_NV). This elements of this table correspond to the
96 * type enums masked with 0x0f.
97 *
98 * \notes
99 * \c GL_HALF_FLOAT_NV is not included. Neither are \c GL_2_BYTES,
100 * \c GL_3_BYTES, or \c GL_4_BYTES.
101 */
102 const GLuint __glXTypeSize_table[16] = {
103 1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
104 };
105
106
107 /**
108 * Free the per-context array state that was allocated with
109 * __glXInitVertexArrayState().
110 */
111 void
112 __glXFreeVertexArrayState(struct glx_context * gc)
113 {
114 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
115 struct array_state_vector *arrays = state->array_state;
116
117 if (arrays) {
118 free(arrays->stack);
119 arrays->stack = NULL;
120 free(arrays->arrays);
121 arrays->arrays = NULL;
122 free(arrays);
123 state->array_state = NULL;
124 }
125 }
126
127
128 /**
129 * Initialize vertex array state of a GLX context.
130 *
131 * \param gc GLX context whose vertex array state is to be initialized.
132 *
133 * \warning
134 * This function may only be called after struct glx_context::gl_extension_bits,
135 * struct glx_context::server_minor, and __GLXcontext::server_major have been
136 * initialized. These values are used to determine what vertex arrays are
137 * supported.
138 */
139 void
140 __glXInitVertexArrayState(struct glx_context * gc)
141 {
142 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
143 struct array_state_vector *arrays;
144
145 unsigned array_count;
146 int texture_units = 1, vertex_program_attribs = 0;
147 unsigned i, j;
148
149 GLboolean got_fog = GL_FALSE;
150 GLboolean got_secondary_color = GL_FALSE;
151
152
153 arrays = calloc(1, sizeof(struct array_state_vector));
154 state->array_state = arrays;
155
156 if (arrays == NULL) {
157 __glXSetError(gc, GL_OUT_OF_MEMORY);
158 return;
159 }
160
161 arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
162 arrays->new_DrawArrays_possible = GL_FALSE;
163 arrays->DrawArrays = NULL;
164
165 arrays->active_texture_unit = 0;
166
167
168 /* Determine how many arrays are actually needed. Only arrays that
169 * are supported by the server are create. For example, if the server
170 * supports only 2 texture units, then only 2 texture coordinate arrays
171 * are created.
172 *
173 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
174 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
175 * GL_EDGE_FLAG_ARRAY are supported.
176 */
177
178 array_count = 5;
179
180 if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit)
181 || (gc->server_major > 1) || (gc->server_minor >= 4)) {
182 got_fog = GL_TRUE;
183 array_count++;
184 }
185
186 if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit)
187 || (gc->server_major > 1) || (gc->server_minor >= 4)) {
188 got_secondary_color = GL_TRUE;
189 array_count++;
190 }
191
192 if (__glExtensionBitIsEnabled(gc, GL_ARB_multitexture_bit)
193 || (gc->server_major > 1) || (gc->server_minor >= 3)) {
194 __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units);
195 }
196
197 if (__glExtensionBitIsEnabled(gc, GL_ARB_vertex_program_bit)) {
198 __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB,
199 GL_MAX_PROGRAM_ATTRIBS_ARB,
200 &vertex_program_attribs);
201 }
202
203 arrays->num_texture_units = texture_units;
204 arrays->num_vertex_program_attribs = vertex_program_attribs;
205 array_count += texture_units + vertex_program_attribs;
206 arrays->num_arrays = array_count;
207 arrays->arrays = calloc(array_count, sizeof(struct array_state));
208
209 if (arrays->arrays == NULL) {
210 state->array_state = NULL;
211 free(arrays);
212 __glXSetError(gc, GL_OUT_OF_MEMORY);
213 return;
214 }
215
216 arrays->arrays[0].data_type = GL_FLOAT;
217 arrays->arrays[0].count = 3;
218 arrays->arrays[0].key = GL_NORMAL_ARRAY;
219 arrays->arrays[0].normalized = GL_TRUE;
220 arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
221
222 arrays->arrays[1].data_type = GL_FLOAT;
223 arrays->arrays[1].count = 4;
224 arrays->arrays[1].key = GL_COLOR_ARRAY;
225 arrays->arrays[1].normalized = GL_TRUE;
226 arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
227
228 arrays->arrays[2].data_type = GL_FLOAT;
229 arrays->arrays[2].count = 1;
230 arrays->arrays[2].key = GL_INDEX_ARRAY;
231 arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
232
233 arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
234 arrays->arrays[3].count = 1;
235 arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
236 arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
237
238 for (i = 0; i < texture_units; i++) {
239 arrays->arrays[4 + i].data_type = GL_FLOAT;
240 arrays->arrays[4 + i].count = 4;
241 arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
242
243 arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
244 arrays->arrays[4 + i].index = i;
245 }
246
247 i = 4 + texture_units;
248
249 if (got_fog) {
250 arrays->arrays[i].data_type = GL_FLOAT;
251 arrays->arrays[i].count = 1;
252 arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
253 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
254 i++;
255 }
256
257 if (got_secondary_color) {
258 arrays->arrays[i].data_type = GL_FLOAT;
259 arrays->arrays[i].count = 3;
260 arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
261 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
262 arrays->arrays[i].normalized = GL_TRUE;
263 i++;
264 }
265
266
267 for (j = 0; j < vertex_program_attribs; j++) {
268 const unsigned idx = (vertex_program_attribs - (j + 1));
269
270
271 arrays->arrays[idx + i].data_type = GL_FLOAT;
272 arrays->arrays[idx + i].count = 4;
273 arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER;
274
275 arrays->arrays[idx + i].old_DrawArrays_possible = 0;
276 arrays->arrays[idx + i].index = idx;
277 }
278
279 i += vertex_program_attribs;
280
281
282 /* Vertex array *must* be last because of the way that
283 * emit_DrawArrays_none works.
284 */
285
286 arrays->arrays[i].data_type = GL_FLOAT;
287 arrays->arrays[i].count = 4;
288 arrays->arrays[i].key = GL_VERTEX_ARRAY;
289 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
290
291 assert((i + 1) == arrays->num_arrays);
292
293 arrays->stack_index = 0;
294 arrays->stack = malloc(sizeof(struct array_stack_state)
295 * arrays->num_arrays
296 * __GL_CLIENT_ATTRIB_STACK_DEPTH);
297
298 if (arrays->stack == NULL) {
299 state->array_state = NULL;
300 free(arrays->arrays);
301 free(arrays);
302 __glXSetError(gc, GL_OUT_OF_MEMORY);
303 return;
304 }
305 }
306
307
308 /**
309 * Calculate the size of a single vertex for the "none" protocol. This is
310 * essentially the size of all the immediate-mode commands required to
311 * implement the enabled vertex arrays.
312 */
313 static size_t
314 calculate_single_vertex_size_none(const struct array_state_vector *arrays)
315 {
316 size_t single_vertex_size = 0;
317 unsigned i;
318
319
320 for (i = 0; i < arrays->num_arrays; i++) {
321 if (arrays->arrays[i].enabled) {
322 single_vertex_size += arrays->arrays[i].header[0];
323 }
324 }
325
326 return single_vertex_size;
327 }
328
329
330 /**
331 * Emit a single element using non-DrawArrays protocol.
332 */
333 GLubyte *
334 emit_element_none(GLubyte * dst,
335 const struct array_state_vector * arrays, unsigned index)
336 {
337 unsigned i;
338
339
340 for (i = 0; i < arrays->num_arrays; i++) {
341 if (arrays->arrays[i].enabled) {
342 const size_t offset = index * arrays->arrays[i].true_stride;
343
344 /* The generic attributes can have more data than is in the
345 * elements. This is because a vertex array can be a 2 element,
346 * normalized, unsigned short, but the "closest" immediate mode
347 * protocol is for a 4Nus. Since the sizes are small, the
348 * performance impact on modern processors should be negligible.
349 */
350 (void) memset(dst, 0, arrays->arrays[i].header[0]);
351
352 (void) memcpy(dst, arrays->arrays[i].header, 4);
353
354 dst += 4;
355
356 if (arrays->arrays[i].key == GL_TEXTURE_COORD_ARRAY &&
357 arrays->arrays[i].index > 0) {
358 /* Multi-texture coordinate arrays require the texture target
359 * to be sent. For doubles it is after the data, for everything
360 * else it is before.
361 */
362 GLenum texture = arrays->arrays[i].index + GL_TEXTURE0;
363 if (arrays->arrays[i].data_type == GL_DOUBLE) {
364 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
365 arrays->arrays[i].element_size);
366 dst += arrays->arrays[i].element_size;
367 (void) memcpy(dst, &texture, 4);
368 dst += 4;
369 } else {
370 (void) memcpy(dst, &texture, 4);
371 dst += 4;
372 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
373 arrays->arrays[i].element_size);
374 dst += __GLX_PAD(arrays->arrays[i].element_size);
375 }
376 } else if (arrays->arrays[i].key == GL_VERTEX_ATTRIB_ARRAY_POINTER) {
377 /* Vertex attribute data requires the index sent first.
378 */
379 (void) memcpy(dst, &arrays->arrays[i].index, 4);
380 dst += 4;
381 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
382 arrays->arrays[i].element_size);
383 dst += __GLX_PAD(arrays->arrays[i].element_size);
384 } else {
385 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
386 arrays->arrays[i].element_size);
387 dst += __GLX_PAD(arrays->arrays[i].element_size);
388 }
389 }
390 }
391
392 return dst;
393 }
394
395
396 /**
397 * Emit a single element using "old" DrawArrays protocol from
398 * EXT_vertex_arrays / OpenGL 1.1.
399 */
400 GLubyte *
401 emit_element_old(GLubyte * dst,
402 const struct array_state_vector * arrays, unsigned index)
403 {
404 unsigned i;
405
406
407 for (i = 0; i < arrays->num_arrays; i++) {
408 if (arrays->arrays[i].enabled) {
409 const size_t offset = index * arrays->arrays[i].true_stride;
410
411 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
412 arrays->arrays[i].element_size);
413
414 dst += __GLX_PAD(arrays->arrays[i].element_size);
415 }
416 }
417
418 return dst;
419 }
420
421
422 struct array_state *
423 get_array_entry(const struct array_state_vector *arrays,
424 GLenum key, unsigned index)
425 {
426 unsigned i;
427
428 for (i = 0; i < arrays->num_arrays; i++) {
429 if ((arrays->arrays[i].key == key)
430 && (arrays->arrays[i].index == index)) {
431 return &arrays->arrays[i];
432 }
433 }
434
435 return NULL;
436 }
437
438
439 static GLboolean
440 allocate_array_info_cache(struct array_state_vector *arrays,
441 size_t required_size)
442 {
443 #define MAX_HEADER_SIZE 20
444 if (arrays->array_info_cache_buffer_size < required_size) {
445 GLubyte *temp = realloc(arrays->array_info_cache_base,
446 required_size + MAX_HEADER_SIZE);
447
448 if (temp == NULL) {
449 return GL_FALSE;
450 }
451
452 arrays->array_info_cache_base = temp;
453 arrays->array_info_cache = temp + MAX_HEADER_SIZE;
454 arrays->array_info_cache_buffer_size = required_size;
455 }
456
457 arrays->array_info_cache_size = required_size;
458 return GL_TRUE;
459 }
460
461
462 /**
463 */
464 void
465 fill_array_info_cache(struct array_state_vector *arrays)
466 {
467 GLboolean old_DrawArrays_possible;
468 unsigned i;
469
470
471 /* Determine how many arrays are enabled.
472 */
473
474 arrays->enabled_client_array_count = 0;
475 old_DrawArrays_possible = arrays->old_DrawArrays_possible;
476 for (i = 0; i < arrays->num_arrays; i++) {
477 if (arrays->arrays[i].enabled) {
478 arrays->enabled_client_array_count++;
479 old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
480 }
481 }
482
483 if (arrays->new_DrawArrays_possible) {
484 assert(!arrays->new_DrawArrays_possible);
485 }
486 else if (old_DrawArrays_possible) {
487 const size_t required_size = arrays->enabled_client_array_count * 12;
488 uint32_t *info;
489
490
491 if (!allocate_array_info_cache(arrays, required_size)) {
492 return;
493 }
494
495
496 info = (uint32_t *) arrays->array_info_cache;
497 for (i = 0; i < arrays->num_arrays; i++) {
498 if (arrays->arrays[i].enabled) {
499 *(info++) = arrays->arrays[i].data_type;
500 *(info++) = arrays->arrays[i].count;
501 *(info++) = arrays->arrays[i].key;
502 }
503 }
504
505 arrays->DrawArrays = emit_DrawArrays_old;
506 arrays->DrawElements = emit_DrawElements_old;
507 }
508 else {
509 arrays->DrawArrays = emit_DrawArrays_none;
510 arrays->DrawElements = emit_DrawElements_none;
511 }
512
513 arrays->array_info_cache_valid = GL_TRUE;
514 }
515
516
517 /**
518 * Emit a \c glDrawArrays command using the "none" protocol. That is,
519 * emit immediate-mode commands that are equivalent to the requiested
520 * \c glDrawArrays command. This is used with servers that don't support
521 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
522 * vertex state is enabled that is not compatible with that protocol.
523 */
524 void
525 emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
526 {
527 struct glx_context *gc = __glXGetCurrentContext();
528 const __GLXattribute *state =
529 (const __GLXattribute *) (gc->client_state_private);
530 struct array_state_vector *arrays = state->array_state;
531
532 size_t single_vertex_size;
533 GLubyte *pc;
534 unsigned i;
535 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
536 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
537
538
539 single_vertex_size = calculate_single_vertex_size_none(arrays);
540
541 pc = gc->pc;
542
543 (void) memcpy(pc, begin_cmd, 4);
544 *(int *) (pc + 4) = mode;
545
546 pc += 8;
547
548 for (i = 0; i < count; i++) {
549 if ((pc + single_vertex_size) >= gc->bufEnd) {
550 pc = __glXFlushRenderBuffer(gc, pc);
551 }
552
553 pc = emit_element_none(pc, arrays, first + i);
554 }
555
556 if ((pc + 4) >= gc->bufEnd) {
557 pc = __glXFlushRenderBuffer(gc, pc);
558 }
559
560 (void) memcpy(pc, end_cmd, 4);
561 pc += 4;
562
563 gc->pc = pc;
564 if (gc->pc > gc->limit) {
565 (void) __glXFlushRenderBuffer(gc, gc->pc);
566 }
567 }
568
569
570 /**
571 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
572 * protocol.
573 *
574 * \param gc GLX context.
575 * \param arrays Array state.
576 * \param elements_per_request Location to store the number of elements that
577 * can fit in a single Render / RenderLarge
578 * command.
579 * \param total_request Total number of requests for a RenderLarge
580 * command. If a Render command is used, this
581 * will be zero.
582 * \param mode Drawing mode.
583 * \param count Number of vertices.
584 *
585 * \returns
586 * A pointer to the buffer for array data.
587 */
588 static GLubyte *
589 emit_DrawArrays_header_old(struct glx_context * gc,
590 struct array_state_vector *arrays,
591 size_t * elements_per_request,
592 unsigned int *total_requests,
593 GLenum mode, GLsizei count)
594 {
595 size_t command_size;
596 size_t single_vertex_size;
597 const unsigned header_size = 16;
598 unsigned i;
599 GLubyte *pc;
600
601
602 /* Determine the size of the whole command. This includes the header,
603 * the ARRAY_INFO data and the array data. Once this size is calculated,
604 * it will be known whether a Render or RenderLarge command is needed.
605 */
606
607 single_vertex_size = 0;
608 for (i = 0; i < arrays->num_arrays; i++) {
609 if (arrays->arrays[i].enabled) {
610 single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size);
611 }
612 }
613
614 command_size = arrays->array_info_cache_size + header_size
615 + (single_vertex_size * count);
616
617
618 /* Write the header for either a Render command or a RenderLarge
619 * command. After the header is written, write the ARRAY_INFO data.
620 */
621
622 if (command_size > gc->maxSmallRenderCommandSize) {
623 /* maxSize is the maximum amount of data can be stuffed into a single
624 * packet. sz_xGLXRenderReq is added because bufSize is the maximum
625 * packet size minus sz_xGLXRenderReq.
626 */
627 const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
628 - sz_xGLXRenderLargeReq;
629 unsigned vertex_requests;
630
631
632 /* Calculate the number of data packets that will be required to send
633 * the whole command. To do this, the number of verticies that
634 * will fit in a single buffer must be calculated.
635 *
636 * The important value here is elements_per_request. This is the
637 * number of complete array elements that will fit in a single
638 * buffer. There may be some wasted space at the end of the buffer,
639 * but splitting elements across buffer boundries would be painful.
640 */
641
642 elements_per_request[0] = maxSize / single_vertex_size;
643
644 vertex_requests = (count + elements_per_request[0] - 1)
645 / elements_per_request[0];
646
647 *total_requests = vertex_requests + 1;
648
649
650 __glXFlushRenderBuffer(gc, gc->pc);
651
652 command_size += 4;
653
654 pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);
655 *(uint32_t *) (pc + 0) = command_size;
656 *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays;
657 *(uint32_t *) (pc + 8) = count;
658 *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count;
659 *(uint32_t *) (pc + 16) = mode;
660
661 __glXSendLargeChunk(gc, 1, *total_requests, pc,
662 header_size + 4 + arrays->array_info_cache_size);
663
664 pc = gc->pc;
665 }
666 else {
667 if ((gc->pc + command_size) >= gc->bufEnd) {
668 (void) __glXFlushRenderBuffer(gc, gc->pc);
669 }
670
671 pc = gc->pc;
672 *(uint16_t *) (pc + 0) = command_size;
673 *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays;
674 *(uint32_t *) (pc + 4) = count;
675 *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count;
676 *(uint32_t *) (pc + 12) = mode;
677
678 pc += header_size;
679
680 (void) memcpy(pc, arrays->array_info_cache,
681 arrays->array_info_cache_size);
682 pc += arrays->array_info_cache_size;
683
684 *elements_per_request = count;
685 *total_requests = 0;
686 }
687
688
689 return pc;
690 }
691
692
693 /**
694 */
695 void
696 emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count)
697 {
698 struct glx_context *gc = __glXGetCurrentContext();
699 const __GLXattribute *state =
700 (const __GLXattribute *) (gc->client_state_private);
701 struct array_state_vector *arrays = state->array_state;
702
703 GLubyte *pc;
704 size_t elements_per_request;
705 unsigned total_requests = 0;
706 unsigned i;
707 size_t total_sent = 0;
708
709
710 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
711 &total_requests, mode, count);
712
713
714 /* Write the arrays.
715 */
716
717 if (total_requests == 0) {
718 assert(elements_per_request >= count);
719
720 for (i = 0; i < count; i++) {
721 pc = emit_element_old(pc, arrays, i + first);
722 }
723
724 assert(pc <= gc->bufEnd);
725
726 gc->pc = pc;
727 if (gc->pc > gc->limit) {
728 (void) __glXFlushRenderBuffer(gc, gc->pc);
729 }
730 }
731 else {
732 unsigned req;
733
734
735 for (req = 2; req <= total_requests; req++) {
736 if (count < elements_per_request) {
737 elements_per_request = count;
738 }
739
740 pc = gc->pc;
741 for (i = 0; i < elements_per_request; i++) {
742 pc = emit_element_old(pc, arrays, i + first);
743 }
744
745 first += elements_per_request;
746
747 total_sent += (size_t) (pc - gc->pc);
748 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
749
750 count -= elements_per_request;
751 }
752 }
753 }
754
755
756 void
757 emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
758 const GLvoid * indices)
759 {
760 struct glx_context *gc = __glXGetCurrentContext();
761 const __GLXattribute *state =
762 (const __GLXattribute *) (gc->client_state_private);
763 struct array_state_vector *arrays = state->array_state;
764 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
765 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
766
767 GLubyte *pc;
768 size_t single_vertex_size;
769 unsigned i;
770
771
772 single_vertex_size = calculate_single_vertex_size_none(arrays);
773
774
775 if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
776 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
777 }
778
779 pc = gc->pc;
780
781 (void) memcpy(pc, begin_cmd, 4);
782 *(int *) (pc + 4) = mode;
783
784 pc += 8;
785
786 for (i = 0; i < count; i++) {
787 unsigned index = 0;
788
789 if ((pc + single_vertex_size) >= gc->bufEnd) {
790 pc = __glXFlushRenderBuffer(gc, pc);
791 }
792
793 switch (type) {
794 case GL_UNSIGNED_INT:
795 index = (unsigned) (((GLuint *) indices)[i]);
796 break;
797 case GL_UNSIGNED_SHORT:
798 index = (unsigned) (((GLushort *) indices)[i]);
799 break;
800 case GL_UNSIGNED_BYTE:
801 index = (unsigned) (((GLubyte *) indices)[i]);
802 break;
803 }
804 pc = emit_element_none(pc, arrays, index);
805 }
806
807 if ((pc + 4) >= gc->bufEnd) {
808 pc = __glXFlushRenderBuffer(gc, pc);
809 }
810
811 (void) memcpy(pc, end_cmd, 4);
812 pc += 4;
813
814 gc->pc = pc;
815 if (gc->pc > gc->limit) {
816 (void) __glXFlushRenderBuffer(gc, gc->pc);
817 }
818 }
819
820
821 /**
822 */
823 void
824 emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
825 const GLvoid * indices)
826 {
827 struct glx_context *gc = __glXGetCurrentContext();
828 const __GLXattribute *state =
829 (const __GLXattribute *) (gc->client_state_private);
830 struct array_state_vector *arrays = state->array_state;
831
832 GLubyte *pc;
833 size_t elements_per_request;
834 unsigned total_requests = 0;
835 unsigned i;
836 unsigned req;
837 unsigned req_element = 0;
838
839
840 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
841 &total_requests, mode, count);
842
843
844 /* Write the arrays.
845 */
846
847 req = 2;
848 while (count > 0) {
849 if (count < elements_per_request) {
850 elements_per_request = count;
851 }
852
853 switch (type) {
854 case GL_UNSIGNED_INT:{
855 const GLuint *ui_ptr = (const GLuint *) indices + req_element;
856
857 for (i = 0; i < elements_per_request; i++) {
858 const GLint index = (GLint) * (ui_ptr++);
859 pc = emit_element_old(pc, arrays, index);
860 }
861 break;
862 }
863 case GL_UNSIGNED_SHORT:{
864 const GLushort *us_ptr = (const GLushort *) indices + req_element;
865
866 for (i = 0; i < elements_per_request; i++) {
867 const GLint index = (GLint) * (us_ptr++);
868 pc = emit_element_old(pc, arrays, index);
869 }
870 break;
871 }
872 case GL_UNSIGNED_BYTE:{
873 const GLubyte *ub_ptr = (const GLubyte *) indices + req_element;
874
875 for (i = 0; i < elements_per_request; i++) {
876 const GLint index = (GLint) * (ub_ptr++);
877 pc = emit_element_old(pc, arrays, index);
878 }
879 break;
880 }
881 }
882
883 if (total_requests != 0) {
884 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
885 pc = gc->pc;
886 req++;
887 }
888
889 count -= elements_per_request;
890 req_element += elements_per_request;
891 }
892
893
894 assert((total_requests == 0) || ((req - 1) == total_requests));
895
896 if (total_requests == 0) {
897 assert(pc <= gc->bufEnd);
898
899 gc->pc = pc;
900 if (gc->pc > gc->limit) {
901 (void) __glXFlushRenderBuffer(gc, gc->pc);
902 }
903 }
904 }
905
906
907 /**
908 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
909 * If it is not valid, then an error code is set in the GLX context.
910 *
911 * \returns
912 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
913 */
914 static GLboolean
915 validate_mode(struct glx_context * gc, GLenum mode)
916 {
917 switch (mode) {
918 case GL_POINTS:
919 case GL_LINE_STRIP:
920 case GL_LINE_LOOP:
921 case GL_LINES:
922 case GL_TRIANGLE_STRIP:
923 case GL_TRIANGLE_FAN:
924 case GL_TRIANGLES:
925 case GL_QUAD_STRIP:
926 case GL_QUADS:
927 case GL_POLYGON:
928 break;
929 default:
930 __glXSetError(gc, GL_INVALID_ENUM);
931 return GL_FALSE;
932 }
933
934 return GL_TRUE;
935 }
936
937
938 /**
939 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
940 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
941 * being set. A value of zero will not result in an error being set, but
942 * will result in \c GL_FALSE being returned.
943 *
944 * \returns
945 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
946 */
947 static GLboolean
948 validate_count(struct glx_context * gc, GLsizei count)
949 {
950 if (count < 0) {
951 __glXSetError(gc, GL_INVALID_VALUE);
952 }
953
954 return (count > 0);
955 }
956
957
958 /**
959 * Validate that the \c type parameter to \c glDrawElements, et. al. is
960 * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
961 * \c GL_UNSIGNED_INT are valid.
962 *
963 * \returns
964 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
965 */
966 static GLboolean
967 validate_type(struct glx_context * gc, GLenum type)
968 {
969 switch (type) {
970 case GL_UNSIGNED_INT:
971 case GL_UNSIGNED_SHORT:
972 case GL_UNSIGNED_BYTE:
973 return GL_TRUE;
974 default:
975 __glXSetError(gc, GL_INVALID_ENUM);
976 return GL_FALSE;
977 }
978 }
979
980
981 void
982 __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
983 {
984 struct glx_context *gc = __glXGetCurrentContext();
985 const __GLXattribute *state =
986 (const __GLXattribute *) (gc->client_state_private);
987 struct array_state_vector *arrays = state->array_state;
988
989
990 if (validate_mode(gc, mode) && validate_count(gc, count)) {
991 if (!arrays->array_info_cache_valid) {
992 fill_array_info_cache(arrays);
993 }
994
995 arrays->DrawArrays(mode, first, count);
996 }
997 }
998
999
1000 void
1001 __indirect_glArrayElement(GLint index)
1002 {
1003 struct glx_context *gc = __glXGetCurrentContext();
1004 const __GLXattribute *state =
1005 (const __GLXattribute *) (gc->client_state_private);
1006 struct array_state_vector *arrays = state->array_state;
1007
1008 size_t single_vertex_size;
1009
1010
1011 single_vertex_size = calculate_single_vertex_size_none(arrays);
1012
1013 if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
1014 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
1015 }
1016
1017 gc->pc = emit_element_none(gc->pc, arrays, index);
1018
1019 if (gc->pc > gc->limit) {
1020 (void) __glXFlushRenderBuffer(gc, gc->pc);
1021 }
1022 }
1023
1024
1025 void
1026 __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
1027 const GLvoid * indices)
1028 {
1029 struct glx_context *gc = __glXGetCurrentContext();
1030 const __GLXattribute *state =
1031 (const __GLXattribute *) (gc->client_state_private);
1032 struct array_state_vector *arrays = state->array_state;
1033
1034
1035 if (validate_mode(gc, mode) && validate_count(gc, count)
1036 && validate_type(gc, type)) {
1037 if (!arrays->array_info_cache_valid) {
1038 fill_array_info_cache(arrays);
1039 }
1040
1041 arrays->DrawElements(mode, count, type, indices);
1042 }
1043 }
1044
1045
1046 void
1047 __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
1048 GLsizei count, GLenum type,
1049 const GLvoid * indices)
1050 {
1051 struct glx_context *gc = __glXGetCurrentContext();
1052 const __GLXattribute *state =
1053 (const __GLXattribute *) (gc->client_state_private);
1054 struct array_state_vector *arrays = state->array_state;
1055
1056
1057 if (validate_mode(gc, mode) && validate_count(gc, count)
1058 && validate_type(gc, type)) {
1059 if (end < start) {
1060 __glXSetError(gc, GL_INVALID_VALUE);
1061 return;
1062 }
1063
1064 if (!arrays->array_info_cache_valid) {
1065 fill_array_info_cache(arrays);
1066 }
1067
1068 arrays->DrawElements(mode, count, type, indices);
1069 }
1070 }
1071
1072
1073 void
1074 __indirect_glMultiDrawArrays(GLenum mode, const GLint *first,
1075 const GLsizei *count, GLsizei primcount)
1076 {
1077 struct glx_context *gc = __glXGetCurrentContext();
1078 const __GLXattribute *state =
1079 (const __GLXattribute *) (gc->client_state_private);
1080 struct array_state_vector *arrays = state->array_state;
1081 GLsizei i;
1082
1083
1084 if (validate_mode(gc, mode)) {
1085 if (!arrays->array_info_cache_valid) {
1086 fill_array_info_cache(arrays);
1087 }
1088
1089 for (i = 0; i < primcount; i++) {
1090 if (validate_count(gc, count[i])) {
1091 arrays->DrawArrays(mode, first[i], count[i]);
1092 }
1093 }
1094 }
1095 }
1096
1097
1098 void
1099 __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count,
1100 GLenum type, const GLvoid * const * indices,
1101 GLsizei primcount)
1102 {
1103 struct glx_context *gc = __glXGetCurrentContext();
1104 const __GLXattribute *state =
1105 (const __GLXattribute *) (gc->client_state_private);
1106 struct array_state_vector *arrays = state->array_state;
1107 GLsizei i;
1108
1109
1110 if (validate_mode(gc, mode) && validate_type(gc, type)) {
1111 if (!arrays->array_info_cache_valid) {
1112 fill_array_info_cache(arrays);
1113 }
1114
1115 for (i = 0; i < primcount; i++) {
1116 if (validate_count(gc, count[i])) {
1117 arrays->DrawElements(mode, count[i], type, indices[i]);
1118 }
1119 }
1120 }
1121 }
1122
1123
1124 /* The HDR_SIZE macro argument is the command header size (4 bytes)
1125 * plus any additional index word e.g. for texture units or vertex
1126 * attributes.
1127 */
1128 #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
1129 do { \
1130 (a)->data = PTR; \
1131 (a)->data_type = TYPE; \
1132 (a)->user_stride = STRIDE; \
1133 (a)->count = COUNT; \
1134 (a)->normalized = NORMALIZED; \
1135 \
1136 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1137 (a)->true_stride = (STRIDE == 0) \
1138 ? (a)->element_size : STRIDE; \
1139 \
1140 (a)->header[0] = __GLX_PAD(HDR_SIZE + (a)->element_size); \
1141 (a)->header[1] = OPCODE; \
1142 } while(0)
1143
1144
1145 void
1146 __indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride,
1147 const GLvoid * pointer)
1148 {
1149 static const uint16_t short_ops[5] = {
1150 0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1151 };
1152 static const uint16_t int_ops[5] = {
1153 0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1154 };
1155 static const uint16_t float_ops[5] = {
1156 0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1157 };
1158 static const uint16_t double_ops[5] = {
1159 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1160 };
1161 uint16_t opcode;
1162 struct glx_context *gc = __glXGetCurrentContext();
1163 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1164 struct array_state_vector *arrays = state->array_state;
1165 struct array_state *a;
1166
1167
1168 if (size < 2 || size > 4 || stride < 0) {
1169 __glXSetError(gc, GL_INVALID_VALUE);
1170 return;
1171 }
1172
1173 switch (type) {
1174 case GL_SHORT:
1175 opcode = short_ops[size];
1176 break;
1177 case GL_INT:
1178 opcode = int_ops[size];
1179 break;
1180 case GL_FLOAT:
1181 opcode = float_ops[size];
1182 break;
1183 case GL_DOUBLE:
1184 opcode = double_ops[size];
1185 break;
1186 default:
1187 __glXSetError(gc, GL_INVALID_ENUM);
1188 return;
1189 }
1190
1191 a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0);
1192 assert(a != NULL);
1193 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4,
1194 opcode);
1195
1196 if (a->enabled) {
1197 arrays->array_info_cache_valid = GL_FALSE;
1198 }
1199 }
1200
1201
1202 void
1203 __indirect_glNormalPointer(GLenum type, GLsizei stride,
1204 const GLvoid * pointer)
1205 {
1206 uint16_t opcode;
1207 struct glx_context *gc = __glXGetCurrentContext();
1208 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1209 struct array_state_vector *arrays = state->array_state;
1210 struct array_state *a;
1211
1212
1213 if (stride < 0) {
1214 __glXSetError(gc, GL_INVALID_VALUE);
1215 return;
1216 }
1217
1218 switch (type) {
1219 case GL_BYTE:
1220 opcode = X_GLrop_Normal3bv;
1221 break;
1222 case GL_SHORT:
1223 opcode = X_GLrop_Normal3sv;
1224 break;
1225 case GL_INT:
1226 opcode = X_GLrop_Normal3iv;
1227 break;
1228 case GL_FLOAT:
1229 opcode = X_GLrop_Normal3fv;
1230 break;
1231 case GL_DOUBLE:
1232 opcode = X_GLrop_Normal3dv;
1233 break;
1234 default:
1235 __glXSetError(gc, GL_INVALID_ENUM);
1236 return;
1237 }
1238
1239 a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0);
1240 assert(a != NULL);
1241 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode);
1242
1243 if (a->enabled) {
1244 arrays->array_info_cache_valid = GL_FALSE;
1245 }
1246 }
1247
1248
1249 void
1250 __indirect_glColorPointer(GLint size, GLenum type, GLsizei stride,
1251 const GLvoid * pointer)
1252 {
1253 static const uint16_t byte_ops[5] = {
1254 0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1255 };
1256 static const uint16_t ubyte_ops[5] = {
1257 0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1258 };
1259 static const uint16_t short_ops[5] = {
1260 0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1261 };
1262 static const uint16_t ushort_ops[5] = {
1263 0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1264 };
1265 static const uint16_t int_ops[5] = {
1266 0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1267 };
1268 static const uint16_t uint_ops[5] = {
1269 0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1270 };
1271 static const uint16_t float_ops[5] = {
1272 0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1273 };
1274 static const uint16_t double_ops[5] = {
1275 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1276 };
1277 uint16_t opcode;
1278 struct glx_context *gc = __glXGetCurrentContext();
1279 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1280 struct array_state_vector *arrays = state->array_state;
1281 struct array_state *a;
1282
1283
1284 if (size < 3 || size > 4 || stride < 0) {
1285 __glXSetError(gc, GL_INVALID_VALUE);
1286 return;
1287 }
1288
1289 switch (type) {
1290 case GL_BYTE:
1291 opcode = byte_ops[size];
1292 break;
1293 case GL_UNSIGNED_BYTE:
1294 opcode = ubyte_ops[size];
1295 break;
1296 case GL_SHORT:
1297 opcode = short_ops[size];
1298 break;
1299 case GL_UNSIGNED_SHORT:
1300 opcode = ushort_ops[size];
1301 break;
1302 case GL_INT:
1303 opcode = int_ops[size];
1304 break;
1305 case GL_UNSIGNED_INT:
1306 opcode = uint_ops[size];
1307 break;
1308 case GL_FLOAT:
1309 opcode = float_ops[size];
1310 break;
1311 case GL_DOUBLE:
1312 opcode = double_ops[size];
1313 break;
1314 default:
1315 __glXSetError(gc, GL_INVALID_ENUM);
1316 return;
1317 }
1318
1319 a = get_array_entry(arrays, GL_COLOR_ARRAY, 0);
1320 assert(a != NULL);
1321 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1322
1323 if (a->enabled) {
1324 arrays->array_info_cache_valid = GL_FALSE;
1325 }
1326 }
1327
1328
1329 void
1330 __indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer)
1331 {
1332 uint16_t opcode;
1333 struct glx_context *gc = __glXGetCurrentContext();
1334 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1335 struct array_state_vector *arrays = state->array_state;
1336 struct array_state *a;
1337
1338
1339 if (stride < 0) {
1340 __glXSetError(gc, GL_INVALID_VALUE);
1341 return;
1342 }
1343
1344 switch (type) {
1345 case GL_UNSIGNED_BYTE:
1346 opcode = X_GLrop_Indexubv;
1347 break;
1348 case GL_SHORT:
1349 opcode = X_GLrop_Indexsv;
1350 break;
1351 case GL_INT:
1352 opcode = X_GLrop_Indexiv;
1353 break;
1354 case GL_FLOAT:
1355 opcode = X_GLrop_Indexfv;
1356 break;
1357 case GL_DOUBLE:
1358 opcode = X_GLrop_Indexdv;
1359 break;
1360 default:
1361 __glXSetError(gc, GL_INVALID_ENUM);
1362 return;
1363 }
1364
1365 a = get_array_entry(arrays, GL_INDEX_ARRAY, 0);
1366 assert(a != NULL);
1367 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1368
1369 if (a->enabled) {
1370 arrays->array_info_cache_valid = GL_FALSE;
1371 }
1372 }
1373
1374
1375 void
1376 __indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer)
1377 {
1378 struct glx_context *gc = __glXGetCurrentContext();
1379 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1380 struct array_state_vector *arrays = state->array_state;
1381 struct array_state *a;
1382
1383
1384 if (stride < 0) {
1385 __glXSetError(gc, GL_INVALID_VALUE);
1386 return;
1387 }
1388
1389
1390 a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0);
1391 assert(a != NULL);
1392 COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE,
1393 4, X_GLrop_EdgeFlagv);
1394
1395 if (a->enabled) {
1396 arrays->array_info_cache_valid = GL_FALSE;
1397 }
1398 }
1399
1400
1401 void
1402 __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
1403 const GLvoid * pointer)
1404 {
1405 static const uint16_t short_ops[5] = {
1406 0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv,
1407 X_GLrop_TexCoord4sv
1408 };
1409 static const uint16_t int_ops[5] = {
1410 0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv,
1411 X_GLrop_TexCoord4iv
1412 };
1413 static const uint16_t float_ops[5] = {
1414 0, X_GLrop_TexCoord1fv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv,
1415 X_GLrop_TexCoord4fv
1416 };
1417 static const uint16_t double_ops[5] = {
1418 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv,
1419 X_GLrop_TexCoord4dv
1420 };
1421
1422 static const uint16_t mshort_ops[5] = {
1423 0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB,
1424 X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
1425 };
1426 static const uint16_t mint_ops[5] = {
1427 0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB,
1428 X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
1429 };
1430 static const uint16_t mfloat_ops[5] = {
1431 0, X_GLrop_MultiTexCoord1fvARB, X_GLrop_MultiTexCoord2fvARB,
1432 X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
1433 };
1434 static const uint16_t mdouble_ops[5] = {
1435 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB,
1436 X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
1437 };
1438
1439 uint16_t opcode;
1440 struct glx_context *gc = __glXGetCurrentContext();
1441 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1442 struct array_state_vector *arrays = state->array_state;
1443 struct array_state *a;
1444 unsigned header_size;
1445 unsigned index;
1446
1447
1448 if (size < 1 || size > 4 || stride < 0) {
1449 __glXSetError(gc, GL_INVALID_VALUE);
1450 return;
1451 }
1452
1453 index = arrays->active_texture_unit;
1454 if (index == 0) {
1455 switch (type) {
1456 case GL_SHORT:
1457 opcode = short_ops[size];
1458 break;
1459 case GL_INT:
1460 opcode = int_ops[size];
1461 break;
1462 case GL_FLOAT:
1463 opcode = float_ops[size];
1464 break;
1465 case GL_DOUBLE:
1466 opcode = double_ops[size];
1467 break;
1468 default:
1469 __glXSetError(gc, GL_INVALID_ENUM);
1470 return;
1471 }
1472
1473 header_size = 4;
1474 }
1475 else {
1476 switch (type) {
1477 case GL_SHORT:
1478 opcode = mshort_ops[size];
1479 break;
1480 case GL_INT:
1481 opcode = mint_ops[size];
1482 break;
1483 case GL_FLOAT:
1484 opcode = mfloat_ops[size];
1485 break;
1486 case GL_DOUBLE:
1487 opcode = mdouble_ops[size];
1488 break;
1489 default:
1490 __glXSetError(gc, GL_INVALID_ENUM);
1491 return;
1492 }
1493
1494 header_size = 8;
1495 }
1496
1497 a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index);
1498 assert(a != NULL);
1499 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE,
1500 header_size, opcode);
1501
1502 if (a->enabled) {
1503 arrays->array_info_cache_valid = GL_FALSE;
1504 }
1505 }
1506
1507
1508 void
1509 __indirect_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride,
1510 const GLvoid * pointer)
1511 {
1512 uint16_t opcode;
1513 struct glx_context *gc = __glXGetCurrentContext();
1514 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1515 struct array_state_vector *arrays = state->array_state;
1516 struct array_state *a;
1517
1518
1519 if (size != 3 || stride < 0) {
1520 __glXSetError(gc, GL_INVALID_VALUE);
1521 return;
1522 }
1523
1524 switch (type) {
1525 case GL_BYTE:
1526 opcode = 4126;
1527 break;
1528 case GL_UNSIGNED_BYTE:
1529 opcode = 4131;
1530 break;
1531 case GL_SHORT:
1532 opcode = 4127;
1533 break;
1534 case GL_UNSIGNED_SHORT:
1535 opcode = 4132;
1536 break;
1537 case GL_INT:
1538 opcode = 4128;
1539 break;
1540 case GL_UNSIGNED_INT:
1541 opcode = 4133;
1542 break;
1543 case GL_FLOAT:
1544 opcode = 4129;
1545 break;
1546 case GL_DOUBLE:
1547 opcode = 4130;
1548 break;
1549 default:
1550 __glXSetError(gc, GL_INVALID_ENUM);
1551 return;
1552 }
1553
1554 a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0);
1555 if (a == NULL) {
1556 __glXSetError(gc, GL_INVALID_OPERATION);
1557 return;
1558 }
1559
1560 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1561
1562 if (a->enabled) {
1563 arrays->array_info_cache_valid = GL_FALSE;
1564 }
1565 }
1566
1567
1568 void
1569 __indirect_glFogCoordPointer(GLenum type, GLsizei stride,
1570 const GLvoid * pointer)
1571 {
1572 uint16_t opcode;
1573 struct glx_context *gc = __glXGetCurrentContext();
1574 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1575 struct array_state_vector *arrays = state->array_state;
1576 struct array_state *a;
1577
1578
1579 if (stride < 0) {
1580 __glXSetError(gc, GL_INVALID_VALUE);
1581 return;
1582 }
1583
1584 switch (type) {
1585 case GL_FLOAT:
1586 opcode = 4124;
1587 break;
1588 case GL_DOUBLE:
1589 opcode = 4125;
1590 break;
1591 default:
1592 __glXSetError(gc, GL_INVALID_ENUM);
1593 return;
1594 }
1595
1596 a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0);
1597 if (a == NULL) {
1598 __glXSetError(gc, GL_INVALID_OPERATION);
1599 return;
1600 }
1601
1602 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1603
1604 if (a->enabled) {
1605 arrays->array_info_cache_valid = GL_FALSE;
1606 }
1607 }
1608
1609
1610 void
1611 __indirect_glVertexAttribPointer(GLuint index, GLint size,
1612 GLenum type, GLboolean normalized,
1613 GLsizei stride, const GLvoid * pointer)
1614 {
1615 static const uint16_t short_ops[5] = {
1616 0, X_GLrop_VertexAttrib1svARB, X_GLrop_VertexAttrib2svARB,
1617 X_GLrop_VertexAttrib3svARB, X_GLrop_VertexAttrib4svARB
1618 };
1619 static const uint16_t float_ops[5] = {
1620 0, X_GLrop_VertexAttrib1fvARB, X_GLrop_VertexAttrib2fvARB,
1621 X_GLrop_VertexAttrib3fvARB, X_GLrop_VertexAttrib4fvARB
1622 };
1623 static const uint16_t double_ops[5] = {
1624 0, X_GLrop_VertexAttrib1dvARB, X_GLrop_VertexAttrib2dvARB,
1625 X_GLrop_VertexAttrib3dvARB, X_GLrop_VertexAttrib4dvARB
1626 };
1627
1628 uint16_t opcode;
1629 struct glx_context *gc = __glXGetCurrentContext();
1630 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1631 struct array_state_vector *arrays = state->array_state;
1632 struct array_state *a;
1633 unsigned true_immediate_count;
1634 unsigned true_immediate_size;
1635
1636
1637 if ((size < 1) || (size > 4) || (stride < 0)
1638 || (index > arrays->num_vertex_program_attribs)) {
1639 __glXSetError(gc, GL_INVALID_VALUE);
1640 return;
1641 }
1642
1643 if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
1644 switch (type) {
1645 case GL_BYTE:
1646 opcode = X_GLrop_VertexAttrib4NbvARB;
1647 break;
1648 case GL_UNSIGNED_BYTE:
1649 opcode = X_GLrop_VertexAttrib4NubvARB;
1650 break;
1651 case GL_SHORT:
1652 opcode = X_GLrop_VertexAttrib4NsvARB;
1653 break;
1654 case GL_UNSIGNED_SHORT:
1655 opcode = X_GLrop_VertexAttrib4NusvARB;
1656 break;
1657 case GL_INT:
1658 opcode = X_GLrop_VertexAttrib4NivARB;
1659 break;
1660 case GL_UNSIGNED_INT:
1661 opcode = X_GLrop_VertexAttrib4NuivARB;
1662 break;
1663 default:
1664 __glXSetError(gc, GL_INVALID_ENUM);
1665 return;
1666 }
1667
1668 true_immediate_count = 4;
1669 }
1670 else {
1671 true_immediate_count = size;
1672
1673 switch (type) {
1674 case GL_BYTE:
1675 opcode = X_GLrop_VertexAttrib4bvARB;
1676 true_immediate_count = 4;
1677 break;
1678 case GL_UNSIGNED_BYTE:
1679 opcode = X_GLrop_VertexAttrib4ubvARB;
1680 true_immediate_count = 4;
1681 break;
1682 case GL_SHORT:
1683 opcode = short_ops[size];
1684 break;
1685 case GL_UNSIGNED_SHORT:
1686 opcode = X_GLrop_VertexAttrib4usvARB;
1687 true_immediate_count = 4;
1688 break;
1689 case GL_INT:
1690 opcode = X_GLrop_VertexAttrib4ivARB;
1691 true_immediate_count = 4;
1692 break;
1693 case GL_UNSIGNED_INT:
1694 opcode = X_GLrop_VertexAttrib4uivARB;
1695 true_immediate_count = 4;
1696 break;
1697 case GL_FLOAT:
1698 opcode = float_ops[size];
1699 break;
1700 case GL_DOUBLE:
1701 opcode = double_ops[size];
1702 break;
1703 default:
1704 __glXSetError(gc, GL_INVALID_ENUM);
1705 return;
1706 }
1707 }
1708
1709 a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index);
1710 if (a == NULL) {
1711 __glXSetError(gc, GL_INVALID_OPERATION);
1712 return;
1713 }
1714
1715 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8,
1716 opcode);
1717
1718 true_immediate_size = __glXTypeSize(type) * true_immediate_count;
1719 a->header[0] = __GLX_PAD(8 + true_immediate_size);
1720
1721 if (a->enabled) {
1722 arrays->array_info_cache_valid = GL_FALSE;
1723 }
1724 }
1725
1726
1727 /**
1728 * I don't have 100% confidence that this is correct. The different rules
1729 * about whether or not generic vertex attributes alias "classic" vertex
1730 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1731 * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My
1732 * feeling is that the client-side doesn't have to worry about it. The
1733 * client just sends all the data to the server and lets the server deal
1734 * with it.
1735 */
1736 void
1737 __indirect_glVertexAttribPointerNV(GLuint index, GLint size,
1738 GLenum type, GLsizei stride,
1739 const GLvoid * pointer)
1740 {
1741 struct glx_context *gc = __glXGetCurrentContext();
1742 GLboolean normalized = GL_FALSE;
1743
1744
1745 switch (type) {
1746 case GL_UNSIGNED_BYTE:
1747 if (size != 4) {
1748 __glXSetError(gc, GL_INVALID_VALUE);
1749 return;
1750 }
1751 normalized = GL_TRUE;
1752 /* fallthrough */
1753 case GL_SHORT:
1754 case GL_FLOAT:
1755 case GL_DOUBLE:
1756 __indirect_glVertexAttribPointer(index, size, type,
1757 normalized, stride, pointer);
1758 return;
1759 default:
1760 __glXSetError(gc, GL_INVALID_ENUM);
1761 return;
1762 }
1763 }
1764
1765
1766 void
1767 __indirect_glClientActiveTexture(GLenum texture)
1768 {
1769 struct glx_context *const gc = __glXGetCurrentContext();
1770 __GLXattribute *const state =
1771 (__GLXattribute *) (gc->client_state_private);
1772 struct array_state_vector *const arrays = state->array_state;
1773 const GLint unit = (GLint) texture - GL_TEXTURE0;
1774
1775
1776 if ((unit < 0) || (unit >= arrays->num_texture_units)) {
1777 __glXSetError(gc, GL_INVALID_ENUM);
1778 return;
1779 }
1780
1781 arrays->active_texture_unit = unit;
1782 }
1783
1784
1785 /**
1786 * Modify the enable state for the selected array
1787 */
1788 GLboolean
1789 __glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index,
1790 GLboolean enable)
1791 {
1792 struct array_state_vector *arrays = state->array_state;
1793 struct array_state *a;
1794
1795
1796 /* Texture coordinate arrays have an implict index set when the
1797 * application calls glClientActiveTexture.
1798 */
1799 if (key == GL_TEXTURE_COORD_ARRAY) {
1800 index = arrays->active_texture_unit;
1801 }
1802
1803 a = get_array_entry(arrays, key, index);
1804
1805 if ((a != NULL) && (a->enabled != enable)) {
1806 a->enabled = enable;
1807 arrays->array_info_cache_valid = GL_FALSE;
1808 }
1809
1810 return (a != NULL);
1811 }
1812
1813
1814 void
1815 __glXArrayDisableAll(__GLXattribute * state)
1816 {
1817 struct array_state_vector *arrays = state->array_state;
1818 unsigned i;
1819
1820
1821 for (i = 0; i < arrays->num_arrays; i++) {
1822 arrays->arrays[i].enabled = GL_FALSE;
1823 }
1824
1825 arrays->array_info_cache_valid = GL_FALSE;
1826 }
1827
1828
1829 /**
1830 */
1831 GLboolean
1832 __glXGetArrayEnable(const __GLXattribute * const state,
1833 GLenum key, unsigned index, GLintptr * dest)
1834 {
1835 const struct array_state_vector *arrays = state->array_state;
1836 const struct array_state *a =
1837 get_array_entry((struct array_state_vector *) arrays,
1838 key, index);
1839
1840 if (a != NULL) {
1841 *dest = (GLintptr) a->enabled;
1842 }
1843
1844 return (a != NULL);
1845 }
1846
1847
1848 /**
1849 */
1850 GLboolean
1851 __glXGetArrayType(const __GLXattribute * const state,
1852 GLenum key, unsigned index, GLintptr * dest)
1853 {
1854 const struct array_state_vector *arrays = state->array_state;
1855 const struct array_state *a =
1856 get_array_entry((struct array_state_vector *) arrays,
1857 key, index);
1858
1859 if (a != NULL) {
1860 *dest = (GLintptr) a->data_type;
1861 }
1862
1863 return (a != NULL);
1864 }
1865
1866
1867 /**
1868 */
1869 GLboolean
1870 __glXGetArraySize(const __GLXattribute * const state,
1871 GLenum key, unsigned index, GLintptr * dest)
1872 {
1873 const struct array_state_vector *arrays = state->array_state;
1874 const struct array_state *a =
1875 get_array_entry((struct array_state_vector *) arrays,
1876 key, index);
1877
1878 if (a != NULL) {
1879 *dest = (GLintptr) a->count;
1880 }
1881
1882 return (a != NULL);
1883 }
1884
1885
1886 /**
1887 */
1888 GLboolean
1889 __glXGetArrayStride(const __GLXattribute * const state,
1890 GLenum key, unsigned index, GLintptr * dest)
1891 {
1892 const struct array_state_vector *arrays = state->array_state;
1893 const struct array_state *a =
1894 get_array_entry((struct array_state_vector *) arrays,
1895 key, index);
1896
1897 if (a != NULL) {
1898 *dest = (GLintptr) a->user_stride;
1899 }
1900
1901 return (a != NULL);
1902 }
1903
1904
1905 /**
1906 */
1907 GLboolean
1908 __glXGetArrayPointer(const __GLXattribute * const state,
1909 GLenum key, unsigned index, void **dest)
1910 {
1911 const struct array_state_vector *arrays = state->array_state;
1912 const struct array_state *a =
1913 get_array_entry((struct array_state_vector *) arrays,
1914 key, index);
1915
1916
1917 if (a != NULL) {
1918 *dest = (void *) (a->data);
1919 }
1920
1921 return (a != NULL);
1922 }
1923
1924
1925 /**
1926 */
1927 GLboolean
1928 __glXGetArrayNormalized(const __GLXattribute * const state,
1929 GLenum key, unsigned index, GLintptr * dest)
1930 {
1931 const struct array_state_vector *arrays = state->array_state;
1932 const struct array_state *a =
1933 get_array_entry((struct array_state_vector *) arrays,
1934 key, index);
1935
1936
1937 if (a != NULL) {
1938 *dest = (GLintptr) a->normalized;
1939 }
1940
1941 return (a != NULL);
1942 }
1943
1944
1945 /**
1946 */
1947 GLuint
1948 __glXGetActiveTextureUnit(const __GLXattribute * const state)
1949 {
1950 return state->array_state->active_texture_unit;
1951 }
1952
1953
1954 void
1955 __glXPushArrayState(__GLXattribute * state)
1956 {
1957 struct array_state_vector *arrays = state->array_state;
1958 struct array_stack_state *stack =
1959 &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1960 unsigned i;
1961
1962 /* XXX are we pushing _all_ the necessary fields? */
1963 for (i = 0; i < arrays->num_arrays; i++) {
1964 stack[i].data = arrays->arrays[i].data;
1965 stack[i].data_type = arrays->arrays[i].data_type;
1966 stack[i].user_stride = arrays->arrays[i].user_stride;
1967 stack[i].count = arrays->arrays[i].count;
1968 stack[i].key = arrays->arrays[i].key;
1969 stack[i].index = arrays->arrays[i].index;
1970 stack[i].enabled = arrays->arrays[i].enabled;
1971 }
1972
1973 arrays->active_texture_unit_stack[arrays->stack_index] =
1974 arrays->active_texture_unit;
1975
1976 arrays->stack_index++;
1977 }
1978
1979
1980 void
1981 __glXPopArrayState(__GLXattribute * state)
1982 {
1983 struct array_state_vector *arrays = state->array_state;
1984 struct array_stack_state *stack;
1985 unsigned i;
1986
1987
1988 arrays->stack_index--;
1989 stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1990
1991 for (i = 0; i < arrays->num_arrays; i++) {
1992 switch (stack[i].key) {
1993 case GL_NORMAL_ARRAY:
1994 __indirect_glNormalPointer(stack[i].data_type,
1995 stack[i].user_stride, stack[i].data);
1996 break;
1997 case GL_COLOR_ARRAY:
1998 __indirect_glColorPointer(stack[i].count,
1999 stack[i].data_type,
2000 stack[i].user_stride, stack[i].data);
2001 break;
2002 case GL_INDEX_ARRAY:
2003 __indirect_glIndexPointer(stack[i].data_type,
2004 stack[i].user_stride, stack[i].data);
2005 break;
2006 case GL_EDGE_FLAG_ARRAY:
2007 __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data);
2008 break;
2009 case GL_TEXTURE_COORD_ARRAY:
2010 arrays->active_texture_unit = stack[i].index;
2011 __indirect_glTexCoordPointer(stack[i].count,
2012 stack[i].data_type,
2013 stack[i].user_stride, stack[i].data);
2014 break;
2015 case GL_SECONDARY_COLOR_ARRAY:
2016 __indirect_glSecondaryColorPointer(stack[i].count,
2017 stack[i].data_type,
2018 stack[i].user_stride,
2019 stack[i].data);
2020 break;
2021 case GL_FOG_COORDINATE_ARRAY:
2022 __indirect_glFogCoordPointer(stack[i].data_type,
2023 stack[i].user_stride, stack[i].data);
2024 break;
2025
2026 }
2027
2028 __glXSetArrayEnable(state, stack[i].key, stack[i].index,
2029 stack[i].enabled);
2030 }
2031
2032 arrays->active_texture_unit =
2033 arrays->active_texture_unit_stack[arrays->stack_index];
2034 }