Merge branch 'mesa_7_5_branch'
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_screen.c
index 497582ee2325b56dd44024ad3b9e0132d92a48df..290ef2394de0fed935ec3b545f2c2ac86fa2b280 100644 (file)
@@ -46,8 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_chipset.h"
 #include "radeon_macros.h"
 #include "radeon_screen.h"
-#include "radeon_buffer.h"
-#include "common_misc.h"
+#include "radeon_common.h"
 #include "radeon_span.h"
 #if !RADEON_COMMON
 #include "radeon_context.h"
@@ -60,19 +59,23 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_context.h"
 #include "r300_fragprog.h"
 #include "r300_tex.h"
+#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+#include "r600_context.h"
+#include "r700_driconf.h" /* +r6/r7 */
+#include "r600_tex.h"     /* +r6/r7 */
 #endif
 
 #include "utils.h"
 #include "vblank.h"
 #include "drirenderbuffer.h"
 
+#include "radeon_bocs_wrapper.h"
+
 #include "GL/internal/dri_interface.h"
 
 /* Radeon configuration
  */
 #include "xmlpool.h"
-#include "radeon_bo_legacy.h"
-#include "radeon_bo_gem.h"
 
 #define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
 DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
@@ -145,7 +148,7 @@ extern const struct dri_extension NV_vp_extension[];
 extern const struct dri_extension ATI_fs_extension[];
 extern const struct dri_extension point_extensions[];
 
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+#elif RADEON_COMMON && (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600))
 
 /* TODO: integrate these into xmlpool.h! */
 #define DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(def,min,max) \
@@ -213,6 +216,8 @@ DRI_CONF_BEGIN
 DRI_CONF_END;
 static const GLuint __driNConfigOptions = 17;
 
