summaryrefslogtreecommitdiff
path: root/src/glx/x11/indirect_vertex_array.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx/x11/indirect_vertex_array.c')
-rw-r--r--src/glx/x11/indirect_vertex_array.c1985
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];
-}