aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-10-14 11:21:04 +0100
committerEric Anholt <[email protected]>2014-12-17 16:07:01 -0800
commit39bc9360116e1c944c1d0d04f67a6ec5f010371f (patch)
treec241e633ec5bdbdf736b46db9e4b33faaac07e27
parent113044e1b9d8f70a26f826f7c03adcbbc8ecb138 (diff)
vc4: Add dmabuf support.
This gets DRI3 working on modesetting with glamor. It's not enabled under simulation, because it looks like handing our dumb-allocated buffers off to the server doesn't actually work for the server's rendering.
-rw-r--r--src/gallium/auxiliary/target-helpers/inline_drm_helper.h5
-rw-r--r--src/gallium/drivers/vc4/vc4_bufmgr.c75
-rw-r--r--src/gallium/drivers/vc4/vc4_bufmgr.h3
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.c19
4 files changed, 78 insertions, 24 deletions
diff --git a/src/gallium/auxiliary/target-helpers/inline_drm_helper.h b/src/gallium/auxiliary/target-helpers/inline_drm_helper.h
index 81649d42582..df818fed713 100644
--- a/src/gallium/auxiliary/target-helpers/inline_drm_helper.h
+++ b/src/gallium/auxiliary/target-helpers/inline_drm_helper.h
@@ -468,6 +468,11 @@ dd_configuration(enum drm_conf conf)
return configuration_query(conf);
else
#endif
+#if defined(GALLIUM_VC4)
+ if (strcmp(driver_name, "vc4") == 0)
+ return configuration_query(conf);
+ else
+#endif
return NULL;
}
#endif /* INLINE_DRM_HELPER_H */
diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.c b/src/gallium/drivers/vc4/vc4_bufmgr.c
index 3b73ac80bf6..64fe2e40e42 100644
--- a/src/gallium/drivers/vc4/vc4_bufmgr.c
+++ b/src/gallium/drivers/vc4/vc4_bufmgr.c
@@ -24,6 +24,7 @@
#include <errno.h>
#include <err.h>
#include <sys/mman.h>
+#include <fcntl.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
@@ -88,26 +89,19 @@ vc4_bo_free(struct vc4_bo *bo)
free(bo);
}
-struct vc4_bo *
-vc4_bo_open_name(struct vc4_screen *screen, uint32_t name,
- uint32_t winsys_stride)
+static struct vc4_bo *
+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 drm_gem_open o;
- o.name = name;
- int ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o);
- if (ret) {
- fprintf(stderr, "Failed to open bo %d: %s\n",
- name, strerror(errno));
- free(bo);
- return NULL;
- }
+ assert(size);
pipe_reference_init(&bo->reference, 1);
bo->screen = screen;
- bo->handle = o.handle;
- bo->size = o.size;
+ bo->handle = handle;
+ bo->size = size;
bo->name = "winsys";
#ifdef USE_VC4_SIMULATOR
@@ -121,6 +115,59 @@ vc4_bo_open_name(struct vc4_screen *screen, uint32_t name,
}
struct vc4_bo *
+vc4_bo_open_name(struct vc4_screen *screen, uint32_t name,
+ uint32_t winsys_stride)
+{
+ struct drm_gem_open o = {
+ .name = name
+ };
+ int ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o);
+ if (ret) {
+ fprintf(stderr, "Failed to open bo %d: %s\n",
+ name, strerror(errno));
+ return NULL;
+ }
+
+ return vc4_bo_open_handle(screen, winsys_stride, o.handle, o.size);
+}
+
+struct vc4_bo *
+vc4_bo_open_dmabuf(struct vc4_screen *screen, int fd, uint32_t winsys_stride)
+{
+ uint32_t handle;
+ int ret = drmPrimeFDToHandle(screen->fd, fd, &handle);
+ int size;
+ if (ret) {
+ fprintf(stderr, "Failed to get vc4 handle for dmabuf %d\n", fd);
+ return NULL;
+ }
+
+ /* Determine the size of the bo we were handed. */
+ size = lseek(fd, 0, SEEK_END);
+ if (size == -1) {
+ fprintf(stderr, "Couldn't get size of dmabuf fd %d.\n", fd);
+ return NULL;
+ }
+
+ return vc4_bo_open_handle(screen, winsys_stride, handle, size);
+}
+
+int
+vc4_bo_get_dmabuf(struct vc4_bo *bo)
+{
+ int fd;
+ int ret = drmPrimeHandleToFD(bo->screen->fd, bo->handle,
+ O_CLOEXEC, &fd);
+ if (ret != 0) {
+ fprintf(stderr, "Failed to export gem bo %d to dmabuf\n",
+ bo->handle);
+ return -1;
+ }
+
+ return fd;
+}
+
+struct vc4_bo *
vc4_bo_alloc_mem(struct vc4_screen *screen, const void *data, uint32_t size,
const char *name)
{
diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.h b/src/gallium/drivers/vc4/vc4_bufmgr.h
index 4a1d4a4ef0d..baaecfdfd3f 100644
--- a/src/gallium/drivers/vc4/vc4_bufmgr.h
+++ b/src/gallium/drivers/vc4/vc4_bufmgr.h
@@ -50,7 +50,10 @@ struct vc4_bo *vc4_bo_alloc_mem(struct vc4_screen *screen, const void *data,
void vc4_bo_free(struct vc4_bo *bo);
struct vc4_bo *vc4_bo_open_name(struct vc4_screen *screen, uint32_t name,
uint32_t winsys_stride);
+struct vc4_bo *vc4_bo_open_dmabuf(struct vc4_screen *screen, int fd,
+ uint32_t winsys_stride);
bool vc4_bo_flink(struct vc4_bo *bo, uint32_t *name);
+int vc4_bo_get_dmabuf(struct vc4_bo *bo);
static inline void
vc4_bo_set_reference(struct vc4_bo **old_bo, struct vc4_bo *new_bo)
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index 98c51c1ce7a..b532cc6782f 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -482,6 +482,9 @@ vc4_screen_bo_get_handle(struct pipe_screen *pscreen,
case DRM_API_HANDLE_TYPE_KMS:
whandle->handle = bo->handle;
return TRUE;
+ case DRM_API_HANDLE_TYPE_FD:
+ whandle->handle = vc4_bo_get_dmabuf(bo);
+ return whandle->handle != -1;
}
return FALSE;
@@ -492,20 +495,16 @@ vc4_screen_bo_from_handle(struct pipe_screen *pscreen,
struct winsys_handle *whandle)
{
struct vc4_screen *screen = vc4_screen(pscreen);
- struct vc4_bo *bo;
- if (whandle->type != DRM_API_HANDLE_TYPE_SHARED) {
+ switch (whandle->type) {
+ case DRM_API_HANDLE_TYPE_SHARED:
+ return vc4_bo_open_name(screen, whandle->handle, whandle->stride);
+ case DRM_API_HANDLE_TYPE_FD:
+ return vc4_bo_open_dmabuf(screen, whandle->handle, whandle->stride);
+ default:
fprintf(stderr,
"Attempt to import unsupported handle type %d\n",
whandle->type);
return NULL;
}
-
- bo = vc4_bo_open_name(screen, whandle->handle, whandle->stride);
- if (!bo) {
- fprintf(stderr, "Open name %d failed\n", whandle->handle);
- return NULL;
- }
-
- return bo;
}