+extern const struct dri_extension gl_20_extension[];
+
 #ifndef RADEON_DEBUG
 
 static const struct dri_debug_control debug_control[] = {
@@ -240,19 +245,36 @@ static const struct dri_debug_control debug_control[] = {
 #endif /* RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) */
 
 extern const struct dri_extension card_extensions[];
+extern const struct dri_extension mm_extensions[];
 
 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
 
 static int
-radeonGetParam(int fd, int param, void *value)
+radeonGetParam(__DRIscreenPrivate *sPriv, int param, void *value)
 {
   int ret;
-  drm_radeon_getparam_t gp;
-
-  gp.param = param;
-  gp.value = value;
+  drm_radeon_getparam_t gp = { 0 };
+  struct drm_radeon_info info = { 0 };
+
+  if (sPriv->drm_version.major >= 2) {
+      info.value = (uint64_t)value;
+      switch (param) {
+      case RADEON_PARAM_DEVICE_ID:
+          info.request = RADEON_INFO_DEVICE_ID;
+          break;
+      case RADEON_PARAM_NUM_GB_PIPES:
+          info.request = RADEON_INFO_NUM_GB_PIPES;
+          break;
+      default:
+          return -EINVAL;
+      }
+      ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_INFO, &info, sizeof(info));
+  } else {
+      gp.param = param;
+      gp.value = value;
 
-  ret = drmCommandWriteRead( fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
+      ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
+  }
   return ret;
 }
 
@@ -265,8 +287,6 @@ radeonFillInModes( __DRIscreenPrivate *psp,
     __GLcontextModes *m;
     unsigned depth_buffer_factor;
     unsigned back_buffer_factor;
-    GLenum fb_format;
-    GLenum fb_type;
     int i;
 
     /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
@@ -280,7 +300,7 @@ radeonFillInModes( __DRIscreenPrivate *psp,
 
     uint8_t depth_bits_array[2];
     uint8_t stencil_bits_array[2];
-
+    uint8_t msaa_samples_array[1];
 
     depth_bits_array[0] = depth_bits;
     depth_bits_array[1] = depth_bits;
@@ -289,25 +309,35 @@ radeonFillInModes( __DRIscreenPrivate *psp,
      * with a stencil buffer.  It will be a sw fallback, but some apps won't
      * care about that.
      */
-    stencil_bits_array[0] = 0;
+    stencil_bits_array[0] = stencil_bits;
     stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
 
-    depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
+    msaa_samples_array[0] = 0;
+
+    depth_buffer_factor = (stencil_bits == 0) ? 2 : 1;
     back_buffer_factor  = (have_back_buffer) ? 2 : 1;
 
-    if ( pixel_bits == 16 ) {
-        fb_format = GL_RGB;
-        fb_type = GL_UNSIGNED_SHORT_5_6_5;
-    }
-    else {
-        fb_format = GL_BGRA;
-        fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-    }
+    if (pixel_bits == 16) {
+       __DRIconfig **configs_a8r8g8b8;
+       __DRIconfig **configs_r5g6b5;
+
+       configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+                                         depth_bits_array, stencil_bits_array,
+                                         depth_buffer_factor, back_buffer_modes,
+                                         back_buffer_factor, msaa_samples_array,
+                                         1);
+       configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+                                           depth_bits_array, stencil_bits_array,
+                                           1, back_buffer_modes, 1,
+                                           msaa_samples_array, 1);
+       configs = driConcatConfigs(configs_r5g6b5, configs_a8r8g8b8);
+   } else
+       configs = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+                                  depth_bits_array, stencil_bits_array,
+                                  depth_buffer_factor,
+                                  back_buffer_modes, back_buffer_factor,
+                                  msaa_samples_array, 1);
 
-    configs = driCreateConfigs(fb_format, fb_type,
-                              depth_bits_array, stencil_bits_array,
-                              depth_buffer_factor,
-                              back_buffer_modes, back_buffer_factor);
     if (configs == NULL) {
        fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
                 __func__, __LINE__ );
@@ -331,6 +361,12 @@ static const __DRItexOffsetExtension radeonTexOffsetExtension = {
     { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
     radeonSetTexOffset,
 };
+
+static const __DRItexBufferExtension radeonTexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+   radeonSetTexBuffer,
+   radeonSetTexBuffer2,
+};
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
@@ -345,6 +381,12 @@ static const __DRItexOffsetExtension r200texOffsetExtension = {
     { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
    r200SetTexOffset,
 };
+
+static const __DRItexBufferExtension r200TexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+   r200SetTexBuffer,
+   r200SetTexBuffer2,
+};
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
@@ -353,17 +395,29 @@ static const __DRItexOffsetExtension r300texOffsetExtension = {
    r300SetTexOffset,
 };
 
-void r300SetTexBuffer(__DRIcontext *pDRICtx,
-                      GLint target,
-                      __DRIdrawable *dPriv);
 static const __DRItexBufferExtension r300TexBufferExtension = {
     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
    r300SetTexBuffer,
+   r300SetTexBuffer2,
 };
 #endif
 
-int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+static const __DRItexOffsetExtension r600texOffsetExtension = {
+    { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
+   r600SetTexOffset, /* +r6/r7 */
+};
+
+static const __DRItexBufferExtension r600TexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+   r600SetTexBuffer,  /* +r6/r7 */
+   r600SetTexBuffer2, /* +r6/r7 */
+};
+#endif
+
+static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
 {
+   screen->device_id = device_id;
    screen->chip_flags = 0;
    switch ( device_id ) {
    case PCI_CHIP_RADEON_LY:
@@ -440,11 +494,7 @@ int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
       screen->chip_family = CHIP_FAMILY_RS300;
       break;
 
-      /* 9500 with 1 pipe verified by: Reid Linnemann <lreid@cs.okstate.edu> */
    case PCI_CHIP_R300_AD:
-      screen->chip_family = CHIP_FAMILY_RV350;
-      screen->chip_flags = RADEON_CHIPSET_TCL;
-      break;
    case PCI_CHIP_R300_AE:
    case PCI_CHIP_R300_AF:
    case PCI_CHIP_R300_AG:
@@ -569,6 +619,12 @@ int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
       screen->chip_family = CHIP_FAMILY_RS400;
       break;
 
+   case PCI_CHIP_RS600_793F:
+   case PCI_CHIP_RS600_7941:
+   case PCI_CHIP_RS600_7942:
+      screen->chip_family = CHIP_FAMILY_RS600;
+      break;
+
    case PCI_CHIP_RS690_791E:
    case PCI_CHIP_RS690_791F:
       screen->chip_family = CHIP_FAMILY_RS690;
@@ -695,6 +751,165 @@ int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
       screen->chip_flags = RADEON_CHIPSET_TCL;
       break;
 
+   case PCI_CHIP_R600_9400:
+   case PCI_CHIP_R600_9401:
+   case PCI_CHIP_R600_9402:
+   case PCI_CHIP_R600_9403:
+   case PCI_CHIP_R600_9405:
+   case PCI_CHIP_R600_940A:
+   case PCI_CHIP_R600_940B:
+   case PCI_CHIP_R600_940F:
+      screen->chip_family = CHIP_FAMILY_R600;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV610_94C0:
+   case PCI_CHIP_RV610_94C1:
+   case PCI_CHIP_RV610_94C3:
+   case PCI_CHIP_RV610_94C4:
+   case PCI_CHIP_RV610_94C5:
+   case PCI_CHIP_RV610_94C6:
+   case PCI_CHIP_RV610_94C7:
+   case PCI_CHIP_RV610_94C8:
+   case PCI_CHIP_RV610_94C9:
+   case PCI_CHIP_RV610_94CB:
+   case PCI_CHIP_RV610_94CC:
+   case PCI_CHIP_RV610_94CD:
+      screen->chip_family = CHIP_FAMILY_RV610;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV630_9580:
+   case PCI_CHIP_RV630_9581:
+   case PCI_CHIP_RV630_9583:
+   case PCI_CHIP_RV630_9586:
+   case PCI_CHIP_RV630_9587:
+   case PCI_CHIP_RV630_9588:
+   case PCI_CHIP_RV630_9589:
+   case PCI_CHIP_RV630_958A:
+   case PCI_CHIP_RV630_958B:
+   case PCI_CHIP_RV630_958C:
+   case PCI_CHIP_RV630_958D:
+   case PCI_CHIP_RV630_958E:
+   case PCI_CHIP_RV630_958F:
+      screen->chip_family = CHIP_FAMILY_RV630;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV670_9500:
+   case PCI_CHIP_RV670_9501:
+   case PCI_CHIP_RV670_9504:
+   case PCI_CHIP_RV670_9505:
+   case PCI_CHIP_RV670_9506:
+   case PCI_CHIP_RV670_9507:
+   case PCI_CHIP_RV670_9508:
+   case PCI_CHIP_RV670_9509:
+   case PCI_CHIP_RV670_950F:
+   case PCI_CHIP_RV670_9511:
+   case PCI_CHIP_RV670_9515:
+   case PCI_CHIP_RV670_9517:
+   case PCI_CHIP_RV670_9519:
+      screen->chip_family = CHIP_FAMILY_RV670;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV620_95C0:
+   case PCI_CHIP_RV620_95C2:
+   case PCI_CHIP_RV620_95C4:
+   case PCI_CHIP_RV620_95C5:
+   case PCI_CHIP_RV620_95C6:
+   case PCI_CHIP_RV620_95C7:
+   case PCI_CHIP_RV620_95C9:
+   case PCI_CHIP_RV620_95CC:
+   case PCI_CHIP_RV620_95CD:
+   case PCI_CHIP_RV620_95CE:
+   case PCI_CHIP_RV620_95CF:
+      screen->chip_family = CHIP_FAMILY_RV620;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV635_9590:
+   case PCI_CHIP_RV635_9591:
+   case PCI_CHIP_RV635_9593:
+   case PCI_CHIP_RV635_9595:
+   case PCI_CHIP_RV635_9596:
+   case PCI_CHIP_RV635_9597:
+   case PCI_CHIP_RV635_9598:
+   case PCI_CHIP_RV635_9599:
+   case PCI_CHIP_RV635_959B:
+      screen->chip_family = CHIP_FAMILY_RV635;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RS780_9610:
+   case PCI_CHIP_RS780_9611:
+   case PCI_CHIP_RS780_9612:
+   case PCI_CHIP_RS780_9613:
+   case PCI_CHIP_RS780_9614:
+   case PCI_CHIP_RS780_9615:
+   case PCI_CHIP_RS780_9616:
+      screen->chip_family = CHIP_FAMILY_RS780;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV770_9440:
+   case PCI_CHIP_RV770_9441:
+   case PCI_CHIP_RV770_9442:
+   case PCI_CHIP_RV770_9444:
+   case PCI_CHIP_RV770_9446:
+   case PCI_CHIP_RV770_944A:
+   case PCI_CHIP_RV770_944B:
+   case PCI_CHIP_RV770_944C:
+   case PCI_CHIP_RV770_944E:
+   case PCI_CHIP_RV770_9450:
+   case PCI_CHIP_RV770_9452:
+   case PCI_CHIP_RV770_9456:
+   case PCI_CHIP_RV770_945A:
+   case PCI_CHIP_RV770_945B:
+   case PCI_CHIP_RV790_9460:
+   case PCI_CHIP_RV790_9462:
+   case PCI_CHIP_RV770_946A:
+   case PCI_CHIP_RV770_946B:
+   case PCI_CHIP_RV770_947A:
+   case PCI_CHIP_RV770_947B:
+      screen->chip_family = CHIP_FAMILY_RV770;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV730_9487:
+   case PCI_CHIP_RV730_9489:
+   case PCI_CHIP_RV730_948F:
+   case PCI_CHIP_RV730_9490:
+   case PCI_CHIP_RV730_9491:
+   case PCI_CHIP_RV730_9498:
+   case PCI_CHIP_RV730_949C:
+   case PCI_CHIP_RV730_949E:
+   case PCI_CHIP_RV730_949F:
+      screen->chip_family = CHIP_FAMILY_RV730;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV710_9540:
+   case PCI_CHIP_RV710_9541:
+   case PCI_CHIP_RV710_9542:
+   case PCI_CHIP_RV710_954E:
+   case PCI_CHIP_RV710_954F:
+   case PCI_CHIP_RV710_9552:
+   case PCI_CHIP_RV710_9553:
+   case PCI_CHIP_RV710_9555:
+      screen->chip_family = CHIP_FAMILY_RV710;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
+   case PCI_CHIP_RV740_94A0:
+   case PCI_CHIP_RV740_94A1:
+   case PCI_CHIP_RV740_94B1:
+   case PCI_CHIP_RV740_94B3:
+   case PCI_CHIP_RV740_94B5:
+      screen->chip_family = CHIP_FAMILY_RV740;
+      screen->chip_flags = RADEON_CHIPSET_TCL;
+      break;
+
    default:
       fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
              device_id);
@@ -715,7 +930,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
    unsigned char *RADEONMMIO = NULL;
    int i;
    int ret;
-   uint32_t temp;
+   uint32_t temp = 0;
 
    if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) {
       fprintf(stderr,"\nERROR!  sizeof(RADEONDRIRec) does not match passed size from device driver\n");
@@ -733,7 +948,6 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
 #if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
        RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
 #endif
-
    /* parse information in __driConfigOptions */
    driParseOptionInfo (&screen->optionCache,
                       __driConfigOptions, __driNConfigOptions);
@@ -745,21 +959,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
    {
       int ret;
 
-#ifdef RADEON_PARAM_KERNEL_MM
-     ret = radeonGetParam( sPriv->fd, RADEON_PARAM_KERNEL_MM,
-                            &screen->kernel_mm);
-
-      if (ret && ret != -EINVAL) {
-         FREE( screen );
-         fprintf(stderr, "drm_radeon_getparam_t (RADEON_OFFSET): %d\n", ret);
-         return NULL;
-      }
-
-      if (ret == -EINVAL)
-          screen->kernel_mm = 0;
-#endif
-
-      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BUFFER_OFFSET,
+      ret = radeonGetParam(sPriv, RADEON_PARAM_GART_BUFFER_OFFSET,
                            &screen->gart_buffer_offset);
 
       if (ret) {
@@ -768,7 +968,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
         return NULL;
       }
 
-      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BASE,
+      ret = radeonGetParam(sPriv, RADEON_PARAM_GART_BASE,
                            &screen->gart_base);
       if (ret) {
         FREE( screen );
@@ -776,7 +976,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
         return NULL;
       }
 
-      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_IRQ_NR,
+      ret = radeonGetParam(sPriv, RADEON_PARAM_IRQ_NR,
                            &screen->irq);
       if (ret) {
         FREE( screen );
@@ -792,66 +992,67 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
       screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25);
    }
 
-   if (!screen->kernel_mm) {
-     screen->mmio.handle = dri_priv->registerHandle;
-     screen->mmio.size   = dri_priv->registerSize;
-     if ( drmMap( sPriv->fd,
-                 screen->mmio.handle,
-                 screen->mmio.size,
-                 &screen->mmio.map ) ) {
-       FREE( screen );
-       __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
-       return NULL;
-     }
+   ret = radeon_set_screen_flags(screen, dri_priv->deviceID);
+   if (ret == -1)
+     return NULL;
 
-     RADEONMMIO = screen->mmio.map;
+   screen->mmio.handle = dri_priv->registerHandle;
+   screen->mmio.size   = dri_priv->registerSize;
+   if ( drmMap( sPriv->fd,
+               screen->mmio.handle,
+               screen->mmio.size,
+               &screen->mmio.map ) ) {
+     FREE( screen );
+     __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
+     return NULL;
+   }
 
-     screen->status.handle = dri_priv->statusHandle;
-     screen->status.size   = dri_priv->statusSize;
-     if ( drmMap( sPriv->fd,
-                 screen->status.handle,
-                 screen->status.size,
-                 &screen->status.map ) ) {
-       drmUnmap( screen->mmio.map, screen->mmio.size );
-       FREE( screen );
-       __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
-       return NULL;
-     }
-     screen->scratch = (__volatile__ uint32_t *)
-       ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
+   RADEONMMIO = screen->mmio.map;
+
+   screen->status.handle = dri_priv->statusHandle;
+   screen->status.size   = dri_priv->statusSize;
+   if ( drmMap( sPriv->fd,
+               screen->status.handle,
+               screen->status.size,
+               &screen->status.map ) ) {
+     drmUnmap( screen->mmio.map, screen->mmio.size );
+     FREE( screen );
+     __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
+     return NULL;
+   }
+   if (screen->chip_family < CHIP_FAMILY_R600)
+          screen->scratch = (__volatile__ uint32_t *)
+                  ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
+   else
+          screen->scratch = (__volatile__ uint32_t *)
+                  ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
+
+   screen->buffers = drmMapBufs( sPriv->fd );
+   if ( !screen->buffers ) {
+     drmUnmap( screen->status.map, screen->status.size );
+     drmUnmap( screen->mmio.map, screen->mmio.size );
+     FREE( screen );
+     __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
+     return NULL;
+   }
 
-     screen->buffers = drmMapBufs( sPriv->fd );
-     if ( !screen->buffers ) {
+   if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
+     screen->gartTextures.handle = dri_priv->gartTexHandle;
+     screen->gartTextures.size   = dri_priv->gartTexMapSize;
+     if ( drmMap( sPriv->fd,
+                 screen->gartTextures.handle,
+                 screen->gartTextures.size,
+                 (drmAddressPtr)&screen->gartTextures.map ) ) {
+       drmUnmapBufs( screen->buffers );
        drmUnmap( screen->status.map, screen->status.size );
        drmUnmap( screen->mmio.map, screen->mmio.size );
        FREE( screen );
-       __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
+       __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
        return NULL;
-     }
-     
-     if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
-       screen->gartTextures.handle = dri_priv->gartTexHandle;
-       screen->gartTextures.size   = dri_priv->gartTexMapSize;
-       if ( drmMap( sPriv->fd,
-                   screen->gartTextures.handle,
-                   screen->gartTextures.size,
-                   (drmAddressPtr)&screen->gartTextures.map ) ) {
-        drmUnmapBufs( screen->buffers );
-        drmUnmap( screen->status.map, screen->status.size );
-        drmUnmap( screen->mmio.map, screen->mmio.size );
-        FREE( screen );
-        __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
-        return NULL;
-       }
-       
-       screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base;
-     }
-   }
-
+    }
 
-   ret = radeon_set_screen_flags(screen, dri_priv->deviceID);
-   if (ret == -1)
-     return NULL;
+     screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base;
+   }
 
    if ((screen->chip_family == CHIP_FAMILY_R350 || screen->chip_family == CHIP_FAMILY_R300) &&
        sPriv->ddx_version.minor < 2) {
@@ -865,35 +1066,57 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
    }
 
    if (getenv("R300_NO_TCL"))
-     screen->chip_flags &= ~RADEON_CHIPSET_TCL;
+          screen->chip_flags &= ~RADEON_CHIPSET_TCL;
 
    if (screen->chip_family <= CHIP_FAMILY_RS200)
-      screen->chip_flags |= RADEON_CLASS_R100;
+          screen->chip_flags |= RADEON_CLASS_R100;
    else if (screen->chip_family <= CHIP_FAMILY_RV280)
-      screen->chip_flags |= RADEON_CLASS_R200;
+          screen->chip_flags |= RADEON_CLASS_R200;
+   else if (screen->chip_family <= CHIP_FAMILY_RV570)
+          screen->chip_flags |= RADEON_CLASS_R300;
    else
-      screen->chip_flags |= RADEON_CLASS_R300;
+          screen->chip_flags |= RADEON_CLASS_R600;
 
    screen->cpp = dri_priv->bpp / 8;
    screen->AGPMode = dri_priv->AGPMode;
 
-   ret = radeonGetParam( sPriv->fd, RADEON_PARAM_FB_LOCATION,
-                         &temp);
-   if (ret) {
-       if (screen->chip_family < CHIP_FAMILY_RS690 && !screen->kernel_mm)
-          screen->fbLocation      = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff) << 16;
-       else {
-           FREE( screen );
-           fprintf(stderr, "Unable to get fb location need newer drm\n");
-           return NULL;
+   ret = radeonGetParam(sPriv, RADEON_PARAM_FB_LOCATION, &temp);
+
+   /* +r6/r7 */
+   if(screen->chip_family >= CHIP_FAMILY_R600)
+   {
+       if (ret) 
+       {
+            FREE( screen );
+            fprintf(stderr, "Unable to get fb location need newer drm\n");
+            return NULL;
+       }
+       else
+       {
+            screen->fbLocation = (temp & 0xffff) << 24;
        }
-   } else {
-       screen->fbLocation = (temp & 0xffff) << 16;
+   }
+   else
+   {
+        if (ret) 
+        {
+            if (screen->chip_family < CHIP_FAMILY_RS600 && !screen->kernel_mm)
+                   screen->fbLocation      = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff) << 16;
+            else 
+            {
+                FREE( screen );
+                fprintf(stderr, "Unable to get fb location need newer drm\n");
+                return NULL;
+            }
+        } 
+        else 
+        {
+            screen->fbLocation = (temp & 0xffff) << 16;
+        }
    }
 
-   if (screen->chip_family >= CHIP_FAMILY_RV515) {
-       ret = radeonGetParam( sPriv->fd, RADEON_PARAM_NUM_GB_PIPES,
-                            &temp);
+   if (IS_R300_CLASS(screen)) {
+       ret = radeonGetParam(sPriv, RADEON_PARAM_NUM_GB_PIPES, &temp);
        if (ret) {
           fprintf(stderr, "Unable to get num_pipes, need newer drm\n");
           switch (screen->chip_family) {
@@ -919,6 +1142,17 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
        } else {
           screen->num_gb_pipes = temp;
        }
+
+       /* pipe overrides */
+       switch (dri_priv->deviceID) {
+       case PCI_CHIP_R300_AD: /* 9500 with 1 quadpipe verified by: Reid Linnemann <lreid@cs.okstate.edu> */
+       case PCI_CHIP_RV410_5E4C: /* RV410 SE only have 1 quadpipe */
+       case PCI_CHIP_RV410_5E4F: /* RV410 SE only have 1 quadpipe */
+          screen->num_gb_pipes = 1;
+          break;
+       default:
+          break;
+       }
    }
 
    if ( sPriv->drm_version.minor >= 10 ) {
@@ -988,13 +1222,17 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
    if (IS_R200_CLASS(screen))
-       screen->extensions[i++] = &r200AllocateExtension.base;
+      screen->extensions[i++] = &r200AllocateExtension.base;
 
    screen->extensions[i++] = &r200texOffsetExtension.base;
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
-   //screen->extensions[i++] = &r300texOffsetExtension.base;
+   screen->extensions[i++] = &r300texOffsetExtension.base;
+#endif
+
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+   screen->extensions[i++] = &r600texOffsetExtension.base;
 #endif
 
    screen->extensions[i++] = NULL;
@@ -1005,10 +1243,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
    screen->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
                                               screen->sarea_priv_offset);
 
-   if (screen->kernel_mm)
-     screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
-   else
-     screen->bom = radeon_bo_manager_legacy_ctor(screen);
+   screen->bom = radeon_bo_manager_legacy_ctor(screen);
    if (screen->bom == NULL) {
      free(screen);
      return NULL;
@@ -1023,7 +1258,8 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
    radeonScreenPtr screen;
    int i;
    int ret;
-   uint32_t device_id;
+   uint32_t device_id = 0;
+   uint32_t temp = 0;
 
    /* Allocate the private area */
    screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
@@ -1045,11 +1281,17 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
    screen->kernel_mm = 1;
    screen->chip_flags = 0;
 
-   ret = radeonGetParam( sPriv->fd, RADEON_PARAM_IRQ_NR,
-                        &screen->irq);
-
-   ret = radeonGetParam( sPriv->fd, RADEON_PARAM_DEVICE_ID,
-                        &device_id);
+   /* if we have kms we can support all of these */
+   screen->drmSupportsCubeMapsR200 = 1;
+   screen->drmSupportsBlendColor = 1;
+   screen->drmSupportsTriPerf = 1;
+   screen->drmSupportsFragShader = 1;
+   screen->drmSupportsPointSprites = 1;
+   screen->drmSupportsCubeMapsR100 = 1;
+   screen->drmSupportsVertexProgram = 1;
+   screen->irq = 1;
+
+   ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
    if (ret) {
      FREE( screen );
      fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret);
@@ -1060,12 +1302,58 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
    if (ret == -1)
      return NULL;
 
+   if (getenv("R300_NO_TCL"))
+          screen->chip_flags &= ~RADEON_CHIPSET_TCL;
+
    if (screen->chip_family <= CHIP_FAMILY_RS200)
-      screen->chip_flags |= RADEON_CLASS_R100;
+          screen->chip_flags |= RADEON_CLASS_R100;
    else if (screen->chip_family <= CHIP_FAMILY_RV280)
-      screen->chip_flags |= RADEON_CLASS_R200;
+          screen->chip_flags |= RADEON_CLASS_R200;
+   else if (screen->chip_family <= CHIP_FAMILY_RV570)
+          screen->chip_flags |= RADEON_CLASS_R300;
    else
-      screen->chip_flags |= RADEON_CLASS_R300;
+          screen->chip_flags |= RADEON_CLASS_R600;
+
+   if (IS_R300_CLASS(screen)) {
+       ret = radeonGetParam(sPriv, RADEON_PARAM_NUM_GB_PIPES, &temp);
+       if (ret) {
+          fprintf(stderr, "Unable to get num_pipes, need newer drm\n");
+          switch (screen->chip_family) {
+          case CHIP_FAMILY_R300:
+          case CHIP_FAMILY_R350:
+              screen->num_gb_pipes = 2;
+              break;
+          case CHIP_FAMILY_R420:
+          case CHIP_FAMILY_R520:
+          case CHIP_FAMILY_R580:
+          case CHIP_FAMILY_RV560:
+          case CHIP_FAMILY_RV570:
+              screen->num_gb_pipes = 4;
+              break;
+          case CHIP_FAMILY_RV350:
+          case CHIP_FAMILY_RV515:
+          case CHIP_FAMILY_RV530:
+          case CHIP_FAMILY_RV410:
+          default:
+              screen->num_gb_pipes = 1;
+              break;
+          }
+       } else {
+          screen->num_gb_pipes = temp;
+       }
+
+       /* pipe overrides */
+       switch (device_id) {
+       case PCI_CHIP_R300_AD: /* 9500 with 1 quadpipe verified by: Reid Linnemann <lreid@cs.okstate.edu> */
+       case PCI_CHIP_RV410_5E4C: /* RV410 SE only have 1 quadpipe */
+       case PCI_CHIP_RV410_5E4F: /* RV410 SE only have 1 quadpipe */
+          screen->num_gb_pipes = 1;
+          break;
+       default:
+          break;
+       }
+
+   }
 
    i = 0;
    screen->extensions[i++] = &driCopySubBufferExtension.base;
@@ -1078,21 +1366,24 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
    }
 
 #if !RADEON_COMMON
-   screen->extensions[i++] = &radeonTexOffsetExtension.base;
+   screen->extensions[i++] = &radeonTexBufferExtension.base;
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
    if (IS_R200_CLASS(screen))
        screen->extensions[i++] = &r200AllocateExtension.base;
 
-   screen->extensions[i++] = &r200texOffsetExtension.base;
+   screen->extensions[i++] = &r200TexBufferExtension.base;
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
-   screen->extensions[i++] = &r300texOffsetExtension.base;
    screen->extensions[i++] = &r300TexBufferExtension.base;
 #endif
 
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+   screen->extensions[i++] = &r600TexBufferExtension.base;
+#endif
+
    screen->extensions[i++] = NULL;
    sPriv->extensions = screen->extensions;
 
@@ -1116,7 +1407,9 @@ radeonDestroyScreen( __DRIscreenPrivate *sPriv )
         return;
 
     if (screen->kernel_mm) {
+#ifdef RADEON_BO_TRACK
         radeon_tracker_print(&screen->bom->tracker, stderr);
+#endif
         radeon_bo_manager_gem_dtor(screen->bom);
     } else {
         radeon_bo_manager_legacy_dtor(screen->bom);
@@ -1155,90 +1448,8 @@ radeonInitDriver( __DRIscreenPrivate *sPriv )
     return GL_TRUE;
 }
 
-static GLboolean
-radeon_alloc_window_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
-                           GLenum intFormat, GLuint w, GLuint h)
-{
-    rb->Width = w;
-    rb->Height = h;
-    rb->_ActualFormat = intFormat;
-
-    return GL_TRUE;
-}
 
 
-static struct radeon_renderbuffer *
-radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
-{
-    struct radeon_renderbuffer *ret;
-
-    ret = CALLOC_STRUCT(radeon_renderbuffer);
-    if (!ret)
-       return NULL;
-
-    _mesa_init_renderbuffer(&ret->base, 0);
-
-    /* XXX format junk */
-    switch (format) {
-       case GL_RGB5:
-           ret->base._ActualFormat = GL_RGB5;
-           ret->base._BaseFormat = GL_RGBA;
-           ret->base.RedBits = 5;
-           ret->base.GreenBits = 6;
-           ret->base.BlueBits = 5;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_RGBA8:
-           ret->base._ActualFormat = GL_RGBA8;
-           ret->base._BaseFormat = GL_RGBA;
-           ret->base.RedBits = 8;
-           ret->base.GreenBits = 8;
-           ret->base.BlueBits = 8;
-           ret->base.AlphaBits = 8;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_STENCIL_INDEX8_EXT:
-           ret->base._ActualFormat = GL_STENCIL_INDEX8_EXT;
-           ret->base._BaseFormat = GL_STENCIL_INDEX;
-           ret->base.StencilBits = 8;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_DEPTH_COMPONENT16:
-           ret->base._ActualFormat = GL_DEPTH_COMPONENT16;
-           ret->base._BaseFormat = GL_DEPTH_COMPONENT;
-           ret->base.DepthBits = 16;
-           ret->base.DataType = GL_UNSIGNED_SHORT;
-           break;
-       case GL_DEPTH_COMPONENT24:
-           ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-           ret->base._BaseFormat = GL_DEPTH_COMPONENT;
-           ret->base.DepthBits = 24;
-           ret->base.DataType = GL_UNSIGNED_INT;
-           break;
-       case GL_DEPTH24_STENCIL8_EXT:
-           ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-           ret->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
-           ret->base.DepthBits = 24;
-           ret->base.StencilBits = 8;
-           ret->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
-           break;
-       default:
-           fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format);
-           _mesa_delete_renderbuffer(&ret->base);
-           return NULL;
-    }
-
-    ret->dPriv = driDrawPriv;
-    ret->base.InternalFormat = format;
-
-    ret->base.AllocStorage = radeon_alloc_window_storage;
-
-    radeonSetSpanFunctions(ret);
-
-    ret->bo = NULL;
-    return ret;
-}
-
 /**
  * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
  *
@@ -1251,92 +1462,111 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
                     const __GLcontextModes *mesaVis,
                     GLboolean isPixmap )
 {
-   radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
+    radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
 
     const GLboolean swDepth = GL_FALSE;
     const GLboolean swAlpha = GL_FALSE;
     const GLboolean swAccum = mesaVis->accumRedBits > 0;
     const GLboolean swStencil = mesaVis->stencilBits > 0 &&
        mesaVis->depthBits != 24;
-    GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8);
-    GLenum depthFormat = GL_NONE;
-    struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
+    GLenum rgbFormat;
+    struct radeon_framebuffer *rfb;
+
+    if (isPixmap)
+      return GL_FALSE; /* not implemented */
+
+    rfb = CALLOC_STRUCT(radeon_framebuffer);
+    if (!rfb)
+      return GL_FALSE;
 
-    if (mesaVis->depthBits == 16)
-       depthFormat = GL_DEPTH_COMPONENT16;
-    else if (mesaVis->depthBits == 24)
-       depthFormat = GL_DEPTH_COMPONENT24;
+    _mesa_initialize_framebuffer(&rfb->base, mesaVis);
+
+    if (mesaVis->redBits == 5)
+        rgbFormat = GL_RGB5;
+    else if (mesaVis->alphaBits == 0)
+        rgbFormat = GL_RGB8;
+    else
+        rgbFormat = GL_RGBA8;
 
     /* front color renderbuffer */
-    {
-       struct radeon_renderbuffer *front =
-           radeon_create_renderbuffer(rgbFormat, driDrawPriv);
-       _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &front->base);
-       front->has_surface = 1;
-    }
+    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
+    _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
+    rfb->color_rb[0]->has_surface = 1;
 
     /* back color renderbuffer */
     if (mesaVis->doubleBufferMode) {
-       struct radeon_renderbuffer *back =
-           radeon_create_renderbuffer(rgbFormat, driDrawPriv);
-       _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &back->base);
-       back->has_surface = 1;
+      rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
+       rfb->color_rb[1]->has_surface = 1;
     }
 
