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