intel: Track named regions and make sure we only have one region per named bo
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 11 Feb 2010 22:18:01 +0000 (17:18 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 12 Feb 2010 21:30:39 +0000 (16:30 -0500)
src/mesa/drivers/dri/intel/intel_regions.c
src/mesa/drivers/dri/intel/intel_regions.h
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/intel/intel_screen.h

index e2859e44f95c63902eddefd15157969c4c3c974e..881653ff01f835dc4578da76f3e0c35c58fe801d 100644 (file)
@@ -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;
index 860ae11bd2321d1e7cbe02d20719ff9687be0c3a..6d36f3d88a0dc27413914775bd3c71729672381b 100644 (file)
@@ -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;
 };
 
 
index 6dc20d0fefe6e9dd04975946af69ade44d4888f7..f7ce87e063f3822f2fa24285f60c3054c3343662 100644 (file)
@@ -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"
@@ -166,6 +167,11 @@ intel_get_param(__DRIscreen *psp, int param, int *value)
    return GL_TRUE;
 }
 
+static void
+nop_callback(GLuint key, void *data, void *userData)
+{
+}
+
 static void
 intelDestroyScreen(__DRIscreen * sPriv)
 {
@@ -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;
 }
 
index c31b83655251dd7e6427ed6b75f93b25a514ca0c..1ce476dacaa9469d591dc6e9d60ecf0b1a0d1b5c 100644 (file)
@@ -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