Hook up i915 driver to new DRI2 infrastructure.
authorKristian Høgsberg <krh@temari.boston.redhat.com>
Mon, 21 Jan 2008 22:07:33 +0000 (17:07 -0500)
committerKristian Høgsberg <krh@redhat.com>
Thu, 14 Feb 2008 22:56:44 +0000 (17:56 -0500)
src/mesa/drivers/dri/i915/intel_context.c
src/mesa/drivers/dri/intel/intel_blit.c
src/mesa/drivers/dri/intel/intel_buffers.c
src/mesa/drivers/dri/intel/intel_regions.c
src/mesa/drivers/dri/intel/intel_regions.h
src/mesa/drivers/dri/intel/intel_screen.c

index b2d9c9c5918556e370285b9915836e101163b486..3b6a1d5ef959ca18a397c8df6652c68331fc9721 100644 (file)
@@ -417,7 +417,7 @@ intelInitContext(struct intel_context *intel,
    /* Dri stuff */
    intel->hHWContext = driContextPriv->hHWContext;
    intel->driFd = sPriv->fd;
-   intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock;
+   intel->driHwLock = sPriv->lock;
 
    intel->width = intelScreen->width;
    intel->height = intelScreen->height;
@@ -523,7 +523,8 @@ intelInitContext(struct intel_context *intel,
    if (intel->ttm)
       driInitExtensions(ctx, ttm_extensions, GL_FALSE);
 
-   intel_recreate_static_regions(intel);
+   if (!sPriv->dri2.enabled)
+      intel_recreate_static_regions(intel);
 
    intel->batch = intel_batchbuffer_alloc(intel);
    intel->last_swap_fence = NULL;
@@ -633,7 +634,7 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
 
       /* XXX FBO temporary fix-ups! */
       /* if the renderbuffers don't have regions, init them from the context */
-      {
+      if (!driContextPriv->driScreenPriv->dri2.enabled) {
          struct intel_renderbuffer *irbDepth
             = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
          struct intel_renderbuffer *irbStencil
@@ -709,6 +710,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
    __DRIdrawablePrivate *dPriv = intel->driDrawable;
    __DRIscreenPrivate *sPriv = intel->driScreen;
    drmI830Sarea *sarea = intel->sarea;
+   int drawable_changed = 0;
 
    drmGetLock(intel->driFd, intel->hHWContext, flags);
 
@@ -720,8 +722,12 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
     * NOTE: This releases and regains the hw lock, so all state
     * checking must be done *after* this call:
     */
-   if (dPriv)
-      DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+   if (dPriv) {
+      if (sPriv->dri2.enabled)
+        drawable_changed = __driParseEvents(sPriv, dPriv);
+      else
+        DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+   }
 
    /* If the last consumer of the texture memory wasn't us, notify the fake
     * bufmgr and record the new owner.  We should have the memory shared
@@ -735,42 +741,47 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
         intel_decode_context_reset();
    }
 
-   if (sarea->width != intel->width ||
-       sarea->height != intel->height) {
-      int numClipRects = intel->numClipRects;
+   if (!sPriv->dri2.enabled) {
+      if (sarea->width != intel->width ||
+         sarea->height != intel->height) {
+        int numClipRects = intel->numClipRects;
 
-      /*
-       * FIXME: Really only need to do this when drawing to a
-       * common back- or front buffer.
-       */
+        /*
+         * FIXME: Really only need to do this when drawing to a
+         * common back- or front buffer.
+         */
 
-      /*
-       * This will essentially drop the outstanding batchbuffer on the floor.
-       */
-      intel->numClipRects = 0;
+        /*
+         * This will essentially drop the outstanding batchbuffer on the floor.
+         */
+        intel->numClipRects = 0;
 
-      if (intel->Fallback)
-        _swrast_flush(&intel->ctx);
+        if (intel->Fallback)
+           _swrast_flush(&intel->ctx);
 
-      INTEL_FIREVERTICES(intel);
+        INTEL_FIREVERTICES(intel);
 
-      if (intel->batch->map != intel->batch->ptr)
-        intel_batchbuffer_flush(intel->batch);
+        if (intel->batch->map != intel->batch->ptr)
+           intel_batchbuffer_flush(intel->batch);
 
-      intel->numClipRects = numClipRects;
+        intel->numClipRects = numClipRects;
 
-      /* force window update */
-      intel->lastStamp = 0;
+        /* force window update */
+        intel->lastStamp = 0;
 
-      intel->width = sarea->width;
-      intel->height = sarea->height;
-   }
+        intel->width = sarea->width;
+        intel->height = sarea->height;
+      }
 
-   /* Drawable changed?
-    */
-   if (dPriv && intel->lastStamp != dPriv->lastStamp) {
-      intelWindowMoved(intel);
-      intel->lastStamp = dPriv->lastStamp;
+      /* Drawable changed?
+       */
+      if (dPriv && intel->lastStamp != dPriv->lastStamp) {
+        intelWindowMoved(intel);
+        intel->lastStamp = dPriv->lastStamp;
+      }
+   } else if (drawable_changed) {
+     intelWindowMoved(intel);                                                 
+     intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
    }
 }
 
index f7968db92f6d63e238f740dc11f35e98c317fb53..f4358bb3ddf09dc49a0480d10652ff20af89e4b0 100644 (file)
@@ -132,9 +132,7 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
         }
 
         if (box.x1 >= box.x2 ||
-            box.y1 >= box.y2 ||
-            box.x2 > intelScreen->width ||
-            box.y2 > intelScreen->height)
+            box.y1 >= box.y2)
            continue;
 
         assert(box.x1 < box.x2);
