Convert TTM code to require the server provide buffers for front/back/depth.
authorEric Anholt <eric@anholt.net>
Thu, 16 Aug 2007 21:32:53 +0000 (14:32 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 16 Aug 2007 21:38:33 +0000 (14:38 -0700)
This removes the use of fake buffers from the driver, such that it could
probably be removed from the interface.  It also should assist in proper
synchronization of access.

src/mesa/drivers/dri/common/dri_bufmgr.h
src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
src/mesa/drivers/dri/i915tex/intel_regions.c
src/mesa/drivers/dri/i915tex/intel_regions.h
src/mesa/drivers/dri/i915tex/intel_screen.c
src/mesa/drivers/dri/i915tex/intel_screen.h
src/mesa/drivers/dri/i915tex/server/i830_common.h

index 0f8e27923be8d634fe23caff5423a5033d4ad6d5..3be342926f74e9d1de1321553a1ca7ba2b674bfd 100644 (file)
@@ -192,5 +192,7 @@ dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
                                                   unsigned int cookie),
                                 void *driver_priv);
 void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
+dri_bo *dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
+                                     unsigned int handle);
 
 #endif
index 2d4f518b315978d85799be5f3f2c53582f6df0b6..5128d9537065cd6e371832fc2108771364de65c0 100644 (file)
@@ -131,15 +131,30 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,
    return &ttm_buf->bo;
 }
 
+/* Our TTM backend doesn't allow creation of static buffers, as that requires
+ * privelege for the non-fake case, and the lock in the fake case where we were
+ * working around the X Server not creating buffers and passing handles to us.
+ */
 static dri_bo *
 dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
                     unsigned long offset, unsigned long size, void *virtual,
                     unsigned int location_mask)
+{
+   return NULL;
+}
+
+/** Returns a dri_bo wrapping the given buffer object handle.
+ *
+ * This can be used when one application needs to pass a buffer object
+ * to another.
+ */
+dri_bo *
+dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
+                             unsigned int handle)
 {
    dri_bufmgr_ttm *ttm_bufmgr;
    dri_bo_ttm *ttm_buf;
    int ret;
-   unsigned int flags, hint;
 
    ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
 
@@ -147,25 +162,14 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
    if (!ttm_buf)
       return NULL;
 
-   /* The mask argument doesn't do anything for us that we want other than
-    * determine which pool (TTM or local) the buffer is allocated into, so just
-    * pass all of the allocation class flags.
-    */
-   flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
-      DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_MOVE;
-   /* No hints we want to use. */
-   hint = 0;
-
-   ret = drmBOCreate(ttm_bufmgr->fd, offset, size, 0,
-                    NULL, drm_bo_type_fake,
-                     flags, hint, &ttm_buf->drm_bo);
+   ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo);
    if (ret != 0) {
       free(ttm_buf);
       return NULL;
    }
    ttm_buf->bo.size = ttm_buf->drm_bo.size;
    ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
-   ttm_buf->bo.virtual = virtual;
+   ttm_buf->bo.virtual = NULL;
    ttm_buf->bo.bufmgr = bufmgr;
    ttm_buf->name = name;
    ttm_buf->refcount = 1;
@@ -367,7 +371,6 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
                    unsigned int fence_type_flush)
 {
    dri_bufmgr_ttm *bufmgr_ttm;
-   dri_bo *test_alloc;
 
    bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
    bufmgr_ttm->fd = fd;
@@ -388,18 +391,5 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
    bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait;
    bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy;
 
-   /* Attempt an allocation to make sure that the DRM was actually set up for
-    * TTM.
-    */
-   test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation",
-     4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT);
-   if (test_alloc == NULL) {
-      fprintf(stderr, "TTM test allocation failed\n");
-      _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
-      free(bufmgr_ttm);
-      return NULL;
-   }
-   dri_bo_unreference(test_alloc);
-
    return &bufmgr_ttm->bufmgr;
 }
index 4e3cea5e05e1b2914ca6abcf67dca05ddaf25d50..4eac859a13356fd8fd4c82a9f19ee1bb41a5a736 100644 (file)
@@ -147,6 +147,7 @@ intel_region_release(struct intel_region **region)
 struct intel_region *
 intel_region_create_static(intelScreenPrivate *intelScreen,
                            GLuint mem_type,
+                          unsigned int bo_handle,
                            GLuint offset,
                            void *virtual,
                            GLuint cpp, GLuint pitch, GLuint height)
@@ -159,9 +160,18 @@ intel_region_create_static(intelScreenPrivate *intelScreen,
    region->height = height;     /* needed? */
    region->refcount = 1;
 
-   region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region",
-                                       offset, pitch * cpp * height, virtual,
-                                       DRM_BO_FLAG_MEM_TT);
+   if (intelScreen->ttm) {
+      assert(bo_handle != -1);
+      region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr,
+                                                    "static region",
+                                                    bo_handle);
+   } else {
+      region->buffer = dri_bo_alloc_static(intelScreen->bufmgr,
+                                          "static region",
+                                          offset, pitch * cpp * height,
+                                          virtual,
+                                          DRM_BO_FLAG_MEM_TT);
+   }
 
    return region;
 }
