aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/main/vtxfmt.c
diff options
context:
space:
mode:
authorGareth Hughes <[email protected]>2001-03-11 18:49:11 +0000
committerGareth Hughes <[email protected]>2001-03-11 18:49:11 +0000
commitd8aa0269cdadba1608522287bcb3b446c5848c09 (patch)
tree390b1c44ee248398514cdce16359c98862ca882d /src/mesa/main/vtxfmt.c
parentb1b403665635350df3f30db992faf50776606545 (diff)
Support for swappable tnl modules.
Core Mesa provides a neutral tnl module that verifies the currently module before installing the tnl function pointers in a lazy fashion. It also records which tnl functions have been swapped out, and only restores these when tnl modules themselves are swapped. Fallback strategies: Drivers set a bitmask of dangerous stage changes. When such a state change occurs, the driver should restore the neutral tnl module via _mesa_restore_exec_vtxfmt(). The neutral tnl module will call _mesa_update_state(), followed by ctx->Driver.ValidateTnlModule() if the validation bitmask matches the new state bitmask. The driver should call _tnl_wakeup_exec() if it can no longer handle the current state, which will revert to the default tnl module. In this case, previous vertices should be replayed as required (depending on the current primitive) after the new tnl module is installed. If the driver uses chooser functions for any part of the tnl module, these should generally be reinstalled as part of the fallback to the neutral tnl module. For example, if the lighting state changes, a driver might fall back to the neutral tnl module, verify that the current lighting state can be handled, and use the chooser function to pick the most efficient implementation of the current lighting state. It is up to the drivers to detect and handle fallback cases caused by tnl function calls themselves (such as glTexCoord4f* if the current tnl module can't handle projected textures, for example).
Diffstat (limited to 'src/mesa/main/vtxfmt.c')
-rw-r--r--src/mesa/main/vtxfmt.c98
1 files changed, 95 insertions, 3 deletions
diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c
index 860a9011fe8..22685e0f376 100644
--- a/src/mesa/main/vtxfmt.c
+++ b/src/mesa/main/vtxfmt.c
@@ -1,9 +1,86 @@
+/* $Id: vtxfmt.c,v 1.2 2001/03/11 18:49:11 gareth Exp $ */
+
+/*
+ * 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.
+ *
+ * Author:
+ * Keith Whitwell <[email protected]>
+ * Gareth Hughes <[email protected]>
+ */
+
#include "glheader.h"
#include "api_loopback.h"
+#include "context.h"
#include "mtypes.h"
#include "vtxfmt.h"
+/* The neutral vertex format. This wraps all tnl module functions,
+ * verifying that the currently-installed module is valid and then
+ * installing the function pointers in a lazy fashion. It records the
+ * function pointers that have been swapped out, which allows a fast
+ * restoration of the neutral module in almost all cases -- a typical
+ * app might only require 4-6 functions to be modified from the neutral
+ * baseline, and only restoring these is certainly preferable to doing
+ * the entire module's 60 or so function pointers.
+ */
+
+#define PRE_LOOPBACK( FUNC ) \
+{ \
+ GET_CURRENT_CONTEXT(ctx); \
+ struct gl_tnl_module *tnl = &(ctx->TnlModule); \
+ const GLuint new_state = ctx->NewState; \
+ \
+ if ( new_state ) \
+ _mesa_update_state( ctx ); \
+ \
+ /* Validate the current tnl module. \
+ */ \
+ if ( new_state & ctx->Driver.NeedValidate ) \
+ ctx->Driver.ValidateTnlModule( ctx, new_state ); \
+ \
+ ASSERT( tnl->Current ); \
+ ASSERT( tnl->SwapCount < NUM_VERTEX_FORMAT_ENTRIES ); \
+ \
+ /* Save the swapped function's dispatch entry so it can be \
+ * restored later. \
+ */ \
+ tnl->Swapped[tnl->SwapCount][0] = (void *)&(ctx->Exec->FUNC); \
+ tnl->Swapped[tnl->SwapCount][1] = (void *)TAG(FUNC); \
+ tnl->SwapCount++; \
+ \
+ if ( 0 ) \
+ fprintf( stderr, " swapping gl" #FUNC"...\n" ); \
+ \
+ /* Install the tnl function pointer. \
+ */ \
+ ctx->Exec->FUNC = tnl->Current->FUNC; \
+}
+
+#define TAG(x) neutral_##x
+#include "vtxfmt_tmp.h"
+
+
static void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt )
{
@@ -59,7 +136,7 @@ static void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt )
tab->Vertex4fv = vfmt->Vertex4fv;
tab->Begin = vfmt->Begin;
tab->End = vfmt->End;
-
+
/* tab->NewList = vfmt->NewList; */
tab->CallList = vfmt->CallList;
@@ -74,12 +151,12 @@ static void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt )
void _mesa_install_exec_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt )
{
- install_vtxfmt( ctx->Exec, vfmt );
+ ctx->TnlModule.Current = vfmt;
+ install_vtxfmt( ctx->Exec, &neutral_vtxfmt );
if (ctx->ExecPrefersFloat != vfmt->prefer_float_colors)
_mesa_loopback_prefer_float( ctx->Exec, vfmt->prefer_float_colors );
}
-
void _mesa_install_save_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt )
{
install_vtxfmt( ctx->Save, vfmt );
@@ -87,3 +164,18 @@ void _mesa_install_save_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt )
_mesa_loopback_prefer_float( ctx->Save, vfmt->prefer_float_colors );
}
+void _mesa_restore_exec_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt )
+{
+ struct gl_tnl_module *tnl = &(ctx->TnlModule);
+ GLuint i;
+
+ tnl->Current = vfmt;
+
+ /* Restore the neutral tnl module wrapper.
+ */
+ for ( i = 0 ; i < tnl->SwapCount ; i++ ) {
+ *(void **)tnl->Swapped[i][0] = tnl->Swapped[i][1];
+ }
+
+ tnl->SwapCount = 0;
+}