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