From: Keith Whitwell Date: Sun, 29 Oct 2006 09:48:15 +0000 (+0000) Subject: Changes for new vbo-building module. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b1f176039ae3690b38e3ccacb079b3d7c3e50402;p=mesa.git Changes for new vbo-building module. - Removed all the old immediate, array and display list code. - Remove references to the old array_cache module. - Added a _tnl_draw_prims() entrypoint. - Added a simplified data import facility for converting non-floating point data as required. Checkpoint commit - trivial/tri works. --- diff --git a/src/mesa/tnl/sources b/src/mesa/tnl/sources index 2c4f4c49ea4..50f2f3a96d0 100644 --- a/src/mesa/tnl/sources +++ b/src/mesa/tnl/sources @@ -1,12 +1,7 @@ # List of ource files in this directory used for X.org xserver build MESA_TNL_SOURCES = \ -t_array_api.c \ -t_array_import.c \ t_context.c \ t_pipeline.c \ -t_save_api.c \ -t_save_loopback.c \ -t_save_playback.c \ t_vb_arbprogram.c \ t_vb_arbprogram_sse.c \ t_vb_arbshader.c \ @@ -23,9 +18,4 @@ t_vb_vertex.c \ t_vertex.c \ t_vertex_generic.c \ t_vertex_sse.c \ -t_vp_build.c \ -t_vtx_api.c \ -t_vtx_eval.c \ -t_vtx_exec.c \ -t_vtx_generic.c \ -t_vtx_x86.c +t_vp_build.c diff --git a/src/mesa/tnl/t_array_api.c b/src/mesa/tnl/t_array_api.c deleted file mode 100644 index 6826cf7e24c..00000000000 --- a/src/mesa/tnl/t_array_api.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - -/** - * \file t_array_api.c - * \brief Vertex array API functions (glDrawArrays, etc) - * \author Keith Whitwell - */ - -#include "glheader.h" -#include "api_validate.h" -#include "context.h" -#include "imports.h" -#include "macros.h" -#include "mtypes.h" -#include "state.h" - -#include "array_cache/acache.h" - -#include "t_array_api.h" -#include "t_array_import.h" -#include "t_save_api.h" -#include "t_context.h" -#include "t_pipeline.h" -#include "dispatch.h" - -static void fallback_drawarrays( GLcontext *ctx, GLenum mode, GLint start, - GLsizei count ) -{ - GLint i; - - assert(!ctx->CompileFlag); - assert(ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END); - - CALL_Begin(GET_DISPATCH(), (mode)); - for (i = 0; i < count; i++) - CALL_ArrayElement(GET_DISPATCH(), ( start + i )); - CALL_End(GET_DISPATCH(), ()); -} - - -static void fallback_drawelements( GLcontext *ctx, GLenum mode, GLsizei count, - const GLuint *indices) -{ - GLint i; - - assert(!ctx->CompileFlag); - assert(ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END); - - /* Here, indices will already reflect the buffer object if active */ - - CALL_Begin(GET_DISPATCH(), (mode)); - for (i = 0 ; i < count ; i++) { - CALL_ArrayElement(GET_DISPATCH(), ( indices[i] )); - } - CALL_End(GET_DISPATCH(), ()); -} - - -/* Note this function no longer takes a 'start' value, the range is - * assumed to start at zero. The old trick of subtracting 'start' - * from each index won't work if the indices are not in writeable - * memory. - */ -static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode, - GLuint max_index, - GLsizei index_count, GLuint *indices ) - -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_prim prim; - FLUSH_CURRENT( ctx, 0 ); - - _tnl_vb_bind_arrays( ctx, 0, max_index ); - - tnl->vb.Primitive = &prim; - tnl->vb.Primitive[0].mode = mode | PRIM_BEGIN | PRIM_END; - tnl->vb.Primitive[0].start = 0; - tnl->vb.Primitive[0].count = index_count; - tnl->vb.PrimitiveCount = 1; - - tnl->vb.Elts = (GLuint *)indices; - - tnl->Driver.RunPipeline( ctx ); -} - - - -/** - * Called via the GL API dispatcher. - */ -void GLAPIENTRY -_tnl_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - /* It's tempting to get rid of this threshold value because we take - * very different paths if 'count' is less than or greater than 'thresh'. - * I've found/fixed at least one bug which only occured for particular - * array sizes. Also, several conformance tests use very short arrays - * which means the long-array path doesn't get tested. -Brian - */ - GLuint thresh = (ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES) ? 30 : 10; - - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(NULL, "_tnl_DrawArrays %d %d\n", start, count); - - /* Check arguments, etc. - */ - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - assert(!ctx->CompileFlag); - - if (!ctx->Array.LockCount && (GLuint) count < thresh) { - /* Small primitives: attempt to share a vb (at the expense of - * using the immediate interface). - */ - fallback_drawarrays( ctx, mode, start, count ); - } - else if (start >= (GLint) ctx->Array.LockFirst && - start + count <= (GLint)(ctx->Array.LockFirst + ctx->Array.LockCount)) { - - struct tnl_prim prim; - - /* Locked primitives which can fit in a single vertex buffer: - */ - FLUSH_CURRENT( ctx, 0 ); - - /* Locked drawarrays. Reuse any previously transformed data. - */ - _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, - ctx->Array.LockFirst + ctx->Array.LockCount ); - - tnl->vb.Primitive = &prim; - tnl->vb.Primitive[0].mode = mode | PRIM_BEGIN | PRIM_END; - tnl->vb.Primitive[0].start = start; - tnl->vb.Primitive[0].count = count; - tnl->vb.PrimitiveCount = 1; - - tnl->Driver.RunPipeline( ctx ); - } - else { - int bufsz = 256; /* Use a small buffer for cache goodness */ - int j, nr; - int minimum, modulo, skip; - - /* Large primitives requiring decomposition to multiple vertex - * buffers: - */ - switch (mode) { - case GL_POINTS: - minimum = 0; - modulo = 1; - skip = 0; - break; - case GL_LINES: - minimum = 1; - modulo = 2; - skip = 1; - break; - case GL_LINE_STRIP: - minimum = 1; - modulo = 1; - skip = 0; - break; - case GL_TRIANGLES: - minimum = 2; - modulo = 3; - skip = 2; - break; - case GL_TRIANGLE_STRIP: - minimum = 2; - modulo = 1; - skip = 0; - break; - case GL_QUADS: - minimum = 3; - modulo = 4; - skip = 3; - break; - case GL_QUAD_STRIP: - minimum = 3; - modulo = 2; - skip = 0; - break; - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - default: - /* Primitives requiring a copied vertex (fan-like primitives) - * must use the slow path if they cannot fit in a single - * vertex buffer. - */ - if (count <= (GLint) ctx->Const.MaxArrayLockSize) { - bufsz = ctx->Const.MaxArrayLockSize; - minimum = 0; - modulo = 1; - skip = 0; - } - else { - fallback_drawarrays( ctx, mode, start, count ); - return; - } - } - - FLUSH_CURRENT( ctx, 0 ); - - bufsz -= bufsz % modulo; - bufsz -= minimum; - count += start; - - for (j = start + minimum ; j < count ; j += nr + skip ) { - - struct tnl_prim prim; - - nr = MIN2( bufsz, count - j ); - - /* XXX is the last parameter a count or index into the array??? */ - _tnl_vb_bind_arrays( ctx, j - minimum, j + nr ); - - tnl->vb.Primitive = &prim; - tnl->vb.Primitive[0].mode = mode; - - if (j == start + minimum) - tnl->vb.Primitive[0].mode |= PRIM_BEGIN; - - if (j + nr + skip >= count) - tnl->vb.Primitive[0].mode |= PRIM_END; - - tnl->vb.Primitive[0].start = 0; - tnl->vb.Primitive[0].count = nr + minimum; - tnl->vb.PrimitiveCount = 1; - - tnl->Driver.RunPipeline( ctx ); - } - } -} - - -/** - * Called via the GL API dispatcher. - */ -void GLAPIENTRY -_tnl_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint *ui_indices; - - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(NULL, "_tnl_DrawRangeElements %d %d %d\n", start, end, count); - - if (ctx->Array.ElementArrayBufferObj->Name) { - /* use indices in the buffer object */ - if (!ctx->Array.ElementArrayBufferObj->Data) { - _mesa_warning(ctx, - "DrawRangeElements with empty vertex elements buffer!"); - return; - } - /* actual address is the sum of pointers */ - indices = (const GLvoid *) - ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, - (const GLubyte *) indices); - } - - /* Check arguments, etc. - */ - if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, - type, indices )) - return; - - ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT, - count, type, indices ); - -#ifdef DEBUG - /* check that array indices really fall inside [start, end] range */ - { - GLuint i; - for (i = 0; i < count; i++) { - if (ui_indices[i] < start || ui_indices[i] > end) { - _mesa_warning(ctx, "Invalid array index in " - "glDrawRangeElements(index=%u)", ui_indices[i]); - } - } - } -#endif - - assert(!ctx->CompileFlag); - - if (ctx->Array.LockCount) { - /* Are the arrays already locked? If so we currently have to look - * at the whole locked range. - */ - - if (start == 0 && ctx->Array.LockFirst == 0 && - end < (ctx->Array.LockFirst + ctx->Array.LockCount)) - _tnl_draw_range_elements( ctx, mode, - ctx->Array.LockCount, - count, ui_indices ); - else { - fallback_drawelements( ctx, mode, count, ui_indices ); - } - } - else if (start == 0 && end < ctx->Const.MaxArrayLockSize) { - /* The arrays aren't locked but we can still fit them inside a - * single vertexbuffer. - */ - _tnl_draw_range_elements( ctx, mode, end + 1, count, ui_indices ); - } - else { - /* Range is too big to optimize: - */ - fallback_drawelements( ctx, mode, count, ui_indices ); - } -} - - - -/** - * Called via the GL API dispatcher. - */ -void GLAPIENTRY -_tnl_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint *ui_indices; - - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(NULL, "_tnl_DrawElements %d\n", count); - - /* Check arguments, etc. */ - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - if (ctx->Array.ElementArrayBufferObj->Name) { - /* actual address is the sum of pointers */ - indices = (const GLvoid *) - ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, - (const GLubyte *) indices); - } - - ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT, - count, type, indices ); - - assert(!ctx->CompileFlag); - - if (ctx->Array.LockCount) { - if (ctx->Array.LockFirst == 0) - _tnl_draw_range_elements( ctx, mode, - ctx->Array.LockCount, - count, ui_indices ); - else - fallback_drawelements( ctx, mode, count, ui_indices ); - } - else { - /* Scan the index list and see if we can use the locked path anyway. - */ - GLuint max_elt = 0; - GLint i; - - for (i = 0 ; i < count ; i++) - if (ui_indices[i] > max_elt) - max_elt = ui_indices[i]; - - if (max_elt < ctx->Const.MaxArrayLockSize && /* can we use it? */ - max_elt < (GLuint) count) /* do we want to use it? */ - _tnl_draw_range_elements( ctx, mode, max_elt+1, count, ui_indices ); - else - fallback_drawelements( ctx, mode, count, ui_indices ); - } -} - - -/** - * Initialize context's vertex array fields. Called during T 'n L context - * creation. - */ -void _tnl_array_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_arrays *tmp = &tnl->array_inputs; - GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt); - GLuint i; - - vfmt->DrawArrays = _tnl_DrawArrays; - vfmt->DrawElements = _tnl_DrawElements; - vfmt->DrawRangeElements = _tnl_DrawRangeElements; - - /* Setup vector pointers that will be used to bind arrays to VB's. - */ - _mesa_vector4f_init( &tmp->Obj, 0, NULL); - _mesa_vector4f_init( &tmp->Normal, 0, NULL); - _mesa_vector4f_init( &tmp->FogCoord, 0, NULL); - _mesa_vector4f_init( &tmp->Index, 0, NULL); - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) - _mesa_vector4f_init( &tmp->TexCoord[i], 0, NULL); -} - - -/** - * Destroy the context's vertex array stuff. - * Called during T 'n L context destruction. - */ -void _tnl_array_destroy( GLcontext *ctx ) -{ - (void) ctx; -} diff --git a/src/mesa/tnl/t_array_api.h b/src/mesa/tnl/t_array_api.h deleted file mode 100644 index 61d1f696b00..00000000000 --- a/src/mesa/tnl/t_array_api.h +++ /dev/null @@ -1,46 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - -#ifndef _T_VARRAY_H -#define _T_VARRAY_H - -#include "mtypes.h" -#include "t_context.h" - - -extern void GLAPIENTRY _tnl_DrawArrays(GLenum mode, GLint first, GLsizei count); - -extern void GLAPIENTRY _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices); - -extern void GLAPIENTRY _tnl_DrawRangeElements(GLenum mode, GLuint start, - GLuint end, GLsizei count, GLenum type, - const GLvoid *indices); - - -extern void _tnl_array_init( GLcontext *ctx ); -extern void _tnl_array_destroy( GLcontext *ctx ); - -#endif diff --git a/src/mesa/tnl/t_array_import.c b/src/mesa/tnl/t_array_import.c deleted file mode 100644 index 13c5689ceb9..00000000000 --- a/src/mesa/tnl/t_array_import.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - * - * Authors: - * Keith Whitwell - */ - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "imports.h" -#include "state.h" -#include "mtypes.h" - -#include "array_cache/acache.h" - -#include "t_array_import.h" -#include "t_context.h" - - -/** - * XXX writable and stride are always false in these functions... - */ -static void _tnl_import_vertex( GLcontext *ctx, - GLboolean writable, - GLboolean stride ) -{ - struct gl_client_array *tmp; - GLboolean is_writable = 0; - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - const GLubyte *data; - - tmp = _ac_import_vertex(ctx, - GL_FLOAT, - stride ? 4*sizeof(GLfloat) : 0, - 0, - writable, - &is_writable); - - data = tmp->Ptr; - inputs->Obj.data = (GLfloat (*)[4]) data; - inputs->Obj.start = (GLfloat *) data; - inputs->Obj.stride = tmp->StrideB; - inputs->Obj.size = tmp->Size; -} - -static void _tnl_import_normal( GLcontext *ctx, - GLboolean writable, - GLboolean stride ) -{ - struct gl_client_array *tmp; - GLboolean is_writable = 0; - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - const GLubyte *data; - - tmp = _ac_import_normal(ctx, GL_FLOAT, - stride ? 3*sizeof(GLfloat) : 0, writable, - &is_writable); - - data = tmp->Ptr; - inputs->Normal.data = (GLfloat (*)[4]) data; - inputs->Normal.start = (GLfloat *) data; - inputs->Normal.stride = tmp->StrideB; - inputs->Normal.size = 3; -} - - -static void _tnl_import_color( GLcontext *ctx, - GLboolean writable, - GLboolean stride ) -{ - struct gl_client_array *tmp; - GLboolean is_writable = 0; - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - const GLubyte *data; - - tmp = _ac_import_color(ctx, - GL_FLOAT, - stride ? 4*sizeof(GLfloat) : 0, - 4, - writable, - &is_writable); - - data = tmp->Ptr; - inputs->Color.data = (GLfloat (*)[4]) data; - inputs->Color.start = (GLfloat *) data; - inputs->Color.stride = tmp->StrideB; - inputs->Color.size = tmp->Size; -} - - -static void _tnl_import_secondarycolor( GLcontext *ctx, - GLboolean writable, - GLboolean stride ) -{ - struct gl_client_array *tmp; - GLboolean is_writable = 0; - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - const GLubyte *data; - - tmp = _ac_import_secondarycolor(ctx, - GL_FLOAT, - stride ? 4*sizeof(GLfloat) : 0, - 4, - writable, - &is_writable); - - data = tmp->Ptr; - inputs->SecondaryColor.data = (GLfloat (*)[4]) data; - inputs->SecondaryColor.start = (GLfloat *) data; - inputs->SecondaryColor.stride = tmp->StrideB; - inputs->SecondaryColor.size = tmp->Size; -} - -static void _tnl_import_fogcoord( GLcontext *ctx, - GLboolean writable, - GLboolean stride ) -{ - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - struct gl_client_array *tmp; - GLboolean is_writable = 0; - const GLubyte *data; - - tmp = _ac_import_fogcoord(ctx, GL_FLOAT, - stride ? sizeof(GLfloat) : 0, writable, - &is_writable); - - data = tmp->Ptr; - inputs->FogCoord.data = (GLfloat (*)[4]) data; - inputs->FogCoord.start = (GLfloat *) data; - inputs->FogCoord.stride = tmp->StrideB; -} - -static void _tnl_import_index( GLcontext *ctx, - GLboolean writable, - GLboolean stride ) -{ - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - struct gl_client_array *tmp; - GLboolean is_writable = 0; - const GLubyte *data; - - tmp = _ac_import_index(ctx, GL_FLOAT, - stride ? sizeof(GLfloat) : 0, writable, - &is_writable); - - data = tmp->Ptr; - inputs->Index.data = (GLfloat (*)[4]) data; - inputs->Index.start = (GLfloat *) data; - inputs->Index.stride = tmp->StrideB; -} - - -static void _tnl_import_texcoord( GLcontext *ctx, - GLuint unit, - GLboolean writable, - GLboolean stride ) -{ - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - struct gl_client_array *tmp; - GLboolean is_writable = 0; - const GLubyte *data; - - tmp = _ac_import_texcoord(ctx, unit, GL_FLOAT, - stride ? 4 * sizeof(GLfloat) : 0, - 0, - writable, - &is_writable); - - data = tmp->Ptr; - inputs->TexCoord[unit].data = (GLfloat (*)[4]) data; - inputs->TexCoord[unit].start = (GLfloat *) data; - inputs->TexCoord[unit].stride = tmp->StrideB; - inputs->TexCoord[unit].size = tmp->Size; -} - - -static void _tnl_import_edgeflag( GLcontext *ctx, - GLboolean writable, - GLboolean stride ) -{ - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - struct gl_client_array *tmp; - GLboolean is_writable = 0; - const GLubyte *data; - (void) writable; (void) stride; - - tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE, - sizeof(GLubyte), - 0, - &is_writable); - - data = tmp->Ptr; - inputs->EdgeFlag = (GLubyte *) data; -} - - - -static void _tnl_import_attrib( GLcontext *ctx, - GLuint index, - GLboolean writable, - GLboolean stride ) -{ - struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; - struct gl_client_array *tmp; - GLboolean is_writable = 0; - const GLubyte *data; - - ASSERT(index < MAX_VERTEX_PROGRAM_ATTRIBS); - - tmp = _ac_import_attrib(ctx, index, GL_FLOAT, - stride ? 4 * sizeof(GLfloat) : 0, - 4, /* want GLfloat[4] */ - writable, - &is_writable); - - data = tmp->Ptr; - inputs->Attribs[index].data = (GLfloat (*)[4]) data; - inputs->Attribs[index].start = (GLfloat *) data; - inputs->Attribs[index].stride = tmp->StrideB; - inputs->Attribs[index].size = tmp->Size; -} - - -static void _tnl_constant_attrib( TNLcontext *tnl, - struct tnl_vertex_arrays *tmp, - GLuint i ) -{ - tmp->Attribs[i].count = 1; - tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i]; - tmp->Attribs[i].start = tnl->vtx.current[i]; - tmp->Attribs[i].size = 4; - tmp->Attribs[i].stride = 0; - tnl->vb.AttribPtr[i] = &tmp->Attribs[i]; -} - - - -void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - struct tnl_vertex_arrays *tmp = &tnl->array_inputs; - const struct gl_vertex_program *program - = ctx->VertexProgram._Enabled ? ctx->VertexProgram.Current : NULL; - GLuint i, index; - - VB->Count = end - start; - VB->Elts = NULL; - - _ac_import_range( ctx, start, end ); - - /* Note that the generic attribute arrays are treated differently - * depending on whether an NV or ARB vertex program is enabled - * (corresponding to aliasing vs. non-aliasing behaviour). - * Generic array 0 always aliases vertex position. - */ - for (index = 0; index < VERT_ATTRIB_MAX; index++) { - if (ctx->VertexProgram._Enabled - && (program->IsNVProgram || index == 0) - && ctx->Array.ArrayObj->VertexAttrib[index].Enabled) { - /* Use generic attribute array. If an NV vertex program is active, - * the generic arrays override the conventional attributes. - * Otherwise, if an ARB vertex program is active, we'll import the - * generic attributes without aliasing over conventional attribs - * (see below). - */ - _tnl_import_attrib( ctx, index, GL_FALSE, GL_TRUE ); - VB->AttribPtr[index] = &tmp->Attribs[index]; - } - /* use conventional arrays... */ - else if (index == VERT_ATTRIB_POS) { - _tnl_import_vertex( ctx, GL_FALSE, GL_FALSE ); - tmp->Obj.count = VB->Count; - VB->AttribPtr[_TNL_ATTRIB_POS] = &tmp->Obj; - } - else if (index == VERT_ATTRIB_NORMAL) { - _tnl_import_normal( ctx, GL_FALSE, GL_FALSE ); - tmp->Normal.count = VB->Count; - VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &tmp->Normal; - } - else if (index == VERT_ATTRIB_COLOR0) { - _tnl_import_color( ctx, GL_FALSE, GL_FALSE ); - tmp->Color.count = VB->Count; - VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &tmp->Color; - } - else if (index == VERT_ATTRIB_COLOR1) { - _tnl_import_secondarycolor( ctx, GL_FALSE, GL_FALSE ); - tmp->SecondaryColor.count = VB->Count; - VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &tmp->SecondaryColor; - } - else if (index == VERT_ATTRIB_FOG) { - _tnl_import_fogcoord( ctx, GL_FALSE, GL_FALSE ); - tmp->FogCoord.count = VB->Count; - VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord; - } - else if (index == VERT_ATTRIB_COLOR_INDEX) { - _tnl_import_index( ctx, GL_FALSE, GL_FALSE ); - tmp->Index.count = VB->Count; - VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX] = &tmp->Index; - } - else if (index >= VERT_ATTRIB_TEX0 && index <= VERT_ATTRIB_TEX7) { - i = index - VERT_ATTRIB_TEX0; - _tnl_import_texcoord( ctx, i, GL_FALSE, GL_FALSE ); - tmp->TexCoord[i].count = VB->Count; - VB->AttribPtr[index] = &tmp->TexCoord[i]; - } - else if (index >= VERT_ATTRIB_GENERIC1 && - index <= VERT_ATTRIB_GENERIC15) { - const GLuint arrayIndex = index - VERT_ATTRIB_GENERIC0; - if (program && !program->IsNVProgram && - ctx->Array.ArrayObj->VertexAttrib[arrayIndex].Enabled) { - /* GL_ARB_vertex_program: bind a generic attribute array */ - _tnl_import_attrib(ctx, arrayIndex, GL_FALSE, GL_TRUE); - VB->AttribPtr[index] = &tmp->Attribs[arrayIndex]; - } - else { - _tnl_constant_attrib(tnl, tmp, index); - } - } - else { - _tnl_constant_attrib(tnl, tmp, index); - } - assert(VB->AttribPtr[index]); - assert(VB->AttribPtr[index]->size); - } - - /* odd-ball vertex attributes */ - { - _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) ); - VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag; - } - - /* These are constant & could be precalculated: - */ - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - _tnl_constant_attrib(tnl, tmp, i); - } - - - /* Legacy pointers -- remove one day. - */ - VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS]; - VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; - VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0]; - VB->ColorPtr[1] = NULL; - VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX]; - VB->IndexPtr[1] = NULL; - VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1]; - VB->SecondaryColorPtr[1] = NULL; - VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG]; - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]; - } -} diff --git a/src/mesa/tnl/t_array_import.h b/src/mesa/tnl/t_array_import.h deleted file mode 100644 index 39b77641d53..00000000000 --- a/src/mesa/tnl/t_array_import.h +++ /dev/null @@ -1,36 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - -#ifndef _T_ARRAY_IMPORT_H -#define _T_ARRAY_IMPORT_H - -#include "mtypes.h" -#include "t_context.h" - -extern void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end ); - -extern void _tnl_array_import_init( GLcontext *ctx ); - -#endif diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index 55b40c0531f..ff05ac03181 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 6.5 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -26,38 +26,19 @@ */ -#include "api_arrayelt.h" #include "glheader.h" #include "imports.h" #include "context.h" #include "macros.h" #include "mtypes.h" -#include "dlist.h" #include "light.h" -#include "vtxfmt.h" #include "tnl.h" -#include "t_array_api.h" #include "t_context.h" #include "t_pipeline.h" -#include "t_save_api.h" #include "t_vp_build.h" -#include "t_vtx_api.h" - - - -static void -install_driver_callbacks( GLcontext *ctx ) -{ - ctx->Driver.NewList = _tnl_NewList; - ctx->Driver.EndList = _tnl_EndList; - ctx->Driver.FlushVertices = _tnl_FlushVertices; - ctx->Driver.SaveFlushVertices = _tnl_SaveFlushVertices; - ctx->Driver.BeginCallList = _tnl_BeginCallList; - ctx->Driver.EndCallList = _tnl_EndCallList; -} - +#include "vbo/vbo_attrib.h" GLboolean _tnl_CreateContext( GLcontext *ctx ) @@ -72,20 +53,13 @@ _tnl_CreateContext( GLcontext *ctx ) return GL_FALSE; } - if (_mesa_getenv("MESA_CODEGEN")) - tnl->AllowCodegen = GL_TRUE; - /* Initialize the VB. */ tnl->vb.Size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES; - /* Initialize tnl state and tnl->vtxfmt. + /* Initialize tnl state. */ - _tnl_save_init( ctx ); - _tnl_array_init( ctx ); - _tnl_vtx_init( ctx ); - if (ctx->_MaintainTnlProgram) { _tnl_ProgramCacheInit( ctx ); _tnl_install_pipeline( ctx, _tnl_vp_pipeline ); @@ -93,30 +67,12 @@ _tnl_CreateContext( GLcontext *ctx ) _tnl_install_pipeline( ctx, _tnl_default_pipeline ); } - /* Initialize the arrayelt helper - */ - if (!_ae_create_context( ctx )) - return GL_FALSE; - - tnl->NeedNdcCoords = GL_TRUE; - tnl->LoopbackDListCassettes = GL_FALSE; - tnl->CalcDListNormalLengths = GL_TRUE; tnl->AllowVertexFog = GL_TRUE; tnl->AllowPixelFog = GL_TRUE; - /* Hook our functions into exec and compile dispatch tables. - */ - _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt ); - - /* Set a few default values in the driver struct. */ - install_driver_callbacks(ctx); - ctx->Driver.NeedFlush = 0; - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; - tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables; @@ -130,11 +86,7 @@ _tnl_DestroyContext( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - _tnl_array_destroy( ctx ); - _tnl_vtx_destroy( ctx ); - _tnl_save_destroy( ctx ); _tnl_destroy_pipeline( ctx ); - _ae_destroy_context( ctx ); if (ctx->_MaintainTnlProgram) _tnl_ProgramCacheDestroy( ctx ); @@ -155,10 +107,7 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) || !tnl->AllowPixelFog; } - _ae_invalidate_state(ctx, new_state); - tnl->pipeline.new_state |= new_state; - tnl->vtx.eval.new_state |= new_state; /* Calculate tnl->render_inputs: */ @@ -184,8 +133,7 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) if (ctx->Fog.Enabled || (ctx->FragmentProgram._Active && - (ctx->FragmentProgram._Current->FogOption != GL_NONE || - ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_FOGC))) + ctx->FragmentProgram._Current->FogOption != GL_NONE)) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); if (ctx->Polygon.FrontMode != GL_FILL || @@ -205,36 +153,21 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) void -_tnl_wakeup_exec( GLcontext *ctx ) +_tnl_wakeup( GLcontext *ctx ) { - TNLcontext *tnl = TNL_CONTEXT(ctx); - - install_driver_callbacks(ctx); - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; - - /* Hook our functions into exec and compile dispatch tables. - */ - _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt ); - /* Assume we haven't been getting state updates either: */ _tnl_InvalidateState( ctx, ~0 ); +#if 0 if (ctx->Light.ColorMaterialEnabled) { _mesa_update_color_material( ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); } +#endif } -void -_tnl_wakeup_save_exec( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - _tnl_wakeup_exec( ctx ); - _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt ); -} /** @@ -252,27 +185,6 @@ _tnl_need_projected_coords( GLcontext *ctx, GLboolean mode ) } } -void -_tnl_need_dlist_loopback( GLcontext *ctx, GLboolean mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->LoopbackDListCassettes = mode; -} - -void -_tnl_need_dlist_norm_lengths( GLcontext *ctx, GLboolean mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->CalcDListNormalLengths = mode; -} - -void -_tnl_isolate_materials( GLcontext *ctx, GLboolean mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->IsolateMaterials = mode; -} - void _tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value ) { diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index d5414bd730d..28d1b7faabe 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -43,29 +43,6 @@ * stages to the vertex_buffer TNLcontext::vb, where the vertex data * is stored. The last stage in the pipeline is the rasterizer. * - * The initial vertex_buffer data may either come from an ::immediate - * structure or client vertex_arrays or display lists: - * - * - * - The ::immediate structure records all the GL commands issued between - * glBegin and glEnd. \n - * The structure accumulates data, until it is either full or it is - * flushed (usually by a state change). Before starting then the pipeline, - * the collected vertex data in ::immediate has to be pushed into - * TNLcontext::vb. - * This happens in ::_tnl_vb_bind_immediate. The pipeline is then run by - * calling tnl_device_driver::RunPipeline = ::_tnl_run_pipeline, which - * is stored in TNLcontext::Driver. \n - * An ::immediate does (for performance reasons) usually not finish with a - * glEnd, and hence it also does not need to start with a glBegin. - * This means that the last vertices of one ::immediate may need to be - * saved for the next one. - * - * - * - NOT SURE ABOUT THIS: The vertex_arrays structure is used to handle - * glDrawArrays etc. \n - * Here, the data of the vertex_arrays is copied by ::_tnl_vb_bind_arrays - * into TNLcontext::vb, so that the pipeline can be started. */ @@ -79,6 +56,7 @@ #include "math/m_vector.h" #include "math/m_xform.h" +#include "vbo/vbo_attrib.h" #define MAX_PIPELINE_STAGES 30 @@ -106,7 +84,7 @@ enum { _TNL_ATTRIB_COLOR1 = 4, _TNL_ATTRIB_FOG = 5, _TNL_ATTRIB_COLOR_INDEX = 6, - _TNL_ATTRIB_SEVEN = 7, + _TNL_ATTRIB_EDGEFLAG = 7, _TNL_ATTRIB_TEX0 = 8, _TNL_ATTRIB_TEX1 = 9, _TNL_ATTRIB_TEX2 = 10, @@ -115,7 +93,8 @@ enum { _TNL_ATTRIB_TEX5 = 13, _TNL_ATTRIB_TEX6 = 14, _TNL_ATTRIB_TEX7 = 15, - _TNL_ATTRIB_GENERIC0 = 16, + + _TNL_ATTRIB_GENERIC0 = 16, /* doesn't really exist! */ _TNL_ATTRIB_GENERIC1 = 17, _TNL_ATTRIB_GENERIC2 = 18, _TNL_ATTRIB_GENERIC3 = 19, @@ -131,21 +110,36 @@ enum { _TNL_ATTRIB_GENERIC13 = 29, _TNL_ATTRIB_GENERIC14 = 30, _TNL_ATTRIB_GENERIC15 = 31, - _TNL_ATTRIB_MAT_FRONT_AMBIENT = 32, - _TNL_ATTRIB_MAT_BACK_AMBIENT = 33, - _TNL_ATTRIB_MAT_FRONT_DIFFUSE = 34, - _TNL_ATTRIB_MAT_BACK_DIFFUSE = 35, - _TNL_ATTRIB_MAT_FRONT_SPECULAR = 36, - _TNL_ATTRIB_MAT_BACK_SPECULAR = 37, - _TNL_ATTRIB_MAT_FRONT_EMISSION = 38, - _TNL_ATTRIB_MAT_BACK_EMISSION = 39, - _TNL_ATTRIB_MAT_FRONT_SHININESS = 40, - _TNL_ATTRIB_MAT_BACK_SHININESS = 41, - _TNL_ATTRIB_MAT_FRONT_INDEXES = 42, - _TNL_ATTRIB_MAT_BACK_INDEXES = 43, - _TNL_ATTRIB_EDGEFLAG = 44, - _TNL_ATTRIB_POINTSIZE = 45, - _TNL_ATTRIB_MAX = 46 + + /* These alias with the generics, but they are not active + * concurrently, so it's not a problem. The TNL module + * doesn't have to do anything about this as this is how they + * are passed into the _draw_prims callback. + * + * When we generate fixed-function replacement programs (in + * t_vp_build.c currently), they refer to the appropriate + * generic attribute in order to pick up per-vertex material + * data. + */ + _TNL_ATTRIB_MAT_FRONT_AMBIENT = 16, + _TNL_ATTRIB_MAT_BACK_AMBIENT = 17, + _TNL_ATTRIB_MAT_FRONT_DIFFUSE = 18, + _TNL_ATTRIB_MAT_BACK_DIFFUSE = 19, + _TNL_ATTRIB_MAT_FRONT_SPECULAR = 20, + _TNL_ATTRIB_MAT_BACK_SPECULAR = 21, + _TNL_ATTRIB_MAT_FRONT_EMISSION = 22, + _TNL_ATTRIB_MAT_BACK_EMISSION = 23, + _TNL_ATTRIB_MAT_FRONT_SHININESS = 24, + _TNL_ATTRIB_MAT_BACK_SHININESS = 25, + _TNL_ATTRIB_MAT_FRONT_INDEXES = 26, + _TNL_ATTRIB_MAT_BACK_INDEXES = 27, + + /* This is really a VERT_RESULT, not an attrib. Need to fix + * tnl to understand the difference. + */ + _TNL_ATTRIB_POINTSIZE = 16, + + _TNL_ATTRIB_MAX = 32 } ; #define _TNL_ATTRIB_TEX(u) (_TNL_ATTRIB_TEX0 + (u)) @@ -166,8 +160,8 @@ enum { #define _TNL_FIRST_GENERIC _TNL_ATTRIB_GENERIC0 #define _TNL_LAST_GENERIC _TNL_ATTRIB_GENERIC15 -#define _TNL_FIRST_MAT _TNL_ATTRIB_MAT_FRONT_AMBIENT -#define _TNL_LAST_MAT _TNL_ATTRIB_MAT_BACK_INDEXES +#define _TNL_FIRST_MAT _TNL_ATTRIB_MAT_FRONT_AMBIENT /* GENERIC0 */ +#define _TNL_LAST_MAT _TNL_ATTRIB_MAT_BACK_INDEXES /* GENERIC11 */ /* Number of available generic attributes */ #define _TNL_NUM_GENERIC 16 @@ -175,221 +169,22 @@ enum { /* Number of attributes used for evaluators */ #define _TNL_NUM_EVAL 16 + #define PRIM_BEGIN 0x10 #define PRIM_END 0x20 -#define PRIM_WEAK 0x40 #define PRIM_MODE_MASK 0x0f -/* - */ -struct tnl_prim { - GLuint mode; - GLuint start; - GLuint count; -}; - - - -struct tnl_eval1_map { - struct gl_1d_map *map; - GLuint sz; -}; - -struct tnl_eval2_map { - struct gl_2d_map *map; - GLuint sz; -}; - -struct tnl_eval { - GLuint new_state; - struct tnl_eval1_map map1[_TNL_NUM_EVAL]; - struct tnl_eval2_map map2[_TNL_NUM_EVAL]; -}; - - -#define TNL_MAX_PRIM 16 -#define TNL_MAX_COPIED_VERTS 3 - -struct tnl_copied_vtx { - GLfloat buffer[_TNL_ATTRIB_MAX * 4 * TNL_MAX_COPIED_VERTS]; - GLuint nr; -}; - -#define VERT_BUFFER_SIZE 2048 /* 8kbytes */ - - -typedef void (*tnl_attrfv_func)( const GLfloat * ); - -struct _tnl_dynfn { - struct _tnl_dynfn *next, *prev; - GLuint key; - char *code; -}; - -struct _tnl_dynfn_lists { - struct _tnl_dynfn Vertex[4]; - struct _tnl_dynfn Attribute[4]; -}; - -struct _tnl_dynfn_generators { - struct _tnl_dynfn *(*Vertex[4])( GLcontext *ctx, int key ); - struct _tnl_dynfn *(*Attribute[4])( GLcontext *ctx, int key ); -}; - -#define _TNL_MAX_ATTR_CODEGEN 32 - - -/** - * The assembly of vertices in immediate mode is separated from - * display list compilation. This allows a simpler immediate mode - * treatment and a display list compiler better suited to - * hardware-acceleration. - */ -struct tnl_vtx { - GLfloat buffer[VERT_BUFFER_SIZE]; - GLubyte attrsz[_TNL_ATTRIB_MAX]; - GLubyte active_sz[_TNL_ATTRIB_MAX]; - GLuint vertex_size; - struct tnl_prim prim[TNL_MAX_PRIM]; - GLuint prim_count; - GLfloat *vbptr; /* cursor, points into buffer */ - GLfloat vertex[_TNL_ATTRIB_MAX*4]; /* current vertex */ - GLfloat *attrptr[_TNL_ATTRIB_MAX]; /* points into vertex */ - GLfloat *current[_TNL_ATTRIB_MAX]; /* points into ctx->Current, etc */ - GLfloat CurrentFloatEdgeFlag; - GLuint counter, initial_counter; - struct tnl_copied_vtx copied; - - /** Note extra space for error handler: */ - tnl_attrfv_func tabfv[_TNL_ATTRIB_ERROR+1][4]; - - struct _tnl_dynfn_lists cache; - struct _tnl_dynfn_generators gen; - - struct tnl_eval eval; - GLboolean *edgeflag_tmp; - GLboolean have_materials; -}; - - - - -/* For display lists, this structure holds a run of vertices of the - * same format, and a strictly well-formed set of begin/end pairs, - * starting on the first vertex and ending at the last. Vertex - * copying on buffer breaks is precomputed according to these - * primitives, though there are situations where the copying will need - * correction at execute-time, perhaps by replaying the list as - * immediate mode commands. - * - * On executing this list, the 'current' values may be updated with - * the values of the final vertex, and often no fixup of the start of - * the vertex list is required. - * - * Eval and other commands that don't fit into these vertex lists are - * compiled using the fallback opcode mechanism provided by dlist.c. - */ -struct tnl_vertex_list { - GLubyte attrsz[_TNL_ATTRIB_MAX]; - GLuint vertex_size; - - GLfloat *buffer; - GLuint count; - GLuint wrap_count; /* number of copied vertices at start */ - GLboolean have_materials; /* bit of a hack - quick check for materials */ - GLboolean dangling_attr_ref; /* current attr implicitly referenced - outside the list */ - - GLfloat *normal_lengths; - struct tnl_prim *prim; - GLuint prim_count; - - struct tnl_vertex_store *vertex_store; - struct tnl_primitive_store *prim_store; -}; - -/* These buffers should be a reasonable size to support upload to - * hardware? Maybe drivers should stitch them back together, or - * specify a desired size? - */ -#define SAVE_BUFFER_SIZE (16*1024) -#define SAVE_PRIM_SIZE 128 - -/* Storage to be shared among several vertex_lists. - */ -struct tnl_vertex_store { - GLfloat buffer[SAVE_BUFFER_SIZE]; - GLuint used; - GLuint refcount; -}; - -struct tnl_primitive_store { - struct tnl_prim buffer[SAVE_PRIM_SIZE]; - GLuint used; - GLuint refcount; -}; - - -struct tnl_save { - GLubyte attrsz[_TNL_ATTRIB_MAX]; - GLuint vertex_size; - - GLfloat *buffer; - GLuint count; - GLuint wrap_count; - GLuint replay_flags; - - struct tnl_prim *prim; - GLuint prim_count, prim_max; - - struct tnl_vertex_store *vertex_store; - struct tnl_primitive_store *prim_store; - - GLfloat *vbptr; /* cursor, points into buffer */ - GLfloat vertex[_TNL_ATTRIB_MAX*4]; /* current values */ - GLfloat *attrptr[_TNL_ATTRIB_MAX]; - GLuint counter, initial_counter; - GLboolean dangling_attr_ref; - GLboolean have_materials; - - GLuint opcode_vertex_list; - - struct tnl_copied_vtx copied; - - GLfloat CurrentFloatEdgeFlag; - - GLfloat *current[_TNL_ATTRIB_MAX]; /* points into ctx->ListState */ - GLubyte *currentsz[_TNL_ATTRIB_MAX]; +static INLINE GLuint _tnl_translate_prim( const struct _mesa_prim *prim ) +{ + GLuint flag; + flag = prim->mode; + if (prim->begin) flag |= PRIM_BEGIN; + if (prim->end) flag |= PRIM_END; + return flag; +} - void (*tabfv[_TNL_ATTRIB_MAX][4])( const GLfloat * ); -}; -/** - * A collection of vertex arrays. - */ -struct tnl_vertex_arrays -{ - /* Conventional vertex attribute arrays */ - GLvector4f Obj; - GLvector4f Normal; - GLvector4f Color; - GLvector4f SecondaryColor; - GLvector4f FogCoord; - GLvector4f TexCoord[MAX_TEXTURE_COORD_UNITS]; - GLvector4f Index; - - GLubyte *EdgeFlag; - GLuint *Elt; - - /* These attributes don't alias with the conventional attributes. - * The GL_NV_vertex_program extension defines 16 extra sets of vertex - * arrays which have precedent over the conventional arrays when enabled. - */ - /* XXX I think the array size is wronge (47 vs. 16) */ - GLvector4f Attribs[_TNL_ATTRIB_MAX]; -}; - /** * Contains the current state of a running pipeline. @@ -424,11 +219,10 @@ struct vertex_buffer GLvector4f *FogCoordPtr; /* _TNL_BIT_FOG */ GLvector4f *VaryingPtr[MAX_VARYING_VECTORS]; - struct tnl_prim *Primitive; + const struct _mesa_prim *Primitive; GLuint PrimitiveCount; /* Inputs to the vertex program stage */ - /* XXX This array may be too large (47 vs. 16) */ GLvector4f *AttribPtr[_TNL_ATTRIB_MAX]; /* GL_NV_vertex_program */ }; @@ -626,12 +420,6 @@ struct tnl_device_driver * arrays. */ - GLboolean (*NotifyBegin)(GLcontext *ctx, GLenum p); - /* Allow drivers to hook in optimized begin/end engines. - * Return value: GL_TRUE - driver handled the begin - * GL_FALSE - driver didn't handle the begin - */ - /*** *** Rendering -- These functions called only from t_vb_render.c ***/ @@ -737,26 +525,11 @@ typedef struct */ struct tnl_device_driver Driver; - /* Execute: - */ - struct tnl_vtx vtx; - - /* Compile: - */ - struct tnl_save save; - /* Pipeline */ struct tnl_pipeline pipeline; struct vertex_buffer vb; - /* GLvectors for binding to vb: - */ - struct tnl_vertex_arrays vtx_inputs; - struct tnl_vertex_arrays save_inputs; - struct tnl_vertex_arrays current; - struct tnl_vertex_arrays array_inputs; - /* Clipspace/ndc/window vertex managment: */ struct tnl_clipspace clipspace; @@ -764,26 +537,21 @@ typedef struct /* Probably need a better configuration mechanism: */ GLboolean NeedNdcCoords; - GLboolean LoopbackDListCassettes; - GLboolean CalcDListNormalLengths; - GLboolean IsolateMaterials; GLboolean AllowVertexFog; GLboolean AllowPixelFog; - GLboolean AllowCodegen; - GLboolean _DoVertexFog; /* eval fog function at each vertex? */ - /* If True, it means we started a glBegin/End primtive with an invalid - * vertex/fragment program or incomplete framebuffer. In that case, - * discard any buffered vertex data. - */ - GLboolean DiscardPrimitive; - DECLARE_RENDERINPUTS(render_inputs_bitset); - GLvertexformat exec_vtxfmt; - GLvertexformat save_vtxfmt; + GLvector4f tmp_inputs[VERT_ATTRIB_MAX]; + /* Temp storage for t_draw.c: + */ + GLubyte *block[VERT_ATTRIB_MAX]; + GLuint nr_blocks; + + /* Cache of fixed-function-replacing vertex programs: + */ struct tnl_cache *vp_cache; } TNLcontext; diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c deleted file mode 100644 index 11d21301d94..00000000000 --- a/src/mesa/tnl/t_save_api.c +++ /dev/null @@ -1,1733 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -on 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 -TUNGSTEN GRAPHICS 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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - */ - - - -/** - * The display list compiler attempts to store lists of vertices with the - * same vertex layout. Additionally it attempts to minimize the need - * for execute-time fixup of these vertex lists, allowing them to be - * cached on hardware. - * - * There are still some circumstances where this can be thwarted, for - * example by building a list that consists of one very long primitive - * (eg Begin(Triangles), 1000 vertices, End), and calling that list - * from inside a different begin/end object (Begin(Lines), CallList, - * End). - * - * In that case the code will have to replay the list as individual - * commands through the Exec dispatch table, or fix up the copied - * vertices at execute-time. - * - * The other case where fixup is required is when a vertex attribute - * is introduced in the middle of a primitive. Eg: - * Begin(Lines) - * TexCoord1f() Vertex2f() - * TexCoord1f() Color3f() Vertex2f() - * End() - * - * If the current value of Color isn't known at compile-time, this - * primitive will require fixup. - * - * - * The list compiler currently doesn't attempt to compile lists - * containing EvalCoord or EvalPoint commands. On encountering one of - * these, compilation falls back to opcodes. - * - * This could be improved to fallback only when a mix of EvalCoord and - * Vertex commands are issued within a single primitive. - */ - - -#include "glheader.h" -#include "context.h" -#include "dlist.h" -#include "enums.h" -#include "macros.h" -#include "api_validate.h" -#include "api_arrayelt.h" -#include "vtxfmt.h" -#include "t_save_api.h" -#include "dispatch.h" - -/* - * NOTE: Old 'parity' issue is gone, but copying can still be - * wrong-footed on replay. - */ -static GLuint _save_copy_vertices( GLcontext *ctx, - const struct tnl_vertex_list *node ) -{ - TNLcontext *tnl = TNL_CONTEXT( ctx ); - const struct tnl_prim *prim = &node->prim[node->prim_count-1]; - GLuint nr = prim->count; - GLuint sz = tnl->save.vertex_size; - const GLfloat *src = node->buffer + prim->start * sz; - GLfloat *dst = tnl->save.copied.buffer; - GLuint ovf, i; - - if (prim->mode & PRIM_END) - return 0; - - switch( prim->mode & PRIM_MODE_MASK ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - else { - _mesa_memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) ); - return 1; - } - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); - return 1; - } else { - _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); - _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) ); - return 2; - } - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - default: - assert(0); - return 0; - } -} - - -static void -build_normal_lengths( struct tnl_vertex_list *node ) -{ - GLuint i; - GLfloat *len; - GLfloat *n = node->buffer; - GLuint stride = node->vertex_size; - GLuint count = node->count; - - len = node->normal_lengths = (GLfloat *) MALLOC( count * sizeof(GLfloat) ); - if (!len) - return; - - /* Find the normal of the first vertex: - */ - for (i = 0 ; i < _TNL_ATTRIB_NORMAL ; i++) - n += node->attrsz[i]; - - for (i = 0 ; i < count ; i++, n += stride) { - len[i] = LEN_3FV( n ); - if (len[i] > 0.0F) len[i] = 1.0F / len[i]; - } -} - -static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx ) -{ - struct tnl_vertex_store *store = MALLOC_STRUCT(tnl_vertex_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static struct tnl_primitive_store *alloc_prim_store( GLcontext *ctx ) -{ - struct tnl_primitive_store *store = MALLOC_STRUCT(tnl_primitive_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static void _save_reset_counters( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - tnl->save.prim = tnl->save.prim_store->buffer + tnl->save.prim_store->used; - tnl->save.buffer = (tnl->save.vertex_store->buffer + - tnl->save.vertex_store->used); - - if (tnl->save.vertex_size) - tnl->save.initial_counter = ((SAVE_BUFFER_SIZE - - tnl->save.vertex_store->used) / - tnl->save.vertex_size); - else - tnl->save.initial_counter = 0; - - if (tnl->save.initial_counter > ctx->Const.MaxArrayLockSize ) - tnl->save.initial_counter = ctx->Const.MaxArrayLockSize; - - tnl->save.counter = tnl->save.initial_counter; - tnl->save.prim_count = 0; - tnl->save.prim_max = SAVE_PRIM_SIZE - tnl->save.prim_store->used; - tnl->save.copied.nr = 0; - tnl->save.dangling_attr_ref = 0; -} - - -/* Insert the active immediate struct onto the display list currently - * being built. - */ -static void _save_compile_vertex_list( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_list *node; - - /* Allocate space for this structure in the display list currently - * being compiled. - */ - node = (struct tnl_vertex_list *) - _mesa_alloc_instruction(ctx, tnl->save.opcode_vertex_list, sizeof(*node)); - - if (!node) - return; - - /* Duplicate our template, increment refcounts to the storage structs: - */ - _mesa_memcpy(node->attrsz, tnl->save.attrsz, sizeof(node->attrsz)); - node->vertex_size = tnl->save.vertex_size; - node->buffer = tnl->save.buffer; - node->count = tnl->save.initial_counter - tnl->save.counter; - node->wrap_count = tnl->save.copied.nr; - node->have_materials = tnl->save.have_materials; - node->dangling_attr_ref = tnl->save.dangling_attr_ref; - node->normal_lengths = NULL; - node->prim = tnl->save.prim; - node->prim_count = tnl->save.prim_count; - node->vertex_store = tnl->save.vertex_store; - node->prim_store = tnl->save.prim_store; - - node->vertex_store->refcount++; - node->prim_store->refcount++; - - assert(node->attrsz[_TNL_ATTRIB_POS] != 0 || - node->count == 0); - - if (tnl->save.dangling_attr_ref) - ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; - - /* Maybe calculate normal lengths: - */ - if (tnl->CalcDListNormalLengths && - node->attrsz[_TNL_ATTRIB_NORMAL] == 3 && - !(ctx->ListState.CurrentList->flags & MESA_DLIST_DANGLING_REFS)) - build_normal_lengths( node ); - - - tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; - tnl->save.prim_store->used += node->prim_count; - - /* Decide whether the storage structs are full, or can be used for - * the next vertex lists as well. - */ - if (tnl->save.vertex_store->used > - SAVE_BUFFER_SIZE - 16 * (tnl->save.vertex_size + 4)) { - - tnl->save.vertex_store->refcount--; - assert(tnl->save.vertex_store->refcount != 0); - tnl->save.vertex_store = alloc_vertex_store( ctx ); - tnl->save.vbptr = tnl->save.vertex_store->buffer; - } - - if (tnl->save.prim_store->used > SAVE_PRIM_SIZE - 6) { - tnl->save.prim_store->refcount--; - assert(tnl->save.prim_store->refcount != 0); - tnl->save.prim_store = alloc_prim_store( ctx ); - } - - /* Reset our structures for the next run of vertices: - */ - _save_reset_counters( ctx ); - - /* Copy duplicated vertices - */ - tnl->save.copied.nr = _save_copy_vertices( ctx, node ); - - - /* Deal with GL_COMPILE_AND_EXECUTE: - */ - if (ctx->ExecuteFlag) { - _tnl_playback_vertex_list( ctx, (void *) node ); - } -} - - -/* TODO -- If no new vertices have been stored, don't bother saving - * it. - */ -static void _save_wrap_buffers( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i = tnl->save.prim_count - 1; - GLenum mode; - - assert(i < (GLint) tnl->save.prim_max); - assert(i >= 0); - - /* Close off in-progress primitive. - */ - tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - - tnl->save.prim[i].start); - mode = tnl->save.prim[i].mode & ~(PRIM_BEGIN|PRIM_END); - - /* store the copied vertices, and allocate a new list. - */ - _save_compile_vertex_list( ctx ); - - /* Restart interrupted primitive - */ - tnl->save.prim[0].mode = mode; - tnl->save.prim[0].start = 0; - tnl->save.prim[0].count = 0; - tnl->save.prim_count = 1; -} - - - -/* Called only when buffers are wrapped as the result of filling the - * vertex_store struct. - */ -static void _save_wrap_filled_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat *data = tnl->save.copied.buffer; - GLuint i; - - /* Emit a glEnd to close off the last vertex list. - */ - _save_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(tnl->save.counter > tnl->save.copied.nr); - - for (i = 0 ; i < tnl->save.copied.nr ; i++) { - _mesa_memcpy( tnl->save.vbptr, data, tnl->save.vertex_size * sizeof(GLfloat)); - data += tnl->save.vertex_size; - tnl->save.vbptr += tnl->save.vertex_size; - tnl->save.counter--; - } -} - - -static void _save_copy_to_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - /* XXX Use _TNL_FIRST_* and _TNL_LAST_* values instead? */ - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) { - if (tnl->save.attrsz[i]) { - tnl->save.currentsz[i][0] = tnl->save.attrsz[i]; - COPY_CLEAN_4V(tnl->save.current[i], - tnl->save.attrsz[i], - tnl->save.attrptr[i]); - } - } - - /* Edgeflag requires special treatment: - * - * TODO: change edgeflag to GLfloat in Mesa. - */ - if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - ctx->ListState.ActiveEdgeFlag = 1; - tnl->save.CurrentFloatEdgeFlag = - tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0]; - ctx->ListState.CurrentEdgeFlag = - (tnl->save.CurrentFloatEdgeFlag == 1.0); - } -} - - -static void _save_copy_from_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) - switch (tnl->save.attrsz[i]) { - case 4: tnl->save.attrptr[i][3] = tnl->save.current[i][3]; - case 3: tnl->save.attrptr[i][2] = tnl->save.current[i][2]; - case 2: tnl->save.attrptr[i][1] = tnl->save.current[i][1]; - case 1: tnl->save.attrptr[i][0] = tnl->save.current[i][0]; - case 0: break; - } - - /* Edgeflag requires special treatment: - */ - if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - tnl->save.CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; - tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0] = tnl->save.CurrentFloatEdgeFlag; - } -} - - - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _save_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz; - GLuint i; - GLfloat *tmp; - - /* Store the current run of vertices, and emit a GL_END. Emit a - * BEGIN in the new buffer. - */ - if (tnl->save.initial_counter != tnl->save.counter) - _save_wrap_buffers( ctx ); - else - assert( tnl->save.copied.nr == 0 ); - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _save_copy_to_current( ctx ); - - /* Fix up sizes: - */ - oldsz = tnl->save.attrsz[attr]; - tnl->save.attrsz[attr] = newsz; - - tnl->save.vertex_size += newsz - oldsz; - tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) / - tnl->save.vertex_size); - if (tnl->save.counter > ctx->Const.MaxArrayLockSize ) - tnl->save.counter = ctx->Const.MaxArrayLockSize; - tnl->save.initial_counter = tnl->save.counter; - - /* Recalculate all the attrptr[] values: - */ - for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) { - if (tnl->save.attrsz[i]) { - tnl->save.attrptr[i] = tmp; - tmp += tnl->save.attrsz[i]; - } - else - tnl->save.attrptr[i] = NULL; /* will not be dereferenced. */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _save_copy_from_current( ctx ); - - /* Replay stored vertices to translate them to new format here. - * - * If there are copied vertices and the new (upgraded) attribute - * has not been defined before, this list is somewhat degenerate, - * and will need fixup at runtime. - */ - if (tnl->save.copied.nr) - { - GLfloat *data = tnl->save.copied.buffer; - GLfloat *dest = tnl->save.buffer; - GLuint j; - - /* Need to note this and fix up at runtime (or loopback): - */ - if (tnl->save.currentsz[attr][0] == 0) { - assert(oldsz == 0); - tnl->save.dangling_attr_ref = GL_TRUE; - -/* _mesa_debug(NULL, "_save_upgrade_vertex: dangling reference attr %d\n", */ -/* attr); */ - -#if 0 - /* The current strategy is to punt these degenerate cases - * through _tnl_loopback_vertex_list(), a lower-performance - * option. To minimize the impact of this, artificially - * reduce the size of this vertex_list. - */ - if (t->save.counter > 10) { - t->save.initial_counter = 10; - t->save.counter = 10; - } -#endif - } - - for (i = 0 ; i < tnl->save.copied.nr ; i++) { - for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { - if (tnl->save.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } - else { - COPY_SZ_4V( dest, newsz, tnl->save.current[attr] ); - dest += newsz; - } - } - else { - GLint sz = tnl->save.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - data += sz; - dest += sz; - } - } - } - } - - tnl->save.vbptr = dest; - tnl->save.counter -= tnl->save.copied.nr; - } -} - - - - -/* Helper function for 'CHOOSE' macro. Do what's necessary when an - * entrypoint is called for the first time. - */ -static void do_choose( GLuint attr, GLuint sz, - void (*attr_func)( const GLfloat *), - void (*choose1)( const GLfloat *), - void (*choose2)( const GLfloat *), - void (*choose3)( const GLfloat *), - void (*choose4)( const GLfloat *), - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - static GLfloat id[4] = { 0, 0, 0, 1 }; - int i; - - if (tnl->save.attrsz[attr] < sz) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _save_upgrade_vertex( ctx, attr, sz ); - } - else { - /* New size is equal or smaller - just need to fill in some - * zeros. - */ - for (i = sz ; i <= tnl->save.attrsz[attr] ; i++) - tnl->save.attrptr[attr][i-1] = id[i-1]; - } - - /* Reset any active pointers for this attribute - */ - tnl->save.tabfv[attr][0] = choose1; - tnl->save.tabfv[attr][1] = choose2; - tnl->save.tabfv[attr][2] = choose3; - tnl->save.tabfv[attr][3] = choose4; - - /* Update the secondary dispatch table with the new function - */ - tnl->save.tabfv[attr][sz-1] = attr_func; - - (*attr_func)(v); -} - - - -/* Only one size for each attribute may be active at once. Eg. if - * Color3f is installed/active, then Color4f may not be, even if the - * vertex actually contains 4 color coordinates. This is because the - * 3f version won't otherwise set color[3] to 1.0 -- this is the job - * of the chooser function when switching between Color4f and Color3f. - */ -#define ATTRFV( ATTR, N ) \ -static void save_choose_##ATTR##_##N( const GLfloat *v ); \ - \ -static void save_attrib_##ATTR##_##N( const GLfloat *v ) \ -{ \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if ((ATTR) == 0) { \ - GLuint i; \ - \ - if (N>0) tnl->save.vbptr[0] = v[0]; \ - if (N>1) tnl->save.vbptr[1] = v[1]; \ - if (N>2) tnl->save.vbptr[2] = v[2]; \ - if (N>3) tnl->save.vbptr[3] = v[3]; \ - \ - for (i = N; i < tnl->save.vertex_size; i++) \ - tnl->save.vbptr[i] = tnl->save.vertex[i]; \ - \ - tnl->save.vbptr += tnl->save.vertex_size; \ - \ - if (--tnl->save.counter == 0) \ - _save_wrap_filled_vertex( ctx ); \ - } \ - else { \ - GLfloat *dest = tnl->save.attrptr[ATTR]; \ - if (N>0) dest[0] = v[0]; \ - if (N>1) dest[1] = v[1]; \ - if (N>2) dest[2] = v[2]; \ - if (N>3) dest[3] = v[3]; \ - } \ -} - -#define CHOOSE( ATTR, N ) \ -static void save_choose_##ATTR##_##N( const GLfloat *v ) \ -{ \ - do_choose(ATTR, N, \ - save_attrib_##ATTR##_##N, \ - save_choose_##ATTR##_1, \ - save_choose_##ATTR##_2, \ - save_choose_##ATTR##_3, \ - save_choose_##ATTR##_4, \ - v ); \ -} - -#define INIT(ATTR) \ -static void save_init_##ATTR( TNLcontext *tnl ) \ -{ \ - tnl->save.tabfv[ATTR][0] = save_choose_##ATTR##_1; \ - tnl->save.tabfv[ATTR][1] = save_choose_##ATTR##_2; \ - tnl->save.tabfv[ATTR][2] = save_choose_##ATTR##_3; \ - tnl->save.tabfv[ATTR][3] = save_choose_##ATTR##_4; \ -} - -#define ATTRS( ATTRIB ) \ - ATTRFV( ATTRIB, 1 ) \ - ATTRFV( ATTRIB, 2 ) \ - ATTRFV( ATTRIB, 3 ) \ - ATTRFV( ATTRIB, 4 ) \ - CHOOSE( ATTRIB, 1 ) \ - CHOOSE( ATTRIB, 2 ) \ - CHOOSE( ATTRIB, 3 ) \ - CHOOSE( ATTRIB, 4 ) \ - INIT( ATTRIB ) \ - - -/* Generate a lot of functions. These are the actual worker - * functions, which are equivalent to those generated via codegen - * elsewhere. - */ -ATTRS( 0 ) -ATTRS( 1 ) -ATTRS( 2 ) -ATTRS( 3 ) -ATTRS( 4 ) -ATTRS( 5 ) -ATTRS( 6 ) -ATTRS( 7 ) -ATTRS( 8 ) -ATTRS( 9 ) -ATTRS( 10 ) -ATTRS( 11 ) -ATTRS( 12 ) -ATTRS( 13 ) -ATTRS( 14 ) -ATTRS( 15 ) - - -static void _save_reset_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - save_init_0( tnl ); - save_init_1( tnl ); - save_init_2( tnl ); - save_init_3( tnl ); - save_init_4( tnl ); - save_init_5( tnl ); - save_init_6( tnl ); - save_init_7( tnl ); - save_init_8( tnl ); - save_init_9( tnl ); - save_init_10( tnl ); - save_init_11( tnl ); - save_init_12( tnl ); - save_init_13( tnl ); - save_init_14( tnl ); - save_init_15( tnl ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - tnl->save.attrsz[i] = 0; - - tnl->save.vertex_size = 0; - tnl->save.have_materials = 0; - - _save_reset_counters( ctx ); -} - - - -/* Cope with aliasing of classic Vertex, Normal, etc. and the fan-out - * of glMultTexCoord and glProgramParamterNV by routing all these - * through a second level dispatch table. - */ -#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \ -do { \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - tnl->save.tabfv[ATTR][COUNT-1]( P ); \ -} while (0) - -#define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V ) -#define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V ) -#define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V ) -#define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V ) - -#define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) ) - -#if defined(USE_X86_ASM) && 0 /* will break register calling convention */ -/* Naughty cheat: - */ -#define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) ) -#define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) ) -#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) ) -#else -/* Safe: - */ -#define DISPATCH_ATTR2F( ATTR, S,T ) \ -do { \ - GLfloat v[2]; \ - v[0] = S; v[1] = T; \ - DISPATCH_ATTR2FV( ATTR, v ); \ -} while (0) -#define DISPATCH_ATTR3F( ATTR, S,T,R ) \ -do { \ - GLfloat v[3]; \ - v[0] = S; v[1] = T; v[2] = R; \ - DISPATCH_ATTR3FV( ATTR, v ); \ -} while (0) -#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \ -do { \ - GLfloat v[4]; \ - v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \ - DISPATCH_ATTR4FV( ATTR, v ); \ -} while (0) -#endif - - -static void enum_error( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - _mesa_compile_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); -} - -static void GLAPIENTRY _save_Vertex2f( GLfloat x, GLfloat y ) -{ - DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y ); -} - -static void GLAPIENTRY _save_Vertex2fv( const GLfloat *v ) -{ - DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z ); -} - -static void GLAPIENTRY _save_Vertex3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w ); -} - -static void GLAPIENTRY _save_Vertex4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_TexCoord1f( GLfloat x ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x ); -} - -static void GLAPIENTRY _save_TexCoord1fv( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord2f( GLfloat x, GLfloat y ) -{ - DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y ); -} - -static void GLAPIENTRY _save_TexCoord2fv( const GLfloat *v ) -{ - DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z ); -} - -static void GLAPIENTRY _save_TexCoord3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w ); -} - -static void GLAPIENTRY _save_TexCoord4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_Normal3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z ); -} - -static void GLAPIENTRY _save_Normal3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v ); -} - -static void GLAPIENTRY _save_FogCoordfEXT( GLfloat x ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x ); -} - -static void GLAPIENTRY _save_FogCoordfvEXT( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v ); -} - -static void GLAPIENTRY _save_Color3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z ); -} - -static void GLAPIENTRY _save_Color3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY _save_Color4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w ); -} - -static void GLAPIENTRY _save_Color4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY _save_SecondaryColor3fEXT( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z ); -} - -static void GLAPIENTRY _save_SecondaryColor3fvEXT( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v ); -} - -static void GLAPIENTRY _save_MultiTexCoord1f( GLenum target, GLfloat x ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR1F( attr, x ); -} - -static void GLAPIENTRY _save_MultiTexCoord1fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR1FV( attr, v ); -} - -static void GLAPIENTRY _save_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR2F( attr, x, y ); -} - -static void GLAPIENTRY _save_MultiTexCoord2fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR2FV( attr, v ); -} - -static void GLAPIENTRY _save_MultiTexCoord3f( GLenum target, GLfloat x, GLfloat y, - GLfloat z) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR3F( attr, x, y, z ); -} - -static void GLAPIENTRY _save_MultiTexCoord3fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR3FV( attr, v ); -} - -static void GLAPIENTRY _save_MultiTexCoord4f( GLenum target, GLfloat x, GLfloat y, - GLfloat z, GLfloat w ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR4F( attr, x, y, z, w ); -} - -static void GLAPIENTRY _save_MultiTexCoord4fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR4FV( attr, v ); -} - -static void GLAPIENTRY _save_VertexAttrib1fNV( GLuint index, GLfloat x ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR1F( index, x ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib1fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR1FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR2F( index, x, y ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib2fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR2FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y, - GLfloat z ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR3F( index, x, y, z ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib3fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR3FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, - GLfloat z, GLfloat w ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR4F( index, x, y, z, w ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR4FV( index, v ); - else - enum_error(); -} - - -static void GLAPIENTRY -_save_VertexAttrib1fARB( GLuint index, GLfloat x ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR1F( index, x ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib1fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR1FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib2fARB( GLuint index, GLfloat x, GLfloat y ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR2F( index, x, y ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib2fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR2FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib3fARB( GLuint index, GLfloat x, GLfloat y, GLfloat z ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR3F( index, x, y, z ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib3fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR3FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib4fARB( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR4F( index, x, y, z, w ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib4fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR4FV( index, v ); - else - enum_error(); -} - - -/* Materials: - * - * These are treated as per-vertex attributes, at indices above where - * the NV_vertex_program leaves off. There are a lot of good things - * about treating materials this way. - * - * However: I don't want to double the number of generated functions - * just to cope with this, so I unroll the 'C' varients of CHOOSE and - * ATTRF into this function, and dispense with codegen and - * second-level dispatch. - * - * There is no aliasing of material attributes with other entrypoints. - */ -#define MAT_ATTR( A, N, params ) \ -do { \ - if (tnl->save.attrsz[A] < N) { \ - _save_upgrade_vertex( ctx, A, N ); \ - tnl->save.have_materials = GL_TRUE; \ - } \ - \ - { \ - GLfloat *dest = tnl->save.attrptr[A]; \ - if (N>0) dest[0] = params[0]; \ - if (N>1) dest[1] = params[1]; \ - if (N>2) dest[2] = params[2]; \ - if (N>3) dest[3] = params[3]; \ - } \ -} while (0) - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - MAT_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - MAT_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/* NOTE: Have to remove/deal-with colormaterial crossovers, probably - * later on - in the meantime just store everything. - */ -static void GLAPIENTRY _save_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - switch (pname) { - case GL_EMISSION: - MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - _mesa_compile_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } -} - - -#define IDX_ATTR( A, IDX ) \ -do { \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if (tnl->save.attrsz[A] < 1) { \ - _save_upgrade_vertex( ctx, A, 1 ); \ - } \ - \ - { \ - GLfloat *dest = tnl->save.attrptr[A]; \ - dest[0] = IDX; \ - } \ -} while (0) - - -static void GLAPIENTRY _save_EdgeFlag( GLboolean b ) -{ - IDX_ATTR( _TNL_ATTRIB_EDGEFLAG, (GLfloat)b ); -} - - -static void GLAPIENTRY _save_Indexf( GLfloat f ) -{ - IDX_ATTR( _TNL_ATTRIB_COLOR_INDEX, f ); -} - -static void GLAPIENTRY _save_Indexfv( const GLfloat *f ) -{ - IDX_ATTR( _TNL_ATTRIB_COLOR_INDEX, f[0] ); -} - - - - -/* Cope with EvalCoord/CallList called within a begin/end object: - * -- Flush current buffer - * -- Fallback to opcodes for the rest of the begin/end object. - */ -#define FALLBACK(ctx) \ -do { \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if (tnl->save.initial_counter != tnl->save.counter || \ - tnl->save.prim_count) \ - _save_compile_vertex_list( ctx ); \ - \ - _save_copy_to_current( ctx ); \ - _save_reset_vertex( ctx ); \ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \ - ctx->Driver.SaveNeedFlush = 0; \ -} while (0) - -static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord1f(ctx->Save, ( u )); -} - -static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord1fv(ctx->Save, ( v )); -} - -static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord2f(ctx->Save, ( u, v )); -} - -static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord2fv(ctx->Save, ( v )); -} - -static void GLAPIENTRY _save_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalPoint1(ctx->Save, ( i )); -} - -static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalPoint2(ctx->Save, ( i, j )); -} - -static void GLAPIENTRY _save_CallList( GLuint l ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_CallList(ctx->Save, ( l )); -} - -static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_CallLists(ctx->Save, ( n, type, v )); -} - - - - -/** - * Called via ctx->Driver.NotifySaveBegin(ctx, mode) when we get a - * glBegin() call while compiling a display list. - * See save_Begin() in dlist.c - * - * This plugs in our special TNL-related display list functions. - * All subsequent glBegin/glVertex/glEnd()s found while compiling a - * display list will get routed to the functions in this file. - * - * Updating of ctx->Driver.CurrentSavePrimitive is already taken care of. - */ -static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - if (1) { - GLuint i = tnl->save.prim_count++; - - assert(i < tnl->save.prim_max); - tnl->save.prim[i].mode = mode | PRIM_BEGIN; - tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter; - tnl->save.prim[i].count = 0; - - _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt ); - ctx->Driver.SaveNeedFlush = 1; - return GL_TRUE; - } - else - return GL_FALSE; -} - - - -static void GLAPIENTRY _save_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i = tnl->save.prim_count - 1; - - ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; - if (ctx->ExecuteFlag) - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - - tnl->save.prim[i].mode |= PRIM_END; - tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - - tnl->save.prim[i].start); - - if (i == (GLint) tnl->save.prim_max - 1) { - _save_compile_vertex_list( ctx ); - assert(tnl->save.copied.nr == 0); - } - - /* Swap out this vertex format while outside begin/end. Any color, - * etc. received between here and the next begin will be compiled - * as opcodes. - */ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/* These are all errors as this vtxfmt is only installed inside - * begin/end pairs. - */ -static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); -} - - -static void GLAPIENTRY _save_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); -} - -static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) count; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); -} - -static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) x1; (void) y1; (void) x2; (void) y2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" ); -} - -static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" ); -} - -static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, - GLint j1, GLint j2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" ); -} - -/** - * This is only called if someone tries to compile nested glBegin()s - * in their display list. - */ -static void GLAPIENTRY _save_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) mode; - _mesa_compile_error(ctx, GL_INVALID_OPERATION, - "glBegin(called inside glBegin/End)"); -} - - -/* Unlike the functions above, these are to be hooked into the vtxfmt - * maintained in ctx->ListState, active when the list is known or - * suspected to be outside any begin/end primitive. - */ -static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - _save_NotifyBegin( ctx, GL_QUADS | PRIM_WEAK ); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - _save_NotifyBegin( ctx, mode | PRIM_WEAK ); - for (i = 0; i < count; i++) - CALL_ArrayElement(GET_DISPATCH(), (start + i)); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - _save_NotifyBegin( ctx, mode | PRIM_WEAK ); - - switch (type) { - case GL_UNSIGNED_BYTE: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); - break; - case GL_UNSIGNED_SHORT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); - break; - case GL_UNSIGNED_INT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - break; - } - - CALL_End(GET_DISPATCH(), ()); -} - -static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - if (_mesa_validate_DrawRangeElements( ctx, mode, - start, end, - count, type, indices )) - _save_OBE_DrawElements( mode, count, type, indices ); -} - - - - - -static void _save_vtxfmt_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLvertexformat *vfmt = &tnl->save_vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _save_Begin; - vfmt->Color3f = _save_Color3f; - vfmt->Color3fv = _save_Color3fv; - vfmt->Color4f = _save_Color4f; - vfmt->Color4fv = _save_Color4fv; - vfmt->EdgeFlag = _save_EdgeFlag; - vfmt->End = _save_End; - vfmt->FogCoordfEXT = _save_FogCoordfEXT; - vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; - vfmt->Indexf = _save_Indexf; - vfmt->Indexfv = _save_Indexfv; - vfmt->Materialfv = _save_Materialfv; - vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; - vfmt->Normal3f = _save_Normal3f; - vfmt->Normal3fv = _save_Normal3fv; - vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; - vfmt->TexCoord1f = _save_TexCoord1f; - vfmt->TexCoord1fv = _save_TexCoord1fv; - vfmt->TexCoord2f = _save_TexCoord2f; - vfmt->TexCoord2fv = _save_TexCoord2fv; - vfmt->TexCoord3f = _save_TexCoord3f; - vfmt->TexCoord3fv = _save_TexCoord3fv; - vfmt->TexCoord4f = _save_TexCoord4f; - vfmt->TexCoord4fv = _save_TexCoord4fv; - vfmt->Vertex2f = _save_Vertex2f; - vfmt->Vertex2fv = _save_Vertex2fv; - vfmt->Vertex3f = _save_Vertex3f; - vfmt->Vertex3fv = _save_Vertex3fv; - vfmt->Vertex4f = _save_Vertex4f; - vfmt->Vertex4fv = _save_Vertex4fv; - vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; - vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; - - /* This will all require us to fallback to saving the list as opcodes: - */ - vfmt->CallList = _save_CallList; /* inside begin/end */ - vfmt->CallLists = _save_CallLists; /* inside begin/end */ - vfmt->EvalCoord1f = _save_EvalCoord1f; - vfmt->EvalCoord1fv = _save_EvalCoord1fv; - vfmt->EvalCoord2f = _save_EvalCoord2f; - vfmt->EvalCoord2fv = _save_EvalCoord2fv; - vfmt->EvalPoint1 = _save_EvalPoint1; - vfmt->EvalPoint2 = _save_EvalPoint2; - - /* These are all errors as we at least know we are in some sort of - * begin/end pair: - */ - vfmt->EvalMesh1 = _save_EvalMesh1; - vfmt->EvalMesh2 = _save_EvalMesh2; - vfmt->Begin = _save_Begin; - vfmt->Rectf = _save_Rectf; - vfmt->DrawArrays = _save_DrawArrays; - vfmt->DrawElements = _save_DrawElements; - vfmt->DrawRangeElements = _save_DrawRangeElements; - -} - - -void _tnl_SaveFlushVertices( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* Noop when we are actually active: - */ - if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || - ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) - return; - - if (tnl->save.initial_counter != tnl->save.counter || - tnl->save.prim_count) - _save_compile_vertex_list( ctx ); - - _save_copy_to_current( ctx ); - _save_reset_vertex( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - (void) list; (void) mode; - - if (!tnl->save.prim_store) - tnl->save.prim_store = alloc_prim_store( ctx ); - - if (!tnl->save.vertex_store) { - tnl->save.vertex_store = alloc_vertex_store( ctx ); - tnl->save.vbptr = tnl->save.vertex_store->buffer; - } - - _save_reset_vertex( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void _tnl_EndList( GLcontext *ctx ) -{ - (void) ctx; - assert(TNL_CONTEXT(ctx)->save.vertex_size == 0); -} - -void _tnl_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->save.replay_flags |= dlist->flags; - tnl->save.replay_flags |= tnl->LoopbackDListCassettes; -} - -void _tnl_EndCallList( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - if (ctx->ListState.CallDepth == 1) - tnl->save.replay_flags = 0; -} - - -static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data ) -{ - struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; - (void) ctx; - - if ( --node->vertex_store->refcount == 0 ) - FREE( node->vertex_store ); - - if ( --node->prim_store->refcount == 0 ) - FREE( node->prim_store ); - - if ( node->normal_lengths ) - FREE( node->normal_lengths ); -} - - -static void _tnl_print_vertex_list( GLcontext *ctx, void *data ) -{ - struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; - GLuint i; - (void) ctx; - - _mesa_debug(NULL, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", - node->count, - node->prim_count, - node->vertex_size); - - for (i = 0 ; i < node->prim_count ; i++) { - struct tnl_prim *prim = &node->prim[i]; - _mesa_debug(NULL, " prim %d: %s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK), - prim->start, - prim->start + prim->count, - (prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)", - (prim->mode & PRIM_END) ? "END" : "(wrap)"); - } -} - - -static void _save_current_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - for (i = 0; i < _TNL_ATTRIB_MAT_FRONT_AMBIENT; i++) { - ASSERT(i < VERT_ATTRIB_MAX); - tnl->save.currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; - tnl->save.current[i] = ctx->ListState.CurrentAttrib[i]; - } - - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - const GLuint j = i - _TNL_FIRST_MAT; - ASSERT(j < MAT_ATTRIB_MAX); - tnl->save.currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; - tnl->save.current[i] = ctx->ListState.CurrentMaterial[j]; - } - - tnl->save.currentsz[_TNL_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; - tnl->save.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->save.CurrentFloatEdgeFlag; -} - -/** - * Initialize the display list compiler - */ -void _tnl_save_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_arrays *tmp = &tnl->save_inputs; - GLuint i; - - - for (i = 0; i < _TNL_ATTRIB_MAX; i++) - _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); - - tnl->save.opcode_vertex_list = - _mesa_alloc_opcode( ctx, - sizeof(struct tnl_vertex_list), - _tnl_playback_vertex_list, - _tnl_destroy_vertex_list, - _tnl_print_vertex_list ); - - ctx->Driver.NotifySaveBegin = _save_NotifyBegin; - - _save_vtxfmt_init( ctx ); - _save_current_init( ctx ); - - /* Hook our array functions into the outside-begin-end vtxfmt in - * ctx->ListState. - */ - ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; - ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; - ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; - ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/** - * Deallocate the immediate-mode buffer for the given context, if - * its reference count goes to zero. - */ -void _tnl_save_destroy( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* Decrement the refcounts. References may still be held by - * display lists yet to be destroyed, so it may not yet be time to - * free these items. - */ - if (tnl->save.prim_store && - --tnl->save.prim_store->refcount == 0 ) - FREE( tnl->save.prim_store ); - - if (tnl->save.vertex_store && - --tnl->save.vertex_store->refcount == 0 ) - FREE( tnl->save.vertex_store ); -} diff --git a/src/mesa/tnl/t_save_api.h b/src/mesa/tnl/t_save_api.h deleted file mode 100644 index c30e0e8ecdb..00000000000 --- a/src/mesa/tnl/t_save_api.h +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -on 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 -TUNGSTEN GRAPHICS 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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - * - */ - -#ifndef __T_SAVE_API_H__ -#define __T_SAVE_API_H__ - -#include "t_context.h" - -extern GLboolean _tnl_weak_begin( GLcontext *ctx, GLenum mode ); - -extern void _tnl_EndList( GLcontext *ctx ); -extern void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ); - -extern void _tnl_EndCallList( GLcontext *ctx ); -extern void _tnl_BeginCallList( GLcontext *ctx, struct mesa_display_list *list ); - -extern void _tnl_SaveFlushVertices( GLcontext *ctx ); - -extern void _tnl_save_init( GLcontext *ctx ); -extern void _tnl_save_destroy( GLcontext *ctx ); - -extern void _tnl_loopback_vertex_list( GLcontext *ctx, - const struct tnl_vertex_list *list ); - -extern void _tnl_playback_vertex_list( GLcontext *ctx, void *data ); - -#endif diff --git a/src/mesa/tnl/t_save_loopback.c b/src/mesa/tnl/t_save_loopback.c deleted file mode 100644 index b96bb4ec552..00000000000 --- a/src/mesa/tnl/t_save_loopback.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2004 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - -/* Author: - * Keith Whitwell - */ - -#include "glheader.h" -#include "context.h" -#include "enums.h" -#include "glapi.h" -#include "imports.h" -#include "macros.h" -#include "mtypes.h" -#include "t_context.h" -#include "t_save_api.h" -#include "dispatch.h" - -/* If someone compiles a display list like: - * glBegin(Triangles) - * glVertex() - * ... lots of vertices ... - * glEnd() - * - * or: - * glDrawArrays(...) - * - * and then tries to execute it like this: - * - * glBegin(Lines) - * glCallList() - * glEnd() - * - * it will wind up in here, as the vertex copying used when wrapping - * buffers in list compilation (Triangles) won't be right for how the - * list is being executed (as Lines). - * - * This could be avoided by not compiling as vertex_lists until after - * the first glEnd() has been seen. However, that would miss an - * important category of display lists, for the sake of a degenerate - * usage. - * - * Further, replaying degenerately-called lists in this fashion is - * probably still faster than the replay using opcodes. - */ - -typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * ); - - -/* Wrapper functions in case glVertexAttrib*fvNV doesn't exist */ -static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib1fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib2fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib2fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib3fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib3fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib4fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib4fvNV(ctx->Exec, (target, v)); -} - -static attr_func vert_attrfunc[4] = { - VertexAttrib1fvNV, - VertexAttrib2fvNV, - VertexAttrib3fvNV, - VertexAttrib4fvNV -}; - - -static void VertexAttrib1fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib1fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib2fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib2fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib3fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib3fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib4fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib4fvARB(ctx->Exec, (target, v)); -} - -static attr_func vert_attrfunc_arb[4] = { - VertexAttrib1fvARB, - VertexAttrib2fvARB, - VertexAttrib3fvARB, - VertexAttrib4fvARB -}; - - - - - - - -static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case _TNL_ATTRIB_MAT_FRONT_SHININESS: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SHININESS, v )); - break; - case _TNL_ATTRIB_MAT_BACK_SHININESS: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SHININESS, v )); - break; - } -} - - -static void mat_attr3fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case _TNL_ATTRIB_MAT_FRONT_INDEXES: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_COLOR_INDEXES, v )); - break; - case _TNL_ATTRIB_MAT_BACK_INDEXES: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_COLOR_INDEXES, v )); - break; - } -} - - -static void mat_attr4fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case _TNL_ATTRIB_MAT_FRONT_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_EMISSION, v )); - break; - case _TNL_ATTRIB_MAT_BACK_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_EMISSION, v )); - break; - case _TNL_ATTRIB_MAT_FRONT_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_AMBIENT, v )); - break; - case _TNL_ATTRIB_MAT_BACK_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_AMBIENT, v )); - break; - case _TNL_ATTRIB_MAT_FRONT_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_DIFFUSE, v )); - break; - case _TNL_ATTRIB_MAT_BACK_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_DIFFUSE, v )); - break; - case _TNL_ATTRIB_MAT_FRONT_SPECULAR: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SPECULAR, v )); - break; - case _TNL_ATTRIB_MAT_BACK_SPECULAR: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SPECULAR, v )); - break; - } -} - - -static attr_func mat_attrfunc[4] = { - mat_attr1fv, - NULL, - mat_attr3fv, - mat_attr4fv -}; - - -static void edgeflag_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v) -{ - (void) target; - CALL_EdgeFlag(ctx->Exec, ((GLboolean)(v[0] == 1.0))); -} - -struct loopback_attr { - GLint target; - GLint sz; - attr_func func; -}; - -/* Don't emit ends and begins on wrapped primitives. Don't replay - * wrapped vertices. If we get here, it's probably because the the - * precalculated wrapping is wrong. - */ -static void loopback_prim( GLcontext *ctx, - const struct tnl_vertex_list *list, GLuint i, - const struct loopback_attr *la, GLuint nr ) -{ - struct tnl_prim *prim = &list->prim[i]; - GLint begin = prim->start; - GLint end = begin + prim->count; - GLfloat *data; - GLint j; - GLuint k; - - if (prim->mode & PRIM_BEGIN) { - CALL_Begin(GET_DISPATCH(), ( prim->mode & PRIM_MODE_MASK )); - } - else { - assert(i == 0); - assert(begin == 0); - begin += list->wrap_count; - } - - data = list->buffer + begin * list->vertex_size; - - for (j = begin ; j < end ; j++) { - GLfloat *tmp = data + la[0].sz; - - for (k = 1 ; k < nr ; k++) { - la[k].func( ctx, la[k].target, tmp ); - tmp += la[k].sz; - } - - /* Fire the vertex - */ - la[0].func( ctx, VERT_ATTRIB_POS, data ); - data = tmp; - } - - if (prim->mode & PRIM_END) { - CALL_End(GET_DISPATCH(), ()); - } - else { - assert (i == list->prim_count-1); - } -} - -/* Primitives generated by DrawArrays/DrawElements/Rectf may be - * caught here. If there is no primitive in progress, execute them - * normally, otherwise need to track and discard the generated - * primitives. - */ -static void loopback_weak_prim( GLcontext *ctx, - const struct tnl_vertex_list *list, GLuint i, - const struct loopback_attr *la, GLuint nr ) -{ - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) - loopback_prim( ctx, list, i, la, nr ); - else { - struct tnl_prim *prim = &list->prim[i]; - - /* Use the prim_weak flag to ensure that if this primitive - * wraps, we don't mistake future vertex_lists for part of the - * surrounding primitive. - * - * While this flag is set, we are simply disposing of data - * generated by an operation now known to be a noop. - */ - if (prim->mode & PRIM_BEGIN) - ctx->Driver.CurrentExecPrimitive |= PRIM_WEAK; - if (prim->mode & PRIM_END) - ctx->Driver.CurrentExecPrimitive &= ~PRIM_WEAK; - } -} - - - -void _tnl_loopback_vertex_list( GLcontext *ctx, - const struct tnl_vertex_list *list ) -{ - struct loopback_attr la[_TNL_ATTRIB_MAX]; - GLuint i, nr = 0; - - /* conventional + generic attributes */ - for (i = 0 ; i <= _TNL_ATTRIB_GENERIC15 ; i++) { - if (list->attrsz[i]) { - la[nr].target = i; - la[nr].sz = list->attrsz[i]; - la[nr].func = vert_attrfunc[list->attrsz[i]-1]; - nr++; - } - } - - /* material attributes */ - for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT ; - i <= _TNL_ATTRIB_MAT_BACK_INDEXES ; - i++) { - if (list->attrsz[i]) { - la[nr].target = i; - la[nr].sz = list->attrsz[i]; - la[nr].func = mat_attrfunc[list->attrsz[i]-1]; - nr++; - } - } - - /* special-case: edgeflag */ - if (list->attrsz[_TNL_ATTRIB_EDGEFLAG]) { - la[nr].target = _TNL_ATTRIB_EDGEFLAG; - la[nr].sz = list->attrsz[_TNL_ATTRIB_EDGEFLAG]; - la[nr].func = edgeflag_attr1fv; - nr++; - } - - for (i = 0 ; i < list->prim_count ; i++) { - if (list->prim[i].mode & PRIM_WEAK) - loopback_weak_prim( ctx, list, i, la, nr ); - else - loopback_prim( ctx, list, i, la, nr ); - } -} diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c deleted file mode 100644 index 9504f0fe680..00000000000 --- a/src/mesa/tnl/t_save_playback.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2004 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - -/* Author: - * Keith Whitwell - */ - -#include "glheader.h" -#include "context.h" -#include "imports.h" -#include "mtypes.h" -#include "macros.h" -#include "light.h" -#include "state.h" -#include "t_pipeline.h" -#include "t_save_api.h" -#include "t_vtx_api.h" - -static INLINE GLint get_size( const GLfloat *f ) -{ - if (f[3] != 1.0) return 4; - if (f[2] != 0.0) return 3; - return 2; -} - - -/* Some nasty stuff still hanging on here. - * - * TODO - remove VB->ColorPtr, etc and just use the AttrPtr's. - */ -static void _tnl_bind_vertex_list( GLcontext *ctx, - const struct tnl_vertex_list *node ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - struct tnl_vertex_arrays *tmp = &tnl->save_inputs; - GLfloat *data = node->buffer; - GLuint attr, i; - - /* Setup constant data in the VB. - */ - VB->Count = node->count; - VB->Primitive = node->prim; - VB->PrimitiveCount = node->prim_count; - VB->Elts = NULL; - VB->NormalLengthPtr = node->normal_lengths; - - for (attr = 0; attr <= _TNL_ATTRIB_EDGEFLAG; attr++) { - if (node->attrsz[attr]) { - tmp->Attribs[attr].count = node->count; - tmp->Attribs[attr].data = (GLfloat (*)[4]) data; - tmp->Attribs[attr].start = data; - tmp->Attribs[attr].size = node->attrsz[attr]; - tmp->Attribs[attr].stride = node->vertex_size * sizeof(GLfloat); - VB->AttribPtr[attr] = &tmp->Attribs[attr]; - data += node->attrsz[attr]; - } - else { - tmp->Attribs[attr].count = 1; - tmp->Attribs[attr].data = (GLfloat (*)[4]) tnl->vtx.current[attr]; - tmp->Attribs[attr].start = tnl->vtx.current[attr]; - tmp->Attribs[attr].size = get_size( tnl->vtx.current[attr] ); - tmp->Attribs[attr].stride = 0; - VB->AttribPtr[attr] = &tmp->Attribs[attr]; - } - } - - - /* Copy edgeflag to a contiguous array - */ - if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) { - if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) { - VB->EdgeFlag = _tnl_translate_edgeflag( ctx, data, - node->count, - node->vertex_size ); - data++; - } - else - VB->EdgeFlag = _tnl_import_current_edgeflag( ctx, node->count ); - } - - /* Legacy pointers -- remove one day. - */ - VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS]; - VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; - VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0]; - VB->ColorPtr[1] = NULL; - VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX]; - VB->IndexPtr[1] = NULL; - VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1]; - VB->SecondaryColorPtr[1] = NULL; - VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG]; - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]; - } -} - -static void _playback_copy_to_current( GLcontext *ctx, - const struct tnl_vertex_list *node ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - const GLfloat *data; - GLuint i; - - if (node->count) - data = node->buffer + (node->count-1) * node->vertex_size; - else - data = node->buffer; - - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) { - if (node->attrsz[i]) { - COPY_CLEAN_4V(tnl->vtx.current[i], node->attrsz[i], data); - data += node->attrsz[i]; - } - } - - /* Edgeflag requires special treatment: - */ - if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (data[0] == 1.0); - } - - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled) { - _mesa_update_color_material(ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); - } - - if (node->have_materials) { - tnl->Driver.NotifyMaterialChange( ctx ); - } - - /* CurrentExecPrimitive - */ - if (node->prim_count) { - GLenum mode = node->prim[node->prim_count - 1].mode; - if (mode & PRIM_END) - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - else - ctx->Driver.CurrentExecPrimitive = (mode & PRIM_MODE_MASK); - } -} - - -/** - * Execute the buffer and save copied verts. - */ -void _tnl_playback_vertex_list( GLcontext *ctx, void *data ) -{ - const struct tnl_vertex_list *node = (const struct tnl_vertex_list *) data; - TNLcontext *tnl = TNL_CONTEXT(ctx); - - FLUSH_CURRENT(ctx, 0); - - if (node->prim_count > 0 && node->count > 0) { - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && - (node->prim[0].mode & PRIM_BEGIN)) { - - /* Degenerate case: list is called inside begin/end pair and - * includes operations such as glBegin or glDrawArrays. - */ - _mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin"); - _tnl_loopback_vertex_list( ctx, node ); - return; - } - else if (tnl->save.replay_flags) { - /* Various degnerate cases: translate into immediate mode - * calls rather than trying to execute in place. - */ - _tnl_loopback_vertex_list( ctx, node ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || - (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBegin (invalid vertex/fragment program)"); - return; - } - - _tnl_bind_vertex_list( ctx, node ); - - tnl->Driver.RunPipeline( ctx ); - } - - /* Copy to current? - */ - _playback_copy_to_current( ctx, node ); -} diff --git a/src/mesa/tnl/t_vb_render.c b/src/mesa/tnl/t_vb_render.c index 163fa312579..c38f0745e1b 100644 --- a/src/mesa/tnl/t_vb_render.c +++ b/src/mesa/tnl/t_vb_render.c @@ -305,7 +305,7 @@ static GLboolean run_render( GLcontext *ctx, for (i = 0 ; i < VB->PrimitiveCount ; i++) { - GLuint prim = VB->Primitive[i].mode; + GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; diff --git a/src/mesa/tnl/t_vb_rendertmp.h b/src/mesa/tnl/t_vb_rendertmp.h index 90319eddfc5..2b5f4e93b22 100644 --- a/src/mesa/tnl/t_vb_rendertmp.h +++ b/src/mesa/tnl/t_vb_rendertmp.h @@ -45,8 +45,8 @@ #endif #ifndef TEST_PRIM_END -#define TEST_PRIM_END(flags) (flags & PRIM_END) -#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN) +#define TEST_PRIM_END(prim) (flags & PRIM_END) +#define TEST_PRIM_BEGIN(prim) (flags & PRIM_BEGIN) #endif #ifndef ELT diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c deleted file mode 100644 index cc00dfda302..00000000000 --- a/src/mesa/tnl/t_vtx_api.c +++ /dev/null @@ -1,1045 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -on 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 -TUNGSTEN GRAPHICS 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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - */ - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "vtxfmt.h" -#include "dlist.h" -#include "state.h" -#include "light.h" -#include "api_arrayelt.h" -#include "api_noop.h" -#include "t_vtx_api.h" -#include "simple_list.h" - -#include "dispatch.h" - -static void reset_attrfv( TNLcontext *tnl ); - -/** Note extra space for error index: */ -static tnl_attrfv_func choose[_TNL_ATTRIB_ERROR+1][4]; -static tnl_attrfv_func generic_attr_func[_TNL_MAX_ATTR_CODEGEN][4]; - - -/* Close off the last primitive, execute the buffer, restart the - * primitive. - */ -static void _tnl_wrap_buffers( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - - if (tnl->vtx.prim_count == 0) { - tnl->vtx.copied.nr = 0; - tnl->vtx.counter = tnl->vtx.initial_counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - } - else { - GLuint last_prim = tnl->vtx.prim[tnl->vtx.prim_count-1].mode; - GLuint last_count; - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - GLint i = tnl->vtx.prim_count - 1; - assert(i >= 0); - tnl->vtx.prim[i].count = ((tnl->vtx.initial_counter - - tnl->vtx.counter) - - tnl->vtx.prim[i].start); - } - - last_count = tnl->vtx.prim[tnl->vtx.prim_count-1].count; - - /* Execute the buffer and save copied vertices. - */ - if (tnl->vtx.counter != tnl->vtx.initial_counter) - _tnl_flush_vtx( ctx ); - else { - tnl->vtx.prim_count = 0; - tnl->vtx.copied.nr = 0; - } - - /* Emit a glBegin to start the new list. - */ - assert(tnl->vtx.prim_count == 0); - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - tnl->vtx.prim[0].mode = ctx->Driver.CurrentExecPrimitive; - tnl->vtx.prim[0].start = 0; - tnl->vtx.prim[0].count = 0; - tnl->vtx.prim_count++; - - if (tnl->vtx.copied.nr == last_count) - tnl->vtx.prim[0].mode |= last_prim & PRIM_BEGIN; - } - } -} - - -/* Deal with buffer wrapping where provoked by the vertex buffer - * filling up, as opposed to upgrade_vertex(). - * - * Make it GLAPIENTRY, so we can tail from the codegen'ed Vertex*fv - */ -void GLAPIENTRY _tnl_wrap_filled_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat *data = tnl->vtx.copied.buffer; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to tnl->copied. - */ - _tnl_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(tnl->vtx.counter > tnl->vtx.copied.nr); - - for (i = 0 ; i < tnl->vtx.copied.nr ; i++) { - _mesa_memcpy( tnl->vtx.vbptr, data, - tnl->vtx.vertex_size * sizeof(GLfloat)); - tnl->vtx.vbptr += tnl->vtx.vertex_size; - data += tnl->vtx.vertex_size; - tnl->vtx.counter--; - } - - tnl->vtx.copied.nr = 0; -} - - -/* - * Copy the active vertex's values to the ctx->Current fields. - */ -static void _tnl_copy_to_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - for (i = _TNL_ATTRIB_POS+1 ; i < _TNL_ATTRIB_EDGEFLAG ; i++) { - if (tnl->vtx.attrsz[i]) { - /* Note: the tnl->vtx.current[i] pointers points to - * the ctx->Current fields. The first 16 or so, anyway. - */ - COPY_CLEAN_4V(tnl->vtx.current[i], - tnl->vtx.attrsz[i], - tnl->vtx.attrptr[i]); - } - } - - /* Edgeflag requires additional treatment: - */ - if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = - (tnl->vtx.CurrentFloatEdgeFlag == 1.0); - } - - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled) { - _mesa_update_color_material(ctx, - ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); - } - - if (tnl->vtx.have_materials) { - tnl->Driver.NotifyMaterialChange( ctx ); - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - - -static void _tnl_copy_from_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - /* Edgeflag requires additional treatment: - */ - tnl->vtx.CurrentFloatEdgeFlag = (GLfloat) ctx->Current.EdgeFlag; - - for (i = _TNL_ATTRIB_POS+1 ; i < _TNL_ATTRIB_MAX ; i++) - switch (tnl->vtx.attrsz[i]) { - case 4: tnl->vtx.attrptr[i][3] = tnl->vtx.current[i][3]; - case 3: tnl->vtx.attrptr[i][2] = tnl->vtx.current[i][2]; - case 2: tnl->vtx.attrptr[i][1] = tnl->vtx.current[i][1]; - case 1: tnl->vtx.attrptr[i][0] = tnl->vtx.current[i][0]; - break; - } - - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz; - GLuint i; - GLfloat *tmp; - GLint lastcount = tnl->vtx.initial_counter - tnl->vtx.counter; - - /* Run pipeline on current vertices, copy wrapped vertices - * to tnl->vtx.copied. - */ - _tnl_wrap_buffers( ctx ); - - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _tnl_copy_to_current( ctx ); - - - /* Heuristic: Attempt to isolate attributes received outside - * begin/end so that they don't bloat the vertices. - */ - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && - tnl->vtx.attrsz[attr] == 0 && - lastcount > 8 && - tnl->vtx.vertex_size) { - reset_attrfv( tnl ); - } - - /* Fix up sizes: - */ - oldsz = tnl->vtx.attrsz[attr]; - tnl->vtx.attrsz[attr] = newsz; - - tnl->vtx.vertex_size += newsz - oldsz; - tnl->vtx.counter = MIN2( VERT_BUFFER_SIZE / tnl->vtx.vertex_size, - ctx->Const.MaxArrayLockSize ); - tnl->vtx.initial_counter = tnl->vtx.counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - - - /* Recalculate all the attrptr[] values - */ - for (i = 0, tmp = tnl->vtx.vertex ; i < _TNL_ATTRIB_MAX ; i++) { - if (tnl->vtx.attrsz[i]) { - tnl->vtx.attrptr[i] = tmp; - tmp += tnl->vtx.attrsz[i]; - } - else - tnl->vtx.attrptr[i] = NULL; /* will not be dereferenced */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _tnl_copy_from_current( ctx ); - - /* Replay stored vertices to translate them - * to new format here. - * - * -- No need to replay - just copy piecewise - */ - if (tnl->vtx.copied.nr) - { - const GLfloat *data = tnl->vtx.copied.buffer; - GLfloat *dest = tnl->vtx.buffer; - GLuint j; - - for (i = 0 ; i < tnl->vtx.copied.nr ; i++) { - for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { - if (tnl->vtx.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } else { - COPY_SZ_4V( dest, newsz, tnl->vtx.current[j] ); - dest += newsz; - } - } - else { - GLuint sz = tnl->vtx.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - dest += sz; - data += sz; - } - } - } - } - - tnl->vtx.vbptr = dest; - tnl->vtx.counter -= tnl->vtx.copied.nr; - tnl->vtx.copied.nr = 0; - } - - /* For codegen - attrptr's may have changed, so need to redo - * codegen. Might be a reasonable place to try & detect attributes - * in the vertex which aren't being submitted any more. - */ - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - if (tnl->vtx.attrsz[i]) { - GLuint j = tnl->vtx.attrsz[i] - 1; - - if (i < _TNL_MAX_ATTR_CODEGEN) - tnl->vtx.tabfv[i][j] = choose[i][j]; - } - -} - - -static void _tnl_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - static const GLfloat id[4] = { 0, 0, 0, 1 }; - int i; - - if (0) - _mesa_printf("%s attr %d sz %d -> %d\n", - __FUNCTION__, attr, tnl->vtx.attrsz[attr], sz); - - if (tnl->vtx.attrsz[attr] < sz) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _tnl_wrap_upgrade_vertex( ctx, attr, sz ); - } - else if (sz < tnl->vtx.active_sz[attr]) { - /* New size is smaller - just need to fill in some - * zeros. Don't need to flush or wrap. - */ - for (i = sz ; i <= tnl->vtx.attrsz[attr] ; i++) - tnl->vtx.attrptr[attr][i-1] = id[i-1]; - } - - tnl->vtx.active_sz[attr] = sz; - - /* Does setting NeedFlush belong here? Necessitates resetting - * vtxfmt on each flush (otherwise flags won't get reset - * afterwards). - */ - if (attr == 0) - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - else - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - -#ifdef USE_X86_ASM - -static struct _tnl_dynfn *lookup( struct _tnl_dynfn *l, GLuint key ) -{ - struct _tnl_dynfn *f; - - foreach( f, l ) { - if (f->key == key) - return f; - } - - return NULL; -} - - -static tnl_attrfv_func do_codegen( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct _tnl_dynfn *dfn = NULL; - - if (attr == 0) { - GLuint key = tnl->vtx.vertex_size; - - dfn = lookup( &tnl->vtx.cache.Vertex[sz-1], key ); - - if (!dfn) - dfn = tnl->vtx.gen.Vertex[sz-1]( ctx, key ); - } - else { - GLuint key = (GLuint) tnl->vtx.attrptr[attr]; - - dfn = lookup( &tnl->vtx.cache.Attribute[sz-1], key ); - - if (!dfn) - dfn = tnl->vtx.gen.Attribute[sz-1]( ctx, key ); - } - - if (dfn) - return *(tnl_attrfv_func *) &dfn->code; - else - return NULL; -} - -#endif /* USE_X86_ASM */ - -/* Helper function for 'CHOOSE' macro. Do what's necessary when an - * entrypoint is called for the first time. - */ - -static tnl_attrfv_func do_choose( GLuint attr, GLuint sz ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz = tnl->vtx.active_sz[attr]; - - assert(attr < _TNL_MAX_ATTR_CODEGEN); - - if (oldsz != sz) { - /* Reset any active pointers for this attribute - */ - if (oldsz) - tnl->vtx.tabfv[attr][oldsz-1] = choose[attr][oldsz-1]; - - _tnl_fixup_vertex( ctx, attr, sz ); - - } - - - /* Try to use codegen: - */ -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) - tnl->vtx.tabfv[attr][sz-1] = do_codegen( ctx, attr, sz ); - else -#endif - tnl->vtx.tabfv[attr][sz-1] = NULL; - - /* Else use generic version: - */ - if (!tnl->vtx.tabfv[attr][sz-1]) - tnl->vtx.tabfv[attr][sz-1] = generic_attr_func[attr][sz-1]; - - ASSERT(tnl->vtx.tabfv[attr][sz-1]); - return tnl->vtx.tabfv[attr][sz-1]; -} - - - -#define CHOOSE( ATTR, N ) \ -static void choose_##ATTR##_##N( const GLfloat *v ) \ -{ \ - tnl_attrfv_func f = do_choose(ATTR, N); \ - ASSERT(f); \ - f( v ); \ -} - -#define CHOOSERS( ATTRIB ) \ - CHOOSE( ATTRIB, 1 ) \ - CHOOSE( ATTRIB, 2 ) \ - CHOOSE( ATTRIB, 3 ) \ - CHOOSE( ATTRIB, 4 ) \ - - -#define INIT_CHOOSERS(ATTR) \ - ASSERT(ATTR <= _TNL_ATTRIB_ERROR);\ - choose[ATTR][0] = choose_##ATTR##_1; \ - choose[ATTR][1] = choose_##ATTR##_2; \ - choose[ATTR][2] = choose_##ATTR##_3; \ - choose[ATTR][3] = choose_##ATTR##_4; - -/* conventional attributes */ -CHOOSERS( 0 ) -CHOOSERS( 1 ) -CHOOSERS( 2 ) -CHOOSERS( 3 ) -CHOOSERS( 4 ) -CHOOSERS( 5 ) -CHOOSERS( 6 ) -CHOOSERS( 7 ) -CHOOSERS( 8 ) -CHOOSERS( 9 ) -CHOOSERS( 10 ) -CHOOSERS( 11 ) -CHOOSERS( 12 ) -CHOOSERS( 13 ) -CHOOSERS( 14 ) -CHOOSERS( 15 ) - -/* generic attributes */ -CHOOSERS( 16 ) -CHOOSERS( 17 ) -CHOOSERS( 18 ) -CHOOSERS( 19 ) -CHOOSERS( 20 ) -CHOOSERS( 21 ) -CHOOSERS( 22 ) -CHOOSERS( 23 ) -CHOOSERS( 24 ) -CHOOSERS( 25 ) -CHOOSERS( 26 ) -CHOOSERS( 27 ) -CHOOSERS( 28 ) -CHOOSERS( 29 ) -CHOOSERS( 30 ) -CHOOSERS( 31 ) - - -/** - * This function will get called when glVertexAttribNV/ARB() is called - * with an invalid index parameter. - */ -static void -error_attrib(const GLfloat *unused) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) unused; - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib(index)" ); -} - - - -/** - * Reset all the per-vertex functions pointers to point to the default - * "chooser" functions. - */ -static void -reset_attrfv(TNLcontext *tnl) -{ - GLuint i; - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - if (tnl->vtx.attrsz[i]) { - GLint j = tnl->vtx.attrsz[i] - 1; - tnl->vtx.attrsz[i] = 0; - tnl->vtx.active_sz[i] = 0; - - if (i < _TNL_MAX_ATTR_CODEGEN) { - while (j >= 0) { - tnl->vtx.tabfv[i][j] = choose[i][j]; - j--; - } - } - } - - tnl->vtx.vertex_size = 0; - tnl->vtx.have_materials = 0; -} - - - -/** - * Materials: - * - * These are treated as per-vertex attributes, at indices above where - * the NV_vertex_program leaves off. There are a lot of good things - * about treating materials this way. - * - * However: I don't want to double the number of generated functions - * just to cope with this, so I unroll the 'C' varients of CHOOSE and - * ATTRF into this function, and dispense with codegen and - * second-level dispatch. - * - * There is no aliasing of material attributes with other entrypoints. - */ -#define OTHER_ATTR( A, N, params ) \ -do { \ - if (tnl->vtx.active_sz[A] != N) { \ - _tnl_fixup_vertex( ctx, A, N ); \ - } \ - \ - { \ - GLfloat *dest = tnl->vtx.attrptr[A]; \ - if (N>0) dest[0] = (params)[0]; \ - if (N>1) dest[1] = (params)[1]; \ - if (N>2) dest[2] = (params)[2]; \ - if (N>3) dest[3] = (params)[3]; \ - } \ -} while (0) - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - OTHER_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - OTHER_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/** - * Called by glMaterialfv(). - * Colormaterial is dealt with later on. - */ -static void GLAPIENTRY -_tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - switch (face) { - case GL_FRONT: - case GL_BACK: - case GL_FRONT_AND_BACK: - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } - - switch (pname) { - case GL_EMISSION: - MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } - - tnl->vtx.have_materials = GL_TRUE; -} - - -static void GLAPIENTRY _tnl_EdgeFlag( GLboolean b ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat f = (GLfloat)b; - - OTHER_ATTR( _TNL_ATTRIB_EDGEFLAG, 1, &f ); -} - - -/* Eval - */ -static void GLAPIENTRY _tnl_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* TODO: use a CHOOSE() function for this: */ - { - GLint i; - if (tnl->vtx.eval.new_state) - _tnl_update_eval( ctx ); - - for (i = 0; i < _TNL_NUM_EVAL; i++) { - if (tnl->vtx.eval.map1[i].map) - if (tnl->vtx.active_sz[i] != tnl->vtx.eval.map1[i].sz) - _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map1[i].sz ); - } - } - - - _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, - tnl->vtx.vertex_size * sizeof(GLfloat)); - - _tnl_do_EvalCoord1f( ctx, u ); - - _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, - tnl->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY _tnl_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* TODO: use a CHOOSE() function for this: */ - { - GLint i; - if (tnl->vtx.eval.new_state) - _tnl_update_eval( ctx ); - - for (i = 0; i < _TNL_NUM_EVAL; i++) { - if (tnl->vtx.eval.map2[i].map) - if (tnl->vtx.active_sz[i] != tnl->vtx.eval.map2[i].sz) - _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map2[i].sz ); - } - - if (ctx->Eval.AutoNormal) - if (tnl->vtx.active_sz[_TNL_ATTRIB_NORMAL] != 3) - _tnl_fixup_vertex( ctx, _TNL_ATTRIB_NORMAL, 3 ); - } - - _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, - tnl->vtx.vertex_size * sizeof(GLfloat)); - - _tnl_do_EvalCoord2f( ctx, u, v ); - - _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, - tnl->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY _tnl_EvalCoord1fv( const GLfloat *u ) -{ - _tnl_EvalCoord1f( u[0] ); -} - -static void GLAPIENTRY _tnl_EvalCoord2fv( const GLfloat *u ) -{ - _tnl_EvalCoord2f( u[0], u[1] ); -} - -static void GLAPIENTRY _tnl_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / - (GLfloat) ctx->Eval.MapGrid1un); - GLfloat u = i * du + ctx->Eval.MapGrid1u1; - - _tnl_EvalCoord1f( u ); -} - - -static void GLAPIENTRY _tnl_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / - (GLfloat) ctx->Eval.MapGrid2un); - GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / - (GLfloat) ctx->Eval.MapGrid2vn); - GLfloat u = i * du + ctx->Eval.MapGrid2u1; - GLfloat v = j * dv + ctx->Eval.MapGrid2v1; - - _tnl_EvalCoord2f( u, v ); -} - - -/** - * Called from glBegin. - * ctx->Driver.CurrentExecPrimitive will be set to . - */ -static void GLAPIENTRY _tnl_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (mode > GL_POLYGON) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBegin(mode)"); - return; - } - - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { - /* we're not inside a glBegin/End pair */ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - if (ctx->NewState) { - _mesa_update_state( ctx ); - - if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || - (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBegin (invalid vertex/fragment program)"); - tnl->DiscardPrimitive = GL_TRUE; - return; - } - - if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "glBegin(incomplete framebuffer)"); - tnl->DiscardPrimitive = GL_TRUE; - return; - } - - tnl->DiscardPrimitive = GL_FALSE; - - if (!(tnl->Driver.NotifyBegin && - tnl->Driver.NotifyBegin( ctx, mode ))) - CALL_Begin(ctx->Exec, (mode)); - return; - } - - /* Heuristic: attempt to isolate attributes occuring outside - * begin/end pairs. - */ - if (tnl->vtx.vertex_size && !tnl->vtx.attrsz[0]) - _tnl_FlushVertices( ctx, ~0 ); - - i = tnl->vtx.prim_count++; - tnl->vtx.prim[i].mode = mode | PRIM_BEGIN; - tnl->vtx.prim[i].start = tnl->vtx.initial_counter - tnl->vtx.counter; - tnl->vtx.prim[i].count = 0; - - ctx->Driver.CurrentExecPrimitive = mode; - } - else { - /* already inside glBegin/End */ - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - } -} - - -/** - * Called from glEnd. - */ -static void GLAPIENTRY _tnl_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - /* closing an open glBegin primitive */ - TNLcontext *tnl = TNL_CONTEXT(ctx); - int idx = tnl->vtx.initial_counter - tnl->vtx.counter; - int i = tnl->vtx.prim_count - 1; - - tnl->vtx.prim[i].mode |= PRIM_END; - tnl->vtx.prim[i].count = idx - tnl->vtx.prim[i].start; - - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - - /* Two choices which effect the way vertex attributes are - * carried over (or not) between adjacent primitives. - */ -#if 0 - if (tnl->vtx.prim_count == TNL_MAX_PRIM) - _tnl_FlushVertices( ctx, ~0 ); -#else - if (tnl->vtx.prim_count == TNL_MAX_PRIM) - _tnl_flush_vtx( ctx ); -#endif - - } - else { - /* glBegin hasn't been called! */ - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - } -} - - -/** - * XXX why aren't all members initialized here?? - */ -static void _tnl_exec_vtxfmt_init( GLcontext *ctx ) -{ - GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt); - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _tnl_Begin; - vfmt->CallList = _mesa_CallList; - vfmt->CallLists = _mesa_CallLists; - vfmt->EdgeFlag = _tnl_EdgeFlag; - vfmt->End = _tnl_End; - vfmt->EvalCoord1f = _tnl_EvalCoord1f; - vfmt->EvalCoord1fv = _tnl_EvalCoord1fv; - vfmt->EvalCoord2f = _tnl_EvalCoord2f; - vfmt->EvalCoord2fv = _tnl_EvalCoord2fv; - vfmt->EvalPoint1 = _tnl_EvalPoint1; - vfmt->EvalPoint2 = _tnl_EvalPoint2; - vfmt->Materialfv = _tnl_Materialfv; - - vfmt->Rectf = _mesa_noop_Rectf; - vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; - vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; -} - - - -void _tnl_FlushVertices( GLcontext *ctx, GLuint flags ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - (void) flags; - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - /* still inside a glBegin/End pair. How'd we get here??? */ - return; - } - - if (tnl->DiscardPrimitive) { - /* discard any primitives */ - tnl->vtx.prim_count = 0; - tnl->vtx.counter = tnl->vtx.initial_counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - } - - if (tnl->vtx.counter != tnl->vtx.initial_counter) { - _tnl_flush_vtx( ctx ); - } - - if (tnl->vtx.vertex_size) { - _tnl_copy_to_current( ctx ); - reset_attrfv( tnl ); - } - - ctx->Driver.NeedFlush = 0; -} - - -/** - * Init the tnl->vtx->current[] pointers to point to the corresponding - * fields in ctx->Current attribute group. - */ -static void _tnl_current_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - /* setup the pointers for the typical (32) vertex attributes */ - for (i = 0; i < VERT_ATTRIB_MAX; i++) - tnl->vtx.current[i] = ctx->Current.Attrib[i]; - - /* setup pointers for the 12 material attributes */ - for (i = 0; i < MAT_ATTRIB_MAX; i++) - tnl->vtx.current[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = - ctx->Light.Material.Attrib[i]; - - /* special case */ - tnl->vtx.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->vtx.CurrentFloatEdgeFlag; -} - -static struct _tnl_dynfn *no_codegen( GLcontext *ctx, int key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void _tnl_vtx_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs; - GLuint i; - static int firsttime = 1; - - if (firsttime) { - firsttime = 0; - - /* conventional attributes */ - INIT_CHOOSERS( 0 ); - INIT_CHOOSERS( 1 ); - INIT_CHOOSERS( 2 ); - INIT_CHOOSERS( 3 ); - INIT_CHOOSERS( 4 ); - INIT_CHOOSERS( 5 ); - INIT_CHOOSERS( 6 ); - INIT_CHOOSERS( 7 ); - INIT_CHOOSERS( 8 ); - INIT_CHOOSERS( 9 ); - INIT_CHOOSERS( 10 ); - INIT_CHOOSERS( 11 ); - INIT_CHOOSERS( 12 ); - INIT_CHOOSERS( 13 ); - INIT_CHOOSERS( 14 ); - INIT_CHOOSERS( 15 ); - - /* generic attributes */ - INIT_CHOOSERS( 16 ); - INIT_CHOOSERS( 17 ); - INIT_CHOOSERS( 18 ); - INIT_CHOOSERS( 19 ); - INIT_CHOOSERS( 20 ); - INIT_CHOOSERS( 21 ); - INIT_CHOOSERS( 22 ); - INIT_CHOOSERS( 23 ); - INIT_CHOOSERS( 24 ); - INIT_CHOOSERS( 25 ); - INIT_CHOOSERS( 26 ); - INIT_CHOOSERS( 27 ); - INIT_CHOOSERS( 28 ); - INIT_CHOOSERS( 29 ); - INIT_CHOOSERS( 30 ); - INIT_CHOOSERS( 31 ); - - choose[_TNL_ATTRIB_ERROR][0] = error_attrib; - choose[_TNL_ATTRIB_ERROR][1] = error_attrib; - choose[_TNL_ATTRIB_ERROR][2] = error_attrib; - choose[_TNL_ATTRIB_ERROR][3] = error_attrib; - -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) { - _tnl_x86choosers(choose, do_choose); /* x86 INIT_CHOOSERS */ - } -#endif - - _tnl_generic_attr_table_init( generic_attr_func ); - } - - for (i = 0; i < _TNL_ATTRIB_EDGEFLAG; i++) - _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); - - for (i = 0; i < 4; i++) { - make_empty_list( &tnl->vtx.cache.Vertex[i] ); - make_empty_list( &tnl->vtx.cache.Attribute[i] ); - tnl->vtx.gen.Vertex[i] = no_codegen; - tnl->vtx.gen.Attribute[i] = no_codegen; - } - -#ifdef USE_X86_ASM - _tnl_InitX86Codegen( &tnl->vtx.gen ); -#endif - - _tnl_current_init( ctx ); - _tnl_exec_vtxfmt_init( ctx ); - _tnl_generic_exec_vtxfmt_init( ctx ); -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) { - _tnl_x86_exec_vtxfmt_init( ctx ); /* x86 DISPATCH_ATTRFV */ - } -#endif - - _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt ); - - _mesa_memcpy( tnl->vtx.tabfv, choose, sizeof(choose) ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) { - tnl->vtx.attrsz[i] = 0; - tnl->vtx.active_sz[i] = 0; - } - - tnl->vtx.vertex_size = 0; - tnl->vtx.have_materials = 0; -} - -static void free_funcs( struct _tnl_dynfn *l ) -{ - struct _tnl_dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - ALIGN_FREE( f->code ); - FREE( f ); - } -} - - -void _tnl_vtx_destroy( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - for (i = 0; i < 4; i++) { - free_funcs( &tnl->vtx.cache.Vertex[i] ); - free_funcs( &tnl->vtx.cache.Attribute[i] ); - } -} - diff --git a/src/mesa/tnl/t_vtx_api.h b/src/mesa/tnl/t_vtx_api.h deleted file mode 100644 index 5311f40a852..00000000000 --- a/src/mesa/tnl/t_vtx_api.h +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -on 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 -TUNGSTEN GRAPHICS 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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - * - */ - -#ifndef __T_VTX_API_H__ -#define __T_VTX_API_H__ - -#include "t_context.h" - - -/* t_vtx_api.c: - */ -extern void _tnl_vtx_init( GLcontext *ctx ); -extern void _tnl_vtx_destroy( GLcontext *ctx ); - -extern void _tnl_FlushVertices( GLcontext *ctx, GLuint flags ); -extern void _tnl_flush_vtx( GLcontext *ctx ); - -extern void GLAPIENTRY _tnl_wrap_filled_vertex( GLcontext *ctx ); - -/* t_vtx_exec.c: - */ - -extern void _tnl_do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v ); -extern void _tnl_do_EvalCoord1f(GLcontext* ctx, GLfloat u); -extern void _tnl_update_eval( GLcontext *ctx ); - -extern GLboolean *_tnl_translate_edgeflag( GLcontext *ctx, - const GLfloat *data, - GLuint count, - GLuint stride ); - -extern GLboolean *_tnl_import_current_edgeflag( GLcontext *ctx, - GLuint count ); - - - -/* t_vtx_generic.c: - */ -extern void _tnl_generic_exec_vtxfmt_init( GLcontext *ctx ); - -extern void _tnl_generic_attr_table_init( tnl_attrfv_func (*tab)[4] ); - -/* t_vtx_x86.c: - */ -extern void _tnl_InitX86Codegen( struct _tnl_dynfn_generators *gen ); - -extern void _tnl_x86_exec_vtxfmt_init( GLcontext *ctx ); - -extern void _tnl_x86choosers( tnl_attrfv_func (*choose)[4], - tnl_attrfv_func (*do_choose)( GLuint attr, - GLuint sz )); - - - - -#endif diff --git a/src/mesa/tnl/t_vtx_eval.c b/src/mesa/tnl/t_vtx_eval.c deleted file mode 100644 index 71564076e37..00000000000 --- a/src/mesa/tnl/t_vtx_eval.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - * - * Authors: - * Keith Whitwell - */ - -#include "glheader.h" -#include "api_eval.h" -#include "context.h" -#include "macros.h" -#include "math/m_eval.h" -#include "t_vtx_api.h" -#include "dispatch.h" - - -static void clear_active_eval1( TNLcontext *tnl, GLuint attr ) -{ - ASSERT(attr < _TNL_NUM_EVAL); - tnl->vtx.eval.map1[attr].map = NULL; -} - -static void clear_active_eval2( TNLcontext *tnl, GLuint attr ) -{ - ASSERT(attr < _TNL_NUM_EVAL); - tnl->vtx.eval.map2[attr].map = NULL; -} - -static void set_active_eval1( TNLcontext *tnl, GLuint attr, GLuint dim, - struct gl_1d_map *map ) -{ - ASSERT(attr < _TNL_NUM_EVAL); - if (!tnl->vtx.eval.map1[attr].map) { - tnl->vtx.eval.map1[attr].map = map; - tnl->vtx.eval.map1[attr].sz = dim; - } -} - -static void set_active_eval2( TNLcontext *tnl, GLuint attr, GLuint dim, - struct gl_2d_map *map ) -{ - ASSERT(attr < _TNL_NUM_EVAL); - if (!tnl->vtx.eval.map2[attr].map) { - tnl->vtx.eval.map2[attr].map = map; - tnl->vtx.eval.map2[attr].sz = dim; - } -} - -void _tnl_update_eval( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint attr; - - /* Vertex program maps have priority over conventional attribs */ - - for (attr = 0; attr < _TNL_NUM_EVAL; attr++) { - clear_active_eval1( tnl, attr ); - clear_active_eval2( tnl, attr ); - } - - if (ctx->Eval.Map1Color4) - set_active_eval1( tnl, VERT_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 ); - - if (ctx->Eval.Map2Color4) - set_active_eval2( tnl, VERT_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map2Color4 ); - - if (ctx->Eval.Map1TextureCoord4) - set_active_eval1( tnl, VERT_ATTRIB_TEX0, 4, &ctx->EvalMap.Map1Texture4 ); - else if (ctx->Eval.Map1TextureCoord3) - set_active_eval1( tnl, VERT_ATTRIB_TEX0, 3, &ctx->EvalMap.Map1Texture3 ); - else if (ctx->Eval.Map1TextureCoord2) - set_active_eval1( tnl, VERT_ATTRIB_TEX0, 2, &ctx->EvalMap.Map1Texture2 ); - else if (ctx->Eval.Map1TextureCoord1) - set_active_eval1( tnl, VERT_ATTRIB_TEX0, 1, &ctx->EvalMap.Map1Texture1 ); - - if (ctx->Eval.Map2TextureCoord4) - set_active_eval2( tnl, VERT_ATTRIB_TEX0, 4, &ctx->EvalMap.Map2Texture4 ); - else if (ctx->Eval.Map2TextureCoord3) - set_active_eval2( tnl, VERT_ATTRIB_TEX0, 3, &ctx->EvalMap.Map2Texture3 ); - else if (ctx->Eval.Map2TextureCoord2) - set_active_eval2( tnl, VERT_ATTRIB_TEX0, 2, &ctx->EvalMap.Map2Texture2 ); - else if (ctx->Eval.Map2TextureCoord1) - set_active_eval2( tnl, VERT_ATTRIB_TEX0, 1, &ctx->EvalMap.Map2Texture1 ); - - if (ctx->Eval.Map1Normal) - set_active_eval1( tnl, VERT_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map1Normal ); - - if (ctx->Eval.Map2Normal) - set_active_eval2( tnl, VERT_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map2Normal ); - - if (ctx->Eval.Map1Vertex4) - set_active_eval1( tnl, VERT_ATTRIB_POS, 4, &ctx->EvalMap.Map1Vertex4 ); - else if (ctx->Eval.Map1Vertex3) - set_active_eval1( tnl, VERT_ATTRIB_POS, 3, &ctx->EvalMap.Map1Vertex3 ); - - if (ctx->Eval.Map2Vertex4) - set_active_eval2( tnl, VERT_ATTRIB_POS, 4, &ctx->EvalMap.Map2Vertex4 ); - else if (ctx->Eval.Map2Vertex3) - set_active_eval2( tnl, VERT_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 ); - - /* Evaluators with generic attributes is only supported for NV vertex - * programs, not ARB vertex programs. 16 evaluator maps are supported. - * We do this after the conventional attributes since the spec says that - * these generic maps have higher priority. - */ - if (ctx->VertexProgram._Enabled && - ctx->VertexProgram._Current && - ctx->VertexProgram._Current->IsNVProgram) { - for (attr = 0; attr < 16; attr++) { - if (ctx->Eval.Map1Attrib[attr]) - set_active_eval1( tnl, attr, 4, &ctx->EvalMap.Map1Attrib[attr] ); - - if (ctx->Eval.Map2Attrib[attr]) - set_active_eval2( tnl, attr, 4, &ctx->EvalMap.Map2Attrib[attr] ); - } - } - - tnl->vtx.eval.new_state = 0; -} - - - -void _tnl_do_EvalCoord1f(GLcontext* ctx, GLfloat u) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint attr; - - for (attr = 1; attr < _TNL_NUM_EVAL; attr++) { - struct gl_1d_map *map = tnl->vtx.eval.map1[attr].map; - if (map) { - GLfloat uu = (u - map->u1) * map->du; - GLfloat data[4]; - - ASSIGN_4V(data, 0, 0, 0, 1); - - _math_horner_bezier_curve(map->Points, data, uu, - tnl->vtx.eval.map1[attr].sz, - map->Order); - - COPY_SZ_4V( tnl->vtx.attrptr[attr], - tnl->vtx.attrsz[attr], - data ); - } - } - - /** Vertex -- EvalCoord1f is a noop if this map not enabled: - **/ - if (tnl->vtx.eval.map1[0].map) { - struct gl_1d_map *map = tnl->vtx.eval.map1[0].map; - GLfloat uu = (u - map->u1) * map->du; - GLfloat vertex[4]; - - ASSIGN_4V(vertex, 0, 0, 0, 1); - - _math_horner_bezier_curve(map->Points, vertex, uu, - tnl->vtx.eval.map1[0].sz, - map->Order); - - if (tnl->vtx.eval.map1[0].sz == 4) - CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); - else - CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); - } -} - - - -void _tnl_do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint attr; - - for (attr = 1; attr < _TNL_NUM_EVAL; attr++) { - struct gl_2d_map *map = tnl->vtx.eval.map2[attr].map; - if (map) { - GLfloat uu = (u - map->u1) * map->du; - GLfloat vv = (v - map->v1) * map->dv; - GLfloat data[4]; - - ASSIGN_4V(data, 0, 0, 0, 1); - - _math_horner_bezier_surf(map->Points, - data, - uu, vv, - tnl->vtx.eval.map2[attr].sz, - map->Uorder, map->Vorder); - - COPY_SZ_4V( tnl->vtx.attrptr[attr], - tnl->vtx.attrsz[attr], - data ); - } - } - - /** Vertex -- EvalCoord2f is a noop if this map not enabled: - **/ - if (tnl->vtx.eval.map2[0].map) { - struct gl_2d_map *map = tnl->vtx.eval.map2[0].map; - GLfloat uu = (u - map->u1) * map->du; - GLfloat vv = (v - map->v1) * map->dv; - GLfloat vertex[4]; - - ASSIGN_4V(vertex, 0, 0, 0, 1); - - if (ctx->Eval.AutoNormal) { - GLfloat normal[4]; - GLfloat du[4], dv[4]; - - _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, - tnl->vtx.eval.map2[0].sz, - map->Uorder, map->Vorder); - - if (tnl->vtx.eval.map2[0].sz == 4) { - du[0] = du[0]*vertex[3] - du[3]*vertex[0]; - du[1] = du[1]*vertex[3] - du[3]*vertex[1]; - du[2] = du[2]*vertex[3] - du[3]*vertex[2]; - - dv[0] = dv[0]*vertex[3] - dv[3]*vertex[0]; - dv[1] = dv[1]*vertex[3] - dv[3]*vertex[1]; - dv[2] = dv[2]*vertex[3] - dv[3]*vertex[2]; - } - - - CROSS3(normal, du, dv); - NORMALIZE_3FV(normal); - normal[3] = 1.0; - - COPY_SZ_4V( tnl->vtx.attrptr[_TNL_ATTRIB_NORMAL], - tnl->vtx.attrsz[_TNL_ATTRIB_NORMAL], - normal ); - - } - else { - _math_horner_bezier_surf(map->Points, vertex, uu, vv, - tnl->vtx.eval.map2[0].sz, - map->Uorder, map->Vorder); - } - - if (tnl->vtx.attrsz[0] == 4) - CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); - else - CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); - } -} - - diff --git a/src/mesa/tnl/t_vtx_exec.c b/src/mesa/tnl/t_vtx_exec.c deleted file mode 100644 index 57d842f05fe..00000000000 --- a/src/mesa/tnl/t_vtx_exec.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - * - * Authors: - * Keith Whitwell - */ - -#include "glheader.h" -#include "api_eval.h" -#include "context.h" -#include "enums.h" -#include "state.h" -#include "macros.h" -#include "math/m_eval.h" -#include "t_vtx_api.h" -#include "t_pipeline.h" - - -static void _tnl_print_vtx( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter; - GLuint i; - - _mesa_debug(ctx, "_tnl_print_vtx: %u vertices %d primitives, %d vertsize\n", - count, - tnl->vtx.prim_count, - tnl->vtx.vertex_size); - - for (i = 0 ; i < tnl->vtx.prim_count ; i++) { - struct tnl_prim *prim = &tnl->vtx.prim[i]; - _mesa_debug(NULL, " prim %d: %s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK), - prim->start, - prim->start + prim->count, - (prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)", - (prim->mode & PRIM_END) ? "END" : "(wrap)"); - } -} - -GLboolean *_tnl_translate_edgeflag( GLcontext *ctx, const GLfloat *data, - GLuint count, GLuint stride ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLboolean *ef = tnl->vtx.edgeflag_tmp; - GLuint i; - - if (!ef) - ef = tnl->vtx.edgeflag_tmp = (GLboolean *) MALLOC( tnl->vb.Size ); - - for (i = 0 ; i < count ; i++, data += stride) - ef[i] = (data[0] == 1.0); - - return ef; -} - - -GLboolean *_tnl_import_current_edgeflag( GLcontext *ctx, - GLuint count ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLboolean *ef = tnl->vtx.edgeflag_tmp; - GLboolean tmp = ctx->Current.EdgeFlag; - GLuint i; - - if (!ef) - ef = tnl->vtx.edgeflag_tmp = (GLboolean *) MALLOC( tnl->vb.Size ); - - for (i = 0 ; i < count ; i++) - ef[i] = tmp; - - return ef; -} - -static INLINE GLint get_size( const GLfloat *f ) -{ - if (f[3] != 1.0) return 4; - if (f[2] != 0.0) return 3; - return 2; -} - -/* Some nasty stuff still hanging on here. - * - * TODO - remove VB->NormalPtr, etc and just use the AttrPtr's. - */ -static void _tnl_vb_bind_vtx( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs; - GLfloat *data = tnl->vtx.buffer; - GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter; - GLuint attr, i; - -#undef DEBUG_VTX - -#ifdef DEBUG_VTX - fprintf(stderr, "_tnl_vb_bind_vtx(): %d verts %d vertsize\n", - count, tnl->vtx.vertex_size); -#endif - - - /* Setup constant data in the VB. - */ - VB->Count = count; - VB->Primitive = tnl->vtx.prim; - VB->PrimitiveCount = tnl->vtx.prim_count; - VB->Elts = NULL; - VB->NormalLengthPtr = NULL; - - for (attr = 0; attr <= _TNL_ATTRIB_EDGEFLAG ; attr++) { - if (tnl->vtx.attrsz[attr]) { - tmp->Attribs[attr].count = count; - tmp->Attribs[attr].data = (GLfloat (*)[4]) data; - tmp->Attribs[attr].start = data; - tmp->Attribs[attr].size = tnl->vtx.attrsz[attr]; - tmp->Attribs[attr].stride = tnl->vtx.vertex_size * sizeof(GLfloat); - VB->AttribPtr[attr] = &tmp->Attribs[attr]; - data += tnl->vtx.attrsz[attr]; - } - else { -/* VB->AttribPtr[attr] = &tnl->current.Attribs[attr]; */ - - - tmp->Attribs[attr].count = 1; - tmp->Attribs[attr].data = (GLfloat (*)[4]) tnl->vtx.current[attr]; - tmp->Attribs[attr].start = tnl->vtx.current[attr]; - tmp->Attribs[attr].size = get_size( tnl->vtx.current[attr] ); - tmp->Attribs[attr].stride = 0; - VB->AttribPtr[attr] = &tmp->Attribs[attr]; - } - } - - - /* Copy and translate EdgeFlag to a contiguous array of GLbooleans - */ - if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) { - if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - VB->EdgeFlag = _tnl_translate_edgeflag( ctx, data, count, - tnl->vtx.vertex_size ); - data++; - } - else - VB->EdgeFlag = _tnl_import_current_edgeflag( ctx, count ); - } - - /* Legacy pointers -- remove one day. - */ - VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS]; - VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; - VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0]; - VB->ColorPtr[1] = NULL; - VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1]; - VB->SecondaryColorPtr[1] = NULL; - VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX]; - VB->IndexPtr[1] = NULL; - VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG]; - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]; - } -} - - -/* - * NOTE: Need to have calculated primitives by this point -- do it on the fly. - * NOTE: Old 'parity' issue is gone. - */ -static GLuint _tnl_copy_vertices( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT( ctx ); - GLuint nr = tnl->vtx.prim[tnl->vtx.prim_count-1].count; - GLuint ovf, i; - GLuint sz = tnl->vtx.vertex_size; - GLfloat *dst = tnl->vtx.copied.buffer; - GLfloat *src = (tnl->vtx.buffer + - tnl->vtx.prim[tnl->vtx.prim_count-1].start * - tnl->vtx.vertex_size); - - - switch( ctx->Driver.CurrentExecPrimitive ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - else { - _mesa_memcpy( dst, src+(nr-1)*sz, sz * sizeof(GLfloat) ); - return 1; - } - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) ); - return 1; - } else { - _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) ); - _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat) ); - return 2; - } - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case PRIM_OUTSIDE_BEGIN_END: - return 0; - default: - assert(0); - return 0; - } -} - - -/** - * Execute the buffer and save copied verts. - */ -void _tnl_flush_vtx( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint vertex_count = tnl->vtx.initial_counter - tnl->vtx.counter; - - if (0) - _tnl_print_vtx( ctx ); - - if (tnl->vtx.prim_count && vertex_count) { - - tnl->vtx.copied.nr = _tnl_copy_vertices( ctx ); - - if (tnl->vtx.copied.nr != vertex_count) { - if (ctx->NewState) - _mesa_update_state( ctx ); - - _tnl_vb_bind_vtx( ctx ); - - tnl->Driver.RunPipeline( ctx ); - } - } - - tnl->vtx.prim_count = 0; - tnl->vtx.counter = tnl->vtx.initial_counter; - tnl->vtx.vbptr = tnl->vtx.buffer; -} diff --git a/src/mesa/tnl/t_vtx_generic.c b/src/mesa/tnl/t_vtx_generic.c deleted file mode 100644 index 28de445ed41..00000000000 --- a/src/mesa/tnl/t_vtx_generic.c +++ /dev/null @@ -1,615 +0,0 @@ -/************************************************************************** - -Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -on 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 -ATI, TUNGSTEN GRAPHICS 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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - */ - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "vtxfmt.h" -#include "dlist.h" -#include "state.h" -#include "light.h" -#include "api_arrayelt.h" -#include "api_noop.h" -#include "t_vtx_api.h" - - -/* Versions of all the entrypoints for situations where codegen isn't - * available. - * - * Note: Only one size for each attribute may be active at once. - * Eg. if Color3f is installed/active, then Color4f may not be, even - * if the vertex actually contains 4 color coordinates. This is - * because the 3f version won't otherwise set color[3] to 1.0 -- this - * is the job of the chooser function when switching between Color4f - * and Color3f. - */ -#define ATTRFV( ATTR, N ) \ -static void attrib_##ATTR##_##N( const GLfloat *v ) \ -{ \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if ((ATTR) == 0) { \ - GLuint i; \ - \ - if (N>0) tnl->vtx.vbptr[0] = v[0]; \ - if (N>1) tnl->vtx.vbptr[1] = v[1]; \ - if (N>2) tnl->vtx.vbptr[2] = v[2]; \ - if (N>3) tnl->vtx.vbptr[3] = v[3]; \ - \ - for (i = N; i < tnl->vtx.vertex_size; i++) \ - tnl->vtx.vbptr[i] = tnl->vtx.vertex[i]; \ - \ - tnl->vtx.vbptr += tnl->vtx.vertex_size; \ - \ - if (--tnl->vtx.counter == 0) \ - _tnl_wrap_filled_vertex( ctx ); \ - } \ - else { \ - GLfloat *dest = tnl->vtx.attrptr[ATTR]; \ - if (N>0) dest[0] = v[0]; \ - if (N>1) dest[1] = v[1]; \ - if (N>2) dest[2] = v[2]; \ - if (N>3) dest[3] = v[3]; \ - } \ -} - -#define INIT(TAB, ATTR) \ - TAB[ATTR][0] = attrib_##ATTR##_1; \ - TAB[ATTR][1] = attrib_##ATTR##_2; \ - TAB[ATTR][2] = attrib_##ATTR##_3; \ - TAB[ATTR][3] = attrib_##ATTR##_4; - - -#define ATTRS( ATTRIB ) \ - ATTRFV( ATTRIB, 1 ) \ - ATTRFV( ATTRIB, 2 ) \ - ATTRFV( ATTRIB, 3 ) \ - ATTRFV( ATTRIB, 4 ) - -/* conventional attribs */ -ATTRS( 0 ) -ATTRS( 1 ) -ATTRS( 2 ) -ATTRS( 3 ) -ATTRS( 4 ) -ATTRS( 5 ) -ATTRS( 6 ) -ATTRS( 7 ) -ATTRS( 8 ) -ATTRS( 9 ) -ATTRS( 10 ) -ATTRS( 11 ) -ATTRS( 12 ) -ATTRS( 13 ) -ATTRS( 14 ) -ATTRS( 15 ) - -/* generic attribs */ -ATTRS( 16 ) -ATTRS( 17 ) -ATTRS( 18 ) -ATTRS( 19 ) -ATTRS( 20 ) -ATTRS( 21 ) -ATTRS( 22 ) -ATTRS( 23 ) -ATTRS( 24 ) -ATTRS( 25 ) -ATTRS( 26 ) -ATTRS( 27 ) -ATTRS( 28 ) -ATTRS( 29 ) -ATTRS( 30 ) -ATTRS( 31 ) - - -void _tnl_generic_attr_table_init( tnl_attrfv_func (*tab)[4] ) -{ - /* conventional attribs */ - INIT( tab, 0 ); - INIT( tab, 1 ); - INIT( tab, 2 ); - INIT( tab, 3 ); - INIT( tab, 4 ); - INIT( tab, 5 ); - INIT( tab, 6 ); - INIT( tab, 7 ); - INIT( tab, 8 ); - INIT( tab, 9 ); - INIT( tab, 10 ); - INIT( tab, 11 ); - INIT( tab, 12 ); - INIT( tab, 13 ); - INIT( tab, 14 ); - INIT( tab, 15 ); - - /* generic attribs */ - INIT( tab, 16 ); - INIT( tab, 17 ); - INIT( tab, 18 ); - INIT( tab, 19 ); - INIT( tab, 20 ); - INIT( tab, 21 ); - INIT( tab, 22 ); - INIT( tab, 23 ); - INIT( tab, 24 ); - INIT( tab, 25 ); - INIT( tab, 26 ); - INIT( tab, 27 ); - INIT( tab, 28 ); - INIT( tab, 29 ); - INIT( tab, 30 ); - INIT( tab, 31 ); -} - -/* These can be made efficient with codegen. Further, by adding more - * logic to do_choose(), the double-dispatch for legacy entrypoints - * like glVertex3f() can be removed. - */ -#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \ -do { \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - tnl->vtx.tabfv[ATTR][COUNT-1]( P ); \ -} while (0) - -#define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V ) -#define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V ) -#define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V ) -#define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V ) - -#define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) ) - -#if defined(USE_X86_ASM) && 0 /* will break register calling convention */ -/* Naughty cheat: - */ -#define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) ) -#define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) ) -#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) ) -#else -/* Safe: - */ -#define DISPATCH_ATTR2F( ATTR, S,T ) \ -do { \ - GLfloat v[2]; \ - v[0] = S; v[1] = T; \ - DISPATCH_ATTR2FV( ATTR, v ); \ -} while (0) -#define DISPATCH_ATTR3F( ATTR, S,T,R ) \ -do { \ - GLfloat v[3]; \ - v[0] = S; v[1] = T; v[2] = R; \ - DISPATCH_ATTR3FV( ATTR, v ); \ -} while (0) -#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \ -do { \ - GLfloat v[4]; \ - v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \ - DISPATCH_ATTR4FV( ATTR, v ); \ -} while (0) -#endif - - -static void GLAPIENTRY _tnl_Vertex2f( GLfloat x, GLfloat y ) -{ - DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y ); -} - -static void GLAPIENTRY _tnl_Vertex2fv( const GLfloat *v ) -{ - DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z ); -} - -static void GLAPIENTRY _tnl_Vertex3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, - GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w ); -} - -static void GLAPIENTRY _tnl_Vertex4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _tnl_TexCoord1f( GLfloat x ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x ); -} - -static void GLAPIENTRY _tnl_TexCoord1fv( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _tnl_TexCoord2f( GLfloat x, GLfloat y ) -{ - DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y ); -} - -static void GLAPIENTRY _tnl_TexCoord2fv( const GLfloat *v ) -{ - DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _tnl_TexCoord3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z ); -} - -static void GLAPIENTRY _tnl_TexCoord3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _tnl_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, - GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w ); -} - -static void GLAPIENTRY _tnl_TexCoord4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _tnl_Normal3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z ); -} - -static void GLAPIENTRY _tnl_Normal3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v ); -} - -static void GLAPIENTRY _tnl_FogCoordfEXT( GLfloat x ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x ); -} - -static void GLAPIENTRY _tnl_FogCoordfvEXT( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v ); -} - -static void GLAPIENTRY _tnl_Color3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z ); -} - -static void GLAPIENTRY _tnl_Color3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY _tnl_Color4f( GLfloat x, GLfloat y, GLfloat z, - GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w ); -} - -static void GLAPIENTRY _tnl_Color4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY _tnl_Indexf( GLfloat v ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_COLOR_INDEX, v ); -} - -static void GLAPIENTRY _tnl_Indexfv( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_COLOR_INDEX, v ); -} - -static void GLAPIENTRY _tnl_SecondaryColor3fEXT( GLfloat x, GLfloat y, - GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z ); -} - -static void GLAPIENTRY _tnl_SecondaryColor3fvEXT( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v ); -} - -static void GLAPIENTRY _tnl_MultiTexCoord1f( GLenum target, GLfloat x ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR1F( attr, x ); -} - -static void GLAPIENTRY _tnl_MultiTexCoord1fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR1FV( attr, v ); -} - -static void GLAPIENTRY _tnl_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR2F( attr, x, y ); -} - -static void GLAPIENTRY _tnl_MultiTexCoord2fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR2FV( attr, v ); -} - -static void GLAPIENTRY _tnl_MultiTexCoord3f( GLenum target, GLfloat x, - GLfloat y, GLfloat z) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR3F( attr, x, y, z ); -} - -static void GLAPIENTRY _tnl_MultiTexCoord3fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR3FV( attr, v ); -} - -static void GLAPIENTRY _tnl_MultiTexCoord4f( GLenum target, GLfloat x, - GLfloat y, GLfloat z, - GLfloat w ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR4F( attr, x, y, z, w ); -} - -static void GLAPIENTRY _tnl_MultiTexCoord4fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR4FV( attr, v ); -} - - -/** - * GL_NV_vertex_program Vertex Attributes - * Note that these attributes DO alias the conventional attributes. - * Also, calling glVertexAttribNV(0, xxx) is equivalent to glVertex(xxx). - */ - -static void GLAPIENTRY _tnl_VertexAttrib1fNV( GLuint index, GLfloat x ) -{ - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - DISPATCH_ATTR1F( index, x ); -} - -static void GLAPIENTRY _tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v ) -{ - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - DISPATCH_ATTR1FV( index, v ); -} - -static void GLAPIENTRY _tnl_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y) -{ - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - DISPATCH_ATTR2F( index, x, y ); -} - -static void GLAPIENTRY _tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v ) -{ - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - DISPATCH_ATTR2FV( index, v ); -} - -static void GLAPIENTRY _tnl_VertexAttrib3fNV( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - DISPATCH_ATTR3F( index, x, y, z ); -} - -static void GLAPIENTRY _tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v ) -{ - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - DISPATCH_ATTR3FV( index, v ); -} - -static void GLAPIENTRY _tnl_VertexAttrib4fNV( GLuint index, GLfloat x, - GLfloat y, GLfloat z, - GLfloat w ) -{ - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - DISPATCH_ATTR4F( index, x, y, z, w ); -} - -static void GLAPIENTRY _tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) -{ - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - DISPATCH_ATTR4FV( index, v ); -} - - - -/** - * GL_ARB_vertex_program Vertex Attributes - * Note that these attributes do NOT alias the conventional attributes. - * Also, calling glVertexAttribARB(0, xxx) is equivalent to glVertex(xxx). - */ - -static void GLAPIENTRY _tnl_VertexAttrib1fARB( GLuint index, GLfloat x ) -{ - if (index >= MAX_VERTEX_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - else if (index > 0) - index += VERT_ATTRIB_GENERIC0; - DISPATCH_ATTR1F( index, x ); -} - -static void GLAPIENTRY _tnl_VertexAttrib1fvARB(GLuint index, const GLfloat *v) -{ - if (index >= MAX_VERTEX_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - else if (index > 0) - index += VERT_ATTRIB_GENERIC0; - DISPATCH_ATTR1FV( index, v ); -} - -static void GLAPIENTRY _tnl_VertexAttrib2fARB( GLuint index, GLfloat x, - GLfloat y ) -{ - if (index >= MAX_VERTEX_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - else if (index > 0) - index += VERT_ATTRIB_GENERIC0; - DISPATCH_ATTR2F( index, x, y ); -} - -static void GLAPIENTRY _tnl_VertexAttrib2fvARB(GLuint index, const GLfloat *v) -{ - if (index >= MAX_VERTEX_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - else if (index > 0) - index += VERT_ATTRIB_GENERIC0; - DISPATCH_ATTR2FV( index, v ); -} - -static void GLAPIENTRY _tnl_VertexAttrib3fARB(GLuint index, GLfloat x, - GLfloat y, GLfloat z) -{ - if (index >= MAX_VERTEX_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - else if (index > 0) - index += VERT_ATTRIB_GENERIC0; - DISPATCH_ATTR3F( index, x, y, z ); -} - -static void GLAPIENTRY _tnl_VertexAttrib3fvARB(GLuint index, const GLfloat *v) -{ - if (index >= MAX_VERTEX_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - else if (index > 0) - index += VERT_ATTRIB_GENERIC0; - DISPATCH_ATTR3FV( index, v ); -} - -static void GLAPIENTRY _tnl_VertexAttrib4fARB(GLuint index, GLfloat x, - GLfloat y, GLfloat z, GLfloat w) -{ - if (index >= MAX_VERTEX_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - else if (index > 0) - index += VERT_ATTRIB_GENERIC0; - DISPATCH_ATTR4F( index, x, y, z, w ); -} - -static void GLAPIENTRY _tnl_VertexAttrib4fvARB(GLuint index, const GLfloat *v) -{ - if (index >= MAX_VERTEX_ATTRIBS) - index = _TNL_ATTRIB_ERROR; - else if (index > 0) - index += VERT_ATTRIB_GENERIC0; - DISPATCH_ATTR4FV( index, v ); -} - - -/* Install the generic versions of the 2nd level dispatch - * functions. Some of these have a codegen alternative. - */ -void _tnl_generic_exec_vtxfmt_init( GLcontext *ctx ) -{ - GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt); - - vfmt->Color3f = _tnl_Color3f; - vfmt->Color3fv = _tnl_Color3fv; - vfmt->Color4f = _tnl_Color4f; - vfmt->Color4fv = _tnl_Color4fv; - vfmt->Indexf = _tnl_Indexf; - vfmt->Indexfv = _tnl_Indexfv; - vfmt->FogCoordfEXT = _tnl_FogCoordfEXT; - vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT; - vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fv; - vfmt->Normal3f = _tnl_Normal3f; - vfmt->Normal3fv = _tnl_Normal3fv; - vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT; - vfmt->TexCoord1f = _tnl_TexCoord1f; - vfmt->TexCoord1fv = _tnl_TexCoord1fv; - vfmt->TexCoord2f = _tnl_TexCoord2f; - vfmt->TexCoord2fv = _tnl_TexCoord2fv; - vfmt->TexCoord3f = _tnl_TexCoord3f; - vfmt->TexCoord3fv = _tnl_TexCoord3fv; - vfmt->TexCoord4f = _tnl_TexCoord4f; - vfmt->TexCoord4fv = _tnl_TexCoord4fv; - vfmt->Vertex2f = _tnl_Vertex2f; - vfmt->Vertex2fv = _tnl_Vertex2fv; - vfmt->Vertex3f = _tnl_Vertex3f; - vfmt->Vertex3fv = _tnl_Vertex3fv; - vfmt->Vertex4f = _tnl_Vertex4f; - vfmt->Vertex4fv = _tnl_Vertex4fv; - vfmt->VertexAttrib1fNV = _tnl_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = _tnl_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = _tnl_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = _tnl_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = _tnl_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = _tnl_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV; - vfmt->VertexAttrib1fARB = _tnl_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = _tnl_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = _tnl_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = _tnl_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = _tnl_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = _tnl_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = _tnl_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = _tnl_VertexAttrib4fvARB; -} diff --git a/src/mesa/tnl/t_vtx_x86.c b/src/mesa/tnl/t_vtx_x86.c deleted file mode 100644 index 99a05509327..00000000000 --- a/src/mesa/tnl/t_vtx_x86.c +++ /dev/null @@ -1,396 +0,0 @@ -/************************************************************************** - -Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -on 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 -ATI, TUNGSTEN GRAPHICS 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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - * Daniel Borca - */ - - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "vtxfmt.h" -#include "dlist.h" -#include "state.h" -#include "light.h" -#include "api_arrayelt.h" -#include "api_noop.h" -#include "t_vtx_api.h" -#include "simple_list.h" - -#if defined(USE_X86_ASM) && !defined(HAVE_NONSTANDARD_GLAPIENTRY) - -#define EXTERN( FUNC ) \ -extern const char FUNC[]; \ -extern const char FUNC##_end[] - -EXTERN( _tnl_x86_Attribute1fv ); -EXTERN( _tnl_x86_Attribute2fv ); -EXTERN( _tnl_x86_Attribute3fv ); -EXTERN( _tnl_x86_Attribute4fv ); -EXTERN( _tnl_x86_Vertex1fv ); -EXTERN( _tnl_x86_Vertex2fv ); -EXTERN( _tnl_x86_Vertex3fv ); -EXTERN( _tnl_x86_Vertex4fv ); - -EXTERN( _tnl_x86_dispatch_attrf1 ); -EXTERN( _tnl_x86_dispatch_attrf2 ); -EXTERN( _tnl_x86_dispatch_attrf3 ); -EXTERN( _tnl_x86_dispatch_attrf4 ); -EXTERN( _tnl_x86_dispatch_attrfv ); -EXTERN( _tnl_x86_dispatch_multitexcoordf1 ); -EXTERN( _tnl_x86_dispatch_multitexcoordf2 ); -EXTERN( _tnl_x86_dispatch_multitexcoordf3 ); -EXTERN( _tnl_x86_dispatch_multitexcoordf4 ); -EXTERN( _tnl_x86_dispatch_multitexcoordfv ); -EXTERN( _tnl_x86_dispatch_vertexattribf1 ); -EXTERN( _tnl_x86_dispatch_vertexattribf2 ); -EXTERN( _tnl_x86_dispatch_vertexattribf3 ); -EXTERN( _tnl_x86_dispatch_vertexattribf4 ); -EXTERN( _tnl_x86_dispatch_vertexattribfv ); - -EXTERN( _tnl_x86_choose_fv ); - - -#define DONT_KNOW_OFFSETS 1 - - -#define DFN( FUNC, CACHE, KEY ) \ - struct _tnl_dynfn *dfn = MALLOC_STRUCT( _tnl_dynfn );\ - const char *start = FUNC; \ - const char *end = FUNC##_end; \ - int offset = 0; \ - insert_at_head( &CACHE, dfn ); \ - dfn->key = KEY; \ - dfn->code = ALIGN_MALLOC( end - start, 16 ); \ - _mesa_memcpy (dfn->code, start, end - start) - - - -#undef DEBUG_VTX - -#ifdef DEBUG_VTX -#define FIXUP_PRINTF( offset, NEWVAL ) \ - fprintf(stderr, "%s/%d: offset %d, new value: 0x%x\n", __FILE__, __LINE__, offset, (int)(NEWVAL)) -#define FIXUPREL_PRINTF( offset, NEWVAL, CODE ) \ - fprintf(stderr, "%s/%d: offset %d, new value: 0x%x\n", __FILE__, __LINE__, offset, (int)(NEWVAL) - ((int)(CODE)+offset) - 4) -#else -#define FIXUP_PRINTF( offset, NEWVAL ) -#define FIXUPREL_PRINTF( offset, NEWVAL, CODE ) -#endif - -#define FIXUP( CODE, KNOWN_OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - GLint subst = 0x10101010 + CHECKVAL; \ - \ - if (DONT_KNOW_OFFSETS) { \ - while (*(int *)(CODE+offset) != subst) offset++; \ - *(int *)(CODE+offset) = (int)(NEWVAL); \ - FIXUP_PRINTF(offset, NEWVAL); \ - offset += 4; \ - } \ - else { \ - int *icode = (int *)(CODE+KNOWN_OFFSET); \ - assert (*icode == subst); \ - *icode = (int)NEWVAL; \ - } \ -} while (0) - - - -#define FIXUPREL( CODE, KNOWN_OFFSET, CHECKVAL, NEWVAL )\ -do { \ - GLint subst = 0x10101010 + CHECKVAL; \ - \ - if (DONT_KNOW_OFFSETS) { \ - while (*(int *)(CODE+offset) != subst) offset++; \ - *(int *)(CODE+offset) = (int)(NEWVAL) - ((int)(CODE)+offset) - 4; \ - FIXUPREL_PRINTF(offset, NEWVAL, CODE); \ - offset += 4; \ - } \ - else { \ - int *icode = (int *)(CODE+KNOWN_OFFSET); \ - assert (*icode == subst); \ - *icode = (int)(NEWVAL) - (int)(icode) - 4; \ - } \ -} while (0) - - - - -/* Build specialized versions of the immediate calls on the fly for - * the current state. Generic x86 versions. - */ - -static struct _tnl_dynfn *makeX86Vertex1fv( GLcontext *ctx, int vertex_size ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - DFN ( _tnl_x86_Vertex1fv, tnl->vtx.cache.Vertex[1-1], vertex_size ); - - FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr); - FIXUP(dfn->code, 0, 1, vertex_size - 1); - FIXUP(dfn->code, 0, 2, (int)&tnl->vtx.vertex[1]); - FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr); - FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter); - FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter); - FIXUP(dfn->code, 0, 4, (int)ctx); - FIXUPREL(dfn->code, 0, 5, (int)&_tnl_wrap_filled_vertex); - - return dfn; -} - -static struct _tnl_dynfn *makeX86Vertex2fv( GLcontext *ctx, int vertex_size ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - DFN ( _tnl_x86_Vertex2fv, tnl->vtx.cache.Vertex[2-1], vertex_size ); - - FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr); - FIXUP(dfn->code, 0, 1, vertex_size - 2); - FIXUP(dfn->code, 0, 2, (int)&tnl->vtx.vertex[2]); - FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr); - FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter); - FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter); - FIXUP(dfn->code, 0, 4, (int)ctx); - FIXUPREL(dfn->code, 0, 5, (int)&_tnl_wrap_filled_vertex); - - return dfn; -} - -static struct _tnl_dynfn *makeX86Vertex3fv( GLcontext *ctx, int vertex_size ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - switch (vertex_size) { - default: { - DFN ( _tnl_x86_Vertex3fv, tnl->vtx.cache.Vertex[3-1], vertex_size ); - - FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr); - FIXUP(dfn->code, 0, 1, vertex_size - 3); - FIXUP(dfn->code, 0, 2, (int)&tnl->vtx.vertex[3]); - FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr); - FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter); - FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter); - FIXUP(dfn->code, 0, 4, (int)ctx); - FIXUPREL(dfn->code, 0, 5, (int)&_tnl_wrap_filled_vertex); - return dfn; - } - } -} - -static struct _tnl_dynfn *makeX86Vertex4fv( GLcontext *ctx, int vertex_size ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - DFN ( _tnl_x86_Vertex4fv, tnl->vtx.cache.Vertex[4-1], vertex_size ); - - FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr); - FIXUP(dfn->code, 0, 1, vertex_size - 4); - FIXUP(dfn->code, 0, 2, (int)&tnl->vtx.vertex[4]); - FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr); - FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter); - FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter); - FIXUP(dfn->code, 0, 4, (int)ctx); - FIXUPREL(dfn->code, 0, 5, (int)&_tnl_wrap_filled_vertex); - - return dfn; -} - - -static struct _tnl_dynfn *makeX86Attribute1fv( GLcontext *ctx, int dest ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - DFN ( _tnl_x86_Attribute1fv, tnl->vtx.cache.Attribute[1-1], dest ); - - FIXUP(dfn->code, 0, 0, dest); - - return dfn; -} - -static struct _tnl_dynfn *makeX86Attribute2fv( GLcontext *ctx, int dest ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - DFN ( _tnl_x86_Attribute2fv, tnl->vtx.cache.Attribute[2-1], dest ); - - FIXUP(dfn->code, 0, 0, dest); - FIXUP(dfn->code, 0, 1, 4+dest); - - return dfn; -} - -static struct _tnl_dynfn *makeX86Attribute3fv( GLcontext *ctx, int dest ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - DFN ( _tnl_x86_Attribute3fv, tnl->vtx.cache.Attribute[3-1], dest ); - - FIXUP(dfn->code, 0, 0, dest); - FIXUP(dfn->code, 0, 1, 4+dest); - FIXUP(dfn->code, 0, 2, 8+dest); - - return dfn; -} - -static struct _tnl_dynfn *makeX86Attribute4fv( GLcontext *ctx, int dest ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - DFN ( _tnl_x86_Attribute4fv, tnl->vtx.cache.Attribute[4-1], dest ); - - FIXUP(dfn->code, 0, 0, dest); - FIXUP(dfn->code, 0, 1, 4+dest); - FIXUP(dfn->code, 0, 2, 8+dest); - FIXUP(dfn->code, 0, 3, 12+dest); - - return dfn; -} - - -void _tnl_InitX86Codegen( struct _tnl_dynfn_generators *gen ) -{ - gen->Vertex[0] = makeX86Vertex1fv; - gen->Vertex[1] = makeX86Vertex2fv; - gen->Vertex[2] = makeX86Vertex3fv; - gen->Vertex[3] = makeX86Vertex4fv; - gen->Attribute[0] = makeX86Attribute1fv; - gen->Attribute[1] = makeX86Attribute2fv; - gen->Attribute[2] = makeX86Attribute3fv; - gen->Attribute[3] = makeX86Attribute4fv; -} - - -#define MKDISP(FUNC, SIZE, ATTR, WARP) \ -do { \ - char *code; \ - const char *start = WARP; \ - const char *end = WARP##_end; \ - int offset = 0; \ - code = ALIGN_MALLOC( end - start, 16 ); \ - _mesa_memcpy (code, start, end - start); \ - FIXUP(code, 0, 0, (int)&(TNL_CONTEXT(ctx)->vtx.tabfv[ATTR][SIZE-1]));\ - *(void **)&vfmt->FUNC = code; \ -} while (0) - - -/* Install the codegen'ed versions of the 2nd level dispatch - * functions. We should keep a list and free them in the end... - */ -void _tnl_x86_exec_vtxfmt_init( GLcontext *ctx ) -{ - GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt); - - MKDISP(Color3f, 3, _TNL_ATTRIB_COLOR0, _tnl_x86_dispatch_attrf3); - MKDISP(Color3fv, 3, _TNL_ATTRIB_COLOR0, _tnl_x86_dispatch_attrfv); - MKDISP(Color4f, 4, _TNL_ATTRIB_COLOR0, _tnl_x86_dispatch_attrf4); - MKDISP(Color4fv, 4, _TNL_ATTRIB_COLOR0, _tnl_x86_dispatch_attrfv); - MKDISP(FogCoordfEXT, 1, _TNL_ATTRIB_FOG, _tnl_x86_dispatch_attrf1); - MKDISP(FogCoordfvEXT, 1, _TNL_ATTRIB_FOG, _tnl_x86_dispatch_attrfv); - MKDISP(Normal3f, 3, _TNL_ATTRIB_NORMAL, _tnl_x86_dispatch_attrf3); - MKDISP(Normal3fv, 3, _TNL_ATTRIB_NORMAL, _tnl_x86_dispatch_attrfv); - MKDISP(SecondaryColor3fEXT, 3, _TNL_ATTRIB_COLOR1, _tnl_x86_dispatch_attrf3); - MKDISP(SecondaryColor3fvEXT,3, _TNL_ATTRIB_COLOR1, _tnl_x86_dispatch_attrfv); - MKDISP(TexCoord1f, 1, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrf1); - MKDISP(TexCoord1fv, 1, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrfv); - MKDISP(TexCoord2f, 2, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrf2); - MKDISP(TexCoord2fv, 2, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrfv); - MKDISP(TexCoord3f, 3, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrf3); - MKDISP(TexCoord3fv, 3, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrfv); - MKDISP(TexCoord4f, 4, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrf4); - MKDISP(TexCoord4fv, 4, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrfv); - MKDISP(Vertex2f, 2, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrf2); - MKDISP(Vertex2fv, 2, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrfv); - MKDISP(Vertex3f, 3, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrf3); - MKDISP(Vertex3fv, 3, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrfv); - MKDISP(Vertex4f, 4, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrf4); - MKDISP(Vertex4fv, 4, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrfv); - - MKDISP(MultiTexCoord1fARB, 1, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordf1); - MKDISP(MultiTexCoord1fvARB, 1, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordfv); - MKDISP(MultiTexCoord2fARB, 2, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordf2); - MKDISP(MultiTexCoord2fvARB, 2, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordfv); - MKDISP(MultiTexCoord3fARB, 3, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordf3); - MKDISP(MultiTexCoord3fvARB, 3, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordfv); - MKDISP(MultiTexCoord4fARB, 4, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordf4); - MKDISP(MultiTexCoord4fvARB, 4, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordfv); - - MKDISP(VertexAttrib1fNV, 1, 0, _tnl_x86_dispatch_vertexattribf1); - MKDISP(VertexAttrib1fvNV, 1, 0, _tnl_x86_dispatch_vertexattribfv); - MKDISP(VertexAttrib2fNV, 2, 0, _tnl_x86_dispatch_vertexattribf2); - MKDISP(VertexAttrib2fvNV, 2, 0, _tnl_x86_dispatch_vertexattribfv); - MKDISP(VertexAttrib3fNV, 3, 0, _tnl_x86_dispatch_vertexattribf3); - MKDISP(VertexAttrib3fvNV, 3, 0, _tnl_x86_dispatch_vertexattribfv); - MKDISP(VertexAttrib4fNV, 4, 0, _tnl_x86_dispatch_vertexattribf4); - MKDISP(VertexAttrib4fvNV, 4, 0, _tnl_x86_dispatch_vertexattribfv); -} - - -/* Install the codegen'ed choosers. - * We should keep a list and free them in the end... - */ -void _tnl_x86choosers( tnl_attrfv_func (*choose)[4], - tnl_attrfv_func (*do_choose)( GLuint attr, - GLuint sz )) -{ - int attr, size; - - for (attr = 0; attr < _TNL_MAX_ATTR_CODEGEN; attr++) { - for (size = 0; size < 4; size++) { - char *code; - const char *start = _tnl_x86_choose_fv; - const char *end = _tnl_x86_choose_fv_end; - int offset = 0; - code = ALIGN_MALLOC( end - start, 16 ); - _mesa_memcpy (code, start, end - start); - FIXUP(code, 0, 0, attr); - FIXUP(code, 0, 1, size + 1); - FIXUPREL(code, 0, 2, do_choose); - choose[attr][size] = (tnl_attrfv_func)code; - } - } -} - -#else - -void _tnl_InitX86Codegen( struct _tnl_dynfn_generators *gen ) -{ - (void) gen; -} - - -void _tnl_x86_exec_vtxfmt_init( GLcontext *ctx ) -{ - (void) ctx; -} - - -void _tnl_x86choosers( tnl_attrfv_func (*choose)[4], - tnl_attrfv_func (*do_choose)( GLuint attr, - GLuint sz )) -{ - (void) choose; - (void) do_choose; -} - -#endif diff --git a/src/mesa/tnl/t_vtx_x86_gcc.S b/src/mesa/tnl/t_vtx_x86_gcc.S deleted file mode 100644 index 93753be759b..00000000000 --- a/src/mesa/tnl/t_vtx_x86_gcc.S +++ /dev/null @@ -1,561 +0,0 @@ -/************************************************************************** - -Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -on 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 -ATI, TUNGSTEN GRAPHICS 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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - * Daniel Borca - */ - -#if defined (__DJGPP__) || defined (__MINGW32__) || defined (__CYGWIN__) -#define GLOBL( x ) \ -.globl _##x; \ -_##x: -#else /* !defined (__DJGPP__) && !defined (__MINGW32__) && !defined (__CYGWIN__) */ -#define GLOBL( x ) \ -.globl x; \ -x: -#endif /* !defined (__DJGPP__) && !defined (__MINGW32__) && !defined (__CYGWIN__) */ - - -#if !defined (STDCALL_API) -#define RETCLEAN( x ) ret -#else -#define RETCLEAN( x ) ret $x -#endif - - -#define _JMP(x) \ -.byte 0xe9; \ -.long x - -#define _CALL(x) \ -.byte 0xe8; \ -.long x - - -/* Someone who knew a lot about this sort of thing would use this - * macro to note current offsets, etc in a special region of the - * object file & just make everything work out neat. I don't know - * enough to do that... - */ - -#define SUBST( x ) (0x10101010 + x) - - -.data - - -/* [dBorca] TODO - * Unfold functions for each vertex size? - * Build super-specialized SSE versions? - * - * There is a trick in Vertex*fv: under certain conditions, - * we tail to _tnl_wrap_filled_vertex(ctx). This means that - * if Vertex*fv is STDCALL, then _tnl_wrap_filled_vertex must - * be STDCALL as well, because (GLcontext *) and (GLfloat *) - * have the same size. - */ -.align 4 -GLOBL ( _tnl_x86_Vertex1fv ) - movl 4(%esp), %ecx - push %edi - push %esi - movl SUBST(0), %edi /* 0x0 --> tnl->vtx.vbptr */ - movl (%ecx), %edx /* load v[0] */ - movl %edx, (%edi) /* tnl->vtx.vbptr[0] = v[0] */ - addl $4, %edi /* tnl->vtx.vbptr += 1 */ - movl $SUBST(1), %ecx /* 0x1 --> (tnl->vtx.vertex_size - 1) */ - movl $SUBST(2), %esi /* 0x2 --> (tnl->vtx.vertex + 1) */ - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, SUBST(0) /* 0x0 --> tnl->vtx.vbptr */ - movl SUBST(3), %edx /* 0x3 --> counter */ - pop %esi - pop %edi - dec %edx /* counter-- */ - movl %edx, SUBST(3) /* 0x3 --> counter */ - je .0 /* if (counter == 0) goto .0 */ - RETCLEAN(4) /* return */ - .balign 16 -.0: - movl $SUBST(4), %eax /* load ctx */ - movl %eax, 4(%esp) /* push ctx */ - _JMP (SUBST(5)) /* jmp _tnl_wrap_filled_vertex */ -GLOBL ( _tnl_x86_Vertex1fv_end ) - -.align 4 -GLOBL ( _tnl_x86_Vertex2fv ) - movl 4(%esp), %ecx - push %edi - push %esi - movl SUBST(0), %edi /* load tnl->vtx.vbptr */ - movl (%ecx), %edx /* load v[0] */ - movl 4(%ecx), %eax /* load v[1] */ - movl %edx, (%edi) /* tnl->vtx.vbptr[0] = v[0] */ - movl %eax, 4(%edi) /* tnl->vtx.vbptr[1] = v[1] */ - addl $8, %edi /* tnl->vtx.vbptr += 2 */ - movl $SUBST(1), %ecx /* vertex_size - 2 */ - movl $SUBST(2), %esi /* tnl->vtx.vertex + 2 */ - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, SUBST(0) /* save tnl->vtx.vbptr */ - movl SUBST(3), %edx /* load counter */ - pop %esi - pop %edi - dec %edx /* counter-- */ - movl %edx, SUBST(3) /* save counter */ - je .1 /* if (counter == 0) goto .1 */ - RETCLEAN(4) /* return */ - .balign 16 -.1: - movl $SUBST(4), %eax /* load ctx */ - movl %eax, 4(%esp) /* push ctx */ - _JMP (SUBST(5)) /* jmp _tnl_wrap_filled_vertex */ -GLOBL ( _tnl_x86_Vertex2fv_end ) - -.align 4 -GLOBL ( _tnl_x86_Vertex3fv ) - movl 4(%esp), %ecx - push %edi - push %esi - movl SUBST(0), %edi /* load tnl->vtx.vbptr */ - movl (%ecx), %edx /* load v[0] */ - movl 4(%ecx), %eax /* load v[1] */ - movl 8(%ecx), %esi /* load v[2] */ - movl %edx, (%edi) /* tnl->vtx.vbptr[0] = v[0] */ - movl %eax, 4(%edi) /* tnl->vtx.vbptr[1] = v[1] */ - movl %esi, 8(%edi) /* tnl->vtx.vbptr[2] = v[2] */ - addl $12, %edi /* tnl->vtx.vbptr += 3 */ - movl $SUBST(1), %ecx /* vertex_size - 3 */ - movl $SUBST(2), %esi /* tnl->vtx.vertex + 3 */ - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, SUBST(0) /* save tnl->vtx.vbptr */ - movl SUBST(3), %edx /* load counter */ - pop %esi - pop %edi - dec %edx /* counter-- */ - movl %edx, SUBST(3) /* save counter */ - je .2 /* if (counter == 0) goto .2 */ - RETCLEAN(4) /* return */ - .balign 16 -.2: - movl $SUBST(4), %eax /* load ctx */ - movl %eax, 4(%esp) /* push ctx */ - _JMP (SUBST(5)) /* jmp _tnl_wrap_filled_vertex */ -GLOBL ( _tnl_x86_Vertex3fv_end ) - -.align 4 -GLOBL ( _tnl_x86_Vertex4fv ) - movl 4(%esp), %ecx - push %edi - push %esi - movl SUBST(0), %edi /* load tnl->vtx.vbptr */ - movl (%ecx), %edx /* load v[0] */ - movl 4(%ecx), %eax /* load v[1] */ - movl 8(%ecx), %esi /* load v[2] */ - movl 12(%ecx), %ecx /* load v[3] */ - movl %edx, (%edi) /* tnl->vtx.vbptr[0] = v[0] */ - movl %eax, 4(%edi) /* tnl->vtx.vbptr[1] = v[1] */ - movl %esi, 8(%edi) /* tnl->vtx.vbptr[2] = v[2] */ - movl %ecx, 12(%edi) /* tnl->vtx.vbptr[3] = v[3] */ - addl $16, %edi /* tnl->vtx.vbptr += 4 */ - movl $SUBST(1), %ecx /* vertex_size - 4 */ - movl $SUBST(2), %esi /* tnl->vtx.vertex + 4 */ - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, SUBST(0) /* save tnl->vtx.vbptr */ - movl SUBST(3), %edx /* load counter */ - pop %esi - pop %edi - dec %edx /* counter-- */ - movl %edx, SUBST(3) /* save counter */ - je .3 /* if (counter == 0) goto .3 */ - RETCLEAN(4) /* return */ - .balign 16 -.3: - movl $SUBST(4), %eax /* load ctx */ - movl %eax, 4(%esp) /* push ctx */ - _JMP (SUBST(5)) /* jmp _tnl_wrap_filled_vertex */ -GLOBL ( _tnl_x86_Vertex4fv_end ) - - -/** - * Generic handlers for vector format data. - */ -GLOBL( _tnl_x86_Attribute1fv ) - movl 4(%esp), %ecx - movl (%ecx), %eax /* load v[0] */ - movl %eax, SUBST(0) /* store v[0] to current vertex */ - RETCLEAN(4) -GLOBL ( _tnl_x86_Attribute1fv_end ) - -GLOBL( _tnl_x86_Attribute2fv ) - movl 4(%esp), %ecx - movl (%ecx), %eax /* load v[0] */ - movl 4(%ecx), %edx /* load v[1] */ - movl %eax, SUBST(0) /* store v[0] to current vertex */ - movl %edx, SUBST(1) /* store v[1] to current vertex */ - RETCLEAN(4) -GLOBL ( _tnl_x86_Attribute2fv_end ) - -GLOBL( _tnl_x86_Attribute3fv ) - movl 4(%esp), %ecx - movl (%ecx), %eax /* load v[0] */ - movl 4(%ecx), %edx /* load v[1] */ - movl 8(%ecx), %ecx /* load v[2] */ - movl %eax, SUBST(0) /* store v[0] to current vertex */ - movl %edx, SUBST(1) /* store v[1] to current vertex */ - movl %ecx, SUBST(2) /* store v[2] to current vertex */ - RETCLEAN(4) -GLOBL ( _tnl_x86_Attribute3fv_end ) - -GLOBL( _tnl_x86_Attribute4fv ) - movl 4(%esp), %ecx - movl (%ecx), %eax /* load v[0] */ - movl 4(%ecx), %edx /* load v[1] */ - movl %eax, SUBST(0) /* store v[0] to current vertex */ - movl %edx, SUBST(1) /* store v[1] to current vertex */ - movl 8(%ecx), %eax /* load v[2] */ - movl 12(%ecx), %edx /* load v[3] */ - movl %eax, SUBST(2) /* store v[2] to current vertex */ - movl %edx, SUBST(3) /* store v[3] to current vertex */ - RETCLEAN(4) -GLOBL ( _tnl_x86_Attribute4fv_end ) - - -/* Choosers: - * - * Must generate all of these ahead of first usage. Generate at - * compile-time? - */ -GLOBL( _tnl_x86_choose_fv ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl $SUBST(0), (%esp) /* arg 0 - attrib */ - movl $SUBST(1), 4(%esp) /* arg 1 - N */ - _CALL (SUBST(2)) /* call do_choose */ - add $12, %esp /* tear down stack frame */ - jmp *%eax /* jump to new func */ -GLOBL ( _tnl_x86_choose_fv_end ) - - -/* FIRST LEVEL FUNCTIONS -- these are plugged directly into GL dispatch. - * - * In the 1st level dispatch functions, switch to a different - * calling convention -- (const GLfloat *v) in %ecx. - * - * As with regular (x86) dispatch, don't create a new stack frame - - * just let the 'ret' in the dispatched function return straight - * back to the original caller. - * - * Vertex/Normal/Color, etc: the address of the function pointer - * is known at codegen time. - */ - -/* Unfortunately, have to play with the stack in the non-fv case: - */ -#if !defined (STDCALL_API) -GLOBL( _tnl_x86_dispatch_attrf1 ) -GLOBL( _tnl_x86_dispatch_attrf2 ) -GLOBL( _tnl_x86_dispatch_attrf3 ) -GLOBL( _tnl_x86_dispatch_attrf4 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - leal 16(%esp), %edx /* address of first float on stack */ - movl %edx, (%esp) /* save as 'v' */ - call *SUBST(0) /* 0x0 --> tabfv[attr][n] */ - addl $12, %esp /* tear down frame */ - ret /* return */ -GLOBL( _tnl_x86_dispatch_attrf4_end ) -GLOBL( _tnl_x86_dispatch_attrf3_end ) -GLOBL( _tnl_x86_dispatch_attrf2_end ) -GLOBL( _tnl_x86_dispatch_attrf1_end ) - -#else /* defined(STDCALL_API) */ - -GLOBL( _tnl_x86_dispatch_attrf1 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - leal 16(%esp), %edx /* address of first float on stack */ - movl %edx, (%esp) /* save as 'v' */ - call *SUBST(0) /* 0x0 --> tabfv[attr][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $4 /* return */ -GLOBL( _tnl_x86_dispatch_attrf1_end ) - -GLOBL( _tnl_x86_dispatch_attrf2 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - leal 16(%esp), %edx /* address of first float on stack */ - movl %edx, (%esp) /* save as 'v' */ - call *SUBST(0) /* 0x0 --> tabfv[attr][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $8 /* return */ -GLOBL( _tnl_x86_dispatch_attrf2_end ) - -GLOBL( _tnl_x86_dispatch_attrf3 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - leal 16(%esp), %edx /* address of first float on stack */ - movl %edx, (%esp) /* save as 'v' */ - call *SUBST(0) /* 0x0 --> tabfv[attr][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $12 /* return */ -GLOBL( _tnl_x86_dispatch_attrf3_end ) - -GLOBL( _tnl_x86_dispatch_attrf4 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - leal 16(%esp), %edx /* address of first float on stack */ - movl %edx, (%esp) /* save as 'v' */ - call *SUBST(0) /* 0x0 --> tabfv[attr][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $16 /* return */ -GLOBL( _tnl_x86_dispatch_attrf4_end ) -#endif /* defined(STDCALL_API) */ - -/* The fv case is simpler: - */ -GLOBL( _tnl_x86_dispatch_attrfv ) - jmp *SUBST(0) /* 0x0 --> tabfv[attr][n] */ -GLOBL( _tnl_x86_dispatch_attrfv_end ) - - -/* MultiTexcoord: the address of the function pointer must be - * calculated, but can use the index argument slot to hold 'v', and - * avoid setting up a new stack frame. - * - * [dBorca] - * right, this would be the preferred approach, but gcc does not - * clean up the stack after each function call when optimizing (-fdefer-pop); - * can it make assumptions about what's already on the stack? I dunno, - * but in this case, we can't mess with the caller's stack frame, and - * we must use a model like `_x86_dispatch_attrfv' above. Caveat emptor! - */ - -/* Also, will only need a maximum of four of each of these per context: - */ -#if !defined (STDCALL_API) -GLOBL( _tnl_x86_dispatch_multitexcoordf1 ) -GLOBL( _tnl_x86_dispatch_multitexcoordf2 ) -GLOBL( _tnl_x86_dispatch_multitexcoordf3 ) -GLOBL( _tnl_x86_dispatch_multitexcoordf4 ) - movl 4(%esp), %ecx - leal 8(%esp), %edx - andl $7, %ecx - movl %edx, 4(%esp) - sall $4, %ecx - jmp *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */ -GLOBL( _tnl_x86_dispatch_multitexcoordf4_end ) -GLOBL( _tnl_x86_dispatch_multitexcoordf3_end ) -GLOBL( _tnl_x86_dispatch_multitexcoordf2_end ) -GLOBL( _tnl_x86_dispatch_multitexcoordf1_end ) - -GLOBL( _tnl_x86_dispatch_multitexcoordfv ) - movl 4(%esp), %ecx - movl 8(%esp), %edx - andl $7, %ecx - movl %edx, 4(%esp) - sall $4, %ecx - jmp *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */ -GLOBL( _tnl_x86_dispatch_multitexcoordfv_end ) - -#else /* defined (STDCALL_API) */ - -GLOBL( _tnl_x86_dispatch_multitexcoordf1 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %ecx - leal 20(%esp), %edx - andl $7, %ecx - movl %edx, (%esp) - sall $4, %ecx - call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $8 /* return */ -GLOBL( _tnl_x86_dispatch_multitexcoordf1_end ) - -GLOBL( _tnl_x86_dispatch_multitexcoordf2 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %ecx - leal 20(%esp), %edx - andl $7, %ecx - movl %edx, (%esp) - sall $4, %ecx - call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $12 /* return */ -GLOBL( _tnl_x86_dispatch_multitexcoordf2_end ) - -GLOBL( _tnl_x86_dispatch_multitexcoordf3 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %ecx - leal 20(%esp), %edx - andl $7, %ecx - movl %edx, (%esp) - sall $4, %ecx - call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $16 /* return */ -GLOBL( _tnl_x86_dispatch_multitexcoordf3_end ) - -GLOBL( _tnl_x86_dispatch_multitexcoordf4 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %ecx - leal 20(%esp), %edx - andl $7, %ecx - movl %edx, (%esp) - sall $4, %ecx - call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $20 /* return */ -GLOBL( _tnl_x86_dispatch_multitexcoordf4_end ) - -GLOBL( _tnl_x86_dispatch_multitexcoordfv ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %ecx - movl 20(%esp), %edx - andl $7, %ecx - movl %edx, (%esp) - sall $4, %ecx - call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $8 /* return */ -GLOBL( _tnl_x86_dispatch_multitexcoordfv_end ) -#endif /* defined (STDCALL_API) */ - - -/* VertexAttrib: the address of the function pointer must be - * calculated. - */ -#if !defined (STDCALL_API) -GLOBL( _tnl_x86_dispatch_vertexattribf1 ) -GLOBL( _tnl_x86_dispatch_vertexattribf2 ) -GLOBL( _tnl_x86_dispatch_vertexattribf3 ) -GLOBL( _tnl_x86_dispatch_vertexattribf4 ) - movl 4(%esp), %eax - cmpl $16, %eax - jb .8 /* "cmovge" is not supported on all CPUs */ - movl $16, %eax -.8: - leal 8(%esp), %ecx /* calculate 'v' */ - movl %ecx, 4(%esp) /* save in 1st arg slot */ - sall $4, %eax - jmp *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */ -GLOBL( _tnl_x86_dispatch_vertexattribf4_end ) -GLOBL( _tnl_x86_dispatch_vertexattribf3_end ) -GLOBL( _tnl_x86_dispatch_vertexattribf2_end ) -GLOBL( _tnl_x86_dispatch_vertexattribf1_end ) - -GLOBL( _tnl_x86_dispatch_vertexattribfv ) - movl 4(%esp), %eax - cmpl $16, %eax - jb .9 /* "cmovge" is not supported on all CPUs */ - movl $16, %eax -.9: - movl 8(%esp), %ecx /* load 'v' */ - movl %ecx, 4(%esp) /* save in 1st arg slot */ - sall $4, %eax - jmp *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */ -GLOBL( _tnl_x86_dispatch_vertexattribfv_end ) - -#else /* defined (STDCALL_API) */ - -GLOBL( _tnl_x86_dispatch_vertexattribf1 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %eax - cmpl $16, %eax - jb .81 /* "cmovge" is not supported on all CPUs */ - movl $16, %eax -.81: - leal 20(%esp), %ecx /* load 'v' */ - movl %ecx, (%esp) /* save in 1st arg slot */ - sall $4, %eax - call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $8 /* return */ -GLOBL( _tnl_x86_dispatch_vertexattribf1_end ) - -GLOBL( _tnl_x86_dispatch_vertexattribf2 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %eax - cmpl $16, %eax - jb .82 /* "cmovge" is not supported on all CPUs */ - movl $16, %eax -.82: - leal 20(%esp), %ecx /* load 'v' */ - movl %ecx, (%esp) /* save in 1st arg slot */ - sall $4, %eax - call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $12 /* return */ -GLOBL( _tnl_x86_dispatch_vertexattribf2_end ) - -GLOBL( _tnl_x86_dispatch_vertexattribf3 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %eax - cmpl $16, %eax - jb .83 /* "cmovge" is not supported on all CPUs */ - movl $16, %eax -.83: - leal 20(%esp), %ecx /* load 'v' */ - movl %ecx, (%esp) /* save in 1st arg slot */ - sall $4, %eax - call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $16 /* return */ -GLOBL( _tnl_x86_dispatch_vertexattribf3_end ) - -GLOBL( _tnl_x86_dispatch_vertexattribf4 ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %eax - cmpl $16, %eax - jb .84 /* "cmovge" is not supported on all CPUs */ - movl $16, %eax -.84: - leal 20(%esp), %ecx /* load 'v' */ - movl %ecx, (%esp) /* save in 1st arg slot */ - sall $4, %eax - call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $20 /* return */ -GLOBL( _tnl_x86_dispatch_vertexattribf4_end ) - -GLOBL( _tnl_x86_dispatch_vertexattribfv ) - subl $12, %esp /* gcc does 16 byte alignment of stack frames? */ - movl 16(%esp), %eax - cmpl $16, %eax - jb .9 /* "cmovge" is not supported on all CPUs */ - movl $16, %eax -.9: - movl 20(%esp), %ecx /* load 'v' */ - movl %ecx, (%esp) /* save in 1st arg slot */ - sall $4, %eax - call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */ - addl $8, %esp /* tear down frame (4 shaved off by the callee) */ - ret $8 /* return */ -GLOBL( _tnl_x86_dispatch_vertexattribfv_end ) -#endif /* defined (STDCALL_API) */ - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h index dab422429a1..17cb30adc76 100644 --- a/src/mesa/tnl/tnl.h +++ b/src/mesa/tnl/tnl.h @@ -50,30 +50,14 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ); * dispatch and/or driver callbacks. */ -/* Restore just the ctx->Exec table: - */ -extern void -_tnl_wakeup_exec( GLcontext *ctx ); - -/* Restore both ctx->Exec and ctx->Save: - */ extern void -_tnl_wakeup_save_exec( GLcontext *ctx ); +_tnl_wakeup( GLcontext *ctx ); /* Driver configuration options: */ extern void _tnl_need_projected_coords( GLcontext *ctx, GLboolean flag ); -extern void -_tnl_need_dlist_loopback( GLcontext *ctx, GLboolean flag ); - -extern void -_tnl_need_dlist_norm_lengths( GLcontext *ctx, GLboolean flag ); - -extern void -_tnl_isolate_materials( GLcontext *ctx, GLboolean flag ); - /* Control whether T&L does per-vertex fog */ @@ -86,4 +70,16 @@ _tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value ); extern void _tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program); +struct _mesa_prim; +struct _mesa_index_buffer; + +void +_tnl_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index); + #endif