radeon_screen.c revision 494d0053909f4304c4d8050f8bc859edc7f05e36
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#endif
181
182#if defined(RADEON_R200)
183static const __DRItexBufferExtension r200TexBufferExtension = {
184    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
185   r200SetTexBuffer,
186   r200SetTexBuffer2,
187};
188#endif
189
190static void
191radeonDRI2Flush(__DRIdrawable *drawable)
192{
193    radeonContextPtr rmesa;
194
195    rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate;
196    radeonFlush(rmesa->glCtx);
197}
198
199static const struct __DRI2flushExtensionRec radeonFlushExtension = {
200    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
201    radeonDRI2Flush,
202    dri2InvalidateDrawable,
203};
204
205static __DRIimage *
206radeon_create_image_from_name(__DRIscreen *screen,
207                              int width, int height, int format,
208                              int name, int pitch, void *loaderPrivate)
209{
210   __DRIimage *image;
211   radeonScreenPtr radeonScreen = screen->driverPrivate;
212
213   if (name == 0)
214      return NULL;
215
216   image = CALLOC(sizeof *image);
217   if (image == NULL)
218      return NULL;
219
220   switch (format) {
221   case __DRI_IMAGE_FORMAT_RGB565:
222      image->format = MESA_FORMAT_RGB565;
223      image->internal_format = GL_RGB;
224      image->data_type = GL_UNSIGNED_BYTE;
225      break;
226   case __DRI_IMAGE_FORMAT_XRGB8888:
227      image->format = MESA_FORMAT_XRGB8888;
228      image->internal_format = GL_RGB;
229      image->data_type = GL_UNSIGNED_BYTE;
230      break;
231   case __DRI_IMAGE_FORMAT_ARGB8888:
232      image->format = MESA_FORMAT_ARGB8888;
233      image->internal_format = GL_RGBA;
234      image->data_type = GL_UNSIGNED_BYTE;
235      break;
236   default:
237      free(image);
238      return NULL;
239   }
240
241   image->data = loaderPrivate;
242   image->cpp = _mesa_get_format_bytes(image->format);
243   image->width = width;
244   image->pitch = pitch;
245   image->height = height;
246
247   image->bo = radeon_bo_open(radeonScreen->bom,
248                              (uint32_t)name,
249                              image->pitch * image->height * image->cpp,
250                              0,
251                              RADEON_GEM_DOMAIN_VRAM,
252                              0);
253
254   if (image->bo == NULL) {
255      FREE(image);
256      return NULL;
257   }
258
259   return image;
260}
261
262static __DRIimage *
263radeon_create_image_from_renderbuffer(__DRIcontext *context,
264                                      int renderbuffer, void *loaderPrivate)
265{
266   __DRIimage *image;
267   radeonContextPtr radeon = context->driverPrivate;
268   struct gl_renderbuffer *rb;
269   struct radeon_renderbuffer *rrb;
270
271   rb = _mesa_lookup_renderbuffer(radeon->glCtx, renderbuffer);
272   if (!rb) {
273      _mesa_error(radeon->glCtx,
274                  GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
275      return NULL;
276   }
277
278   rrb = radeon_renderbuffer(rb);
279   image = CALLOC(sizeof *image);
280   if (image == NULL)
281      return NULL;
282
283   image->internal_format = rb->InternalFormat;
284   image->format = rb->Format;
285   image->cpp = rrb->cpp;
286   image->data_type = rb->DataType;
287   image->data = loaderPrivate;
288   radeon_bo_ref(rrb->bo);
289   image->bo = rrb->bo;
290
291   image->width = rb->Width;
292   image->height = rb->Height;
293   image->pitch = rrb->pitch / image->cpp;
294
295   return image;
296}
297
298static void
299radeon_destroy_image(__DRIimage *image)
300{
301   radeon_bo_unref(image->bo);
302   FREE(image);
303}
304
305static __DRIimage *
306radeon_create_image(__DRIscreen *screen,
307                    int width, int height, int format,
308                    unsigned int use,
309                    void *loaderPrivate)
310{
311   __DRIimage *image;
312   radeonScreenPtr radeonScreen = screen->driverPrivate;
313
314   image = CALLOC(sizeof *image);
315   if (image == NULL)
316      return NULL;
317
318   switch (format) {
319   case __DRI_IMAGE_FORMAT_RGB565:
320      image->format = MESA_FORMAT_RGB565;
321      image->internal_format = GL_RGB;
322      image->data_type = GL_UNSIGNED_BYTE;
323      break;
324   case __DRI_IMAGE_FORMAT_XRGB8888:
325      image->format = MESA_FORMAT_XRGB8888;
326      image->internal_format = GL_RGB;
327      image->data_type = GL_UNSIGNED_BYTE;
328      break;
329   case __DRI_IMAGE_FORMAT_ARGB8888:
330      image->format = MESA_FORMAT_ARGB8888;
331      image->internal_format = GL_RGBA;
332      image->data_type = GL_UNSIGNED_BYTE;
333      break;
334   default:
335      free(image);
336      return NULL;
337   }
338
339   image->data = loaderPrivate;
340   image->cpp = _mesa_get_format_bytes(image->format);
341   image->width = width;
342   image->height = height;
343   image->pitch = ((image->cpp * image->width + 255) & ~255) / image->cpp;
344
345   image->bo = radeon_bo_open(radeonScreen->bom,
346                              0,
347                              image->pitch * image->height * image->cpp,
348                              0,
349                              RADEON_GEM_DOMAIN_VRAM,
350                              0);
351
352   if (image->bo == NULL) {
353      FREE(image);
354      return NULL;
355   }
356
357   return image;
358}
359
360static GLboolean
361radeon_query_image(__DRIimage *image, int attrib, int *value)
362{
363   switch (attrib) {
364   case __DRI_IMAGE_ATTRIB_STRIDE:
365      *value = image->pitch * image->cpp;
366      return GL_TRUE;
367   case __DRI_IMAGE_ATTRIB_HANDLE:
368      *value = image->bo->handle;
369      return GL_TRUE;
370   case __DRI_IMAGE_ATTRIB_NAME:
371      radeon_gem_get_kernel_name(image->bo, (uint32_t *) value);
372      return GL_TRUE;
373   default:
374      return GL_FALSE;
375   }
376}
377
378static struct __DRIimageExtensionRec radeonImageExtension = {
379    { __DRI_IMAGE, __DRI_IMAGE_VERSION },
380   radeon_create_image_from_name,
381   radeon_create_image_from_renderbuffer,
382   radeon_destroy_image,
383   radeon_create_image,
384   radeon_query_image
385};
386
387static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
388{
389   screen->device_id = device_id;
390   screen->chip_flags = 0;
391   switch ( device_id ) {
392#if defined(RADEON_R100)
393   case PCI_CHIP_RN50_515E:
394   case PCI_CHIP_RN50_5969:
395	return -1;
396
397   case PCI_CHIP_RADEON_LY:
398   case PCI_CHIP_RADEON_LZ:
399   case PCI_CHIP_RADEON_QY:
400   case PCI_CHIP_RADEON_QZ:
401      screen->chip_family = CHIP_FAMILY_RV100;
402      break;
403
404   case PCI_CHIP_RS100_4136:
405   case PCI_CHIP_RS100_4336:
406      screen->chip_family = CHIP_FAMILY_RS100;
407      break;
408
409   case PCI_CHIP_RS200_4137:
410   case PCI_CHIP_RS200_4337:
411   case PCI_CHIP_RS250_4237:
412   case PCI_CHIP_RS250_4437:
413      screen->chip_family = CHIP_FAMILY_RS200;
414      break;
415
416   case PCI_CHIP_RADEON_QD:
417   case PCI_CHIP_RADEON_QE:
418   case PCI_CHIP_RADEON_QF:
419   case PCI_CHIP_RADEON_QG:
420      /* all original radeons (7200) presumably have a stencil op bug */
421      screen->chip_family = CHIP_FAMILY_R100;
422      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL;
423      break;
424
425   case PCI_CHIP_RV200_QW:
426   case PCI_CHIP_RV200_QX:
427   case PCI_CHIP_RADEON_LW:
428   case PCI_CHIP_RADEON_LX:
429      screen->chip_family = CHIP_FAMILY_RV200;
430      screen->chip_flags = RADEON_CHIPSET_TCL;
431      break;
432
433#elif defined(RADEON_R200)
434   case PCI_CHIP_R200_BB:
435   case PCI_CHIP_R200_QH:
436   case PCI_CHIP_R200_QL:
437   case PCI_CHIP_R200_QM:
438      screen->chip_family = CHIP_FAMILY_R200;
439      screen->chip_flags = RADEON_CHIPSET_TCL;
440      break;
441
442   case PCI_CHIP_RV250_If:
443   case PCI_CHIP_RV250_Ig:
444   case PCI_CHIP_RV250_Ld:
445   case PCI_CHIP_RV250_Lf:
446   case PCI_CHIP_RV250_Lg:
447      screen->chip_family = CHIP_FAMILY_RV250;
448      screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL;
449      break;
450
451   case PCI_CHIP_RV280_4C6E:
452   case PCI_CHIP_RV280_5960:
453   case PCI_CHIP_RV280_5961:
454   case PCI_CHIP_RV280_5962:
455   case PCI_CHIP_RV280_5964:
456   case PCI_CHIP_RV280_5965:
457   case PCI_CHIP_RV280_5C61:
458   case PCI_CHIP_RV280_5C63:
459      screen->chip_family = CHIP_FAMILY_RV280;
460      screen->chip_flags = RADEON_CHIPSET_TCL;
461      break;
462
463   case PCI_CHIP_RS300_5834:
464   case PCI_CHIP_RS300_5835:
465   case PCI_CHIP_RS350_7834:
466   case PCI_CHIP_RS350_7835:
467      screen->chip_family = CHIP_FAMILY_RS300;
468      break;
469#endif
470
471   default:
472      fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
473	      device_id);
474      return -1;
475   }
476
477   return 0;
478}
479
480static radeonScreenPtr
481radeonCreateScreen2(__DRIscreen *sPriv)
482{
483   radeonScreenPtr screen;
484   int i;
485   int ret;
486   uint32_t device_id = 0;
487
488   /* Allocate the private area */
489   screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
490   if ( !screen ) {
491      fprintf(stderr, "%s: Could not allocate memory for screen structure", __FUNCTION__);
492      fprintf(stderr, "leaving here\n");
493      return NULL;
494   }
495
496   radeon_init_debug();
497
498   /* parse information in __driConfigOptions */
499   driParseOptionInfo (&screen->optionCache,
500		       __driConfigOptions, __driNConfigOptions);
501
502   screen->chip_flags = 0;
503
504   screen->irq = 1;
505
506   ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
507   if (ret) {
508     FREE( screen );
509     fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret);
510     return NULL;
511   }
512
513   ret = radeon_set_screen_flags(screen, device_id);
514   if (ret == -1)
515     return NULL;
516
517   if (getenv("R300_NO_TCL"))
518	   screen->chip_flags &= ~RADEON_CHIPSET_TCL;
519
520#if defined(RADEON_R100)
521   screen->chip_flags |= RADEON_CLASS_R100;
522#elif defined(RADEON_R200)
523   screen->chip_flags |= RADEON_CLASS_R200;
524#endif
525
526   i = 0;
527   screen->extensions[i++] = &dri2ConfigQueryExtension.base;
528
529#if defined(RADEON_R100)
530   screen->extensions[i++] = &radeonTexBufferExtension.base;
531#endif
532
533#if defined(RADEON_R200)
534   screen->extensions[i++] = &r200TexBufferExtension.base;
535#endif
536
537   screen->extensions[i++] = &radeonFlushExtension.base;
538   screen->extensions[i++] = &radeonImageExtension.base;
539
540   screen->extensions[i++] = NULL;
541   sPriv->extensions = screen->extensions;
542
543   screen->driScreen = sPriv;
544   screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
545   if (screen->bom == NULL) {
546       free(screen);
547       return NULL;
548   }
549   return screen;
550}
551
552/* Destroy the device specific screen private data struct.
553 */
554static void
555radeonDestroyScreen( __DRIscreen *sPriv )
556{
557    radeonScreenPtr screen = (radeonScreenPtr)sPriv->driverPrivate;
558
559    if (!screen)
560        return;
561
562#ifdef RADEON_BO_TRACK
563    radeon_tracker_print(&screen->bom->tracker, stderr);
564#endif
565    radeon_bo_manager_gem_dtor(screen->bom);
566
567    /* free all option information */
568    driDestroyOptionInfo (&screen->optionCache);
569
570    FREE( screen );
571    sPriv->driverPrivate = NULL;
572}
573
574
575/* Initialize the driver specific screen private data.
576 */
577static GLboolean
578radeonInitDriver( __DRIscreen *sPriv )
579{
580    sPriv->driverPrivate = (void *) radeonCreateScreen2( sPriv );
581    if ( !sPriv->driverPrivate ) {
582        radeonDestroyScreen( sPriv );
583        return GL_FALSE;
584    }
585
586    return GL_TRUE;
587}
588
589
590
591/**
592 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
593 *
594 * \todo This function (and its interface) will need to be updated to support
595 * pbuffers.
596 */
597static GLboolean
598radeonCreateBuffer( __DRIscreen *driScrnPriv,
599                    __DRIdrawable *driDrawPriv,
600                    const struct gl_config *mesaVis,
601                    GLboolean isPixmap )
602{
603    radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate;
604
605    const GLboolean swDepth = GL_FALSE;
606    const GLboolean swAlpha = GL_FALSE;
607    const GLboolean swAccum = mesaVis->accumRedBits > 0;
608    const GLboolean swStencil = mesaVis->stencilBits > 0 &&
609	mesaVis->depthBits != 24;
610    gl_format rgbFormat;
611    struct radeon_framebuffer *rfb;
612
613    if (isPixmap)
614      return GL_FALSE; /* not implemented */
615
616    rfb = CALLOC_STRUCT(radeon_framebuffer);
617    if (!rfb)
618      return GL_FALSE;
619
620    _mesa_initialize_window_framebuffer(&rfb->base, mesaVis);
621
622    if (mesaVis->redBits == 5)
623        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV;
624    else if (mesaVis->alphaBits == 0)
625        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_XRGB8888 : MESA_FORMAT_XRGB8888_REV;
626    else
627        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB8888_REV;
628
629    /* front color renderbuffer */
630    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
631    _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
632    rfb->color_rb[0]->has_surface = 1;
633
634    /* back color renderbuffer */
635    if (mesaVis->doubleBufferMode) {
636      rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
637	_mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
638	rfb->color_rb[1]->has_surface = 1;
639    }
640
641    if (mesaVis->depthBits == 24) {
642      if (mesaVis->stencilBits == 8) {
643	struct radeon_renderbuffer *depthStencilRb =
644           radeon_create_renderbuffer(MESA_FORMAT_S8_Z24, driDrawPriv);
645	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base);
646	_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base);
647	depthStencilRb->has_surface = screen->depthHasSurface;
648      } else {
649	/* depth renderbuffer */
650	struct radeon_renderbuffer *depth =
651           radeon_create_renderbuffer(MESA_FORMAT_X8_Z24, driDrawPriv);
652	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
653	depth->has_surface = screen->depthHasSurface;
654      }
655    } else if (mesaVis->depthBits == 16) {
656        /* just 16-bit depth buffer, no hw stencil */
657	struct radeon_renderbuffer *depth =
658           radeon_create_renderbuffer(MESA_FORMAT_Z16, driDrawPriv);
659	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
660	depth->has_surface = screen->depthHasSurface;
661    }
662
663    _mesa_add_soft_renderbuffers(&rfb->base,
664	    GL_FALSE, /* color */
665	    swDepth,
666	    swStencil,
667	    swAccum,
668	    swAlpha,
669	    GL_FALSE /* aux */);
670    driDrawPriv->driverPrivate = (void *) rfb;
671
672    return (driDrawPriv->driverPrivate != NULL);
673}
674
675
676static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb)
677{
678	struct radeon_renderbuffer *rb;
679
680	rb = rfb->color_rb[0];
681	if (rb && rb->bo) {
682		radeon_bo_unref(rb->bo);
683		rb->bo = NULL;
684	}
685	rb = rfb->color_rb[1];
686	if (rb && rb->bo) {
687		radeon_bo_unref(rb->bo);
688		rb->bo = NULL;
689	}
690	rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
691	if (rb && rb->bo) {
692		radeon_bo_unref(rb->bo);
693		rb->bo = NULL;
694	}
695}
696
697void
698radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
699{
700    struct radeon_framebuffer *rfb;
701    if (!driDrawPriv)
702	return;
703
704    rfb = (void*)driDrawPriv->driverPrivate;
705    if (!rfb)
706	return;
707    radeon_cleanup_renderbuffers(rfb);
708    _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
709}
710
711#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
712
713/**
714 * This is the driver specific part of the createNewScreen entry point.
715 * Called when using DRI2.
716 *
717 * \return the struct gl_config supported by this driver
718 */
719static const
720__DRIconfig **radeonInitScreen2(__DRIscreen *psp)
721{
722   GLenum fb_format[3];
723   GLenum fb_type[3];
724   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
725    * support pageflipping at all.
726    */
727   static const GLenum back_buffer_modes[] = {
728     GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
729   };
730   uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
731   int color;
732   __DRIconfig **configs = NULL;
733
734   if (!radeonInitDriver(psp)) {
735       return NULL;
736    }
737   depth_bits[0] = 0;
738   stencil_bits[0] = 0;
739   depth_bits[1] = 16;
740   stencil_bits[1] = 0;
741   depth_bits[2] = 24;
742   stencil_bits[2] = 0;
743   depth_bits[3] = 24;
744   stencil_bits[3] = 8;
745
746   msaa_samples_array[0] = 0;
747
748   fb_format[0] = GL_RGB;
749   fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
750
751   fb_format[1] = GL_BGR;
752   fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
753
754   fb_format[2] = GL_BGRA;
755   fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
756
757   for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
758      __DRIconfig **new_configs;
759
760      new_configs = driCreateConfigs(fb_format[color], fb_type[color],
761				     depth_bits,
762				     stencil_bits,
763				     ARRAY_SIZE(depth_bits),
764				     back_buffer_modes,
765				     ARRAY_SIZE(back_buffer_modes),
766				     msaa_samples_array,
767				     ARRAY_SIZE(msaa_samples_array),
768				     GL_TRUE);
769      if (configs == NULL)
770	 configs = new_configs;
771      else
772	 configs = driConcatConfigs(configs, new_configs);
773   }
774
775   if (configs == NULL) {
776      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
777              __LINE__);
778      return NULL;
779   }
780
781   return (const __DRIconfig **)configs;
782}
783
784const struct __DriverAPIRec driDriverAPI = {
785   .InitScreen      = radeonInitScreen2,
786   .DestroyScreen   = radeonDestroyScreen,
787#if defined(RADEON_R200)
788   .CreateContext   = r200CreateContext,
789   .DestroyContext  = r200DestroyContext,
790#else
791   .CreateContext   = r100CreateContext,
792   .DestroyContext  = radeonDestroyContext,
793#endif
794   .CreateBuffer    = radeonCreateBuffer,
795   .DestroyBuffer   = radeonDestroyBuffer,
796   .MakeCurrent     = radeonMakeCurrent,
797   .UnbindContext   = radeonUnbindContext,
798};
799
800/* This is the table of extensions that the loader will dlsym() for. */
801PUBLIC const __DRIextension *__driDriverExtensions[] = {
802    &driCoreExtension.base,
803    &driDRI2Extension.base,
804    NULL
805};
806