From: Christopher James Halse Rogers <r...@ubuntu.com> This is only exposed by drivers wich support the new PIPE_CAP_PRIME parameter, for PRIME import/export. ---
This stubs out texture_from_renderbuffer, which I don't care about, but that looks like it wouldn't be terribly painful to implement if it's a blocker for the PRIME support, which I do care about. src/gallium/drivers/freedreno/freedreno_screen.c | 1 + src/gallium/drivers/i915/i915_screen.c | 1 + src/gallium/drivers/llvmpipe/lp_screen.c | 2 + src/gallium/drivers/nv30/nv30_screen.c | 1 + src/gallium/drivers/nv50/nv50_screen.c | 2 + src/gallium/drivers/nvc0/nvc0_screen.c | 2 + src/gallium/drivers/r300/r300_screen.c | 1 + src/gallium/drivers/r600/r600_pipe.c | 1 + src/gallium/drivers/radeonsi/radeonsi_pipe.c | 1 + src/gallium/drivers/softpipe/sp_screen.c | 2 + src/gallium/drivers/svga/svga_screen.c | 1 + src/gallium/include/pipe/p_defines.h | 3 +- src/gallium/include/state_tracker/drm_driver.h | 9 +- src/gallium/state_trackers/dri/drm/dri2.c | 120 +++++++++++++++++++-- .../state_trackers/egl/common/native_helper.c | 1 + src/gallium/state_trackers/egl/x11/native_dri2.c | 1 + 16 files changed, 137 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 4a9a54e..db122d3 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -201,6 +201,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_QUERY_PIPELINE_STATISTICS: case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: + case PIPE_CAP_PRIME: return 0; /* Stream output. */ diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index dfb76b3..6623dca 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -214,6 +214,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) case PIPE_CAP_TEXTURE_MULTISAMPLE: case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: + case PIPE_CAP_PRIME: return 0; case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 667ade1..5ff30f1 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -228,6 +228,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: return 0; + case PIPE_CAP_PRIME: + return 0; } /* should only get here on unhandled cases */ debug_printf("Unexpected PIPE_CAP %d query\n", param); diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 5b3b470..97471a7 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -124,6 +124,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: case PIPE_CAP_QUERY_PIPELINE_STATISTICS: case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: + case PIPE_CAP_PRIME: return 0; case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 5aa8ef3..1177c1b 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -188,6 +188,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 0; case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50; + case PIPE_CAP_PRIME: + return 0; default: NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 8dfd4d1..e3eff40 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -178,6 +178,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50; + case PIPE_CAP_PRIME: + return 0; default: NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index a932be9..000c71d 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -163,6 +163,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: + case PIPE_CAP_PRIME: return 0; /* SWTCL-only features. */ diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 4948ddd..b056041 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -612,6 +612,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: case PIPE_CAP_VERTEX_COLOR_CLAMPED: case PIPE_CAP_USER_VERTEX_BUFFERS: + case PIPE_CAP_PRIME: return 0; /* Stream output. */ diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c index 4e97f51..1705e3e 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c @@ -381,6 +381,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: + case PIPE_CAP_PRIME: return 0; /* Stream output. */ diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 53ee7d3..0323f82 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -180,6 +180,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TGSI_TEXCOORD: case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: return 0; + case PIPE_CAP_PRIME: + return 0; } /* should only get here on unhandled cases */ debug_printf("Unexpected PIPE_CAP %d query\n", param); diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 60e0442..683203b 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -265,6 +265,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: case PIPE_CAP_QUERY_PIPELINE_STATISTICS: + case PIPE_CAP_PRIME: return 0; case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: return 1; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 2d38ce1..7e626dc 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -506,7 +506,8 @@ enum pipe_cap { PIPE_CAP_TGSI_TEXCOORD = 79, PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER = 80, PIPE_CAP_QUERY_PIPELINE_STATISTICS = 81, - PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK = 82 + PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK = 82, + PIPE_CAP_PRIME = 83 }; #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0) 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 f8d311c..7f1dc0e 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -231,6 +231,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 +453,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 +500,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 +518,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 +658,11 @@ 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; case __DRI_IMAGE_ATTRIB_FORMAT: *value = image->dri_format; return GL_TRUE; @@ -749,6 +786,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) { @@ -813,6 +911,12 @@ dri2_init_screen(__DRIscreen * sPriv) screen->default_throttle_frames = throttle_ret->val.val_int; } + if (pscreen->get_param(pscreen, PIPE_CAP_PRIME)) { + 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( -- 1.8.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev