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#include "radeon_chipset.h"
48#include "radeon_screen.h"
49#include "radeon_common.h"
50#include "radeon_common_context.h"
51#if defined(RADEON_R100)
52#include "radeon_context.h"
53#include "radeon_tex.h"
54#elif defined(RADEON_R200)
55#include "r200_context.h"
56#include "r200_tex.h"
57#endif
58
59#include "utils.h"
60
61#include "GL/internal/dri_interface.h"
62
63/* Radeon configuration
64 */
65#include "xmlpool.h"
66
67#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
68DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
69        DRI_CONF_DESC(en,"Size of command buffer (in KB)") \
70        DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
71DRI_CONF_OPT_END
72
73#if defined(RADEON_R100)	/* R100 */
74static const __DRIconfigOptionsExtension radeon_config_options = {
75   .base = { __DRI_CONFIG_OPTIONS, 1 },
76   .xml =
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_SECTION_END
95    DRI_CONF_SECTION_DEBUG
96        DRI_CONF_NO_RAST("false")
97    DRI_CONF_SECTION_END
98DRI_CONF_END
99};
100
101#elif defined(RADEON_R200)
102static const __DRIconfigOptionsExtension radeon_config_options = {
103   .base = { __DRI_CONFIG_OPTIONS, 1 },
104   .xml =
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_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
127DRI_CONF_END
128};
129#endif
130
131#ifndef RADEON_INFO_TILE_CONFIG
132#define RADEON_INFO_TILE_CONFIG 0x6
133#endif
134
135static int
136radeonGetParam(__DRIscreen *sPriv, int param, void *value)
137{
138  struct drm_radeon_info info = { 0 };
139
140  info.value = (uint64_t)(uintptr_t)value;
141  switch (param) {
142  case RADEON_PARAM_DEVICE_ID:
143    info.request = RADEON_INFO_DEVICE_ID;
144    break;
145  case RADEON_PARAM_NUM_GB_PIPES:
146    info.request = RADEON_INFO_NUM_GB_PIPES;
147    break;
148  case RADEON_PARAM_NUM_Z_PIPES:
149    info.request = RADEON_INFO_NUM_Z_PIPES;
150    break;
151  case RADEON_INFO_TILE_CONFIG:
152    info.request = RADEON_INFO_TILE_CONFIG;
153    break;
154  default:
155    return -EINVAL;
156  }
157  return drmCommandWriteRead(sPriv->fd, DRM_RADEON_INFO, &info, sizeof(info));
158}
159
160#if defined(RADEON_R100)
161static const __DRItexBufferExtension radeonTexBufferExtension = {
162   .base = { __DRI_TEX_BUFFER, 3 },
163
164   .setTexBuffer        = radeonSetTexBuffer,
165   .setTexBuffer2       = radeonSetTexBuffer2,
166   .releaseTexBuffer    = NULL,
167};
168#elif defined(RADEON_R200)
169static const __DRItexBufferExtension r200TexBufferExtension = {
170   .base = { __DRI_TEX_BUFFER, 3 },
171
172   .setTexBuffer        = r200SetTexBuffer,
173   .setTexBuffer2       = r200SetTexBuffer2,
174   .releaseTexBuffer    = NULL,
175};
176#endif
177
178static void
179radeonDRI2Flush(__DRIdrawable *drawable)
180{
181    radeonContextPtr rmesa;
182
183    rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate;
184    radeonFlush(&rmesa->glCtx);
185}
186
187static const struct __DRI2flushExtensionRec radeonFlushExtension = {
188   .base = { __DRI2_FLUSH, 3 },
189
190   .flush               = radeonDRI2Flush,
191   .invalidate          = dri2InvalidateDrawable,
192};
193
194static __DRIimage *
195radeon_create_image_from_name(__DRIscreen *screen,
196                              int width, int height, int format,
197                              int name, int pitch, void *loaderPrivate)
198{
199   __DRIimage *image;
200   radeonScreenPtr radeonScreen = screen->driverPrivate;
201
202   if (name == 0)
203      return NULL;
204
205   image = calloc(1, sizeof *image);
206   if (image == NULL)
207      return NULL;
208
209   switch (format) {
210   case __DRI_IMAGE_FORMAT_RGB565:
211      image->format = MESA_FORMAT_B5G6R5_UNORM;
212      image->internal_format = GL_RGB;
213      image->data_type = GL_UNSIGNED_BYTE;
214      break;
215   case __DRI_IMAGE_FORMAT_XRGB8888:
216      image->format = MESA_FORMAT_B8G8R8X8_UNORM;
217      image->internal_format = GL_RGB;
218      image->data_type = GL_UNSIGNED_BYTE;
219      break;
220   case __DRI_IMAGE_FORMAT_ARGB8888:
221      image->format = MESA_FORMAT_B8G8R8A8_UNORM;
222      image->internal_format = GL_RGBA;
223      image->data_type = GL_UNSIGNED_BYTE;
224      break;
225   default:
226      free(image);
227      return NULL;
228   }
229
230   image->data = loaderPrivate;
231   image->cpp = _mesa_get_format_bytes(image->format);
232   image->width = width;
233   image->pitch = pitch;
234   image->height = height;
235
236   image->bo = radeon_bo_open(radeonScreen->bom,
237                              (uint32_t)name,
238                              image->pitch * image->height * image->cpp,
239                              0,
240                              RADEON_GEM_DOMAIN_VRAM,
241                              0);
242
243   if (image->bo == NULL) {
244      free(image);
245      return NULL;
246   }
247
248   return image;
249}
250
251static __DRIimage *
252radeon_create_image_from_renderbuffer(__DRIcontext *context,
253                                      int renderbuffer, void *loaderPrivate)
254{
255   __DRIimage *image;
256   radeonContextPtr radeon = context->driverPrivate;
257   struct gl_renderbuffer *rb;
258   struct radeon_renderbuffer *rrb;
259
260   rb = _mesa_lookup_renderbuffer(&radeon->glCtx, renderbuffer);
261   if (!rb) {
262      _mesa_error(&radeon->glCtx,
263                  GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
264      return NULL;
265   }
266
267   rrb = radeon_renderbuffer(rb);
268   image = calloc(1, sizeof *image);
269   if (image == NULL)
270      return NULL;
271
272   image->internal_format = rb->InternalFormat;
273   image->format = rb->Format;
274   image->cpp = rrb->cpp;
275   image->data_type = GL_UNSIGNED_BYTE;
276   image->data = loaderPrivate;
277   radeon_bo_ref(rrb->bo);
278   image->bo = rrb->bo;
279
280   image->width = rb->Width;
281   image->height = rb->Height;
282   image->pitch = rrb->pitch / image->cpp;
283
284   return image;
285}
286
287static void
288radeon_destroy_image(__DRIimage *image)
289{
290   radeon_bo_unref(image->bo);
291   free(image);
292}
293
294static __DRIimage *
295radeon_create_image(__DRIscreen *screen,
296                    int width, int height, int format,
297                    unsigned int use,
298                    void *loaderPrivate)
299{
300   __DRIimage *image;
301   radeonScreenPtr radeonScreen = screen->driverPrivate;
302
303   image = calloc(1, sizeof *image);
304   if (image == NULL)
305      return NULL;
306
307   image->dri_format = format;
308
309   switch (format) {
310   case __DRI_IMAGE_FORMAT_RGB565:
311      image->format = MESA_FORMAT_B5G6R5_UNORM;
312      image->internal_format = GL_RGB;
313      image->data_type = GL_UNSIGNED_BYTE;
314      break;
315   case __DRI_IMAGE_FORMAT_XRGB8888:
316      image->format = MESA_FORMAT_B8G8R8X8_UNORM;
317      image->internal_format = GL_RGB;
318      image->data_type = GL_UNSIGNED_BYTE;
319      break;
320   case __DRI_IMAGE_FORMAT_ARGB8888:
321      image->format = MESA_FORMAT_B8G8R8A8_UNORM;
322      image->internal_format = GL_RGBA;
323      image->data_type = GL_UNSIGNED_BYTE;
324      break;
325   default:
326      free(image);
327      return NULL;
328   }
329
330   image->data = loaderPrivate;
331   image->cpp = _mesa_get_format_bytes(image->format);
332   image->width = width;
333   image->height = height;
334   image->pitch = ((image->cpp * image->width + 255) & ~255) / image->cpp;
335
336   image->bo = radeon_bo_open(radeonScreen->bom,
337                              0,
338                              image->pitch * image->height * image->cpp,
339                              0,
340                              RADEON_GEM_DOMAIN_VRAM,
341                              0);
342
343   if (image->bo == NULL) {
344      free(image);
345      return NULL;
346   }
347
348   return image;
349}
350
351static GLboolean
352radeon_query_image(__DRIimage *image, int attrib, int *value)
353{
354   switch (attrib) {
355   case __DRI_IMAGE_ATTRIB_STRIDE:
356      *value = image->pitch * image->cpp;
357      return GL_TRUE;
358   case __DRI_IMAGE_ATTRIB_HANDLE:
359      *value = image->bo->handle;
360      return GL_TRUE;
361   case __DRI_IMAGE_ATTRIB_NAME:
362      radeon_gem_get_kernel_name(image->bo, (uint32_t *) value);
363      return GL_TRUE;
364   default:
365      return GL_FALSE;
366   }
367}
368
369static const __DRIimageExtension radeonImageExtension = {
370   .base = { __DRI_IMAGE, 1 },
371
372   .createImageFromName         = radeon_create_image_from_name,
373   .createImageFromRenderbuffer = radeon_create_image_from_renderbuffer,
374   .destroyImage                = radeon_destroy_image,
375   .createImage                 = radeon_create_image,
376   .queryImage                  = radeon_query_image
377};
378
379static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
380{
381   screen->device_id = device_id;
382   screen->chip_flags = 0;
383   switch ( device_id ) {
384#if defined(RADEON_R100)
385   case PCI_CHIP_RN50_515E:
386   case PCI_CHIP_RN50_5969:
387	return -1;
388
389   case PCI_CHIP_RADEON_LY:
390   case PCI_CHIP_RADEON_LZ:
391   case PCI_CHIP_RADEON_QY:
392   case PCI_CHIP_RADEON_QZ:
393      screen->chip_family = CHIP_FAMILY_RV100;
394      break;
395
396   case PCI_CHIP_RS100_4136:
397   case PCI_CHIP_RS100_4336:
398      screen->chip_family = CHIP_FAMILY_RS100;
399      break;
400
401   case PCI_CHIP_RS200_4137:
402   case PCI_CHIP_RS200_4337:
403   case PCI_CHIP_RS250_4237:
404   case PCI_CHIP_RS250_4437:
405      screen->chip_family = CHIP_FAMILY_RS200;
406      break;
407
408   case PCI_CHIP_RADEON_QD:
409   case PCI_CHIP_RADEON_QE:
410   case PCI_CHIP_RADEON_QF:
411   case PCI_CHIP_RADEON_QG:
412      /* all original radeons (7200) presumably have a stencil op bug */
413      screen->chip_family = CHIP_FAMILY_R100;
414      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
415      break;
416
417   case PCI_CHIP_RV200_QW:
418   case PCI_CHIP_RV200_QX:
419   case PCI_CHIP_RADEON_LW:
420   case PCI_CHIP_RADEON_LX:
421      screen->chip_family = CHIP_FAMILY_RV200;
422      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
423      break;
424
425#elif defined(RADEON_R200)
426   case PCI_CHIP_R200_BB:
427   case PCI_CHIP_R200_QH:
428   case PCI_CHIP_R200_QL:
429   case PCI_CHIP_R200_QM:
430      screen->chip_family = CHIP_FAMILY_R200;
431      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
432      break;
433
434   case PCI_CHIP_RV250_If:
435   case PCI_CHIP_RV250_Ig:
436   case PCI_CHIP_RV250_Ld:
437   case PCI_CHIP_RV250_Lf:
438   case PCI_CHIP_RV250_Lg:
439      screen->chip_family = CHIP_FAMILY_RV250;
440      screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
441      break;
442
443   case PCI_CHIP_RV280_4C6E:
444   case PCI_CHIP_RV280_5960:
445   case PCI_CHIP_RV280_5961:
446   case PCI_CHIP_RV280_5962:
447   case PCI_CHIP_RV280_5964:
448   case PCI_CHIP_RV280_5965:
449   case PCI_CHIP_RV280_5C61:
450   case PCI_CHIP_RV280_5C63:
451      screen->chip_family = CHIP_FAMILY_RV280;
452      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
453      break;
454
455   case PCI_CHIP_RS300_5834:
456   case PCI_CHIP_RS300_5835:
457   case PCI_CHIP_RS350_7834:
458   case PCI_CHIP_RS350_7835:
459      screen->chip_family = CHIP_FAMILY_RS300;
460      screen->chip_flags = RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
461      break;
462#endif
463
464   default:
465      fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
466	      device_id);
467      return -1;
468   }
469
470   return 0;
471}
472
473static int
474radeonQueryRendererInteger(__DRIscreen *psp, int param,
475			       unsigned int *value)
476{
477   radeonScreenPtr screen = (radeonScreenPtr)psp->driverPrivate;
478
479   switch (param) {
480   case __DRI2_RENDERER_VENDOR_ID:
481      value[0] = 0x1002;
482      return 0;
483   case __DRI2_RENDERER_DEVICE_ID:
484      value[0] = screen->device_id;
485      return 0;
486   case __DRI2_RENDERER_ACCELERATED:
487      value[0] = 1;
488      return 0;
489   case __DRI2_RENDERER_VIDEO_MEMORY: {
490      struct drm_radeon_gem_info gem_info;
491      int retval;
492      memset(&gem_info, 0, sizeof(gem_info));
493
494      /* Get GEM info. */
495      retval = drmCommandWriteRead(psp->fd, DRM_RADEON_GEM_INFO, &gem_info,
496				   sizeof(gem_info));
497
498      if (retval) {
499         fprintf(stderr, "radeon: Failed to get MM info, error number %d\n",
500                retval);
501         return -1;
502
503      }
504      /* XXX: Do we want to return vram_size or vram_visible ? */
505      value[0] = gem_info.vram_size >> 20;
506      return 0;
507   }
508   case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE:
509      value[0] = 0;
510      return 0;
511   default:
512      return driQueryRendererIntegerCommon(psp, param, value);
513   }
514}
515
516static int
517radeonQueryRendererString(__DRIscreen *psp, int param, const char **value)
518{
519   radeonScreenPtr screen = (radeonScreenPtr)psp->driverPrivate;
520
521   switch (param) {
522   case __DRI2_RENDERER_VENDOR_ID:
523      value[0] = radeonVendorString;
524      return 0;
525   case __DRI2_RENDERER_DEVICE_ID:
526      value[0] = radeonGetRendererString(screen);
527      return 0;
528   default:
529      return -1;
530   }
531}
532
533static const __DRI2rendererQueryExtension radeonRendererQueryExtension = {
534   .base = { __DRI2_RENDERER_QUERY, 1 },
535
536   .queryInteger        = radeonQueryRendererInteger,
537   .queryString         = radeonQueryRendererString
538};
539
540
541static const __DRIextension *radeon_screen_extensions[] = {
542    &dri2ConfigQueryExtension.base,
543#if defined(RADEON_R100)
544    &radeonTexBufferExtension.base,
545#elif defined(RADEON_R200)
546    &r200TexBufferExtension.base,
547#endif
548    &radeonFlushExtension.base,
549    &radeonImageExtension.base,
550    &radeonRendererQueryExtension.base,
551    NULL
552};
553
554static radeonScreenPtr
555radeonCreateScreen2(__DRIscreen *sPriv)
556{
557   radeonScreenPtr screen;
558   int ret;
559   uint32_t device_id = 0;
560
561   /* Allocate the private area */
562   screen = calloc(1, sizeof(*screen));
563   if ( !screen ) {
564      fprintf(stderr, "%s: Could not allocate memory for screen structure", __func__);
565      fprintf(stderr, "leaving here\n");
566      return NULL;
567   }
568
569   radeon_init_debug();
570
571   /* parse information in __driConfigOptions */
572   driParseOptionInfo (&screen->optionCache, radeon_config_options.xml);
573
574   screen->chip_flags = 0;
575
576   screen->irq = 1;
577
578   ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
579   if (ret) {
580     free( screen );
581     fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret);
582     return NULL;
583   }
584
585   ret = radeon_set_screen_flags(screen, device_id);
586   if (ret == -1) {
587     free(screen);
588     return NULL;
589   }
590
591   if (getenv("RADEON_NO_TCL"))
592	   screen->chip_flags &= ~RADEON_CHIPSET_TCL;
593
594   sPriv->extensions = radeon_screen_extensions;
595
596   screen->driScreen = sPriv;
597   screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
598   if (screen->bom == NULL) {
599       free(screen);
600       return NULL;
601   }
602   return screen;
603}
604
605/* Destroy the device specific screen private data struct.
606 */
607static void
608radeonDestroyScreen( __DRIscreen *sPriv )
609{
610    radeonScreenPtr screen = (radeonScreenPtr)sPriv->driverPrivate;
611
612    if (!screen)
613        return;
614
615#ifdef RADEON_BO_TRACK
616    radeon_tracker_print(&screen->bom->tracker, stderr);
617#endif
618    radeon_bo_manager_gem_dtor(screen->bom);
619
620    /* free all option information */
621    driDestroyOptionInfo (&screen->optionCache);
622
623    free( screen );
624    sPriv->driverPrivate = NULL;
625}
626
627
628/* Initialize the driver specific screen private data.
629 */
630static GLboolean
631radeonInitDriver( __DRIscreen *sPriv )
632{
633    sPriv->driverPrivate = (void *) radeonCreateScreen2( sPriv );
634    if ( !sPriv->driverPrivate ) {
635        radeonDestroyScreen( sPriv );
636        return GL_FALSE;
637    }
638
639    return GL_TRUE;
640}
641
642
643
644/**
645 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
646 *
647 * \todo This function (and its interface) will need to be updated to support
648 * pbuffers.
649 */
650static GLboolean
651radeonCreateBuffer( __DRIscreen *driScrnPriv,
652                    __DRIdrawable *driDrawPriv,
653                    const struct gl_config *mesaVis,
654                    GLboolean isPixmap )
655{
656    radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate;
657
658    const GLboolean swDepth = GL_FALSE;
659    const GLboolean swAlpha = GL_FALSE;
660    const GLboolean swAccum = mesaVis->accumRedBits > 0;
661    const GLboolean swStencil = mesaVis->stencilBits > 0 &&
662	mesaVis->depthBits != 24;
663    mesa_format rgbFormat;
664    struct radeon_framebuffer *rfb;
665
666    if (isPixmap)
667      return GL_FALSE; /* not implemented */
668
669    rfb = CALLOC_STRUCT(radeon_framebuffer);
670    if (!rfb)
671      return GL_FALSE;
672
673    _mesa_initialize_window_framebuffer(&rfb->base, mesaVis);
674
675    if (mesaVis->redBits == 5)
676        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B5G6R5_UNORM : MESA_FORMAT_R5G6B5_UNORM;
677    else if (mesaVis->alphaBits == 0)
678        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8X8_UNORM : MESA_FORMAT_X8R8G8B8_UNORM;
679    else
680        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8A8_UNORM : MESA_FORMAT_A8R8G8B8_UNORM;
681
682    /* front color renderbuffer */
683    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
684    _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base.Base);
685    rfb->color_rb[0]->has_surface = 1;
686
687    /* back color renderbuffer */
688    if (mesaVis->doubleBufferMode) {
689      rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
690	_mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base.Base);
691	rfb->color_rb[1]->has_surface = 1;
692    }
693
694    if (mesaVis->depthBits == 24) {
695      if (mesaVis->stencilBits == 8) {
696	struct radeon_renderbuffer *depthStencilRb =
697           radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT, driDrawPriv);
698	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base.Base);
699	_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base.Base);
700	depthStencilRb->has_surface = screen->depthHasSurface;
701      } else {
702	/* depth renderbuffer */
703	struct radeon_renderbuffer *depth =
704           radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT, driDrawPriv);
705	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base.Base);
706	depth->has_surface = screen->depthHasSurface;
707      }
708    } else if (mesaVis->depthBits == 16) {
709        /* just 16-bit depth buffer, no hw stencil */
710	struct radeon_renderbuffer *depth =
711           radeon_create_renderbuffer(MESA_FORMAT_Z_UNORM16, driDrawPriv);
712	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base.Base);
713	depth->has_surface = screen->depthHasSurface;
714    }
715
716    _swrast_add_soft_renderbuffers(&rfb->base,
717	    GL_FALSE, /* color */
718	    swDepth,
719	    swStencil,
720	    swAccum,
721	    swAlpha,
722	    GL_FALSE /* aux */);
723    driDrawPriv->driverPrivate = (void *) rfb;
724
725    return (driDrawPriv->driverPrivate != NULL);
726}
727
728
729static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb)
730{
731	struct radeon_renderbuffer *rb;
732
733	rb = rfb->color_rb[0];
734	if (rb && rb->bo) {
735		radeon_bo_unref(rb->bo);
736		rb->bo = NULL;
737	}
738	rb = rfb->color_rb[1];
739	if (rb && rb->bo) {
740		radeon_bo_unref(rb->bo);
741		rb->bo = NULL;
742	}
743	rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
744	if (rb && rb->bo) {
745		radeon_bo_unref(rb->bo);
746		rb->bo = NULL;
747	}
748}
749
750void
751radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
752{
753    struct radeon_framebuffer *rfb;
754    if (!driDrawPriv)
755	return;
756
757    rfb = (void*)driDrawPriv->driverPrivate;
758    if (!rfb)
759	return;
760    radeon_cleanup_renderbuffers(rfb);
761    _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
762}
763
764/**
765 * This is the driver specific part of the createNewScreen entry point.
766 * Called when using DRI2.
767 *
768 * \return the struct gl_config supported by this driver
769 */
770static const
771__DRIconfig **radeonInitScreen2(__DRIscreen *psp)
772{
773   static const mesa_format formats[3] = {
774      MESA_FORMAT_B5G6R5_UNORM,
775      MESA_FORMAT_B8G8R8X8_UNORM,
776      MESA_FORMAT_B8G8R8A8_UNORM
777   };
778   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
779    * support pageflipping at all.
780    */
781   static const GLenum back_buffer_modes[] = {
782     GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
783   };
784   uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
785   int color;
786   __DRIconfig **configs = NULL;
787
788   psp->max_gl_compat_version = 13;
789   psp->max_gl_es1_version = 11;
790
791   if (!radeonInitDriver(psp)) {
792       return NULL;
793    }
794   depth_bits[0] = 0;
795   stencil_bits[0] = 0;
796   depth_bits[1] = 16;
797   stencil_bits[1] = 0;
798   depth_bits[2] = 24;
799   stencil_bits[2] = 0;
800   depth_bits[3] = 24;
801   stencil_bits[3] = 8;
802
803   msaa_samples_array[0] = 0;
804
805   for (color = 0; color < ARRAY_SIZE(formats); color++) {
806      __DRIconfig **new_configs;
807
808      new_configs = driCreateConfigs(formats[color],
809				     depth_bits,
810				     stencil_bits,
811				     ARRAY_SIZE(depth_bits),
812				     back_buffer_modes,
813				     ARRAY_SIZE(back_buffer_modes),
814				     msaa_samples_array,
815				     ARRAY_SIZE(msaa_samples_array),
816				     GL_TRUE, GL_FALSE);
817      configs = driConcatConfigs(configs, new_configs);
818   }
819
820   if (configs == NULL) {
821      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
822              __LINE__);
823      return NULL;
824   }
825
826   return (const __DRIconfig **)configs;
827}
828
829static const struct __DriverAPIRec radeon_driver_api = {
830   .InitScreen      = radeonInitScreen2,
831   .DestroyScreen   = radeonDestroyScreen,
832#if defined(RADEON_R200)
833   .CreateContext   = r200CreateContext,
834   .DestroyContext  = r200DestroyContext,
835#else
836   .CreateContext   = r100CreateContext,
837   .DestroyContext  = radeonDestroyContext,
838#endif
839   .CreateBuffer    = radeonCreateBuffer,
840   .DestroyBuffer   = radeonDestroyBuffer,
841   .MakeCurrent     = radeonMakeCurrent,
842   .UnbindContext   = radeonUnbindContext,
843};
844
845static const struct __DRIDriverVtableExtensionRec radeon_vtable = {
846   .base = { __DRI_DRIVER_VTABLE, 1 },
847   .vtable = &radeon_driver_api,
848};
849
850/* This is the table of extensions that the loader will dlsym() for. */
851static const __DRIextension *radeon_driver_extensions[] = {
852    &driCoreExtension.base,
853    &driDRI2Extension.base,
854    &radeon_config_options.base,
855    &radeon_vtable.base,
856    NULL
857};
858
859#ifdef RADEON_R200
860PUBLIC const __DRIextension **__driDriverGetExtensions_r200(void)
861{
862   globalDriverAPI = &radeon_driver_api;
863
864   return radeon_driver_extensions;
865}
866#else
867PUBLIC const __DRIextension **__driDriverGetExtensions_radeon(void)
868{
869   globalDriverAPI = &radeon_driver_api;
870
871   return radeon_driver_extensions;
872}
873#endif
874