index a77e498b863449987df6e0c788184fe775c9f6bf..d6665081ff9082a08420f9d3d5a63add71ce6efc 100644 (file)
@@ -302,7 +302,8 @@ intelWindowMoved(struct intel_context *intel)
       }
    }
 
-   if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
+   if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
+       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
       volatile drmI830Sarea *sarea = intel->sarea;
       drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
                                   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
index dcf32d9f84fde5d2a1275a088fb3c0c07d2dff9e..8bc548913f4628407b6099b59c051db8b017f4b6 100644 (file)
@@ -76,27 +76,57 @@ intel_region_unmap(struct intel_context *intel, struct intel_region *region)
    }
 }
 
-struct intel_region *
-intel_region_alloc(struct intel_context *intel,
-                   GLuint cpp, GLuint pitch, GLuint height)
+static struct intel_region *
+intel_region_alloc_internal(struct intel_context *intel,
+                           GLuint cpp, GLuint pitch, GLuint height,
+                           GLuint tiled, dri_bo *buffer)
 {
-   struct intel_region *region = calloc(sizeof(*region), 1);
+   struct intel_region *region;
 
    DBG("%s\n", __FUNCTION__);
 
+   if (buffer == NULL)
+      return NULL;
+
+   region = calloc(sizeof(*region), 1);
    region->cpp = cpp;
    region->pitch = pitch;
    region->height = height;     /* needed? */
    region->refcount = 1;
+   region->tiled = tiled;
+   region->buffer = buffer;
 
-   region->buffer = dri_bo_alloc(intel->bufmgr, "region",
-                                pitch * cpp * height, 64,
-                                DRM_BO_FLAG_MEM_LOCAL |
-                                DRM_BO_FLAG_CACHED |
-                                DRM_BO_FLAG_CACHED_MAPPED);
    return region;
 }
 
