855dd203bebb9e1020d5e569d02048c78ce35e73
[profile/ivi/mesa.git] / src / mesa / drivers / dri / r200 / r200_screen.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_screen.c,v 1.4 2003/05/08 09:25:35 herrb 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  * \file r200_screen.c
33  * Screen initialization functions for the R200 driver.
34  * 
35  * \author Keith Whitwell <keith@tungstengraphics.com>
36  */
37
38 #include <dlfcn.h>
39
40 #include "glheader.h"
41 #include "imports.h"
42 #include "context.h"
43
44 #define STANDALONE_MMIO
45 #include "r200_screen.h"
46 #include "r200_context.h"
47 #include "r200_ioctl.h"
48 #include "radeon_macros.h"
49 #include "radeon_reg.h"
50
51 #include "utils.h"
52 #include "vblank.h"
53 #include "GL/internal/dri_interface.h"
54
55 /* R200 configuration
56  */
57 #include "xmlpool.h"
58
59 const char __driConfigOptions[] =
60 DRI_CONF_BEGIN
61     DRI_CONF_SECTION_PERFORMANCE
62         DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
63         DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
64         DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
65         DRI_CONF_MAX_TEXTURE_UNITS(4,2,6)
66     DRI_CONF_SECTION_END
67     DRI_CONF_SECTION_QUALITY
68         DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
69         DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
70         DRI_CONF_NO_NEG_LOD_BIAS(false)
71         DRI_CONF_FORCE_S3TC_ENABLE(false)
72         DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
73         DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
74         DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
75     DRI_CONF_SECTION_END
76     DRI_CONF_SECTION_DEBUG
77         DRI_CONF_NO_RAST(false)
78     DRI_CONF_SECTION_END
79     DRI_CONF_SECTION_SOFTWARE
80         DRI_CONF_ARB_VERTEX_PROGRAM(true)
81         DRI_CONF_NV_VERTEX_PROGRAM(false)
82     DRI_CONF_SECTION_END
83 DRI_CONF_END;
84 static const GLuint __driNConfigOptions = 14;
85
86 #if 1
87 /* Including xf86PciInfo.h introduces a bunch of errors...
88  */
89 #define PCI_CHIP_R200_QD        0x5144 /* why do they have r200 names? */
90 #define PCI_CHIP_R200_QE        0x5145 /* Those are all standard radeons */
91 #define PCI_CHIP_R200_QF        0x5146
92 #define PCI_CHIP_R200_QG        0x5147
93 #define PCI_CHIP_R200_QY        0x5159
94 #define PCI_CHIP_R200_QZ        0x515A
95 #define PCI_CHIP_R200_LW        0x4C57
96 #define PCI_CHIP_R200_LX        0x4C58
97 #define PCI_CHIP_R200_LY        0x4C59
98 #define PCI_CHIP_R200_LZ        0x4C5A
99 #define PCI_CHIP_RV200_QW       0x5157 /* Radeon 7500 - not an R200 at all */
100 #define PCI_CHIP_RV200_QX       0x5158
101 #define PCI_CHIP_RS100_4136     0x4136 /* IGP RS100, RS200, RS250 are not R200 */
102 #define PCI_CHIP_RS200_4137     0x4137
103 #define PCI_CHIP_RS250_4237     0x4237
104 #define PCI_CHIP_RS100_4336     0x4336
105 #define PCI_CHIP_RS200_4337     0x4337
106 #define PCI_CHIP_RS250_4437     0x4437
107 #define PCI_CHIP_RS300_5834     0x5834 /* All RS300's are R200 */
108 #define PCI_CHIP_RS300_5835     0x5835
109 #define PCI_CHIP_RS300_5836     0x5836
110 #define PCI_CHIP_RS300_5837     0x5837
111 #define PCI_CHIP_R200_BB        0x4242 /* r200 (non-derived) start */
112 #define PCI_CHIP_R200_BC        0x4243
113 #define PCI_CHIP_R200_QH        0x5148
114 #define PCI_CHIP_R200_QI        0x5149
115 #define PCI_CHIP_R200_QJ        0x514A
116 #define PCI_CHIP_R200_QK        0x514B
117 #define PCI_CHIP_R200_QL        0x514C
118 #define PCI_CHIP_R200_QM        0x514D
119 #define PCI_CHIP_R200_QN        0x514E
120 #define PCI_CHIP_R200_QO        0x514F /* r200 (non-derived) end */
121 /* are the R200 Qh (0x5168) and following needed too? They are not in
122    xf86PciInfo.h but in the pci database. Maybe just secondary ports or
123    something ? Ah well, better be safe than sorry */
124 #define PCI_CHIP_R200_Qh        0x5168
125 #define PCI_CHIP_R200_Qi        0x5169
126 #define PCI_CHIP_R200_Qj        0x516A
127 #define PCI_CHIP_R200_Qk        0x516B
128 #define PCI_CHIP_R200_Ql        0x516C
129
130 #endif
131
132 #ifdef USE_NEW_INTERFACE
133 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
134 #endif /* USE_NEW_INTERFACE */
135
136 static r200ScreenPtr __r200Screen;
137
138 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
139
140 #ifdef USE_NEW_INTERFACE
141 static __GLcontextModes *
142 r200FillInModes( unsigned pixel_bits, unsigned depth_bits,
143                  unsigned stencil_bits, GLboolean have_back_buffer )
144 {
145     __GLcontextModes * modes;
146     __GLcontextModes * m;
147     unsigned num_modes;
148     unsigned depth_buffer_factor;
149     unsigned back_buffer_factor;
150     GLenum fb_format;
151     GLenum fb_type;
152
153     /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
154      * enough to add support.  Basically, if a context is created with an
155      * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
156      * will never be used.
157      */
158     static const GLenum back_buffer_modes[] = {
159         GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
160     };
161
162     uint8_t depth_bits_array[2];
163     uint8_t stencil_bits_array[2];
164
165
166     depth_bits_array[0] = depth_bits;
167     depth_bits_array[1] = depth_bits;
168     
169     /* Just like with the accumulation buffer, always provide some modes
170      * with a stencil buffer.  It will be a sw fallback, but some apps won't
171      * care about that.
172      */
173     stencil_bits_array[0] = 0;
174     stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
175
176     depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
177     back_buffer_factor  = (have_back_buffer) ? 2 : 1;
178
179     num_modes = depth_buffer_factor * back_buffer_factor * 4;
180
181     if ( pixel_bits == 16 ) {
182         fb_format = GL_RGB;
183         fb_type = GL_UNSIGNED_SHORT_5_6_5;
184     }
185     else {
186         fb_format = GL_BGRA;
187         fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
188     }
189
190     modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) );
191     m = modes;
192     if ( ! driFillInModes( & m, fb_format, fb_type,
193                            depth_bits_array, stencil_bits_array, depth_buffer_factor,
194                            back_buffer_modes, back_buffer_factor,
195                            GLX_TRUE_COLOR ) ) {
196         fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
197                  __func__, __LINE__ );
198         return NULL;
199     }
200
201     if ( ! driFillInModes( & m, fb_format, fb_type,
202                            depth_bits_array, stencil_bits_array, depth_buffer_factor,
203                            back_buffer_modes, back_buffer_factor,
204                            GLX_DIRECT_COLOR ) ) {
205         fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
206                  __func__, __LINE__ );
207         return NULL;
208     }
209
210     /* Mark the visual as slow if there are "fake" stencil bits.
211      */
212     for ( m = modes ; m != NULL ; m = m->next ) {
213         if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
214             m->visualRating = GLX_SLOW_CONFIG;
215         }
216     }
217
218     return modes;
219 }
220 #endif /* USE_NEW_INTERFACE */
221
222
223 /* Create the device specific screen private data struct.
224  */
225 static r200ScreenPtr 
226 r200CreateScreen( __DRIscreenPrivate *sPriv )
227 {
228    r200ScreenPtr screen;
229    RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
230    unsigned char *RADEONMMIO;
231
232
233    /* Allocate the private area */
234    screen = (r200ScreenPtr) CALLOC( sizeof(*screen) );
235    if ( !screen ) {
236       __driUtilMessage("%s: Could not allocate memory for screen structure",
237                        __FUNCTION__);
238       return NULL;
239    }
240
241    screen->chipset = 0;
242    switch ( dri_priv->deviceID ) {
243    case PCI_CHIP_R200_QD:
244    case PCI_CHIP_R200_QE:
245    case PCI_CHIP_R200_QF:
246    case PCI_CHIP_R200_QG:
247    case PCI_CHIP_R200_QY:
248    case PCI_CHIP_R200_QZ:
249    case PCI_CHIP_RV200_QW:
250    case PCI_CHIP_RV200_QX:
251    case PCI_CHIP_R200_LW:
252    case PCI_CHIP_R200_LX:
253    case PCI_CHIP_R200_LY:
254    case PCI_CHIP_R200_LZ:
255    case PCI_CHIP_RS100_4136:
256    case PCI_CHIP_RS200_4137:
257    case PCI_CHIP_RS250_4237:
258    case PCI_CHIP_RS100_4336:
259    case PCI_CHIP_RS200_4337:
260    case PCI_CHIP_RS250_4437:
261       __driUtilMessage("r200CreateScreen(): Device isn't an r200!\n");
262       FREE( screen );
263       return NULL;
264
265    case PCI_CHIP_RS300_5834:
266    case PCI_CHIP_RS300_5835:
267    case PCI_CHIP_RS300_5836:
268    case PCI_CHIP_RS300_5837:
269       break;
270
271    case PCI_CHIP_R200_BB:
272    case PCI_CHIP_R200_BC:
273    case PCI_CHIP_R200_QH:
274    case PCI_CHIP_R200_QI:
275    case PCI_CHIP_R200_QJ:
276    case PCI_CHIP_R200_QK:
277    case PCI_CHIP_R200_QL:
278    case PCI_CHIP_R200_QM:
279    case PCI_CHIP_R200_QN:
280    case PCI_CHIP_R200_QO:
281    case PCI_CHIP_R200_Qh:
282    case PCI_CHIP_R200_Qi:
283    case PCI_CHIP_R200_Qj:
284    case PCI_CHIP_R200_Qk:
285    case PCI_CHIP_R200_Ql:
286       screen->chipset |= R200_CHIPSET_REAL_R200;
287    /* fallthrough */
288    default:
289       screen->chipset |= R200_CHIPSET_TCL;
290       break;
291    }
292
293    /* parse information in __driConfigOptions */
294    driParseOptionInfo (&screen->optionCache,
295                        __driConfigOptions, __driNConfigOptions);
296
297    /* This is first since which regions we map depends on whether or
298     * not we are using a PCI card.
299     */
300    screen->IsPCI = dri_priv->IsPCI;
301
302    {
303       int ret;
304       drm_radeon_getparam_t gp;
305
306       gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
307       gp.value = &screen->gart_buffer_offset;
308
309       ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
310                                  &gp, sizeof(gp));
311       if (ret) {
312          FREE( screen );
313          fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
314          return NULL;
315       }
316
317       if (sPriv->drmMinor >= 6) {
318          gp.param = RADEON_PARAM_GART_BASE;
319          gp.value = &screen->gart_base;
320
321          ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
322                                     &gp, sizeof(gp));
323          if (ret) {
324             FREE( screen );
325             fprintf(stderr, "drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n", ret);
326             return NULL;
327          }
328
329
330          gp.param = RADEON_PARAM_IRQ_NR;
331          gp.value = &screen->irq;
332
333          ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
334                                     &gp, sizeof(gp));
335          if (ret) {
336             FREE( screen );
337             fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret);
338             return NULL;
339          }
340
341          /* Check if kernel module is new enough to support cube maps */
342          screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
343          /* Check if kernel module is new enough to support blend color and
344             separate blend functions/equations */
345          screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
346
347       }
348    }
349
350    screen->mmio.handle = dri_priv->registerHandle;
351    screen->mmio.size   = dri_priv->registerSize;
352    if ( drmMap( sPriv->fd,
353                 screen->mmio.handle,
354                 screen->mmio.size,
355                 &screen->mmio.map ) ) {
356       FREE( screen );
357       __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
358       return NULL;
359    }
360
361    RADEONMMIO = screen->mmio.map;
362
363    screen->status.handle = dri_priv->statusHandle;
364    screen->status.size   = dri_priv->statusSize;
365    if ( drmMap( sPriv->fd,
366                 screen->status.handle,
367                 screen->status.size,
368                 &screen->status.map ) ) {
369       drmUnmap( screen->mmio.map, screen->mmio.size );
370       FREE( screen );
371       __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
372       return NULL;
373    }
374    screen->scratch = (__volatile__ uint32_t *)
375       ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
376
377    screen->buffers = drmMapBufs( sPriv->fd );
378    if ( !screen->buffers ) {
379       drmUnmap( screen->status.map, screen->status.size );
380       drmUnmap( screen->mmio.map, screen->mmio.size );
381       FREE( screen );
382       __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
383       return NULL;
384    }
385
386    RADEONMMIO = screen->mmio.map;
387
388    if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
389
390       screen->gartTextures.handle = dri_priv->gartTexHandle;
391       screen->gartTextures.size   = dri_priv->gartTexMapSize;
392       if ( drmMap( sPriv->fd,
393                    screen->gartTextures.handle,
394                    screen->gartTextures.size,
395                    (drmAddressPtr)&screen->gartTextures.map ) ) {
396          drmUnmapBufs( screen->buffers );
397          drmUnmap( screen->status.map, screen->status.size );
398          drmUnmap( screen->mmio.map, screen->mmio.size );
399          FREE( screen );
400          __driUtilMessage("%s: drmMAP failed for GART texture area\n", __FUNCTION__);
401          return NULL;
402       }
403
404       screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
405                 ? INREG( RADEON_AIC_LO_ADDR )
406                 : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
407    }
408
409    screen->cpp = dri_priv->bpp / 8;
410    screen->AGPMode = dri_priv->AGPMode;
411
412    screen->fbLocation   = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
413
414    if ( sPriv->drmMinor >= 10 ) {
415       drm_radeon_setparam_t sp;
416
417       sp.param = RADEON_SETPARAM_FB_LOCATION;
418       sp.value = screen->fbLocation;
419
420       drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
421                        &sp, sizeof( sp ) );
422    }
423
424    screen->frontOffset  = dri_priv->frontOffset;
425    screen->frontPitch   = dri_priv->frontPitch;
426    screen->backOffset   = dri_priv->backOffset;
427    screen->backPitch    = dri_priv->backPitch;
428    screen->depthOffset  = dri_priv->depthOffset;
429    screen->depthPitch   = dri_priv->depthPitch;
430
431    screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
432                                        + screen->fbLocation;
433    screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
434    screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
435       dri_priv->log2TexGran;
436
437    if ( !screen->gartTextures.map ) {
438       screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
439       screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
440       screen->texSize[RADEON_GART_TEX_HEAP] = 0;
441       screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
442    } else {
443       screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
444       screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
445       screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
446       screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
447          dri_priv->log2GARTTexGran;
448    }
449
450    screen->driScreen = sPriv;
451    screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
452
453    if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
454       PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
455           (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
456       void * const psc = sPriv->psc->screenConfigs;
457
458       if ( glx_enable_extension != NULL ) {
459          if ( screen->irq != 0 ) {
460             (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
461             (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
462             (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
463          }
464
465          (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
466
467          if ( driCompareGLXAPIVersion( 20030818 ) >= 0 ) {
468             sPriv->psc->allocateMemory = (void *) r200AllocateMemoryMESA;
469             sPriv->psc->freeMemory     = (void *) r200FreeMemoryMESA;
470             sPriv->psc->memoryOffset   = (void *) r200GetMemoryOffsetMESA;
471
472             (*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
473          }
474           
475          if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
476             (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
477             (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
478          }
479       }
480    }
481    return screen;
482 }
483
484 /* Destroy the device specific screen private data struct.
485  */
486 static void 
487 r200DestroyScreen( __DRIscreenPrivate *sPriv )
488 {
489    r200ScreenPtr screen = (r200ScreenPtr)sPriv->private;
490
491    if (!screen)
492       return;
493
494    if ( screen->gartTextures.map ) {
495       drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
496    }
497    drmUnmapBufs( screen->buffers );
498    drmUnmap( screen->status.map, screen->status.size );
499    drmUnmap( screen->mmio.map, screen->mmio.size );
500
501    /* free all option information */
502    driDestroyOptionInfo (&screen->optionCache);
503
504    FREE( screen );
505    sPriv->private = NULL;
506 }
507
508
509 /* Initialize the driver specific screen private data.
510  */
511 static GLboolean
512 r200InitDriver( __DRIscreenPrivate *sPriv )
513 {
514    __r200Screen = r200CreateScreen( sPriv );
515
516    sPriv->private = (void *) __r200Screen;
517
518    return sPriv->private ? GL_TRUE : GL_FALSE;
519 }
520
521
522
523 /**
524  * Create and initialize the Mesa and driver specific pixmap buffer
525  * data.
526  * 
527  * \todo This function (and its interface) will need to be updated to support
528  * pbuffers.
529  */
530 static GLboolean
531 r200CreateBuffer( __DRIscreenPrivate *driScrnPriv,
532                   __DRIdrawablePrivate *driDrawPriv,
533                   const __GLcontextModes *mesaVis,
534                   GLboolean isPixmap )
535 {
536    if (isPixmap) {
537       return GL_FALSE; /* not implemented */
538    }
539    else {
540       const GLboolean swDepth = GL_FALSE;
541       const GLboolean swAlpha = GL_FALSE;
542       const GLboolean swAccum = mesaVis->accumRedBits > 0;
543       const GLboolean swStencil = mesaVis->stencilBits > 0 &&
544          mesaVis->depthBits != 24;
545       driDrawPriv->driverPrivate = (void *)
546          _mesa_create_framebuffer( mesaVis,
547                                    swDepth,
548                                    swStencil,
549                                    swAccum,
550                                    swAlpha );
551       return (driDrawPriv->driverPrivate != NULL);
552    }
553 }
554
555
556 static void
557 r200DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
558 {
559    _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
560 }
561
562
563
564
565 static const struct __DriverAPIRec r200API = {
566    .InitDriver      = r200InitDriver,
567    .DestroyScreen   = r200DestroyScreen,
568    .CreateContext   = r200CreateContext,
569    .DestroyContext  = r200DestroyContext,
570    .CreateBuffer    = r200CreateBuffer,
571    .DestroyBuffer   = r200DestroyBuffer,
572    .SwapBuffers     = r200SwapBuffers,
573    .MakeCurrent     = r200MakeCurrent,
574    .UnbindContext   = r200UnbindContext,
575    .GetSwapInfo     = getSwapInfo,
576    .GetMSC          = driGetMSC32,
577    .WaitForMSC      = driWaitForMSC32,
578    .WaitForSBC      = NULL,
579    .SwapBuffersMSC  = NULL
580 };
581
582
583 /*
584  * This is the bootstrap function for the driver.
585  * The __driCreateScreen name is the symbol that libGL.so fetches.
586  * Return:  pointer to a __DRIscreenPrivate.
587  *
588  */
589 #if !defined(DRI_NEW_INTERFACE_ONLY)
590 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
591                         int numConfigs, __GLXvisualConfig *config)
592 {
593    __DRIscreenPrivate *psp;
594    psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r200API);
595    return (void *) psp;
596 }
597 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
598
599
600 /**
601  * This is the bootstrap function for the driver.  libGL supplies all of the
602  * requisite information about the system, and the driver initializes itself.
603  * This routine also fills in the linked list pointed to by \c driver_modes
604  * with the \c __GLcontextModes that the driver can support for windows or
605  * pbuffers.
606  * 
607  * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on 
608  *         failure.
609  */
610 #ifdef USE_NEW_INTERFACE
611 void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
612                              const __GLcontextModes * modes,
613                              const __DRIversion * ddx_version,
614                              const __DRIversion * dri_version,
615                              const __DRIversion * drm_version,
616                              const __DRIframebuffer * frame_buffer,
617                              drmAddress pSAREA, int fd, 
618                              int internal_api_version,
619                              __GLcontextModes ** driver_modes )
620                              
621 {
622    __DRIscreenPrivate *psp;
623    static const __DRIversion ddx_expected = { 4, 0, 0 };
624    static const __DRIversion dri_expected = { 4, 0, 0 };
625    static const __DRIversion drm_expected = { 1, 5, 0 };
626
627    if ( ! driCheckDriDdxDrmVersions2( "R200",
628                                       dri_version, & dri_expected,
629                                       ddx_version, & ddx_expected,
630                                       drm_version, & drm_expected ) ) {
631       return NULL;
632    }
633       
634    psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
635                                   ddx_version, dri_version, drm_version,
636                                   frame_buffer, pSAREA, fd,
637                                   internal_api_version, &r200API);
638    if ( psp != NULL ) {
639       create_context_modes = (PFNGLXCREATECONTEXTMODES)
640           glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
641       if ( create_context_modes != NULL ) {
642          RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
643          *driver_modes = r200FillInModes( dri_priv->bpp,
644                                           (dri_priv->bpp == 16) ? 16 : 24,
645                                           (dri_priv->bpp == 16) ? 0  : 8,
646                                           (dri_priv->backOffset != dri_priv->depthOffset) );
647       }
648    }
649
650    return (void *) psp;
651 }
652 #endif /* USE_NEW_INTERFACE */
653
654
655 /**
656  * Get information about previous buffer swaps.
657  */
658 static int
659 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
660 {
661    r200ContextPtr  rmesa;
662
663    if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
664         || (dPriv->driContextPriv->driverPrivate == NULL)
665         || (sInfo == NULL) ) {
666       return -1;
667    }
668
669    rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
670    sInfo->swap_count = rmesa->swap_count;
671    sInfo->swap_ust = rmesa->swap_ust;
672    sInfo->swap_missed_count = rmesa->swap_missed_count;
673
674    sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
675        ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
676        : 0.0;
677
678    return 0;
679 }