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