r200_context.c revision 8aa209c766b79144db499063dd1c8482562b07bf
1/*
2Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3
4The Weather Channel (TM) funded Tungsten Graphics to develop the
5initial release of the Radeon 8500 driver under the XFree86 license.
6This notice must be preserved.
7
8Permission is hereby granted, free of charge, to any person obtaining
9a copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sublicense, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial
18portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/*
31 * Authors:
32 *   Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35#include "main/glheader.h"
36#include "main/api_arrayelt.h"
37#include "main/context.h"
38#include "main/simple_list.h"
39#include "main/imports.h"
40#include "main/matrix.h"
41#include "main/extensions.h"
42#include "main/framebuffer.h"
43#include "main/state.h"
44
45#include "swrast/swrast.h"
46#include "swrast_setup/swrast_setup.h"
47#include "vbo/vbo.h"
48
49#include "tnl/tnl.h"
50#include "tnl/t_pipeline.h"
51
52#include "drivers/common/driverfuncs.h"
53
54#include "r200_context.h"
55#include "r200_ioctl.h"
56#include "r200_state.h"
57#include "r200_span.h"
58#include "r200_pixel.h"
59#include "r200_tex.h"
60#include "r200_swtcl.h"
61#include "r200_tcl.h"
62#include "r200_maos.h"
63#include "r200_vertprog.h"
64
65#define need_GL_ARB_vertex_program
66#define need_GL_ATI_fragment_shader
67#define need_GL_EXT_blend_minmax
68#define need_GL_EXT_fog_coord
69#define need_GL_EXT_secondary_color
70#define need_GL_EXT_blend_equation_separate
71#define need_GL_EXT_blend_func_separate
72#define need_GL_NV_vertex_program
73#define need_GL_ARB_point_parameters
74#include "extension_helper.h"
75
76#define DRIVER_DATE	"20060602"
77
78#include "vblank.h"
79#include "utils.h"
80#include "xmlpool.h" /* for symbolic values of enum-type options */
81#ifndef R200_DEBUG
82int R200_DEBUG = (0);
83#endif
84
85/* Return various strings for glGetString().
86 */
87static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
88{
89   r200ContextPtr rmesa = R200_CONTEXT(ctx);
90   static char buffer[128];
91   unsigned   offset;
92   GLuint agp_mode = (rmesa->r200Screen->card_type == RADEON_CARD_PCI)? 0 :
93      rmesa->r200Screen->AGPMode;
94
95   switch ( name ) {
96   case GL_VENDOR:
97      return (GLubyte *)"Tungsten Graphics, Inc.";
98
99   case GL_RENDERER:
100      offset = driGetRendererString( buffer, "R200", DRIVER_DATE,
101				     agp_mode );
102
103      sprintf( & buffer[ offset ], " %sTCL",
104	       !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
105	       ? "" : "NO-" );
106
107      return (GLubyte *)buffer;
108
109   default:
110      return NULL;
111   }
112}
113
114
115/* Extension strings exported by the R200 driver.
116 */
117const struct dri_extension card_extensions[] =
118{
119    { "GL_ARB_multitexture",               NULL },
120    { "GL_ARB_texture_border_clamp",       NULL },
121    { "GL_ARB_texture_env_add",            NULL },
122    { "GL_ARB_texture_env_combine",        NULL },
123    { "GL_ARB_texture_env_dot3",           NULL },
124    { "GL_ARB_texture_env_crossbar",       NULL },
125    { "GL_ARB_texture_mirrored_repeat",    NULL },
126    { "GL_EXT_blend_minmax",               GL_EXT_blend_minmax_functions },
127    { "GL_EXT_blend_subtract",             NULL },
128    { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
129    { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
130    { "GL_EXT_stencil_wrap",               NULL },
131    { "GL_EXT_texture_edge_clamp",         NULL },
132    { "GL_EXT_texture_env_combine",        NULL },
133    { "GL_EXT_texture_env_dot3",           NULL },
134    { "GL_EXT_texture_filter_anisotropic", NULL },
135    { "GL_EXT_texture_lod_bias",           NULL },
136    { "GL_EXT_texture_mirror_clamp",       NULL },
137    { "GL_EXT_texture_rectangle",          NULL },
138    { "GL_ATI_texture_env_combine3",       NULL },
139    { "GL_ATI_texture_mirror_once",        NULL },
140    { "GL_MESA_pack_invert",               NULL },
141    { "GL_NV_blend_square",                NULL },
142    { "GL_SGIS_generate_mipmap",           NULL },
143    { NULL,                                NULL }
144};
145
146const struct dri_extension blend_extensions[] = {
147    { "GL_EXT_blend_equation_separate",    GL_EXT_blend_equation_separate_functions },
148    { "GL_EXT_blend_func_separate",        GL_EXT_blend_func_separate_functions },
149    { NULL,                                NULL }
150};
151
152const struct dri_extension ARB_vp_extension[] = {
153    { "GL_ARB_vertex_program",             GL_ARB_vertex_program_functions }
154};
155
156const struct dri_extension NV_vp_extension[] = {
157    { "GL_NV_vertex_program",              GL_NV_vertex_program_functions }
158};
159
160const struct dri_extension ATI_fs_extension[] = {
161    { "GL_ATI_fragment_shader",            GL_ATI_fragment_shader_functions }
162};
163
164const struct dri_extension point_extensions[] = {
165    { "GL_ARB_point_sprite",               NULL },
166    { "GL_ARB_point_parameters",           GL_ARB_point_parameters_functions },
167    { NULL,                                NULL }
168};
169
170extern const struct tnl_pipeline_stage _r200_render_stage;
171extern const struct tnl_pipeline_stage _r200_tcl_stage;
172
173static const struct tnl_pipeline_stage *r200_pipeline[] = {
174
175   /* Try and go straight to t&l
176    */
177   &_r200_tcl_stage,
178
179   /* Catch any t&l fallbacks
180    */
181   &_tnl_vertex_transform_stage,
182   &_tnl_normal_transform_stage,
183   &_tnl_lighting_stage,
184   &_tnl_fog_coordinate_stage,
185   &_tnl_texgen_stage,
186   &_tnl_texture_transform_stage,
187   &_tnl_point_attenuation_stage,
188   &_tnl_vertex_program_stage,
189   /* Try again to go to tcl?
190    *     - no good for asymmetric-twoside (do with multipass)
191    *     - no good for asymmetric-unfilled (do with multipass)
192    *     - good for material
193    *     - good for texgen
194    *     - need to manipulate a bit of state
195    *
196    * - worth it/not worth it?
197    */
198
199   /* Else do them here.
200    */
201/*    &_r200_render_stage,  */ /* FIXME: bugs with ut2003 */
202   &_tnl_render_stage,		/* FALLBACK:  */
203   NULL,
204};
205
206
207
208/* Initialize the driver's misc functions.
209 */
210static void r200InitDriverFuncs( struct dd_function_table *functions )
211{
212    functions->GetBufferSize		= NULL; /* OBSOLETE */
213    functions->GetString		= r200GetString;
214}
215
216static const struct dri_debug_control debug_control[] =
217{
218    { "fall",  DEBUG_FALLBACKS },
219    { "tex",   DEBUG_TEXTURE },
220    { "ioctl", DEBUG_IOCTL },
221    { "prim",  DEBUG_PRIMS },
222    { "vert",  DEBUG_VERTS },
223    { "state", DEBUG_STATE },
224    { "code",  DEBUG_CODEGEN },
225    { "vfmt",  DEBUG_VFMT },
226    { "vtxf",  DEBUG_VFMT },
227    { "verb",  DEBUG_VERBOSE },
228    { "dri",   DEBUG_DRI },
229    { "dma",   DEBUG_DMA },
230    { "san",   DEBUG_SANITY },
231    { "sync",  DEBUG_SYNC },
232    { "pix",   DEBUG_PIXEL },
233    { "mem",   DEBUG_MEMORY },
234    { NULL,    0 }
235};
236
237
238/* Create the device specific rendering context.
239 */
240GLboolean r200CreateContext( const __GLcontextModes *glVisual,
241			     __DRIcontextPrivate *driContextPriv,
242			     void *sharedContextPrivate)
243{
244   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
245   radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private);
246   struct dd_function_table functions;
247   r200ContextPtr rmesa;
248   GLcontext *ctx, *shareCtx;
249   int i;
250   int tcl_mode, fthrottle_mode;
251
252   assert(glVisual);
253   assert(driContextPriv);
254   assert(screen);
255
256   /* Allocate the R200 context */
257   rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
258   if ( !rmesa )
259      return GL_FALSE;
260
261   /* init exp fog table data */
262   r200InitStaticFogData();
263
264   /* Parse configuration files.
265    * Do this here so that initialMaxAnisotropy is set before we create
266    * the default textures.
267    */
268   driParseConfigFiles (&rmesa->optionCache, &screen->optionCache,
269			screen->driScreen->myNum, "r200");
270   rmesa->initialMaxAnisotropy = driQueryOptionf(&rmesa->optionCache,
271                                                 "def_max_anisotropy");
272
273   if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) {
274      if ( sPriv->drm_version.minor < 13 )
275	 fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
276			  "disabling.\n", sPriv->drm_version.minor );
277      else
278	 rmesa->using_hyperz = GL_TRUE;
279   }
280
281   if ( sPriv->drm_version.minor >= 15 )
282      rmesa->texmicrotile = GL_TRUE;
283
284   /* Init default driver functions then plug in our R200-specific functions
285    * (the texture functions are especially important)
286    */
287   _mesa_init_driver_functions(&functions);
288   r200InitDriverFuncs(&functions);
289   r200InitIoctlFuncs(&functions);
290   r200InitStateFuncs(&functions);
291   r200InitTextureFuncs(&functions);
292   r200InitShaderFuncs(&functions);
293
294   /* Allocate and initialize the Mesa context */
295   if (sharedContextPrivate)
296      shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx;
297   else
298      shareCtx = NULL;
299   rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
300                                       &functions, (void *) rmesa);
301   if (!rmesa->glCtx) {
302      FREE(rmesa);
303      return GL_FALSE;
304   }
305   driContextPriv->driverPrivate = rmesa;
306
307   /* Init r200 context data */
308   rmesa->dri.context = driContextPriv;
309   rmesa->dri.screen = sPriv;
310   rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
311   rmesa->dri.hwContext = driContextPriv->hHWContext;
312   rmesa->dri.hwLock = &sPriv->pSAREA->lock;
313   rmesa->dri.fd = sPriv->fd;
314   rmesa->dri.drmMinor = sPriv->drm_version.minor;
315
316   rmesa->r200Screen = screen;
317   rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
318				       screen->sarea_priv_offset);
319
320
321   rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address;
322
323   (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
324   make_empty_list( & rmesa->swapped );
325
326   rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ;
327   assert(rmesa->nr_heaps < RADEON_NR_TEX_HEAPS);
328   for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
329      rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
330	    screen->texSize[i],
331	    12,
332	    RADEON_NR_TEX_REGIONS,
333	    (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
334	    & rmesa->sarea->tex_age[i],
335	    & rmesa->swapped,
336	    sizeof( r200TexObj ),
337	    (destroy_texture_object_t *) r200DestroyTexObj );
338   }
339   rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
340					   "texture_depth");
341   if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
342      rmesa->texture_depth = ( screen->cpp == 4 ) ?
343	 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
344
345   rmesa->swtcl.RenderIndex = ~0;
346   rmesa->hw.all_dirty = 1;
347
348   /* Set the maximum texture size small enough that we can guarentee that
349    * all texture units can bind a maximal texture and have all of them in
350    * texturable memory at once. Depending on the allow_large_textures driconf
351    * setting allow larger textures.
352    */
353
354   ctx = rmesa->glCtx;
355   ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->optionCache,
356						 "texture_units");
357   ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
358   ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
359
360   i = driQueryOptioni( &rmesa->optionCache, "allow_large_textures");
361
362   driCalculateMaxTextureLevels( rmesa->texture_heaps,
363				 rmesa->nr_heaps,
364				 & ctx->Const,
365				 4,
366				 11, /* max 2D texture size is 2048x2048 */
367#if ENABLE_HW_3D_TEXTURE
368				 8,  /* max 3D texture size is 256^3 */
369#else
370				 0,  /* 3D textures unsupported */
371#endif
372				 11, /* max cube texture size is 2048x2048 */
373				 11, /* max texture rectangle size is 2048x2048 */
374				 12,
375				 GL_FALSE,
376				 i );
377
378   ctx->Const.MaxTextureMaxAnisotropy = 16.0;
379
380   /* No wide AA points.
381    */
382   ctx->Const.MinPointSize = 1.0;
383   ctx->Const.MinPointSizeAA = 1.0;
384   ctx->Const.MaxPointSizeAA = 1.0;
385   ctx->Const.PointSizeGranularity = 0.0625;
386   if (rmesa->r200Screen->drmSupportsPointSprites)
387      ctx->Const.MaxPointSize = 2047.0;
388   else
389      ctx->Const.MaxPointSize = 1.0;
390
391   /* mesa initialization problem - _mesa_init_point was already called */
392   ctx->Point.MaxSize = ctx->Const.MaxPointSize;
393
394   ctx->Const.MinLineWidth = 1.0;
395   ctx->Const.MinLineWidthAA = 1.0;
396   ctx->Const.MaxLineWidth = 10.0;
397   ctx->Const.MaxLineWidthAA = 10.0;
398   ctx->Const.LineWidthGranularity = 0.0625;
399
400   ctx->Const.VertexProgram.MaxNativeInstructions = R200_VSF_MAX_INST;
401   ctx->Const.VertexProgram.MaxNativeAttribs = 12;
402   ctx->Const.VertexProgram.MaxNativeTemps = R200_VSF_MAX_TEMPS;
403   ctx->Const.VertexProgram.MaxNativeParameters = R200_VSF_MAX_PARAM;
404   ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
405
406   ctx->Const.MaxDrawBuffers = 1;
407
408   /* Initialize the software rasterizer and helper modules.
409    */
410   _swrast_CreateContext( ctx );
411   _vbo_CreateContext( ctx );
412   _tnl_CreateContext( ctx );
413   _swsetup_CreateContext( ctx );
414   _ae_create_context( ctx );
415
416   /* Install the customized pipeline:
417    */
418   _tnl_destroy_pipeline( ctx );
419   _tnl_install_pipeline( ctx, r200_pipeline );
420
421   /* Try and keep materials and vertices separate:
422    */
423/*    _tnl_isolate_materials( ctx, GL_TRUE ); */
424
425
426   /* Configure swrast and TNL to match hardware characteristics:
427    */
428   _swrast_allow_pixel_fog( ctx, GL_FALSE );
429   _swrast_allow_vertex_fog( ctx, GL_TRUE );
430   _tnl_allow_pixel_fog( ctx, GL_FALSE );
431   _tnl_allow_vertex_fog( ctx, GL_TRUE );
432
433
434   for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
435      _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
436      _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
437   }
438   _math_matrix_ctr( &rmesa->tmpmat );
439   _math_matrix_set_identity( &rmesa->tmpmat );
440
441   driInitExtensions( ctx, card_extensions, GL_TRUE );
442   if (!(rmesa->r200Screen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) {
443     /* yuv textures don't work with some chips - R200 / rv280 okay so far
444	others get the bit ordering right but don't actually do YUV-RGB conversion */
445      _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
446   }
447   if (rmesa->glCtx->Mesa_DXTn) {
448      _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
449      _mesa_enable_extension( ctx, "GL_S3_s3tc" );
450   }
451   else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) {
452      _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
453   }
454
455   if (rmesa->r200Screen->drmSupportsCubeMapsR200)
456      _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
457   if (rmesa->r200Screen->drmSupportsBlendColor) {
458       driInitExtensions( ctx, blend_extensions, GL_FALSE );
459   }
460   if(rmesa->r200Screen->drmSupportsVertexProgram)
461      driInitSingleExtension( ctx, ARB_vp_extension );
462   if(driQueryOptionb(&rmesa->optionCache, "nv_vertex_program"))
463      driInitSingleExtension( ctx, NV_vp_extension );
464
465   if ((ctx->Const.MaxTextureUnits == 6) && rmesa->r200Screen->drmSupportsFragShader)
466      driInitSingleExtension( ctx, ATI_fs_extension );
467   if (rmesa->r200Screen->drmSupportsPointSprites)
468      driInitExtensions( ctx, point_extensions, GL_FALSE );
469#if 0
470   r200InitDriverFuncs( ctx );
471   r200InitIoctlFuncs( ctx );
472   r200InitStateFuncs( ctx );
473   r200InitTextureFuncs( ctx );
474#endif
475   /* plug in a few more device driver functions */
476   /* XXX these should really go right after _mesa_init_driver_functions() */
477   r200InitPixelFuncs( ctx );
478   r200InitSpanFuncs( ctx );
479   r200InitTnlFuncs( ctx );
480   r200InitState( rmesa );
481   r200InitSwtcl( ctx );
482
483   fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode");
484   rmesa->iw.irq_seq = -1;
485   rmesa->irqsEmitted = 0;
486   rmesa->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
487		     rmesa->r200Screen->irq);
488
489   rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
490
491   if (!rmesa->do_irqs)
492      fprintf(stderr,
493	      "IRQ's not enabled, falling back to %s: %d %d\n",
494	      rmesa->do_usleeps ? "usleeps" : "busy waits",
495	      fthrottle_mode,
496	      rmesa->r200Screen->irq);
497
498   rmesa->prefer_gart_client_texturing =
499      (getenv("R200_GART_CLIENT_TEXTURES") != 0);
500
501   (*sPriv->systemTime->getUST)( & rmesa->swap_ust );
502
503
504#if DO_DEBUG
505   R200_DEBUG  = driParseDebugString( getenv( "R200_DEBUG" ),
506				      debug_control );
507   R200_DEBUG |= driParseDebugString( getenv( "RADEON_DEBUG" ),
508				      debug_control );
509#endif
510
511   tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
512   if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
513      fprintf(stderr, "disabling 3D acceleration\n");
514      FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
515   }
516   else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
517	    !(rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL)) {
518      if (rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL) {
519	 rmesa->r200Screen->chip_flags &= ~RADEON_CHIPSET_TCL;
520	 fprintf(stderr, "Disabling HW TCL support\n");
521      }
522      TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
523   }
524
525   return GL_TRUE;
526}
527
528
529/* Destroy the device specific context.
530 */
531/* Destroy the Mesa and driver specific context data.
532 */
533void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
534{
535   GET_CURRENT_CONTEXT(ctx);
536   r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
537   r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL;
538
539   /* check if we're deleting the currently bound context */
540   if (rmesa == current) {
541      R200_FIREVERTICES( rmesa );
542      _mesa_make_current(NULL, NULL, NULL);
543   }
544
545   /* Free r200 context resources */
546   assert(rmesa); /* should never be null */
547   if ( rmesa ) {
548      GLboolean   release_texture_heaps;
549
550
551      release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
552      _swsetup_DestroyContext( rmesa->glCtx );
553      _tnl_DestroyContext( rmesa->glCtx );
554      _vbo_DestroyContext( rmesa->glCtx );
555      _swrast_DestroyContext( rmesa->glCtx );
556
557      r200DestroySwtcl( rmesa->glCtx );
558      r200ReleaseArrays( rmesa->glCtx, ~0 );
559
560      if (rmesa->dma.current.buf) {
561	 r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
562	 r200FlushCmdBuf( rmesa, __FUNCTION__ );
563      }
564
565      if (rmesa->state.scissor.pClipRects) {
566	 FREE(rmesa->state.scissor.pClipRects);
567	 rmesa->state.scissor.pClipRects = NULL;
568      }
569
570      if ( release_texture_heaps ) {
571         /* This share group is about to go away, free our private
572          * texture object data.
573          */
574         int i;
575
576         for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
577	    driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
578	    rmesa->texture_heaps[ i ] = NULL;
579         }
580
581	 assert( is_empty_list( & rmesa->swapped ) );
582      }
583
584      /* free the Mesa context */
585      rmesa->glCtx->DriverCtx = NULL;
586      _mesa_destroy_context( rmesa->glCtx );
587
588      /* free the option cache */
589      driDestroyOptionCache (&rmesa->optionCache);
590
591      FREE( rmesa );
592   }
593}
594
595
596
597
598void
599r200SwapBuffers( __DRIdrawablePrivate *dPriv )
600{
601   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
602      r200ContextPtr rmesa;
603      GLcontext *ctx;
604      rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
605      ctx = rmesa->glCtx;
606      if (ctx->Visual.doubleBufferMode) {
607         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
608         if ( rmesa->doPageFlip ) {
609            r200PageFlip( dPriv );
610         }
611         else {
612	     r200CopyBuffer( dPriv, NULL );
613         }
614      }
615   }
616   else {
617      /* XXX this shouldn't be an error but we can't handle it for now */
618      _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
619   }
620}
621
622void
623r200CopySubBuffer( __DRIdrawablePrivate *dPriv,
624		   int x, int y, int w, int h )
625{
626   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
627      r200ContextPtr rmesa;
628      GLcontext *ctx;
629      rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
630      ctx = rmesa->glCtx;
631      if (ctx->Visual.doubleBufferMode) {
632	 drm_clip_rect_t rect;
633	 rect.x1 = x + dPriv->x;
634	 rect.y1 = (dPriv->h - y - h) + dPriv->y;
635	 rect.x2 = rect.x1 + w;
636	 rect.y2 = rect.y1 + h;
637         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
638	 r200CopyBuffer( dPriv, &rect );
639      }
640   }
641   else {
642      /* XXX this shouldn't be an error but we can't handle it for now */
643      _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
644   }
645}
646
647/* Force the context `c' to be the current context and associate with it
648 * buffer `b'.
649 */
650GLboolean
651r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
652                   __DRIdrawablePrivate *driDrawPriv,
653                   __DRIdrawablePrivate *driReadPriv )
654{
655   if ( driContextPriv ) {
656      r200ContextPtr newCtx =
657	 (r200ContextPtr) driContextPriv->driverPrivate;
658
659      if (R200_DEBUG & DEBUG_DRI)
660	 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
661
662      newCtx->dri.readable = driReadPriv;
663
664      if ( newCtx->dri.drawable != driDrawPriv ||
665           newCtx->lastStamp != driDrawPriv->lastStamp ) {
666	 if (driDrawPriv->swap_interval == (unsigned)-1) {
667	    driDrawPriv->vblFlags = (newCtx->r200Screen->irq != 0)
668	       ? driGetDefaultVBlankFlags(&newCtx->optionCache)
669	       : VBLANK_FLAG_NO_IRQ;
670
671	    driDrawableInitVBlank( driDrawPriv );
672	 }
673
674	 newCtx->dri.drawable = driDrawPriv;
675
676	 r200SetCliprects(newCtx);
677	 r200UpdateViewportOffset( newCtx->glCtx );
678      }
679
680      _mesa_make_current( newCtx->glCtx,
681			  (GLframebuffer *) driDrawPriv->driverPrivate,
682			  (GLframebuffer *) driReadPriv->driverPrivate );
683
684      _mesa_update_state( newCtx->glCtx );
685      r200ValidateState( newCtx->glCtx );
686
687   } else {
688      if (R200_DEBUG & DEBUG_DRI)
689	 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
690      _mesa_make_current( NULL, NULL, NULL );
691   }
692
693   if (R200_DEBUG & DEBUG_DRI)
694      fprintf(stderr, "End %s\n", __FUNCTION__);
695   return GL_TRUE;
696}
697
698/* Force the context `c' to be unbound from its buffer.
699 */
700GLboolean
701r200UnbindContext( __DRIcontextPrivate *driContextPriv )
702{
703   r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
704
705   if (R200_DEBUG & DEBUG_DRI)
706      fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx);
707
708   return GL_TRUE;
709}
710