Major check-in of changes for GL_EXT_framebuffer_object extension.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_screen.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.7 2003/03/26 20:43:51 tsi Exp $ */
2 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
6
7 All Rights Reserved.
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 * \file radeon_screen.c
33 * Screen initialization functions for the Radeon driver.
34 *
35 * \author Kevin E. Martin <martin@valinux.com>
36 * \author Gareth Hughes <gareth@valinux.com>
37 */
38
39 #include "glheader.h"
40 #include "imports.h"
41 #include "mtypes.h"
42 #include "framebuffer.h"
43 #include "renderbuffer.h"
44
45 #define STANDALONE_MMIO
46 #include "radeon_context.h"
47 #include "radeon_screen.h"
48 #include "radeon_macros.h"
49 #include "radeon_span.h"
50
51 #include "utils.h"
52 #include "context.h"
53 #include "vblank.h"
54 #include "drirenderbuffer.h"
55
56 #include "GL/internal/dri_interface.h"
57
58 /* Radeon configuration
59 */
60 #include "xmlpool.h"
61
62 PUBLIC const char __driConfigOptions[] =
63 DRI_CONF_BEGIN
64 DRI_CONF_SECTION_PERFORMANCE
65 DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
66 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
67 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
68 DRI_CONF_HYPERZ(false)
69 DRI_CONF_SECTION_END
70 DRI_CONF_SECTION_QUALITY
71 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
72 DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
73 DRI_CONF_NO_NEG_LOD_BIAS(false)
74 DRI_CONF_FORCE_S3TC_ENABLE(false)
75 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
76 DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
77 DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
78 DRI_CONF_TEXTURE_LEVEL_HACK(false)
79 DRI_CONF_SECTION_END
80 DRI_CONF_SECTION_DEBUG
81 DRI_CONF_NO_RAST(false)
82 DRI_CONF_SECTION_END
83 DRI_CONF_END;
84 static const GLuint __driNConfigOptions = 13;
85
86 #if 1
87 /* Including xf86PciInfo.h introduces a bunch of errors...
88 */
89 #define PCI_CHIP_RADEON_QD 0x5144
90 #define PCI_CHIP_RADEON_QE 0x5145
91 #define PCI_CHIP_RADEON_QF 0x5146
92 #define PCI_CHIP_RADEON_QG 0x5147
93
94 #define PCI_CHIP_RADEON_QY 0x5159
95 #define PCI_CHIP_RADEON_QZ 0x515A
96
97 #define PCI_CHIP_RN50_515E 0x515E
98 #define PCI_CHIP_RN50_5969 0x5969
99
100 #define PCI_CHIP_RADEON_LW 0x4C57 /* mobility 7 - has tcl */
101 #define PCI_CHIP_RADEON_LX 0x4C58 /* mobility FireGL 7800 m7 */
102
103 #define PCI_CHIP_RADEON_LY 0x4C59
104 #define PCI_CHIP_RADEON_LZ 0x4C5A
105
106 #define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
107 #define PCI_CHIP_RV200_QX 0x5158
108
109 /* IGP Chipsets */
110 #define PCI_CHIP_RS100_4136 0x4136
111 #define PCI_CHIP_RS200_4137 0x4137
112 #define PCI_CHIP_RS250_4237 0x4237
113 #define PCI_CHIP_RS100_4336 0x4336
114 #define PCI_CHIP_RS200_4337 0x4337
115 #define PCI_CHIP_RS250_4437 0x4437
116 #endif
117
118 #ifdef USE_NEW_INTERFACE
119 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
120 #endif /* USE_NEW_INTERFACE */
121
122 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
123
124 #ifdef USE_NEW_INTERFACE
125 static __GLcontextModes *
126 radeonFillInModes( unsigned pixel_bits, unsigned depth_bits,
127 unsigned stencil_bits, GLboolean have_back_buffer )
128 {
129 __GLcontextModes * modes;
130 __GLcontextModes * m;
131 unsigned num_modes;
132 unsigned depth_buffer_factor;
133 unsigned back_buffer_factor;
134 GLenum fb_format;
135 GLenum fb_type;
136
137 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
138 * enough to add support. Basically, if a context is created with an
139 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
140 * will never be used.
141 */
142 static const GLenum back_buffer_modes[] = {
143 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
144 };
145
146 u_int8_t depth_bits_array[2];
147 u_int8_t stencil_bits_array[2];
148
149
150 depth_bits_array[0] = depth_bits;
151 depth_bits_array[1] = depth_bits;
152
153 /* Just like with the accumulation buffer, always provide some modes
154 * with a stencil buffer. It will be a sw fallback, but some apps won't
155 * care about that.
156 */
157 stencil_bits_array[0] = 0;
158 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
159
160 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
161 back_buffer_factor = (have_back_buffer) ? 2 : 1;
162
163 num_modes = depth_buffer_factor * back_buffer_factor * 4;
164
165 if ( pixel_bits == 16 ) {
166 fb_format = GL_RGB;
167 fb_type = GL_UNSIGNED_SHORT_5_6_5;
168 }
169 else {
170 fb_format = GL_BGRA;
171 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
172 }
173
174 modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) );
175 m = modes;
176 if ( ! driFillInModes( & m, fb_format, fb_type,
177 depth_bits_array, stencil_bits_array, depth_buffer_factor,
178 back_buffer_modes, back_buffer_factor,
179 GLX_TRUE_COLOR ) ) {
180 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
181 __func__, __LINE__ );
182 return NULL;
183 }
184
185 if ( ! driFillInModes( & m, fb_format, fb_type,
186 depth_bits_array, stencil_bits_array, depth_buffer_factor,
187 back_buffer_modes, back_buffer_factor,
188 GLX_DIRECT_COLOR ) ) {
189 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
190 __func__, __LINE__ );
191 return NULL;
192 }
193
194 /* Mark the visual as slow if there are "fake" stencil bits.
195 */
196 for ( m = modes ; m != NULL ; m = m->next ) {
197 if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
198 m->visualRating = GLX_SLOW_CONFIG;
199 }
200 }
201
202 return modes;
203 }
204 #endif /* USE_NEW_INTERFACE */
205
206 /* Create the device specific screen private data struct.
207 */
208 radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
209 {
210 radeonScreenPtr screen;
211 RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
212 unsigned char *RADEONMMIO;
213
214
215 /* Allocate the private area */
216 screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
217 if ( !screen ) {
218 __driUtilMessage("%s: Could not allocate memory for screen structure",
219 __FUNCTION__);
220 return NULL;
221 }
222
223 /* parse information in __driConfigOptions */
224 driParseOptionInfo (&screen->optionCache,
225 __driConfigOptions, __driNConfigOptions);
226
227 /* This is first since which regions we map depends on whether or
228 * not we are using a PCI card.
229 */
230 screen->IsPCI = dri_priv->IsPCI;
231
232 {
233 int ret;
234 drm_radeon_getparam_t gp;
235
236 gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
237 gp.value = &screen->gart_buffer_offset;
238
239 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
240 &gp, sizeof(gp));
241 if (ret) {
242 FREE( screen );
243 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
244 return NULL;
245 }
246
247 if (sPriv->drmMinor >= 6) {
248 gp.param = RADEON_PARAM_IRQ_NR;
249 gp.value = &screen->irq;
250
251 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
252 &gp, sizeof(gp));
253 if (ret) {
254 FREE( screen );
255 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
256 return NULL;
257 }
258 }
259 }
260
261 screen->mmio.handle = dri_priv->registerHandle;
262 screen->mmio.size = dri_priv->registerSize;
263 if ( drmMap( sPriv->fd,
264 screen->mmio.handle,
265 screen->mmio.size,
266 &screen->mmio.map ) ) {
267 FREE( screen );
268 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
269 return NULL;
270 }
271
272 RADEONMMIO = screen->mmio.map;
273
274 screen->status.handle = dri_priv->statusHandle;
275 screen->status.size = dri_priv->statusSize;
276 if ( drmMap( sPriv->fd,
277 screen->status.handle,
278 screen->status.size,
279 &screen->status.map ) ) {
280 drmUnmap( screen->mmio.map, screen->mmio.size );
281 FREE( screen );
282 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
283 return NULL;
284 }
285 screen->scratch = (__volatile__ u_int32_t *)
286 ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
287
288 screen->buffers = drmMapBufs( sPriv->fd );
289 if ( !screen->buffers ) {
290 drmUnmap( screen->status.map, screen->status.size );
291 drmUnmap( screen->mmio.map, screen->mmio.size );
292 FREE( screen );
293 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
294 return NULL;
295 }
296
297 if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
298 screen->gartTextures.handle = dri_priv->gartTexHandle;
299 screen->gartTextures.size = dri_priv->gartTexMapSize;
300 if ( drmMap( sPriv->fd,
301 screen->gartTextures.handle,
302 screen->gartTextures.size,
303 (drmAddressPtr)&screen->gartTextures.map ) ) {
304 drmUnmapBufs( screen->buffers );
305 drmUnmap( screen->status.map, screen->status.size );
306 drmUnmap( screen->mmio.map, screen->mmio.size );
307 FREE( screen );
308 __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
309 return NULL;
310 }
311
312 screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
313 ? INREG( RADEON_AIC_LO_ADDR )
314 : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
315 }
316
317 screen->chipset = 0;
318 switch ( dri_priv->deviceID ) {
319 default:
320 fprintf(stderr, "unknown chip id, assuming full radeon support\n");
321 case PCI_CHIP_RADEON_QD:
322 case PCI_CHIP_RADEON_QE:
323 case PCI_CHIP_RADEON_QF:
324 case PCI_CHIP_RADEON_QG:
325 /* all original radeons (7200) presumably have a stencil op bug */
326 screen->chipset |= RADEON_CHIPSET_BROKEN_STENCIL;
327 case PCI_CHIP_RV200_QW:
328 case PCI_CHIP_RV200_QX:
329 case PCI_CHIP_RADEON_LW:
330 case PCI_CHIP_RADEON_LX:
331 screen->chipset |= RADEON_CHIPSET_TCL;
332 case PCI_CHIP_RADEON_QY:
333 case PCI_CHIP_RADEON_QZ:
334 case PCI_CHIP_RN50_515E:
335 case PCI_CHIP_RN50_5969:
336 case PCI_CHIP_RADEON_LY:
337 case PCI_CHIP_RADEON_LZ:
338 case PCI_CHIP_RS100_4136: /* IGPs don't have TCL */
339 case PCI_CHIP_RS200_4137:
340 case PCI_CHIP_RS250_4237:
341 case PCI_CHIP_RS100_4336:
342 case PCI_CHIP_RS200_4337:
343 case PCI_CHIP_RS250_4437:
344 break;
345 }
346
347 screen->cpp = dri_priv->bpp / 8;
348 screen->AGPMode = dri_priv->AGPMode;
349
350 screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
351
352 if ( sPriv->drmMinor >= 10 ) {
353 drm_radeon_setparam_t sp;
354
355 sp.param = RADEON_SETPARAM_FB_LOCATION;
356 sp.value = screen->fbLocation;
357
358 drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
359 &sp, sizeof( sp ) );
360 }
361
362 screen->frontOffset = dri_priv->frontOffset;
363 screen->frontPitch = dri_priv->frontPitch;
364 screen->backOffset = dri_priv->backOffset;
365 screen->backPitch = dri_priv->backPitch;
366 screen->depthOffset = dri_priv->depthOffset;
367 screen->depthPitch = dri_priv->depthPitch;
368
369 /* Check if ddx has set up a surface reg to cover depth buffer */
370 screen->depthHasSurface = ((sPriv->ddxMajor > 4) &&
371 (screen->chipset & RADEON_CHIPSET_TCL));
372
373 screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
374 + screen->fbLocation;
375 screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
376 screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
377 dri_priv->log2TexGran;
378
379 if ( !screen->gartTextures.map
380 || getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) {
381 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
382 screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
383 screen->texSize[RADEON_GART_TEX_HEAP] = 0;
384 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
385 } else {
386 screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
387 screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
388 screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
389 screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
390 dri_priv->log2GARTTexGran;
391 }
392
393 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
394 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
395 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
396 void * const psc = sPriv->psc->screenConfigs;
397
398 if ( glx_enable_extension != NULL ) {
399 if ( screen->irq != 0 ) {
400 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
401 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
402 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
403 }
404
405 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
406
407 if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
408 (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
409 (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
410 }
411
412 }
413 }
414
415 screen->driScreen = sPriv;
416 screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
417 return screen;
418 }
419
420 /* Destroy the device specific screen private data struct.
421 */
422 void radeonDestroyScreen( __DRIscreenPrivate *sPriv )
423 {
424 radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
425
426 if (!screen)
427 return;
428
429 if ( screen->gartTextures.map ) {
430 drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
431 }
432 drmUnmapBufs( screen->buffers );
433 drmUnmap( screen->status.map, screen->status.size );
434 drmUnmap( screen->mmio.map, screen->mmio.size );
435
436 /* free all option information */
437 driDestroyOptionInfo (&screen->optionCache);
438
439 FREE( screen );
440 sPriv->private = NULL;
441 }
442
443
444 /* Initialize the driver specific screen private data.
445 */
446 static GLboolean
447 radeonInitDriver( __DRIscreenPrivate *sPriv )
448 {
449 sPriv->private = (void *) radeonCreateScreen( sPriv );
450 if ( !sPriv->private ) {
451 radeonDestroyScreen( sPriv );
452 return GL_FALSE;
453 }
454
455 return GL_TRUE;
456 }
457
458
459 /**
460 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
461 *
462 * \todo This function (and its interface) will need to be updated to support
463 * pbuffers.
464 */
465 static GLboolean
466 radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
467 __DRIdrawablePrivate *driDrawPriv,
468 const __GLcontextModes *mesaVis,
469 GLboolean isPixmap )
470 {
471 radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
472
473 if (isPixmap) {
474 return GL_FALSE; /* not implemented */
475 }
476 else {
477 const GLboolean swDepth = GL_FALSE;
478 const GLboolean swAlpha = GL_FALSE;
479 const GLboolean swAccum = mesaVis->accumRedBits > 0;
480 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
481 mesaVis->depthBits != 24;
482 #if 0
483 driDrawPriv->driverPrivate = (void *)
484 _mesa_create_framebuffer( mesaVis,
485 swDepth,
486 swStencil,
487 swAccum,
488 swAlpha );
489 #else
490 struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
491
492 {
493 driRenderbuffer *frontRb
494 = driNewRenderbuffer(GL_RGBA, screen->cpp,
495 screen->frontOffset, screen->frontPitch);
496 radeonSetSpanFunctions(frontRb, mesaVis);
497 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
498 }
499
500 if (mesaVis->doubleBufferMode) {
501 driRenderbuffer *backRb
502 = driNewRenderbuffer(GL_RGBA, screen->cpp,
503 screen->backOffset, screen->backPitch);
504 radeonSetSpanFunctions(backRb, mesaVis);
505 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
506 }
507
508 if (mesaVis->depthBits == 16) {
509 driRenderbuffer *depthRb
510 = driNewRenderbuffer(GL_DEPTH_COMPONENT16, screen->cpp,
511 screen->depthOffset, screen->depthPitch);
512 radeonSetSpanFunctions(depthRb, mesaVis);
513 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
514 }
515 else if (mesaVis->depthBits == 24) {
516 driRenderbuffer *depthRb
517 = driNewRenderbuffer(GL_DEPTH_COMPONENT24, screen->cpp,
518 screen->depthOffset, screen->depthPitch);
519 radeonSetSpanFunctions(depthRb, mesaVis);
520 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
521 }
522
523 if (mesaVis->stencilBits > 0 && !swStencil) {
524 driRenderbuffer *stencilRb
525 = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, screen->cpp,
526 screen->depthOffset, screen->depthPitch);
527 radeonSetSpanFunctions(stencilRb, mesaVis);
528 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
529 }
530
531 _mesa_add_soft_renderbuffers(fb,
532 GL_FALSE, /* color */
533 swDepth,
534 swStencil,
535 swAccum,
536 swAlpha,
537 GL_FALSE /* aux */);
538 driDrawPriv->driverPrivate = (void *) fb;
539 #endif
540 return (driDrawPriv->driverPrivate != NULL);
541 }
542 }
543
544
545 static void
546 radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
547 {
548 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
549 }
550
551 static struct __DriverAPIRec radeonAPI = {
552 .InitDriver = radeonInitDriver,
553 .DestroyScreen = radeonDestroyScreen,
554 .CreateContext = radeonCreateContext,
555 .DestroyContext = radeonDestroyContext,
556 .CreateBuffer = radeonCreateBuffer,
557 .DestroyBuffer = radeonDestroyBuffer,
558 .SwapBuffers = radeonSwapBuffers,
559 .MakeCurrent = radeonMakeCurrent,
560 .UnbindContext = radeonUnbindContext,
561 .GetSwapInfo = getSwapInfo,
562 .GetMSC = driGetMSC32,
563 .WaitForMSC = driWaitForMSC32,
564 .WaitForSBC = NULL,
565 .SwapBuffersMSC = NULL
566 };
567
568
569 /*
570 * This is the bootstrap function for the driver.
571 * The __driCreateScreen name is the symbol that libGL.so fetches.
572 * Return: pointer to a __DRIscreenPrivate.
573 */
574 #if !defined(DRI_NEW_INTERFACE_ONLY)
575 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
576 int numConfigs, __GLXvisualConfig *config)
577 {
578 __DRIscreenPrivate *psp;
579 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
580 return (void *) psp;
581 }
582 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
583
584 /**
585 * This is the bootstrap function for the driver. libGL supplies all of the
586 * requisite information about the system, and the driver initializes itself.
587 * This routine also fills in the linked list pointed to by \c driver_modes
588 * with the \c __GLcontextModes that the driver can support for windows or
589 * pbuffers.
590 *
591 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
592 * failure.
593 */
594 #ifdef USE_NEW_INTERFACE
595 PUBLIC
596 void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
597 const __GLcontextModes * modes,
598 const __DRIversion * ddx_version,
599 const __DRIversion * dri_version,
600 const __DRIversion * drm_version,
601 const __DRIframebuffer * frame_buffer,
602 drmAddress pSAREA, int fd,
603 int internal_api_version,
604 __GLcontextModes ** driver_modes )
605
606 {
607 __DRIscreenPrivate *psp;
608 static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
609 static const __DRIversion dri_expected = { 4, 0, 0 };
610 static const __DRIversion drm_expected = { 1, 3, 0 };
611
612 if ( ! driCheckDriDdxDrmVersions3( "Radeon",
613 dri_version, & dri_expected,
614 ddx_version, & ddx_expected,
615 drm_version, & drm_expected ) ) {
616 return NULL;
617 }
618
619 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
620 ddx_version, dri_version, drm_version,
621 frame_buffer, pSAREA, fd,
622 internal_api_version, &radeonAPI);
623 if ( psp != NULL ) {
624 create_context_modes = (PFNGLXCREATECONTEXTMODES)
625 glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
626 if ( create_context_modes != NULL ) {
627 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
628 *driver_modes = radeonFillInModes( dri_priv->bpp,
629 (dri_priv->bpp == 16) ? 16 : 24,
630 (dri_priv->bpp == 16) ? 0 : 8,
631 (dri_priv->backOffset != dri_priv->depthOffset) );
632 }
633 }
634
635 return (void *) psp;
636 }
637 #endif /* USE_NEW_INTERFACE */
638
639 /**
640 * Get information about previous buffer swaps.
641 */
642 static int
643 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
644 {
645 radeonContextPtr rmesa;
646
647 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
648 || (dPriv->driContextPriv->driverPrivate == NULL)
649 || (sInfo == NULL) ) {
650 return -1;
651 }
652
653 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
654 sInfo->swap_count = rmesa->swap_count;
655 sInfo->swap_ust = rmesa->swap_ust;
656 sInfo->swap_missed_count = rmesa->swap_missed_count;
657
658 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
659 ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
660 : 0.0;
661
662 return 0;
663 }