removed need for Shared->TexObjectList, walk over texture hash table entries instead
[profile/ivi/mesa.git] / src / mesa / drivers / dri / tdfx / tdfx_context.c
1 /* -*- mode: c; c-basic-offset: 3 -*-
2  *
3  * Copyright 2000 VA Linux Systems Inc., Fremont, California.
4  *
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the next
15  * paragraph) shall be included in all copies or substantial portions of the
16  * Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c,v 1.12 2003/05/08 09:25:35 herrb Exp $ */
27
28 /*
29  * New fixes:
30  *      Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
31  *
32  * Original rewrite:
33  *      Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
34  *
35  * Authors:
36  *      Gareth Hughes <gareth@valinux.com>
37  *      Brian Paul <brianp@valinux.com>
38  *
39  */
40
41 #include <dlfcn.h>
42 #include "tdfx_context.h"
43 #include "tdfx_dd.h"
44 #include "tdfx_state.h"
45 #include "tdfx_vb.h"
46 #include "tdfx_tex.h"
47 #include "tdfx_tris.h"
48 #include "tdfx_render.h"
49 #include "tdfx_span.h"
50 #include "tdfx_texman.h"
51 #include "extensions.h"
52 #include "hash.h"
53
54 #include "swrast/swrast.h"
55 #include "swrast_setup/swrast_setup.h"
56 #include "array_cache/acache.h"
57
58 #include "tnl/tnl.h"
59 #include "tnl/t_pipeline.h"
60
61 #include "drivers/common/driverfuncs.h"
62
63 #include "utils.h"
64
65 PUBLIC const char __driConfigOptions[] = { 0 };
66 const GLuint __driNConfigOptions = 0;
67
68 /**
69  * Common extension strings exported by all cards
70  */
71 static const char * const card_extensions[] =
72 {
73    "GL_ARB_texture_mirrored_repeat",
74    "GL_ARB_vertex_buffer_object",
75    "GL_EXT_blend_func_separate",
76    "GL_EXT_fog_coord",
77    "GL_EXT_multi_draw_arrays",
78    "GL_EXT_paletted_texture",
79    "GL_EXT_shared_texture_palette",
80    "GL_EXT_stencil_wrap",
81    "GL_EXT_texture_env_add",
82    "GL_EXT_texture_lod_bias",
83    "GL_HP_occlusion_test",
84    "GL_IBM_multimode_draw_arrays",
85
86 #if 0
87    "GL_ARB_point_sprite",
88    "GL_EXT_point_parameters",
89    "GL_EXT_secondary_color",
90 #endif
91 #if 0
92    /* not just yet */
93    "GL_ARB_vertex_program",
94    "GL_NV_vertex_program",
95    "GL_NV_vertex_program1_1",
96    "GL_MESA_program_debug",
97 #endif
98    NULL
99 };
100
101 /**
102  * Extension strings exported only by Naplam (e.g., Voodoo4 & Voodoo5) cards.
103  */
104 static const char * const napalm_extensions[] =
105 {
106    "GL_ARB_texture_compression",
107    "GL_ARB_texture_env_combine",
108    "GL_EXT_blend_equation_separate",
109    "GL_EXT_blend_subtract",
110    "GL_EXT_texture_compression_s3tc",
111    "GL_EXT_texture_env_combine",
112
113    "GL_3DFX_texture_compression_FXT1",
114    "GL_NV_blend_square",
115    "GL_S3_s3tc",
116    NULL
117 };
118
119 /*
120  * Enable/Disable the extensions for this context.
121  */
122 static void tdfxDDInitExtensions( GLcontext *ctx )
123 {
124    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
125
126    driInitExtensions( ctx, card_extensions, GL_FALSE );
127
128    if ( fxMesa->haveTwoTMUs ) {
129       _mesa_enable_extension( ctx, "GL_ARB_multitexture" );
130    }
131
132    if ( TDFX_IS_NAPALM( fxMesa ) ) {
133       driInitExtensions( ctx, napalm_extensions, GL_FALSE );
134    } else {
135       _mesa_enable_extension( ctx, "GL_SGIS_generate_mipmap" );
136    }
137 }
138
139
140
141 static const struct tnl_pipeline_stage *tdfx_pipeline[] = {
142    &_tnl_vertex_transform_stage, 
143    &_tnl_normal_transform_stage, 
144    &_tnl_lighting_stage,
145    &_tnl_fog_coordinate_stage, 
146    &_tnl_texgen_stage, 
147    &_tnl_texture_transform_stage, 
148    &_tnl_point_attenuation_stage,
149 #if 0
150 #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program)
151    &_tnl_vertex_program_stage,
152 #endif
153 #endif
154    &_tnl_render_stage,          
155    0,
156 };
157
158
159 GLboolean tdfxCreateContext( const __GLcontextModes *mesaVis,
160                              __DRIcontextPrivate *driContextPriv,
161                              void *sharedContextPrivate )
162 {
163    tdfxContextPtr fxMesa;
164    GLcontext *ctx, *shareCtx;
165    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
166    tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private;
167    TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) ((char *) sPriv->pSAREA +
168                                               sizeof(drm_sarea_t));
169    struct dd_function_table functions;
170
171    /* Allocate tdfx context */
172    fxMesa = (tdfxContextPtr) CALLOC( sizeof(tdfxContextRec) );
173    if (!fxMesa)
174       return GL_FALSE;
175
176    /* Init default driver functions then plug in our tdfx-specific functions
177     * (the texture functions are especially important)
178     */
179    _mesa_init_driver_functions(&functions);
180    tdfxDDInitDriverFuncs(mesaVis, &functions);
181    tdfxInitTextureFuncs(&functions);
182    tdfxInitRenderFuncs(&functions);
183
184    /* Allocate the Mesa context */
185    if (sharedContextPrivate)
186       shareCtx = ((tdfxContextPtr) sharedContextPrivate)->glCtx;
187    else 
188       shareCtx = NULL;
189
190    fxMesa->glCtx = _mesa_create_context(mesaVis, shareCtx,
191                                         &functions, (void *) fxMesa);
192    if (!fxMesa->glCtx) {
193       FREE(fxMesa);
194       return GL_FALSE;
195    }
196    driContextPriv->driverPrivate = fxMesa;
197
198    /* Mirror some important DRI state
199     */
200    fxMesa->hHWContext = driContextPriv->hHWContext;
201    fxMesa->driHwLock = &sPriv->pSAREA->lock;
202    fxMesa->driFd = sPriv->fd;
203
204    fxMesa->driScreen = sPriv;
205    fxMesa->driContext = driContextPriv;
206    fxMesa->fxScreen = fxScreen;
207    fxMesa->sarea = saPriv;
208
209    /*JJJ - really?*/
210    fxMesa->haveHwAlpha = ( mesaVis->alphaBits &&
211                            ((mesaVis->greenBits == 8) ||
212                             (mesaVis->depthBits == 0)) );
213    fxMesa->haveHwStencil = ( TDFX_IS_NAPALM( fxMesa ) &&
214                              mesaVis->stencilBits &&
215                              mesaVis->depthBits == 24 );
216
217    fxMesa->screen_width = fxScreen->width;
218    fxMesa->screen_height = fxScreen->height;
219
220    fxMesa->new_gl_state = ~0;
221    fxMesa->new_state = ~0;
222    fxMesa->dirty = ~0;
223
224    /* NOTE: This must be here before any Glide calls! */
225    if (!tdfxInitGlide( fxMesa )) {
226       FREE(fxMesa);
227       return GL_FALSE;
228    }
229
230    fxMesa->Glide.grDRIOpen( (char*) sPriv->pFB, fxScreen->regs.map, fxScreen->deviceID,
231               fxScreen->width, fxScreen->height, fxScreen->mem, fxScreen->cpp,
232               fxScreen->stride, fxScreen->fifoOffset, fxScreen->fifoSize,
233               fxScreen->fbOffset, fxScreen->backOffset, fxScreen->depthOffset,
234               fxScreen->textureOffset, fxScreen->textureSize, &saPriv->fifoPtr,
235               &saPriv->fifoRead );
236
237    if ( getenv( "FX_GLIDE_SWAPINTERVAL" ) ) {
238       fxMesa->Glide.SwapInterval = atoi( getenv( "FX_GLIDE_SWAPINTERVAL" ) );
239    } else {
240       fxMesa->Glide.SwapInterval = 0;
241    }
242    if ( getenv( "FX_MAX_PENDING_SWAPS" ) ) {
243       fxMesa->Glide.MaxPendingSwaps = atoi( getenv( "FX_MAX_PENDING_SWAPS" ) );
244    } else {
245       fxMesa->Glide.MaxPendingSwaps = 2;
246    }
247
248    fxMesa->Glide.Initialized = GL_FALSE;
249    fxMesa->Glide.Board = 0;
250
251
252    if (getenv("FX_EMULATE_SINGLE_TMU")) {
253       fxMesa->haveTwoTMUs = GL_FALSE;
254    }
255    else {
256       if ( TDFX_IS_BANSHEE( fxMesa ) ) {
257          fxMesa->haveTwoTMUs = GL_FALSE;
258       } else {
259          fxMesa->haveTwoTMUs = GL_TRUE;
260       }
261    }
262
263    fxMesa->stats.swapBuffer = 0;
264    fxMesa->stats.reqTexUpload = 0;
265    fxMesa->stats.texUpload = 0;
266    fxMesa->stats.memTexUpload = 0;
267
268    fxMesa->tmuSrc = TDFX_TMU_NONE;
269
270    ctx = fxMesa->glCtx;
271    if ( TDFX_IS_NAPALM( fxMesa ) ) {
272       ctx->Const.MaxTextureLevels = 12;
273    } else {
274       ctx->Const.MaxTextureLevels = 9;
275    }
276    ctx->Const.MaxTextureUnits = TDFX_IS_BANSHEE( fxMesa ) ? 1 : 2;
277    ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
278    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
279
280    /* No wide points.
281     */
282    ctx->Const.MinPointSize = 1.0;
283    ctx->Const.MinPointSizeAA = 1.0;
284    ctx->Const.MaxPointSize = 1.0;
285    ctx->Const.MaxPointSizeAA = 1.0;
286
287    /* Disable wide lines as we can't antialias them correctly in
288     * hardware.
289     */
290    ctx->Const.MinLineWidth = 1.0;
291    ctx->Const.MinLineWidthAA = 1.0;
292    ctx->Const.MaxLineWidth = 1.0;
293    ctx->Const.MaxLineWidthAA = 1.0;
294    ctx->Const.LineWidthGranularity = 1.0;
295
296    /* Initialize the software rasterizer and helper modules.
297     */
298    _swrast_CreateContext( ctx );
299    _ac_CreateContext( ctx );
300    _tnl_CreateContext( ctx );
301    _swsetup_CreateContext( ctx );
302
303    /* Install the customized pipeline:
304     */
305    _tnl_destroy_pipeline( ctx );
306    _tnl_install_pipeline( ctx, tdfx_pipeline );
307
308    /* Configure swrast and T&L to match hardware characteristics:
309     */
310    _swrast_allow_pixel_fog( ctx, GL_TRUE );
311    _swrast_allow_vertex_fog( ctx, GL_FALSE );
312    _tnl_allow_pixel_fog( ctx, GL_TRUE );
313    _tnl_allow_vertex_fog( ctx, GL_FALSE );
314
315    tdfxDDInitExtensions( ctx );
316    /* XXX these should really go right after _mesa_init_driver_functions() */
317    tdfxDDInitSpanFuncs( ctx ); 
318    tdfxDDInitStateFuncs( ctx );
319    tdfxDDInitTriFuncs( ctx );
320    tdfxInitVB( ctx );
321    tdfxInitState( fxMesa );
322
323    return GL_TRUE;
324 }
325
326
327 static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa )
328 {
329    FxI32 result;
330    int i;
331
332    LOCK_HARDWARE( fxMesa );
333
334    fxMesa->Glide.grGet( GR_GLIDE_VERTEXLAYOUT_SIZE, sizeof(FxI32), &result );
335    for ( i = 0 ; i < TDFX_NUM_LAYOUTS ; i++ ) {
336       fxMesa->layout[i] = MALLOC( result );
337       if ( !fxMesa->layout[i] ) {
338          UNLOCK_HARDWARE( fxMesa );
339          return GL_FALSE;
340       }
341    }
342
343    /* Tiny vertex format - 16 bytes.
344     */
345    fxMesa->Glide.grReset( GR_VERTEX_PARAMETER );
346    fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS );
347    fxMesa->Glide.grVertexLayout( GR_PARAM_XY,   TDFX_XY_OFFSET, GR_PARAM_ENABLE );
348    fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE );
349    fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE );
350    fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_TINY] );
351
352    /* Non textured vertex format - 24 bytes (Need w for table fog)
353     */
354    fxMesa->Glide.grReset( GR_VERTEX_PARAMETER );
355    fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS );
356    fxMesa->Glide.grVertexLayout( GR_PARAM_XY,   TDFX_XY_OFFSET, GR_PARAM_ENABLE );
357    fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE );
358    fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE );
359    fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE );
360    fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_NOTEX] );
361
362    /* Single textured vertex format - 32 bytes.
363     */
364    fxMesa->Glide.grReset( GR_VERTEX_PARAMETER );
365    fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS );
366    fxMesa->Glide.grVertexLayout( GR_PARAM_XY,   TDFX_XY_OFFSET, GR_PARAM_ENABLE );
367    fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE );
368    fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE );
369    fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE );
370    fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE );
371    fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_SINGLE] );
372
373    /* Multitextured vertex format - 40 bytes.
374     */
375    fxMesa->Glide.grReset( GR_VERTEX_PARAMETER );
376    fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS );
377    fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE );
378    fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE );
379    fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE );
380    fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE );
381    fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE );
382    fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE );
383    fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_MULTI] );
384
385    /* Projected texture vertex format - 36 bytes.
386     */
387    fxMesa->Glide.grReset( GR_VERTEX_PARAMETER );
388    fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS );
389    fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE );
390    fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE );
391    fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE );
392    fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE );
393    fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE );
394    fxMesa->Glide.grVertexLayout( GR_PARAM_Q0, TDFX_Q0_OFFSET, GR_PARAM_ENABLE );
395    fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_PROJ1] );
396
397    /* Projected multitexture vertex format - 48 bytes.
398     */
399    fxMesa->Glide.grReset( GR_VERTEX_PARAMETER );
400    fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS );
401    fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE );
402    fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE );
403    fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE );
404    fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE );
405    fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE );
406    fxMesa->Glide.grVertexLayout( GR_PARAM_Q0, TDFX_Q0_OFFSET, GR_PARAM_ENABLE );
407    fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE );
408    fxMesa->Glide.grVertexLayout( GR_PARAM_Q1, TDFX_Q1_OFFSET, GR_PARAM_ENABLE );
409    fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_PROJ2] );
410
411    UNLOCK_HARDWARE( fxMesa );
412
413    return GL_TRUE;
414 }
415
416
417 /*
418  * Initialize the state in an tdfxContextPtr struct.
419  */
420 static GLboolean
421 tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, tdfxContextPtr fxMesa )
422 {
423    /* KW: Would be nice to make one of these a member of the other.
424     */
425    FxI32 result[2];
426    const char *gext;
427
428    if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
429       fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)fxMesa );
430    }
431
432 #if DEBUG_LOCKING
433    fprintf(stderr, "Debug locking enabled\n");
434 #endif
435
436    if ( fxMesa->Glide.Initialized )
437       return GL_TRUE;
438
439    fxMesa->width = driDrawPriv->w;
440    fxMesa->height = driDrawPriv->h;
441
442    /* We have to use a light lock here, because we can't do any glide
443     * operations yet. No use of FX_* functions in this function.
444     */
445    DRM_LIGHT_LOCK( fxMesa->driFd, fxMesa->driHwLock, fxMesa->hHWContext );
446
447    fxMesa->Glide.grGlideInit();
448    fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
449
450    fxMesa->Glide.Context = fxMesa->Glide.grSstWinOpen( (FxU32) -1,
451                                          GR_RESOLUTION_NONE,
452                                          GR_REFRESH_NONE,
453                                          fxMesa->Glide.ColorFormat,
454                                          fxMesa->Glide.Origin,
455                                          2, 1 );
456
457    fxMesa->Glide.grDRIResetSAREA();
458
459    DRM_UNLOCK( fxMesa->driFd, fxMesa->driHwLock, fxMesa->hHWContext );
460
461    if ( !fxMesa->Glide.Context )
462       return GL_FALSE;
463
464
465    /* Perform the Glide-dependant part of the context initialization.
466     */
467    FX_grColorMaskv( fxMesa->glCtx, true4 );
468
469    tdfxTMInit( fxMesa );
470
471    LOCK_HARDWARE( fxMesa );
472
473    /* JJJ - COMMAND_TRANSPORT, PALETTE6666 */
474    gext = fxMesa->Glide.grGetString( GR_EXTENSION );
475    fxMesa->Glide.HaveCombineExt = strstr(gext, "COMBINE") && !getenv("MESA_FX_IGNORE_CMBEXT");
476    fxMesa->Glide.HaveCommandTransportExt = GL_FALSE;
477    fxMesa->Glide.HaveFogCoordExt = GL_TRUE;
478    fxMesa->Glide.HavePixelExt = strstr(gext, "PIXEXT") && !getenv("MESA_FX_IGNORE_PIXEXT");
479    fxMesa->Glide.HaveTextureBufferExt = GL_TRUE;
480    fxMesa->Glide.HaveTexFmtExt = strstr(gext, "TEXFMT") && !getenv("MESA_FX_IGNORE_TEXFMT");
481    fxMesa->Glide.HaveTexUMAExt = strstr(gext, "TEXUMA") && !getenv("MESA_FX_IGNORE_TEXUMA");
482    fxMesa->Glide.HaveMirrorExt = strstr(gext, "TEXMIRROR") && !getenv("MESA_FX_IGNORE_MIREXT");
483    fxMesa->Glide.HaveTexus2 = GL_FALSE;
484
485    if ( fxMesa->glCtx->Visual.depthBits > 0 ) {
486       fxMesa->Glide.grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER);
487    } else {
488       fxMesa->Glide.grDepthBufferMode(GR_DEPTHBUFFER_DISABLE);
489    }
490
491    fxMesa->Glide.grLfbWriteColorFormat( GR_COLORFORMAT_ABGR );
492
493    fxMesa->Glide.grGet( GR_TEXTURE_ALIGN, sizeof(FxI32), result );
494    fxMesa->Glide.TextureAlign = result[0];
495
496    fxMesa->Glide.State = NULL;
497    fxMesa->Glide.grGet( GR_GLIDE_STATE_SIZE, sizeof(FxI32), result );
498    fxMesa->Glide.State = MALLOC( result[0] );
499
500    fxMesa->Fog.Table = NULL;
501    fxMesa->Glide.grGet( GR_FOG_TABLE_ENTRIES, sizeof(FxI32), result );
502    fxMesa->Fog.Table = MALLOC( result[0] * sizeof(GrFog_t) );
503
504    UNLOCK_HARDWARE( fxMesa );
505
506    if ( !fxMesa->Glide.State || !fxMesa->Fog.Table ) {
507       if ( fxMesa->Glide.State )
508          FREE( fxMesa->Glide.State );
509       if ( fxMesa->Fog.Table )
510          FREE( fxMesa->Fog.Table );
511       return GL_FALSE;
512    }
513
514    if ( !tdfxInitVertexFormats( fxMesa ) ) {
515       return GL_FALSE;
516    }
517
518    LOCK_HARDWARE( fxMesa );
519
520    fxMesa->Glide.grGlideGetState( fxMesa->Glide.State );
521
522    if ( getenv( "FX_GLIDE_INFO" ) ) {
523       printf( "GR_RENDERER  = %s\n", (char *) fxMesa->Glide.grGetString( GR_RENDERER ) );
524       printf( "GR_VERSION   = %s\n", (char *) fxMesa->Glide.grGetString( GR_VERSION ) );
525       printf( "GR_VENDOR    = %s\n", (char *) fxMesa->Glide.grGetString( GR_VENDOR ) );
526       printf( "GR_HARDWARE  = %s\n", (char *) fxMesa->Glide.grGetString( GR_HARDWARE ) );
527       printf( "GR_EXTENSION = %s\n", (char *) gext );
528    }
529
530    UNLOCK_HARDWARE( fxMesa );
531
532    {
533       const char *debug = getenv("LIBGL_DEBUG");
534       if (debug && strstr(debug, "fallbacks")) {
535          fxMesa->debugFallbacks = GL_TRUE;
536       }
537    }
538
539
540    fxMesa->numClipRects = 0;
541    fxMesa->pClipRects = NULL;
542    fxMesa->scissoredClipRects = GL_FALSE;
543
544    fxMesa->Glide.Initialized = GL_TRUE;
545
546    return GL_TRUE;
547 }
548
549
550 void
551 tdfxDestroyContext( __DRIcontextPrivate *driContextPriv )
552 {
553    tdfxContextPtr fxMesa = (tdfxContextPtr) driContextPriv->driverPrivate;
554
555    if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
556       fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)fxMesa );
557    }
558
559    if ( fxMesa ) {
560       if (fxMesa->glCtx->Shared->RefCount == 1 && fxMesa->driDrawable) {
561          /* This share group is about to go away, free our private
562           * texture object data.
563           */
564 #if 0
565          struct gl_texture_object *tObj;
566          tObj = fxMesa->glCtx->Shared->TexObjectList;
567          while (tObj) {
568             tdfxTMFreeTexture(fxMesa, tObj);
569             tObj = tObj->Next;
570          }
571 #else
572          struct _mesa_HashTable *textures = fxMesa->glCtx->Shared->TexObjects;
573          GLuint id;
574          for (id = _mesa_HashFirstEntry(textures);
575               id;
576               id = _mesa_HashNextEntry(textures, id)) {
577             struct gl_texture_object *tObj
578                = (struct gl_texture_object *) _mesa_HashLookup(textures, id);
579             tdfxTMFreeTexture(fxMesa, tObj);
580          }
581 #endif
582       }
583
584       tdfxTMClose(fxMesa);  /* free texture memory */
585
586       _swsetup_DestroyContext( fxMesa->glCtx );
587       _tnl_DestroyContext( fxMesa->glCtx );
588       _ac_DestroyContext( fxMesa->glCtx );
589       _swrast_DestroyContext( fxMesa->glCtx );
590
591       tdfxFreeVB( fxMesa->glCtx );
592
593       /* Free Mesa context */
594       fxMesa->glCtx->DriverCtx = NULL;
595       _mesa_destroy_context(fxMesa->glCtx);
596
597       /* free the tdfx context */
598       FREE( fxMesa );
599    }
600 }
601
602
603 GLboolean
604 tdfxUnbindContext( __DRIcontextPrivate *driContextPriv )
605 {
606    GET_CURRENT_CONTEXT(ctx);
607    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
608
609    if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
610       fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)driContextPriv );
611    }
612
613    if ( driContextPriv && (tdfxContextPtr) driContextPriv == fxMesa ) {
614       LOCK_HARDWARE(fxMesa);
615       fxMesa->Glide.grGlideGetState(fxMesa->Glide.State);
616       UNLOCK_HARDWARE(fxMesa);
617    }
618    return GL_TRUE;
619 }
620
621
622 GLboolean
623 tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv,
624                  __DRIdrawablePrivate *driDrawPriv,
625                  __DRIdrawablePrivate *driReadPriv )
626 {
627    if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
628       fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)driContextPriv );
629    }
630
631    if ( driContextPriv ) {
632       tdfxContextPtr newFx = (tdfxContextPtr) driContextPriv->driverPrivate;
633       GLcontext *newCtx = newFx->glCtx;
634       GET_CURRENT_CONTEXT(curCtx);
635
636       if ( newFx->driDrawable != driDrawPriv ) {
637          newFx->driDrawable = driDrawPriv;
638          newFx->dirty = ~0;
639       }
640       else {
641          if (curCtx == newCtx) {
642             /* same drawable, same context -> no-op */
643             /* Need to call _mesa_make_current2() in order to make sure API
644              * dispatch is set correctly.
645              */
646             _mesa_make_current2( newCtx,
647                                  (GLframebuffer *) driDrawPriv->driverPrivate,
648                                  (GLframebuffer *) driReadPriv->driverPrivate );
649             return GL_TRUE;
650          }
651          /* [dBorca] tunnel2 requires this */
652          newFx->dirty = ~0;
653       }
654
655       if ( !newFx->Glide.Initialized ) {
656          if ( !tdfxInitContext( driDrawPriv, newFx ) )
657             return GL_FALSE;
658
659          LOCK_HARDWARE( newFx );
660
661          /* FIXME: Force loading of window information */
662          newFx->width = 0;
663          tdfxUpdateClipping(newCtx);
664          tdfxUploadClipping(newFx);
665
666          UNLOCK_HARDWARE( newFx );
667       } else {
668          LOCK_HARDWARE( newFx );
669
670          newFx->Glide.grSstSelect( newFx->Glide.Board );
671          newFx->Glide.grGlideSetState( newFx->Glide.State );
672
673          tdfxUpdateClipping(newCtx);
674          tdfxUploadClipping(newFx);
675
676          UNLOCK_HARDWARE( newFx );
677       }
678
679       _mesa_make_current2( newCtx,
680                            (GLframebuffer *) driDrawPriv->driverPrivate,
681                            (GLframebuffer *) driReadPriv->driverPrivate );
682    } else {
683       _mesa_make_current( 0, 0 );
684    }
685
686    return GL_TRUE;
687 }
688
689
690 /*
691  * Enable this to trace calls to various Glide functions.
692  */
693 /*#define DEBUG_TRAP*/
694 #ifdef DEBUG_TRAP
695 static void (*real_grDrawTriangle)( const void *a, const void *b, const void *c );
696 static void (*real_grDrawPoint)( const void *a );
697 static void (*real_grDrawVertexArray)(FxU32 mode, FxU32 Count, void *pointers);
698 static void (*real_grDrawVertexArrayContiguous)(FxU32 mode, FxU32 Count,
699                                        void *pointers, FxU32 stride);
700 static void (*real_grClipWindow)( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy );
701
702 static void (*real_grVertexLayout)(FxU32 param, FxI32 offset, FxU32 mode);
703 static void (*real_grGlideGetVertexLayout)( void *layout );
704 static void (*real_grGlideSetVertexLayout)( const void *layout );
705
706 static void (*real_grTexDownloadMipMapLevel)( GrChipID_t        tmu,
707                                      FxU32             startAddress,
708                                      GrLOD_t           thisLod,
709                                      GrLOD_t           largeLod,
710                                      GrAspectRatio_t   aspectRatio,
711                                      GrTextureFormat_t format,
712                                      FxU32             evenOdd,
713                                               void              *data );
714
715
716 static void debug_grDrawTriangle( const void *a, const void *b, const void *c )
717 {
718    printf("%s\n", __FUNCTION__);
719    (*real_grDrawTriangle)(a, b, c);
720 }
721
722 static void debug_grDrawPoint( const void *a )
723 {
724    const float *f = (const float *) a;
725    printf("%s %g %g\n", __FUNCTION__, f[0], f[1]);
726    (*real_grDrawPoint)(a);
727 }
728
729 static void debug_grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers)
730 {
731    printf("%s count=%d\n", __FUNCTION__, (int) Count);
732    (*real_grDrawVertexArray)(mode, Count, pointers);
733 }
734
735 static void debug_grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count,
736                                        void *pointers, FxU32 stride)
737 {
738    printf("%s mode=0x%x count=%d\n", __FUNCTION__, (int) mode, (int) Count);
739    (*real_grDrawVertexArrayContiguous)(mode, Count, pointers, stride);
740 }
741
742 static void debug_grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy )
743 {
744    printf("%s %d,%d .. %d,%d\n", __FUNCTION__,
745           (int) minx, (int) miny, (int) maxx, (int) maxy);
746    (*real_grClipWindow)(minx, miny, maxx, maxy);
747 }
748
749 static void debug_grVertexLayout(FxU32 param, FxI32 offset, FxU32 mode)
750 {
751    (*real_grVertexLayout)(param, offset, mode);
752 }
753
754 static void debug_grGlideGetVertexLayout( void *layout )
755 {
756    (*real_grGlideGetVertexLayout)(layout);
757 }
758
759 static void debug_grGlideSetVertexLayout( const void *layout )
760 {
761    (*real_grGlideSetVertexLayout)(layout);
762 }
763
764 static void debug_grTexDownloadMipMapLevel( GrChipID_t        tmu,
765                                      FxU32             startAddress,
766                                      GrLOD_t           thisLod,
767                                      GrLOD_t           largeLod,
768                                      GrAspectRatio_t   aspectRatio,
769                                      GrTextureFormat_t format,
770                                      FxU32             evenOdd,
771                                      void              *data )
772 {
773    (*real_grTexDownloadMipMapLevel)(tmu, startAddress, thisLod, largeLod,
774                                     aspectRatio, format, evenOdd, data);
775 }
776
777 #endif
778
779
780 /*
781  * Examine the context's deviceID to determine what kind of 3dfx hardware
782  * is installed.  dlopen() the appropriate Glide library and initialize
783  * this context's Glide function pointers.
784  * Return:  true/false = success/failure
785  */
786 GLboolean tdfxInitGlide(tdfxContextPtr tmesa)
787 {
788    static const char *defaultGlide = "libglide3.so";
789    const char *libName;
790    void *libHandle;
791
792    /*
793     * XXX this code which selects a Glide library filename given the
794     * deviceID may need to be cleaned up a bit.
795     * Non-Linux systems may have different filenames, for example.
796     */
797    switch (tmesa->fxScreen->deviceID) {
798    case PCI_CHIP_BANSHEE:
799    case PCI_CHIP_VOODOO3:
800       libName = "libglide3-v3.so";
801       break;
802    case PCI_CHIP_VOODOO5:   /* same as PCI_CHIP_VOODOO4 */
803       libName = "libglide3-v5.so";
804       break;
805    default:
806       {
807          __driUtilMessage("unrecognized 3dfx deviceID: 0x%x",
808                  tmesa->fxScreen->deviceID);
809       }
810       return GL_FALSE;
811    }
812
813    libHandle = dlopen(libName, RTLD_NOW);
814    if (!libHandle) {
815       /* The device-specific Glide library filename didn't work, try the
816        * old, generic libglide3.so library.
817        */
818       libHandle = dlopen(defaultGlide, RTLD_NOW); 
819       if (!libHandle) {
820          __driUtilMessage(
821             "can't find Glide library, dlopen(%s) and dlopen(%s) both failed.",
822             libName, defaultGlide);
823          __driUtilMessage("dlerror() message: %s", dlerror());
824          return GL_FALSE;
825       }
826       libName = defaultGlide;
827    }
828
829    {
830       const char *env = getenv("LIBGL_DEBUG");
831       if (env && strstr(env, "verbose")) {
832          fprintf(stderr, "libGL: using Glide library %s\n", libName);
833       }
834    }         
835
836 #define GET_FUNCTION(PTR, NAME)                                         \
837    tmesa->Glide.PTR = dlsym(libHandle, NAME);                           \
838    if (!tmesa->Glide.PTR) {                                             \
839       __driUtilMessage("couldn't find Glide function %s in %s.",        \
840               NAME, libName);                                           \
841    }
842
843    GET_FUNCTION(grDrawPoint, "grDrawPoint");
844    GET_FUNCTION(grDrawLine, "grDrawLine");
845    GET_FUNCTION(grDrawTriangle, "grDrawTriangle");
846    GET_FUNCTION(grVertexLayout, "grVertexLayout");
847    GET_FUNCTION(grDrawVertexArray, "grDrawVertexArray");
848    GET_FUNCTION(grDrawVertexArrayContiguous, "grDrawVertexArrayContiguous");
849    GET_FUNCTION(grBufferClear, "grBufferClear");
850    /*GET_FUNCTION(grBufferSwap, "grBufferSwap");*/
851    GET_FUNCTION(grRenderBuffer, "grRenderBuffer");
852    GET_FUNCTION(grErrorSetCallback, "grErrorSetCallback");
853    GET_FUNCTION(grFinish, "grFinish");
854    GET_FUNCTION(grFlush, "grFlush");
855    GET_FUNCTION(grSstWinOpen, "grSstWinOpen");
856    GET_FUNCTION(grSstWinClose, "grSstWinClose");
857 #if 0
858    /* Not in V3 lib, and not used anyway. */
859    GET_FUNCTION(grSetNumPendingBuffers, "grSetNumPendingBuffers");
860 #endif
861    GET_FUNCTION(grSelectContext, "grSelectContext");
862    GET_FUNCTION(grSstOrigin, "grSstOrigin");
863    GET_FUNCTION(grSstSelect, "grSstSelect");
864    GET_FUNCTION(grAlphaBlendFunction, "grAlphaBlendFunction");
865    GET_FUNCTION(grAlphaCombine, "grAlphaCombine");
866    GET_FUNCTION(grAlphaControlsITRGBLighting, "grAlphaControlsITRGBLighting");
867    GET_FUNCTION(grAlphaTestFunction, "grAlphaTestFunction");
868    GET_FUNCTION(grAlphaTestReferenceValue, "grAlphaTestReferenceValue");
869    GET_FUNCTION(grChromakeyMode, "grChromakeyMode");
870    GET_FUNCTION(grChromakeyValue, "grChromakeyValue");
871    GET_FUNCTION(grClipWindow, "grClipWindow");
872    GET_FUNCTION(grColorCombine, "grColorCombine");
873    GET_FUNCTION(grColorMask, "grColorMask");
874    GET_FUNCTION(grCullMode, "grCullMode");
875    GET_FUNCTION(grConstantColorValue, "grConstantColorValue");
876    GET_FUNCTION(grDepthBiasLevel, "grDepthBiasLevel");
877    GET_FUNCTION(grDepthBufferFunction, "grDepthBufferFunction");
878    GET_FUNCTION(grDepthBufferMode, "grDepthBufferMode");
879    GET_FUNCTION(grDepthMask, "grDepthMask");
880    GET_FUNCTION(grDisableAllEffects, "grDisableAllEffects");
881    GET_FUNCTION(grDitherMode, "grDitherMode");
882    GET_FUNCTION(grFogColorValue, "grFogColorValue");
883    GET_FUNCTION(grFogMode, "grFogMode");
884    GET_FUNCTION(grFogTable, "grFogTable");
885    GET_FUNCTION(grLoadGammaTable, "grLoadGammaTable");
886    GET_FUNCTION(grSplash, "grSplash");
887    GET_FUNCTION(grGet, "grGet");
888    GET_FUNCTION(grGetString, "grGetString");
889    GET_FUNCTION(grQueryResolutions, "grQueryResolutions");
890    GET_FUNCTION(grReset, "grReset");
891    GET_FUNCTION(grGetProcAddress, "grGetProcAddress");
892    GET_FUNCTION(grEnable, "grEnable");
893    GET_FUNCTION(grDisable, "grDisable");
894    GET_FUNCTION(grCoordinateSpace, "grCoordinateSpace");
895    GET_FUNCTION(grDepthRange, "grDepthRange");
896    GET_FUNCTION(grStippleMode, "grStippleMode");
897    GET_FUNCTION(grStipplePattern, "grStipplePattern");
898    GET_FUNCTION(grViewport, "grViewport");
899    GET_FUNCTION(grTexCalcMemRequired, "grTexCalcMemRequired");
900    GET_FUNCTION(grTexTextureMemRequired, "grTexTextureMemRequired");
901    GET_FUNCTION(grTexMinAddress, "grTexMinAddress");
902    GET_FUNCTION(grTexMaxAddress, "grTexMaxAddress");
903    GET_FUNCTION(grTexNCCTable, "grTexNCCTable");
904    GET_FUNCTION(grTexSource, "grTexSource");
905    GET_FUNCTION(grTexClampMode, "grTexClampMode");
906    GET_FUNCTION(grTexCombine, "grTexCombine");
907    GET_FUNCTION(grTexDetailControl, "grTexDetailControl");
908    GET_FUNCTION(grTexFilterMode, "grTexFilterMode");
909    GET_FUNCTION(grTexLodBiasValue, "grTexLodBiasValue");
910    GET_FUNCTION(grTexDownloadMipMap, "grTexDownloadMipMap");
911    GET_FUNCTION(grTexDownloadMipMapLevel, "grTexDownloadMipMapLevel");
912    GET_FUNCTION(grTexDownloadMipMapLevelPartial, "grTexDownloadMipMapLevelPartial");
913    GET_FUNCTION(grTexDownloadTable, "grTexDownloadTable");
914    GET_FUNCTION(grTexDownloadTablePartial, "grTexDownloadTablePartial");
915    GET_FUNCTION(grTexMipMapMode, "grTexMipMapMode");
916    GET_FUNCTION(grTexMultibase, "grTexMultibase");
917    GET_FUNCTION(grTexMultibaseAddress, "grTexMultibaseAddress");
918    GET_FUNCTION(grLfbLock, "grLfbLock");
919    GET_FUNCTION(grLfbUnlock, "grLfbUnlock");
920    GET_FUNCTION(grLfbConstantAlpha, "grLfbConstantAlpha");
921    GET_FUNCTION(grLfbConstantDepth, "grLfbConstantDepth");
922    GET_FUNCTION(grLfbWriteColorSwizzle, "grLfbWriteColorSwizzle");
923    GET_FUNCTION(grLfbWriteColorFormat, "grLfbWriteColorFormat");
924    GET_FUNCTION(grLfbWriteRegion, "grLfbWriteRegion");
925    GET_FUNCTION(grLfbReadRegion, "grLfbReadRegion");
926    GET_FUNCTION(grGlideInit, "grGlideInit");
927    GET_FUNCTION(grGlideShutdown, "grGlideShutdown");
928    GET_FUNCTION(grGlideGetState, "grGlideGetState");
929    GET_FUNCTION(grGlideSetState, "grGlideSetState");
930    GET_FUNCTION(grGlideGetVertexLayout, "grGlideGetVertexLayout");
931    GET_FUNCTION(grGlideSetVertexLayout, "grGlideSetVertexLayout");
932
933    /* Glide utility functions */
934    GET_FUNCTION(guFogGenerateExp, "guFogGenerateExp");
935    GET_FUNCTION(guFogGenerateExp2, "guFogGenerateExp2");
936    GET_FUNCTION(guFogGenerateLinear, "guFogGenerateLinear");
937
938    /* DRI functions */
939    GET_FUNCTION(grDRIOpen, "grDRIOpen");
940    GET_FUNCTION(grDRIPosition, "grDRIPosition");
941    /*GET_FUNCTION(grDRILostContext, "grDRILostContext");*/
942    GET_FUNCTION(grDRIImportFifo, "grDRIImportFifo");
943    GET_FUNCTION(grDRIInvalidateAll, "grDRIInvalidateAll");
944    GET_FUNCTION(grDRIResetSAREA, "grDRIResetSAREA");
945    GET_FUNCTION(grDRIBufferSwap, "grDRIBufferSwap");
946
947    /*
948     * Extension functions:
949     * Just use dlysm() because we want a NULL pointer if the function is
950     * not found.
951     */
952    /* PIXEXT extension */
953    tmesa->Glide.grStencilFunc = dlsym(libHandle, "grStencilFunc");
954    tmesa->Glide.grStencilMask = dlsym(libHandle, "grStencilMask");
955    tmesa->Glide.grStencilOp = dlsym(libHandle, "grStencilOp");
956    tmesa->Glide.grBufferClearExt = dlsym(libHandle, "grBufferClearExt");
957    tmesa->Glide.grColorMaskExt = dlsym(libHandle, "grColorMaskExt");
958    /* COMBINE extension */
959    tmesa->Glide.grColorCombineExt = dlsym(libHandle, "grColorCombineExt");
960    tmesa->Glide.grTexColorCombineExt = dlsym(libHandle, "grTexColorCombineExt");
961    tmesa->Glide.grAlphaCombineExt = dlsym(libHandle, "grAlphaCombineExt");
962    tmesa->Glide.grTexAlphaCombineExt = dlsym(libHandle, "grTexAlphaCombineExt");
963    tmesa->Glide.grAlphaBlendFunctionExt = dlsym(libHandle, "grAlphaBlendFunctionExt");
964    tmesa->Glide.grConstantColorValueExt = dlsym(libHandle, "grConstantColorValueExt");
965    /* Texus 2 */
966    tmesa->Glide.txImgQuantize = dlsym(libHandle, "txImgQuantize");
967    tmesa->Glide.txImgDequantizeFXT1 = dlsym(libHandle, "_txImgDequantizeFXT1");
968    tmesa->Glide.txErrorSetCallback = dlsym(libHandle, "txErrorSetCallback");
969    
970 #ifdef DEBUG_TRAP
971    /* wrap the drawing functions so we can trap them */
972    real_grDrawTriangle = tmesa->Glide.grDrawTriangle;
973    tmesa->Glide.grDrawTriangle = debug_grDrawTriangle;
974
975    real_grDrawPoint = tmesa->Glide.grDrawPoint;
976    tmesa->Glide.grDrawPoint = debug_grDrawPoint;
977
978    real_grDrawVertexArray = tmesa->Glide.grDrawVertexArray;
979    tmesa->Glide.grDrawVertexArray = debug_grDrawVertexArray;
980
981    real_grDrawVertexArrayContiguous = tmesa->Glide.grDrawVertexArrayContiguous;
982    tmesa->Glide.grDrawVertexArrayContiguous = debug_grDrawVertexArrayContiguous;
983
984    real_grClipWindow = tmesa->Glide.grClipWindow;
985    tmesa->Glide.grClipWindow = debug_grClipWindow;
986
987    real_grVertexLayout = tmesa->Glide.grVertexLayout;
988    tmesa->Glide.grVertexLayout = debug_grVertexLayout;
989
990    real_grGlideGetVertexLayout = tmesa->Glide.grGlideGetVertexLayout;
991    tmesa->Glide.grGlideGetVertexLayout = debug_grGlideGetVertexLayout;
992
993    real_grGlideSetVertexLayout = tmesa->Glide.grGlideSetVertexLayout;
994    tmesa->Glide.grGlideSetVertexLayout = debug_grGlideSetVertexLayout;
995
996    real_grTexDownloadMipMapLevel = tmesa->Glide.grTexDownloadMipMapLevel;
997    tmesa->Glide.grTexDownloadMipMapLevel = debug_grTexDownloadMipMapLevel;
998
999 #endif
1000    return GL_TRUE;
1001 }