-    /* depth renderbuffer */
-    if (depthFormat != GL_NONE) {
-       struct radeon_renderbuffer *depth =
-           radeon_create_renderbuffer(depthFormat, driDrawPriv);
-       _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth->base);
+    if (mesaVis->depthBits == 24) {
+      if (mesaVis->stencilBits == 8) {
+       struct radeon_renderbuffer *depthStencilRb = radeon_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base);
+       depthStencilRb->has_surface = screen->depthHasSurface;
+      } else {
+       /* depth renderbuffer */
+       struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT24, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
+       depth->has_surface = screen->depthHasSurface;
+      }
+    } else if (mesaVis->depthBits == 16) {
+      /* just 16-bit depth buffer, no hw stencil */
+       struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT16, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
        depth->has_surface = screen->depthHasSurface;
     }
 
-    /* stencil renderbuffer */
-    if (mesaVis->stencilBits > 0 && !swStencil) {
-       struct radeon_renderbuffer *stencil =
-           radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv);
-       _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencil->base);
-       stencil->has_surface = screen->depthHasSurface;
-    }
-
-    _mesa_add_soft_renderbuffers(fb,
+    _mesa_add_soft_renderbuffers(&rfb->base,
            GL_FALSE, /* color */
            swDepth,
            swStencil,
            swAccum,
            swAlpha,
            GL_FALSE /* aux */);
-    driDrawPriv->driverPrivate = (void *) fb;
+    driDrawPriv->driverPrivate = (void *) rfb;
 
     return (driDrawPriv->driverPrivate != NULL);
 }
 
-static void
-radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+
+static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb)
 {
        struct radeon_renderbuffer *rb;
-       GLframebuffer *fb;
-    
-    fb = (void*)driDrawPriv->driverPrivate;
-    rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
-    if (rb && rb->bo) {
-        radeon_bo_unref(rb->bo);
-        rb->bo = NULL;
-    }
-    rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
-    if (rb && rb->bo) {
-        radeon_bo_unref(rb->bo);
-        rb->bo = NULL;
-    }
-    rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
-    if (rb && rb->bo) {
-        radeon_bo_unref(rb->bo);
-        rb->bo = NULL;
-    }
-   _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
+
+       rb = rfb->color_rb[0];
+       if (rb && rb->bo) {
+               radeon_bo_unref(rb->bo);
+               rb->bo = NULL;
+       }
+       rb = rfb->color_rb[1];
+       if (rb && rb->bo) {
+               radeon_bo_unref(rb->bo);
+               rb->bo = NULL;
+       }
+       rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
+       if (rb && rb->bo) {
+               radeon_bo_unref(rb->bo);
+               rb->bo = NULL;
+       }
+}
+
+void
+radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+    struct radeon_framebuffer *rfb;
+    if (!driDrawPriv)
+       return;
+
+    rfb = (void*)driDrawPriv->driverPrivate;
+    if (!rfb)
+       return;
+    radeon_cleanup_renderbuffers(rfb);
+    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
 
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
 /**
  * Choose the appropriate CreateContext function based on the chipset.
  * Eventually, all drivers will go through this process.
@@ -1347,26 +1577,29 @@ static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
 {
        __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
        radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+       if (IS_R600_CLASS(screen))
+               return r600CreateContext(glVisual, driContextPriv, sharedContextPriv);
+#endif
 
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
        if (IS_R300_CLASS(screen))
                return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
-        return GL_FALSE;
-}
+#endif
 
-/**
- * Choose the appropriate DestroyContext function based on the chipset.
- */
-static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
-{
-       radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+       if (IS_R200_CLASS(screen))
+               return r200CreateContext(glVisual, driContextPriv, sharedContextPriv);
+#endif
 
-       if (IS_R300_CLASS(radeon->radeonScreen))
-               return r300DestroyContext(driContextPriv);
+#if !RADEON_COMMON
+       (void)screen;
+       return r100CreateContext(glVisual, driContextPriv, sharedContextPriv);
+#endif
+       return GL_FALSE;
 }
 
 
