OSDN Git Service

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 5afaad0..550f467 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 18e7348..15ab9cb 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 58c8176..ac9e933 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 526e383..2ea4000 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 c193830..5cfb893 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 9a73b13..299da87 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