[Mesa-dev] [PATCH 2/7] intel: allow regions hashing per name + plane id.

Gwenole Beauchesne gb.devel at gmail.com
Tue Apr 24 08:30:34 PDT 2012


Allow regions to be hashed from a single key (name) and plane id. This
is preparatory work to support multitexturing from a single YUV buffer.
---
 src/mesa/drivers/dri/intel/intel_regions.c |   98 ++++++++++++++++++++++++++--
 src/mesa/drivers/dri/intel/intel_regions.h |    9 +++
 src/mesa/drivers/dri/intel/intel_screen.c  |   13 +---
 3 files changed, 104 insertions(+), 16 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index f10424d..70619af 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -104,7 +104,95 @@ debug_backtrace(void)
 
 #endif
 
+/* Region hash utilities */
+#define MAX_PLANES 3
 
+struct hash_entry {
+    struct intel_region *regions[MAX_PLANES];
+    unsigned int num_regions;
+};
+
+static inline struct hash_entry *
+hash_entry_new(void)
+{
+    return calloc(1, sizeof(struct hash_entry));
+}
+
+static inline void
+hash_entry_destroy(struct hash_entry *e)
+{
+    free(e);
+}
+
+static void
+intel_region_hash_destroy_callback(GLuint key, void *data, void *userData)
+{
+    hash_entry_destroy(data);
+}
+
+struct _mesa_HashTable *
+intel_region_hash_new(void)
+{
+    return _mesa_NewHashTable();
+}
+
+void
+intel_region_hash_destroy(struct _mesa_HashTable **h_ptr)
+{
+    struct _mesa_HashTable * const h = *h_ptr;
+
+   /* 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(h, intel_region_hash_destroy_callback, NULL);
+   _mesa_DeleteHashTable(h);
+   *h_ptr = NULL;
+}
+
+static inline struct intel_region *
+intel_region_hash_lookup(struct _mesa_HashTable *h, uint32_t name, uint32_t id)
+{
+    struct hash_entry * const e = _mesa_HashLookup(h, name);
+
+    if (e && id < ARRAY_SIZE(e->regions))
+        return e->regions[id];
+    return NULL;
+}
+
+static void
+intel_region_hash_insert(struct _mesa_HashTable *h, struct intel_region *region)
+{
+    struct hash_entry *e = _mesa_HashLookup(h, region->name);
+
+    if (!e) {
+        e = hash_entry_new();
+        if (!e)
+            return;
+        _mesa_HashInsert(h, region->name, e);
+    }
+
+    if (region->plane_id < ARRAY_SIZE(e->regions)) {
+        if (!e->regions[region->plane_id])
+            e->num_regions++;
+        e->regions[region->plane_id] = region;
+    }
+}
+
+static void
+intel_region_hash_remove(struct _mesa_HashTable *h, struct intel_region *region)
+{
+    struct hash_entry * const e = _mesa_HashLookup(h, region->name);
+
+    if (e && region->plane_id < ARRAY_SIZE(e->regions)) {
+        e->regions[region->plane_id] = NULL;
+        e->num_regions--;
+    }
+
+    if (e->num_regions == 0) {
+        _mesa_HashRemove(h, region->name);
+        hash_entry_destroy(e);
+    }
+}
 
 /* XXX: Thread safety?
  */
@@ -169,6 +257,7 @@ intel_region_alloc_internal(struct intel_screen *screen,
    if (region == NULL)
       return region;
 
+   region->plane_id = 0;
    region->cpp = attrs->cpp;
    region->width = attrs->width;
    region->height = attrs->height;
@@ -223,8 +312,7 @@ intel_region_flink(struct intel_region *region, uint32_t *name)
       if (drm_intel_bo_flink(region->bo, &region->name))
 	 return false;
       
-      _mesa_HashInsert(region->screen->named_regions,
-		       region->name, region);
+      intel_region_hash_insert(region->screen->named_regions, region);
    }
 
    *name = region->name;
@@ -252,7 +340,7 @@ intel_region_alloc_for_handle2(struct intel_screen *screen,
    int ret;
    uint32_t bit_6_swizzle, tiling;
 
-   region = _mesa_HashLookup(screen->named_regions, handle);
+   region = intel_region_hash_lookup(screen->named_regions, handle, 0);
    if (region != NULL) {
       dummy = NULL;
       if (!intel_region_validate_attributes(region, attrs)) {
@@ -283,7 +371,7 @@ intel_region_alloc_for_handle2(struct intel_screen *screen,
    }
 
    region->name = handle;
-   _mesa_HashInsert(screen->named_regions, handle, region);
+   intel_region_hash_insert(screen->named_regions, region);
 
    return region;
 }
@@ -325,7 +413,7 @@ intel_region_release(struct intel_region **region_handle)
       drm_intel_bo_unreference(region->bo);
 
       if (region->name > 0)
-	 _mesa_HashRemove(region->screen->named_regions, region->name);
+	 intel_region_hash_remove(region->screen->named_regions, region);
 
       free(region);
    }
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 00cdab9..acfecd6 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -56,6 +56,7 @@ struct intel_region
 {
    drm_intel_bo *bo;  /**< buffer manager's buffer */
    GLuint refcount; /**< Reference count for region */
+   GLuint plane_id; /**< Plane id out of 3 (range: 0..2) */
    GLuint cpp;      /**< bytes per pixel */
    GLuint width;    /**< in pixels */
    GLuint height;   /**< in pixels */
@@ -164,4 +165,12 @@ struct __DRIimageRec {
    void *data;
 };
 
+struct _mesa_HashTable;
+
+struct _mesa_HashTable *
+intel_region_hash_new(void);
+
+void
+intel_region_hash_destroy(struct _mesa_HashTable **h);
+
 #endif
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index e823792..7f9d037 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -429,11 +429,6 @@ intel_get_boolean(__DRIscreen *psp, int param)
 }
 
 static void
-nop_callback(GLuint key, void *data, void *userData)
-{
-}
-
-static void
 intelDestroyScreen(__DRIscreen * sPriv)
 {
    struct intel_screen *intelScreen = sPriv->driverPrivate;
@@ -441,11 +436,7 @@ 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);
+   intel_region_hash_destroy(&intelScreen->named_regions);
 
    FREE(intelScreen);
    sPriv->driverPrivate = NULL;
@@ -651,7 +642,7 @@ intel_init_bufmgr(struct intel_screen *intelScreen)
 
    drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
 
-   intelScreen->named_regions = _mesa_NewHashTable();
+   intelScreen->named_regions = intel_region_hash_new();
 
    intelScreen->relaxed_relocations = 0;
    intelScreen->relaxed_relocations |=
-- 
1.7.5.4



More information about the mesa-dev mailing list