DRI2: Drop sarea, implement swap buffers in the X server.
[mesa.git] / src / mesa / drivers / dri / intel / intel_screen.c
index e1f62bd70ef4de8fcfd3cdae632f5b6fd4008279..c193830f05fb40dbabeeede87d555656423ea5ce 100644 (file)
 #include "intel_buffers.h"
 #include "intel_tex.h"
 #include "intel_span.h"
-#include "intel_tris.h"
 #include "intel_ioctl.h"
 #include "intel_fbo.h"
+#include "intel_chipset.h"
 
+#include "i915_drm.h"
 #include "i830_dri.h"
 #include "intel_regions.h"
 #include "intel_batchbuffer.h"
+#include "intel_bufmgr.h"
 
 PUBLIC const char __driConfigOptions[] =
-   DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
-   DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
-   DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
-   DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
-   DRI_CONF_FORCE_S3TC_ENABLE(false)
-   DRI_CONF_ALLOW_LARGE_TEXTURES(1)
-   DRI_CONF_SECTION_END DRI_CONF_END;
-     const GLuint __driNConfigOptions = 4;
+   DRI_CONF_BEGIN
+   DRI_CONF_SECTION_PERFORMANCE
+      DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
+      DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
+      /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
+       * DRI_CONF_BO_REUSE_ALL
+       */
+      DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
+        DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
+           DRI_CONF_ENUM(0, "Disable buffer object reuse")
+           DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
+        DRI_CONF_DESC_END
+      DRI_CONF_OPT_END
+   DRI_CONF_SECTION_END
+   DRI_CONF_SECTION_QUALITY
+      DRI_CONF_FORCE_S3TC_ENABLE(false)
+      DRI_CONF_ALLOW_LARGE_TEXTURES(2)
+   DRI_CONF_SECTION_END
+   DRI_CONF_SECTION_DEBUG
+     DRI_CONF_NO_RAST(false)
+   DRI_CONF_SECTION_END
+DRI_CONF_END;
+
+const GLuint __driNConfigOptions = 6;
 
 #ifdef USE_NEW_INTERFACE
-     static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
+static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
 #endif /*USE_NEW_INTERFACE */
 
