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.
This commit is contained in:
@@ -467,6 +467,11 @@ dd_configuration(enum drm_conf conf)
|
||||
if ((strcmp(driver_name, "kgsl") == 0) || (strcmp(driver_name, "msm") == 0))
|
||||
return configuration_query(conf);
|
||||
else
|
||||
#endif
|
||||
#if defined(GALLIUM_VC4)
|
||||
if (strcmp(driver_name, "vc4") == 0)
|
||||
return configuration_query(conf);
|
||||
else
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -120,6 +114,59 @@ vc4_bo_open_name(struct vc4_screen *screen, uint32_t name,
|
||||
return bo;
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user