-#endif
-
 /**
  * This is the driver specific part of the createNewScreen entry point.
  *
@@ -1392,6 +1625,11 @@ radeonInitScreen(__DRIscreenPrivate *psp)
    static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
    static const __DRIversion dri_expected = { 4, 0, 0 };
    static const __DRIversion drm_expected = { 1, 24, 0 };
+#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+   static const char *driver_name = "R600";
+   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
+   static const __DRIversion dri_expected = { 4, 0, 0 };
+   static const __DRIversion drm_expected = { 1, 24, 0 };
 #endif
    RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
 
@@ -1419,6 +1657,8 @@ radeonInitScreen(__DRIscreenPrivate *psp)
    driInitSingleExtension( NULL, NV_vp_extension );
    driInitSingleExtension( NULL, ATI_fs_extension );
    driInitExtensions( NULL, point_extensions, GL_FALSE );
+#elif (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600))
+   driInitSingleExtension( NULL, gl_20_extension );
 #endif
 
    if (!radeonInitDriver(psp))
@@ -1430,6 +1670,7 @@ radeonInitScreen(__DRIscreenPrivate *psp)
                             (dri_priv->bpp == 16) ? 16 : 24,
                             (dri_priv->bpp == 16) ? 0  : 8, 1);
 }
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
 /**
  * This is the driver specific part of the createNewScreen entry point.
@@ -1440,6 +1681,18 @@ radeonInitScreen(__DRIscreenPrivate *psp)
 static const
 __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
 {
+   GLenum fb_format[3];
+   GLenum fb_type[3];
+   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
+    * support pageflipping at all.
+    */
+   static const GLenum back_buffer_modes[] = {
+     GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
+   };
+   uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
+   int color;
+   __DRIconfig **configs = NULL;
+
    /* Calling driInitExtensions here, with a NULL context pointer,
     * does not actually enable the extensions.  It just makes sure
     * that all the dispatch offsets for all the extensions that
@@ -1451,6 +1704,7 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
     * Hello chicken.  Hello egg.  How are you two today?
     */
    driInitExtensions( NULL, card_extensions, GL_FALSE );
