Mesa (master): r300g: prevent creating multiple winsys BOs for the same handle

Marek Olšák mareko at kemper.freedesktop.org
Wed Sep 15 02:30:37 UTC 2010


Module: Mesa
Branch: master
Commit: 0b9eb5c9bb03e5134d9a41786178100109e80c5a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0b9eb5c9bb03e5134d9a41786178100109e80c5a

Author: Marek Olšák <maraeo at gmail.com>
Date:   Wed Sep 15 03:46:10 2010 +0200

r300g: prevent creating multiple winsys BOs for the same handle

This fixes a DRM deadlock in the cubestorm xscreensaver, because somehow
there must not be 2 different BOs relocated in one CS if both BOs back
the same handle. I was told it is impossible to happen, but apparently
it is not, or there is something else wrong.

---

 src/gallium/drivers/r300/r300_blit.c              |    4 ---
 src/gallium/winsys/radeon/drm/radeon_drm_buffer.c |   26 +++++++++++++++++++++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 77f0e27..91a374a 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -263,10 +263,6 @@ static void r300_clear(struct pipe_context* pipe,
          zstex->hiz_in_use[fb->zsbuf->level])) {
         r300->hyperz_state.dirty = TRUE;
     }
-
-    /* XXX this flush "fixes" a hardlock in the cubestorm xscreensaver */
-    if (r300->flush_counter == 0)
-        pipe->flush(pipe, 0, NULL);
 }
 
 /* Clear a region of a color surface to a constant value. */
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index 19f194b..46e8df7 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -5,6 +5,7 @@
 #include "radeon_cs_gem.h"
 #include "radeon_buffer.h"
 
+#include "util/u_hash_table.h"
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
 #include "util/u_simple_list.h"
@@ -41,6 +42,7 @@ struct radeon_drm_bufmgr {
     struct pb_manager base;
     struct radeon_libdrm_winsys *rws;
     struct radeon_drm_buffer buffer_map_list;
+    struct util_hash_table *buffer_handles;
 };
 
 static INLINE struct radeon_drm_bufmgr *
@@ -60,6 +62,9 @@ radeon_drm_buffer_destroy(struct pb_buffer *_buf)
 	radeon_bo_unmap(buf->bo);
 	buf->bo->ptr = NULL;
     }
+
+    util_hash_table_remove(buf->mgr->buffer_handles,
+                           (void*)(uintptr_t)buf->bo->handle);
     radeon_bo_unref(buf->bo);
 
     FREE(buf);
@@ -186,6 +191,13 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager
     struct radeon_drm_buffer *buf;
     struct radeon_bo *bo;
 
+    buf = util_hash_table_get(mgr->buffer_handles, (void*)(uintptr_t)handle);
+    if (buf) {
+        struct pb_buffer *b = NULL;
+        pb_reference(&b, &buf->base);
+        return b;
+    }
+
     bo = radeon_bo_open(rws->bom, handle, 0,
 			0, 0, 0);
     if (bo == NULL)
@@ -208,6 +220,8 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager
 
     buf->bo = bo;
 
+    util_hash_table_set(mgr->buffer_handles, (void*)(uintptr_t)handle, buf);
+
     return &buf->base;
 }
 
@@ -261,9 +275,20 @@ static void
 radeon_drm_bufmgr_destroy(struct pb_manager *_mgr)
 {
     struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+    util_hash_table_destroy(mgr->buffer_handles);
     FREE(mgr);
 }
 
+static unsigned handle_hash(void *key)
+{
+    return (unsigned)key;
+}
+
+static int handle_compare(void *key1, void *key2)
+{
+    return !((int)key1 == (int)key2);
+}
+
 struct pb_manager *
 radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
 {
@@ -279,6 +304,7 @@ radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
 
     mgr->rws = rws;
     make_empty_list(&mgr->buffer_map_list);
+    mgr->buffer_handles = util_hash_table_create(handle_hash, handle_compare);
     return &mgr->base;
 }
 




More information about the mesa-commit mailing list