#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include <xf86drm.h>
#include "drv_priv.h"
#include "helpers.h"
#include "util.h"
+#ifdef DRV_AMDGPU
+extern struct backend backend_amdgpu;
+#endif
extern struct backend backend_cirrus;
extern struct backend backend_evdi;
#ifdef DRV_EXYNOS
return NULL;
struct backend *backend_list[] = {
+#ifdef DRV_AMDGPU
+ &backend_amdgpu,
+#endif
&backend_cirrus,
&backend_evdi,
#ifdef DRV_EXYNOS
free(bo);
}
+void *
+drv_bo_map(struct bo *bo)
+{
+ assert(drv_num_buffers_per_bo(bo) == 1);
+
+ if (!bo->map_data || bo->map_data == MAP_FAILED)
+ bo->map_data = bo->drv->backend->bo_map(bo);
+
+ return bo->map_data;
+}
+
+int
+drv_bo_unmap(struct bo *bo)
+{
+ int ret = -1;
+
+ assert(drv_num_buffers_per_bo(bo) == 1);
+
+ if (bo->map_data && bo->map_data != MAP_FAILED)
+ ret = munmap(bo->map_data, bo->total_size);
+
+ bo->map_data = NULL;
+
+ return ret;
+}
+
struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
{
int ret;
+ size_t plane;
struct bo *bo;
struct drm_prime_handle prime_handle;
- memset(&prime_handle, 0, sizeof(prime_handle));
- prime_handle.fd = data->fd;
+ bo = drv_bo_new(drv, data->width, data->height, data->format);
- /* This function can support only single plane formats. */
- /* If multi-plane import is desired, new function should be added. */
- if (drv_num_planes_from_format(data->format) != 1)
+ if (!bo)
return NULL;
- bo = drv_bo_new(drv, data->width, data->height, data->format);
+ for (plane = 0; plane < bo->num_planes; plane++) {
- ret = drmIoctl(drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE,
- &prime_handle);
+ memset(&prime_handle, 0, sizeof(prime_handle));
+ prime_handle.fd = data->fds[plane];
- if (ret) {
- fprintf(stderr, "drv: DRM_IOCTL_PRIME_FD_TO_HANDLE failed "
+ ret = drmIoctl(drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE,
+ &prime_handle);
+
+ if (ret) {
+ fprintf(stderr, "drv: DRM_IOCTL_PRIME_FD_TO_HANDLE failed "
"(fd=%u)\n", prime_handle.fd);
- free(bo);
- return NULL;
- }
- bo->strides[0] = data->stride;
- bo->sizes[0] = data->height * data->stride;
- bo->handles[0].u32 = prime_handle.handle;
+ if (plane > 0) {
+ bo->num_planes = plane;
+ drv_bo_destroy(bo);
+ } else {
+ free(bo);
+ }
- pthread_mutex_lock(&drv->table_lock);
- drv_increment_reference_count(drv, bo, 0);
- pthread_mutex_unlock(&drv->table_lock);
+ return NULL;
+ }
+
+ bo->handles[plane].u32 = prime_handle.handle;
+ bo->strides[plane] = data->strides[plane];
+ bo->offsets[plane] = data->offsets[plane];
+ bo->sizes[plane] = data->sizes[plane];
+ bo->format_modifiers[plane] = data->format_modifiers[plane];
+
+ pthread_mutex_lock(&drv->table_lock);
+ drv_increment_reference_count(drv, bo, plane);
+ pthread_mutex_unlock(&drv->table_lock);
+ }
return bo;
}
assert(plane < bo->num_planes);
return bo->format_modifiers[plane];
}
+
+drv_format_t drv_resolve_format(struct driver *drv, drv_format_t format)
+{
+ if (drv->backend->resolve_format)
+ return drv->backend->resolve_format(format);
+
+ return format;
+}