-     extern const struct dri_extension card_extensions[];
-     extern const struct dri_extension ttm_extensions[];
-
 /**
  * Map all the memory regions described by the screen.
  * \return GL_TRUE if success, GL_FALSE if error.
@@ -75,51 +90,6 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv)
 {
    intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
 
-   if (intelScreen->front.handle) {
-      if (drmMap(sPriv->fd,
-                 intelScreen->front.handle,
-                 intelScreen->front.size,
-                 (drmAddress *) & intelScreen->front.map) != 0) {
-         _mesa_problem(NULL, "drmMap(frontbuffer) failed!");
-         return GL_FALSE;
-      }
-   }
-   else {
-      _mesa_warning(NULL, "no front buffer handle in intelMapScreenRegions!");
-   }
-
-   if (0)
-      _mesa_printf("Back 0x%08x ", intelScreen->back.handle);
-   if (drmMap(sPriv->fd,
-              intelScreen->back.handle,
-              intelScreen->back.size,
-              (drmAddress *) & intelScreen->back.map) != 0) {
-      intelUnmapScreenRegions(intelScreen);
-      return GL_FALSE;
-   }
-
-   if (intelScreen->third.handle) {
-      if (0)
-        _mesa_printf("Third 0x%08x ", intelScreen->third.handle);
-      if (drmMap(sPriv->fd,
-                intelScreen->third.handle,
-                intelScreen->third.size,
-                (drmAddress *) & intelScreen->third.map) != 0) {
-        intelUnmapScreenRegions(intelScreen);
-        return GL_FALSE;
-      }
-   }
-
-   if (0)
-      _mesa_printf("Depth 0x%08x ", intelScreen->depth.handle);
-   if (drmMap(sPriv->fd,
-              intelScreen->depth.handle,
-              intelScreen->depth.size,
-              (drmAddress *) & intelScreen->depth.map) != 0) {
-      intelUnmapScreenRegions(intelScreen);
-      return GL_FALSE;
-   }
-
    if (0)
       _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle);
    if (intelScreen->tex.size != 0) {
@@ -132,50 +102,15 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv)
       }
    }
 
-   if (0)
-      printf("Mappings:  front: %p  back: %p  third: %p  depth: %p  tex: %p\n",
-             intelScreen->front.map,
-             intelScreen->back.map, intelScreen->third.map,
-             intelScreen->depth.map, intelScreen->tex.map);
    return GL_TRUE;
 }
 
 void
 intelUnmapScreenRegions(intelScreenPrivate * intelScreen)
 {
-#define REALLY_UNMAP 1
-   if (intelScreen->front.map) {
-#if REALLY_UNMAP
-      if (drmUnmap(intelScreen->front.map, intelScreen->front.size) != 0)
-         printf("drmUnmap front failed!\n");
-#endif
-      intelScreen->front.map = NULL;
-   }
-   if (intelScreen->back.map) {
-#if REALLY_UNMAP
-      if (drmUnmap(intelScreen->back.map, intelScreen->back.size) != 0)
-         printf("drmUnmap back failed!\n");
-#endif
-      intelScreen->back.map = NULL;
-   }
-   if (intelScreen->third.map) {
-#if REALLY_UNMAP
-      if (drmUnmap(intelScreen->third.map, intelScreen->third.size) != 0)
-         printf("drmUnmap third failed!\n");
-#endif
-      intelScreen->third.map = NULL;
-   }
-   if (intelScreen->depth.map) {
-#if REALLY_UNMAP
-      drmUnmap(intelScreen->depth.map, intelScreen->depth.size);
-      intelScreen->depth.map = NULL;
-#endif
-   }
    if (intelScreen->tex.map) {
-#if REALLY_UNMAP
       drmUnmap(intelScreen->tex.map, intelScreen->tex.size);
       intelScreen->tex.map = NULL;
-#endif
    }
 }
 
@@ -186,13 +121,13 @@ intelPrintDRIInfo(intelScreenPrivate * intelScreen,
 {
    fprintf(stderr, "*** Front size:   0x%x  offset: 0x%x  pitch: %d\n",
            intelScreen->front.size, intelScreen->front.offset,
-           intelScreen->front.pitch);
+           intelScreen->pitch);
    fprintf(stderr, "*** Back size:    0x%x  offset: 0x%x  pitch: %d\n",
            intelScreen->back.size, intelScreen->back.offset,
-           intelScreen->back.pitch);
+           intelScreen->pitch);
    fprintf(stderr, "*** Depth size:   0x%x  offset: 0x%x  pitch: %d\n",
            intelScreen->depth.size, intelScreen->depth.offset,
-           intelScreen->depth.pitch);
+           intelScreen->pitch);
    fprintf(stderr, "*** Texture size: 0x%x  offset: 0x%x\n",
            intelScreen->tex.size, intelScreen->tex.offset);
    fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem);
@@ -200,22 +135,22 @@ intelPrintDRIInfo(intelScreenPrivate * intelScreen,
 
 
 static void
-intelPrintSAREA(const drmI830Sarea * sarea)
+intelPrintSAREA(const struct drm_i915_sarea * sarea)
 {
    fprintf(stderr, "SAREA: sarea width %d  height %d\n", sarea->width,
            sarea->height);
    fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch);
    fprintf(stderr,
-           "SAREA: front offset: 0x%08x  size: 0x%x  handle: 0x%x\n",
+           "SAREA: front offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
            sarea->front_offset, sarea->front_size,
-           (unsigned) sarea->front_handle);
+           (unsigned) sarea->front_handle, sarea->front_tiled);
    fprintf(stderr,
-           "SAREA: back  offset: 0x%08x  size: 0x%x  handle: 0x%x\n",
+           "SAREA: back  offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
            sarea->back_offset, sarea->back_size,
-           (unsigned) sarea->back_handle);
-   fprintf(stderr, "SAREA: depth offset: 0x%08x  size: 0x%x  handle: 0x%x\n",
+           (unsigned) sarea->back_handle, sarea->back_tiled);
+   fprintf(stderr, "SAREA: depth offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
            sarea->depth_offset, sarea->depth_size,
-           (unsigned) sarea->depth_handle);
+           (unsigned) sarea->depth_handle, sarea->depth_tiled);
    fprintf(stderr, "SAREA: tex   offset: 0x%08x  size: 0x%x  handle: 0x%x\n",
            sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle);
 }
@@ -227,33 +162,30 @@ intelPrintSAREA(const drmI830Sarea * sarea)
  */
 void
 intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
-                           drmI830Sarea * sarea)
+                           struct drm_i915_sarea * sarea)
 {
    intelScreen->width = sarea->width;
    intelScreen->height = sarea->height;
+   intelScreen->pitch = sarea->pitch;
 
    intelScreen->front.offset = sarea->front_offset;
-   intelScreen->front.pitch = sarea->pitch * intelScreen->cpp;
    intelScreen->front.handle = sarea->front_handle;
    intelScreen->front.size = sarea->front_size;
    intelScreen->front.tiled = sarea->front_tiled;
 
    intelScreen->back.offset = sarea->back_offset;
-   intelScreen->back.pitch = sarea->pitch * intelScreen->cpp;
    intelScreen->back.handle = sarea->back_handle;
    intelScreen->back.size = sarea->back_size;
    intelScreen->back.tiled = sarea->back_tiled;
 
    if (intelScreen->driScrnPriv->ddx_version.minor >= 8) {
       intelScreen->third.offset = sarea->third_offset;
-      intelScreen->third.pitch = sarea->pitch * intelScreen->cpp;
       intelScreen->third.handle = sarea->third_handle;
       intelScreen->third.size = sarea->third_size;
       intelScreen->third.tiled = sarea->third_tiled;
    }
 
    intelScreen->depth.offset = sarea->depth_offset;
-   intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp;
    intelScreen->depth.handle = sarea->depth_handle;
    intelScreen->depth.size = sarea->depth_size;
    intelScreen->depth.tiled = sarea->depth_tiled;
@@ -284,22 +216,45 @@ static const __DRItexOffsetExtension intelTexOffsetExtension = {
    intelSetTexOffset,
 };
 
-static const __DRIextension *intelExtensions[] = {
+static const __DRItexBufferExtension intelTexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+   intelSetTexBuffer,
+};
+
+static const __DRIextension *intelScreenExtensions[] = {
     &driReadDrawableExtension,
     &driCopySubBufferExtension.base,
     &driSwapControlExtension.base,
     &driFrameTrackingExtension.base,
     &driMediaStreamCounterExtension.base,
     &intelTexOffsetExtension.base,
+    &intelTexBufferExtension.base,
     NULL
 };
 
+static GLboolean
+intel_get_param(__DRIscreenPrivate *psp, int param, int *value)
+{
+   int ret;
+   struct drm_i915_getparam gp;
+
+   gp.param = param;
+   gp.value = value;
+
+   ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
+   if (ret) {
+      fprintf(stderr, "drm_i915_getparam: %d\n", ret);
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
 
 static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
 {
    intelScreenPrivate *intelScreen;
    I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv;
-   drmI830Sarea *sarea;
+   struct drm_i915_sarea *sarea;
 
    if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
       fprintf(stderr,
@@ -320,26 +275,11 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
    intelScreen->driScrnPriv = sPriv;
    sPriv->private = (void *) intelScreen;
    intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
-   sarea = (drmI830Sarea *)
+   sarea = (struct drm_i915_sarea *)
       (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset);
 
    intelScreen->deviceID = gDRIPriv->deviceID;
 
-   intelScreen->mem = gDRIPriv->mem;
-   intelScreen->cpp = gDRIPriv->cpp;
-
-   switch (gDRIPriv->bitsPerPixel) {
-   case 16:
-      intelScreen->fbFormat = DV_PF_565;
-      break;
-   case 32:
-      intelScreen->fbFormat = DV_PF_8888;
-      break;
-   default:
-      exit(1);
-      break;
-   }
-
    intelUpdateScreenFromSAREA(intelScreen, sarea);
 
    if (!intelMapScreenRegions(sPriv)) {
@@ -357,38 +297,16 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
    intelScreen->drmMinor = sPriv->drm_version.minor;
 
    /* Determine if IRQs are active? */
-   {
-      int ret;
-      drmI830GetParam gp;
-
-      gp.param = I830_PARAM_IRQ_ACTIVE;
-      gp.value = &intelScreen->irq_active;
-
-      ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM,
-                                &gp, sizeof(gp));
-      if (ret) {
-         fprintf(stderr, "drmI830GetParam: %d\n", ret);
-         return GL_FALSE;
-      }
-   }
+   if (!intel_get_param(sPriv, I915_PARAM_IRQ_ACTIVE,
+                       &intelScreen->irq_active))
+      return GL_FALSE;
 
    /* Determine if batchbuffers are allowed */
-   {
-      int ret;
-      drmI830GetParam gp;
-
-      gp.param = I830_PARAM_ALLOW_BATCHBUFFER;
-      gp.value = &intelScreen->allow_batchbuffer;
-
-      ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM,
-                                &gp, sizeof(gp));
-      if (ret) {
-         fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret);
-         return GL_FALSE;
-      }
-   }
+   if (!intel_get_param(sPriv, I915_PARAM_ALLOW_BATCHBUFFER,
+                       &intelScreen->allow_batchbuffer))
+      return GL_FALSE;
 
-   sPriv->extensions = intelExtensions;
+   sPriv->extensions = intelScreenExtensions;
 
    return GL_TRUE;
 }
@@ -432,42 +350,20 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
       _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis);
 
       /* setup the hardware-based renderbuffers */
-      {
-         intel_fb->color_rb[0]
-            = intel_create_renderbuffer(rgbFormat,
-                                        screen->width, screen->height,
-                                        screen->front.offset,
-                                        screen->front.pitch,
-                                        screen->cpp,
-                                        screen->front.map);
-         intel_set_span_functions(&intel_fb->color_rb[0]->Base);
-         _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT,
-                               &intel_fb->color_rb[0]->Base);
-      }
+      intel_fb->color_rb[0] = intel_create_renderbuffer(rgbFormat);
+      _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT,
+                            &intel_fb->color_rb[0]->Base);
 
       if (mesaVis->doubleBufferMode) {
-         intel_fb->color_rb[1]
-            = intel_create_renderbuffer(rgbFormat,
-                                        screen->width, screen->height,
-                                        screen->back.offset,
-                                        screen->back.pitch,
-                                        screen->cpp,
-                                        screen->back.map);
-         intel_set_span_functions(&intel_fb->color_rb[1]->Base);
+        intel_fb->color_rb[1] = intel_create_renderbuffer(rgbFormat);
+
          _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT,
                                &intel_fb->color_rb[1]->Base);
 
         if (screen->third.handle) {
            struct gl_renderbuffer *tmp_rb = NULL;
 
-           intel_fb->color_rb[2]
-              = intel_create_renderbuffer(rgbFormat,
-                                          screen->width, screen->height,
-                                          screen->third.offset,
-                                          screen->third.pitch,
-                                          screen->cpp,
-                                          screen->third.map);
-           intel_set_span_functions(&intel_fb->color_rb[2]->Base);
+           intel_fb->color_rb[2] = intel_create_renderbuffer(rgbFormat);
            _mesa_reference_renderbuffer(&tmp_rb, &intel_fb->color_rb[2]->Base);
         }
       }