+struct intel_region *
+intel_region_alloc(struct intel_context *intel,
+                   GLuint cpp, GLuint pitch, GLuint height)
+{
+   dri_bo *buffer;
+
+   buffer = dri_bo_alloc(intel->bufmgr, "region",
+                        pitch * cpp * height, 64,
+                        DRM_BO_FLAG_MEM_LOCAL |
+                        DRM_BO_FLAG_CACHED |
+                        DRM_BO_FLAG_CACHED_MAPPED);
+
+   return intel_region_alloc_internal(intel, cpp, pitch, height, 0, buffer);
+}
+
+struct intel_region *
+intel_region_alloc_for_handle(struct intel_context *intel,
+                             GLuint cpp, GLuint pitch, GLuint height,
+                             GLuint tiled, GLuint handle)
+{
+   dri_bo *buffer;
+
+   buffer = intel_ttm_bo_create_from_handle(intel->bufmgr, "region", handle);
+
+   return intel_region_alloc_internal(intel,
+                                     cpp, pitch, height, tiled, buffer);
+}
+
 void
 intel_region_reference(struct intel_region **dst, struct intel_region *src)
 {
index 0d1dabe9ca789519951c61f8ec8261807c8bea17..229f79aeba73c3745010d4397d514bf3628e4211 100644 (file)
@@ -66,6 +66,11 @@ struct intel_region *intel_region_alloc(struct intel_context *intel,
                                         GLuint cpp,
                                         GLuint pitch, GLuint height);
 
+struct intel_region *
+intel_region_alloc_for_handle(struct intel_context *intel,
+                             GLuint cpp, GLuint pitch, GLuint height,
+                             GLuint tiled, unsigned int handle);
+
 void intel_region_reference(struct intel_region **dst,
                             struct intel_region *src);
 
index 84c77d399199f651e9b3b281989248c295089592..7e0c52005dee3dde98210278f9f2edc085f51202 100644 (file)
@@ -49,6 +49,7 @@
 #include "i830_dri.h"
 #include "intel_regions.h"
 #include "intel_batchbuffer.h"
+#include "intel_bufmgr_ttm.h"
 
 PUBLIC const char __driConfigOptions[] =
    DRI_CONF_BEGIN
@@ -287,6 +288,111 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
       intelPrintSAREA(sarea);
 }
 
