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