@@ -172,6 +182,7 @@ void
 intel_region_update_static(intelScreenPrivate *intelScreen,
                           struct intel_region *region,
                            GLuint mem_type,
+                          unsigned int bo_handle,
                            GLuint offset,
                            void *virtual,
                            GLuint cpp, GLuint pitch, GLuint height)
@@ -188,9 +199,18 @@ intel_region_update_static(intelScreenPrivate *intelScreen,
     */
 
    dri_bo_unreference(region->buffer);
-   region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region",
-                                       offset, pitch * cpp * height, virtual,
-                                       DRM_BO_FLAG_MEM_TT);
+   if (intelScreen->ttm) {
+      assert(bo_handle != -1);
+      region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr,
+                                                    "static region",
+                                                    bo_handle);
+   } else {
+      region->buffer = dri_bo_alloc_static(intelScreen->bufmgr,
+                                          "static region",
+                                          offset, pitch * cpp * height,
+                                          virtual,
+                                          DRM_BO_FLAG_MEM_TT);
+   }
 }
 
 
index 9623cf7bd5647e3741dc2d7e8932f333a1e972d4..42d7b177117147512f4a360865463721b199413c 100644 (file)
@@ -73,6 +73,7 @@ void intel_region_release(struct intel_region **ib);
 extern struct intel_region 
 *intel_region_create_static(intelScreenPrivate *intelScreen,
                            GLuint mem_type,
+                           unsigned int bo_handle,
                            GLuint offset,
                            void *virtual,
                            GLuint cpp,
@@ -81,6 +82,7 @@ extern void
 intel_region_update_static(intelScreenPrivate *intelScreen,
                           struct intel_region *region,
                           GLuint mem_type,
+                          unsigned int bo_handle,
                           GLuint offset,
                           void *virtual,
                           GLuint cpp, GLuint pitch, GLuint height);
index a0471019e43f86765fc314a1f85f73de7ecc4246..2721a900945396b731c5df825e1ea86f1fe6233a 100644 (file)
@@ -170,18 +170,26 @@ intel_fence_wait(void *private, unsigned int cookie)
 static struct intel_region *
 intel_recreate_static(intelScreenPrivate *intelScreen,
                      struct intel_region *region,
-                     GLuint mem_type,
-                     GLuint offset,
-                     void *virtual,
-                     GLuint cpp, GLuint pitch, GLuint height)
+                     intelRegion *region_desc,
+                     GLuint mem_type)
 {
   if (region) {
-    intel_region_update_static(intelScreen, region, mem_type, offset,
-                              virtual, cpp, pitch, height);
+    intel_region_update_static(intelScreen, region, mem_type,
+                              region_desc->bo_handle, region_desc->offset,
+                              region_desc->map, intelScreen->cpp,
+                              region_desc->pitch / intelScreen->cpp,
+                              intelScreen->height);
   } else {
-    region = intel_region_create_static(intelScreen, mem_type, offset,
-                                       virtual, cpp, pitch, height);
+    region = intel_region_create_static(intelScreen, mem_type,
+                                       region_desc->bo_handle,
+                                       region_desc->offset,
+                                       region_desc->map, intelScreen->cpp,
+                                       region_desc->pitch / intelScreen->cpp,
+                                       intelScreen->height);
   }
+
+  assert(region->buffer != NULL);
+
   return region;
 }
     
@@ -203,57 +211,42 @@ intel_recreate_static_regions(intelScreenPrivate *intelScreen)
    intelScreen->front_region =
       intel_recreate_static(intelScreen,
                            intelScreen->front_region,
-                           DRM_BO_FLAG_MEM_TT,
-                           intelScreen->front.offset,
-                           intelScreen->front.map,
-                           intelScreen->cpp,
-                           intelScreen->front.pitch / intelScreen->cpp,
-                           intelScreen->height);
-
-   intelScreen->rotated_region =
-      intel_recreate_static(intelScreen,
-                           intelScreen->rotated_region,
-                           DRM_BO_FLAG_MEM_TT,
-                           intelScreen->rotated.offset,
-                           intelScreen->rotated.map,
-                           intelScreen->cpp,
-                           intelScreen->rotated.pitch /
-                           intelScreen->cpp, intelScreen->height);
+                           &intelScreen->front,
+                           DRM_BO_FLAG_MEM_TT);
 