@@ -476,13 +372,7 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
         if (mesaVis->stencilBits == 8) {
            /* combined depth/stencil buffer */
            struct intel_renderbuffer *depthStencilRb
-              = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT,
-                                          screen->width, screen->height,
-                                          screen->depth.offset,
-                                          screen->depth.pitch,
-                                          screen->cpp,    /* 4! */
-                                          screen->depth.map);
-           intel_set_span_functions(&depthStencilRb->Base);
+              = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT);
            /* note: bind RB to two attachment points */
            _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH,
                                   &depthStencilRb->Base);
@@ -490,13 +380,7 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
                                   &depthStencilRb->Base);
         } else {
            struct intel_renderbuffer *depthRb
-              = intel_create_renderbuffer(GL_DEPTH_COMPONENT24,
-                                          screen->width, screen->height,
-                                          screen->depth.offset,
-                                          screen->depth.pitch,
-                                          screen->cpp,    /* 4! */
-                                          screen->depth.map);
-           intel_set_span_functions(&depthRb->Base);
+              = intel_create_renderbuffer(GL_DEPTH_COMPONENT24);
            _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH,
                                   &depthRb->Base);
         }
@@ -504,13 +388,7 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
       else if (mesaVis->depthBits == 16) {
          /* just 16-bit depth buffer, no hw stencil */
          struct intel_renderbuffer *depthRb
-            = intel_create_renderbuffer(GL_DEPTH_COMPONENT16,
-                                        screen->width, screen->height,
-                                        screen->depth.offset,
-                                        screen->depth.pitch,
-                                        screen->cpp,    /* 2! */
-                                        screen->depth.map);
-         intel_set_span_functions(&depthRb->Base);
+           = intel_create_renderbuffer(GL_DEPTH_COMPONENT16);
          _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base);
       }
 
@@ -571,9 +449,9 @@ extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis,
 extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis,
                                    __DRIcontextPrivate * driContextPriv,
                                    void *sharedContextPrivate);
