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