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