radeon_screen.c revision 781a204bcf5599716991e5d36b08a36db5209441
1/**************************************************************************
2
3Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4                     VA Linux Systems Inc., Fremont, California.
5
6All Rights Reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining
9a copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sublicense, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial
18portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/**
31 * \file radeon_screen.c
32 * Screen initialization functions for the Radeon driver.
33 *
34 * \author Kevin E. Martin <martin@valinux.com>
35 * \author  Gareth Hughes <gareth@valinux.com>
36 */
37
38#include <errno.h>
39#include "main/glheader.h"
40#include "main/imports.h"
41#include "main/mtypes.h"
42#include "main/framebuffer.h"
43#include "main/renderbuffer.h"
44#include "main/fbobject.h"
45
46#define STANDALONE_MMIO
47#include "radeon_chipset.h"
48#include "radeon_macros.h"
49#include "radeon_screen.h"
50#include "radeon_common.h"
51#include "radeon_common_context.h"
52#if defined(RADEON_R100)
53#include "radeon_context.h"
54#include "radeon_tex.h"
55#elif defined(RADEON_R200)
56#include "r200_context.h"
57#include "r200_tex.h"
58#endif
59
60#include "utils.h"
61
62#include "GL/internal/dri_interface.h"
63
64/* Radeon configuration
65 */
66#include "xmlpool.h"
67
68#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
69DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
70        DRI_CONF_DESC(en,"Size of command buffer (in KB)") \
71        DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
72DRI_CONF_OPT_END
73
74#if defined(RADEON_R100)	/* R100 */
75PUBLIC const char __driConfigOptions[] =
76DRI_CONF_BEGIN
77    DRI_CONF_SECTION_PERFORMANCE
78        DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
79        DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
80        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
81        DRI_CONF_MAX_TEXTURE_UNITS(3,2,3)
82        DRI_CONF_HYPERZ(false)
83        DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
84    DRI_CONF_SECTION_END
85    DRI_CONF_SECTION_QUALITY
86        DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
87        DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
88        DRI_CONF_NO_NEG_LOD_BIAS(false)
89        DRI_CONF_FORCE_S3TC_ENABLE(false)
90        DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
91        DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
92        DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
93        DRI_CONF_ALLOW_LARGE_TEXTURES(2)
94    DRI_CONF_SECTION_END
95    DRI_CONF_SECTION_DEBUG
96        DRI_CONF_NO_RAST(false)
97    DRI_CONF_SECTION_END
98DRI_CONF_END;
99static const GLuint __driNConfigOptions = 15;
100
101#elif defined(RADEON_R200)
102
103PUBLIC const char __driConfigOptions[] =
104DRI_CONF_BEGIN
105    DRI_CONF_SECTION_PERFORMANCE
106        DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
107        DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
108        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
109        DRI_CONF_MAX_TEXTURE_UNITS(6,2,6)
110        DRI_CONF_HYPERZ(false)
111        DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
112    DRI_CONF_SECTION_END
113    DRI_CONF_SECTION_QUALITY
114        DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
115        DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
116        DRI_CONF_NO_NEG_LOD_BIAS(false)
117        DRI_CONF_FORCE_S3TC_ENABLE(false)
118        DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
119        DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
120        DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
121        DRI_CONF_ALLOW_LARGE_TEXTURES(2)
122        DRI_CONF_TEXTURE_BLEND_QUALITY(1.0,"0.0:1.0")
123    DRI_CONF_SECTION_END
124    DRI_CONF_SECTION_DEBUG
125        DRI_CONF_NO_RAST(false)
126    DRI_CONF_SECTION_END
127    DRI_CONF_SECTION_SOFTWARE
128        DRI_CONF_NV_VERTEX_PROGRAM(false)
129    DRI_CONF_SECTION_END
130DRI_CONF_END;
131static const GLuint __driNConfigOptions = 17;
132
133#endif
134
135#ifndef RADEON_INFO_TILE_CONFIG
136#define RADEON_INFO_TILE_CONFIG 0x6
137#endif
138
139static int
140radeonGetParam(__DRIscreen *sPriv, int param, void *value)
141{
142  int ret;
143  drm_radeon_getparam_t gp = { 0 };
144  struct drm_radeon_info info = { 0 };
145
146  if (sPriv->drm_version.major >= 2) {
147      info.value = (uint64_t)(uintptr_t)value;
148      switch (param) {
149      case RADEON_PARAM_DEVICE_ID:
150          info.request = RADEON_INFO_DEVICE_ID;
151          break;
152      case RADEON_PARAM_NUM_GB_PIPES:
153          info.request = RADEON_INFO_NUM_GB_PIPES;
154          break;
155      case RADEON_PARAM_NUM_Z_PIPES:
156          info.request = RADEON_INFO_NUM_Z_PIPES;
157          break;
158      case RADEON_INFO_TILE_CONFIG:
159	  info.request = RADEON_INFO_TILE_CONFIG;
160          break;
161      default:
162          return -EINVAL;
163      }
164      ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_INFO, &info, sizeof(info));
165  } else {
166      gp.param = param;
167      gp.value = value;
168
169      ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
170  }
171  return ret;
172}
173
174#if defined(RADEON_R100)
175static const __DRItexBufferExtension radeonTexBufferExtension = {
176    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
177   radeonSetTexBuffer,
178   radeonSetTexBuffer2,
179};
180#elif defined(RADEON_R200)
181static const __DRItexBufferExtension r200TexBufferExtension = {
182    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
183   r200SetTexBuffer,
184   r200SetTexBuffer2,
185};
186#endif
187
188static void
189radeonDRI2Flush(__DRIdrawable *drawable)
190{
191    radeonContextPtr rmesa;
192
193    rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate;
194    radeonFlush(rmesa->glCtx);
195}
196
197static const struct __DRI2flushExtensionRec radeonFlushExtension = {
198    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
199    radeonDRI2Flush,
200    dri2InvalidateDrawable,
201};
202
203static __DRIimage *
204radeon_create_image_from_name(__DRIscreen *screen,
205                              int width, int height, int format,
206                              int name, int pitch, void *loaderPrivate)
207{
208   __DRIimage *image;
209   radeonScreenPtr radeonScreen = screen->driverPrivate;
210
211   if (name == 0)
212      return NULL;
213
214   image = CALLOC(sizeof *image);
215   if (image == NULL)
216      return NULL;
217
218   switch (format) {
219   case __DRI_IMAGE_FORMAT_RGB565:
220      image->format = MESA_FORMAT_RGB565;
221      image->internal_format = GL_RGB;
222      image->data_type = GL_UNSIGNED_BYTE;
223      break;
224   case __DRI_IMAGE_FORMAT_XRGB8888:
225      image->format = MESA_FORMAT_XRGB8888;
226      image->internal_format = GL_RGB;
227      image->data_type = GL_UNSIGNED_BYTE;
228      break;
229   case __DRI_IMAGE_FORMAT_ARGB8888:
230      image->format = MESA_FORMAT_ARGB8888;
231      image->internal_format = GL_RGBA;
232      image->data_type = GL_UNSIGNED_BYTE;
233      break;
234   default:
235      free(image);
236      return NULL;
237   }
238
239   image->data = loaderPrivate;
240   image->cpp = _mesa_get_format_bytes(image->format);
241   image->width = width;
242   image->pitch = pitch;
243   image->height = height;
244
245   image->bo = radeon_bo_open(radeonScreen->bom,
246                              (uint32_t)name,
247                              image->pitch * image->height * image->cpp,
248                              0,
249                              RADEON_GEM_DOMAIN_VRAM,
250                              0);
251
252   if (image->bo == NULL) {
253      FREE(image);
254      return NULL;
255   }
256
257   return image;
258}
259
260static __DRIimage *
261radeon_create_image_from_renderbuffer(__DRIcontext *context,
262                                      int renderbuffer, void *loaderPrivate)
263{
264   __DRIimage *image;
265   radeonContextPtr radeon = context->driverPrivate;
266   struct gl_renderbuffer *rb;
267   struct radeon_renderbuffer *rrb;
268
269   rb = _mesa_lookup_renderbuffer(radeon->glCtx, renderbuffer);
270   if (!rb) {
271      _mesa_error(radeon->glCtx,
272                  GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
273      return NULL;
274   }
275
276   rrb = radeon_renderbuffer(rb);
277   image = CALLOC(sizeof *image);
278   if (image == NULL)
279      return NULL;
280
281   image->internal_format = rb->InternalFormat;
282   image->format = rb->Format;
283   image->cpp = rrb->cpp;
284   image->data_type = rb->DataType;
285   image->data = loaderPrivate;
286   radeon_bo_ref(rrb->bo);
287   image->bo = rrb->bo;
288
289   image->width = rb->Width;
290   image->height = rb->Height;
291   image->pitch = rrb->pitch / image->cpp;
292
293   return image;
294}
295
296static void
297radeon_destroy_image(__DRIimage *image)
298{
299   radeon_bo_unref(image->bo);
300   FREE(image);
301}
302
303static __DRIimage *
304radeon_create_image(__DRIscreen *screen,
305                    int width, int height, int format,
306                    unsigned int use,
307                    void *loaderPrivate)
308{
309   __DRIimage *image;
310   radeonScreenPtr radeonScreen = screen->driverPrivate;
311
312   image = CALLOC(sizeof *image);
313   if (image == NULL)
314      return NULL;
315
316   switch (format) {
317   case __DRI_IMAGE_FORMAT_RGB565:
318      image->format = MESA_FORMAT_RGB565;
319      image->internal_format = GL_RGB;
320      image->data_type = GL_UNSIGNED_BYTE;
321      break;
322   case __DRI_IMAGE_FORMAT_XRGB8888:
323      image->format = MESA_FORMAT_XRGB8888;
324      image->internal_format = GL_RGB;
325      image->data_type = GL_UNSIGNED_BYTE;
326      break;
327   case __DRI_IMAGE_FORMAT_ARGB8888:
328      image->format = MESA_FORMAT_ARGB8888;
329      image->internal_format = GL_RGBA;
330      image->data_type = GL_UNSIGNED_BYTE;
331      break;
332   default:
333      free(image);
334      return NULL;
335   }
336
337   image->data = loaderPrivate;
338   image->cpp = _mesa_get_format_bytes(image->format);
339   image->width = width;
340   image->height = height;
341   image->pitch = ((image->cpp * image->width + 255) & ~255) / image->cpp;
342
343   image->bo = radeon_bo_open(radeonScreen->bom,
344                              0,
345                              image->pitch * image->height * image->cpp,
346                              0,
347                              RADEON_GEM_DOMAIN_VRAM,
348                              0);
349
350   if (image->bo == NULL) {
351      FREE(image);
352      return NULL;
353   }
354
355   return image;
356}
357
358static GLboolean
359radeon_query_image(__DRIimage *image, int attrib, int *value)
360{
361   switch (attrib) {
362   case __DRI_IMAGE_ATTRIB_STRIDE:
363      *value = image->pitch * image->cpp;
364      return GL_TRUE;
365   case __DRI_IMAGE_ATTRIB_HANDLE:
366      *value = image->bo->handle;
367      return GL_TRUE;
368   case __DRI_IMAGE_ATTRIB_NAME:
369      radeon_gem_get_kernel_name(image->bo, (uint32_t *) value);
370      return GL_TRUE;
371   default:
372      return GL_FALSE;
373   }
374}
375
376static struct __DRIimageExtensionRec radeonImageExtension = {
377    { __DRI_IMAGE, __DRI_IMAGE_VERSION },
378   radeon_create_image_from_name,
379   radeon_create_image_from_renderbuffer,
380   radeon_destroy_image,
381   radeon_create_image,
382   radeon_query_image
383};
384
385static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
386{
387   screen->device_id = device_id;
388   screen->chip_flags = 0;
389   switch ( device_id ) {
390#if defined(RADEON_R100)
391   case PCI_CHIP_RN50_515E:
392   case PCI_CHIP_RN50_5969:
393	return -1;
394
395   case PCI_CHIP_RADEON_LY:
396   case PCI_CHIP_RADEON_LZ:
397   case PCI_CHIP_RADEON_QY:
398   case PCI_CHIP_RADEON_QZ:
399      screen->chip_family = CHIP_FAMILY_RV100;
400      break;
401
402   case PCI_CHIP_RS100_4136:
403   case PCI_CHIP_RS100_4336:
404      screen->chip_family = CHIP_FAMILY_RS100;
405      break;
406
407   case PCI_CHIP_RS200_4137:
408   case PCI_CHIP_RS200_4337:
409   case PCI_CHIP_RS250_4237:
410   case PCI_CHIP_RS250_4437:
411      screen->chip_family = CHIP_FAMILY_RS200;
412      break;
413
414   case PCI_CHIP_RADEON_QD:
415   case PCI_CHIP_RADEON_QE:
416   case PCI_CHIP_RADEON_QF:
417   case PCI_CHIP_RADEON_QG:
418      /* all original radeons (7200) presumably have a stencil op bug */
419      screen->chip_family = CHIP_FAMILY_R100;
420      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL;
421      break;
422
423   case PCI_CHIP_RV200_QW:
424   case PCI_CHIP_RV200_QX:
425   case PCI_CHIP_RADEON_LW:
426   case PCI_CHIP_RADEON_LX:
427      screen->chip_family = CHIP_FAMILY_RV200;
428      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
429      break;
430
431#elif defined(RADEON_R200)
432   case PCI_CHIP_R200_BB:
433   case PCI_CHIP_R200_QH:
434   case PCI_CHIP_R200_QL:
435   case PCI_CHIP_R200_QM:
436      screen->chip_family = CHIP_FAMILY_R200;
437      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
438      break;
439
440   case PCI_CHIP_RV250_If:
441   case PCI_CHIP_RV250_Ig:
442   case PCI_CHIP_RV250_Ld:
443   case PCI_CHIP_RV250_Lf:
444   case PCI_CHIP_RV250_Lg:
445      screen->chip_family = CHIP_FAMILY_RV250;
446      screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
447      break;
448
449   case PCI_CHIP_RV280_4C6E:
450   case PCI_CHIP_RV280_5960:
451   case PCI_CHIP_RV280_5961:
452   case PCI_CHIP_RV280_5962:
453   case PCI_CHIP_RV280_5964:
454   case PCI_CHIP_RV280_5965:
455   case PCI_CHIP_RV280_5C61:
456   case PCI_CHIP_RV280_5C63:
457      screen->chip_family = CHIP_FAMILY_RV280;
458      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
459      break;
460
461   case PCI_CHIP_RS300_5834:
462   case PCI_CHIP_RS300_5835:
463   case PCI_CHIP_RS350_7834:
464   case PCI_CHIP_RS350_7835:
465      screen->chip_family = CHIP_FAMILY_RS300;
466      screen->chip_flags = RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
467      break;
468#endif
469
470   default:
471      fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
472	      device_id);
473      return -1;
474   }
475
476   return 0;
477}
478
479static radeonScreenPtr
480radeonCreateScreen2(__DRIscreen *sPriv)
481{
482   radeonScreenPtr screen;
483   int i;
484   int ret;
485   uint32_t device_id = 0;
486
487   /* Allocate the private area */
488   screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
489   if ( !screen ) {
490      fprintf(stderr, "%s: Could not allocate memory for screen structure", __FUNCTION__);
491      fprintf(stderr, "leaving here\n");
492      return NULL;
493   }
494
495   radeon_init_debug();
496
497   /* parse information in __driConfigOptions */
498   driParseOptionInfo (&screen->optionCache,
499		       __driConfigOptions, __driNConfigOptions);
500
501   screen->chip_flags = 0;
502
503   screen->irq = 1;
504
505   ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
506   if (ret) {
507     FREE( screen );
508     fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret);
509     return NULL;
510   }
511
512   ret = radeon_set_screen_flags(screen, device_id);
513   if (ret == -1)
514     return NULL;
515
516   if (getenv("R300_NO_TCL"))
517	   screen->chip_flags &= ~RADEON_CHIPSET_TCL;
518
519   i = 0;
520   screen->extensions[i++] = &dri2ConfigQueryExtension.base;
521
522#if defined(RADEON_R100)
523   screen->extensions[i++] = &radeonTexBufferExtension.base;
524#elif defined(RADEON_R200)
525   screen->extensions[i++] = &r200TexBufferExtension.base;
526#endif
527
528   screen->extensions[i++] = &radeonFlushExtension.base;
529   screen->extensions[i++] = &radeonImageExtension.base;
530
531   screen->extensions[i++] = NULL;
532   sPriv->extensions = screen->extensions;
533
534   screen->driScreen = sPriv;
535   screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
536   if (screen->bom == NULL) {
537       free(screen);
538       return NULL;
539   }
540   return screen;
541}
542
543/* Destroy the device specific screen private data struct.
544 */
545static void
546radeonDestroyScreen( __DRIscreen *sPriv )
547{
548    radeonScreenPtr screen = (radeonScreenPtr)sPriv->driverPrivate;
549
550    if (!screen)
551        return;
552
553#ifdef RADEON_BO_TRACK
554    radeon_tracker_print(&screen->bom->tracker, stderr);
555#endif
556    radeon_bo_manager_gem_dtor(screen->bom);
557
558    /* free all option information */
559    driDestroyOptionInfo (&screen->optionCache);
560
561    FREE( screen );
562    sPriv->driverPrivate = NULL;
563}
564
565
566/* Initialize the driver specific screen private data.
567 */
568static GLboolean
569radeonInitDriver( __DRIscreen *sPriv )
570{
571    sPriv->driverPrivate = (void *) radeonCreateScreen2( sPriv );
572    if ( !sPriv->driverPrivate ) {
573        radeonDestroyScreen( sPriv );
574        return GL_FALSE;
575    }
576
577    return GL_TRUE;
578}
579
580
581
582/**
583 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
584 *
585 * \todo This function (and its interface) will need to be updated to support
586 * pbuffers.
587 */
588static GLboolean
589radeonCreateBuffer( __DRIscreen *driScrnPriv,
590                    __DRIdrawable *driDrawPriv,
591                    const struct gl_config *mesaVis,
592                    GLboolean isPixmap )
593{
594    radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate;
595
596    const GLboolean swDepth = GL_FALSE;
597    const GLboolean swAlpha = GL_FALSE;
598    const GLboolean swAccum = mesaVis->accumRedBits > 0;
599    const GLboolean swStencil = mesaVis->stencilBits > 0 &&
600	mesaVis->depthBits != 24;
601    gl_format rgbFormat;
602    struct radeon_framebuffer *rfb;
603
604    if (isPixmap)
605      return GL_FALSE; /* not implemented */
606
607    rfb = CALLOC_STRUCT(radeon_framebuffer);
608    if (!rfb)
609      return GL_FALSE;
610
611    _mesa_initialize_window_framebuffer(&rfb->base, mesaVis);
612
613    if (mesaVis->redBits == 5)
614        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV;
615    else if (mesaVis->alphaBits == 0)
616        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_XRGB8888 : MESA_FORMAT_XRGB8888_REV;
617    else
618        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB8888_REV;
619
620    /* front color renderbuffer */
621    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
622    _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
623    rfb->color_rb[0]->has_surface = 1;
624
625    /* back color renderbuffer */
626    if (mesaVis->doubleBufferMode) {
627      rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
628	_mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
629	rfb->color_rb[1]->has_surface = 1;
630    }
631
632    if (mesaVis->depthBits == 24) {
633      if (mesaVis->stencilBits == 8) {
634	struct radeon_renderbuffer *depthStencilRb =
635           radeon_create_renderbuffer(MESA_FORMAT_S8_Z24, driDrawPriv);
636	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base);
637	_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base);
638	depthStencilRb->has_surface = screen->depthHasSurface;
639      } else {
640	/* depth renderbuffer */
641	struct radeon_renderbuffer *depth =
642           radeon_create_renderbuffer(MESA_FORMAT_X8_Z24, driDrawPriv);
643	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
644	depth->has_surface = screen->depthHasSurface;
645      }
646    } else if (mesaVis->depthBits == 16) {
647        /* just 16-bit depth buffer, no hw stencil */
648	struct radeon_renderbuffer *depth =
649           radeon_create_renderbuffer(MESA_FORMAT_Z16, driDrawPriv);
650	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
651	depth->has_surface = screen->depthHasSurface;
652    }
653
654    _mesa_add_soft_renderbuffers(&rfb->base,
655	    GL_FALSE, /* color */
656	    swDepth,
657	    swStencil,
658	    swAccum,
659	    swAlpha,
660	    GL_FALSE /* aux */);
661    driDrawPriv->driverPrivate = (void *) rfb;
662
663    return (driDrawPriv->driverPrivate != NULL);
664}
665
666
667static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb)
668{
669	struct radeon_renderbuffer *rb;
670
671	rb = rfb->color_rb[0];
672	if (rb && rb->bo) {
673		radeon_bo_unref(rb->bo);
674		rb->bo = NULL;
675	}
676	rb = rfb->color_rb[1];
677	if (rb && rb->bo) {
678		radeon_bo_unref(rb->bo);
679		rb->bo = NULL;
680	}
681	rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
682	if (rb && rb->bo) {
683		radeon_bo_unref(rb->bo);
684		rb->bo = NULL;
685	}
686}
687
688void
689radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
690{
691    struct radeon_framebuffer *rfb;
692    if (!driDrawPriv)
693	return;
694
695    rfb = (void*)driDrawPriv->driverPrivate;
696    if (!rfb)
697	return;
698    radeon_cleanup_renderbuffers(rfb);
699    _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
700}
701
702#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
703
704/**
705 * This is the driver specific part of the createNewScreen entry point.
706 * Called when using DRI2.
707 *
708 * \return the struct gl_config supported by this driver
709 */
710static const
711__DRIconfig **radeonInitScreen2(__DRIscreen *psp)
712{
713   GLenum fb_format[3];
714   GLenum fb_type[3];
715   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
716    * support pageflipping at all.
717    */
718   static const GLenum back_buffer_modes[] = {
719     GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
720   };
721   uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
722   int color;
723   __DRIconfig **configs = NULL;
724
725   if (!radeonInitDriver(psp)) {
726       return NULL;
727    }
728   depth_bits[0] = 0;
729   stencil_bits[0] = 0;
730   depth_bits[1] = 16;
731   stencil_bits[1] = 0;
732   depth_bits[2] = 24;
733   stencil_bits[2] = 0;
734   depth_bits[3] = 24;
735   stencil_bits[3] = 8;
736
737   msaa_samples_array[0] = 0;
738
739   fb_format[0] = GL_RGB;
740   fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
741
742   fb_format[1] = GL_BGR;
743   fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
744
745   fb_format[2] = GL_BGRA;
746   fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
747
748   for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
749      __DRIconfig **new_configs;
750
751      new_configs = driCreateConfigs(fb_format[color], fb_type[color],
752				     depth_bits,
753				     stencil_bits,
754				     ARRAY_SIZE(depth_bits),
755				     back_buffer_modes,
756				     ARRAY_SIZE(back_buffer_modes),
757				     msaa_samples_array,
758				     ARRAY_SIZE(msaa_samples_array),
759				     GL_TRUE);
760      if (configs == NULL)
761	 configs = new_configs;
762      else
763	 configs = driConcatConfigs(configs, new_configs);
764   }
765
766   if (configs == NULL) {
767      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
768              __LINE__);
769      return NULL;
770   }
771
772   return (const __DRIconfig **)configs;
773}
774
775const struct __DriverAPIRec driDriverAPI = {
776   .InitScreen      = radeonInitScreen2,
777   .DestroyScreen   = radeonDestroyScreen,
778#if defined(RADEON_R200)
779   .CreateContext   = r200CreateContext,
780   .DestroyContext  = r200DestroyContext,
781#else
782   .CreateContext   = r100CreateContext,
783   .DestroyContext  = radeonDestroyContext,
784#endif
785   .CreateBuffer    = radeonCreateBuffer,
786   .DestroyBuffer   = radeonDestroyBuffer,
787   .MakeCurrent     = radeonMakeCurrent,
788   .UnbindContext   = radeonUnbindContext,
789};
790
791/* This is the table of extensions that the loader will dlsym() for. */
792PUBLIC const __DRIextension *__driDriverExtensions[] = {
793    &driCoreExtension.base,
794    &driDRI2Extension.base,
795    NULL
796};
797