1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 12bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#include <dlfcn.h> 24bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 25bf215546Sopenharmony_ci#include "util/u_memory.h" 26bf215546Sopenharmony_ci#include "pipe/p_screen.h" 27bf215546Sopenharmony_ci#include "state_tracker/st_texture.h" 28bf215546Sopenharmony_ci#include "state_tracker/st_context.h" 29bf215546Sopenharmony_ci#include "main/texobj.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "dri_helpers.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_cistatic bool 34bf215546Sopenharmony_cidri2_is_opencl_interop_loaded_locked(struct dri_screen *screen) 35bf215546Sopenharmony_ci{ 36bf215546Sopenharmony_ci return screen->opencl_dri_event_add_ref && 37bf215546Sopenharmony_ci screen->opencl_dri_event_release && 38bf215546Sopenharmony_ci screen->opencl_dri_event_wait && 39bf215546Sopenharmony_ci screen->opencl_dri_event_get_fence; 40bf215546Sopenharmony_ci} 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistatic bool 43bf215546Sopenharmony_cidri2_load_opencl_interop(struct dri_screen *screen) 44bf215546Sopenharmony_ci{ 45bf215546Sopenharmony_ci#if defined(RTLD_DEFAULT) 46bf215546Sopenharmony_ci bool success; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci mtx_lock(&screen->opencl_func_mutex); 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci if (dri2_is_opencl_interop_loaded_locked(screen)) { 51bf215546Sopenharmony_ci mtx_unlock(&screen->opencl_func_mutex); 52bf215546Sopenharmony_ci return true; 53bf215546Sopenharmony_ci } 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci screen->opencl_dri_event_add_ref = 56bf215546Sopenharmony_ci dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref"); 57bf215546Sopenharmony_ci screen->opencl_dri_event_release = 58bf215546Sopenharmony_ci dlsym(RTLD_DEFAULT, "opencl_dri_event_release"); 59bf215546Sopenharmony_ci screen->opencl_dri_event_wait = 60bf215546Sopenharmony_ci dlsym(RTLD_DEFAULT, "opencl_dri_event_wait"); 61bf215546Sopenharmony_ci screen->opencl_dri_event_get_fence = 62bf215546Sopenharmony_ci dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence"); 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci success = dri2_is_opencl_interop_loaded_locked(screen); 65bf215546Sopenharmony_ci mtx_unlock(&screen->opencl_func_mutex); 66bf215546Sopenharmony_ci return success; 67bf215546Sopenharmony_ci#else 68bf215546Sopenharmony_ci return false; 69bf215546Sopenharmony_ci#endif 70bf215546Sopenharmony_ci} 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_cistruct dri2_fence { 73bf215546Sopenharmony_ci struct dri_screen *driscreen; 74bf215546Sopenharmony_ci struct pipe_fence_handle *pipe_fence; 75bf215546Sopenharmony_ci void *cl_event; 76bf215546Sopenharmony_ci}; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic unsigned dri2_fence_get_caps(__DRIscreen *_screen) 79bf215546Sopenharmony_ci{ 80bf215546Sopenharmony_ci struct dri_screen *driscreen = dri_screen(_screen); 81bf215546Sopenharmony_ci struct pipe_screen *screen = driscreen->base.screen; 82bf215546Sopenharmony_ci unsigned caps = 0; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD)) 85bf215546Sopenharmony_ci caps |= __DRI_FENCE_CAP_NATIVE_FD; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci return caps; 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_cistatic void * 91bf215546Sopenharmony_cidri2_create_fence(__DRIcontext *_ctx) 92bf215546Sopenharmony_ci{ 93bf215546Sopenharmony_ci struct st_context_iface *stapi = dri_context(_ctx)->st; 94bf215546Sopenharmony_ci struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci if (!fence) 97bf215546Sopenharmony_ci return NULL; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci stapi->flush(stapi, 0, &fence->pipe_fence, NULL, NULL); 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci if (!fence->pipe_fence) { 102bf215546Sopenharmony_ci FREE(fence); 103bf215546Sopenharmony_ci return NULL; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci fence->driscreen = dri_screen(_ctx->driScreenPriv); 107bf215546Sopenharmony_ci return fence; 108bf215546Sopenharmony_ci} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_cistatic void * 111bf215546Sopenharmony_cidri2_create_fence_fd(__DRIcontext *_ctx, int fd) 112bf215546Sopenharmony_ci{ 113bf215546Sopenharmony_ci struct st_context_iface *stapi = dri_context(_ctx)->st; 114bf215546Sopenharmony_ci struct pipe_context *ctx = stapi->pipe; 115bf215546Sopenharmony_ci struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence); 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci if (fd == -1) { 118bf215546Sopenharmony_ci /* exporting driver created fence, flush: */ 119bf215546Sopenharmony_ci stapi->flush(stapi, ST_FLUSH_FENCE_FD, &fence->pipe_fence, NULL, NULL); 120bf215546Sopenharmony_ci } else { 121bf215546Sopenharmony_ci /* importing a foreign fence fd: */ 122bf215546Sopenharmony_ci ctx->create_fence_fd(ctx, &fence->pipe_fence, fd, PIPE_FD_TYPE_NATIVE_SYNC); 123bf215546Sopenharmony_ci } 124bf215546Sopenharmony_ci if (!fence->pipe_fence) { 125bf215546Sopenharmony_ci FREE(fence); 126bf215546Sopenharmony_ci return NULL; 127bf215546Sopenharmony_ci } 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci fence->driscreen = dri_screen(_ctx->driScreenPriv); 130bf215546Sopenharmony_ci return fence; 131bf215546Sopenharmony_ci} 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_cistatic int 134bf215546Sopenharmony_cidri2_get_fence_fd(__DRIscreen *_screen, void *_fence) 135bf215546Sopenharmony_ci{ 136bf215546Sopenharmony_ci struct dri_screen *driscreen = dri_screen(_screen); 137bf215546Sopenharmony_ci struct pipe_screen *screen = driscreen->base.screen; 138bf215546Sopenharmony_ci struct dri2_fence *fence = (struct dri2_fence*)_fence; 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci return screen->fence_get_fd(screen, fence->pipe_fence); 141bf215546Sopenharmony_ci} 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_cistatic void * 144bf215546Sopenharmony_cidri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci struct dri_screen *driscreen = dri_screen(_screen); 147bf215546Sopenharmony_ci struct dri2_fence *fence; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci if (!dri2_load_opencl_interop(driscreen)) 150bf215546Sopenharmony_ci return NULL; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci fence = CALLOC_STRUCT(dri2_fence); 153bf215546Sopenharmony_ci if (!fence) 154bf215546Sopenharmony_ci return NULL; 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci fence->cl_event = (void*)cl_event; 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) { 159bf215546Sopenharmony_ci free(fence); 160bf215546Sopenharmony_ci return NULL; 161bf215546Sopenharmony_ci } 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci fence->driscreen = driscreen; 164bf215546Sopenharmony_ci return fence; 165bf215546Sopenharmony_ci} 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_cistatic void 168bf215546Sopenharmony_cidri2_destroy_fence(__DRIscreen *_screen, void *_fence) 169bf215546Sopenharmony_ci{ 170bf215546Sopenharmony_ci struct dri_screen *driscreen = dri_screen(_screen); 171bf215546Sopenharmony_ci struct pipe_screen *screen = driscreen->base.screen; 172bf215546Sopenharmony_ci struct dri2_fence *fence = (struct dri2_fence*)_fence; 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci if (fence->pipe_fence) 175bf215546Sopenharmony_ci screen->fence_reference(screen, &fence->pipe_fence, NULL); 176bf215546Sopenharmony_ci else if (fence->cl_event) 177bf215546Sopenharmony_ci driscreen->opencl_dri_event_release(fence->cl_event); 178bf215546Sopenharmony_ci else 179bf215546Sopenharmony_ci assert(0); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci FREE(fence); 182bf215546Sopenharmony_ci} 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_cistatic GLboolean 185bf215546Sopenharmony_cidri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags, 186bf215546Sopenharmony_ci uint64_t timeout) 187bf215546Sopenharmony_ci{ 188bf215546Sopenharmony_ci struct dri2_fence *fence = (struct dri2_fence*)_fence; 189bf215546Sopenharmony_ci struct dri_screen *driscreen = fence->driscreen; 190bf215546Sopenharmony_ci struct pipe_screen *screen = driscreen->base.screen; 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci /* No need to flush. The context was flushed when the fence was created. */ 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if (fence->pipe_fence) 195bf215546Sopenharmony_ci return screen->fence_finish(screen, NULL, fence->pipe_fence, timeout); 196bf215546Sopenharmony_ci else if (fence->cl_event) { 197bf215546Sopenharmony_ci struct pipe_fence_handle *pipe_fence = 198bf215546Sopenharmony_ci driscreen->opencl_dri_event_get_fence(fence->cl_event); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci if (pipe_fence) 201bf215546Sopenharmony_ci return screen->fence_finish(screen, NULL, pipe_fence, timeout); 202bf215546Sopenharmony_ci else 203bf215546Sopenharmony_ci return driscreen->opencl_dri_event_wait(fence->cl_event, timeout); 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci else { 206bf215546Sopenharmony_ci assert(0); 207bf215546Sopenharmony_ci return false; 208bf215546Sopenharmony_ci } 209bf215546Sopenharmony_ci} 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_cistatic void 212bf215546Sopenharmony_cidri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags) 213bf215546Sopenharmony_ci{ 214bf215546Sopenharmony_ci struct pipe_context *ctx = dri_context(_ctx)->st->pipe; 215bf215546Sopenharmony_ci struct dri2_fence *fence = (struct dri2_fence*)_fence; 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci /* We might be called here with a NULL fence as a result of WaitSyncKHR 218bf215546Sopenharmony_ci * on a EGL_KHR_reusable_sync fence. Nothing to do here in such case. 219bf215546Sopenharmony_ci */ 220bf215546Sopenharmony_ci if (!fence) 221bf215546Sopenharmony_ci return; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci if (ctx->fence_server_sync) 224bf215546Sopenharmony_ci ctx->fence_server_sync(ctx, fence->pipe_fence); 225bf215546Sopenharmony_ci} 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ciconst __DRI2fenceExtension dri2FenceExtension = { 228bf215546Sopenharmony_ci .base = { __DRI2_FENCE, 2 }, 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci .create_fence = dri2_create_fence, 231bf215546Sopenharmony_ci .get_fence_from_cl_event = dri2_get_fence_from_cl_event, 232bf215546Sopenharmony_ci .destroy_fence = dri2_destroy_fence, 233bf215546Sopenharmony_ci .client_wait_sync = dri2_client_wait_sync, 234bf215546Sopenharmony_ci .server_wait_sync = dri2_server_wait_sync, 235bf215546Sopenharmony_ci .get_capabilities = dri2_fence_get_caps, 236bf215546Sopenharmony_ci .create_fence_fd = dri2_create_fence_fd, 237bf215546Sopenharmony_ci .get_fence_fd = dri2_get_fence_fd, 238bf215546Sopenharmony_ci}; 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci__DRIimage * 241bf215546Sopenharmony_cidri2_lookup_egl_image(struct dri_screen *screen, void *handle) 242bf215546Sopenharmony_ci{ 243bf215546Sopenharmony_ci const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image; 244bf215546Sopenharmony_ci __DRIimage *img; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci if (!loader->lookupEGLImage) 247bf215546Sopenharmony_ci return NULL; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci img = loader->lookupEGLImage(screen->sPriv, 250bf215546Sopenharmony_ci handle, screen->sPriv->loaderPrivate); 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci return img; 253bf215546Sopenharmony_ci} 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ciboolean 256bf215546Sopenharmony_cidri2_validate_egl_image(struct dri_screen *screen, void *handle) 257bf215546Sopenharmony_ci{ 258bf215546Sopenharmony_ci const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image; 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci return loader->validateEGLImage(handle, screen->sPriv->loaderPrivate); 261bf215546Sopenharmony_ci} 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci__DRIimage * 264bf215546Sopenharmony_cidri2_lookup_egl_image_validated(struct dri_screen *screen, void *handle) 265bf215546Sopenharmony_ci{ 266bf215546Sopenharmony_ci const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci return loader->lookupEGLImageValidated(handle, screen->sPriv->loaderPrivate); 269bf215546Sopenharmony_ci} 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci__DRIimage * 272bf215546Sopenharmony_cidri2_create_image_from_renderbuffer2(__DRIcontext *context, 273bf215546Sopenharmony_ci int renderbuffer, void *loaderPrivate, 274bf215546Sopenharmony_ci unsigned *error) 275bf215546Sopenharmony_ci{ 276bf215546Sopenharmony_ci struct st_context *st_ctx = (struct st_context *)dri_context(context)->st; 277bf215546Sopenharmony_ci struct gl_context *ctx = st_ctx->ctx; 278bf215546Sopenharmony_ci struct pipe_context *p_ctx = st_ctx->pipe; 279bf215546Sopenharmony_ci struct gl_renderbuffer *rb; 280bf215546Sopenharmony_ci struct pipe_resource *tex; 281bf215546Sopenharmony_ci __DRIimage *img; 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci /* Section 3.9 (EGLImage Specification and Management) of the EGL 1.5 284bf215546Sopenharmony_ci * specification says: 285bf215546Sopenharmony_ci * 286bf215546Sopenharmony_ci * "If target is EGL_GL_RENDERBUFFER and buffer is not the name of a 287bf215546Sopenharmony_ci * renderbuffer object, or if buffer is the name of a multisampled 288bf215546Sopenharmony_ci * renderbuffer object, the error EGL_BAD_PARAMETER is generated." 289bf215546Sopenharmony_ci * 290bf215546Sopenharmony_ci * "If target is EGL_GL_TEXTURE_2D , EGL_GL_TEXTURE_CUBE_MAP_*, 291bf215546Sopenharmony_ci * EGL_GL_RENDERBUFFER or EGL_GL_TEXTURE_3D and buffer refers to the 292bf215546Sopenharmony_ci * default GL texture object (0) for the corresponding GL target, the 293bf215546Sopenharmony_ci * error EGL_BAD_PARAMETER is generated." 294bf215546Sopenharmony_ci * (rely on _mesa_lookup_renderbuffer returning NULL in this case) 295bf215546Sopenharmony_ci */ 296bf215546Sopenharmony_ci rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 297bf215546Sopenharmony_ci if (!rb || rb->NumSamples > 0) { 298bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 299bf215546Sopenharmony_ci return NULL; 300bf215546Sopenharmony_ci } 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci tex = rb->texture; 303bf215546Sopenharmony_ci if (!tex) { 304bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 305bf215546Sopenharmony_ci return NULL; 306bf215546Sopenharmony_ci } 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci img = CALLOC_STRUCT(__DRIimageRec); 309bf215546Sopenharmony_ci if (!img) { 310bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_ALLOC; 311bf215546Sopenharmony_ci return NULL; 312bf215546Sopenharmony_ci } 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci img->dri_format = driGLFormatToImageFormat(rb->Format); 315bf215546Sopenharmony_ci img->internal_format = rb->InternalFormat; 316bf215546Sopenharmony_ci img->loader_private = loaderPrivate; 317bf215546Sopenharmony_ci img->sPriv = context->driScreenPriv; 318bf215546Sopenharmony_ci img->in_fence_fd = -1; 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci pipe_resource_reference(&img->texture, tex); 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci /* If the resource supports EGL_MESA_image_dma_buf_export, make sure that 323bf215546Sopenharmony_ci * it's in a shareable state. Do this now while we still have the access to 324bf215546Sopenharmony_ci * the context. 325bf215546Sopenharmony_ci */ 326bf215546Sopenharmony_ci if (dri2_get_mapping_by_format(img->dri_format)) 327bf215546Sopenharmony_ci p_ctx->flush_resource(p_ctx, tex); 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci ctx->Shared->HasExternallySharedImages = true; 330bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_SUCCESS; 331bf215546Sopenharmony_ci return img; 332bf215546Sopenharmony_ci} 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci__DRIimage * 335bf215546Sopenharmony_cidri2_create_image_from_renderbuffer(__DRIcontext *context, 336bf215546Sopenharmony_ci int renderbuffer, void *loaderPrivate) 337bf215546Sopenharmony_ci{ 338bf215546Sopenharmony_ci unsigned error; 339bf215546Sopenharmony_ci return dri2_create_image_from_renderbuffer2(context, renderbuffer, 340bf215546Sopenharmony_ci loaderPrivate, &error); 341bf215546Sopenharmony_ci} 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_civoid 344bf215546Sopenharmony_cidri2_destroy_image(__DRIimage *img) 345bf215546Sopenharmony_ci{ 346bf215546Sopenharmony_ci const __DRIimageLoaderExtension *imgLoader = img->sPriv->image.loader; 347bf215546Sopenharmony_ci const __DRIdri2LoaderExtension *dri2Loader = img->sPriv->dri2.loader; 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci if (imgLoader && imgLoader->base.version >= 4 && 350bf215546Sopenharmony_ci imgLoader->destroyLoaderImageState) { 351bf215546Sopenharmony_ci imgLoader->destroyLoaderImageState(img->loader_private); 352bf215546Sopenharmony_ci } else if (dri2Loader && dri2Loader->base.version >= 5 && 353bf215546Sopenharmony_ci dri2Loader->destroyLoaderImageState) { 354bf215546Sopenharmony_ci dri2Loader->destroyLoaderImageState(img->loader_private); 355bf215546Sopenharmony_ci } 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci pipe_resource_reference(&img->texture, NULL); 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci if (img->in_fence_fd != -1) 360bf215546Sopenharmony_ci close(img->in_fence_fd); 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci FREE(img); 363bf215546Sopenharmony_ci} 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci__DRIimage * 367bf215546Sopenharmony_cidri2_create_from_texture(__DRIcontext *context, int target, unsigned texture, 368bf215546Sopenharmony_ci int depth, int level, unsigned *error, 369bf215546Sopenharmony_ci void *loaderPrivate) 370bf215546Sopenharmony_ci{ 371bf215546Sopenharmony_ci __DRIimage *img; 372bf215546Sopenharmony_ci struct st_context *st_ctx = (struct st_context *)dri_context(context)->st; 373bf215546Sopenharmony_ci struct gl_context *ctx = st_ctx->ctx; 374bf215546Sopenharmony_ci struct pipe_context *p_ctx = st_ctx->pipe; 375bf215546Sopenharmony_ci struct gl_texture_object *obj; 376bf215546Sopenharmony_ci struct pipe_resource *tex; 377bf215546Sopenharmony_ci GLuint face = 0; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci obj = _mesa_lookup_texture(ctx, texture); 380bf215546Sopenharmony_ci if (!obj || obj->Target != target) { 381bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 382bf215546Sopenharmony_ci return NULL; 383bf215546Sopenharmony_ci } 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci tex = st_get_texobj_resource(obj); 386bf215546Sopenharmony_ci if (!tex) { 387bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 388bf215546Sopenharmony_ci return NULL; 389bf215546Sopenharmony_ci } 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci if (target == GL_TEXTURE_CUBE_MAP) 392bf215546Sopenharmony_ci face = depth; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci _mesa_test_texobj_completeness(ctx, obj); 395bf215546Sopenharmony_ci if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) { 396bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; 397bf215546Sopenharmony_ci return NULL; 398bf215546Sopenharmony_ci } 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci if (level < obj->Attrib.BaseLevel || level > obj->_MaxLevel) { 401bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_MATCH; 402bf215546Sopenharmony_ci return NULL; 403bf215546Sopenharmony_ci } 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) { 406bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_MATCH; 407bf215546Sopenharmony_ci return NULL; 408bf215546Sopenharmony_ci } 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci img = CALLOC_STRUCT(__DRIimageRec); 411bf215546Sopenharmony_ci if (!img) { 412bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_BAD_ALLOC; 413bf215546Sopenharmony_ci return NULL; 414bf215546Sopenharmony_ci } 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci img->level = level; 417bf215546Sopenharmony_ci img->layer = depth; 418bf215546Sopenharmony_ci img->in_fence_fd = -1; 419bf215546Sopenharmony_ci img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat); 420bf215546Sopenharmony_ci img->internal_format = obj->Image[face][level]->InternalFormat; 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci img->loader_private = loaderPrivate; 423bf215546Sopenharmony_ci img->sPriv = context->driScreenPriv; 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci pipe_resource_reference(&img->texture, tex); 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci /* If the resource supports EGL_MESA_image_dma_buf_export, make sure that 428bf215546Sopenharmony_ci * it's in a shareable state. Do this now while we still have the access to 429bf215546Sopenharmony_ci * the context. 430bf215546Sopenharmony_ci */ 431bf215546Sopenharmony_ci if (dri2_get_mapping_by_format(img->dri_format)) 432bf215546Sopenharmony_ci p_ctx->flush_resource(p_ctx, tex); 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci ctx->Shared->HasExternallySharedImages = true; 435bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_SUCCESS; 436bf215546Sopenharmony_ci return img; 437bf215546Sopenharmony_ci} 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_cistatic const struct dri2_format_mapping dri2_format_table[] = { 440bf215546Sopenharmony_ci { DRM_FORMAT_ABGR16161616F, __DRI_IMAGE_FORMAT_ABGR16161616F, 441bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R16G16B16A16_FLOAT, 1, 442bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616F } } }, 443bf215546Sopenharmony_ci { DRM_FORMAT_XBGR16161616F, __DRI_IMAGE_FORMAT_XBGR16161616F, 444bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R16G16B16X16_FLOAT, 1, 445bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR16161616F } } }, 446bf215546Sopenharmony_ci { DRM_FORMAT_ABGR16161616, __DRI_IMAGE_FORMAT_ABGR16161616, 447bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R16G16B16A16_UNORM, 1, 448bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 449bf215546Sopenharmony_ci { DRM_FORMAT_XBGR16161616, __DRI_IMAGE_FORMAT_XBGR16161616, 450bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R16G16B16X16_UNORM, 1, 451bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR16161616 } } }, 452bf215546Sopenharmony_ci { DRM_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 453bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B10G10R10A2_UNORM, 1, 454bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB2101010 } } }, 455bf215546Sopenharmony_ci { DRM_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 456bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B10G10R10X2_UNORM, 1, 457bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB2101010 } } }, 458bf215546Sopenharmony_ci { DRM_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 459bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R10G10B10A2_UNORM, 1, 460bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR2101010 } } }, 461bf215546Sopenharmony_ci { DRM_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 462bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R10G10B10X2_UNORM, 1, 463bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR2101010 } } }, 464bf215546Sopenharmony_ci { DRM_FORMAT_ARGB8888, __DRI_IMAGE_FORMAT_ARGB8888, 465bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_UNORM, 1, 466bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } }, 467bf215546Sopenharmony_ci { DRM_FORMAT_ABGR8888, __DRI_IMAGE_FORMAT_ABGR8888, 468bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_RGBA8888_UNORM, 1, 469bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } }, 470bf215546Sopenharmony_ci { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_FORMAT_SARGB8, 471bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_SRGB, 1, 472bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8 } } }, 473bf215546Sopenharmony_ci { DRM_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888, 474bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_BGRX8888_UNORM, 1, 475bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888 } } }, 476bf215546Sopenharmony_ci { DRM_FORMAT_XBGR8888, __DRI_IMAGE_FORMAT_XBGR8888, 477bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_RGBX8888_UNORM, 1, 478bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888 } } }, 479bf215546Sopenharmony_ci { DRM_FORMAT_ARGB1555, __DRI_IMAGE_FORMAT_ARGB1555, 480bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B5G5R5A1_UNORM, 1, 481bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB1555 } } }, 482bf215546Sopenharmony_ci { DRM_FORMAT_RGB565, __DRI_IMAGE_FORMAT_RGB565, 483bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B5G6R5_UNORM, 1, 484bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565 } } }, 485bf215546Sopenharmony_ci { DRM_FORMAT_R8, __DRI_IMAGE_FORMAT_R8, 486bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R8_UNORM, 1, 487bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 } } }, 488bf215546Sopenharmony_ci { DRM_FORMAT_R16, __DRI_IMAGE_FORMAT_R16, 489bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R16_UNORM, 1, 490bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 } } }, 491bf215546Sopenharmony_ci { DRM_FORMAT_GR88, __DRI_IMAGE_FORMAT_GR88, 492bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG88_UNORM, 1, 493bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 } } }, 494bf215546Sopenharmony_ci { DRM_FORMAT_GR1616, __DRI_IMAGE_FORMAT_GR1616, 495bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG1616_UNORM, 1, 496bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 } } }, 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci { DRM_FORMAT_YUV410, __DRI_IMAGE_FORMAT_NONE, 499bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 500bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 501bf215546Sopenharmony_ci { 1, 2, 2, __DRI_IMAGE_FORMAT_R8 }, 502bf215546Sopenharmony_ci { 2, 2, 2, __DRI_IMAGE_FORMAT_R8 } } }, 503bf215546Sopenharmony_ci { DRM_FORMAT_YUV411, __DRI_IMAGE_FORMAT_NONE, 504bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 505bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 506bf215546Sopenharmony_ci { 1, 2, 0, __DRI_IMAGE_FORMAT_R8 }, 507bf215546Sopenharmony_ci { 2, 2, 0, __DRI_IMAGE_FORMAT_R8 } } }, 508bf215546Sopenharmony_ci { DRM_FORMAT_YUV420, __DRI_IMAGE_FORMAT_NONE, 509bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 510bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 511bf215546Sopenharmony_ci { 1, 1, 1, __DRI_IMAGE_FORMAT_R8 }, 512bf215546Sopenharmony_ci { 2, 1, 1, __DRI_IMAGE_FORMAT_R8 } } }, 513bf215546Sopenharmony_ci { DRM_FORMAT_YUV422, __DRI_IMAGE_FORMAT_NONE, 514bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 515bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 516bf215546Sopenharmony_ci { 1, 1, 0, __DRI_IMAGE_FORMAT_R8 }, 517bf215546Sopenharmony_ci { 2, 1, 0, __DRI_IMAGE_FORMAT_R8 } } }, 518bf215546Sopenharmony_ci { DRM_FORMAT_YUV444, __DRI_IMAGE_FORMAT_NONE, 519bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 520bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 521bf215546Sopenharmony_ci { 1, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 522bf215546Sopenharmony_ci { 2, 0, 0, __DRI_IMAGE_FORMAT_R8 } } }, 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci { DRM_FORMAT_YVU410, __DRI_IMAGE_FORMAT_NONE, 525bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 526bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 527bf215546Sopenharmony_ci { 2, 2, 2, __DRI_IMAGE_FORMAT_R8 }, 528bf215546Sopenharmony_ci { 1, 2, 2, __DRI_IMAGE_FORMAT_R8 } } }, 529bf215546Sopenharmony_ci { DRM_FORMAT_YVU411, __DRI_IMAGE_FORMAT_NONE, 530bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 531bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 532bf215546Sopenharmony_ci { 2, 2, 0, __DRI_IMAGE_FORMAT_R8 }, 533bf215546Sopenharmony_ci { 1, 2, 0, __DRI_IMAGE_FORMAT_R8 } } }, 534bf215546Sopenharmony_ci { DRM_FORMAT_YVU420, __DRI_IMAGE_FORMAT_NONE, 535bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 536bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 537bf215546Sopenharmony_ci { 2, 1, 1, __DRI_IMAGE_FORMAT_R8 }, 538bf215546Sopenharmony_ci { 1, 1, 1, __DRI_IMAGE_FORMAT_R8 } } }, 539bf215546Sopenharmony_ci { DRM_FORMAT_YVU422, __DRI_IMAGE_FORMAT_NONE, 540bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 541bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 542bf215546Sopenharmony_ci { 2, 1, 0, __DRI_IMAGE_FORMAT_R8 }, 543bf215546Sopenharmony_ci { 1, 1, 0, __DRI_IMAGE_FORMAT_R8 } } }, 544bf215546Sopenharmony_ci { DRM_FORMAT_YVU444, __DRI_IMAGE_FORMAT_NONE, 545bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV, 3, 546bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 547bf215546Sopenharmony_ci { 2, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 548bf215546Sopenharmony_ci { 1, 0, 0, __DRI_IMAGE_FORMAT_R8 } } }, 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci { DRM_FORMAT_NV12, __DRI_IMAGE_FORMAT_NONE, 551bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12, 2, 552bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 553bf215546Sopenharmony_ci { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } }, 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci { DRM_FORMAT_P010, __DRI_IMAGE_FORMAT_NONE, 556bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P010, 2, 557bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 }, 558bf215546Sopenharmony_ci { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } }, 559bf215546Sopenharmony_ci { DRM_FORMAT_P012, __DRI_IMAGE_FORMAT_NONE, 560bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P012, 2, 561bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 }, 562bf215546Sopenharmony_ci { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } }, 563bf215546Sopenharmony_ci { DRM_FORMAT_P016, __DRI_IMAGE_FORMAT_NONE, 564bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P016, 2, 565bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 }, 566bf215546Sopenharmony_ci { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } }, 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_ci { DRM_FORMAT_NV16, __DRI_IMAGE_FORMAT_NONE, 569bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12, 2, 570bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 571bf215546Sopenharmony_ci { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88 } } }, 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci { DRM_FORMAT_AYUV, __DRI_IMAGE_FORMAT_ABGR8888, 574bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_AYUV, 1, 575bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } }, 576bf215546Sopenharmony_ci { DRM_FORMAT_XYUV8888, __DRI_IMAGE_FORMAT_XBGR8888, 577bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_XYUV, PIPE_FORMAT_XYUV, 1, 578bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888 } } }, 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci { DRM_FORMAT_Y410, __DRI_IMAGE_FORMAT_ABGR2101010, 581bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_Y410, 1, 582bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR2101010 } } }, 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_ci /* Y412 is an unusual format. It has the same layout as Y416 (i.e., 585bf215546Sopenharmony_ci * 16-bits of physical storage per channel), but the low 4 bits of each 586bf215546Sopenharmony_ci * component are unused padding. The writer is supposed to write zeros 587bf215546Sopenharmony_ci * to these bits. 588bf215546Sopenharmony_ci */ 589bf215546Sopenharmony_ci { DRM_FORMAT_Y412, __DRI_IMAGE_FORMAT_ABGR16161616, 590bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_Y412, 1, 591bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 592bf215546Sopenharmony_ci { DRM_FORMAT_Y416, __DRI_IMAGE_FORMAT_ABGR16161616, 593bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_AYUV, PIPE_FORMAT_Y416, 1, 594bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci /* For YUYV and UYVY buffers, we set up two overlapping DRI images 597bf215546Sopenharmony_ci * and treat them as planar buffers in the compositors. 598bf215546Sopenharmony_ci * Plane 0 is GR88 and samples YU or YV pairs and places Y into 599bf215546Sopenharmony_ci * the R component, while plane 1 is ARGB/ABGR and samples YUYV/UYVY 600bf215546Sopenharmony_ci * clusters and places pairs and places U into the G component and 601bf215546Sopenharmony_ci * V into A. This lets the texture sampler interpolate the Y 602bf215546Sopenharmony_ci * components correctly when sampling from plane 0, and interpolate 603bf215546Sopenharmony_ci * U and V correctly when sampling from plane 1. */ 604bf215546Sopenharmony_ci { DRM_FORMAT_YUYV, __DRI_IMAGE_FORMAT_NONE, 605bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_YUYV, 2, 606bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, 607bf215546Sopenharmony_ci { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } }, 608bf215546Sopenharmony_ci { DRM_FORMAT_UYVY, __DRI_IMAGE_FORMAT_NONE, 609bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_UXVX, PIPE_FORMAT_UYVY, 2, 610bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, 611bf215546Sopenharmony_ci { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } }, 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci /* The Y21x formats work in a similar fashion to the YUYV and UYVY 614bf215546Sopenharmony_ci * formats. 615bf215546Sopenharmony_ci */ 616bf215546Sopenharmony_ci { DRM_FORMAT_Y210, __DRI_IMAGE_FORMAT_NONE, 617bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_Y210, 2, 618bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 }, 619bf215546Sopenharmony_ci { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 620bf215546Sopenharmony_ci /* Y212 is an unusual format. It has the same layout as Y216 (i.e., 621bf215546Sopenharmony_ci * 16-bits of physical storage per channel), but the low 4 bits of each 622bf215546Sopenharmony_ci * component are unused padding. The writer is supposed to write zeros 623bf215546Sopenharmony_ci * to these bits. 624bf215546Sopenharmony_ci */ 625bf215546Sopenharmony_ci { DRM_FORMAT_Y212, __DRI_IMAGE_FORMAT_NONE, 626bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_Y212, 2, 627bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 }, 628bf215546Sopenharmony_ci { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 629bf215546Sopenharmony_ci { DRM_FORMAT_Y216, __DRI_IMAGE_FORMAT_NONE, 630bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_Y216, 2, 631bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 }, 632bf215546Sopenharmony_ci { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } }, 633bf215546Sopenharmony_ci}; 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ciconst struct dri2_format_mapping * 636bf215546Sopenharmony_cidri2_get_mapping_by_fourcc(int fourcc) 637bf215546Sopenharmony_ci{ 638bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { 639bf215546Sopenharmony_ci if (dri2_format_table[i].dri_fourcc == fourcc) 640bf215546Sopenharmony_ci return &dri2_format_table[i]; 641bf215546Sopenharmony_ci } 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci return NULL; 644bf215546Sopenharmony_ci} 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ciconst struct dri2_format_mapping * 647bf215546Sopenharmony_cidri2_get_mapping_by_format(int format) 648bf215546Sopenharmony_ci{ 649bf215546Sopenharmony_ci if (format == __DRI_IMAGE_FORMAT_NONE) 650bf215546Sopenharmony_ci return NULL; 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { 653bf215546Sopenharmony_ci if (dri2_format_table[i].dri_format == format) 654bf215546Sopenharmony_ci return &dri2_format_table[i]; 655bf215546Sopenharmony_ci } 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci return NULL; 658bf215546Sopenharmony_ci} 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_cienum pipe_format 661bf215546Sopenharmony_cidri2_get_pipe_format_for_dri_format(int format) 662bf215546Sopenharmony_ci{ 663bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { 664bf215546Sopenharmony_ci if (dri2_format_table[i].dri_format == format) 665bf215546Sopenharmony_ci return dri2_format_table[i].pipe_format; 666bf215546Sopenharmony_ci } 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci return PIPE_FORMAT_NONE; 669bf215546Sopenharmony_ci} 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_ciboolean 672bf215546Sopenharmony_cidri2_yuv_dma_buf_supported(struct dri_screen *screen, 673bf215546Sopenharmony_ci const struct dri2_format_mapping *map) 674bf215546Sopenharmony_ci{ 675bf215546Sopenharmony_ci struct pipe_screen *pscreen = screen->base.screen; 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci for (unsigned i = 0; i < map->nplanes; i++) { 678bf215546Sopenharmony_ci if (!pscreen->is_format_supported(pscreen, 679bf215546Sopenharmony_ci dri2_get_pipe_format_for_dri_format(map->planes[i].dri_format), 680bf215546Sopenharmony_ci screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) 681bf215546Sopenharmony_ci return false; 682bf215546Sopenharmony_ci } 683bf215546Sopenharmony_ci return true; 684bf215546Sopenharmony_ci} 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ciboolean 687bf215546Sopenharmony_cidri2_query_dma_buf_formats(__DRIscreen *_screen, int max, int *formats, 688bf215546Sopenharmony_ci int *count) 689bf215546Sopenharmony_ci{ 690bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(_screen); 691bf215546Sopenharmony_ci struct pipe_screen *pscreen = screen->base.screen; 692bf215546Sopenharmony_ci int i, j; 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci for (i = 0, j = 0; (i < ARRAY_SIZE(dri2_format_table)) && 695bf215546Sopenharmony_ci (j < max || max == 0); i++) { 696bf215546Sopenharmony_ci const struct dri2_format_mapping *map = &dri2_format_table[i]; 697bf215546Sopenharmony_ci 698bf215546Sopenharmony_ci /* The sRGB format is not a real FourCC as defined by drm_fourcc.h, so we 699bf215546Sopenharmony_ci * must not leak it out to clients. */ 700bf215546Sopenharmony_ci if (dri2_format_table[i].dri_fourcc == __DRI_IMAGE_FOURCC_SARGB8888) 701bf215546Sopenharmony_ci continue; 702bf215546Sopenharmony_ci 703bf215546Sopenharmony_ci if (pscreen->is_format_supported(pscreen, map->pipe_format, 704bf215546Sopenharmony_ci screen->target, 0, 0, 705bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET) || 706bf215546Sopenharmony_ci pscreen->is_format_supported(pscreen, map->pipe_format, 707bf215546Sopenharmony_ci screen->target, 0, 0, 708bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW) || 709bf215546Sopenharmony_ci dri2_yuv_dma_buf_supported(screen, map)) { 710bf215546Sopenharmony_ci if (j < max) 711bf215546Sopenharmony_ci formats[j] = map->dri_fourcc; 712bf215546Sopenharmony_ci j++; 713bf215546Sopenharmony_ci } 714bf215546Sopenharmony_ci } 715bf215546Sopenharmony_ci *count = j; 716bf215546Sopenharmony_ci return true; 717bf215546Sopenharmony_ci} 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci/* vim: set sw=3 ts=8 sts=3 expandtab: */ 720