intel: Move the bufmgr back to the screen.
authorEric Anholt <eric@anholt.net>
Thu, 4 Sep 2008 21:16:31 +0000 (22:16 +0100)
committerEric Anholt <eric@anholt.net>
Wed, 10 Sep 2008 20:59:45 +0000 (13:59 -0700)
Mesa requires that we be able to share objects between contexts, which means
that the objects need to be created by the same bufmgr, and the bufmgr
internally requires pthread protection for thread safety.
Rely on the bufmgr having appropriate locking.

src/mesa/drivers/dri/intel/intel_batchbuffer.c
src/mesa/drivers/dri/intel/intel_context.c
src/mesa/drivers/dri/intel/intel_ioctl.c
src/mesa/drivers/dri/intel/intel_ioctl.h
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/intel/intel_screen.h

index 5afaad070cf537ce3cdc677e760a9195b343a356..550f467f830afa5de610f0e8f3d1ef00dd645099 100644 (file)
@@ -265,9 +265,9 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
 
       fprintf(stderr, "waiting for idle\n");
       LOCK_HARDWARE(intel);
-      irq = intelEmitIrqLocked(intel);
+      irq = intelEmitIrqLocked(intel->intelScreen);
       UNLOCK_HARDWARE(intel);
-      intelWaitIrq(intel, irq);
+      intelWaitIrq(intel->intelScreen, irq);
    }
 
    /* Reset the buffer:
index 18e73484ae877efb89c3c031b9a11941b6f8fe50..15ab9cbf358c2b2f4801d907d1b68889f5deb77c 100644 (file)
@@ -575,105 +575,6 @@ intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
 }
 #endif
 
-/** Driver-specific fence emit implementation for the fake memory manager. */
-static unsigned int
-intel_fence_emit(void *private)
-{
-   struct intel_context *intel = (struct intel_context *)private;
-   unsigned int fence;
-
-   /* XXX: Need to emit a flush, if we haven't already (at least with the
-    * current batchbuffer implementation, we have).
-    */
-
-   fence = intelEmitIrqLocked(intel);
-
-   return fence;
-}
-
-/** Driver-specific fence wait implementation for the fake memory manager. */
-static int
-intel_fence_wait(void *private, unsigned int cookie)
-{
-   struct intel_context *intel = (struct intel_context *)private;
-
-   intelWaitIrq(intel, cookie);
-
-   return 0;
-}
-
-static GLboolean
-intel_init_bufmgr(struct intel_context *intel)
-{
-   intelScreenPrivate *intelScreen = intel->intelScreen;
-   GLboolean gem_disable = getenv("INTEL_NO_GEM") != NULL;
-   int gem_kernel = 0;
-   GLboolean gem_supported;
-   struct drm_i915_getparam gp;
-
-   gp.param = I915_PARAM_HAS_GEM;
-   gp.value = &gem_kernel;
-
-   (void) drmCommandWriteRead(intel->driFd, DRM_I915_GETPARAM, &gp, sizeof(gp));
-
-   /* If we've got a new enough DDX that's initializing GEM and giving us
-    * object handles for the shared buffers, use that.
-    */
-   intel->ttm = GL_FALSE;
-   if (intel->intelScreen->driScrnPriv->dri2.enabled)
-       gem_supported = GL_TRUE;
-   else if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 9 &&
-           gem_kernel &&
-           intel->intelScreen->front.bo_handle != -1)
-       gem_supported = GL_TRUE;
-   else
-       gem_supported = GL_FALSE;
-
-   if (!gem_disable && gem_supported) {
-      int bo_reuse_mode;
-      intel->bufmgr = intel_bufmgr_gem_init(intel->driFd,
-                                           BATCH_SZ);
-      if (intel->bufmgr != NULL)
-        intel->ttm = GL_TRUE;
-
-      bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
-      switch (bo_reuse_mode) {
-      case DRI_CONF_BO_REUSE_DISABLED:
-        break;
-      case DRI_CONF_BO_REUSE_ALL:
-        intel_bufmgr_gem_enable_reuse(intel->bufmgr);
-        break;
-      }
-   }
-   /* Otherwise, use the classic buffer manager. */
-   if (intel->bufmgr == NULL) {
-      if (gem_disable) {
-        fprintf(stderr, "GEM disabled.  Using classic.\n");
-      } else {
-        fprintf(stderr, "Failed to initialize GEM.  "
-                "Falling back to classic.\n");
-      }
-
-      if (intelScreen->tex.size == 0) {
-        fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
-                __func__, __LINE__);
-        return GL_FALSE;
-      }
-
-      intel->bufmgr = intel_bufmgr_fake_init(intelScreen->tex.offset,
-                                            intelScreen->tex.map,
-                                            intelScreen->tex.size,
-                                            intel_fence_emit,
-                                            intel_fence_wait,
-                                            intel);
-   }
-
-   /* XXX bufmgr should be per-screen, not per-context */
-   intelScreen->ttm = intel->ttm;
-
-   return GL_TRUE;
-}
-
 void
 intelInitDriverFunctions(struct dd_function_table *functions)
 {
@@ -745,8 +646,20 @@ intelInitContext(struct intel_context *intel,
    else
       intel->maxBatchSize = BATCH_SZ;
 
-   if (!intel_init_bufmgr(intel))
-      return GL_FALSE;
+   intel->bufmgr = intelScreen->bufmgr;
+   intel->ttm = intelScreen->ttm;
+   if (intel->ttm) {
+      int bo_reuse_mode;
+
+      bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
+      switch (bo_reuse_mode) {
+      case DRI_CONF_BO_REUSE_DISABLED:
+        break;
+      case DRI_CONF_BO_REUSE_ALL:
+        intel_bufmgr_gem_enable_reuse(intel->bufmgr);
+        break;
+      }
+   }
 
    ctx->Const.MaxTextureMaxAnisotropy = 2.0;
 
index 58c81766cdd9e406cae2a65aaa1549ff738e35a5..ac9e9337d6fdb9ef9abaed774787e5a9c45e423d 100644 (file)
 #define FILE_DEBUG_FLAG DEBUG_IOCTL
 
 int
-intelEmitIrqLocked(struct intel_context *intel)
+intelEmitIrqLocked(intelScreenPrivate *intelScreen)
 {
+   __DRIscreenPrivate *spriv = intelScreen->driScrnPriv;
    struct drm_i915_irq_emit ie;
    int ret, seq = 1;
 
-   if (intel->no_hw)
+   if (intelScreen->no_hw)
       return 1;
 
    /*
-     assert(((*(int *)intel->driHwLock) & ~DRM_LOCK_CONT) ==
-     (DRM_LOCK_HELD|intel->hHWContext));
+     assert(((*(int *)intelScreen->driHwLock) & ~DRM_LOCK_CONT) ==
+     (DRM_LOCK_HELD|intelScreen->hHWContext));
    */
 
    ie.irq_seq = &seq;
 
-   ret = drmCommandWriteRead(intel->driFd, DRM_I915_IRQ_EMIT, &ie, sizeof(ie));
+   ret = drmCommandWriteRead(spriv->fd, DRM_I915_IRQ_EMIT, &ie, sizeof(ie));
    if (ret) {
       fprintf(stderr, "%s: drm_i915_irq_emit: %d\n", __FUNCTION__, ret);
       exit(1);
@@ -77,13 +78,15 @@ intelEmitIrqLocked(struct intel_context *intel)
 }
 
 void
-intelWaitIrq(struct intel_context *intel, int seq)
+intelWaitIrq(intelScreenPrivate *intelScreen, int seq)
 {
+   __DRIscreenPrivate *spriv = intelScreen->driScrnPriv;
    struct drm_i915_irq_wait iw;
    int ret, lastdispatch;
-   volatile struct drm_i915_sarea *sarea = intel->sarea;
+   volatile struct drm_i915_sarea *sarea = (struct drm_i915_sarea *)
+      (((GLubyte *) spriv->pSAREA) + intelScreen->sarea_priv_offset);
 
-   if (intel->no_hw)
+   if (intelScreen->no_hw)
       return;
 
    DBG("%s %d\n", __FUNCTION__, seq);
@@ -92,7 +95,7 @@ intelWaitIrq(struct intel_context *intel, int seq)
 
    do {
       lastdispatch = sarea->last_dispatch;
-      ret = drmCommandWrite(intel->driFd, DRM_I915_IRQ_WAIT, &iw, sizeof(iw));
+      ret = drmCommandWrite(spriv->fd, DRM_I915_IRQ_WAIT, &iw, sizeof(iw));
    } while (ret == -EAGAIN ||
            ret == -EINTR ||
            (ret == -EBUSY && lastdispatch != sarea->last_dispatch) ||
index 526e38358cc83509f9409bdb1496aff20af54e07..2ea40001db97954556089d1c884725856367a2ac 100644 (file)
@@ -30,8 +30,8 @@
 
 #include "intel_context.h"
 
-void intelWaitIrq( struct intel_context *intel, int seq );
-int intelEmitIrqLocked( struct intel_context *intel );
+void intelWaitIrq(intelScreenPrivate *intelScreen, int seq);
+int intelEmitIrqLocked(intelScreenPrivate *intelScreen);
 
 int intel_batch_ioctl(struct intel_context *intel,
                      GLuint start_offset,
index c193830f05fb40dbabeeede87d555656423ea5ce..5cfb89330569cc84096a47a8cfbee5083deb5263 100644 (file)
@@ -552,6 +552,96 @@ intelFillInModes(__DRIscreenPrivate *psp,
 }
 
 
+/** Driver-specific fence emit implementation for the fake memory manager. */
+static unsigned int
+intel_fence_emit(void *private)
+{
+   intelScreenPrivate *intelScreen = (intelScreenPrivate *)private;
+   unsigned int fence;
+
+   /* XXX: Need to emit a flush, if we haven't already (at least with the
+    * current batchbuffer implementation, we have).
+    */
+
+   fence = intelEmitIrqLocked(intelScreen);
+
+   return fence;
+}
+
+/** Driver-specific fence wait implementation for the fake memory manager. */
+static int
+intel_fence_wait(void *private, unsigned int cookie)
+{
+   intelScreenPrivate *intelScreen = (intelScreenPrivate *)private;
+
+   intelWaitIrq(intelScreen, cookie);
+
+   return 0;
+}
+
+static GLboolean
+intel_init_bufmgr(intelScreenPrivate *intelScreen)
+{
+   GLboolean gem_disable = getenv("INTEL_NO_GEM") != NULL;
+   int gem_kernel = 0;
+   GLboolean gem_supported;
+   struct drm_i915_getparam gp;
+   __DRIscreenPrivate *spriv = intelScreen->driScrnPriv;
+
+   intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
+
+   gp.param = I915_PARAM_HAS_GEM;
+   gp.value = &gem_kernel;
+
+   (void) drmCommandWriteRead(spriv->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
+
+   /* If we've got a new enough DDX that's initializing GEM and giving us
+    * object handles for the shared buffers, use that.
+    */
+   intelScreen->ttm = GL_FALSE;
+   if (intelScreen->driScrnPriv->dri2.enabled)
+       gem_supported = GL_TRUE;
+   else if (intelScreen->driScrnPriv->ddx_version.minor >= 9 &&
+           gem_kernel &&
+           intelScreen->front.bo_handle != -1)
+       gem_supported = GL_TRUE;
+   else
+       gem_supported = GL_FALSE;
+
+   if (!gem_disable && gem_supported) {
+      intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
+      if (intelScreen->bufmgr != NULL)
+        intelScreen->ttm = GL_TRUE;
+   }
+   /* Otherwise, use the classic buffer manager. */
+   if (intelScreen->bufmgr == NULL) {
+      if (gem_disable) {
+        fprintf(stderr, "GEM disabled.  Using classic.\n");
+      } else {
+        fprintf(stderr, "Failed to initialize GEM.  "
+                "Falling back to classic.\n");
+      }
+
+      if (intelScreen->tex.size == 0) {
+        fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
+                __func__, __LINE__);
+        return GL_FALSE;
+      }
+
+      intelScreen->bufmgr = intel_bufmgr_fake_init(intelScreen->tex.offset,
+                                                  intelScreen->tex.map,
+                                                  intelScreen->tex.size,
+                                                  intel_fence_emit,
+                                                  intel_fence_wait,
+                                                  intelScreen);
+   }
+
+   /* XXX bufmgr should be per-screen, not per-context */
+   intelScreen->ttm = intelScreen->ttm;
+
+   return GL_TRUE;
+}
+
 /**
  * This is the driver specific part of the createNewScreen entry point.
  * Called when using legacy DRI.
@@ -562,6 +652,7 @@ intelFillInModes(__DRIscreenPrivate *psp,
  */
 static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp)
 {
+   intelScreenPrivate *intelScreen;
 #ifdef I915
    static const __DRIversion ddx_expected = { 1, 5, 0 };
 #else
@@ -595,6 +686,10 @@ static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp)
 
    psp->extensions = intelScreenExtensions;
 
+   intelScreen = psp->private;
+   if (!intel_init_bufmgr(intelScreen))
+       return GL_FALSE;
+
    return (const __DRIconfig **)
        intelFillInModes(psp, dri_priv->cpp * 8,
                        (dri_priv->cpp == 2) ? 16 : 24,
@@ -659,6 +754,9 @@ __DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp)
                        &intelScreen->deviceID))
       return GL_FALSE;
 
+   if (!intel_init_bufmgr(intelScreen))
+       return GL_FALSE;
+
    intelScreen->irq_active = 1;
    psp->extensions = intelScreenExtensions;
 
index 9a73b13951798db90417d4f741e4dd6a2cf237f4..299da872100b759b41fafe0f02da698a0bb50f7c 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <sys/time.h>
 #include "dri_util.h"
+#include "dri_bufmgr.h"
 #include "i915_drm.h"
 #include "xmlconfig.h"
 
@@ -74,7 +75,10 @@ typedef struct
    int irq_active;
    int allow_batchbuffer;
 
+   GLboolean no_hw;
+
    int ttm;
+   dri_bufmgr *bufmgr;
 
    /**
    * Configuration cache with default values for all contexts