+   driInitExtensions( NULL, mm_extensions, GL_FALSE );
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
    driInitExtensions( NULL, blend_extensions, GL_FALSE );
    driInitSingleExtension( NULL, ARB_vp_extension );
@@ -1462,9 +1716,50 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
    if (!radeonInitDriver(psp)) {
        return NULL;
     }
+   depth_bits[0] = 0;
+   stencil_bits[0] = 0;
+   depth_bits[1] = 16;
+   stencil_bits[1] = 0;
+   depth_bits[2] = 24;
+   stencil_bits[2] = 0;
+   depth_bits[3] = 24;
+   stencil_bits[3] = 8;
+
+   msaa_samples_array[0] = 0;
+
+   fb_format[0] = GL_RGB;
+   fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
+
+   fb_format[1] = GL_BGR;
+   fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
+
+   fb_format[2] = GL_BGRA;
+   fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
+
+   for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
+      __DRIconfig **new_configs;
+
+      new_configs = driCreateConfigs(fb_format[color], fb_type[color],
+                                    depth_bits,
+                                    stencil_bits,
+                                    ARRAY_SIZE(depth_bits),
+                                    back_buffer_modes,
+                                    ARRAY_SIZE(back_buffer_modes),
+                                    msaa_samples_array,
+                                    ARRAY_SIZE(msaa_samples_array));
+      if (configs == NULL)
+        configs = new_configs;
+      else
+        configs = driConcatConfigs(configs, new_configs);
+   }
 