-
-
-
+extern GLboolean brwCreateContext(const __GLcontextModes * mesaVis,
+                                 __DRIcontextPrivate * driContextPriv,
+                                 void *sharedContextPrivate);
 
 static GLboolean
 intelCreateContext(const __GLcontextModes * mesaVis,
@@ -583,63 +461,36 @@ intelCreateContext(const __GLcontextModes * mesaVis,
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
    intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
 
-   switch (intelScreen->deviceID) {
-      /* Don't deal with i830 until texture work complete:
-       */
-   case PCI_CHIP_845_G:
-   case PCI_CHIP_I830_M:
-   case PCI_CHIP_I855_GM:
-   case PCI_CHIP_I865_G:
+#ifdef I915
+   if (IS_9XX(intelScreen->deviceID)) {
+      if (!IS_965(intelScreen->deviceID)) {
+        return i915CreateContext(mesaVis, driContextPriv,
+                                 sharedContextPrivate);
+      }
+   } else {
       return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
-
-   case PCI_CHIP_I915_G:
-   case PCI_CHIP_I915_GM:
-   case PCI_CHIP_I945_G:
-   case PCI_CHIP_I945_GM:
-   case PCI_CHIP_I945_GME:
-   case PCI_CHIP_G33_G:
-   case PCI_CHIP_Q35_G:
-   case PCI_CHIP_Q33_G:
-      return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
-
-   default:
-      fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
-      return GL_FALSE;
    }
+#else
+   if (IS_965(intelScreen->deviceID))
+      return brwCreateContext(mesaVis, driContextPriv, sharedContextPrivate);
+#endif
+   fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
+   return GL_FALSE;
 }
 
 
-static const struct __DriverAPIRec intelAPI = {
-   .DestroyScreen = intelDestroyScreen,
-   .CreateContext = intelCreateContext,
-   .DestroyContext = intelDestroyContext,
-   .CreateBuffer = intelCreateBuffer,
-   .DestroyBuffer = intelDestroyBuffer,
-   .SwapBuffers = intelSwapBuffers,
-   .MakeCurrent = intelMakeCurrent,
-   .UnbindContext = intelUnbindContext,
-   .GetSwapInfo = intelGetSwapInfo,
-   .GetMSC = driGetMSC32,
-   .GetDrawableMSC = driDrawableGetMSC32,
-   .WaitForMSC = driWaitForMSC32,
-   .WaitForSBC = NULL,
-   .SwapBuffersMSC = NULL,
-   .CopySubBuffer = intelCopySubBuffer,
-   .setTexOffset = intelSetTexOffset,
-};
-
-
-static __GLcontextModes *
-intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
+static __DRIconfig **
+intelFillInModes(__DRIscreenPrivate *psp,
+                unsigned pixel_bits, unsigned depth_bits,
                  unsigned stencil_bits, GLboolean have_back_buffer)
 {
-   __GLcontextModes *modes;
+   __DRIconfig **configs;
    __GLcontextModes *m;
-   unsigned num_modes;
    unsigned depth_buffer_factor;
    unsigned back_buffer_factor;
    GLenum fb_format;
    GLenum fb_type;
+   int i;
 
    /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
     * support pageflipping at all.
@@ -651,7 +502,6 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
    u_int8_t depth_bits_array[3];
    u_int8_t stencil_bits_array[3];
 
-
    depth_bits_array[0] = 0;
    depth_bits_array[1] = depth_bits;
    depth_bits_array[2] = depth_bits;
@@ -670,8 +520,6 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
    depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
    back_buffer_factor = (have_back_buffer) ? 3 : 1;
 
-   num_modes = depth_buffer_factor * back_buffer_factor * 4;
-
    if (pixel_bits == 16) {
       fb_format = GL_RGB;
       fb_type = GL_UNSIGNED_SHORT_5_6_5;
@@ -681,55 +529,48 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
       fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
    }
 
-   modes =
-      (*dri_interface->createContextModes) (num_modes,
-                                            sizeof(__GLcontextModes));
-   m = modes;
-   if (!driFillInModes(&m, fb_format, fb_type,
-                       depth_bits_array, stencil_bits_array,
-                       depth_buffer_factor, back_buffer_modes,
-                       back_buffer_factor, GLX_TRUE_COLOR)) {
-      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
-              __LINE__);
-      return NULL;
-   }
-   if (!driFillInModes(&m, fb_format, fb_type,
-                       depth_bits_array, stencil_bits_array,
-                       depth_buffer_factor, back_buffer_modes,
-                       back_buffer_factor, GLX_DIRECT_COLOR)) {
-      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+   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__);
       return NULL;
    }
 
    /* Mark the visual as slow if there are "fake" stencil bits.
     */
-   for (m = modes; m != NULL; m = m->next) {
+   for (i = 0; configs[i]; i++) {
+      m = &configs[i]->modes;
       if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
          m->visualRating = GLX_SLOW_CONFIG;
       }
    }
 
-   return modes;
+   return configs;
 }
 
 
 /**
  * This is the driver specific part of the createNewScreen entry point.
+ * Called when using legacy DRI.
  * 
  * \todo maybe fold this into intelInitDriver
  *
  * \return the __GLcontextModes supported by this driver
  */
