[Mesa-dev] [PATCH 3/3] intel: allow region hash with offset specification.
Gwenole Beauchesne
gb.devel at gmail.com
Fri Apr 20 09:39:05 PDT 2012
Allow regions to be hashed by name + offset in bytes to the base bo.
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
src/mesa/drivers/dri/intel/intel_regions.c | 105 ++++++++++++++++++++++++++--
1 files changed, 99 insertions(+), 6 deletions(-)
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 235c2cd..0028326 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -106,7 +106,7 @@ debug_backtrace(void)
/* Forward declarations */
static struct intel_region *
-intel_region_hash_lookup(struct _mesa_HashTable *h, uint32_t name);
+intel_region_hash_lookup(struct _mesa_HashTable *h, uint32_t name, uint32_t ofs);
static void
intel_region_hash_insert(struct _mesa_HashTable *h,
@@ -250,7 +250,7 @@ intel_region_alloc_for_handle(struct intel_screen *screen,
int ret;
uint32_t bit_6_swizzle, tiling;
- region = intel_region_hash_lookup(screen->named_regions, handle);
+ region = intel_region_hash_lookup(screen->named_regions, handle, 0);
if (region != NULL) {
dummy = NULL;
if (region->width != width || region->height != height ||
@@ -401,9 +401,55 @@ intel_region_copy(struct intel_context *intel,
logicop);
}
+struct hash_entry {
+ struct intel_region *base_region; /* base region for offset = 0 */
+ struct intel_region **regions;
+ unsigned int num_regions;
+ unsigned int max_regions;
+};
+
+static inline struct hash_entry *
+hash_entry_new(void)
+{
+ return calloc(1, sizeof(struct hash_entry));
+}
+
+static void
+hash_entry_destroy(struct hash_entry *e)
+{
+ if (e->regions) {
+ free(e->regions);
+ e->regions = NULL;
+ }
+ free(e);
+}
+
+static void
+hash_entry_append_region(struct hash_entry *e, struct intel_region *region)
+{
+ struct intel_region **new_regions;
+ unsigned int i, num_regions;
+
+ for (i = 0; i < e->num_regions; i++) {
+ if (e->regions[i]->offset == region->offset)
+ return;
+ }
+
+ if (e->num_regions >= e->max_regions) {
+ num_regions = e->max_regions + 4;
+ new_regions = realloc(e->regions, num_regions * sizeof(*new_regions));
+ if (!new_regions)
+ return;
+ e->regions = new_regions;
+ e->max_regions = num_regions;
+ }
+ e->regions[e->num_regions++] = region;
+}
+
static void
intel_region_hash_destroy_callback(GLuint key, void *data, void *userData)
{
+ hash_entry_destroy(data);
}
struct _mesa_HashTable *
@@ -426,19 +472,66 @@ intel_region_hash_destroy(struct _mesa_HashTable **h_ptr)
}
static struct intel_region *
-intel_region_hash_lookup(struct _mesa_HashTable *h, uint32_t name)
+intel_region_hash_lookup(struct _mesa_HashTable *h, uint32_t name, uint32_t offset)
{
- return _mesa_HashLookup(h, name);
+ struct hash_entry * const e = _mesa_HashLookup(h, name);
+ unsigned int i;
+
+ if (!e)
+ return NULL;
+
+ if (offset == 0) {
+ assert(e->base_region);
+ return e->base_region;
+ }
+
+ for (i = 0; i < e->num_regions; i++) {
+ struct intel_region * const region = e->regions[i];
+ if (region->offset == offset)
+ return region;
+ }
+ return NULL;
}
static void
intel_region_hash_insert(struct _mesa_HashTable *h, struct intel_region *region)
{
- _mesa_HashInsert(h, region->name, 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->offset == 0)
+ e->base_region = region;
+ else
+ hash_entry_append_region(e, region);
}
static void
intel_region_hash_remove(struct _mesa_HashTable *h, struct intel_region *region)
{
- _mesa_HashRemove(h, region->name);
+ struct hash_entry * const e = _mesa_HashLookup(h, region->name);
+ unsigned int i;
+
+ if (region->offset == 0)
+ e->base_region = NULL;
+ else {
+ for (i = 0; i < e->num_regions; i++) {
+ if (e->regions[i]->offset == region->offset) {
+ if (--e->num_regions > i) /* swap with the last entry */
+ e->regions[i] = e->regions[e->num_regions];
+ e->regions[e->num_regions] = NULL;
+ break;
+ }
+ }
+ }
+
+ if (!e->base_region && e->num_regions == 0) {
+ _mesa_HashRemove(h, region->name);
+ hash_entry_destroy(e);
+ }
}
--
1.7.5.4
More information about the mesa-dev
mailing list