diff options
Diffstat (limited to 'src/mesa/tnl')
-rw-r--r-- | src/mesa/tnl/sources | 14 | ||||
-rw-r--r-- | src/mesa/tnl/t_array_api.c | 432 | ||||
-rw-r--r-- | src/mesa/tnl/t_array_api.h | 46 | ||||
-rw-r--r-- | src/mesa/tnl/t_array_import.c | 376 | ||||
-rw-r--r-- | src/mesa/tnl/t_array_import.h | 36 | ||||
-rw-r--r-- | src/mesa/tnl/t_context.c | 99 | ||||
-rw-r--r-- | src/mesa/tnl/t_context.h | 340 | ||||
-rw-r--r-- | src/mesa/tnl/t_draw.c | 406 | ||||
-rw-r--r-- | src/mesa/tnl/t_save_api.h | 57 | ||||
-rw-r--r-- | src/mesa/tnl/t_save_loopback.c | 330 | ||||
-rw-r--r-- | src/mesa/tnl/t_save_playback.c | 216 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_arbprogram.c | 63 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_render.c | 2 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_rendertmp.h | 4 | ||||
-rw-r--r-- | src/mesa/tnl/t_vp_build.c | 62 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_api.c | 1046 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_api.h | 86 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_eval.c | 264 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_exec.c | 293 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_generic.c | 615 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_x86.c | 396 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_x86_gcc.S | 561 | ||||
-rw-r--r-- | src/mesa/tnl/tnl.h | 30 |
23 files changed, 556 insertions, 5218 deletions
diff --git a/src/mesa/tnl/sources b/src/mesa/tnl/sources index e01f55dbafb..a0888be11d6 100644 --- a/src/mesa/tnl/sources +++ b/src/mesa/tnl/sources @@ -1,12 +1,7 @@ # List of source 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,24 +18,17 @@ 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 MESA_TNL_HEADERS = \ t_array_api.h \ t_array_import.h \ t_context.h \ t_pipeline.h \ -t_save_api.h \ t_vb_arbprogram.h \ t_vb_cliptmp.h \ t_vb_lighttmp.h \ t_vb_rendertmp.h \ t_vertex.h \ t_vp_build.h \ -t_vtx_api.h \ tnl.h 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 <[email protected]> - */ - -#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 3887f18213a..3b2f91acbaf 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -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.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->VertexProgram._MaintainTnlProgram) { _tnl_ProgramCacheInit( ctx ); _tnl_install_pipeline( ctx, _tnl_vp_pipeline ); @@ -93,34 +67,18 @@ _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; + tnl->nr_blocks = 0; + return GL_TRUE; } @@ -130,11 +88,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->VertexProgram._MaintainTnlProgram) _tnl_ProgramCacheDestroy( ctx ); @@ -155,10 +109,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: */ @@ -210,36 +161,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 ); -} /** @@ -255,27 +191,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 ) { TNLcontext *tnl = TNL_CONTEXT(ctx); diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index ea2a6bed546..733b3a5fe1a 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.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]; - 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_draw.c b/src/mesa/tnl/t_draw.c new file mode 100644 index 00000000000..c97cf5f7b21 --- /dev/null +++ b/src/mesa/tnl/t_draw.c @@ -0,0 +1,406 @@ + +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * 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 <[email protected]> + */ + +#include "glheader.h" +#include "context.h" +#include "imports.h" +#include "state.h" +#include "mtypes.h" +#include "macros.h" +#include "enums.h" + +#include "t_context.h" +#include "t_pipeline.h" +#include "t_vp_build.h" +#include "t_vertex.h" +#include "tnl.h" + + + +static GLubyte *get_space(GLcontext *ctx, GLuint bytes) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLubyte *space = _mesa_malloc(bytes); + + tnl->block[tnl->nr_blocks++] = space; + return space; +} + + +static void free_space(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint i; + for (i = 0; i < tnl->nr_blocks; i++) + _mesa_free(tnl->block[i]); + tnl->nr_blocks = 0; +} + + +/* Convert the incoming array to GLfloats. Understands the + * array->Normalized flag and selects the correct conversion method. + */ +#define CONVERT( TYPE, MACRO ) do { \ + GLuint i, j; \ + if (input->Normalized) { \ + for (i = 0; i < count; i++) { \ + const TYPE *in = (TYPE *)ptr; \ + for (j = 0; j < sz; j++) { \ + *fptr++ = MACRO(*in); \ + in++; \ + } \ + ptr += input->StrideB; \ + } \ + } else { \ + for (i = 0; i < count; i++) { \ + const TYPE *in = (TYPE *)ptr; \ + for (j = 0; j < sz; j++) { \ + *fptr++ = (GLfloat)(*in); \ + in++; \ + } \ + ptr += input->StrideB; \ + } \ + } \ +} while (0) + + + +/* Adjust pointer to point at first requested element, convert to + * floating point, populate VB->AttribPtr[]. + */ +static void _tnl_import_array( GLcontext *ctx, + GLuint attrib, + GLuint count, + const struct gl_client_array *input, + const GLubyte *ptr ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint stride = input->StrideB; + + if (input->Type != GL_FLOAT) { + const GLuint sz = input->Size; + GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat)); + GLfloat *fptr = (GLfloat *)buf; + + switch (input->Type) { + case GL_BYTE: + CONVERT(GLbyte, BYTE_TO_FLOAT); + break; + case GL_UNSIGNED_BYTE: + CONVERT(GLubyte, UBYTE_TO_FLOAT); + break; + case GL_SHORT: + CONVERT(GLshort, SHORT_TO_FLOAT); + break; + case GL_UNSIGNED_SHORT: + CONVERT(GLushort, USHORT_TO_FLOAT); + break; + case GL_INT: + CONVERT(GLint, INT_TO_FLOAT); + break; + case GL_UNSIGNED_INT: + CONVERT(GLuint, UINT_TO_FLOAT); + break; + case GL_DOUBLE: + CONVERT(GLdouble, (GLfloat)); + break; + default: + assert(0); + break; + } + + ptr = buf; + stride = sz * sizeof(GLfloat); + } + + VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib]; + VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr; + VB->AttribPtr[attrib]->start = (GLfloat *)ptr; + VB->AttribPtr[attrib]->count = count; + VB->AttribPtr[attrib]->stride = stride; + VB->AttribPtr[attrib]->size = input->Size; + + /* This should die, but so should the whole GLvector4f concept: + */ + VB->AttribPtr[attrib]->flags = (((1<<input->Size)-1) | + VEC_NOT_WRITEABLE | + (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE)); + + VB->AttribPtr[attrib]->storage = NULL; +} + +#define CLIPVERTS ((6 + MAX_CLIP_PLANES) * 2) + + +static GLboolean *_tnl_import_edgeflag( GLcontext *ctx, + const GLvector4f *input, + GLuint count) +{ + const GLubyte *ptr = (const GLubyte *)input->data; + const GLuint stride = input->stride; + GLboolean *space = (GLboolean *)get_space(ctx, count + CLIPVERTS); + GLboolean *bptr = space; + GLuint i; + + for (i = 0; i < count; i++) { + *bptr++ = ((GLfloat *)ptr)[0] == 1.0; + ptr += stride; + } + + return space; +} + + +static void bind_inputs( GLcontext *ctx, + const struct gl_client_array *inputs[], + GLint count, + struct gl_buffer_object **bo, + GLuint *nr_bo ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + + /* Map all the VBOs + */ + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + const void *ptr; + + if (inputs[i]->BufferObj->Name) { + if (!inputs[i]->BufferObj->Pointer) { + bo[*nr_bo] = inputs[i]->BufferObj; + (*nr_bo)++; + ctx->Driver.MapBuffer(ctx, + GL_ARRAY_BUFFER, + GL_READ_ONLY_ARB, + inputs[i]->BufferObj); + + assert(inputs[i]->BufferObj->Pointer); + } + + ptr = ADD_POINTERS(inputs[i]->BufferObj->Pointer, + inputs[i]->Ptr); + } + else + ptr = inputs[i]->Ptr; + + /* Just make sure the array is floating point, otherwise convert to + * temporary storage. + * + * XXX: remove the GLvector4f type at some stage and just use + * client arrays. + */ + _tnl_import_array(ctx, i, count, inputs[i], ptr); + } + + /* We process only the vertices between min & max index: + */ + VB->Count = 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]; + } + + /* Clipping and drawing code still requires this to be a packed + * array of ubytes which can be written into. TODO: Fix and + * remove. + */ + if (ctx->Polygon.FrontMode != GL_FILL || + ctx->Polygon.BackMode != GL_FILL) + { + VB->EdgeFlag = _tnl_import_edgeflag( ctx, + VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG], + VB->Count ); + } + +} + + +/* Translate indices to GLuints and store in VB->Elts. + */ +static void bind_indices( GLcontext *ctx, + const struct _mesa_index_buffer *ib, + struct gl_buffer_object **bo, + GLuint *nr_bo) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + void *ptr; + + if (!ib) { + VB->Elts = NULL; + return; + } + + if (ib->obj->Name && !ib->obj->Pointer) { + bo[*nr_bo] = ib->obj; + (*nr_bo)++; + ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER, + GL_READ_ONLY_ARB, + ib->obj); + + assert(ib->obj->Pointer); + } + + ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr); + + if (ib->type == GL_UNSIGNED_INT) { + VB->Elts = (GLuint *) ptr; + } + else { + GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint)); + VB->Elts = elts; + + if (ib->type == GL_UNSIGNED_SHORT) { + const GLushort *in = (GLushort *)ptr; + for (i = 0; i < ib->count; i++) + *elts++ = (GLuint)(*in++); + } + else { + const GLubyte *in = (GLubyte *)ptr; + for (i = 0; i < ib->count; i++) + *elts++ = (GLuint)(*in++); + } + } +} + +static void bind_prims( GLcontext *ctx, + const struct _mesa_prim *prim, + GLuint nr_prims ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + VB->Primitive = prim; + VB->PrimitiveCount = nr_prims; +} + +static void unmap_vbos( GLcontext *ctx, + struct gl_buffer_object **bo, + GLuint nr_bo ) +{ + GLuint i; + for (i = 0; i < nr_bo; i++) { + ctx->Driver.UnmapBuffer(ctx, + 0, /* target -- I don't see why this would be needed */ + bo[i]); + } +} + + + +/* This is the main entrypoint into the slimmed-down software tnl + * module. In a regular swtnl driver, this can be plugged straight + * into the vbo->Driver.DrawPrims() callback. + */ +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) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + const GLuint TEST_SPLIT = 0; + const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES; + + if (0) + { + GLuint i; + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); + for (i = 0; i < nr_prims; i++) + _mesa_printf("prim %d: %s start %d count %d\n", i, + _mesa_lookup_enum_by_nr(prim[i].mode), + prim[i].start, + prim[i].count); + } + + if (min_index) { + /* We always translate away calls with min_index != 0. + */ + vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, + min_index, max_index, + _tnl_draw_prims ); + return; + } + else if (max_index >= max) { + /* The software TNL pipeline has a fixed amount of storage for + * vertices and it is necessary to split incoming drawing commands + * if they exceed that limit. + */ + struct split_limits limits; + limits.max_verts = max; + limits.max_vb_size = ~0; + limits.max_indices = ~0; + + /* This will split the buffers one way or another and + * recursively call back into this function. + */ + vbo_split_prims( ctx, arrays, prim, nr_prims, ib, + 0, max_index, + _tnl_draw_prims, + &limits ); + } + else { + /* May need to map a vertex buffer object for every attribute plus + * one for the index buffer. + */ + struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1]; + GLuint nr_bo = 0; + + /* Binding inputs may imply mapping some vertex buffer objects. + * They will need to be unmapped below. + */ + bind_inputs(ctx, arrays, max_index+1, bo, &nr_bo); + bind_indices(ctx, ib, bo, &nr_bo); + bind_prims(ctx, prim, nr_prims ); + + TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx); + + unmap_vbos(ctx, bo, nr_bo); + free_space(ctx); + } +} + 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 <[email protected]> - * - */ - -#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 <[email protected]> - */ - -#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 426e94372ec..00000000000 --- a/src/mesa/tnl/t_save_playback.c +++ /dev/null @@ -1,216 +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 <[email protected]> - */ - -#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 ); - ctx->NewState |= _NEW_LIGHT; - } - - /* 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_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 0a443b3e017..97ff4c7f102 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -1096,7 +1096,7 @@ static void compile_vertex_program( struct gl_vertex_program *program, { struct compilation cp; struct tnl_compiled_program *p = CALLOC_STRUCT(tnl_compiled_program); - GLuint i; + GLint i; #if 1 if (!program->IsNVProgram && program->IsPositionInvariant) { @@ -1293,8 +1293,7 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) m->nr_inputs = m->nr_outputs = 0; for (i = 0; i < VERT_ATTRIB_MAX; i++) { - if (program->Base.InputsRead & (1<<i) || - (i == VERT_ATTRIB_POS && program->IsPositionInvariant)) { + if (program->Base.InputsRead & (1<<i)) { GLuint j = m->nr_inputs++; m->input[j].idx = i; m->input[j].data = (GLfloat *)m->VB->AttribPtr[i]->data; @@ -1302,16 +1301,15 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) m->input[j].size = m->VB->AttribPtr[i]->size; ASSIGN_4V(m->File[0][REG_IN0 + i], 0, 0, 0, 1); } - } + } for (i = 0; i < VERT_RESULT_MAX; i++) { - if (program->Base.OutputsWritten & (1 << i) || - (i == VERT_RESULT_HPOS && program->IsPositionInvariant)) { + if (program->Base.OutputsWritten & (1 << i)) { GLuint j = m->nr_outputs++; m->output[j].idx = i; m->output[j].data = (GLfloat *)m->attribs[i].data; } - } + } /* Run the actual program: @@ -1325,7 +1323,13 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) case 2: m->File[0][idx][1] = m->input[j].data[1]; case 1: m->File[0][idx][0] = m->input[j].data[0]; } - +#if 0 + printf(" attr %d/%d: %g %g %g %g\n", j, idx-REG_IN0, + m->input[j].data[0], + m->input[j].data[1], + m->input[j].data[2], + m->input[j].data[3]); +#endif STRIDE_F(m->input[j].data, m->input[j].stride); } @@ -1334,22 +1338,13 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) call_func( p, m ); } else { + GLint j; for (j = 0; j < p->nr_instructions; j++) { union instruction inst = p->instructions[j]; opcode_func[inst.alu.opcode]( m, inst ); } } - /* If the program is position invariant, multiply the input position - * by the MVP matrix and store in the vertex position result register. - */ -#if 0 - if (program->IsPositionInvariant) { - TRANSFORM_POINT( m->File[0][REG_OUT0+0], - ctx->_ModelProjectMatrix.m, - m->File[0][REG_IN0+0]); - } -#endif for (j = 0; j < m->nr_outputs; j++) { GLuint idx = REG_OUT0 + m->output[j].idx; m->output[j].data[0] = m->File[0][idx][0]; @@ -1371,15 +1366,39 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) * TODO: 2) Integrate t_vertex.c so that we just go straight ahead * and build machine vertices here. */ - VB->ClipPtr = &m->attribs[VERT_RESULT_HPOS]; - VB->ClipPtr->count = VB->Count; /* XXX There seems to be confusion between using the VERT_ATTRIB_* * values vs _TNL_ATTRIB_* tokens here: */ outputs = program->Base.OutputsWritten; - if (program->IsPositionInvariant) - outputs |= (1<<VERT_RESULT_HPOS); + + if (program->IsPositionInvariant) { + /* We need the exact same transform as in the fixed function path here + to guarantee invariance, depending on compiler optimization flags results + could be different otherwise */ + VB->ClipPtr = TransformRaw( &m->attribs[0], + &ctx->_ModelProjectMatrix, + m->VB->AttribPtr[0] ); + + /* Drivers expect this to be clean to element 4... + */ + switch (VB->ClipPtr->size) { + case 1: + /* impossible */ + case 2: + _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); + /* fall-through */ + case 3: + _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); + /* fall-through */ + case 4: + break; + } + } + else { + VB->ClipPtr = &m->attribs[VERT_RESULT_HPOS]; + VB->ClipPtr->count = VB->Count; + } if (outputs & (1<<VERT_RESULT_COL0)) { VB->ColorPtr[0] = 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_vp_build.c b/src/mesa/tnl/t_vp_build.c index 8b75dff96a8..283782588aa 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -812,14 +812,13 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p, /* Calculate spot attenuation: */ if (!p->state->unit[i].light_spotcutoff_is_180) { - struct ureg spot_dir = register_param3(p, STATE_LIGHT, i, - STATE_SPOT_DIRECTION); + struct ureg spot_dir_norm = register_param3(p, STATE_INTERNAL, + STATE_SPOT_DIR_NORMALIZED, i); struct ureg spot = get_temp(p); struct ureg slt = get_temp(p); - - emit_normalize_vec3( p, spot, spot_dir ); /* XXX: precompute! */ - emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot); - emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir,W), spot); + + emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm); + emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot); emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); emit_op2(p, OPCODE_MUL, att, 0, slt, spot); @@ -1109,29 +1108,27 @@ static void build_fog( struct tnl_program *p ) } if (p->state->tnl_do_vertex_fog) { - struct ureg params = register_param2(p, STATE_FOG, STATE_FOG_PARAMS); + struct ureg params = register_param2(p, STATE_INTERNAL, + STATE_FOG_PARAMS_OPTIMIZED); struct ureg tmp = get_temp(p); switch (p->state->fog_mode) { case FOG_LINEAR: { struct ureg id = get_identity_param(p); - emit_op2(p, OPCODE_SUB, tmp, 0, swizzle1(params,Z), input); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,W)); + emit_op3(p, OPCODE_MAD, tmp, 0, input, swizzle1(params,X), swizzle1(params,Y)); emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); break; } case FOG_EXP: emit_op1(p, OPCODE_ABS, tmp, 0, input); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,X)); - emit_op2(p, OPCODE_POW, fog, WRITEMASK_X, - register_const1f(p, M_E), negate(tmp)); + emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z)); + emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); break; case FOG_EXP2: - emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,X)); + emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); - emit_op2(p, OPCODE_POW, fog, WRITEMASK_X, - register_const1f(p, M_E), negate(tmp)); + emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); break; } @@ -1323,8 +1320,6 @@ static void build_texture_transform( struct tnl_program *p ) } -/* Seems like it could be tighter: - */ static void build_pointsize( struct tnl_program *p ) { struct ureg eye = get_eye_position(p); @@ -1333,20 +1328,25 @@ static void build_pointsize( struct tnl_program *p ) struct ureg out = register_output(p, VERT_RESULT_PSIZ); struct ureg ut = get_temp(p); - /* 1, -Z, Z * Z, 1 */ - emit_op1(p, OPCODE_MOV, ut, 0, swizzle1(get_identity_param(p), W)); - emit_op2(p, OPCODE_MUL, ut, WRITEMASK_YZ, ut, negate(swizzle1(eye, Z))); - emit_op2(p, OPCODE_MUL, ut, WRITEMASK_Z, ut, negate(swizzle1(eye, Z))); - - - /* p1 + p2 * dist + p3 * dist * dist, 0 */ - emit_op2(p, OPCODE_DP3, ut, 0, ut, state_attenuation); - - /* 1 / factor */ - emit_op1(p, OPCODE_RCP, ut, 0, ut ); - - /* out = pointSize / factor */ - emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); + /* p1 + dist * (p2 + dist * p3); */ + emit_op3(p, OPCODE_MAD, ut, 0, negate(swizzle1(eye, Z)), + swizzle1(state_attenuation, Z), swizzle1(state_attenuation, Y)); + emit_op3(p, OPCODE_MAD, ut, 0, negate(swizzle1(eye, Z)), + ut, swizzle1(state_attenuation, X)); + + /* 1 / sqrt(factor) */ + emit_op1(p, OPCODE_RSQ, ut, 0, ut ); + +#if 1 + /* out = pointSize / sqrt(factor) */ + emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); +#else + /* not sure, might make sense to do clamping here, + but it's not done in t_vb_points neither */ + emit_op2(p, OPCODE_MUL, ut, 0, ut, state_size); + emit_op2(p, OPCODE_MAX, ut, 0, ut, swizzle1(state_size, Y)); + emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); +#endif release_temp(p, ut); } diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c deleted file mode 100644 index 77eec8b3b44..00000000000 --- a/src/mesa/tnl/t_vtx_api.c +++ /dev/null @@ -1,1046 +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 <[email protected]> - */ - -#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->NewState |= _NEW_LIGHT; - } - - 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 <mode>. - */ -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 <[email protected]> - * - */ - -#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 bb621ecbe39..00000000000 --- a/src/mesa/tnl/t_vtx_eval.c +++ /dev/null @@ -1,264 +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 <[email protected]> - */ - -#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._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 900c4ab6cc1..00000000000 --- a/src/mesa/tnl/t_vtx_exec.c +++ /dev/null @@ -1,293 +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 <[email protected]> - */ - -#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: - /* no parity issue, but need to make sure the tri is not drawn twice */ - if (nr & 1) { - tnl->vtx.prim[tnl->vtx.prim_count-1].count--; - } - /* fallthrough */ - 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 <[email protected]> - */ - -#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 <[email protected]> - * Daniel Borca <[email protected]> - */ - - -#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 <[email protected]> - * Daniel Borca <[email protected]> - */ - -#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 |