[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, ®ion->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