+   /* The rotated region is only used for old DDXes that didn't handle rotation
+\    * on their own.
+    */
+   if (intelScreen->driScrnPriv->ddxMinor < 8) {
+      intelScreen->rotated_region =
+        intel_recreate_static(intelScreen,
+                              intelScreen->rotated_region,
+                              &intelScreen->rotated,
+                              DRM_BO_FLAG_MEM_TT);
+   }
 
    intelScreen->back_region =
       intel_recreate_static(intelScreen,
                            intelScreen->back_region,
-                           DRM_BO_FLAG_MEM_TT,
-                           intelScreen->back.offset,
-                           intelScreen->back.map,
-                           intelScreen->cpp,
-                           intelScreen->back.pitch / intelScreen->cpp,
-                           intelScreen->height);
+                           &intelScreen->back,
+                           DRM_BO_FLAG_MEM_TT);
 
    if (intelScreen->third.handle) {
       intelScreen->third_region =
         intel_recreate_static(intelScreen,
                               intelScreen->third_region,
-                              DRM_BO_FLAG_MEM_TT,
-                              intelScreen->third.offset,
-                              intelScreen->third.map,
-                              intelScreen->cpp,
-                              intelScreen->third.pitch / intelScreen->cpp,
-                              intelScreen->height);
+                              &intelScreen->third,
+                              DRM_BO_FLAG_MEM_TT);
    }
 
-   /* Still assuming front.cpp == depth.cpp
+   /* Still assumes front.cpp == depth.cpp.  We can kill this when we move to
+    * private buffers.
     */
    intelScreen->depth_region =
       intel_recreate_static(intelScreen,
                            intelScreen->depth_region,
-                           DRM_BO_FLAG_MEM_TT,
-                           intelScreen->depth.offset,
-                           intelScreen->depth.map,
-                           intelScreen->cpp,
-                           intelScreen->depth.pitch / intelScreen->cpp,
-                           intelScreen->height);
+                           &intelScreen->depth,
+                           DRM_BO_FLAG_MEM_TT);
 }
 
 /**
@@ -396,6 +389,18 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
    intelScreen->depth.handle = sarea->depth_handle;
    intelScreen->depth.size = sarea->depth_size;
 
+   if (intelScreen->driScrnPriv->ddxMinor >= 9) {
+      intelScreen->front.bo_handle = sarea->front_bo_handle;
+      intelScreen->back.bo_handle = sarea->back_bo_handle;
+      intelScreen->third.bo_handle = sarea->third_bo_handle;
+      intelScreen->depth.bo_handle = sarea->depth_bo_handle;
+   } else {
+      intelScreen->front.bo_handle = -1;
+      intelScreen->back.bo_handle = -1;
+      intelScreen->third.bo_handle = -1;
+      intelScreen->depth.bo_handle = -1;
+   }
+
    intelScreen->tex.offset = sarea->tex_offset;
    intelScreen->logTextureGranularity = sarea->log_tex_granularity;
    intelScreen->tex.handle = sarea->tex_handle;
@@ -526,10 +531,21 @@ intelInitDriver(__DRIscreenPrivate * sPriv)
       (*glx_enable_extension) (psc, "GLX_SGI_make_current_read");
    }
 
-   intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd,
-                                            DRM_FENCE_TYPE_EXE,
-                                            DRM_FENCE_TYPE_EXE |
-                                            DRM_I915_FENCE_TYPE_RW);
+   /* If we've got a new enough DDX that's initializing TTM and giving us
+    * object handles for the shared buffers, use that.
+    */
+   intelScreen->ttm = GL_FALSE;
+   if (getenv("INTEL_NO_TTM") == NULL &&
+       intelScreen->driScrnPriv->ddxMinor >= 9 &&
+       intelScreen->front.bo_handle != -1) {
+      intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd,
+                                               DRM_FENCE_TYPE_EXE,
+                                               DRM_FENCE_TYPE_EXE |
+                                               DRM_I915_FENCE_TYPE_RW);
+      if (intelScreen->bufmgr != NULL)
+        intelScreen->ttm = GL_TRUE;
+   }
+   /* Otherwise, use the classic buffer manager. */
    if (intelScreen->bufmgr == NULL) {
       if (intelScreen->tex.size == 0) {
         fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
index 168793d05a6cd90911da5bb159ada5add7c1b1cf..aa0ef2c5090aeb534d37ef9d403961fb54743bf6 100644 (file)
@@ -45,6 +45,7 @@ typedef struct
    char *map;                   /* memory map */
    int offset;                  /* from start of video mem, in bytes */
    int pitch;                   /* row stride, in bytes */
+   unsigned int bo_handle;     /* buffer object id if available, or -1 */
 } intelRegion;
 
 typedef struct
index 7a76957c6a1afecd2173b832c061f2ca36028897..bd2bec3eaea840d9c1b52c8f13355d77e6624ab1 100644 (file)
@@ -136,6 +136,15 @@ typedef struct {
        int third_offset;
        int third_size;
        unsigned int third_tiled;
+
+       /* buffer object handles for the static buffers.  May change
+        * over the lifetime of the client, though it doesn't in our current
+        * implementation.
+        */
+       unsigned int front_bo_handle;
+       unsigned int back_bo_handle;
+       unsigned int third_bo_handle;
+       unsigned int depth_bo_handle;
 } drmI830Sarea;
 
 /* Flags for perf_boxes