1 /**************************************************************************
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
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:
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.
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.
28 **************************************************************************/
32 * Kevin E. Martin <martin@valinux.com>
33 * Gareth Hughes <gareth@valinux.com>
34 * Keith Whitwell <keith@tungstengraphics.com>
38 #include "api_arrayelt.h"
40 #include "simple_list.h"
43 #include "extensions.h"
44 #include "framebuffer.h"
46 #include "swrast/swrast.h"
47 #include "swrast_setup/swrast_setup.h"
51 #include "tnl/t_pipeline.h"
53 #include "drivers/common/driverfuncs.h"
55 #include "radeon_context.h"
56 #include "radeon_ioctl.h"
57 #include "radeon_state.h"
58 #include "radeon_span.h"
59 #include "radeon_tex.h"
60 #include "radeon_swtcl.h"
61 #include "radeon_tcl.h"
62 #include "radeon_maos.h"
64 #define need_GL_ARB_multisample
65 #define need_GL_ARB_texture_compression
66 #define need_GL_ARB_vertex_buffer_object
67 #define need_GL_EXT_blend_minmax
68 #define need_GL_EXT_fog_coord
69 #define need_GL_EXT_secondary_color
70 #include "extension_helper.h"
72 #define DRIVER_DATE "20061018"
76 #include "xmlpool.h" /* for symbolic values of enum-type options */
78 int RADEON_DEBUG
= (0);
82 /* Return various strings for glGetString().
84 static const GLubyte
*radeonGetString( GLcontext
*ctx
, GLenum name
)
86 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
87 static char buffer
[128];
89 GLuint agp_mode
= (rmesa
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
90 rmesa
->radeonScreen
->AGPMode
;
94 return (GLubyte
*)"Tungsten Graphics, Inc.";
97 offset
= driGetRendererString( buffer
, "Radeon", DRIVER_DATE
,
100 sprintf( & buffer
[ offset
], " %sTCL",
101 !(rmesa
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
104 return (GLubyte
*)buffer
;
112 /* Extension strings exported by the R100 driver.
114 const struct dri_extension card_extensions
[] =
116 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
117 { "GL_ARB_multitexture", NULL
},
118 { "GL_ARB_texture_border_clamp", NULL
},
119 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions
},
120 { "GL_ARB_texture_env_add", NULL
},
121 { "GL_ARB_texture_env_combine", NULL
},
122 { "GL_ARB_texture_env_crossbar", NULL
},
123 { "GL_ARB_texture_env_dot3", NULL
},
124 { "GL_ARB_texture_mirrored_repeat", NULL
},
125 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions
},
126 { "GL_EXT_blend_logic_op", NULL
},
127 { "GL_EXT_blend_subtract", GL_EXT_blend_minmax_functions
},
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_ATI_texture_env_combine3", NULL
},
138 { "GL_ATI_texture_mirror_once", NULL
},
139 { "GL_MESA_ycbcr_texture", NULL
},
140 { "GL_NV_blend_square", NULL
},
141 { "GL_SGIS_generate_mipmap", NULL
},
145 extern const struct tnl_pipeline_stage _radeon_render_stage
;
146 extern const struct tnl_pipeline_stage _radeon_tcl_stage
;
148 static const struct tnl_pipeline_stage
*radeon_pipeline
[] = {
150 /* Try and go straight to t&l
154 /* Catch any t&l fallbacks
156 &_tnl_vertex_transform_stage
,
157 &_tnl_normal_transform_stage
,
158 &_tnl_lighting_stage
,
159 &_tnl_fog_coordinate_stage
,
161 &_tnl_texture_transform_stage
,
163 &_radeon_render_stage
,
164 &_tnl_render_stage
, /* FALLBACK: */
170 /* Initialize the driver's misc functions.
172 static void radeonInitDriverFuncs( struct dd_function_table
*functions
)
174 functions
->GetString
= radeonGetString
;
177 static const struct dri_debug_control debug_control
[] =
179 { "fall", DEBUG_FALLBACKS
},
180 { "tex", DEBUG_TEXTURE
},
181 { "ioctl", DEBUG_IOCTL
},
182 { "prim", DEBUG_PRIMS
},
183 { "vert", DEBUG_VERTS
},
184 { "state", DEBUG_STATE
},
185 { "code", DEBUG_CODEGEN
},
186 { "vfmt", DEBUG_VFMT
},
187 { "vtxf", DEBUG_VFMT
},
188 { "verb", DEBUG_VERBOSE
},
189 { "dri", DEBUG_DRI
},
190 { "dma", DEBUG_DMA
},
191 { "san", DEBUG_SANITY
},
192 { "sync", DEBUG_SYNC
},
197 /* Create the device specific context.
200 radeonCreateContext( const __GLcontextModes
*glVisual
,
201 __DRIcontextPrivate
*driContextPriv
,
202 void *sharedContextPrivate
)
204 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
205 radeonScreenPtr screen
= (radeonScreenPtr
)(sPriv
->private);
206 struct dd_function_table functions
;
207 radeonContextPtr rmesa
;
208 GLcontext
*ctx
, *shareCtx
;
210 int tcl_mode
, fthrottle_mode
;
213 assert(driContextPriv
);
216 /* Allocate the Radeon context */
217 rmesa
= (radeonContextPtr
) CALLOC( sizeof(*rmesa
) );
221 /* init exp fog table data */
222 radeonInitStaticFogData();
224 /* Parse configuration files.
225 * Do this here so that initialMaxAnisotropy is set before we create
226 * the default textures.
228 driParseConfigFiles (&rmesa
->optionCache
, &screen
->optionCache
,
229 screen
->driScreen
->myNum
, "radeon");
230 rmesa
->initialMaxAnisotropy
= driQueryOptionf(&rmesa
->optionCache
,
231 "def_max_anisotropy");
233 if ( driQueryOptionb( &rmesa
->optionCache
, "hyperz" ) ) {
234 if ( sPriv
->drmMinor
< 13 )
235 fprintf( stderr
, "DRM version 1.%d too old to support HyperZ, "
236 "disabling.\n",sPriv
->drmMinor
);
238 rmesa
->using_hyperz
= GL_TRUE
;
241 if ( sPriv
->drmMinor
>= 15 )
242 rmesa
->texmicrotile
= GL_TRUE
;
244 /* Init default driver functions then plug in our Radeon-specific functions
245 * (the texture functions are especially important)
247 _mesa_init_driver_functions( &functions
);
248 radeonInitDriverFuncs( &functions
);
249 radeonInitTextureFuncs( &functions
);
251 /* Allocate the Mesa context */
252 if (sharedContextPrivate
)
253 shareCtx
= ((radeonContextPtr
) sharedContextPrivate
)->glCtx
;
256 rmesa
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
257 &functions
, (void *) rmesa
);
262 driContextPriv
->driverPrivate
= rmesa
;
264 /* Init radeon context data */
265 rmesa
->dri
.context
= driContextPriv
;
266 rmesa
->dri
.screen
= sPriv
;
267 rmesa
->dri
.drawable
= NULL
;
268 rmesa
->dri
.readable
= NULL
;
269 rmesa
->dri
.hwContext
= driContextPriv
->hHWContext
;
270 rmesa
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
271 rmesa
->dri
.fd
= sPriv
->fd
;
272 rmesa
->dri
.drmMinor
= sPriv
->drmMinor
;
274 rmesa
->radeonScreen
= screen
;
275 rmesa
->sarea
= (drm_radeon_sarea_t
*)((GLubyte
*)sPriv
->pSAREA
+
276 screen
->sarea_priv_offset
);
279 rmesa
->dma
.buf0_address
= rmesa
->radeonScreen
->buffers
->list
[0].address
;
281 (void) memset( rmesa
->texture_heaps
, 0, sizeof( rmesa
->texture_heaps
) );
282 make_empty_list( & rmesa
->swapped
);
284 rmesa
->nr_heaps
= screen
->numTexHeaps
;
285 for ( i
= 0 ; i
< rmesa
->nr_heaps
; i
++ ) {
286 rmesa
->texture_heaps
[i
] = driCreateTextureHeap( i
, rmesa
,
289 RADEON_NR_TEX_REGIONS
,
290 (drmTextureRegionPtr
)rmesa
->sarea
->tex_list
[i
],
291 & rmesa
->sarea
->tex_age
[i
],
293 sizeof( radeonTexObj
),
294 (destroy_texture_object_t
*) radeonDestroyTexObj
);
296 driSetTextureSwapCounterLocation( rmesa
->texture_heaps
[i
],
297 & rmesa
->c_textureSwaps
);
299 rmesa
->texture_depth
= driQueryOptioni (&rmesa
->optionCache
,
301 if (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
302 rmesa
->texture_depth
= ( screen
->cpp
== 4 ) ?
303 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
305 rmesa
->swtcl
.RenderIndex
= ~0;
306 rmesa
->hw
.all_dirty
= GL_TRUE
;
308 /* Set the maximum texture size small enough that we can guarentee that
309 * all texture units can bind a maximal texture and have all of them in
310 * texturable memory at once. Depending on the allow_large_textures driconf
311 * setting allow larger textures.
315 ctx
->Const
.MaxTextureUnits
= driQueryOptioni (&rmesa
->optionCache
,
317 ctx
->Const
.MaxTextureImageUnits
= ctx
->Const
.MaxTextureUnits
;
318 ctx
->Const
.MaxTextureCoordUnits
= ctx
->Const
.MaxTextureUnits
;
320 i
= driQueryOptioni( &rmesa
->optionCache
, "allow_large_textures");
322 driCalculateMaxTextureLevels( rmesa
->texture_heaps
,
326 11, /* max 2D texture size is 2048x2048 */
328 9, /* \todo: max cube texture size seems to be 512x512(x6) */
329 11, /* max rect texture size is 2048x2048. */
335 ctx
->Const
.MaxTextureMaxAnisotropy
= 16.0;
339 ctx
->Const
.MinPointSize
= 1.0;
340 ctx
->Const
.MinPointSizeAA
= 1.0;
341 ctx
->Const
.MaxPointSize
= 1.0;
342 ctx
->Const
.MaxPointSizeAA
= 1.0;
344 ctx
->Const
.MinLineWidth
= 1.0;
345 ctx
->Const
.MinLineWidthAA
= 1.0;
346 ctx
->Const
.MaxLineWidth
= 10.0;
347 ctx
->Const
.MaxLineWidthAA
= 10.0;
348 ctx
->Const
.LineWidthGranularity
= 0.0625;
350 /* Set maxlocksize (and hence vb size) small enough to avoid
351 * fallbacks in radeon_tcl.c. ie. guarentee that all vertices can
352 * fit in a single dma buffer for indexed rendering of quad strips,
355 ctx
->Const
.MaxArrayLockSize
=
356 MIN2( ctx
->Const
.MaxArrayLockSize
,
357 RADEON_BUFFER_SIZE
/ RADEON_MAX_TCL_VERTSIZE
);
361 /* Initialize the software rasterizer and helper modules.
363 _swrast_CreateContext( ctx
);
364 _vbo_CreateContext( ctx
);
365 _tnl_CreateContext( ctx
);
366 _swsetup_CreateContext( ctx
);
367 _ae_create_context( ctx
);
369 /* Install the customized pipeline:
371 _tnl_destroy_pipeline( ctx
);
372 _tnl_install_pipeline( ctx
, radeon_pipeline
);
374 /* Try and keep materials and vertices separate:
376 /* _tnl_isolate_materials( ctx, GL_TRUE ); */
378 /* Configure swrast and T&L to match hardware characteristics:
380 _swrast_allow_pixel_fog( ctx
, GL_FALSE
);
381 _swrast_allow_vertex_fog( ctx
, GL_TRUE
);
382 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
383 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
386 for ( i
= 0 ; i
< RADEON_MAX_TEXTURE_UNITS
; i
++ ) {
387 _math_matrix_ctr( &rmesa
->TexGenMatrix
[i
] );
388 _math_matrix_ctr( &rmesa
->tmpmat
[i
] );
389 _math_matrix_set_identity( &rmesa
->TexGenMatrix
[i
] );
390 _math_matrix_set_identity( &rmesa
->tmpmat
[i
] );
393 driInitExtensions( ctx
, card_extensions
, GL_TRUE
);
394 if (rmesa
->radeonScreen
->drmSupportsCubeMapsR100
)
395 _mesa_enable_extension( ctx
, "GL_ARB_texture_cube_map" );
396 if (rmesa
->glCtx
->Mesa_DXTn
) {
397 _mesa_enable_extension( ctx
, "GL_EXT_texture_compression_s3tc" );
398 _mesa_enable_extension( ctx
, "GL_S3_s3tc" );
400 else if (driQueryOptionb (&rmesa
->optionCache
, "force_s3tc_enable")) {
401 _mesa_enable_extension( ctx
, "GL_EXT_texture_compression_s3tc" );
404 if (rmesa
->dri
.drmMinor
>= 9)
405 _mesa_enable_extension( ctx
, "GL_NV_texture_rectangle");
407 /* XXX these should really go right after _mesa_init_driver_functions() */
408 radeonInitIoctlFuncs( ctx
);
409 radeonInitStateFuncs( ctx
);
410 radeonInitSpanFuncs( ctx
);
411 radeonInitState( rmesa
);
412 radeonInitSwtcl( ctx
);
414 _mesa_vector4f_alloc( &rmesa
->tcl
.ObjClean
, 0,
415 ctx
->Const
.MaxArrayLockSize
, 32 );
417 fthrottle_mode
= driQueryOptioni(&rmesa
->optionCache
, "fthrottle_mode");
418 rmesa
->iw
.irq_seq
= -1;
419 rmesa
->irqsEmitted
= 0;
420 rmesa
->do_irqs
= (rmesa
->radeonScreen
->irq
!= 0 &&
421 fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
);
423 rmesa
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
425 rmesa
->vblank_flags
= (rmesa
->radeonScreen
->irq
!= 0)
426 ? driGetDefaultVBlankFlags(&rmesa
->optionCache
) : VBLANK_FLAG_NO_IRQ
;
428 (*dri_interface
->getUST
)( & rmesa
->swap_ust
);
432 RADEON_DEBUG
= driParseDebugString( getenv( "RADEON_DEBUG" ),
436 tcl_mode
= driQueryOptioni(&rmesa
->optionCache
, "tcl_mode");
437 if (driQueryOptionb(&rmesa
->optionCache
, "no_rast")) {
438 fprintf(stderr
, "disabling 3D acceleration\n");
439 FALLBACK(rmesa
, RADEON_FALLBACK_DISABLE
, 1);
440 } else if (tcl_mode
== DRI_CONF_TCL_SW
||
441 !(rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)) {
442 if (rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
443 rmesa
->radeonScreen
->chip_flags
&= ~RADEON_CHIPSET_TCL
;
444 fprintf(stderr
, "Disabling HW TCL support\n");
446 TCL_FALLBACK(rmesa
->glCtx
, RADEON_TCL_FALLBACK_TCL_DISABLE
, 1);
449 if (rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
450 /* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
456 /* Destroy the device specific context.
458 /* Destroy the Mesa and driver specific context data.
460 void radeonDestroyContext( __DRIcontextPrivate
*driContextPriv
)
462 GET_CURRENT_CONTEXT(ctx
);
463 radeonContextPtr rmesa
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
464 radeonContextPtr current
= ctx
? RADEON_CONTEXT(ctx
) : NULL
;
466 /* check if we're deleting the currently bound context */
467 if (rmesa
== current
) {
468 RADEON_FIREVERTICES( rmesa
);
469 _mesa_make_current(NULL
, NULL
, NULL
);
472 /* Free radeon context resources */
473 assert(rmesa
); /* should never be null */
475 GLboolean release_texture_heaps
;
478 release_texture_heaps
= (rmesa
->glCtx
->Shared
->RefCount
== 1);
479 _swsetup_DestroyContext( rmesa
->glCtx
);
480 _tnl_DestroyContext( rmesa
->glCtx
);
481 _vbo_DestroyContext( rmesa
->glCtx
);
482 _swrast_DestroyContext( rmesa
->glCtx
);
484 radeonDestroySwtcl( rmesa
->glCtx
);
485 radeonReleaseArrays( rmesa
->glCtx
, ~0 );
486 if (rmesa
->dma
.current
.buf
) {
487 radeonReleaseDmaRegion( rmesa
, &rmesa
->dma
.current
, __FUNCTION__
);
488 radeonFlushCmdBuf( rmesa
, __FUNCTION__
);
491 _mesa_vector4f_free( &rmesa
->tcl
.ObjClean
);
493 if (rmesa
->state
.scissor
.pClipRects
) {
494 FREE(rmesa
->state
.scissor
.pClipRects
);
495 rmesa
->state
.scissor
.pClipRects
= NULL
;
498 if ( release_texture_heaps
) {
499 /* This share group is about to go away, free our private
500 * texture object data.
504 for ( i
= 0 ; i
< rmesa
->nr_heaps
; i
++ ) {
505 driDestroyTextureHeap( rmesa
->texture_heaps
[ i
] );
506 rmesa
->texture_heaps
[ i
] = NULL
;
509 assert( is_empty_list( & rmesa
->swapped
) );
512 /* free the Mesa context */
513 rmesa
->glCtx
->DriverCtx
= NULL
;
514 _mesa_destroy_context( rmesa
->glCtx
);
516 /* free the option cache */
517 driDestroyOptionCache (&rmesa
->optionCache
);
527 radeonSwapBuffers( __DRIdrawablePrivate
*dPriv
)
530 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
531 radeonContextPtr rmesa
;
533 rmesa
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
535 if (ctx
->Visual
.doubleBufferMode
) {
536 _mesa_notifySwapBuffers( ctx
); /* flush pending rendering comands */
538 if ( rmesa
->doPageFlip
) {
539 radeonPageFlip( dPriv
);
542 radeonCopyBuffer( dPriv
, NULL
);
547 /* XXX this shouldn't be an error but we can't handle it for now */
548 _mesa_problem(NULL
, "%s: drawable has no context!", __FUNCTION__
);
552 void radeonCopySubBuffer(__DRIdrawablePrivate
* dPriv
,
553 int x
, int y
, int w
, int h
)
555 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
556 radeonContextPtr radeon
;
559 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
562 if (ctx
->Visual
.doubleBufferMode
) {
563 drm_clip_rect_t rect
;
564 rect
.x1
= x
+ dPriv
->x
;
565 rect
.y1
= (dPriv
->h
- y
- h
) + dPriv
->y
;
566 rect
.x2
= rect
.x1
+ w
;
567 rect
.y2
= rect
.y1
+ h
;
568 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
569 radeonCopyBuffer(dPriv
, &rect
);
572 /* XXX this shouldn't be an error but we can't handle it for now */
573 _mesa_problem(NULL
, "%s: drawable has no context!",
578 /* Make context `c' the current context and bind it to the given
579 * drawing and reading surfaces.
582 radeonMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
583 __DRIdrawablePrivate
*driDrawPriv
,
584 __DRIdrawablePrivate
*driReadPriv
)
586 if ( driContextPriv
) {
587 radeonContextPtr newCtx
=
588 (radeonContextPtr
) driContextPriv
->driverPrivate
;
590 if (RADEON_DEBUG
& DEBUG_DRI
)
591 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
, (void *) newCtx
->glCtx
);
593 if ( newCtx
->dri
.drawable
!= driDrawPriv
) {
594 /* XXX we may need to validate the drawable here!!! */
595 driDrawableInitVBlank( driDrawPriv
, newCtx
->vblank_flags
,
599 newCtx
->dri
.readable
= driReadPriv
;
601 if ( (newCtx
->dri
.drawable
!= driDrawPriv
) ||
602 newCtx
->lastStamp
!= driDrawPriv
->lastStamp
) {
603 newCtx
->dri
.drawable
= driDrawPriv
;
605 radeonSetCliprects(newCtx
);
606 radeonUpdateViewportOffset( newCtx
->glCtx
);
609 _mesa_make_current( newCtx
->glCtx
,
610 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
611 (GLframebuffer
*) driReadPriv
->driverPrivate
);
613 _mesa_update_state( newCtx
->glCtx
);
615 if (RADEON_DEBUG
& DEBUG_DRI
)
616 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
617 _mesa_make_current( NULL
, NULL
, NULL
);
620 if (RADEON_DEBUG
& DEBUG_DRI
)
621 fprintf(stderr
, "End %s\n", __FUNCTION__
);
625 /* Force the context `c' to be unbound from its buffer.
628 radeonUnbindContext( __DRIcontextPrivate
*driContextPriv
)
630 radeonContextPtr rmesa
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
632 if (RADEON_DEBUG
& DEBUG_DRI
)
633 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
, (void *) rmesa
->glCtx
);