[Mesa-dev] [PATCH 1/2] gallium/dri: Allow drivers to support DRI Image v7 (v2)
christopher.halse.rogers at canonical.com
christopher.halse.rogers at canonical.com
Fri Apr 26 00:36:36 PDT 2013
From: Christopher James Halse Rogers <raof at ubuntu.com>
Enabled based on kernel drm support for dma-buf.
v2: Detect dma-buf support from st/dri rather than adding a PIPE_CAP_PRIME
---
src/gallium/drivers/freedreno/freedreno_screen.c | 5 +
src/gallium/drivers/nouveau/nouveau_screen.c | 6 +
src/gallium/include/state_tracker/drm_driver.h | 9 +-
src/gallium/state_trackers/dri/drm/dri2.c | 125 +++++++++++++++++++--
.../state_trackers/egl/common/native_helper.c | 1 +
src/gallium/state_trackers/egl/x11/native_dri2.c | 1 +
src/gallium/winsys/i915/drm/i915_drm_buffer.c | 5 +
src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 6 +
8 files changed, 147 insertions(+), 11 deletions(-)
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index b4fc20e..708baaf 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -431,6 +431,11 @@ fd_screen_bo_from_handle(struct pipe_screen *pscreen,
struct fd_screen *screen = fd_screen(pscreen);
struct fd_bo *bo;
+ if (whandle->type != DRM_API_HANDLE_TYPE_SHARED) {
+ DBG("Attempt to import unsupported handle type: %d", whandle->type);
+ return NULL;
+ }
+
bo = fd_bo_from_name(screen->dev, whandle->handle);
if (!bo) {
DBG("ref name 0x%08x failed", whandle->handle);
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index d129a55..e1d4ca5 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -86,6 +86,12 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
struct nouveau_bo *bo = 0;
int ret;
+ if (whandle->type != DRM_API_HANDLE_TYPE_SHARED) {
+ debug_printf("%s: attempt to import unsupported handle type %d\n",
+ __FUNCTION__, whandle->type);
+ return NULL;
+ }
+
ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
if (ret) {
debug_printf("%s: ref name 0x%08x failed with %d\n",
diff --git a/src/gallium/include/state_tracker/drm_driver.h b/src/gallium/include/state_tracker/drm_driver.h
index f9bd222..5b76d87 100644
--- a/src/gallium/include/state_tracker/drm_driver.h
+++ b/src/gallium/include/state_tracker/drm_driver.h
@@ -10,6 +10,8 @@ struct pipe_resource;
#define DRM_API_HANDLE_TYPE_SHARED 0
#define DRM_API_HANDLE_TYPE_KMS 1
+#define DRM_API_HANDLE_TYPE_FD 2
+
/**
* For use with pipe_screen::{texture_from_handle|texture_get_handle}.
@@ -17,9 +19,10 @@ struct pipe_resource;
struct winsys_handle
{
/**
- * Unused for texture_from_handle, always
- * DRM_API_HANDLE_TYPE_SHARED. Input to texture_get_handle,
- * use TEXTURE_USAGE to select handle for kms or ipc.
+ * Input for texture_from_handle, valid values are
+ * DRM_API_HANDLE_TYPE_SHARED or DRM_API_HANDLE_TYPE_FD.
+ * Input to texture_get_handle,
+ * to select handle for kms, flink, or prime.
*/
unsigned type;
/**
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 1750ff0..f554f98 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -40,6 +40,8 @@
#include "dri_drawable.h"
#include "dri2_buffer.h"
+#include <xf86drm.h>
+
/**
* DRI2 flush extension.
*/
@@ -231,6 +233,7 @@ dri2_drawable_process_buffers(struct dri_drawable *drawable,
templ.format = format;
templ.bind = bind;
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
whandle.handle = buf->name;
whandle.stride = buf->pitch;
@@ -452,14 +455,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;
@@ -499,12 +502,10 @@ dri2_create_image_from_name(__DRIscreen *_screen,
templ.depth0 = 1;
templ.array_size = 1;
- memset(&whandle, 0, sizeof(whandle));
- whandle.handle = name;
- 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;
@@ -519,6 +520,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)
{
@@ -626,6 +660,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;
@@ -749,6 +789,67 @@ dri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate)
return img;
}
+static __DRIimage *
+dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
+ int depth, int level, unsigned *error,
+ void *loaderPrivate)
+{
+ /* Bad parameter seems like the least-incorrect error */
+ *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+ return NULL;
+}
+
+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)
{
@@ -794,6 +895,7 @@ dri2_init_screen(__DRIscreen * sPriv)
struct dri_screen *screen;
struct pipe_screen *pscreen;
const struct drm_conf_ret *throttle_ret = NULL;
+ uint64_t prime_caps;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
@@ -813,6 +915,13 @@ dri2_init_screen(__DRIscreen * sPriv)
screen->default_throttle_frames = throttle_ret->val.val_int;
}
+ drmGetCap(screen->fd, DRM_CAP_PRIME, &prime_caps);
+ if (prime_caps & (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT)) {
+ dri2ImageExtension.base.version = 7;
+ dri2ImageExtension.createImageFromTexture = dri2_create_from_texture;
+ dri2ImageExtension.createImageFromFds = dri2_from_fds;
+ }
+
sPriv->extensions = dri_screen_extensions;
/* dri_init_screen_helper checks pscreen for us */
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
index 99259b8..eda6668 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.c
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -428,6 +428,7 @@ drm_display_import_native_buffer(struct native_display *ndpy,
memset(&wsh, 0, sizeof(wsh));
wsh.handle = nbuf->u.drm.name;
+ wsh.type = DRM_API_HANDLE_TYPE_SHARED;
wsh.stride = nbuf->u.drm.stride;
res = screen->resource_from_handle(screen, &nbuf->u.drm.templ, &wsh);
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index fc18a4c..673e3d7 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -177,6 +177,7 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
}
memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
whandle.stride = xbuf->pitch;
whandle.handle = xbuf->name;
dri2surf->textures[natt] = dri2dpy->base.screen->resource_from_handle(
diff --git a/src/gallium/winsys/i915/drm/i915_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
index ac66af3..1f84cc6 100644
--- a/src/gallium/winsys/i915/drm/i915_drm_buffer.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
@@ -101,6 +101,11 @@ i915_drm_buffer_from_handle(struct i915_winsys *iws,
if (!buf)
return NULL;
+ if (whandle->type != DRM_API_HANDLE_TYPE_SHARED) {
+ assert(!"Unsupported handle type");
+ return NULL;
+ }
+
buf->magic = 0xDEAD1337;
buf->bo = drm_intel_bo_gem_create_from_name(idws->gem_manager, "gallium3d_from_handle", whandle->handle);
buf->flinked = TRUE;
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 6ec1713..6fd1fdc 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -873,6 +873,12 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
struct drm_gem_open open_arg = {};
int r;
+ if (whandle->type != DRM_API_HANDLE_TYPE_SHARED) {
+ fprintf(stderr, "Attempted to import unsupported handle type %d\n",
+ whandle->type);
+ return NULL;
+ }
+
memset(&open_arg, 0, sizeof(open_arg));
/* We must maintain a list of pairs <handle, bo>, so that we always return
--
1.8.1.2
More information about the mesa-dev
mailing list