Home | History | Annotate | Download | only in r200
      1 /**************************************************************************
      2 
      3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
      4                      VA Linux Systems Inc., Fremont, California.
      5 
      6 All Rights Reserved.
      7 
      8 Permission is hereby granted, free of charge, to any person obtaining
      9 a copy of this software and associated documentation files (the
     10 "Software"), to deal in the Software without restriction, including
     11 without limitation the rights to use, copy, modify, merge, publish,
     12 distribute, sublicense, and/or sell copies of the Software, and to
     13 permit persons to whom the Software is furnished to do so, subject to
     14 the following conditions:
     15 
     16 The above copyright notice and this permission notice (including the
     17 next paragraph) shall be included in all copies or substantial
     18 portions of the Software.
     19 
     20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     26 WITH 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 (at) valinux.com>
     35  * \author  Gareth Hughes <gareth (at) 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) \
     70 DRI_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,"Grsse des Befehlspuffers (in KB)") \
     73 DRI_CONF_OPT_END
     74 
     75 #if defined(RADEON_R100)	/* R100 */
     76 PUBLIC const char __driConfigOptions[] =
     77 DRI_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
     99 DRI_CONF_END;
    100 static const GLuint __driNConfigOptions = 15;
    101 
    102 #elif defined(RADEON_R200)
    103 
    104 PUBLIC const char __driConfigOptions[] =
    105 DRI_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
    131 DRI_CONF_END;
    132 static const GLuint __driNConfigOptions = 17;
    133 
    134 #endif
    135 
    136 #ifndef RADEON_INFO_TILE_CONFIG
    137 #define RADEON_INFO_TILE_CONFIG 0x6
    138 #endif
    139 
    140 static int
    141 radeonGetParam(__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)
    176 static const __DRItexBufferExtension radeonTexBufferExtension = {
    177     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
    178    radeonSetTexBuffer,
    179    radeonSetTexBuffer2,
    180 };
    181 #elif defined(RADEON_R200)
    182 static const __DRItexBufferExtension r200TexBufferExtension = {
    183     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
    184    r200SetTexBuffer,
    185    r200SetTexBuffer2,
    186 };
    187 #endif
    188 
    189 static void
    190 radeonDRI2Flush(__DRIdrawable *drawable)
    191 {
    192     radeonContextPtr rmesa;
    193 
    194     rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate;
    195     radeonFlush(rmesa->glCtx);
    196 }
    197 
    198 static const struct __DRI2flushExtensionRec radeonFlushExtension = {
    199     { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
    200     radeonDRI2Flush,
    201     dri2InvalidateDrawable,
    202 };
    203 
    204 static __DRIimage *
    205 radeon_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 
    261 static __DRIimage *
    262 radeon_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 
    297 static void
    298 radeon_destroy_image(__DRIimage *image)
    299 {
    300    radeon_bo_unref(image->bo);
    301    FREE(image);
    302 }
    303 
    304 static __DRIimage *
    305 radeon_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 
    361 static GLboolean
    362 radeon_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 
    379 static 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 
    388 static 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 
    482 static radeonScreenPtr
    483 radeonCreateScreen2(__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  */
    548 static void
    549 radeonDestroyScreen( __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  */
    571 static GLboolean
    572 radeonInitDriver( __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  */
    591 static GLboolean
    592 radeonCreateBuffer( __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 
    670 static 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 
    691 void
    692 radeonDestroyBuffer(__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  */
    713 static 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 
    775 const 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. */
    792 PUBLIC const __DRIextension *__driDriverExtensions[] = {
    793     &driCoreExtension.base,
    794     &driDRI2Extension.base,
    795     NULL
    796 };
    797