-PUBLIC __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
+static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp)
 {
+#ifdef I915
    static const __DRIversion ddx_expected = { 1, 5, 0 };
+#else
+   static const __DRIversion ddx_expected = { 1, 6, 0 };
+#endif
    static const __DRIversion dri_expected = { 4, 0, 0 };
    static const __DRIversion drm_expected = { 1, 5, 0 };
    I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
 
-   psp->DriverAPI = intelAPI;
-
    if (!driCheckDriDdxDrmVersions2("i915",
                                    &psp->dri_version, &dri_expected,
                                    &psp->ddx_version, &ddx_expected,
@@ -747,15 +588,17 @@ PUBLIC __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
     *
     * Hello chicken.  Hello egg.  How are you two today?
     */
-   driInitExtensions(NULL, card_extensions, GL_FALSE);
-   driInitExtensions(NULL, ttm_extensions, GL_FALSE);
-
+   intelInitExtensions(NULL, GL_TRUE);
+          
    if (!intelInitDriver(psp))
        return NULL;
 
-   return intelFillInModes(dri_priv->cpp * 8,
-                          (dri_priv->cpp == 2) ? 16 : 24,
-                          (dri_priv->cpp == 2) ? 0  : 8, 1);
+   psp->extensions = intelScreenExtensions;
+
+   return (const __DRIconfig **)
+       intelFillInModes(psp, dri_priv->cpp * 8,
+                       (dri_priv->cpp == 2) ? 16 : 24,
+                       (dri_priv->cpp == 2) ? 0  : 8, 1);
 }
 
 struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
@@ -773,3 +616,70 @@ struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
   return intel_context(ctx);
 }
 
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ * Called when using DRI2.
+ *
+ * \return the __GLcontextModes supported by this driver
+ */
+static const
+__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp)
+{
+   intelScreenPrivate *intelScreen;
+
+   /* 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
+    * *might* be enables are known.  This is needed because the
+    * dispatch offsets need to be known when _mesa_context_create is
+    * called, but we can't enable the extensions until we have a
+    * context pointer.
+    *
+    * Hello chicken.  Hello egg.  How are you two today?
+    */
+   intelInitExtensions(NULL, GL_TRUE);
+
+   /* Allocate the private area */
+   intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate));
+   if (!intelScreen) {
+      fprintf(stderr, "\nERROR!  Allocating private area failed\n");
+      return GL_FALSE;
+   }
+   /* parse information in __driConfigOptions */
+   driParseOptionInfo(&intelScreen->optionCache,
+                      __driConfigOptions, __driNConfigOptions);
+
+   intelScreen->driScrnPriv = psp;
+   psp->private = (void *) intelScreen;
+
+   intelScreen->drmMinor = psp->drm_version.minor;
+
+   /* Determine chipset ID */
+   if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID,
+                       &intelScreen->deviceID))
+      return GL_FALSE;
+
+   intelScreen->irq_active = 1;
+   psp->extensions = intelScreenExtensions;
+
+   return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1),
+                          intelFillInModes(psp, 32, 24, 8, 1));
+}
+
+const struct __DriverAPIRec driDriverAPI = {
+   .InitScreen          = intelInitScreen,
+   .DestroyScreen       = intelDestroyScreen,
+   .CreateContext       = intelCreateContext,
+   .DestroyContext      = intelDestroyContext,
+   .CreateBuffer        = intelCreateBuffer,
+   .DestroyBuffer       = intelDestroyBuffer,
+   .SwapBuffers                 = intelSwapBuffers,
+   .MakeCurrent                 = intelMakeCurrent,
+   .UnbindContext       = intelUnbindContext,
+   .GetSwapInfo                 = intelGetSwapInfo,
+   .GetDrawableMSC      = driDrawableGetMSC32,
+   .WaitForMSC          = driWaitForMSC32,
+   .CopySubBuffer       = intelCopySubBuffer,
+
+   .InitScreen2                 = intelInitScreen2,
+};