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