summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/include/state_tracker/drm_driver.h2
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c114
2 files changed, 106 insertions, 10 deletions
diff --git a/src/gallium/include/state_tracker/drm_driver.h b/src/gallium/include/state_tracker/drm_driver.h
index 5b76d87a69f..959a7625e30 100644
--- a/src/gallium/include/state_tracker/drm_driver.h
+++ b/src/gallium/include/state_tracker/drm_driver.h
@@ -45,6 +45,8 @@ struct winsys_handle
enum drm_conf {
/* How many frames to allow before throttling. Or -1 to indicate any number */
DRM_CONF_THROTTLE, /* DRM_CONF_INT. */
+ /* Can this driver, running on this kernel, import and export dma-buf fds? */
+ DRM_CONF_SHARE_FD, /* DRM_CONF_BOOL. */
DRM_CONF_MAX
};
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 59c072235cb..8ff77b38507 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -530,14 +530,14 @@ dri2_lookup_egl_image(struct dri_screen *screen, void *handle)
}
static __DRIimage *
-dri2_create_image_from_name(__DRIscreen *_screen,
- int width, int height, int format,
- int name, int pitch, void *loaderPrivate)
+dri2_create_image_from_winsys(__DRIscreen *_screen,
+ int width, int height, int format,
+ struct winsys_handle *whandle, int pitch,
+ void *loaderPrivate)
{
struct dri_screen *screen = dri_screen(_screen);
__DRIimage *img;
struct pipe_resource templ;
- struct winsys_handle whandle;
unsigned tex_usage;
enum pipe_format pf;
@@ -577,13 +577,10 @@ dri2_create_image_from_name(__DRIscreen *_screen,
templ.depth0 = 1;
templ.array_size = 1;
- memset(&whandle, 0, sizeof(whandle));
- whandle.handle = name;
- whandle.type = DRM_API_HANDLE_TYPE_SHARED;
- whandle.stride = pitch * util_format_get_blocksize(pf);
+ whandle->stride = pitch * util_format_get_blocksize(pf);
img->texture = screen->base.screen->resource_from_handle(screen->base.screen,
- &templ, &whandle);
+ &templ, whandle);
if (!img->texture) {
FREE(img);
return NULL;
@@ -598,6 +595,39 @@ dri2_create_image_from_name(__DRIscreen *_screen,
}
static __DRIimage *
+dri2_create_image_from_name(__DRIscreen *_screen,
+ int width, int height, int format,
+ int name, int pitch, void *loaderPrivate)
+{
+ struct winsys_handle whandle;
+
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ whandle.handle = name;
+
+ return dri2_create_image_from_winsys(_screen, width, height, format,
+ &whandle, pitch, loaderPrivate);
+}
+
+static __DRIimage *
+dri2_create_image_from_fd(__DRIscreen *_screen,
+ int width, int height, int format,
+ int fd, int pitch, void *loaderPrivate)
+{
+ struct winsys_handle whandle;
+
+ if (fd < 0)
+ return NULL;
+
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_FD;
+ whandle.handle = (unsigned)fd;
+
+ return dri2_create_image_from_winsys(_screen, width, height, format,
+ &whandle, pitch, loaderPrivate);
+}
+
+static __DRIimage *
dri2_create_image_from_renderbuffer(__DRIcontext *context,
int renderbuffer, void *loaderPrivate)
{
@@ -708,6 +738,12 @@ dri2_query_image(__DRIimage *image, int attrib, int *value)
image->texture, &whandle);
*value = whandle.handle;
return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_FD:
+ whandle.type= DRM_API_HANDLE_TYPE_FD;
+ image->texture->screen->resource_get_handle(image->texture->screen,
+ image->texture, &whandle);
+ *value = whandle.handle;
+ return GL_TRUE;
case __DRI_IMAGE_ATTRIB_FORMAT:
*value = image->dri_format;
return GL_TRUE;
@@ -897,6 +933,56 @@ dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
return img;
}
+static __DRIimage *
+dri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc,
+ int *fds, int num_fds, int *strides, int *offsets,
+ void *loaderPrivate)
+{
+ __DRIimage *img;
+ int format, stride, dri_components;
+
+ if (num_fds != 1)
+ return NULL;
+ if (offsets[0] != 0)
+ return NULL;
+
+ switch(fourcc) {
+ case __DRI_IMAGE_FOURCC_RGB565:
+ format = __DRI_IMAGE_FORMAT_RGB565;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGB;
+ break;
+ case __DRI_IMAGE_FOURCC_ARGB8888:
+ format = __DRI_IMAGE_FORMAT_ARGB8888;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
+ break;
+ case __DRI_IMAGE_FOURCC_XRGB8888:
+ format = __DRI_IMAGE_FORMAT_XRGB8888;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGB;
+ break;
+ case __DRI_IMAGE_FOURCC_ABGR8888:
+ format = __DRI_IMAGE_FORMAT_ABGR8888;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
+ break;
+ case __DRI_IMAGE_FOURCC_XBGR8888:
+ format = __DRI_IMAGE_FORMAT_XBGR8888;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGB;
+ break;
+ default:
+ return NULL;
+ }
+
+ /* Strides are in bytes not pixels. */
+ stride = strides[0] /4;
+
+ img = dri2_create_image_from_fd(screen, width, height, format,
+ fds[0], stride, loaderPrivate);
+ if (img == NULL)
+ return NULL;
+
+ img->dri_components = dri_components;
+ return img;
+}
+
static void
dri2_destroy_image(__DRIimage *img)
{
@@ -943,6 +1029,7 @@ dri2_init_screen(__DRIscreen * sPriv)
struct dri_screen *screen;
struct pipe_screen *pscreen;
const struct drm_conf_ret *throttle_ret = NULL;
+ const struct drm_conf_ret *dmabuf_ret = NULL;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
@@ -954,14 +1041,21 @@ dri2_init_screen(__DRIscreen * sPriv)
sPriv->driverPrivate = (void *)screen;
pscreen = driver_descriptor.create_screen(screen->fd);
- if (driver_descriptor.configuration)
+ if (driver_descriptor.configuration) {
throttle_ret = driver_descriptor.configuration(DRM_CONF_THROTTLE);
+ dmabuf_ret = driver_descriptor.configuration(DRM_CONF_SHARE_FD);
+ }
if (throttle_ret && throttle_ret->val.val_int != -1) {
screen->throttling_enabled = TRUE;
screen->default_throttle_frames = throttle_ret->val.val_int;
}
+ if (dmabuf_ret && dmabuf_ret->val.val_bool) {
+ dri2ImageExtension.base.version = 7;
+ dri2ImageExtension.createImageFromFds = dri2_from_fds;
+ }
+
sPriv->extensions = dri_screen_extensions;
/* dri_init_screen_helper checks pscreen for us */