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