+static void
+intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv,
+                         __DRIDrawableConfigEvent *event)
+{
+   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   struct intel_region *region;
+   struct intel_renderbuffer *rb, *depth_rb, *stencil_rb;
+   struct intel_context *intel = dPriv->driContextPriv->driverPrivate;
+   int cpp = intel->ctx.Visual.rgbBits / 8;
+   GLuint pitch = ((cpp * dPriv->w + 63) & ~63) / cpp;
+
+   rb = intel_fb->color_rb[1];
+   if (rb) {
+      region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
+      intel_renderbuffer_set_region(rb, region);
+   }
+
+   rb = intel_fb->color_rb[2];
+   if (rb) {
+      region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
+      intel_renderbuffer_set_region(rb, region);
+   }
+
+   depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+   stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+   if (depth_rb || stencil_rb)
+      region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
+   if (depth_rb)
+      intel_renderbuffer_set_region(depth_rb, region);
+   if (stencil_rb)
+      intel_renderbuffer_set_region(stencil_rb, region);
+
+   /* FIXME: Tell the X server about the regions we just allocated and
+    * attached. */
+}
+
+#define BUFFER_FLAG_TILED 0x0100
+
+static void
+intelHandleBufferAttach(__DRIdrawablePrivate *dPriv,
+                       __DRIBufferAttachEvent *ba)
+{
+   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   struct intel_renderbuffer *rb;
+   struct intel_region *region;
+   struct intel_context *intel = dPriv->driContextPriv->driverPrivate;
+   GLuint tiled;
+
+   switch (ba->buffer.attachment) {
+   case DRI_DRAWABLE_BUFFER_FRONT_LEFT:
+      rb = intel_fb->color_rb[0];
+      break;
+
+   case DRI_DRAWABLE_BUFFER_BACK_LEFT:
+      rb = intel_fb->color_rb[0];
+      break;
+
+   case DRI_DRAWABLE_BUFFER_DEPTH:
+     rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+     break;
+
+   case DRI_DRAWABLE_BUFFER_STENCIL:
+     rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+     break;
+
+   case DRI_DRAWABLE_BUFFER_ACCUM:
+   default:
+      fprintf(stderr, "unhandled buffer attach event, attacment type %d\n",
+             ba->buffer.attachment);
+      return;
+   }
+
+#if 0
+   /* FIXME: Add this so we can filter out when the X server sends us
+    * attachment events for the buffers we just allocated.  Need to
+    * get the BO handle for a render buffer. */
+   if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle)
+      return;
+#endif
+
+   tiled = (ba->buffer.flags & BUFFER_FLAG_TILED) > 0;
+   region = intel_region_alloc_for_handle(intel, ba->buffer.cpp,
+                                         ba->buffer.pitch / ba->buffer.cpp,
+                                         dPriv->h, tiled,
+                                         ba->buffer.handle);
+
+   intel_renderbuffer_set_region(rb, region);
+}
+
+static void
+intelUpdateBuffer(__DRIdrawablePrivate *dPriv, unsigned int *event)
+{
+   switch (DRI2_EVENT_TYPE(*event)) {
+   case DRI2_EVENT_DRAWABLE_CONFIG:
+      /* flush all current regions, allocate new ones, except front buffer */
+      intelHandleDrawableConfig(dPriv, (__DRIDrawableConfigEvent *) event);
+      break;
+
+   case DRI2_EVENT_BUFFER_ATTACH:
+      /* attach buffer if different from what we have */
+      intelHandleBufferAttach(dPriv, (__DRIBufferAttachEvent *) event);
+      break;
+   }
+}
+
 static const __DRItexOffsetExtension intelTexOffsetExtension = {
    { __DRI_TEX_OFFSET },
    intelSetTexOffset,
@@ -569,6 +675,7 @@ static const struct __DriverAPIRec intelAPI = {
 #ifdef I915
    .setTexOffset = intelSetTexOffset,
 #endif
+   .UpdateBuffer = intelUpdateBuffer,
 };
 
 
@@ -723,3 +830,83 @@ struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
   return intel_context(ctx);
 }
 
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ * 
+ * \return the __GLcontextModes supported by this driver
+ */
+PUBLIC __GLcontextModes *__dri2DriverInitScreen(__DRIscreenPrivate *psp)
+{
+   static const __DRIversion ddx_expected = { 1, 9, 0 };
+   static const __DRIversion dri_expected = { 4, 0, 0 };
+   static const __DRIversion drm_expected = { 1, 5, 0 };
+   intelScreenPrivate *intelScreen;
+   __GLcontextModes *modes, *m;
+
+   psp->DriverAPI = intelAPI;
+
+   if (!driCheckDriDdxDrmVersions2("i915",
+                                   &psp->dri_version, &dri_expected,
+                                   &psp->ddx_version, &ddx_expected,
+                                   &psp->drm_version, &drm_expected)) {
+      fprintf(stderr, "bad version voodoo\n");
+      return 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
+    * *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?
+    */
+   driInitExtensions(NULL, card_extensions, GL_FALSE);
+   driInitExtensions(NULL, ttm_extensions, GL_FALSE);
+
+   /* 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;
+
+   /* Determine if IRQs are active? */
+   if (!intel_get_param(psp, I830_PARAM_IRQ_ACTIVE,
+                       &intelScreen->irq_active))
+      return GL_FALSE;
+
+   /* Determine if batchbuffers are allowed */
+   if (!intel_get_param(psp, I830_PARAM_ALLOW_BATCHBUFFER,
+                       &intelScreen->allow_batchbuffer))
+      return GL_FALSE;
+
+   if (!intelScreen->allow_batchbuffer) {
+      fprintf(stderr, "batch buffer not allowed\n");
+      return GL_FALSE;
+   }
+
+   psp->extensions = intelExtensions;
+
+   modes = intelFillInModes(16, 16, 0, 1);
+   for (m = modes; m->next != NULL; m = m->next)
+     ;
+   m->next = intelFillInModes(32, 24, 8, 1);
+
+   return modes;
+}