From: Gurchetan Singh <gurchetansi...@chromium.org> This image extension is is needed by the Android studio emulator when using the host's GLES implementation.
This patch moves the extension code from dri2.c to dri_extensions.c. Since some functions in this extension are initialized at runtime by dri2.c, we need to expose them in dri_extensions.h. --- src/gallium/state_trackers/dri/dri2.c | 756 ----------------------- src/gallium/state_trackers/dri/dri_extensions.c | 770 +++++++++++++++++++++++- src/gallium/state_trackers/dri/dri_extensions.h | 17 + 3 files changed, 784 insertions(+), 759 deletions(-) diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c index 625678f257..b68d93bdaa 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -35,7 +35,6 @@ #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_debug.h" -#include "state_tracker/drm_driver.h" #include "state_tracker/st_cb_bufferobjects.h" #include "state_tracker/st_cb_fbo.h" #include "state_tracker/st_cb_texture.h" @@ -52,126 +51,6 @@ #include "dri_query_renderer.h" #include "dri2_buffer.h" -static int convert_fourcc(int format, int *dri_components_p) -{ - int dri_components; - switch(format) { - 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; - case __DRI_IMAGE_FOURCC_R8: - format = __DRI_IMAGE_FORMAT_R8; - dri_components = __DRI_IMAGE_COMPONENTS_R; - break; - case __DRI_IMAGE_FOURCC_GR88: - format = __DRI_IMAGE_FORMAT_GR88; - dri_components = __DRI_IMAGE_COMPONENTS_RG; - break; - /* - * For multi-planar YUV formats, we return the format of the first - * plane only. Since there is only one caller which supports multi- - * planar YUV it gets to figure out the remaining planes on it's - * own. - */ - case __DRI_IMAGE_FOURCC_YUV420: - case __DRI_IMAGE_FOURCC_YVU420: - format = __DRI_IMAGE_FORMAT_R8; - dri_components = __DRI_IMAGE_COMPONENTS_Y_U_V; - break; - case __DRI_IMAGE_FOURCC_NV12: - format = __DRI_IMAGE_FORMAT_R8; - dri_components = __DRI_IMAGE_COMPONENTS_Y_UV; - break; - default: - return -1; - } - *dri_components_p = dri_components; - return format; -} - -/* NOTE this probably isn't going to do the right thing for YUV images - * (but I think the same can be said for intel_query_image()). I think - * only needed for exporting dmabuf's, so I think I won't loose much - * sleep over it. - */ -static int convert_to_fourcc(int format) -{ - switch(format) { - case __DRI_IMAGE_FORMAT_RGB565: - format = __DRI_IMAGE_FOURCC_RGB565; - break; - case __DRI_IMAGE_FORMAT_ARGB8888: - format = __DRI_IMAGE_FOURCC_ARGB8888; - break; - case __DRI_IMAGE_FORMAT_XRGB8888: - format = __DRI_IMAGE_FOURCC_XRGB8888; - break; - case __DRI_IMAGE_FORMAT_ABGR8888: - format = __DRI_IMAGE_FOURCC_ABGR8888; - break; - case __DRI_IMAGE_FORMAT_XBGR8888: - format = __DRI_IMAGE_FOURCC_XBGR8888; - break; - case __DRI_IMAGE_FORMAT_R8: - format = __DRI_IMAGE_FOURCC_R8; - break; - case __DRI_IMAGE_FORMAT_GR88: - format = __DRI_IMAGE_FOURCC_GR88; - break; - default: - return -1; - } - return format; -} - -static enum pipe_format dri2_format_to_pipe_format (int format) -{ - enum pipe_format pf; - - switch (format) { - case __DRI_IMAGE_FORMAT_RGB565: - pf = PIPE_FORMAT_B5G6R5_UNORM; - break; - case __DRI_IMAGE_FORMAT_XRGB8888: - pf = PIPE_FORMAT_BGRX8888_UNORM; - break; - case __DRI_IMAGE_FORMAT_ARGB8888: - pf = PIPE_FORMAT_BGRA8888_UNORM; - break; - case __DRI_IMAGE_FORMAT_ABGR8888: - pf = PIPE_FORMAT_RGBA8888_UNORM; - break; - case __DRI_IMAGE_FORMAT_R8: - pf = PIPE_FORMAT_R8_UNORM; - break; - case __DRI_IMAGE_FORMAT_GR88: - pf = PIPE_FORMAT_RG88_UNORM; - break; - default: - pf = PIPE_FORMAT_NONE; - break; - } - - return pf; -} - /** * DRI2 flush extension. */ @@ -780,641 +659,6 @@ dri2_lookup_egl_image(struct dri_screen *screen, void *handle) return img; } -static __DRIimage * -dri2_create_image_from_winsys(__DRIscreen *_screen, - int width, int height, int format, - int num_handles, struct winsys_handle *whandle, - void *loaderPrivate) -{ - struct dri_screen *screen = dri_screen(_screen); - struct pipe_screen *pscreen = screen->base.screen; - __DRIimage *img; - struct pipe_resource templ; - unsigned tex_usage; - enum pipe_format pf; - int i; - - tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; - - pf = dri2_format_to_pipe_format (format); - if (pf == PIPE_FORMAT_NONE) - return NULL; - - img = CALLOC_STRUCT(__DRIimageRec); - if (!img) - return NULL; - - memset(&templ, 0, sizeof(templ)); - templ.bind = tex_usage; - templ.target = screen->target; - templ.last_level = 0; - templ.depth0 = 1; - templ.array_size = 1; - - for (i = num_handles - 1; i >= 0; i--) { - struct pipe_resource *tex; - - /* TODO: something a lot less ugly */ - switch (i) { - case 0: - templ.width0 = width; - templ.height0 = height; - templ.format = pf; - break; - case 1: - templ.width0 = width / 2; - templ.height0 = height / 2; - templ.format = (num_handles == 2) ? - PIPE_FORMAT_RG88_UNORM : /* NV12, etc */ - PIPE_FORMAT_R8_UNORM; /* I420, etc */ - break; - case 2: - templ.width0 = width / 2; - templ.height0 = height / 2; - templ.format = PIPE_FORMAT_R8_UNORM; - break; - default: - unreachable("too many planes!"); - } - - tex = pscreen->resource_from_handle(pscreen, - &templ, &whandle[i], PIPE_HANDLE_USAGE_READ_WRITE); - if (!tex) { - pipe_resource_reference(&img->texture, NULL); - FREE(img); - return NULL; - } - - tex->next = img->texture; - img->texture = tex; - } - - img->level = 0; - img->layer = 0; - img->dri_format = format; - img->use = 0; - img->loader_private = loaderPrivate; - - return img; -} - -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; - enum pipe_format pf; - - memset(&whandle, 0, sizeof(whandle)); - whandle.type = DRM_API_HANDLE_TYPE_SHARED; - whandle.handle = name; - - pf = dri2_format_to_pipe_format (format); - if (pf == PIPE_FORMAT_NONE) - return NULL; - - whandle.stride = pitch * util_format_get_blocksize(pf); - - return dri2_create_image_from_winsys(_screen, width, height, format, - 1, &whandle, loaderPrivate); -} - -static __DRIimage * -dri2_create_image_from_fd(__DRIscreen *_screen, - int width, int height, int fourcc, - int *fds, int num_fds, int *strides, - int *offsets, unsigned *error, - int *dri_components, void *loaderPrivate) -{ - struct winsys_handle whandles[3]; - int format; - __DRIimage *img = NULL; - unsigned err = __DRI_IMAGE_ERROR_SUCCESS; - int expected_num_fds, i; - - switch (fourcc) { - case __DRI_IMAGE_FOURCC_YUV420: - case __DRI_IMAGE_FOURCC_YVU420: - expected_num_fds = 3; - break; - case __DRI_IMAGE_FOURCC_NV12: - expected_num_fds = 2; - break; - default: - expected_num_fds = 1; - break; - } - - if (num_fds != expected_num_fds) { - err = __DRI_IMAGE_ERROR_BAD_MATCH; - goto exit; - } - - format = convert_fourcc(fourcc, dri_components); - if (format == -1) { - err = __DRI_IMAGE_ERROR_BAD_MATCH; - goto exit; - } - - memset(whandles, 0, sizeof(whandles)); - - for (i = 0; i < num_fds; i++) { - if (fds[i] < 0) { - err = __DRI_IMAGE_ERROR_BAD_ALLOC; - goto exit; - } - - whandles[i].type = DRM_API_HANDLE_TYPE_FD; - whandles[i].handle = (unsigned)fds[i]; - whandles[i].stride = (unsigned)strides[i]; - whandles[i].offset = (unsigned)offsets[i]; - } - - if (fourcc == __DRI_IMAGE_FOURCC_YVU420) { - /* convert to YUV420 by swapping 2nd and 3rd planes: */ - struct winsys_handle tmp = whandles[1]; - whandles[1] = whandles[2]; - whandles[2] = tmp; - fourcc = __DRI_IMAGE_FOURCC_YUV420; - } - - img = dri2_create_image_from_winsys(_screen, width, height, format, - num_fds, whandles, loaderPrivate); - if(img == NULL) - err = __DRI_IMAGE_ERROR_BAD_ALLOC; - -exit: - if (error) - *error = err; - - return img; -} - -static __DRIimage * -dri2_create_image_from_renderbuffer(__DRIcontext *context, - int renderbuffer, void *loaderPrivate) -{ - struct dri_context *ctx = dri_context(context); - - if (!ctx->st->get_resource_for_egl_image) - return NULL; - - /* TODO */ - return NULL; -} - -static __DRIimage * -dri2_create_image(__DRIscreen *_screen, - int width, int height, int format, - unsigned int use, void *loaderPrivate) -{ - struct dri_screen *screen = dri_screen(_screen); - __DRIimage *img; - struct pipe_resource templ; - unsigned tex_usage; - enum pipe_format pf; - - tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; - if (use & __DRI_IMAGE_USE_SCANOUT) - tex_usage |= PIPE_BIND_SCANOUT; - if (use & __DRI_IMAGE_USE_SHARE) - tex_usage |= PIPE_BIND_SHARED; - if (use & __DRI_IMAGE_USE_LINEAR) - tex_usage |= PIPE_BIND_LINEAR; - if (use & __DRI_IMAGE_USE_CURSOR) { - if (width != 64 || height != 64) - return NULL; - tex_usage |= PIPE_BIND_CURSOR; - } - - pf = dri2_format_to_pipe_format (format); - if (pf == PIPE_FORMAT_NONE) - return NULL; - - img = CALLOC_STRUCT(__DRIimageRec); - if (!img) - return NULL; - - memset(&templ, 0, sizeof(templ)); - templ.bind = tex_usage; - templ.format = pf; - templ.target = PIPE_TEXTURE_2D; - templ.last_level = 0; - templ.width0 = width; - templ.height0 = height; - templ.depth0 = 1; - templ.array_size = 1; - - img->texture = screen->base.screen->resource_create(screen->base.screen, &templ); - if (!img->texture) { - FREE(img); - return NULL; - } - - img->level = 0; - img->layer = 0; - img->dri_format = format; - img->dri_components = 0; - img->use = use; - - img->loader_private = loaderPrivate; - return img; -} - -static GLboolean -dri2_query_image(__DRIimage *image, int attrib, int *value) -{ - struct winsys_handle whandle; - unsigned usage; - - if (image->use & __DRI_IMAGE_USE_BACKBUFFER) - usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ; - else - usage = PIPE_HANDLE_USAGE_READ_WRITE; - - memset(&whandle, 0, sizeof(whandle)); - - switch (attrib) { - case __DRI_IMAGE_ATTRIB_STRIDE: - whandle.type = DRM_API_HANDLE_TYPE_KMS; - image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage); - *value = whandle.stride; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_HANDLE: - whandle.type = DRM_API_HANDLE_TYPE_KMS; - image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage); - *value = whandle.handle; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_NAME: - whandle.type = DRM_API_HANDLE_TYPE_SHARED; - image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage); - *value = whandle.handle; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_FD: - whandle.type= DRM_API_HANDLE_TYPE_FD; - if (!image->texture->screen->resource_get_handle(image->texture->screen, - NULL, image->texture, &whandle, usage)) - return GL_FALSE; - - *value = whandle.handle; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_FORMAT: - *value = image->dri_format; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_WIDTH: - *value = image->texture->width0; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_HEIGHT: - *value = image->texture->height0; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_COMPONENTS: - if (image->dri_components == 0) - return GL_FALSE; - *value = image->dri_components; - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_FOURCC: - *value = convert_to_fourcc(image->dri_format); - return GL_TRUE; - case __DRI_IMAGE_ATTRIB_NUM_PLANES: - *value = 1; - return GL_TRUE; - default: - return GL_FALSE; - } -} - -static __DRIimage * -dri2_dup_image(__DRIimage *image, void *loaderPrivate) -{ - __DRIimage *img; - - img = CALLOC_STRUCT(__DRIimageRec); - if (!img) - return NULL; - - img->texture = NULL; - pipe_resource_reference(&img->texture, image->texture); - img->level = image->level; - img->layer = image->layer; - img->dri_format = image->dri_format; - /* This should be 0 for sub images, but dup is also used for base images. */ - img->dri_components = image->dri_components; - img->loader_private = loaderPrivate; - - return img; -} - -static GLboolean -dri2_validate_usage(__DRIimage *image, unsigned int use) -{ - /* - * Gallium drivers are bad at adding usages to the resources - * once opened again in another process, which is the main use - * case for this, so we have to lie. - */ - if (image != NULL) - return GL_TRUE; - else - return GL_FALSE; -} - -static __DRIimage * -dri2_from_names(__DRIscreen *screen, int width, int height, int format, - int *names, int num_names, int *strides, int *offsets, - void *loaderPrivate) -{ - __DRIimage *img; - int dri_components; - struct winsys_handle whandle; - - if (num_names != 1) - return NULL; - - format = convert_fourcc(format, &dri_components); - if (format == -1) - return NULL; - - memset(&whandle, 0, sizeof(whandle)); - whandle.type = DRM_API_HANDLE_TYPE_SHARED; - whandle.handle = names[0]; - whandle.stride = strides[0]; - whandle.offset = offsets[0]; - - img = dri2_create_image_from_winsys(screen, width, height, format, - 1, &whandle, loaderPrivate); - if (img == NULL) - return NULL; - - img->dri_components = dri_components; - return img; -} - -static __DRIimage * -dri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate) -{ - __DRIimage *img; - - if (plane != 0) - return NULL; - - if (image->dri_components == 0) - return NULL; - - img = dri2_dup_image(image, loaderPrivate); - if (img == NULL) - return NULL; - - if (img->texture->screen->resource_changed) - img->texture->screen->resource_changed(img->texture->screen, - img->texture); - - /* set this to 0 for sub images. */ - img->dri_components = 0; - return img; -} - -static __DRIimage * -dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture, - int depth, int level, unsigned *error, - void *loaderPrivate) -{ - __DRIimage *img; - struct gl_context *ctx = ((struct st_context *)dri_context(context)->st)->ctx; - struct gl_texture_object *obj; - struct pipe_resource *tex; - GLuint face = 0; - - obj = _mesa_lookup_texture(ctx, texture); - if (!obj || obj->Target != target) { - *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; - return NULL; - } - - tex = st_get_texobj_resource(obj); - if (!tex) { - *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; - return NULL; - } - - if (target == GL_TEXTURE_CUBE_MAP) - face = depth; - - _mesa_test_texobj_completeness(ctx, obj); - if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) { - *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; - return NULL; - } - - if (level < obj->BaseLevel || level > obj->_MaxLevel) { - *error = __DRI_IMAGE_ERROR_BAD_MATCH; - return NULL; - } - - if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) { - *error = __DRI_IMAGE_ERROR_BAD_MATCH; - return NULL; - } - - img = CALLOC_STRUCT(__DRIimageRec); - if (!img) { - *error = __DRI_IMAGE_ERROR_BAD_ALLOC; - return NULL; - } - - img->level = level; - img->layer = depth; - img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat); - - img->loader_private = loaderPrivate; - - if (img->dri_format == __DRI_IMAGE_FORMAT_NONE) { - *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; - free(img); - return NULL; - } - - pipe_resource_reference(&img->texture, tex); - - *error = __DRI_IMAGE_ERROR_SUCCESS; - 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 dri_components; - - img = dri2_create_image_from_fd(screen, width, height, fourcc, - fds, num_fds, strides, offsets, NULL, - &dri_components, loaderPrivate); - if (img == NULL) - return NULL; - - img->dri_components = dri_components; - return img; -} - -static __DRIimage * -dri2_from_dma_bufs(__DRIscreen *screen, - int width, int height, int fourcc, - int *fds, int num_fds, - int *strides, int *offsets, - enum __DRIYUVColorSpace yuv_color_space, - enum __DRISampleRange sample_range, - enum __DRIChromaSiting horizontal_siting, - enum __DRIChromaSiting vertical_siting, - unsigned *error, - void *loaderPrivate) -{ - __DRIimage *img; - int dri_components; - - img = dri2_create_image_from_fd(screen, width, height, fourcc, - fds, num_fds, strides, offsets, error, - &dri_components, loaderPrivate); - if (img == NULL) - return NULL; - - img->yuv_color_space = yuv_color_space; - img->sample_range = sample_range; - img->horizontal_siting = horizontal_siting; - img->vertical_siting = vertical_siting; - img->dri_components = dri_components; - - *error = __DRI_IMAGE_ERROR_SUCCESS; - return img; -} - -static void -dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src, - int dstx0, int dsty0, int dstwidth, int dstheight, - int srcx0, int srcy0, int srcwidth, int srcheight, - int flush_flag) -{ - struct dri_context *ctx = dri_context(context); - struct pipe_context *pipe = ctx->st->pipe; - struct pipe_screen *screen; - struct pipe_fence_handle *fence; - struct pipe_blit_info blit; - - if (!dst || !src) - return; - - memset(&blit, 0, sizeof(blit)); - blit.dst.resource = dst->texture; - blit.dst.box.x = dstx0; - blit.dst.box.y = dsty0; - blit.dst.box.width = dstwidth; - blit.dst.box.height = dstheight; - blit.dst.box.depth = 1; - blit.dst.format = dst->texture->format; - blit.src.resource = src->texture; - blit.src.box.x = srcx0; - blit.src.box.y = srcy0; - blit.src.box.width = srcwidth; - blit.src.box.height = srcheight; - blit.src.box.depth = 1; - blit.src.format = src->texture->format; - blit.mask = PIPE_MASK_RGBA; - blit.filter = PIPE_TEX_FILTER_NEAREST; - - pipe->blit(pipe, &blit); - - if (flush_flag == __BLIT_FLAG_FLUSH) { - pipe->flush_resource(pipe, dst->texture); - ctx->st->flush(ctx->st, 0, NULL); - } else if (flush_flag == __BLIT_FLAG_FINISH) { - screen = dri_screen(ctx->sPriv)->base.screen; - pipe->flush_resource(pipe, dst->texture); - ctx->st->flush(ctx->st, 0, &fence); - (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE); - screen->fence_reference(screen, &fence, NULL); - } -} - -static void * -dri2_map_image(__DRIcontext *context, __DRIimage *image, - int x0, int y0, int width, int height, - unsigned int flags, int *stride, void **data) -{ - struct dri_context *ctx = dri_context(context); - struct pipe_context *pipe = ctx->st->pipe; - enum pipe_transfer_usage pipe_access = 0; - struct pipe_transfer *trans; - void *map; - - if (!image || !data || *data) - return NULL; - - if (flags & __DRI_IMAGE_TRANSFER_READ) - pipe_access |= PIPE_TRANSFER_READ; - if (flags & __DRI_IMAGE_TRANSFER_WRITE) - pipe_access |= PIPE_TRANSFER_WRITE; - - map = pipe_transfer_map(pipe, image->texture, - 0, 0, pipe_access, x0, y0, width, height, - &trans); - if (map) { - *data = trans; - *stride = trans->stride; - } - - return map; -} - -static void -dri2_unmap_image(__DRIcontext *context, __DRIimage *image, void *data) -{ - struct dri_context *ctx = dri_context(context); - struct pipe_context *pipe = ctx->st->pipe; - - pipe_transfer_unmap(pipe, (struct pipe_transfer *)data); -} - -static void -dri2_destroy_image(__DRIimage *img) -{ - pipe_resource_reference(&img->texture, NULL); - FREE(img); -} - -static int -dri2_get_capabilities(__DRIscreen *_screen) -{ - struct dri_screen *screen = dri_screen(_screen); - - return (screen->can_share_buffer ? __DRI_IMAGE_CAP_GLOBAL_NAMES : 0); -} - -/* The extension is modified during runtime if DRI_PRIME is detected */ -static __DRIimageExtension dri2ImageExtension = { - .base = { __DRI_IMAGE, 12 }, - - .createImageFromName = dri2_create_image_from_name, - .createImageFromRenderbuffer = dri2_create_image_from_renderbuffer, - .destroyImage = dri2_destroy_image, - .createImage = dri2_create_image, - .queryImage = dri2_query_image, - .dupImage = dri2_dup_image, - .validateUsage = dri2_validate_usage, - .createImageFromNames = dri2_from_names, - .fromPlanar = dri2_from_planar, - .createImageFromTexture = dri2_create_from_texture, - .createImageFromFds = NULL, - .createImageFromDmaBufs = NULL, - .blitImage = dri2_blit_image, - .getCapabilities = dri2_get_capabilities, - .mapImage = dri2_map_image, - .unmapImage = dri2_unmap_image, -}; - static const __DRIrobustnessExtension dri2Robustness = { .base = { __DRI2_ROBUSTNESS, 1 } }; diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c index b3a2cb78f9..c3daca1762 100644 --- a/src/gallium/state_trackers/dri/dri_extensions.c +++ b/src/gallium/state_trackers/dri/dri_extensions.c @@ -21,10 +21,139 @@ */ #include <dlfcn.h> -#include "dri_context.h" -#include "dri_screen.h" -#include "pipe/p_screen.h" #include "util/u_memory.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "state_tracker/st_texture.h" +#include "state_tracker/st_context.h" +#include "state_tracker/drm_driver.h" +#include "pipe/p_screen.h" +#include "main/texobj.h" + +#include "dri_screen.h" +#include "dri_context.h" +#include "dri_extensions.h" + +static int convert_fourcc(int format, int *dri_components_p) +{ + int dri_components; + switch(format) { + 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; + case __DRI_IMAGE_FOURCC_R8: + format = __DRI_IMAGE_FORMAT_R8; + dri_components = __DRI_IMAGE_COMPONENTS_R; + break; + case __DRI_IMAGE_FOURCC_GR88: + format = __DRI_IMAGE_FORMAT_GR88; + dri_components = __DRI_IMAGE_COMPONENTS_RG; + break; + /* + * For multi-planar YUV formats, we return the format of the first + * plane only. Since there is only one caller which supports multi- + * planar YUV it gets to figure out the remaining planes on it's + * own. + */ + case __DRI_IMAGE_FOURCC_YUV420: + case __DRI_IMAGE_FOURCC_YVU420: + format = __DRI_IMAGE_FORMAT_R8; + dri_components = __DRI_IMAGE_COMPONENTS_Y_U_V; + break; + case __DRI_IMAGE_FOURCC_NV12: + format = __DRI_IMAGE_FORMAT_R8; + dri_components = __DRI_IMAGE_COMPONENTS_Y_UV; + break; + default: + return -1; + } + *dri_components_p = dri_components; + return format; +} + +/* NOTE this probably isn't going to do the right thing for YUV images + * (but I think the same can be said for intel_query_image()). I think + * only needed for exporting dmabuf's, so I think I won't loose much + * sleep over it. + */ +static int convert_to_fourcc(int format) +{ + switch(format) { + case __DRI_IMAGE_FORMAT_RGB565: + format = __DRI_IMAGE_FOURCC_RGB565; + break; + case __DRI_IMAGE_FORMAT_ARGB8888: + format = __DRI_IMAGE_FOURCC_ARGB8888; + break; + case __DRI_IMAGE_FORMAT_XRGB8888: + format = __DRI_IMAGE_FOURCC_XRGB8888; + break; + case __DRI_IMAGE_FORMAT_ABGR8888: + format = __DRI_IMAGE_FOURCC_ABGR8888; + break; + case __DRI_IMAGE_FORMAT_XBGR8888: + format = __DRI_IMAGE_FOURCC_XBGR8888; + break; + case __DRI_IMAGE_FORMAT_R8: + format = __DRI_IMAGE_FOURCC_R8; + break; + case __DRI_IMAGE_FORMAT_GR88: + format = __DRI_IMAGE_FOURCC_GR88; + break; + default: + return -1; + } + return format; +} + +static enum pipe_format dri2_format_to_pipe_format (int format) +{ + enum pipe_format pf; + + switch (format) { + case __DRI_IMAGE_FORMAT_RGB565: + pf = PIPE_FORMAT_B5G6R5_UNORM; + break; + case __DRI_IMAGE_FORMAT_XRGB8888: + pf = PIPE_FORMAT_BGRX8888_UNORM; + break; + case __DRI_IMAGE_FORMAT_ARGB8888: + pf = PIPE_FORMAT_BGRA8888_UNORM; + break; + case __DRI_IMAGE_FORMAT_ABGR8888: + pf = PIPE_FORMAT_RGBA8888_UNORM; + break; + case __DRI_IMAGE_FORMAT_R8: + pf = PIPE_FORMAT_R8_UNORM; + break; + case __DRI_IMAGE_FORMAT_GR88: + pf = PIPE_FORMAT_RG88_UNORM; + break; + default: + pf = PIPE_FORMAT_NONE; + break; + } + + return pf; +} + static bool dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen) @@ -227,4 +356,639 @@ const __DRI2fenceExtension dri2FenceExtension = { .get_fence_fd = dri2_get_fence_fd, }; +static __DRIimage * +dri2_create_image_from_winsys(__DRIscreen *_screen, + int width, int height, int format, + int num_handles, struct winsys_handle *whandle, + void *loaderPrivate) +{ + struct dri_screen *screen = dri_screen(_screen); + struct pipe_screen *pscreen = screen->base.screen; + __DRIimage *img; + struct pipe_resource templ; + unsigned tex_usage; + enum pipe_format pf; + int i; + + tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + + pf = dri2_format_to_pipe_format (format); + if (pf == PIPE_FORMAT_NONE) + return NULL; + + img = CALLOC_STRUCT(__DRIimageRec); + if (!img) + return NULL; + + memset(&templ, 0, sizeof(templ)); + templ.bind = tex_usage; + templ.target = screen->target; + templ.last_level = 0; + templ.depth0 = 1; + templ.array_size = 1; + + for (i = num_handles - 1; i >= 0; i--) { + struct pipe_resource *tex; + + /* TODO: something a lot less ugly */ + switch (i) { + case 0: + templ.width0 = width; + templ.height0 = height; + templ.format = pf; + break; + case 1: + templ.width0 = width / 2; + templ.height0 = height / 2; + templ.format = (num_handles == 2) ? + PIPE_FORMAT_RG88_UNORM : /* NV12, etc */ + PIPE_FORMAT_R8_UNORM; /* I420, etc */ + break; + case 2: + templ.width0 = width / 2; + templ.height0 = height / 2; + templ.format = PIPE_FORMAT_R8_UNORM; + break; + default: + unreachable("too many planes!"); + } + + tex = pscreen->resource_from_handle(pscreen, + &templ, &whandle[i], PIPE_HANDLE_USAGE_READ_WRITE); + if (!tex) { + pipe_resource_reference(&img->texture, NULL); + FREE(img); + return NULL; + } + + tex->next = img->texture; + img->texture = tex; + } + + img->level = 0; + img->layer = 0; + img->dri_format = format; + img->use = 0; + img->loader_private = loaderPrivate; + + return img; +} + +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; + enum pipe_format pf; + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_SHARED; + whandle.handle = name; + + pf = dri2_format_to_pipe_format (format); + if (pf == PIPE_FORMAT_NONE) + return NULL; + + whandle.stride = pitch * util_format_get_blocksize(pf); + + return dri2_create_image_from_winsys(_screen, width, height, format, + 1, &whandle, loaderPrivate); +} + +static __DRIimage * +dri2_create_image_from_fd(__DRIscreen *_screen, + int width, int height, int fourcc, + int *fds, int num_fds, int *strides, + int *offsets, unsigned *error, + int *dri_components, void *loaderPrivate) +{ + struct winsys_handle whandles[3]; + int format; + __DRIimage *img = NULL; + unsigned err = __DRI_IMAGE_ERROR_SUCCESS; + int expected_num_fds, i; + + switch (fourcc) { + case __DRI_IMAGE_FOURCC_YUV420: + case __DRI_IMAGE_FOURCC_YVU420: + expected_num_fds = 3; + break; + case __DRI_IMAGE_FOURCC_NV12: + expected_num_fds = 2; + break; + default: + expected_num_fds = 1; + break; + } + + if (num_fds != expected_num_fds) { + err = __DRI_IMAGE_ERROR_BAD_MATCH; + goto exit; + } + + format = convert_fourcc(fourcc, dri_components); + if (format == -1) { + err = __DRI_IMAGE_ERROR_BAD_MATCH; + goto exit; + } + + memset(whandles, 0, sizeof(whandles)); + + for (i = 0; i < num_fds; i++) { + if (fds[i] < 0) { + err = __DRI_IMAGE_ERROR_BAD_ALLOC; + goto exit; + } + + whandles[i].type = DRM_API_HANDLE_TYPE_FD; + whandles[i].handle = (unsigned)fds[i]; + whandles[i].stride = (unsigned)strides[i]; + whandles[i].offset = (unsigned)offsets[i]; + } + + if (fourcc == __DRI_IMAGE_FOURCC_YVU420) { + /* convert to YUV420 by swapping 2nd and 3rd planes: */ + struct winsys_handle tmp = whandles[1]; + whandles[1] = whandles[2]; + whandles[2] = tmp; + fourcc = __DRI_IMAGE_FOURCC_YUV420; + } + + img = dri2_create_image_from_winsys(_screen, width, height, format, + num_fds, whandles, loaderPrivate); + if(img == NULL) + err = __DRI_IMAGE_ERROR_BAD_ALLOC; + +exit: + if (error) + *error = err; + + return img; +} + +static __DRIimage * +dri2_create_image_from_renderbuffer(__DRIcontext *context, + int renderbuffer, void *loaderPrivate) +{ + struct dri_context *ctx = dri_context(context); + + if (!ctx->st->get_resource_for_egl_image) + return NULL; + + /* TODO */ + return NULL; +} + +static __DRIimage * +dri2_create_image(__DRIscreen *_screen, + int width, int height, int format, + unsigned int use, void *loaderPrivate) +{ + struct dri_screen *screen = dri_screen(_screen); + __DRIimage *img; + struct pipe_resource templ; + unsigned tex_usage; + enum pipe_format pf; + + tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + if (use & __DRI_IMAGE_USE_SCANOUT) + tex_usage |= PIPE_BIND_SCANOUT; + if (use & __DRI_IMAGE_USE_SHARE) + tex_usage |= PIPE_BIND_SHARED; + if (use & __DRI_IMAGE_USE_LINEAR) + tex_usage |= PIPE_BIND_LINEAR; + if (use & __DRI_IMAGE_USE_CURSOR) { + if (width != 64 || height != 64) + return NULL; + tex_usage |= PIPE_BIND_CURSOR; + } + + pf = dri2_format_to_pipe_format (format); + if (pf == PIPE_FORMAT_NONE) + return NULL; + + img = CALLOC_STRUCT(__DRIimageRec); + if (!img) + return NULL; + + memset(&templ, 0, sizeof(templ)); + templ.bind = tex_usage; + templ.format = pf; + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.array_size = 1; + + img->texture = screen->base.screen->resource_create(screen->base.screen, &templ); + if (!img->texture) { + FREE(img); + return NULL; + } + + img->level = 0; + img->layer = 0; + img->dri_format = format; + img->dri_components = 0; + img->use = use; + + img->loader_private = loaderPrivate; + return img; +} + +static GLboolean +dri2_query_image(__DRIimage *image, int attrib, int *value) +{ + struct winsys_handle whandle; + unsigned usage; + + if (image->use & __DRI_IMAGE_USE_BACKBUFFER) + usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ; + else + usage = PIPE_HANDLE_USAGE_READ_WRITE; + + memset(&whandle, 0, sizeof(whandle)); + + switch (attrib) { + case __DRI_IMAGE_ATTRIB_STRIDE: + whandle.type = DRM_API_HANDLE_TYPE_KMS; + image->texture->screen->resource_get_handle(image->texture->screen, + NULL, image->texture, &whandle, usage); + *value = whandle.stride; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_HANDLE: + whandle.type = DRM_API_HANDLE_TYPE_KMS; + image->texture->screen->resource_get_handle(image->texture->screen, + NULL, image->texture, &whandle, usage); + *value = whandle.handle; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_NAME: + whandle.type = DRM_API_HANDLE_TYPE_SHARED; + image->texture->screen->resource_get_handle(image->texture->screen, + NULL, image->texture, &whandle, usage); + *value = whandle.handle; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_FD: + whandle.type= DRM_API_HANDLE_TYPE_FD; + if (!image->texture->screen->resource_get_handle(image->texture->screen, + NULL, image->texture, &whandle, usage)) + return GL_FALSE; + + *value = whandle.handle; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_FORMAT: + *value = image->dri_format; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_WIDTH: + *value = image->texture->width0; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_HEIGHT: + *value = image->texture->height0; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_COMPONENTS: + if (image->dri_components == 0) + return GL_FALSE; + *value = image->dri_components; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_FOURCC: + *value = convert_to_fourcc(image->dri_format); + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_NUM_PLANES: + *value = 1; + return GL_TRUE; + default: + return GL_FALSE; + } +} + +static __DRIimage * +dri2_dup_image(__DRIimage *image, void *loaderPrivate) +{ + __DRIimage *img; + + img = CALLOC_STRUCT(__DRIimageRec); + if (!img) + return NULL; + + img->texture = NULL; + pipe_resource_reference(&img->texture, image->texture); + img->level = image->level; + img->layer = image->layer; + img->dri_format = image->dri_format; + /* This should be 0 for sub images, but dup is also used for base images. */ + img->dri_components = image->dri_components; + img->loader_private = loaderPrivate; + + return img; +} + +static GLboolean +dri2_validate_usage(__DRIimage *image, unsigned int use) +{ + /* + * Gallium drivers are bad at adding usages to the resources + * once opened again in another process, which is the main use + * case for this, so we have to lie. + */ + if (image != NULL) + return GL_TRUE; + else + return GL_FALSE; +} + +static __DRIimage * +dri2_from_names(__DRIscreen *screen, int width, int height, int format, + int *names, int num_names, int *strides, int *offsets, + void *loaderPrivate) +{ + __DRIimage *img; + int dri_components; + struct winsys_handle whandle; + + if (num_names != 1) + return NULL; + + format = convert_fourcc(format, &dri_components); + if (format == -1) + return NULL; + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_SHARED; + whandle.handle = names[0]; + whandle.stride = strides[0]; + whandle.offset = offsets[0]; + + img = dri2_create_image_from_winsys(screen, width, height, format, + 1, &whandle, loaderPrivate); + if (img == NULL) + return NULL; + + img->dri_components = dri_components; + return img; +} + +static __DRIimage * +dri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate) +{ + __DRIimage *img; + + if (plane != 0) + return NULL; + + if (image->dri_components == 0) + return NULL; + + img = dri2_dup_image(image, loaderPrivate); + if (img == NULL) + return NULL; + + if (img->texture->screen->resource_changed) + img->texture->screen->resource_changed(img->texture->screen, + img->texture); + + /* set this to 0 for sub images. */ + img->dri_components = 0; + return img; +} + +static __DRIimage * +dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture, + int depth, int level, unsigned *error, + void *loaderPrivate) +{ + __DRIimage *img; + struct gl_context *ctx = ((struct st_context *)dri_context(context)->st)->ctx; + struct gl_texture_object *obj; + struct pipe_resource *tex; + GLuint face = 0; + + obj = _mesa_lookup_texture(ctx, texture); + if (!obj || obj->Target != target) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + tex = st_get_texobj_resource(obj); + if (!tex) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + if (target == GL_TEXTURE_CUBE_MAP) + face = depth; + + _mesa_test_texobj_completeness(ctx, obj); + if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + if (level < obj->BaseLevel || level > obj->_MaxLevel) { + *error = __DRI_IMAGE_ERROR_BAD_MATCH; + return NULL; + } + + if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) { + *error = __DRI_IMAGE_ERROR_BAD_MATCH; + return NULL; + } + + img = CALLOC_STRUCT(__DRIimageRec); + if (!img) { + *error = __DRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + img->level = level; + img->layer = depth; + img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat); + + img->loader_private = loaderPrivate; + + if (img->dri_format == __DRI_IMAGE_FORMAT_NONE) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + free(img); + return NULL; + } + + pipe_resource_reference(&img->texture, tex); + + *error = __DRI_IMAGE_ERROR_SUCCESS; + return img; +} + +__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 dri_components; + + img = dri2_create_image_from_fd(screen, width, height, fourcc, + fds, num_fds, strides, offsets, NULL, + &dri_components, loaderPrivate); + if (img == NULL) + return NULL; + + img->dri_components = dri_components; + return img; +} + +__DRIimage * +dri2_from_dma_bufs(__DRIscreen *screen, + int width, int height, int fourcc, + int *fds, int num_fds, + int *strides, int *offsets, + enum __DRIYUVColorSpace yuv_color_space, + enum __DRISampleRange sample_range, + enum __DRIChromaSiting horizontal_siting, + enum __DRIChromaSiting vertical_siting, + unsigned *error, + void *loaderPrivate) +{ + __DRIimage *img; + int dri_components; + + img = dri2_create_image_from_fd(screen, width, height, fourcc, + fds, num_fds, strides, offsets, error, + &dri_components, loaderPrivate); + if (img == NULL) + return NULL; + + img->yuv_color_space = yuv_color_space; + img->sample_range = sample_range; + img->horizontal_siting = horizontal_siting; + img->vertical_siting = vertical_siting; + img->dri_components = dri_components; + + *error = __DRI_IMAGE_ERROR_SUCCESS; + return img; +} + +static void +dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src, + int dstx0, int dsty0, int dstwidth, int dstheight, + int srcx0, int srcy0, int srcwidth, int srcheight, + int flush_flag) +{ + struct dri_context *ctx = dri_context(context); + struct pipe_context *pipe = ctx->st->pipe; + struct pipe_screen *screen; + struct pipe_fence_handle *fence; + struct pipe_blit_info blit; + + if (!dst || !src) + return; + + memset(&blit, 0, sizeof(blit)); + blit.dst.resource = dst->texture; + blit.dst.box.x = dstx0; + blit.dst.box.y = dsty0; + blit.dst.box.width = dstwidth; + blit.dst.box.height = dstheight; + blit.dst.box.depth = 1; + blit.dst.format = dst->texture->format; + blit.src.resource = src->texture; + blit.src.box.x = srcx0; + blit.src.box.y = srcy0; + blit.src.box.width = srcwidth; + blit.src.box.height = srcheight; + blit.src.box.depth = 1; + blit.src.format = src->texture->format; + blit.mask = PIPE_MASK_RGBA; + blit.filter = PIPE_TEX_FILTER_NEAREST; + + pipe->blit(pipe, &blit); + + if (flush_flag == __BLIT_FLAG_FLUSH) { + pipe->flush_resource(pipe, dst->texture); + ctx->st->flush(ctx->st, 0, NULL); + } else if (flush_flag == __BLIT_FLAG_FINISH) { + screen = dri_screen(ctx->sPriv)->base.screen; + pipe->flush_resource(pipe, dst->texture); + ctx->st->flush(ctx->st, 0, &fence); + (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE); + screen->fence_reference(screen, &fence, NULL); + } +} + +static void * +dri2_map_image(__DRIcontext *context, __DRIimage *image, + int x0, int y0, int width, int height, + unsigned int flags, int *stride, void **data) +{ + struct dri_context *ctx = dri_context(context); + struct pipe_context *pipe = ctx->st->pipe; + enum pipe_transfer_usage pipe_access = 0; + struct pipe_transfer *trans; + void *map; + + if (!image || !data || *data) + return NULL; + + if (flags & __DRI_IMAGE_TRANSFER_READ) + pipe_access |= PIPE_TRANSFER_READ; + if (flags & __DRI_IMAGE_TRANSFER_WRITE) + pipe_access |= PIPE_TRANSFER_WRITE; + + map = pipe_transfer_map(pipe, image->texture, + 0, 0, pipe_access, x0, y0, width, height, + &trans); + if (map) { + *data = trans; + *stride = trans->stride; + } + + return map; +} + +static void +dri2_unmap_image(__DRIcontext *context, __DRIimage *image, void *data) +{ + struct dri_context *ctx = dri_context(context); + struct pipe_context *pipe = ctx->st->pipe; + + pipe_transfer_unmap(pipe, (struct pipe_transfer *)data); +} + +static void +dri2_destroy_image(__DRIimage *img) +{ + pipe_resource_reference(&img->texture, NULL); + FREE(img); +} + +static int +dri2_get_capabilities(__DRIscreen *_screen) +{ + struct dri_screen *screen = dri_screen(_screen); + + return (screen->can_share_buffer ? __DRI_IMAGE_CAP_GLOBAL_NAMES : 0); +} + +/* The extension is modified during runtime if DRI_PRIME is detected */ +__DRIimageExtension dri2ImageExtension = { + .base = { __DRI_IMAGE, 12 }, + + .createImageFromName = dri2_create_image_from_name, + .createImageFromRenderbuffer = dri2_create_image_from_renderbuffer, + .destroyImage = dri2_destroy_image, + .createImage = dri2_create_image, + .queryImage = dri2_query_image, + .dupImage = dri2_dup_image, + .validateUsage = dri2_validate_usage, + .createImageFromNames = dri2_from_names, + .fromPlanar = dri2_from_planar, + .createImageFromTexture = dri2_create_from_texture, + .createImageFromFds = NULL, + .createImageFromDmaBufs = NULL, + .blitImage = dri2_blit_image, + .getCapabilities = dri2_get_capabilities, + .mapImage = dri2_map_image, + .unmapImage = dri2_unmap_image, +}; + /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/dri_extensions.h b/src/gallium/state_trackers/dri/dri_extensions.h index 89b01cd3ed..6c19ccac75 100644 --- a/src/gallium/state_trackers/dri/dri_extensions.h +++ b/src/gallium/state_trackers/dri/dri_extensions.h @@ -24,7 +24,24 @@ #define DRI_EXTENSIONS_H extern const __DRI2fenceExtension dri2FenceExtension; +extern __DRIimageExtension dri2ImageExtension; +__DRIimage * +dri2_from_dma_bufs(__DRIscreen *screen, + int width, int height, int fourcc, + int *fds, int num_fds, + int *strides, int *offsets, + enum __DRIYUVColorSpace yuv_color_space, + enum __DRISampleRange sample_range, + enum __DRIChromaSiting horizontal_siting, + enum __DRIChromaSiting vertical_siting, + unsigned *error, + void *loaderPrivate); + +__DRIimage * +dri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc, + int *fds, int num_fds, int *strides, int *offsets, + void *loaderPrivate); #endif /* vim: set sw=3 ts=8 sts=3 expandtab: */ -- 2.12.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev