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