summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Herring <[email protected]>2016-07-22 15:28:30 -0500
committerEric Anholt <[email protected]>2016-07-26 13:47:50 -0700
commit9ace2c13550609dfe78164f104500d438821f383 (patch)
tree1b556d0fe722c7bb2603786ebdd1bf49a0ba8068
parentce8504d196291452b42ed755ed3830ecb16febcd (diff)
vc4: add hash table look-up for exported dmabufs
It is necessary to reuse existing BOs when dmabufs are imported. There are 2 cases that need to be handled. dmabufs can be created/exported and imported by the same process and can be imported multiple times. Copying other drivers, add a hash table to track exported BOs so the BOs get reused. v2: Whitespace fixup (by anholt) Signed-off-by: Rob Herring <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r--src/gallium/drivers/vc4/vc4_bufmgr.c20
-rw-r--r--src/gallium/drivers/vc4/vc4_bufmgr.h21
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.c15
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.h3
4 files changed, 56 insertions, 3 deletions
diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.c b/src/gallium/drivers/vc4/vc4_bufmgr.c
index 21e3bde2ee2..f6bacfd39e0 100644
--- a/src/gallium/drivers/vc4/vc4_bufmgr.c
+++ b/src/gallium/drivers/vc4/vc4_bufmgr.c
@@ -28,6 +28,7 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
+#include "util/u_hash_table.h"
#include "util/u_memory.h"
#include "util/ralloc.h"
@@ -329,10 +330,19 @@ vc4_bo_open_handle(struct vc4_screen *screen,
uint32_t winsys_stride,
uint32_t handle, uint32_t size)
{
- struct vc4_bo *bo = CALLOC_STRUCT(vc4_bo);
+ struct vc4_bo *bo;
assert(size);
+ pipe_mutex_lock(screen->bo_handles_mutex);
+
+ bo = util_hash_table_get(screen->bo_handles, (void*)(uintptr_t)handle);
+ if (bo) {
+ pipe_reference(NULL, &bo->reference);
+ goto done;
+ }
+
+ bo = CALLOC_STRUCT(vc4_bo);
pipe_reference_init(&bo->reference, 1);
bo->screen = screen;
bo->handle = handle;
@@ -347,6 +357,10 @@ vc4_bo_open_handle(struct vc4_screen *screen,
bo->map = malloc(bo->size);
#endif
+ util_hash_table_set(screen->bo_handles, (void *)(uintptr_t)handle, bo);
+
+done:
+ pipe_mutex_unlock(screen->bo_handles_mutex);
return bo;
}
@@ -399,7 +413,11 @@ vc4_bo_get_dmabuf(struct vc4_bo *bo)
bo->handle);
return -1;
}
+
+ pipe_mutex_lock(bo->screen->bo_handles_mutex);
bo->private = false;
+ util_hash_table_set(bo->screen->bo_handles, (void *)(uintptr_t)bo->handle, bo);
+ pipe_mutex_unlock(bo->screen->bo_handles_mutex);
return fd;
}
diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.h b/src/gallium/drivers/vc4/vc4_bufmgr.h
index b77506e242a..71a4426480c 100644
--- a/src/gallium/drivers/vc4/vc4_bufmgr.h
+++ b/src/gallium/drivers/vc4/vc4_bufmgr.h
@@ -25,6 +25,7 @@
#define VC4_BUFMGR_H
#include <stdint.h>
+#include "util/u_hash_table.h"
#include "util/u_inlines.h"
#include "vc4_qir.h"
@@ -87,11 +88,27 @@ vc4_bo_reference(struct vc4_bo *bo)
static inline void
vc4_bo_unreference(struct vc4_bo **bo)
{
+ struct vc4_screen *screen;
if (!*bo)
return;
- if (pipe_reference(&(*bo)->reference, NULL))
- vc4_bo_last_unreference(*bo);
+ if ((*bo)->private) {
+ /* Avoid the mutex for private BOs */
+ if (pipe_reference(&(*bo)->reference, NULL))
+ vc4_bo_last_unreference(*bo);
+ } else {
+ screen = (*bo)->screen;
+ pipe_mutex_lock(screen->bo_handles_mutex);
+
+ if (pipe_reference(&(*bo)->reference, NULL)) {
+ util_hash_table_remove(screen->bo_handles,
+ (void *)(uintptr_t)(*bo)->handle);
+ vc4_bo_last_unreference(*bo);
+ }
+
+ pipe_mutex_unlock(screen->bo_handles_mutex);
+ }
+
*bo = NULL;
}
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index 5882f070340..aeb6c9a784e 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -30,6 +30,7 @@
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_format.h"
+#include "util/u_hash_table.h"
#include "util/ralloc.h"
#include <xf86drm.h>
@@ -508,6 +509,18 @@ vc4_screen_is_format_supported(struct pipe_screen *pscreen,
return retval == usage;
}
+#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
+
+static unsigned handle_hash(void *key)
+{
+ return PTR_TO_UINT(key);
+}
+
+static int handle_compare(void *key1, void *key2)
+{
+ return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
+}
+
static bool
vc4_supports_branches(struct vc4_screen *screen)
{
@@ -595,6 +608,8 @@ vc4_screen_create(int fd)
screen->fd = fd;
list_inithead(&screen->bo_cache.time_list);
+ pipe_mutex_init(screen->bo_handles_mutex);
+ screen->bo_handles = util_hash_table_create(handle_hash, handle_compare);
if (vc4_supports_branches(screen))
screen->has_control_flow = true;
diff --git a/src/gallium/drivers/vc4/vc4_screen.h b/src/gallium/drivers/vc4/vc4_screen.h
index 345b73ac1d8..1bbede25422 100644
--- a/src/gallium/drivers/vc4/vc4_screen.h
+++ b/src/gallium/drivers/vc4/vc4_screen.h
@@ -77,6 +77,9 @@ struct vc4_screen {
uint32_t bo_count;
} bo_cache;
+ struct util_hash_table *bo_handles;
+ pipe_mutex bo_handles_mutex;
+
uint32_t bo_size;
uint32_t bo_count;
bool has_control_flow;