Allow regions to be hashed by name + offset in bytes to the base bo. Signed-off-by: Gwenole Beauchesne <gwenole.beauche...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev