summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <[email protected]>2012-08-30 10:26:48 +0200
committerChristian König <[email protected]>2012-09-04 10:51:38 +0200
commit73dd82061e7a5242c88b529c274784731462e039 (patch)
treeb4c9f85392d5d0655fab297258c550161280fe13
parent88a4fd8fe6b47b4685e3fb5e36047d27f764703b (diff)
winsys/radeon: create only one winsys for each fd
Fixing problems with GLAMOR. Signed-off-by: Christian König <[email protected]> Reviewed-by: Michel Dänzer <[email protected]>
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_winsys.c38
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_winsys.h5
2 files changed, 41 insertions, 2 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index c03dd045edf..33451abdf8a 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -37,6 +37,7 @@
#include "pipebuffer/pb_bufmgr.h"
#include "util/u_memory.h"
+#include "util/u_hash_table.h"
#include <xf86drm.h>
#include <stdio.h>
@@ -89,6 +90,7 @@
#define RADEON_INFO_TIMESTAMP 0x11
#endif
+static struct util_hash_table *fd_tab = NULL;
/* Enable/disable feature access for one command stream.
* If enable == TRUE, return TRUE on success.
@@ -318,6 +320,10 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
{
struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
+ if (!pipe_reference(&ws->base.reference, NULL)) {
+ return;
+ }
+
pipe_mutex_destroy(ws->hyperz_owner_mutex);
pipe_mutex_destroy(ws->cmask_owner_mutex);
@@ -326,6 +332,9 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
if (ws->gen >= R600) {
radeon_surface_manager_free(ws->surf_man);
}
+ if (fd_tab) {
+ util_hash_table_remove(fd_tab, intptr_to_pointer(ws->fd));
+ }
FREE(rws);
}
@@ -395,14 +404,36 @@ static uint64_t radeon_query_timestamp(struct radeon_winsys *rws)
return ts;
}
+static unsigned hash_fd(void *key)
+{
+ return pointer_to_intptr(key);
+}
+
+static int compare_fd(void *key1, void *key2)
+{
+ return pointer_to_intptr(key1) != pointer_to_intptr(key2);
+}
+
struct radeon_winsys *radeon_drm_winsys_create(int fd)
{
- struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys);
+ struct radeon_drm_winsys *ws;
+
+ if (!fd_tab) {
+ fd_tab = util_hash_table_create(hash_fd, compare_fd);
+ }
+
+ ws = util_hash_table_get(fd_tab, intptr_to_pointer(fd));
+ if (ws) {
+ pipe_reference(NULL, &ws->base.reference);
+ return &ws->base;
+ }
+
+ ws = CALLOC_STRUCT(radeon_drm_winsys);
if (!ws) {
return NULL;
}
-
ws->fd = fd;
+ util_hash_table_set(fd_tab, intptr_to_pointer(fd), ws);
if (!do_winsys_init(ws))
goto fail;
@@ -421,6 +452,9 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd)
goto fail;
}
+ /* init reference */
+ pipe_reference_init(&ws->base.reference, 1);
+
/* Set functions. */
ws->base.destroy = radeon_winsys_destroy;
ws->base.query_info = radeon_query_info;
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index 4eb57fb1259..8e4693be92a 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -108,6 +108,11 @@ enum radeon_feature_id {
struct radeon_winsys {
/**
+ * Reference counting
+ */
+ struct pipe_reference reference;
+
+ /**
* Destroy this winsys.
*
* \param ws The winsys this function is called from.