diff options
Diffstat (limited to 'src/glx/x11/indirect_vertex_array.c')
-rw-r--r-- | src/glx/x11/indirect_vertex_array.c | 1985 |
1 files changed, 0 insertions, 1985 deletions
diff --git a/src/glx/x11/indirect_vertex_array.c b/src/glx/x11/indirect_vertex_array.c deleted file mode 100644 index ad9882528f..0000000000 --- a/src/glx/x11/indirect_vertex_array.c +++ /dev/null @@ -1,1985 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2004, 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * IBM, - * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include <inttypes.h> -#include <assert.h> -#include <string.h> - -#include "glxclient.h" -#include "indirect.h" -#include <GL/glxproto.h> -#include "glxextensions.h" -#include "indirect_vertex_array.h" -#include "indirect_vertex_array_priv.h" - -#define __GLX_PAD(n) (((n)+3) & ~3) - -/** - * \file indirect_vertex_array.c - * Implement GLX protocol for vertex arrays and vertex buffer objects. - * - * The most important function in this fill is \c fill_array_info_cache. - * The \c array_state_vector contains a cache of the ARRAY_INFO data sent - * in the DrawArrays protocol. Certain operations, such as enabling or - * disabling an array, can invalidate this cache. \c fill_array_info_cache - * fills-in this data. Additionally, it examines the enabled state and - * other factors to determine what "version" of DrawArrays protocoal can be - * used. - * - * Current, only two versions of DrawArrays protocol are implemented. The - * first version is the "none" protocol. This is the fallback when the - * server does not support GL 1.1 / EXT_vertex_arrays. It is implemented - * by sending batches of immediate mode commands that are equivalent to the - * DrawArrays protocol. - * - * The other protocol that is currently implemented is the "old" protocol. - * This is the GL 1.1 DrawArrays protocol. The only difference between GL - * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command. - * This protocol is called "old" because the ARB is in the process of - * defining a new protocol, which will probably be called wither "new" or - * "vbo", to support multiple texture coordinate arrays, generic attributes, - * and vertex buffer objects. - * - * \author Ian Romanick <ian.d.romanick@intel.com> - */ - -static void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count); -static void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count); - -static void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices); -static void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices); - - -static GLubyte *emit_element_none(GLubyte * dst, - const struct array_state_vector *arrays, - unsigned index); -static GLubyte *emit_element_old(GLubyte * dst, - const struct array_state_vector *arrays, - unsigned index); -static struct array_state *get_array_entry(const struct array_state_vector - *arrays, GLenum key, - unsigned index); -static void fill_array_info_cache(struct array_state_vector *arrays); -static GLboolean validate_mode(__GLXcontext * gc, GLenum mode); -static GLboolean validate_count(__GLXcontext * gc, GLsizei count); -static GLboolean validate_type(__GLXcontext * gc, GLenum type); - - -/** - * Table of sizes, in bytes, of a GL types. All of the type enums are be in - * the range 0x1400 - 0x140F. That includes types added by extensions (i.e., - * \c GL_HALF_FLOAT_NV). This elements of this table correspond to the - * type enums masked with 0x0f. - * - * \notes - * \c GL_HALF_FLOAT_NV is not included. Neither are \c GL_2_BYTES, - * \c GL_3_BYTES, or \c GL_4_BYTES. - */ -const GLuint __glXTypeSize_table[16] = { - 1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0 -}; - - -/** - * Free the per-context array state that was allocated with - * __glXInitVertexArrayState(). - */ -void -__glXFreeVertexArrayState(__GLXcontext * gc) -{ - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - - if (arrays) { - if (arrays->stack) { - free(arrays->stack); - arrays->stack = NULL; - } - if (arrays->arrays) { - free(arrays->arrays); - arrays->arrays = NULL; - } - free(arrays); - state->array_state = NULL; - } -} - - -/** - * Initialize vertex array state of a GLX context. - * - * \param gc GLX context whose vertex array state is to be initialized. - * - * \warning - * This function may only be called after __GLXcontext::gl_extension_bits, - * __GLXcontext::server_minor, and __GLXcontext::server_major have been - * initialized. These values are used to determine what vertex arrays are - * supported. - * - * \bug - * Return values from malloc are not properly tested. - */ -void -__glXInitVertexArrayState(__GLXcontext * gc) -{ - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays; - - unsigned array_count; - int texture_units = 1, vertex_program_attribs = 0; - unsigned i, j; - - GLboolean got_fog = GL_FALSE; - GLboolean got_secondary_color = GL_FALSE; - - - arrays = calloc(1, sizeof(struct array_state_vector)); - state->array_state = arrays; - - arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol; - arrays->new_DrawArrays_possible = GL_FALSE; - arrays->DrawArrays = NULL; - - arrays->active_texture_unit = 0; - - - /* Determine how many arrays are actually needed. Only arrays that - * are supported by the server are create. For example, if the server - * supports only 2 texture units, then only 2 texture coordinate arrays - * are created. - * - * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, - * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and - * GL_EDGE_FLAG_ARRAY are supported. - */ - - array_count = 5; - - if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit) - || (gc->server_major > 1) || (gc->server_minor >= 4)) { - got_fog = GL_TRUE; - array_count++; - } - - if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit) - || (gc->server_major > 1) || (gc->server_minor >= 4)) { - got_secondary_color = GL_TRUE; - array_count++; - } - - if (__glExtensionBitIsEnabled(gc, GL_ARB_multitexture_bit) - || (gc->server_major > 1) || (gc->server_minor >= 3)) { - __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units); - } - - if (__glExtensionBitIsEnabled(gc, GL_ARB_vertex_program_bit)) { - __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, - GL_MAX_PROGRAM_ATTRIBS_ARB, - &vertex_program_attribs); - } - - arrays->num_texture_units = texture_units; - arrays->num_vertex_program_attribs = vertex_program_attribs; - array_count += texture_units + vertex_program_attribs; - arrays->num_arrays = array_count; - arrays->arrays = calloc(array_count, sizeof(struct array_state)); - - arrays->arrays[0].data_type = GL_FLOAT; - arrays->arrays[0].count = 3; - arrays->arrays[0].key = GL_NORMAL_ARRAY; - arrays->arrays[0].normalized = GL_TRUE; - arrays->arrays[0].old_DrawArrays_possible = GL_TRUE; - - arrays->arrays[1].data_type = GL_FLOAT; - arrays->arrays[1].count = 4; - arrays->arrays[1].key = GL_COLOR_ARRAY; - arrays->arrays[1].normalized = GL_TRUE; - arrays->arrays[1].old_DrawArrays_possible = GL_TRUE; - - arrays->arrays[2].data_type = GL_FLOAT; - arrays->arrays[2].count = 1; - arrays->arrays[2].key = GL_INDEX_ARRAY; - arrays->arrays[2].old_DrawArrays_possible = GL_TRUE; - - arrays->arrays[3].data_type = GL_UNSIGNED_BYTE; - arrays->arrays[3].count = 1; - arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY; - arrays->arrays[3].old_DrawArrays_possible = GL_TRUE; - - for (i = 0; i < texture_units; i++) { - arrays->arrays[4 + i].data_type = GL_FLOAT; - arrays->arrays[4 + i].count = 4; - arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY; - - arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0); - arrays->arrays[4 + i].index = i; - - arrays->arrays[4 + i].header[1] = i + GL_TEXTURE0; - } - - i = 4 + texture_units; - - if (got_fog) { - arrays->arrays[i].data_type = GL_FLOAT; - arrays->arrays[i].count = 1; - arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY; - arrays->arrays[i].old_DrawArrays_possible = GL_TRUE; - i++; - } - - if (got_secondary_color) { - arrays->arrays[i].data_type = GL_FLOAT; - arrays->arrays[i].count = 3; - arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY; - arrays->arrays[i].old_DrawArrays_possible = GL_TRUE; - arrays->arrays[i].normalized = GL_TRUE; - i++; - } - - - for (j = 0; j < vertex_program_attribs; j++) { - const unsigned idx = (vertex_program_attribs - (j + 1)); - - - arrays->arrays[idx + i].data_type = GL_FLOAT; - arrays->arrays[idx + i].count = 4; - arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER; - - arrays->arrays[idx + i].old_DrawArrays_possible = 0; - arrays->arrays[idx + i].index = idx; - - arrays->arrays[idx + i].header[1] = idx; - } - - i += vertex_program_attribs; - - - /* Vertex array *must* be last becuase of the way that - * emit_DrawArrays_none works. - */ - - arrays->arrays[i].data_type = GL_FLOAT; - arrays->arrays[i].count = 4; - arrays->arrays[i].key = GL_VERTEX_ARRAY; - arrays->arrays[i].old_DrawArrays_possible = GL_TRUE; - - assert((i + 1) == arrays->num_arrays); - - arrays->stack_index = 0; - arrays->stack = malloc(sizeof(struct array_stack_state) - * arrays->num_arrays); -} - - -/** - * Calculate the size of a single vertex for the "none" protocol. This is - * essentially the size of all the immediate-mode commands required to - * implement the enabled vertex arrays. - */ -static size_t -calculate_single_vertex_size_none(const struct array_state_vector *arrays) -{ - size_t single_vertex_size = 0; - unsigned i; - - - for (i = 0; i < arrays->num_arrays; i++) { - if (arrays->arrays[i].enabled) { - single_vertex_size += ((uint16_t *) arrays->arrays[i].header)[0]; - } - } - - return single_vertex_size; -} - - -/** - * Emit a single element using non-DrawArrays protocol. - */ -GLubyte * -emit_element_none(GLubyte * dst, - const struct array_state_vector * arrays, unsigned index) -{ - unsigned i; - - - for (i = 0; i < arrays->num_arrays; i++) { - if (arrays->arrays[i].enabled) { - const size_t offset = index * arrays->arrays[i].true_stride; - - /* The generic attributes can have more data than is in the - * elements. This is because a vertex array can be a 2 element, - * normalized, unsigned short, but the "closest" immediate mode - * protocol is for a 4Nus. Since the sizes are small, the - * performance impact on modern processors should be negligible. - */ - (void) memset(dst, 0, ((uint16_t *) arrays->arrays[i].header)[0]); - - (void) memcpy(dst, arrays->arrays[i].header, - arrays->arrays[i].header_size); - - dst += arrays->arrays[i].header_size; - - (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset, - arrays->arrays[i].element_size); - - dst += __GLX_PAD(arrays->arrays[i].element_size); - } - } - - return dst; -} - - -/** - * Emit a single element using "old" DrawArrays protocol from - * EXT_vertex_arrays / OpenGL 1.1. - */ -GLubyte * -emit_element_old(GLubyte * dst, - const struct array_state_vector * arrays, unsigned index) -{ - unsigned i; - - - for (i = 0; i < arrays->num_arrays; i++) { - if (arrays->arrays[i].enabled) { - const size_t offset = index * arrays->arrays[i].true_stride; - - (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset, - arrays->arrays[i].element_size); - - dst += __GLX_PAD(arrays->arrays[i].element_size); - } - } - - return dst; -} - - -struct array_state * -get_array_entry(const struct array_state_vector *arrays, - GLenum key, unsigned index) -{ - unsigned i; - - for (i = 0; i < arrays->num_arrays; i++) { - if ((arrays->arrays[i].key == key) - && (arrays->arrays[i].index == index)) { - return &arrays->arrays[i]; - } - } - - return NULL; -} - - -static GLboolean -allocate_array_info_cache(struct array_state_vector *arrays, - size_t required_size) -{ -#define MAX_HEADER_SIZE 20 - if (arrays->array_info_cache_buffer_size < required_size) { - GLubyte *temp = realloc(arrays->array_info_cache_base, - required_size + MAX_HEADER_SIZE); - - if (temp == NULL) { - return GL_FALSE; - } - - arrays->array_info_cache_base = temp; - arrays->array_info_cache = temp + MAX_HEADER_SIZE; - arrays->array_info_cache_buffer_size = required_size; - } - - arrays->array_info_cache_size = required_size; - return GL_TRUE; -} - - -/** - */ -void -fill_array_info_cache(struct array_state_vector *arrays) -{ - GLboolean old_DrawArrays_possible; - unsigned i; - - - /* Determine how many arrays are enabled. - */ - - arrays->enabled_client_array_count = 0; - old_DrawArrays_possible = arrays->old_DrawArrays_possible; - for (i = 0; i < arrays->num_arrays; i++) { - if (arrays->arrays[i].enabled) { - arrays->enabled_client_array_count++; - old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible; - } - } - - if (arrays->new_DrawArrays_possible) { - assert(!arrays->new_DrawArrays_possible); - } - else if (old_DrawArrays_possible) { - const size_t required_size = arrays->enabled_client_array_count * 12; - uint32_t *info; - - - if (!allocate_array_info_cache(arrays, required_size)) { - return; - } - - - info = (uint32_t *) arrays->array_info_cache; - for (i = 0; i < arrays->num_arrays; i++) { - if (arrays->arrays[i].enabled) { - *(info++) = arrays->arrays[i].data_type; - *(info++) = arrays->arrays[i].count; - *(info++) = arrays->arrays[i].key; - } - } - - arrays->DrawArrays = emit_DrawArrays_old; - arrays->DrawElements = emit_DrawElements_old; - } - else { - arrays->DrawArrays = emit_DrawArrays_none; - arrays->DrawElements = emit_DrawElements_none; - } - - arrays->array_info_cache_valid = GL_TRUE; -} - - -/** - * Emit a \c glDrawArrays command using the "none" protocol. That is, - * emit immediate-mode commands that are equivalent to the requiested - * \c glDrawArrays command. This is used with servers that don't support - * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where - * vertex state is enabled that is not compatible with that protocol. - */ -void -emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - - size_t single_vertex_size; - GLubyte *pc; - unsigned i; - static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin }; - static const uint16_t end_cmd[2] = { 4, X_GLrop_End }; - - - single_vertex_size = calculate_single_vertex_size_none(arrays); - - pc = gc->pc; - - (void) memcpy(pc, begin_cmd, 4); - *(int *) (pc + 4) = mode; - - pc += 8; - - for (i = 0; i < count; i++) { - if ((pc + single_vertex_size) >= gc->bufEnd) { - pc = __glXFlushRenderBuffer(gc, pc); - } - - pc = emit_element_none(pc, arrays, first + i); - } - - if ((pc + 4) >= gc->bufEnd) { - pc = __glXFlushRenderBuffer(gc, pc); - } - - (void) memcpy(pc, end_cmd, 4); - pc += 4; - - gc->pc = pc; - if (gc->pc > gc->limit) { - (void) __glXFlushRenderBuffer(gc, gc->pc); - } -} - - -/** - * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays - * protocol. - * - * \param gc GLX context. - * \param arrays Array state. - * \param elements_per_request Location to store the number of elements that - * can fit in a single Render / RenderLarge - * command. - * \param total_request Total number of requests for a RenderLarge - * command. If a Render command is used, this - * will be zero. - * \param mode Drawing mode. - * \param count Number of vertices. - * - * \returns - * A pointer to the buffer for array data. - */ -static GLubyte * -emit_DrawArrays_header_old(__GLXcontext * gc, - struct array_state_vector *arrays, - size_t * elements_per_request, - unsigned int *total_requests, - GLenum mode, GLsizei count) -{ - size_t command_size; - size_t single_vertex_size; - const unsigned header_size = 16; - unsigned i; - GLubyte *pc; - - - /* Determine the size of the whole command. This includes the header, - * the ARRAY_INFO data and the array data. Once this size is calculated, - * it will be known whether a Render or RenderLarge command is needed. - */ - - single_vertex_size = 0; - for (i = 0; i < arrays->num_arrays; i++) { - if (arrays->arrays[i].enabled) { - single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size); - } - } - - command_size = arrays->array_info_cache_size + header_size - + (single_vertex_size * count); - - - /* Write the header for either a Render command or a RenderLarge - * command. After the header is written, write the ARRAY_INFO data. - */ - - if (command_size > gc->maxSmallRenderCommandSize) { - /* maxSize is the maximum amount of data can be stuffed into a single - * packet. sz_xGLXRenderReq is added because bufSize is the maximum - * packet size minus sz_xGLXRenderReq. - */ - const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq) - - sz_xGLXRenderLargeReq; - unsigned vertex_requests; - - - /* Calculate the number of data packets that will be required to send - * the whole command. To do this, the number of verticies that - * will fit in a single buffer must be calculated. - * - * The important value here is elements_per_request. This is the - * number of complete array elements that will fit in a single - * buffer. There may be some wasted space at the end of the buffer, - * but splitting elements across buffer boundries would be painful. - */ - - elements_per_request[0] = maxSize / single_vertex_size; - - vertex_requests = (count + elements_per_request[0] - 1) - / elements_per_request[0]; - - *total_requests = vertex_requests + 1; - - - __glXFlushRenderBuffer(gc, gc->pc); - - command_size += 4; - - pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4); - *(uint32_t *) (pc + 0) = command_size; - *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays; - *(uint32_t *) (pc + 8) = count; - *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count; - *(uint32_t *) (pc + 16) = mode; - - __glXSendLargeChunk(gc, 1, *total_requests, pc, - header_size + 4 + arrays->array_info_cache_size); - - pc = gc->pc; - } - else { - if ((gc->pc + command_size) >= gc->bufEnd) { - (void) __glXFlushRenderBuffer(gc, gc->pc); - } - - pc = gc->pc; - *(uint16_t *) (pc + 0) = command_size; - *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays; - *(uint32_t *) (pc + 4) = count; - *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count; - *(uint32_t *) (pc + 12) = mode; - - pc += header_size; - - (void) memcpy(pc, arrays->array_info_cache, - arrays->array_info_cache_size); - pc += arrays->array_info_cache_size; - - *elements_per_request = count; - *total_requests = 0; - } - - - return pc; -} - - -/** - */ -void -emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - - GLubyte *pc; - size_t elements_per_request; - unsigned total_requests = 0; - unsigned i; - size_t total_sent = 0; - - - pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request, - &total_requests, mode, count); - - - /* Write the arrays. - */ - - if (total_requests == 0) { - assert(elements_per_request >= count); - - for (i = 0; i < count; i++) { - pc = emit_element_old(pc, arrays, i + first); - } - - assert(pc <= gc->bufEnd); - - gc->pc = pc; - if (gc->pc > gc->limit) { - (void) __glXFlushRenderBuffer(gc, gc->pc); - } - } - else { - unsigned req; - - - for (req = 2; req <= total_requests; req++) { - if (count < elements_per_request) { - elements_per_request = count; - } - - pc = gc->pc; - for (i = 0; i < elements_per_request; i++) { - pc = emit_element_old(pc, arrays, i + first); - } - - first += elements_per_request; - - total_sent += (size_t) (pc - gc->pc); - __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc); - - count -= elements_per_request; - } - } -} - - -void -emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin }; - static const uint16_t end_cmd[2] = { 4, X_GLrop_End }; - - GLubyte *pc; - size_t single_vertex_size; - unsigned i; - - - single_vertex_size = calculate_single_vertex_size_none(arrays); - - - if ((gc->pc + single_vertex_size) >= gc->bufEnd) { - gc->pc = __glXFlushRenderBuffer(gc, gc->pc); - } - - pc = gc->pc; - - (void) memcpy(pc, begin_cmd, 4); - *(int *) (pc + 4) = mode; - - pc += 8; - - for (i = 0; i < count; i++) { - unsigned index = 0; - - if ((pc + single_vertex_size) >= gc->bufEnd) { - pc = __glXFlushRenderBuffer(gc, pc); - } - - switch (type) { - case GL_UNSIGNED_INT: - index = (unsigned) (((GLuint *) indices)[i]); - break; - case GL_UNSIGNED_SHORT: - index = (unsigned) (((GLushort *) indices)[i]); - break; - case GL_UNSIGNED_BYTE: - index = (unsigned) (((GLubyte *) indices)[i]); - break; - } - pc = emit_element_none(pc, arrays, index); - } - - if ((pc + 4) >= gc->bufEnd) { - pc = __glXFlushRenderBuffer(gc, pc); - } - - (void) memcpy(pc, end_cmd, 4); - pc += 4; - - gc->pc = pc; - if (gc->pc > gc->limit) { - (void) __glXFlushRenderBuffer(gc, gc->pc); - } -} - - -/** - */ -void -emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - - GLubyte *pc; - size_t elements_per_request; - unsigned total_requests = 0; - unsigned i; - unsigned req; - unsigned req_element = 0; - - - pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request, - &total_requests, mode, count); - - - /* Write the arrays. - */ - - req = 2; - while (count > 0) { - if (count < elements_per_request) { - elements_per_request = count; - } - - switch (type) { - case GL_UNSIGNED_INT:{ - const GLuint *ui_ptr = (const GLuint *) indices + req_element; - - for (i = 0; i < elements_per_request; i++) { - const GLint index = (GLint) * (ui_ptr++); - pc = emit_element_old(pc, arrays, index); - } - break; - } - case GL_UNSIGNED_SHORT:{ - const GLushort *us_ptr = (const GLushort *) indices + req_element; - - for (i = 0; i < elements_per_request; i++) { - const GLint index = (GLint) * (us_ptr++); - pc = emit_element_old(pc, arrays, index); - } - break; - } - case GL_UNSIGNED_BYTE:{ - const GLubyte *ub_ptr = (const GLubyte *) indices + req_element; - - for (i = 0; i < elements_per_request; i++) { - const GLint index = (GLint) * (ub_ptr++); - pc = emit_element_old(pc, arrays, index); - } - break; - } - } - - if (total_requests != 0) { - __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc); - pc = gc->pc; - req++; - } - - count -= elements_per_request; - req_element += elements_per_request; - } - - - assert((total_requests == 0) || ((req - 1) == total_requests)); - - if (total_requests == 0) { - assert(pc <= gc->bufEnd); - - gc->pc = pc; - if (gc->pc > gc->limit) { - (void) __glXFlushRenderBuffer(gc, gc->pc); - } - } -} - - -/** - * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid. - * If it is not valid, then an error code is set in the GLX context. - * - * \returns - * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not. - */ -static GLboolean -validate_mode(__GLXcontext * gc, GLenum mode) -{ - switch (mode) { - case GL_POINTS: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - case GL_LINES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - case GL_TRIANGLES: - case GL_QUAD_STRIP: - case GL_QUADS: - case GL_POLYGON: - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return GL_FALSE; - } - - return GL_TRUE; -} - - -/** - * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid. - * A value less than zero is invalid and will result in \c GL_INVALID_VALUE - * being set. A value of zero will not result in an error being set, but - * will result in \c GL_FALSE being returned. - * - * \returns - * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. - */ -static GLboolean -validate_count(__GLXcontext * gc, GLsizei count) -{ - if (count < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - } - - return (count > 0); -} - - -/** - * Validate that the \c type parameter to \c glDrawElements, et. al. is - * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and - * \c GL_UNSIGNED_INT are valid. - * - * \returns - * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. - */ -static GLboolean -validate_type(__GLXcontext * gc, GLenum type) -{ - switch (type) { - case GL_UNSIGNED_INT: - case GL_UNSIGNED_SHORT: - case GL_UNSIGNED_BYTE: - return GL_TRUE; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return GL_FALSE; - } -} - - -void -__indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - - - if (validate_mode(gc, mode) && validate_count(gc, count)) { - if (!arrays->array_info_cache_valid) { - fill_array_info_cache(arrays); - } - - arrays->DrawArrays(mode, first, count); - } -} - - -void -__indirect_glArrayElement(GLint index) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - - size_t single_vertex_size; - - - single_vertex_size = calculate_single_vertex_size_none(arrays); - - if ((gc->pc + single_vertex_size) >= gc->bufEnd) { - gc->pc = __glXFlushRenderBuffer(gc, gc->pc); - } - - gc->pc = emit_element_none(gc->pc, arrays, index); - - if (gc->pc > gc->limit) { - (void) __glXFlushRenderBuffer(gc, gc->pc); - } -} - - -void -__indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - - - if (validate_mode(gc, mode) && validate_count(gc, count) - && validate_type(gc, type)) { - if (!arrays->array_info_cache_valid) { - fill_array_info_cache(arrays); - } - - arrays->DrawElements(mode, count, type, indices); - } -} - - -void -__indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid * indices) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - - - if (validate_mode(gc, mode) && validate_count(gc, count) - && validate_type(gc, type)) { - if (end < start) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - if (!arrays->array_info_cache_valid) { - fill_array_info_cache(arrays); - } - - arrays->DrawElements(mode, count, type, indices); - } -} - - -void -__indirect_glMultiDrawArraysEXT(GLenum mode, GLint * first, GLsizei * count, - GLsizei primcount) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - GLsizei i; - - - if (validate_mode(gc, mode)) { - if (!arrays->array_info_cache_valid) { - fill_array_info_cache(arrays); - } - - for (i = 0; i < primcount; i++) { - if (validate_count(gc, count[i])) { - arrays->DrawArrays(mode, first[i], count[i]); - } - } - } -} - - -void -__indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count, - GLenum type, const GLvoid ** indices, - GLsizei primcount) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - const __GLXattribute *state = - (const __GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - GLsizei i; - - - if (validate_mode(gc, mode) && validate_type(gc, type)) { - if (!arrays->array_info_cache_valid) { - fill_array_info_cache(arrays); - } - - for (i = 0; i < primcount; i++) { - if (validate_count(gc, count[i])) { - arrays->DrawElements(mode, count[i], type, indices[i]); - } - } - } -} - - -#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \ - do { \ - (a)->data = PTR; \ - (a)->data_type = TYPE; \ - (a)->user_stride = STRIDE; \ - (a)->count = COUNT; \ - (a)->normalized = NORMALIZED; \ - \ - (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \ - (a)->true_stride = (STRIDE == 0) \ - ? (a)->element_size : STRIDE; \ - \ - (a)->header_size = HDR_SIZE; \ - ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \ - ((uint16_t *) (a)->header)[1] = OPCODE; \ - } while(0) - - -void -__indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride, - const GLvoid * pointer) -{ - static const uint16_t short_ops[5] = { - 0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv - }; - static const uint16_t int_ops[5] = { - 0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv - }; - static const uint16_t float_ops[5] = { - 0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv - }; - static const uint16_t double_ops[5] = { - 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv - }; - uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - - - if (size < 2 || size > 4 || stride < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - switch (type) { - case GL_SHORT: - opcode = short_ops[size]; - break; - case GL_INT: - opcode = int_ops[size]; - break; - case GL_FLOAT: - opcode = float_ops[size]; - break; - case GL_DOUBLE: - opcode = double_ops[size]; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0); - assert(a != NULL); - COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4, - opcode); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -void -__indirect_glNormalPointer(GLenum type, GLsizei stride, - const GLvoid * pointer) -{ - uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - - - if (stride < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - switch (type) { - case GL_BYTE: - opcode = X_GLrop_Normal3bv; - break; - case GL_SHORT: - opcode = X_GLrop_Normal3sv; - break; - case GL_INT: - opcode = X_GLrop_Normal3iv; - break; - case GL_FLOAT: - opcode = X_GLrop_Normal3fv; - break; - case GL_DOUBLE: - opcode = X_GLrop_Normal3dv; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0); - assert(a != NULL); - COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -void -__indirect_glColorPointer(GLint size, GLenum type, GLsizei stride, - const GLvoid * pointer) -{ - static const uint16_t byte_ops[5] = { - 0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv - }; - static const uint16_t ubyte_ops[5] = { - 0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv - }; - static const uint16_t short_ops[5] = { - 0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv - }; - static const uint16_t ushort_ops[5] = { - 0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv - }; - static const uint16_t int_ops[5] = { - 0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv - }; - static const uint16_t uint_ops[5] = { - 0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv - }; - static const uint16_t float_ops[5] = { - 0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv - }; - static const uint16_t double_ops[5] = { - 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv - }; - uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - - - if (size < 3 || size > 4 || stride < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - switch (type) { - case GL_BYTE: - opcode = byte_ops[size]; - break; - case GL_UNSIGNED_BYTE: - opcode = ubyte_ops[size]; - break; - case GL_SHORT: - opcode = short_ops[size]; - break; - case GL_UNSIGNED_SHORT: - opcode = ushort_ops[size]; - break; - case GL_INT: - opcode = int_ops[size]; - break; - case GL_UNSIGNED_INT: - opcode = uint_ops[size]; - break; - case GL_FLOAT: - opcode = float_ops[size]; - break; - case GL_DOUBLE: - opcode = double_ops[size]; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - a = get_array_entry(arrays, GL_COLOR_ARRAY, 0); - assert(a != NULL); - COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -void -__indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) -{ - uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - - - if (stride < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - switch (type) { - case GL_UNSIGNED_BYTE: - opcode = X_GLrop_Indexubv; - break; - case GL_SHORT: - opcode = X_GLrop_Indexsv; - break; - case GL_INT: - opcode = X_GLrop_Indexiv; - break; - case GL_FLOAT: - opcode = X_GLrop_Indexfv; - break; - case GL_DOUBLE: - opcode = X_GLrop_Indexdv; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - a = get_array_entry(arrays, GL_INDEX_ARRAY, 0); - assert(a != NULL); - COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -void -__indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - - - if (stride < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - - a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0); - assert(a != NULL); - COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE, - 4, X_GLrop_EdgeFlagv); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -void -__indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, - const GLvoid * pointer) -{ - static const uint16_t short_ops[5] = { - 0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv, - X_GLrop_TexCoord4sv - }; - static const uint16_t int_ops[5] = { - 0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv, - X_GLrop_TexCoord4iv - }; - static const uint16_t float_ops[5] = { - 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv, - X_GLrop_TexCoord4fv - }; - static const uint16_t double_ops[5] = { - 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv, - X_GLrop_TexCoord4dv - }; - - static const uint16_t mshort_ops[5] = { - 0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB, - X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB - }; - static const uint16_t mint_ops[5] = { - 0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB, - X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB - }; - static const uint16_t mfloat_ops[5] = { - 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2fvARB, - X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB - }; - static const uint16_t mdouble_ops[5] = { - 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB, - X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB - }; - - uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - unsigned header_size; - unsigned index; - - - if (size < 1 || size > 4 || stride < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - index = arrays->active_texture_unit; - if (index == 0) { - switch (type) { - case GL_SHORT: - opcode = short_ops[size]; - break; - case GL_INT: - opcode = int_ops[size]; - break; - case GL_FLOAT: - opcode = float_ops[size]; - break; - case GL_DOUBLE: - opcode = double_ops[size]; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - header_size = 4; - } - else { - switch (type) { - case GL_SHORT: - opcode = mshort_ops[size]; - break; - case GL_INT: - opcode = mint_ops[size]; - break; - case GL_FLOAT: - opcode = mfloat_ops[size]; - break; - case GL_DOUBLE: - opcode = mdouble_ops[size]; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - header_size = 8; - } - - a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index); - assert(a != NULL); - COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, - header_size, opcode); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -void -__indirect_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, - const GLvoid * pointer) -{ - uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - - - if (size != 3 || stride < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - switch (type) { - case GL_BYTE: - opcode = 4126; - break; - case GL_UNSIGNED_BYTE: - opcode = 4131; - break; - case GL_SHORT: - opcode = 4127; - break; - case GL_UNSIGNED_SHORT: - opcode = 4132; - break; - case GL_INT: - opcode = 4128; - break; - case GL_UNSIGNED_INT: - opcode = 4133; - break; - case GL_FLOAT: - opcode = 4129; - break; - case GL_DOUBLE: - opcode = 4130; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0); - if (a == NULL) { - __glXSetError(gc, GL_INVALID_OPERATION); - return; - } - - COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -void -__indirect_glFogCoordPointerEXT(GLenum type, GLsizei stride, - const GLvoid * pointer) -{ - uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - - - if (stride < 0) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - switch (type) { - case GL_FLOAT: - opcode = 4124; - break; - case GL_DOUBLE: - opcode = 4125; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0); - if (a == NULL) { - __glXSetError(gc, GL_INVALID_OPERATION); - return; - } - - COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -void -__indirect_glVertexAttribPointerARB(GLuint index, GLint size, - GLenum type, GLboolean normalized, - GLsizei stride, const GLvoid * pointer) -{ - static const uint16_t short_ops[5] = { 0, 4189, 4190, 4191, 4192 }; - static const uint16_t float_ops[5] = { 0, 4193, 4194, 4195, 4196 }; - static const uint16_t double_ops[5] = { 0, 4197, 4198, 4199, 4200 }; - - uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); - __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - unsigned true_immediate_count; - unsigned true_immediate_size; - - - if ((size < 1) || (size > 4) || (stride < 0) - || (index > arrays->num_vertex_program_attribs)) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - - if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) { - switch (type) { - case GL_BYTE: - opcode = X_GLrop_VertexAttrib4NbvARB; - break; - case GL_UNSIGNED_BYTE: - opcode = X_GLrop_VertexAttrib4NubvARB; - break; - case GL_SHORT: - opcode = X_GLrop_VertexAttrib4NsvARB; - break; - case GL_UNSIGNED_SHORT: - opcode = X_GLrop_VertexAttrib4NusvARB; - break; - case GL_INT: - opcode = X_GLrop_VertexAttrib4NivARB; - break; - case GL_UNSIGNED_INT: - opcode = X_GLrop_VertexAttrib4NuivARB; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - true_immediate_count = 4; - } - else { - true_immediate_count = size; - - switch (type) { - case GL_BYTE: - opcode = X_GLrop_VertexAttrib4bvARB; - true_immediate_count = 4; - break; - case GL_UNSIGNED_BYTE: - opcode = X_GLrop_VertexAttrib4ubvARB; - true_immediate_count = 4; - break; - case GL_SHORT: - opcode = short_ops[size]; - break; - case GL_UNSIGNED_SHORT: - opcode = X_GLrop_VertexAttrib4usvARB; - true_immediate_count = 4; - break; - case GL_INT: - opcode = X_GLrop_VertexAttrib4ivARB; - true_immediate_count = 4; - break; - case GL_UNSIGNED_INT: - opcode = X_GLrop_VertexAttrib4uivARB; - true_immediate_count = 4; - break; - case GL_FLOAT: - opcode = float_ops[size]; - break; - case GL_DOUBLE: - opcode = double_ops[size]; - break; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - } - - a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index); - if (a == NULL) { - __glXSetError(gc, GL_INVALID_OPERATION); - return; - } - - COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8, - opcode); - - true_immediate_size = __glXTypeSize(type) * true_immediate_count; - ((uint16_t *) (a)->header)[0] = __GLX_PAD(a->header_size - + true_immediate_size); - - if (a->enabled) { - arrays->array_info_cache_valid = GL_FALSE; - } -} - - -/** - * I don't have 100% confidence that this is correct. The different rules - * about whether or not generic vertex attributes alias "classic" vertex - * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program, - * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My - * feeling is that the client-side doesn't have to worry about it. The - * client just sends all the data to the server and lets the server deal - * with it. - */ -void -__indirect_glVertexAttribPointerNV(GLuint index, GLint size, - GLenum type, GLsizei stride, - const GLvoid * pointer) -{ - __GLXcontext *gc = __glXGetCurrentContext(); - GLboolean normalized = GL_FALSE; - - - switch (type) { - case GL_UNSIGNED_BYTE: - if (size != 4) { - __glXSetError(gc, GL_INVALID_VALUE); - return; - } - normalized = GL_TRUE; - - case GL_SHORT: - case GL_FLOAT: - case GL_DOUBLE: - __indirect_glVertexAttribPointerARB(index, size, type, - normalized, stride, pointer); - return; - default: - __glXSetError(gc, GL_INVALID_ENUM); - return; - } -} - - -void -__indirect_glClientActiveTextureARB(GLenum texture) -{ - __GLXcontext *const gc = __glXGetCurrentContext(); - __GLXattribute *const state = - (__GLXattribute *) (gc->client_state_private); - struct array_state_vector *const arrays = state->array_state; - const GLint unit = (GLint) texture - GL_TEXTURE0; - - - if ((unit < 0) || (unit >= arrays->num_texture_units)) { - __glXSetError(gc, GL_INVALID_ENUM); - return; - } - - arrays->active_texture_unit = unit; -} - - -/** - * Modify the enable state for the selected array - */ -GLboolean -__glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index, - GLboolean enable) -{ - struct array_state_vector *arrays = state->array_state; - struct array_state *a; - - - /* Texture coordinate arrays have an implict index set when the - * application calls glClientActiveTexture. - */ - if (key == GL_TEXTURE_COORD_ARRAY) { - index = arrays->active_texture_unit; - } - - a = get_array_entry(arrays, key, index); - - if ((a != NULL) && (a->enabled != enable)) { - a->enabled = enable; - arrays->array_info_cache_valid = GL_FALSE; - } - - return (a != NULL); -} - - -void -__glXArrayDisableAll(__GLXattribute * state) -{ - struct array_state_vector *arrays = state->array_state; - unsigned i; - - - for (i = 0; i < arrays->num_arrays; i++) { - arrays->arrays[i].enabled = GL_FALSE; - } - - arrays->array_info_cache_valid = GL_FALSE; -} - - -/** - */ -GLboolean -__glXGetArrayEnable(const __GLXattribute * const state, - GLenum key, unsigned index, GLintptr * dest) -{ - const struct array_state_vector *arrays = state->array_state; - const struct array_state *a = - get_array_entry((struct array_state_vector *) arrays, - key, index); - - if (a != NULL) { - *dest = (GLintptr) a->enabled; - } - - return (a != NULL); -} - - -/** - */ -GLboolean -__glXGetArrayType(const __GLXattribute * const state, - GLenum key, unsigned index, GLintptr * dest) -{ - const struct array_state_vector *arrays = state->array_state; - const struct array_state *a = - get_array_entry((struct array_state_vector *) arrays, - key, index); - - if (a != NULL) { - *dest = (GLintptr) a->data_type; - } - - return (a != NULL); -} - - -/** - */ -GLboolean -__glXGetArraySize(const __GLXattribute * const state, - GLenum key, unsigned index, GLintptr * dest) -{ - const struct array_state_vector *arrays = state->array_state; - const struct array_state *a = - get_array_entry((struct array_state_vector *) arrays, - key, index); - - if (a != NULL) { - *dest = (GLintptr) a->count; - } - - return (a != NULL); -} - - -/** - */ -GLboolean -__glXGetArrayStride(const __GLXattribute * const state, - GLenum key, unsigned index, GLintptr * dest) -{ - const struct array_state_vector *arrays = state->array_state; - const struct array_state *a = - get_array_entry((struct array_state_vector *) arrays, - key, index); - - if (a != NULL) { - *dest = (GLintptr) a->user_stride; - } - - return (a != NULL); -} - - -/** - */ -GLboolean -__glXGetArrayPointer(const __GLXattribute * const state, - GLenum key, unsigned index, void **dest) -{ - const struct array_state_vector *arrays = state->array_state; - const struct array_state *a = - get_array_entry((struct array_state_vector *) arrays, - key, index); - - - if (a != NULL) { - *dest = (void *) (a->data); - } - - return (a != NULL); -} - - -/** - */ -GLboolean -__glXGetArrayNormalized(const __GLXattribute * const state, - GLenum key, unsigned index, GLintptr * dest) -{ - const struct array_state_vector *arrays = state->array_state; - const struct array_state *a = - get_array_entry((struct array_state_vector *) arrays, - key, index); - - - if (a != NULL) { - *dest = (GLintptr) a->normalized; - } - - return (a != NULL); -} - - -/** - */ -GLuint -__glXGetActiveTextureUnit(const __GLXattribute * const state) -{ - return state->array_state->active_texture_unit; -} - - -void -__glXPushArrayState(__GLXattribute * state) -{ - struct array_state_vector *arrays = state->array_state; - struct array_stack_state *stack = - &arrays->stack[(arrays->stack_index * arrays->num_arrays)]; - unsigned i; - - /* XXX are we pushing _all_ the necessary fields? */ - for (i = 0; i < arrays->num_arrays; i++) { - stack[i].data = arrays->arrays[i].data; - stack[i].data_type = arrays->arrays[i].data_type; - stack[i].user_stride = arrays->arrays[i].user_stride; - stack[i].count = arrays->arrays[i].count; - stack[i].key = arrays->arrays[i].key; - stack[i].index = arrays->arrays[i].index; - stack[i].enabled = arrays->arrays[i].enabled; - } - - arrays->active_texture_unit_stack[arrays->stack_index] = - arrays->active_texture_unit; - - arrays->stack_index++; -} - - -void -__glXPopArrayState(__GLXattribute * state) -{ - struct array_state_vector *arrays = state->array_state; - struct array_stack_state *stack; - unsigned i; - - - arrays->stack_index--; - stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)]; - - for (i = 0; i < arrays->num_arrays; i++) { - switch (stack[i].key) { - case GL_NORMAL_ARRAY: - __indirect_glNormalPointer(stack[i].data_type, - stack[i].user_stride, stack[i].data); - break; - case GL_COLOR_ARRAY: - __indirect_glColorPointer(stack[i].count, - stack[i].data_type, - stack[i].user_stride, stack[i].data); - break; - case GL_INDEX_ARRAY: - __indirect_glIndexPointer(stack[i].data_type, - stack[i].user_stride, stack[i].data); - break; - case GL_EDGE_FLAG_ARRAY: - __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data); - break; - case GL_TEXTURE_COORD_ARRAY: - arrays->active_texture_unit = stack[i].index; - __indirect_glTexCoordPointer(stack[i].count, - stack[i].data_type, - stack[i].user_stride, stack[i].data); - break; - case GL_SECONDARY_COLOR_ARRAY: - __indirect_glSecondaryColorPointerEXT(stack[i].count, - stack[i].data_type, - stack[i].user_stride, - stack[i].data); - break; - case GL_FOG_COORDINATE_ARRAY: - __indirect_glFogCoordPointerEXT(stack[i].data_type, - stack[i].user_stride, stack[i].data); - break; - - } - - __glXSetArrayEnable(state, stack[i].key, stack[i].index, - stack[i].enabled); - } - - arrays->active_texture_unit = - arrays->active_texture_unit_stack[arrays->stack_index]; -} |