-   /* for now fill in all modes */
-   return radeonFillInModes( psp, 24, 24, 8, 1);
+   if (configs == NULL) {
+      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+              __LINE__);
+      return NULL;
+   }
+
+   return (const __DRIconfig **)configs;
 }
 
 /**
@@ -1473,27 +1768,26 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
 static int
 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
 {
-   radeonContextPtr  rmesa;
+    struct radeon_framebuffer *rfb;
 
-   if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
-       || (dPriv->driContextPriv->driverPrivate == NULL)
-       || (sInfo == NULL) ) {
-      return -1;
+    if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
+        || (dPriv->driContextPriv->driverPrivate == NULL)
+        || (sInfo == NULL) ) {
+       return -1;
    }
 
-   rmesa = dPriv->driContextPriv->driverPrivate;
-   sInfo->swap_count = rmesa->swap_count;
-   sInfo->swap_ust = rmesa->swap_ust;
-   sInfo->swap_missed_count = rmesa->swap_missed_count;
+    rfb = dPriv->driverPrivate;
+    sInfo->swap_count = rfb->swap_count;
+    sInfo->swap_ust = rfb->swap_ust;
+    sInfo->swap_missed_count = rfb->swap_missed_count;
 
    sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
-       ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
+       ? driCalculateSwapUsage( dPriv, 0, rfb->swap_missed_ust )
        : 0.0;
 
    return 0;
 }
 
-#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
 const struct __DriverAPIRec driDriverAPI = {
    .InitScreen      = radeonInitScreen,
    .DestroyScreen   = radeonDestroyScreen,
@@ -1513,23 +1807,4 @@ const struct __DriverAPIRec driDriverAPI = {
     /* DRI2 */
    .InitScreen2     = radeonInitScreen2,
 };
-#else
-const struct __DriverAPIRec driDriverAPI = {
-   .InitScreen      = radeonInitScreen,
-   .DestroyScreen   = radeonDestroyScreen,
-   .CreateContext   = r200CreateContext,
-   .DestroyContext  = r200DestroyContext,
-   .CreateBuffer    = radeonCreateBuffer,
-   .DestroyBuffer   = radeonDestroyBuffer,
-   .SwapBuffers     = radeonSwapBuffers,
-   .MakeCurrent     = radeonMakeCurrent,
-   .UnbindContext   = r200UnbindContext,
-   .GetSwapInfo     = getSwapInfo,
-   .GetDrawableMSC  = driDrawableGetMSC32,
-   .WaitForMSC      = driWaitForMSC32,
-   .WaitForSBC      = NULL,
-   .SwapBuffersMSC  = NULL,
-   .CopySubBuffer   = radeonCopySubBuffer,
-};
-#endif