Mesa (master): intel: Track named regions and make sure we only have one region per named bo

Kristian Høgsberg krh at kemper.freedesktop.org
Fri Feb 12 21:39:05 UTC 2010


Module: Mesa
Branch: master
Commit: 2d99588b3556928a0879b4160210ac771dbf1f0b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2d99588b3556928a0879b4160210ac771dbf1f0b

Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Thu Feb 11 17:18:01 2010 -0500

intel: Track named regions and make sure we only have one region per named bo

---

 src/mesa/drivers/dri/intel/intel_regions.c |   24 +++++++++++++++++++++++-
 src/mesa/drivers/dri/intel/intel_regions.h |    3 +++
 src/mesa/drivers/dri/intel/intel_screen.c  |   14 ++++++++++++++
 src/mesa/drivers/dri/intel/intel_screen.h  |    1 +
 4 files changed, 41 insertions(+), 1 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index e2859e4..881653f 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -42,6 +42,7 @@
 #include <sys/ioctl.h>
 #include <errno.h>
 
+#include <main/hash.h>
 #include "intel_context.h"
 #include "intel_regions.h"
 #include "intel_blit.h"
@@ -228,10 +229,24 @@ intel_region_alloc_for_handle(struct intel_context *intel,
 			      GLuint width, GLuint height, GLuint pitch,
 			      GLuint handle, const char *name)
 {
-   struct intel_region *region;
+   struct intel_region *region, *dummy;
    dri_bo *buffer;
    int ret;
 
+   region = _mesa_HashLookup(intel->intelScreen->named_regions, handle);
+   if (region != NULL) {
+      dummy = NULL;
+      if (region->width != width || region->height != height ||
+	  region->cpp != cpp || region->pitch != pitch) {
+	 fprintf(stderr,
+		 "Region for name %d already exists but is not compatible\n",
+		 handle);
+	 return NULL;
+      }
+      intel_region_reference(&dummy, region);
+      return dummy;
+   }
+
    buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, handle);
 
    region = intel_region_alloc_internal(intel, cpp,
@@ -248,6 +263,10 @@ intel_region_alloc_for_handle(struct intel_context *intel,
       return NULL;
    }
 
+   region->name = handle;
+   region->screen = intel->intelScreen;
+   _mesa_HashInsert(intel->intelScreen->named_regions, handle, region);
+
    return region;
 }
 
@@ -287,6 +306,9 @@ intel_region_release(struct intel_region **region_handle)
       region->pbo = NULL;
       dri_bo_unreference(region->buffer);
 
+      if (region->name > 0)
+	 _mesa_HashRemove(region->screen->named_regions, region->name);
+
       free(region);
    }
    *region_handle = NULL;
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 860ae11..6d36f3d 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -67,6 +67,9 @@ struct intel_region
    uint32_t tiling; /**< Which tiling mode the region is in */
    uint32_t bit_6_swizzle; /**< GEM flag for address swizzling requirement */
    struct intel_buffer_object *pbo;     /* zero-copy uploads */
+
+   uint32_t name; /**< Global name for the bo */
+   struct intel_screen *screen;
 };
 
 
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 6dc20d0..f7ce87e 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -29,6 +29,7 @@
 #include "main/context.h"
 #include "main/framebuffer.h"
 #include "main/renderbuffer.h"
+#include "main/hash.h"
 
 #include "utils.h"
 #include "xmlpool.h"
@@ -167,6 +168,11 @@ intel_get_param(__DRIscreen *psp, int param, int *value)
 }
 
 static void
+nop_callback(GLuint key, void *data, void *userData)
+{
+}
+
+static void
 intelDestroyScreen(__DRIscreen * sPriv)
 {
    struct intel_screen *intelScreen = sPriv->private;
@@ -174,6 +180,12 @@ intelDestroyScreen(__DRIscreen * sPriv)
    dri_bufmgr_destroy(intelScreen->bufmgr);
    driDestroyOptionInfo(&intelScreen->optionCache);
 
+   /* Some regions may still have references to them at this point, so
+    * flush the hash table to prevent _mesa_DeleteHashTable() from
+    * complaining about the hash not being empty; */
+   _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
+   _mesa_DeleteHashTable(intelScreen->named_regions);
+
    FREE(intelScreen);
    sPriv->private = NULL;
 }
@@ -324,6 +336,8 @@ intel_init_bufmgr(struct intel_screen *intelScreen)
    else
       intelScreen->kernel_exec_fencing = GL_FALSE;
 
+   intelScreen->named_regions = _mesa_NewHashTable();
+
    return GL_TRUE;
 }
 
diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h
index c31b836..1ce476d 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.h
+++ b/src/mesa/drivers/dri/intel/intel_screen.h
@@ -47,6 +47,7 @@ struct intel_screen
    GLboolean no_vbo;
    dri_bufmgr *bufmgr;
    GLboolean kernel_exec_fencing;
+   struct _mesa_HashTable *named_regions;
 
    /**
    * Configuration cache with default values for all contexts




More information about the mesa-commit mailing list