17ec681f3Smrg/* 27ec681f3Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice shall be included 127ec681f3Smrg * in all copies or substantial portions of the Software. 137ec681f3Smrg * 147ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 157ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 177ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 187ec681f3Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 197ec681f3Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 207ec681f3Smrg * OTHER DEALINGS IN THE SOFTWARE. 217ec681f3Smrg */ 227ec681f3Smrg 237ec681f3Smrg#include <dlfcn.h> 247ec681f3Smrg#include "drm-uapi/drm_fourcc.h" 257ec681f3Smrg#include "util/u_memory.h" 267ec681f3Smrg#include "pipe/p_screen.h" 277ec681f3Smrg#include "state_tracker/st_texture.h" 287ec681f3Smrg#include "state_tracker/st_context.h" 297ec681f3Smrg#include "state_tracker/st_cb_fbo.h" 307ec681f3Smrg#include "main/texobj.h" 317ec681f3Smrg 327ec681f3Smrg#include "dri_helpers.h" 337ec681f3Smrg 347ec681f3Smrgstatic bool 357ec681f3Smrgdri2_is_opencl_interop_loaded_locked(struct dri_screen *screen) 367ec681f3Smrg{ 377ec681f3Smrg return screen->opencl_dri_event_add_ref && 387ec681f3Smrg screen->opencl_dri_event_release && 397ec681f3Smrg screen->opencl_dri_event_wait && 407ec681f3Smrg screen->opencl_dri_event_get_fence; 417ec681f3Smrg} 427ec681f3Smrg 437ec681f3Smrgstatic bool 447ec681f3Smrgdri2_load_opencl_interop(struct dri_screen *screen) 457ec681f3Smrg{ 467ec681f3Smrg#if defined(RTLD_DEFAULT) 477ec681f3Smrg bool success; 487ec681f3Smrg 497ec681f3Smrg mtx_lock(&screen->opencl_func_mutex); 507ec681f3Smrg 517ec681f3Smrg if (dri2_is_opencl_interop_loaded_locked(screen)) { 527ec681f3Smrg mtx_unlock(&screen->opencl_func_mutex); 537ec681f3Smrg return true; 547ec681f3Smrg } 557ec681f3Smrg 567ec681f3Smrg screen->opencl_dri_event_add_ref = 577ec681f3Smrg dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref"); 587ec681f3Smrg screen->opencl_dri_event_release = 597ec681f3Smrg dlsym(RTLD_DEFAULT, "opencl_dri_event_release"); 607ec681f3Smrg screen->opencl_dri_event_wait = 617ec681f3Smrg dlsym(RTLD_DEFAULT, "opencl_dri_event_wait"); 627ec681f3Smrg screen->opencl_dri_event_get_fence = 637ec681f3Smrg dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence"); 647ec681f3Smrg 657ec681f3Smrg success = dri2_is_opencl_interop_loaded_locked(screen); 667ec681f3Smrg mtx_unlock(&screen->opencl_func_mutex); 677ec681f3Smrg return success; 687ec681f3Smrg#else 697ec681f3Smrg return false; 707ec681f3Smrg#endif 717ec681f3Smrg} 727ec681f3Smrg 737ec681f3Smrgstruct dri2_fence { 747ec681f3Smrg struct dri_screen *driscreen; 757ec681f3Smrg struct pipe_fence_handle *pipe_fence; 767ec681f3Smrg void *cl_event; 777ec681f3Smrg}; 787ec681f3Smrg 797ec681f3Smrgstatic unsigned dri2_fence_get_caps(__DRIscreen *_screen) 807ec681f3Smrg{ 817ec681f3Smrg struct dri_screen *driscreen = dri_screen(_screen); 827ec681f3Smrg struct pipe_screen *screen = driscreen->base.screen; 837ec681f3Smrg unsigned caps = 0; 847ec681f3Smrg 857ec681f3Smrg if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD)) 867ec681f3Smrg caps |= __DRI_FENCE_CAP_NATIVE_FD; 877ec681f3Smrg 887ec681f3Smrg return caps; 897ec681f3Smrg} 907ec681f3Smrg 917ec681f3Smrgstatic void * 927ec681f3Smrgdri2_create_fence(__DRIcontext *_ctx) 937ec681f3Smrg{ 947ec681f3Smrg struct st_context_iface *stapi = dri_context(_ctx)->st; 957ec681f3Smrg struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence); 967ec681f3Smrg 977ec681f3Smrg if (!fence) 987ec681f3Smrg return NULL; 997ec681f3Smrg 1007ec681f3Smrg stapi->flush(stapi, 0, &fence->pipe_fence, NULL, NULL); 1017ec681f3Smrg 1027ec681f3Smrg if (!fence->pipe_fence) { 1037ec681f3Smrg FREE(fence); 1047ec681f3Smrg return NULL; 1057ec681f3Smrg } 1067ec681f3Smrg 1077ec681f3Smrg fence->driscreen = dri_screen(_ctx->driScreenPriv); 1087ec681f3Smrg return fence; 1097ec681f3Smrg} 1107ec681f3Smrg 1117ec681f3Smrgstatic void * 1127ec681f3Smrgdri2_create_fence_fd(__DRIcontext *_ctx, int fd) 1137ec681f3Smrg{ 1147ec681f3Smrg struct st_context_iface *stapi = dri_context(_ctx)->st; 1157ec681f3Smrg struct pipe_context *ctx = stapi->pipe; 1167ec681f3Smrg struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence); 1177ec681f3Smrg 1187ec681f3Smrg if (fd == -1) { 1197ec681f3Smrg /* exporting driver created fence, flush: */ 1207ec681f3Smrg stapi->flush(stapi, ST_FLUSH_FENCE_FD, &fence->pipe_fence, NULL, NULL); 1217ec681f3Smrg } else { 1227ec681f3Smrg /* importing a foreign fence fd: */ 1237ec681f3Smrg ctx->create_fence_fd(ctx, &fence->pipe_fence, fd, PIPE_FD_TYPE_NATIVE_SYNC); 1247ec681f3Smrg } 1257ec681f3Smrg if (!fence->pipe_fence) { 1267ec681f3Smrg FREE(fence); 1277ec681f3Smrg return NULL; 1287ec681f3Smrg } 1297ec681f3Smrg 1307ec681f3Smrg fence->driscreen = dri_screen(_ctx->driScreenPriv); 1317ec681f3Smrg return fence; 1327ec681f3Smrg} 1337ec681f3Smrg 1347ec681f3Smrgstatic int 1357ec681f3Smrgdri2_get_fence_fd(__DRIscreen *_screen, void *_fence) 1367ec681f3Smrg{ 1377ec681f3Smrg struct dri_screen *driscreen = dri_screen(_screen); 1387ec681f3Smrg struct pipe_screen *screen = driscreen->base.screen; 1397ec681f3Smrg struct dri2_fence *fence = (struct dri2_fence*)_fence; 1407ec681f3Smrg 1417ec681f3Smrg return screen->fence_get_fd(screen, fence->pipe_fence); 1427ec681f3Smrg} 1437ec681f3Smrg 1447ec681f3Smrgstatic void * 1457ec681f3Smrgdri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event) 1467ec681f3Smrg{ 1477ec681f3Smrg struct dri_screen *driscreen = dri_screen(_screen); 1487ec681f3Smrg struct dri2_fence *fence; 1497ec681f3Smrg 1507ec681f3Smrg if (!dri2_load_opencl_interop(driscreen)) 1517ec681f3Smrg return NULL; 1527ec681f3Smrg 1537ec681f3Smrg fence = CALLOC_STRUCT(dri2_fence); 1547ec681f3Smrg if (!fence) 1557ec681f3Smrg return NULL; 1567ec681f3Smrg 1577ec681f3Smrg fence->cl_event = (void*)cl_event; 1587ec681f3Smrg 1597ec681f3Smrg if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) { 1607ec681f3Smrg free(fence); 1617ec681f3Smrg return NULL; 1627ec681f3Smrg } 1637ec681f3Smrg 1647ec681f3Smrg fence->driscreen = driscreen; 1657ec681f3Smrg return fence; 1667ec681f3Smrg} 1677ec681f3Smrg 1687ec681f3Smrgstatic void 1697ec681f3Smrgdri2_destroy_fence(__DRIscreen *_screen, void *_fence) 1707ec681f3Smrg{ 1717ec681f3Smrg struct dri_screen *driscreen = dri_screen(_screen); 1727ec681f3Smrg struct pipe_screen *screen = driscreen->base.screen; 1737ec681f3Smrg struct dri2_fence *fence = (struct dri2_fence*)_fence; 1747ec681f3Smrg 1757ec681f3Smrg if (fence->pipe_fence) 1767ec681f3Smrg screen->fence_reference(screen, &fence->pipe_fence, NULL); 1777ec681f3Smrg else if (fence->cl_event) 1787ec681f3Smrg driscreen->opencl_dri_event_release(fence->cl_event); 1797ec681f3Smrg else 1807ec681f3Smrg assert(0); 1817ec681f3Smrg 1827ec681f3Smrg FREE(fence); 1837ec681f3Smrg} 1847ec681f3Smrg 1857ec681f3Smrgstatic GLboolean 1867ec681f3Smrgdri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags, 1877ec681f3Smrg uint64_t timeout) 1887ec681f3Smrg{ 1897ec681f3Smrg struct dri2_fence *fence = (struct dri2_fence*)_fence; 1907ec681f3Smrg struct dri_screen *driscreen = fence->driscreen; 1917ec681f3Smrg struct pipe_screen *screen = driscreen->base.screen; 1927ec681f3Smrg 1937ec681f3Smrg /* No need to flush. The context was flushed when the fence was created. */ 1947ec681f3Smrg 1957ec681f3Smrg if (fence->pipe_fence) 1967ec681f3Smrg return screen->fence_finish(screen, NULL, fence->pipe_fence, timeout); 1977ec681f3Smrg else if (fence->cl_event) { 1987ec681f3Smrg struct pipe_fence_handle *pipe_fence = 1997ec681f3Smrg driscreen->opencl_dri_event_get_fence(fence->cl_event); 2007ec681f3Smrg 2017ec681f3Smrg if (pipe_fence) 2027ec681f3Smrg return screen->fence_finish(screen, NULL, pipe_fence, timeout); 2037ec681f3Smrg else 2047ec681f3Smrg return driscreen->opencl_dri_event_wait(fence->cl_event, timeout); 2057ec681f3Smrg } 2067ec681f3Smrg else { 2077ec681f3Smrg assert(0); 2087ec681f3Smrg return false; 2097ec681f3Smrg } 2107ec681f3Smrg} 2117ec681f3Smrg 2127ec681f3Smrgstatic void 2137ec681f3Smrgdri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags) 2147ec681f3Smrg{ 2157ec681f3Smrg struct pipe_context *ctx = dri_context(_ctx)->st->pipe; 2167ec681f3Smrg struct dri2_fence *fence = (struct dri2_fence*)_fence; 2177ec681f3Smrg 2187ec681f3Smrg /* We might be called here with a NULL fence as a result of WaitSyncKHR 2197ec681f3Smrg * on a EGL_KHR_reusable_sync fence. Nothing to do here in such case. 2207ec681f3Smrg */ 2217ec681f3Smrg if (!fence) 2227ec681f3Smrg return; 2237ec681f3Smrg 2247ec681f3Smrg if (ctx->fence_server_sync) 2257ec681f3Smrg ctx->fence_server_sync(ctx, fence->pipe_fence); 2267ec681f3Smrg} 2277ec681f3Smrg 2287ec681f3Smrgconst __DRI2fenceExtension dri2FenceExtension = { 2297ec681f3Smrg .base = { __DRI2_FENCE, 2 }, 2307ec681f3Smrg 2317ec681f3Smrg .create_fence = dri2_create_fence, 2327ec681f3Smrg .get_fence_from_cl_event = dri2_get_fence_from_cl_event, 2337ec681f3Smrg .destroy_fence = dri2_destroy_fence, 2347ec681f3Smrg .client_wait_sync = dri2_client_wait_sync, 2357ec681f3Smrg .server_wait_sync = dri2_server_wait_sync, 2367ec681f3Smrg .get_capabilities = dri2_fence_get_caps, 2377ec681f3Smrg .create_fence_fd = dri2_create_fence_fd, 2387ec681f3Smrg .get_fence_fd = dri2_get_fence_fd, 2397ec681f3Smrg}; 2407ec681f3Smrg 2417ec681f3Smrg__DRIimage * 2427ec681f3Smrgdri2_lookup_egl_image(struct dri_screen *screen, void *handle) 2437ec681f3Smrg{ 2447ec681f3Smrg const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image; 2457ec681f3Smrg __DRIimage *img; 2467ec681f3Smrg 2477ec681f3Smrg if (!loader->lookupEGLImage) 2487ec681f3Smrg return NULL; 2497ec681f3Smrg 2507ec681f3Smrg img = loader->lookupEGLImage(screen->sPriv, 2517ec681f3Smrg handle, screen->sPriv->loaderPrivate); 2527ec681f3Smrg 2537ec681f3Smrg return img; 2547ec681f3Smrg} 2557ec681f3Smrg 2567ec681f3Smrgboolean 2577ec681f3Smrgdri2_validate_egl_image(struct dri_screen *screen, void *handle) 2587ec681f3Smrg{ 2597ec681f3Smrg const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image; 2607ec681f3Smrg 2617ec681f3Smrg return loader->validateEGLImage(handle, screen->sPriv->loaderPrivate); 2627ec681f3Smrg} 2637ec681f3Smrg 2647ec681f3Smrg__DRIimage * 2657ec681f3Smrgdri2_lookup_egl_image_validated(struct dri_screen *screen, void *handle) 2667ec681f3Smrg{ 2677ec681f3Smrg const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image; 2687ec681f3Smrg 2697ec681f3Smrg return loader->lookupEGLImageValidated(handle, screen->sPriv->loaderPrivate); 2707ec681f3Smrg} 2717ec681f3Smrg 2727ec681f3Smrg__DRIimage * 2737ec681f3Smrgdri2_create_image_from_renderbuffer2(__DRIcontext *context, 2747ec681f3Smrg int renderbuffer, void *loaderPrivate, 2757ec681f3Smrg unsigned *error) 2767ec681f3Smrg{ 2777ec681f3Smrg struct st_context *st_ctx = (struct st_context *)dri_context(context)->st; 2787ec681f3Smrg struct gl_context *ctx = st_ctx->ctx; 2797ec681f3Smrg struct pipe_context *p_ctx = st_ctx->pipe; 2807ec681f3Smrg struct gl_renderbuffer *rb; 2817ec681f3Smrg struct pipe_resource *tex; 2827ec681f3Smrg __DRIimage *img; 2837ec681f3Smrg 2847ec681f3Smrg /* Section 3.9 (EGLImage Specification and Management) of the EGL 1.5 2857ec681f3Smrg * specification says: 2867ec681f3Smrg * 2877ec681f3Smrg * "If target is EGL_GL_RENDERBUFFER and buffer is not the name of a 2887ec681f3Smrg * renderbuffer object, or if buffer is the name of a multisampled 2897ec681f3Smrg * renderbuffer object, the error EGL_BAD_PARAMETER is generated." 2907ec681f3Smrg * 2917ec681f3Smrg * "If target is EGL_GL_TEXTURE_2D , EGL_GL_TEXTURE_CUBE_MAP_*, 2927ec681f3Smrg * EGL_GL_RENDERBUFFER or EGL_GL_TEXTURE_3D and buffer refers to the 2937ec681f3Smrg * default GL texture object (0) for the corresponding GL target, the 2947ec681f3Smrg * error EGL_BAD_PARAMETER is generated." 2957ec681f3Smrg * (rely on _mesa_lookup_renderbuffer returning NULL in this case) 2967ec681f3Smrg */ 2977ec681f3Smrg rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 2987ec681f3Smrg if (!rb || rb->NumSamples > 0) { 2997ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 3007ec681f3Smrg return NULL; 3017ec681f3Smrg } 3027ec681f3Smrg 3037ec681f3Smrg tex = st_get_renderbuffer_resource(rb); 3047ec681f3Smrg if (!tex) { 3057ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 3067ec681f3Smrg return NULL; 3077ec681f3Smrg } 3087ec681f3Smrg 3097ec681f3Smrg img = CALLOC_STRUCT(__DRIimageRec); 3107ec681f3Smrg if (!img) { 3117ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_ALLOC; 3127ec681f3Smrg return NULL; 3137ec681f3Smrg } 3147ec681f3Smrg 3157ec681f3Smrg img->dri_format = driGLFormatToImageFormat(rb->Format); 3167ec681f3Smrg img->loader_private = loaderPrivate; 3177ec681f3Smrg img->sPriv = context->driScreenPriv; 3187ec681f3Smrg 3197ec681f3Smrg pipe_resource_reference(&img->texture, tex); 3207ec681f3Smrg 3217ec681f3Smrg /* If the resource supports EGL_MESA_image_dma_buf_export, make sure that 3227ec681f3Smrg * it's in a shareable state. Do this now while we still have the access to 3237ec681f3Smrg * the context. 3247ec681f3Smrg */ 3257ec681f3Smrg if (dri2_get_mapping_by_format(img->dri_format)) 3267ec681f3Smrg p_ctx->flush_resource(p_ctx, tex); 3277ec681f3Smrg 3287ec681f3Smrg ctx->Shared->HasExternallySharedImages = true; 3297ec681f3Smrg *error = __DRI_IMAGE_ERROR_SUCCESS; 3307ec681f3Smrg return img; 3317ec681f3Smrg} 3327ec681f3Smrg 3337ec681f3Smrg__DRIimage * 3347ec681f3Smrgdri2_create_image_from_renderbuffer(__DRIcontext *context, 3357ec681f3Smrg int renderbuffer, void *loaderPrivate) 3367ec681f3Smrg{ 3377ec681f3Smrg unsigned error; 3387ec681f3Smrg return dri2_create_image_from_renderbuffer2(context, renderbuffer, 3397ec681f3Smrg loaderPrivate, &error); 3407ec681f3Smrg} 3417ec681f3Smrg 3427ec681f3Smrgvoid 3437ec681f3Smrgdri2_destroy_image(__DRIimage *img) 3447ec681f3Smrg{ 3457ec681f3Smrg const __DRIimageLoaderExtension *imgLoader = img->sPriv->image.loader; 3467ec681f3Smrg const __DRIdri2LoaderExtension *dri2Loader = img->sPriv->dri2.loader; 3477ec681f3Smrg 3487ec681f3Smrg if (imgLoader && imgLoader->base.version >= 4 && 3497ec681f3Smrg imgLoader->destroyLoaderImageState) { 3507ec681f3Smrg imgLoader->destroyLoaderImageState(img->loader_private); 3517ec681f3Smrg } else if (dri2Loader && dri2Loader->base.version >= 5 && 3527ec681f3Smrg dri2Loader->destroyLoaderImageState) { 3537ec681f3Smrg dri2Loader->destroyLoaderImageState(img->loader_private); 3547ec681f3Smrg } 3557ec681f3Smrg 3567ec681f3Smrg pipe_resource_reference(&img->texture, NULL); 3577ec681f3Smrg FREE(img); 3587ec681f3Smrg} 3597ec681f3Smrg 3607ec681f3Smrg 3617ec681f3Smrg__DRIimage * 3627ec681f3Smrgdri2_create_from_texture(__DRIcontext *context, int target, unsigned texture, 3637ec681f3Smrg int depth, int level, unsigned *error, 3647ec681f3Smrg void *loaderPrivate) 3657ec681f3Smrg{ 3667ec681f3Smrg __DRIimage *img; 3677ec681f3Smrg struct st_context *st_ctx = (struct st_context *)dri_context(context)->st; 3687ec681f3Smrg struct gl_context *ctx = st_ctx->ctx; 3697ec681f3Smrg struct pipe_context *p_ctx = st_ctx->pipe; 3707ec681f3Smrg struct gl_texture_object *obj; 3717ec681f3Smrg struct pipe_resource *tex; 3727ec681f3Smrg GLuint face = 0; 3737ec681f3Smrg 3747ec681f3Smrg obj = _mesa_lookup_texture(ctx, texture); 3757ec681f3Smrg if (!obj || obj->Target != target) { 3767ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 3777ec681f3Smrg return NULL; 3787ec681f3Smrg } 3797ec681f3Smrg 3807ec681f3Smrg tex = st_get_texobj_resource(obj); 3817ec681f3Smrg if (!tex) { 3827ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 3837ec681f3Smrg return NULL; 3847ec681f3Smrg } 3857ec681f3Smrg 3867ec681f3Smrg if (target == GL_TEXTURE_CUBE_MAP) 3877ec681f3Smrg face = depth; 3887ec681f3Smrg 3897ec681f3Smrg _mesa_test_texobj_completeness(ctx, obj); 3907ec681f3Smrg if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) { 3917ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 3927ec681f3Smrg return NULL; 3937ec681f3Smrg } 3947ec681f3Smrg 3957ec681f3Smrg if (level < obj->Attrib.BaseLevel || level > obj->_MaxLevel) { 3967ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_MATCH; 3977ec681f3Smrg return NULL; 3987ec681f3Smrg } 3997ec681f3Smrg 4007ec681f3Smrg if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) { 4017ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_MATCH; 4027ec681f3Smrg return NULL; 4037ec681f3Smrg } 4047ec681f3Smrg 4057ec681f3Smrg img = CALLOC_STRUCT(__DRIimageRec); 4067ec681f3Smrg if (!img) { 4077ec681f3Smrg *error = __DRI_IMAGE_ERROR_BAD_ALLOC; 4087ec681f3Smrg return NULL; 4097ec681f3Smrg } 4107ec681f3Smrg 4117ec681f3Smrg img->level = level; 4127ec681f3Smrg img->layer = depth; 4137ec681f3Smrg img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat); 4147ec681f3Smrg 4157ec681f3Smrg img->loader_private = loaderPrivate; 4167ec681f3Smrg img->sPriv = context->driScreenPriv; 4177ec681f3Smrg 4187ec681f3Smrg pipe_resource_reference(&img->texture, tex); 4197ec681f3Smrg 4207ec681f3Smrg /* If the resource supports EGL_MESA_image_dma_buf_export, make sure that 4217ec681f3Smrg * it's in a shareable state. Do this now while we still have the access to 4227ec681f3Smrg * the context. 4237ec681f3Smrg */ 4247ec681f3Smrg if (dri2_get_mapping_by_format(img->dri_format)) 4257ec681f3Smrg p_ctx->flush_resource(p_ctx, tex); 4267ec681f3Smrg 4277ec681f3Smrg ctx->Shared->HasExternallySharedImages = true; 4287ec681f3Smrg *error = __DRI_IMAGE_ERROR_SUCCESS; 4297ec681f3Smrg return img; 4307ec681f3Smrg} 4317ec681f3Smrg 4327ec681f3Smrgstatic const struct dri2_format_mapping dri2_format_table[] = { 4337ec681f3Smrg { DRM_FORMAT_ABGR16161616F, __DRI_IMAGE_FORMAT_ABGR16161616F, 4347ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R16G16B16A16_FLOAT, 1, 4357ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616F } } }, 4367ec681f3Smrg { DRM_FORMAT_XBGR16161616F, __DRI_IMAGE_FORMAT_XBGR16161616F, 4377ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R16G16B16X16_FLOAT, 1, 4387ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR16161616F } } }, 4397ec681f3Smrg { __DRI_IMAGE_FOURCC_RGBA16161616, __DRI_IMAGE_FORMAT_ABGR16161616, 4407ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R16G16B16A16_UNORM, 1, 4417ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 4427ec681f3Smrg { DRM_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 4437ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B10G10R10A2_UNORM, 1, 4447ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB2101010 } } }, 4457ec681f3Smrg { DRM_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 4467ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B10G10R10X2_UNORM, 1, 4477ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB2101010 } } }, 4487ec681f3Smrg { DRM_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 4497ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R10G10B10A2_UNORM, 1, 4507ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR2101010 } } }, 4517ec681f3Smrg { DRM_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 4527ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R10G10B10X2_UNORM, 1, 4537ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR2101010 } } }, 4547ec681f3Smrg { DRM_FORMAT_ARGB8888, __DRI_IMAGE_FORMAT_ARGB8888, 4557ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_UNORM, 1, 4567ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } }, 4577ec681f3Smrg { DRM_FORMAT_ABGR8888, __DRI_IMAGE_FORMAT_ABGR8888, 4587ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_RGBA8888_UNORM, 1, 4597ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } }, 4607ec681f3Smrg { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_FORMAT_SARGB8, 4617ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_SRGB, 1, 4627ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8 } } }, 4637ec681f3Smrg { DRM_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888, 4647ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_BGRX8888_UNORM, 1, 4657ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888 } } }, 4667ec681f3Smrg { DRM_FORMAT_XBGR8888, __DRI_IMAGE_FORMAT_XBGR8888, 4677ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_RGBX8888_UNORM, 1, 4687ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888 } } }, 4697ec681f3Smrg { DRM_FORMAT_ARGB1555, __DRI_IMAGE_FORMAT_ARGB1555, 4707ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B5G5R5A1_UNORM, 1, 4717ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB1555 } } }, 4727ec681f3Smrg { DRM_FORMAT_RGB565, __DRI_IMAGE_FORMAT_RGB565, 4737ec681f3Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B5G6R5_UNORM, 1, 4747ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565 } } }, 4757ec681f3Smrg { DRM_FORMAT_R8, __DRI_IMAGE_FORMAT_R8, 4767ec681f3Smrg __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R8_UNORM, 1, 4777ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 } } }, 4787ec681f3Smrg { DRM_FORMAT_R16, __DRI_IMAGE_FORMAT_R16, 4797ec681f3Smrg __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R16_UNORM, 1, 4807ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 } } }, 4817ec681f3Smrg { DRM_FORMAT_GR88, __DRI_IMAGE_FORMAT_GR88, 4827ec681f3Smrg __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG88_UNORM, 1, 4837ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 } } }, 4847ec681f3Smrg { DRM_FORMAT_GR1616, __DRI_IMAGE_FORMAT_GR1616, 4857ec681f3Smrg __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG1616_UNORM, 1, 4867ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 } } }, 4877ec681f3Smrg 4887ec681f3Smrg { DRM_FORMAT_YUV410, __DRI_IMAGE_FORMAT_NONE, 4897ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 4907ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 4917ec681f3Smrg { 1, 2, 2, __DRI_IMAGE_FORMAT_R8 }, 4927ec681f3Smrg { 2, 2, 2, __DRI_IMAGE_FORMAT_R8 } } }, 4937ec681f3Smrg { DRM_FORMAT_YUV411, __DRI_IMAGE_FORMAT_NONE, 4947ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 4957ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 4967ec681f3Smrg { 1, 2, 0, __DRI_IMAGE_FORMAT_R8 }, 4977ec681f3Smrg { 2, 2, 0, __DRI_IMAGE_FORMAT_R8 } } }, 4987ec681f3Smrg { DRM_FORMAT_YUV420, __DRI_IMAGE_FORMAT_NONE, 4997ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 5007ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5017ec681f3Smrg { 1, 1, 1, __DRI_IMAGE_FORMAT_R8 }, 5027ec681f3Smrg { 2, 1, 1, __DRI_IMAGE_FORMAT_R8 } } }, 5037ec681f3Smrg { DRM_FORMAT_YUV422, __DRI_IMAGE_FORMAT_NONE, 5047ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 5057ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5067ec681f3Smrg { 1, 1, 0, __DRI_IMAGE_FORMAT_R8 }, 5077ec681f3Smrg { 2, 1, 0, __DRI_IMAGE_FORMAT_R8 } } }, 5087ec681f3Smrg { DRM_FORMAT_YUV444, __DRI_IMAGE_FORMAT_NONE, 5097ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 5107ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5117ec681f3Smrg { 1, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5127ec681f3Smrg { 2, 0, 0, __DRI_IMAGE_FORMAT_R8 } } }, 5137ec681f3Smrg 5147ec681f3Smrg { DRM_FORMAT_YVU410, __DRI_IMAGE_FORMAT_NONE, 5157ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 5167ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5177ec681f3Smrg { 2, 2, 2, __DRI_IMAGE_FORMAT_R8 }, 5187ec681f3Smrg { 1, 2, 2, __DRI_IMAGE_FORMAT_R8 } } }, 5197ec681f3Smrg { DRM_FORMAT_YVU411, __DRI_IMAGE_FORMAT_NONE, 5207ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 5217ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5227ec681f3Smrg { 2, 2, 0, __DRI_IMAGE_FORMAT_R8 }, 5237ec681f3Smrg { 1, 2, 0, __DRI_IMAGE_FORMAT_R8 } } }, 5247ec681f3Smrg { DRM_FORMAT_YVU420, __DRI_IMAGE_FORMAT_NONE, 5257ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 5267ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5277ec681f3Smrg { 2, 1, 1, __DRI_IMAGE_FORMAT_R8 }, 5287ec681f3Smrg { 1, 1, 1, __DRI_IMAGE_FORMAT_R8 } } }, 5297ec681f3Smrg { DRM_FORMAT_YVU422, __DRI_IMAGE_FORMAT_NONE, 5307ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 5317ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5327ec681f3Smrg { 2, 1, 0, __DRI_IMAGE_FORMAT_R8 }, 5337ec681f3Smrg { 1, 1, 0, __DRI_IMAGE_FORMAT_R8 } } }, 5347ec681f3Smrg { DRM_FORMAT_YVU444, __DRI_IMAGE_FORMAT_NONE, 5357ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 5367ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5377ec681f3Smrg { 2, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5387ec681f3Smrg { 1, 0, 0, __DRI_IMAGE_FORMAT_R8 } } }, 5397ec681f3Smrg 5407ec681f3Smrg { DRM_FORMAT_NV12, __DRI_IMAGE_FORMAT_NONE, 5417ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12, 2, 5427ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5437ec681f3Smrg { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } }, 5447ec681f3Smrg 5457ec681f3Smrg { DRM_FORMAT_P010, __DRI_IMAGE_FORMAT_NONE, 5467ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P010, 2, 5477ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 }, 5487ec681f3Smrg { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } }, 5497ec681f3Smrg { DRM_FORMAT_P012, __DRI_IMAGE_FORMAT_NONE, 5507ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P012, 2, 5517ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 }, 5527ec681f3Smrg { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } }, 5537ec681f3Smrg { DRM_FORMAT_P016, __DRI_IMAGE_FORMAT_NONE, 5547ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P016, 2, 5557ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 }, 5567ec681f3Smrg { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } }, 5577ec681f3Smrg 5587ec681f3Smrg { DRM_FORMAT_NV16, __DRI_IMAGE_FORMAT_NONE, 5597ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12, 2, 5607ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 5617ec681f3Smrg { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88 } } }, 5627ec681f3Smrg 5637ec681f3Smrg { DRM_FORMAT_AYUV, __DRI_IMAGE_FORMAT_ABGR8888, 5647ec681f3Smrg __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_AYUV, 1, 5657ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } }, 5667ec681f3Smrg { DRM_FORMAT_XYUV8888, __DRI_IMAGE_FORMAT_XBGR8888, 5677ec681f3Smrg __DRI_IMAGE_COMPONENTS_XYUV, PIPE_FORMAT_XYUV, 1, 5687ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888 } } }, 5697ec681f3Smrg 5707ec681f3Smrg { DRM_FORMAT_Y410, __DRI_IMAGE_FORMAT_ABGR2101010, 5717ec681f3Smrg __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_Y410, 1, 5727ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR2101010 } } }, 5737ec681f3Smrg 5747ec681f3Smrg /* Y412 is an unusual format. It has the same layout as Y416 (i.e., 5757ec681f3Smrg * 16-bits of physical storage per channel), but the low 4 bits of each 5767ec681f3Smrg * component are unused padding. The writer is supposed to write zeros 5777ec681f3Smrg * to these bits. 5787ec681f3Smrg */ 5797ec681f3Smrg { DRM_FORMAT_Y412, __DRI_IMAGE_FORMAT_ABGR16161616, 5807ec681f3Smrg __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_Y412, 1, 5817ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 5827ec681f3Smrg { DRM_FORMAT_Y416, __DRI_IMAGE_FORMAT_ABGR16161616, 5837ec681f3Smrg __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_Y416, 1, 5847ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 5857ec681f3Smrg 5867ec681f3Smrg /* For YUYV and UYVY buffers, we set up two overlapping DRI images 5877ec681f3Smrg * and treat them as planar buffers in the compositors. 5887ec681f3Smrg * Plane 0 is GR88 and samples YU or YV pairs and places Y into 5897ec681f3Smrg * the R component, while plane 1 is ARGB/ABGR and samples YUYV/UYVY 5907ec681f3Smrg * clusters and places pairs and places U into the G component and 5917ec681f3Smrg * V into A. This lets the texture sampler interpolate the Y 5927ec681f3Smrg * components correctly when sampling from plane 0, and interpolate 5937ec681f3Smrg * U and V correctly when sampling from plane 1. */ 5947ec681f3Smrg { DRM_FORMAT_YUYV, __DRI_IMAGE_FORMAT_NONE, 5957ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_YUYV, 2, 5967ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, 5977ec681f3Smrg { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } }, 5987ec681f3Smrg { DRM_FORMAT_UYVY, __DRI_IMAGE_FORMAT_NONE, 5997ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_UXVX, PIPE_FORMAT_UYVY, 2, 6007ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, 6017ec681f3Smrg { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } }, 6027ec681f3Smrg 6037ec681f3Smrg /* The Y21x formats work in a similar fashion to the YUYV and UYVY 6047ec681f3Smrg * formats. 6057ec681f3Smrg */ 6067ec681f3Smrg { DRM_FORMAT_Y210, __DRI_IMAGE_FORMAT_NONE, 6077ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_Y210, 2, 6087ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 }, 6097ec681f3Smrg { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 6107ec681f3Smrg /* Y212 is an unusual format. It has the same layout as Y216 (i.e., 6117ec681f3Smrg * 16-bits of physical storage per channel), but the low 4 bits of each 6127ec681f3Smrg * component are unused padding. The writer is supposed to write zeros 6137ec681f3Smrg * to these bits. 6147ec681f3Smrg */ 6157ec681f3Smrg { DRM_FORMAT_Y212, __DRI_IMAGE_FORMAT_NONE, 6167ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_Y212, 2, 6177ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 }, 6187ec681f3Smrg { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 6197ec681f3Smrg { DRM_FORMAT_Y216, __DRI_IMAGE_FORMAT_NONE, 6207ec681f3Smrg __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_Y216, 2, 6217ec681f3Smrg { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 }, 6227ec681f3Smrg { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 6237ec681f3Smrg}; 6247ec681f3Smrg 6257ec681f3Smrgconst struct dri2_format_mapping * 6267ec681f3Smrgdri2_get_mapping_by_fourcc(int fourcc) 6277ec681f3Smrg{ 6287ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { 6297ec681f3Smrg if (dri2_format_table[i].dri_fourcc == fourcc) 6307ec681f3Smrg return &dri2_format_table[i]; 6317ec681f3Smrg } 6327ec681f3Smrg 6337ec681f3Smrg return NULL; 6347ec681f3Smrg} 6357ec681f3Smrg 6367ec681f3Smrgconst struct dri2_format_mapping * 6377ec681f3Smrgdri2_get_mapping_by_format(int format) 6387ec681f3Smrg{ 6397ec681f3Smrg if (format == __DRI_IMAGE_FORMAT_NONE) 6407ec681f3Smrg return NULL; 6417ec681f3Smrg 6427ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { 6437ec681f3Smrg if (dri2_format_table[i].dri_format == format) 6447ec681f3Smrg return &dri2_format_table[i]; 6457ec681f3Smrg } 6467ec681f3Smrg 6477ec681f3Smrg return NULL; 6487ec681f3Smrg} 6497ec681f3Smrg 6507ec681f3Smrgenum pipe_format 6517ec681f3Smrgdri2_get_pipe_format_for_dri_format(int format) 6527ec681f3Smrg{ 6537ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { 6547ec681f3Smrg if (dri2_format_table[i].dri_format == format) 6557ec681f3Smrg return dri2_format_table[i].pipe_format; 6567ec681f3Smrg } 6577ec681f3Smrg 6587ec681f3Smrg return PIPE_FORMAT_NONE; 6597ec681f3Smrg} 6607ec681f3Smrg 6617ec681f3Smrgboolean 6627ec681f3Smrgdri2_yuv_dma_buf_supported(struct dri_screen *screen, 6637ec681f3Smrg const struct dri2_format_mapping *map) 6647ec681f3Smrg{ 6657ec681f3Smrg struct pipe_screen *pscreen = screen->base.screen; 6667ec681f3Smrg 6677ec681f3Smrg for (unsigned i = 0; i < map->nplanes; i++) { 6687ec681f3Smrg if (!pscreen->is_format_supported(pscreen, 6697ec681f3Smrg dri2_get_pipe_format_for_dri_format(map->planes[i].dri_format), 6707ec681f3Smrg screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) 6717ec681f3Smrg return false; 6727ec681f3Smrg } 6737ec681f3Smrg return true; 6747ec681f3Smrg} 6757ec681f3Smrg 6767ec681f3Smrgboolean 6777ec681f3Smrgdri2_query_dma_buf_formats(__DRIscreen *_screen, int max, int *formats, 6787ec681f3Smrg int *count) 6797ec681f3Smrg{ 6807ec681f3Smrg struct dri_screen *screen = dri_screen(_screen); 6817ec681f3Smrg struct pipe_screen *pscreen = screen->base.screen; 6827ec681f3Smrg int i, j; 6837ec681f3Smrg 6847ec681f3Smrg for (i = 0, j = 0; (i < ARRAY_SIZE(dri2_format_table)) && 6857ec681f3Smrg (j < max || max == 0); i++) { 6867ec681f3Smrg const struct dri2_format_mapping *map = &dri2_format_table[i]; 6877ec681f3Smrg 6887ec681f3Smrg /* The sRGB format is not a real FourCC as defined by drm_fourcc.h, so we 6897ec681f3Smrg * must not leak it out to clients. The RGBA16161616 format isn't 6907ec681f3Smrg * real either, but at some point it could be. Don't leak it out form 6917ec681f3Smrg * now. 6927ec681f3Smrg */ 6937ec681f3Smrg if (dri2_format_table[i].dri_fourcc == __DRI_IMAGE_FOURCC_SARGB8888 || 6947ec681f3Smrg dri2_format_table[i].dri_fourcc == __DRI_IMAGE_FOURCC_RGBA16161616) 6957ec681f3Smrg continue; 6967ec681f3Smrg 6977ec681f3Smrg if (pscreen->is_format_supported(pscreen, map->pipe_format, 6987ec681f3Smrg screen->target, 0, 0, 6997ec681f3Smrg PIPE_BIND_RENDER_TARGET) || 7007ec681f3Smrg pscreen->is_format_supported(pscreen, map->pipe_format, 7017ec681f3Smrg screen->target, 0, 0, 7027ec681f3Smrg PIPE_BIND_SAMPLER_VIEW) || 7037ec681f3Smrg dri2_yuv_dma_buf_supported(screen, map)) { 7047ec681f3Smrg if (j < max) 7057ec681f3Smrg formats[j] = map->dri_fourcc; 7067ec681f3Smrg j++; 7077ec681f3Smrg } 7087ec681f3Smrg } 7097ec681f3Smrg *count = j; 7107ec681f3Smrg return true; 7117ec681f3Smrg} 7127ec681f3Smrg 7137ec681f3Smrg/* vim: set sw=3 ts=8 sts=3 expandtab: */ 714