X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglx%2Findirect_vertex_array.c;h=c81aae603866c8f3e7d7ba9e2a01c9a409f48787;hb=d971a4230d54069c996bca78b6ed6a6a23377821;hp=ec0e654ceae6bfe53baca2a3d98e33c1c5b92604;hpb=685340a53e1dcb2a888e634ee71ba24356befe69;p=mesa.git diff --git a/src/glx/indirect_vertex_array.c b/src/glx/indirect_vertex_array.c index ec0e654ceae..c81aae60386 100644 --- a/src/glx/indirect_vertex_array.c +++ b/src/glx/indirect_vertex_array.c @@ -84,9 +84,9 @@ 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); +static GLboolean validate_mode(struct glx_context * gc, GLenum mode); +static GLboolean validate_count(struct glx_context * gc, GLsizei count); +static GLboolean validate_type(struct glx_context * gc, GLenum type); /** @@ -109,20 +109,16 @@ const GLuint __glXTypeSize_table[16] = { * __glXInitVertexArrayState(). */ void -__glXFreeVertexArrayState(__GLXcontext * gc) +__glXFreeVertexArrayState(struct glx_context * 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->stack); + arrays->stack = NULL; + free(arrays->arrays); + arrays->arrays = NULL; free(arrays); state->array_state = NULL; } @@ -135,16 +131,13 @@ __glXFreeVertexArrayState(__GLXcontext * gc) * \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 + * This function may only be called after struct glx_context::gl_extension_bits, + * struct glx_context::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) +__glXInitVertexArrayState(struct glx_context * gc) { __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays; @@ -160,6 +153,11 @@ __glXInitVertexArrayState(__GLXcontext * gc) arrays = calloc(1, sizeof(struct array_state_vector)); state->array_state = arrays; + if (arrays == NULL) { + __glXSetError(gc, GL_OUT_OF_MEMORY); + return; + } + arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol; arrays->new_DrawArrays_possible = GL_FALSE; arrays->DrawArrays = NULL; @@ -208,6 +206,13 @@ __glXInitVertexArrayState(__GLXcontext * gc) arrays->num_arrays = array_count; arrays->arrays = calloc(array_count, sizeof(struct array_state)); + if (arrays->arrays == NULL) { + state->array_state = NULL; + free(arrays); + __glXSetError(gc, GL_OUT_OF_MEMORY); + return; + } + arrays->arrays[0].data_type = GL_FLOAT; arrays->arrays[0].count = 3; arrays->arrays[0].key = GL_NORMAL_ARRAY; @@ -237,8 +242,6 @@ __glXInitVertexArrayState(__GLXcontext * gc) 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; @@ -271,14 +274,12 @@ __glXInitVertexArrayState(__GLXcontext * gc) 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 + /* Vertex array *must* be last because of the way that * emit_DrawArrays_none works. */ @@ -293,6 +294,14 @@ __glXInitVertexArrayState(__GLXcontext * gc) arrays->stack = malloc(sizeof(struct array_stack_state) * arrays->num_arrays * __GL_CLIENT_ATTRIB_STACK_DEPTH); + + if (arrays->stack == NULL) { + state->array_state = NULL; + free(arrays->arrays); + free(arrays); + __glXSetError(gc, GL_OUT_OF_MEMORY); + return; + } } @@ -310,7 +319,7 @@ calculate_single_vertex_size_none(const struct array_state_vector *arrays) for (i = 0; i < arrays->num_arrays; i++) { if (arrays->arrays[i].enabled) { - single_vertex_size += ((uint16_t *) arrays->arrays[i].header)[0]; + single_vertex_size += arrays->arrays[i].header[0]; } } @@ -338,17 +347,45 @@ emit_element_none(GLubyte * dst, * 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); + (void) memset(dst, 0, arrays->arrays[i].header[0]); + + (void) memcpy(dst, arrays->arrays[i].header, 4); + + dst += 4; + + if (arrays->arrays[i].key == GL_TEXTURE_COORD_ARRAY && + arrays->arrays[i].index > 0) { + /* Multi-texture coordinate arrays require the texture target + * to be sent. For doubles it is after the data, for everything + * else it is before. + */ + GLenum texture = arrays->arrays[i].index + GL_TEXTURE0; + if (arrays->arrays[i].data_type == GL_DOUBLE) { + (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset, + arrays->arrays[i].element_size); + dst += arrays->arrays[i].element_size; + (void) memcpy(dst, &texture, 4); + dst += 4; + } else { + (void) memcpy(dst, &texture, 4); + dst += 4; + (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset, + arrays->arrays[i].element_size); + dst += __GLX_PAD(arrays->arrays[i].element_size); + } + } else if (arrays->arrays[i].key == GL_VERTEX_ATTRIB_ARRAY_POINTER) { + /* Vertex attribute data requires the index sent first. + */ + (void) memcpy(dst, &arrays->arrays[i].index, 4); + dst += 4; + (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset, + arrays->arrays[i].element_size); + dst += __GLX_PAD(arrays->arrays[i].element_size); + } else { + (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset, + arrays->arrays[i].element_size); + dst += __GLX_PAD(arrays->arrays[i].element_size); + } } } @@ -487,7 +524,7 @@ fill_array_info_cache(struct array_state_vector *arrays) void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -549,7 +586,7 @@ emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count) * A pointer to the buffer for array data. */ static GLubyte * -emit_DrawArrays_header_old(__GLXcontext * gc, +emit_DrawArrays_header_old(struct glx_context * gc, struct array_state_vector *arrays, size_t * elements_per_request, unsigned int *total_requests, @@ -658,7 +695,7 @@ emit_DrawArrays_header_old(__GLXcontext * gc, void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -720,7 +757,7 @@ void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -787,7 +824,7 @@ void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -875,7 +912,7 @@ emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type, * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not. */ static GLboolean -validate_mode(__GLXcontext * gc, GLenum mode) +validate_mode(struct glx_context * gc, GLenum mode) { switch (mode) { case GL_POINTS: @@ -908,7 +945,7 @@ validate_mode(__GLXcontext * gc, GLenum mode) * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. */ static GLboolean -validate_count(__GLXcontext * gc, GLsizei count) +validate_count(struct glx_context * gc, GLsizei count) { if (count < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -927,7 +964,7 @@ validate_count(__GLXcontext * gc, GLsizei count) * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. */ static GLboolean -validate_type(__GLXcontext * gc, GLenum type) +validate_type(struct glx_context * gc, GLenum type) { switch (type) { case GL_UNSIGNED_INT: @@ -944,7 +981,7 @@ validate_type(__GLXcontext * gc, GLenum type) void __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -963,7 +1000,7 @@ __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count) void __indirect_glArrayElement(GLint index) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -989,7 +1026,7 @@ void __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -1011,7 +1048,7 @@ __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -1034,10 +1071,10 @@ __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, void -__indirect_glMultiDrawArraysEXT(GLenum mode, GLint * first, GLsizei * count, - GLsizei primcount) +__indirect_glMultiDrawArrays(GLenum mode, const GLint *first, + const GLsizei *count, GLsizei primcount) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -1060,10 +1097,10 @@ __indirect_glMultiDrawArraysEXT(GLenum mode, GLint * first, GLsizei * count, void __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count, - GLenum type, const GLvoid ** indices, + GLenum type, const GLvoid * const * indices, GLsizei primcount) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -1084,6 +1121,10 @@ __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count, } +/* The HDR_SIZE macro argument is the command header size (4 bytes) + * plus any additional index word e.g. for texture units or vertex + * attributes. + */ #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \ do { \ (a)->data = PTR; \ @@ -1096,9 +1137,8 @@ __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * 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; \ + (a)->header[0] = __GLX_PAD(HDR_SIZE + (a)->element_size); \ + (a)->header[1] = OPCODE; \ } while(0) @@ -1119,7 +1159,7 @@ __indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride, 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv }; uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1164,7 +1204,7 @@ __indirect_glNormalPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1235,7 +1275,7 @@ __indirect_glColorPointer(GLint size, GLenum type, GLsizei stride, 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv }; uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1290,7 +1330,7 @@ void __indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1335,7 +1375,7 @@ __indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) void __indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1371,7 +1411,7 @@ __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, X_GLrop_TexCoord4iv }; static const uint16_t float_ops[5] = { - 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv, + 0, X_GLrop_TexCoord1fv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv, X_GLrop_TexCoord4fv }; static const uint16_t double_ops[5] = { @@ -1388,7 +1428,7 @@ __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB }; static const uint16_t mfloat_ops[5] = { - 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2fvARB, + 0, X_GLrop_MultiTexCoord1fvARB, X_GLrop_MultiTexCoord2fvARB, X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB }; static const uint16_t mdouble_ops[5] = { @@ -1397,7 +1437,7 @@ __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, }; uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1466,11 +1506,11 @@ __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, void -__indirect_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, +__indirect_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1526,11 +1566,11 @@ __indirect_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, void -__indirect_glFogCoordPointerEXT(GLenum type, GLsizei stride, +__indirect_glFogCoordPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1568,16 +1608,25 @@ __indirect_glFogCoordPointerEXT(GLenum type, GLsizei stride, void -__indirect_glVertexAttribPointerARB(GLuint index, GLint size, +__indirect_glVertexAttribPointer(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 }; + static const uint16_t short_ops[5] = { + 0, X_GLrop_VertexAttrib1svARB, X_GLrop_VertexAttrib2svARB, + X_GLrop_VertexAttrib3svARB, X_GLrop_VertexAttrib4svARB + }; + static const uint16_t float_ops[5] = { + 0, X_GLrop_VertexAttrib1fvARB, X_GLrop_VertexAttrib2fvARB, + X_GLrop_VertexAttrib3fvARB, X_GLrop_VertexAttrib4fvARB + }; + static const uint16_t double_ops[5] = { + 0, X_GLrop_VertexAttrib1dvARB, X_GLrop_VertexAttrib2dvARB, + X_GLrop_VertexAttrib3dvARB, X_GLrop_VertexAttrib4dvARB + }; uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1667,8 +1716,7 @@ __indirect_glVertexAttribPointerARB(GLuint index, GLint size, opcode); true_immediate_size = __glXTypeSize(type) * true_immediate_count; - ((uint16_t *) (a)->header)[0] = __GLX_PAD(a->header_size - + true_immediate_size); + a->header[0] = __GLX_PAD(8 + true_immediate_size); if (a->enabled) { arrays->array_info_cache_valid = GL_FALSE; @@ -1690,7 +1738,7 @@ __indirect_glVertexAttribPointerNV(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); GLboolean normalized = GL_FALSE; @@ -1705,7 +1753,7 @@ __indirect_glVertexAttribPointerNV(GLuint index, GLint size, case GL_SHORT: case GL_FLOAT: case GL_DOUBLE: - __indirect_glVertexAttribPointerARB(index, size, type, + __indirect_glVertexAttribPointer(index, size, type, normalized, stride, pointer); return; default: @@ -1716,9 +1764,9 @@ __indirect_glVertexAttribPointerNV(GLuint index, GLint size, void -__indirect_glClientActiveTextureARB(GLenum texture) +__indirect_glClientActiveTexture(GLenum texture) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); __GLXattribute *const state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *const arrays = state->array_state; @@ -1965,13 +2013,13 @@ __glXPopArrayState(__GLXattribute * state) stack[i].user_stride, stack[i].data); break; case GL_SECONDARY_COLOR_ARRAY: - __indirect_glSecondaryColorPointerEXT(stack[i].count, + __indirect_glSecondaryColorPointer(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, + __indirect_glFogCoordPointer(stack[i].data_type, stack[i].user_stride, stack[i].data); break;