1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright 2009, VMware, Inc. 5bf215546Sopenharmony_ci * All Rights Reserved. 6bf215546Sopenharmony_ci * Copyright (C) 2010 LunarG Inc. 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 10bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 11bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 13bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 16bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci * Authors: 27bf215546Sopenharmony_ci * Keith Whitwell <keithw@vmware.com> Jakob Bornecrantz 28bf215546Sopenharmony_ci * <wallbraker@gmail.com> Chia-I Wu <olv@lunarg.com> 29bf215546Sopenharmony_ci */ 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include <xf86drm.h> 32bf215546Sopenharmony_ci#include "GL/mesa_glinterop.h" 33bf215546Sopenharmony_ci#include "util/disk_cache.h" 34bf215546Sopenharmony_ci#include "util/u_memory.h" 35bf215546Sopenharmony_ci#include "util/u_inlines.h" 36bf215546Sopenharmony_ci#include "util/format/u_format.h" 37bf215546Sopenharmony_ci#include "util/u_debug.h" 38bf215546Sopenharmony_ci#include "util/libsync.h" 39bf215546Sopenharmony_ci#include "util/os_file.h" 40bf215546Sopenharmony_ci#include "frontend/drm_driver.h" 41bf215546Sopenharmony_ci#include "state_tracker/st_format.h" 42bf215546Sopenharmony_ci#include "state_tracker/st_cb_texture.h" 43bf215546Sopenharmony_ci#include "state_tracker/st_texture.h" 44bf215546Sopenharmony_ci#include "state_tracker/st_context.h" 45bf215546Sopenharmony_ci#include "pipe-loader/pipe_loader.h" 46bf215546Sopenharmony_ci#include "main/bufferobj.h" 47bf215546Sopenharmony_ci#include "main/texobj.h" 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci#include "dri_util.h" 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci#include "dri_helpers.h" 52bf215546Sopenharmony_ci#include "dri_drawable.h" 53bf215546Sopenharmony_ci#include "dri_query_renderer.h" 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_cistruct dri2_buffer 58bf215546Sopenharmony_ci{ 59bf215546Sopenharmony_ci __DRIbuffer base; 60bf215546Sopenharmony_ci struct pipe_resource *resource; 61bf215546Sopenharmony_ci}; 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_cistatic inline struct dri2_buffer * 64bf215546Sopenharmony_cidri2_buffer(__DRIbuffer * driBufferPriv) 65bf215546Sopenharmony_ci{ 66bf215546Sopenharmony_ci return (struct dri2_buffer *) driBufferPriv; 67bf215546Sopenharmony_ci} 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci/** 70bf215546Sopenharmony_ci * DRI2 flush extension. 71bf215546Sopenharmony_ci */ 72bf215546Sopenharmony_cistatic void 73bf215546Sopenharmony_cidri2_flush_drawable(__DRIdrawable *dPriv) 74bf215546Sopenharmony_ci{ 75bf215546Sopenharmony_ci dri_flush(dPriv->driContextPriv, dPriv, __DRI2_FLUSH_DRAWABLE, -1); 76bf215546Sopenharmony_ci} 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic void 79bf215546Sopenharmony_cidri2_invalidate_drawable(__DRIdrawable *dPriv) 80bf215546Sopenharmony_ci{ 81bf215546Sopenharmony_ci struct dri_drawable *drawable = dri_drawable(dPriv); 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci dPriv->dri2.stamp++; 84bf215546Sopenharmony_ci drawable->dPriv->lastStamp = drawable->dPriv->dri2.stamp; 85bf215546Sopenharmony_ci drawable->texture_mask = 0; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci p_atomic_inc(&drawable->base.stamp); 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_cistatic const __DRI2flushExtension dri2FlushExtension = { 91bf215546Sopenharmony_ci .base = { __DRI2_FLUSH, 4 }, 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci .flush = dri2_flush_drawable, 94bf215546Sopenharmony_ci .invalidate = dri2_invalidate_drawable, 95bf215546Sopenharmony_ci .flush_with_flags = dri_flush, 96bf215546Sopenharmony_ci}; 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci/** 99bf215546Sopenharmony_ci * Retrieve __DRIbuffer from the DRI loader. 100bf215546Sopenharmony_ci */ 101bf215546Sopenharmony_cistatic __DRIbuffer * 102bf215546Sopenharmony_cidri2_drawable_get_buffers(struct dri_drawable *drawable, 103bf215546Sopenharmony_ci const enum st_attachment_type *atts, 104bf215546Sopenharmony_ci unsigned *count) 105bf215546Sopenharmony_ci{ 106bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = drawable->dPriv; 107bf215546Sopenharmony_ci const __DRIdri2LoaderExtension *loader = drawable->sPriv->dri2.loader; 108bf215546Sopenharmony_ci boolean with_format; 109bf215546Sopenharmony_ci __DRIbuffer *buffers; 110bf215546Sopenharmony_ci int num_buffers; 111bf215546Sopenharmony_ci unsigned attachments[__DRI_BUFFER_COUNT]; 112bf215546Sopenharmony_ci unsigned num_attachments, i; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci assert(loader); 115bf215546Sopenharmony_ci assert(*count <= __DRI_BUFFER_COUNT); 116bf215546Sopenharmony_ci with_format = dri_with_format(drawable->sPriv); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci num_attachments = 0; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci /* for Xserver 1.6.0 (DRI2 version 1) we always need to ask for the front */ 121bf215546Sopenharmony_ci if (!with_format) 122bf215546Sopenharmony_ci attachments[num_attachments++] = __DRI_BUFFER_FRONT_LEFT; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci for (i = 0; i < *count; i++) { 125bf215546Sopenharmony_ci enum pipe_format format; 126bf215546Sopenharmony_ci unsigned bind; 127bf215546Sopenharmony_ci int att, depth; 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci dri_drawable_get_format(drawable, atts[i], &format, &bind); 130bf215546Sopenharmony_ci if (format == PIPE_FORMAT_NONE) 131bf215546Sopenharmony_ci continue; 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci switch (atts[i]) { 134bf215546Sopenharmony_ci case ST_ATTACHMENT_FRONT_LEFT: 135bf215546Sopenharmony_ci /* already added */ 136bf215546Sopenharmony_ci if (!with_format) 137bf215546Sopenharmony_ci continue; 138bf215546Sopenharmony_ci att = __DRI_BUFFER_FRONT_LEFT; 139bf215546Sopenharmony_ci break; 140bf215546Sopenharmony_ci case ST_ATTACHMENT_BACK_LEFT: 141bf215546Sopenharmony_ci att = __DRI_BUFFER_BACK_LEFT; 142bf215546Sopenharmony_ci break; 143bf215546Sopenharmony_ci case ST_ATTACHMENT_FRONT_RIGHT: 144bf215546Sopenharmony_ci att = __DRI_BUFFER_FRONT_RIGHT; 145bf215546Sopenharmony_ci break; 146bf215546Sopenharmony_ci case ST_ATTACHMENT_BACK_RIGHT: 147bf215546Sopenharmony_ci att = __DRI_BUFFER_BACK_RIGHT; 148bf215546Sopenharmony_ci break; 149bf215546Sopenharmony_ci default: 150bf215546Sopenharmony_ci continue; 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci /* 154bf215546Sopenharmony_ci * In this switch statement we must support all formats that 155bf215546Sopenharmony_ci * may occur as the stvis->color_format. 156bf215546Sopenharmony_ci */ 157bf215546Sopenharmony_ci switch(format) { 158bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16A16_FLOAT: 159bf215546Sopenharmony_ci depth = 64; 160bf215546Sopenharmony_ci break; 161bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16X16_FLOAT: 162bf215546Sopenharmony_ci depth = 48; 163bf215546Sopenharmony_ci break; 164bf215546Sopenharmony_ci case PIPE_FORMAT_B10G10R10A2_UNORM: 165bf215546Sopenharmony_ci case PIPE_FORMAT_R10G10B10A2_UNORM: 166bf215546Sopenharmony_ci case PIPE_FORMAT_BGRA8888_UNORM: 167bf215546Sopenharmony_ci case PIPE_FORMAT_RGBA8888_UNORM: 168bf215546Sopenharmony_ci depth = 32; 169bf215546Sopenharmony_ci break; 170bf215546Sopenharmony_ci case PIPE_FORMAT_R10G10B10X2_UNORM: 171bf215546Sopenharmony_ci case PIPE_FORMAT_B10G10R10X2_UNORM: 172bf215546Sopenharmony_ci depth = 30; 173bf215546Sopenharmony_ci break; 174bf215546Sopenharmony_ci case PIPE_FORMAT_BGRX8888_UNORM: 175bf215546Sopenharmony_ci case PIPE_FORMAT_RGBX8888_UNORM: 176bf215546Sopenharmony_ci depth = 24; 177bf215546Sopenharmony_ci break; 178bf215546Sopenharmony_ci case PIPE_FORMAT_B5G6R5_UNORM: 179bf215546Sopenharmony_ci depth = 16; 180bf215546Sopenharmony_ci break; 181bf215546Sopenharmony_ci default: 182bf215546Sopenharmony_ci depth = util_format_get_blocksizebits(format); 183bf215546Sopenharmony_ci assert(!"Unexpected format in dri2_drawable_get_buffers()"); 184bf215546Sopenharmony_ci } 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci attachments[num_attachments++] = att; 187bf215546Sopenharmony_ci if (with_format) { 188bf215546Sopenharmony_ci attachments[num_attachments++] = depth; 189bf215546Sopenharmony_ci } 190bf215546Sopenharmony_ci } 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci if (with_format) { 193bf215546Sopenharmony_ci num_attachments /= 2; 194bf215546Sopenharmony_ci buffers = loader->getBuffersWithFormat(dri_drawable, 195bf215546Sopenharmony_ci &dri_drawable->w, &dri_drawable->h, 196bf215546Sopenharmony_ci attachments, num_attachments, 197bf215546Sopenharmony_ci &num_buffers, dri_drawable->loaderPrivate); 198bf215546Sopenharmony_ci } 199bf215546Sopenharmony_ci else { 200bf215546Sopenharmony_ci buffers = loader->getBuffers(dri_drawable, 201bf215546Sopenharmony_ci &dri_drawable->w, &dri_drawable->h, 202bf215546Sopenharmony_ci attachments, num_attachments, 203bf215546Sopenharmony_ci &num_buffers, dri_drawable->loaderPrivate); 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci if (buffers) 207bf215546Sopenharmony_ci *count = num_buffers; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci return buffers; 210bf215546Sopenharmony_ci} 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_cibool 213bf215546Sopenharmony_cidri_image_drawable_get_buffers(struct dri_drawable *drawable, 214bf215546Sopenharmony_ci struct __DRIimageList *images, 215bf215546Sopenharmony_ci const enum st_attachment_type *statts, 216bf215546Sopenharmony_ci unsigned statts_count); 217bf215546Sopenharmony_cibool 218bf215546Sopenharmony_cidri_image_drawable_get_buffers(struct dri_drawable *drawable, 219bf215546Sopenharmony_ci struct __DRIimageList *images, 220bf215546Sopenharmony_ci const enum st_attachment_type *statts, 221bf215546Sopenharmony_ci unsigned statts_count) 222bf215546Sopenharmony_ci{ 223bf215546Sopenharmony_ci __DRIdrawable *dPriv = drawable->dPriv; 224bf215546Sopenharmony_ci __DRIscreen *sPriv = drawable->sPriv; 225bf215546Sopenharmony_ci unsigned int image_format = __DRI_IMAGE_FORMAT_NONE; 226bf215546Sopenharmony_ci enum pipe_format pf; 227bf215546Sopenharmony_ci uint32_t buffer_mask = 0; 228bf215546Sopenharmony_ci unsigned i, bind; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci for (i = 0; i < statts_count; i++) { 231bf215546Sopenharmony_ci dri_drawable_get_format(drawable, statts[i], &pf, &bind); 232bf215546Sopenharmony_ci if (pf == PIPE_FORMAT_NONE) 233bf215546Sopenharmony_ci continue; 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci switch (statts[i]) { 236bf215546Sopenharmony_ci case ST_ATTACHMENT_FRONT_LEFT: 237bf215546Sopenharmony_ci buffer_mask |= __DRI_IMAGE_BUFFER_FRONT; 238bf215546Sopenharmony_ci break; 239bf215546Sopenharmony_ci case ST_ATTACHMENT_BACK_LEFT: 240bf215546Sopenharmony_ci buffer_mask |= __DRI_IMAGE_BUFFER_BACK; 241bf215546Sopenharmony_ci break; 242bf215546Sopenharmony_ci default: 243bf215546Sopenharmony_ci continue; 244bf215546Sopenharmony_ci } 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci switch (pf) { 247bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16A16_FLOAT: 248bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ABGR16161616F; 249bf215546Sopenharmony_ci break; 250bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16X16_FLOAT: 251bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XBGR16161616F; 252bf215546Sopenharmony_ci break; 253bf215546Sopenharmony_ci case PIPE_FORMAT_B5G5R5A1_UNORM: 254bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ARGB1555; 255bf215546Sopenharmony_ci break; 256bf215546Sopenharmony_ci case PIPE_FORMAT_B5G6R5_UNORM: 257bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_RGB565; 258bf215546Sopenharmony_ci break; 259bf215546Sopenharmony_ci case PIPE_FORMAT_BGRX8888_UNORM: 260bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XRGB8888; 261bf215546Sopenharmony_ci break; 262bf215546Sopenharmony_ci case PIPE_FORMAT_BGRA8888_UNORM: 263bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ARGB8888; 264bf215546Sopenharmony_ci break; 265bf215546Sopenharmony_ci case PIPE_FORMAT_RGBX8888_UNORM: 266bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XBGR8888; 267bf215546Sopenharmony_ci break; 268bf215546Sopenharmony_ci case PIPE_FORMAT_RGBA8888_UNORM: 269bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ABGR8888; 270bf215546Sopenharmony_ci break; 271bf215546Sopenharmony_ci case PIPE_FORMAT_B10G10R10X2_UNORM: 272bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XRGB2101010; 273bf215546Sopenharmony_ci break; 274bf215546Sopenharmony_ci case PIPE_FORMAT_B10G10R10A2_UNORM: 275bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ARGB2101010; 276bf215546Sopenharmony_ci break; 277bf215546Sopenharmony_ci case PIPE_FORMAT_R10G10B10X2_UNORM: 278bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XBGR2101010; 279bf215546Sopenharmony_ci break; 280bf215546Sopenharmony_ci case PIPE_FORMAT_R10G10B10A2_UNORM: 281bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ABGR2101010; 282bf215546Sopenharmony_ci break; 283bf215546Sopenharmony_ci default: 284bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_NONE; 285bf215546Sopenharmony_ci break; 286bf215546Sopenharmony_ci } 287bf215546Sopenharmony_ci } 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci return (*sPriv->image.loader->getBuffers) (dPriv, image_format, 290bf215546Sopenharmony_ci (uint32_t *) &drawable->base.stamp, 291bf215546Sopenharmony_ci dPriv->loaderPrivate, buffer_mask, 292bf215546Sopenharmony_ci images); 293bf215546Sopenharmony_ci} 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_cistatic __DRIbuffer * 296bf215546Sopenharmony_cidri2_allocate_buffer(__DRIscreen *sPriv, 297bf215546Sopenharmony_ci unsigned attachment, unsigned format, 298bf215546Sopenharmony_ci int width, int height) 299bf215546Sopenharmony_ci{ 300bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(sPriv); 301bf215546Sopenharmony_ci struct dri2_buffer *buffer; 302bf215546Sopenharmony_ci struct pipe_resource templ; 303bf215546Sopenharmony_ci enum pipe_format pf; 304bf215546Sopenharmony_ci unsigned bind = 0; 305bf215546Sopenharmony_ci struct winsys_handle whandle; 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci /* struct pipe_resource height0 is 16-bit, avoid overflow */ 308bf215546Sopenharmony_ci if (height > 0xffff) 309bf215546Sopenharmony_ci return NULL; 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci switch (attachment) { 312bf215546Sopenharmony_ci case __DRI_BUFFER_FRONT_LEFT: 313bf215546Sopenharmony_ci case __DRI_BUFFER_FAKE_FRONT_LEFT: 314bf215546Sopenharmony_ci bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; 315bf215546Sopenharmony_ci break; 316bf215546Sopenharmony_ci case __DRI_BUFFER_BACK_LEFT: 317bf215546Sopenharmony_ci bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; 318bf215546Sopenharmony_ci break; 319bf215546Sopenharmony_ci case __DRI_BUFFER_DEPTH: 320bf215546Sopenharmony_ci case __DRI_BUFFER_DEPTH_STENCIL: 321bf215546Sopenharmony_ci case __DRI_BUFFER_STENCIL: 322bf215546Sopenharmony_ci bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */ 323bf215546Sopenharmony_ci break; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci /* because we get the handle and stride */ 327bf215546Sopenharmony_ci bind |= PIPE_BIND_SHARED; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci switch (format) { 330bf215546Sopenharmony_ci case 64: 331bf215546Sopenharmony_ci pf = PIPE_FORMAT_R16G16B16A16_FLOAT; 332bf215546Sopenharmony_ci break; 333bf215546Sopenharmony_ci case 48: 334bf215546Sopenharmony_ci pf = PIPE_FORMAT_R16G16B16X16_FLOAT; 335bf215546Sopenharmony_ci break; 336bf215546Sopenharmony_ci case 32: 337bf215546Sopenharmony_ci pf = PIPE_FORMAT_BGRA8888_UNORM; 338bf215546Sopenharmony_ci break; 339bf215546Sopenharmony_ci case 30: 340bf215546Sopenharmony_ci pf = PIPE_FORMAT_B10G10R10X2_UNORM; 341bf215546Sopenharmony_ci break; 342bf215546Sopenharmony_ci case 24: 343bf215546Sopenharmony_ci pf = PIPE_FORMAT_BGRX8888_UNORM; 344bf215546Sopenharmony_ci break; 345bf215546Sopenharmony_ci case 16: 346bf215546Sopenharmony_ci pf = PIPE_FORMAT_Z16_UNORM; 347bf215546Sopenharmony_ci break; 348bf215546Sopenharmony_ci default: 349bf215546Sopenharmony_ci return NULL; 350bf215546Sopenharmony_ci } 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci buffer = CALLOC_STRUCT(dri2_buffer); 353bf215546Sopenharmony_ci if (!buffer) 354bf215546Sopenharmony_ci return NULL; 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci memset(&templ, 0, sizeof(templ)); 357bf215546Sopenharmony_ci templ.bind = bind; 358bf215546Sopenharmony_ci templ.format = pf; 359bf215546Sopenharmony_ci templ.target = PIPE_TEXTURE_2D; 360bf215546Sopenharmony_ci templ.last_level = 0; 361bf215546Sopenharmony_ci templ.width0 = width; 362bf215546Sopenharmony_ci templ.height0 = height; 363bf215546Sopenharmony_ci templ.depth0 = 1; 364bf215546Sopenharmony_ci templ.array_size = 1; 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci buffer->resource = 367bf215546Sopenharmony_ci screen->base.screen->resource_create(screen->base.screen, &templ); 368bf215546Sopenharmony_ci if (!buffer->resource) { 369bf215546Sopenharmony_ci FREE(buffer); 370bf215546Sopenharmony_ci return NULL; 371bf215546Sopenharmony_ci } 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 374bf215546Sopenharmony_ci if (screen->can_share_buffer) 375bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_SHARED; 376bf215546Sopenharmony_ci else 377bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_KMS; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci screen->base.screen->resource_get_handle(screen->base.screen, NULL, 380bf215546Sopenharmony_ci buffer->resource, &whandle, 381bf215546Sopenharmony_ci PIPE_HANDLE_USAGE_EXPLICIT_FLUSH); 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci buffer->base.attachment = attachment; 384bf215546Sopenharmony_ci buffer->base.name = whandle.handle; 385bf215546Sopenharmony_ci buffer->base.cpp = util_format_get_blocksize(pf); 386bf215546Sopenharmony_ci buffer->base.pitch = whandle.stride; 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_ci return &buffer->base; 389bf215546Sopenharmony_ci} 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_cistatic void 392bf215546Sopenharmony_cidri2_release_buffer(__DRIscreen *sPriv, __DRIbuffer *bPriv) 393bf215546Sopenharmony_ci{ 394bf215546Sopenharmony_ci struct dri2_buffer *buffer = dri2_buffer(bPriv); 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci pipe_resource_reference(&buffer->resource, NULL); 397bf215546Sopenharmony_ci FREE(buffer); 398bf215546Sopenharmony_ci} 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_cistatic void 401bf215546Sopenharmony_cidri2_set_in_fence_fd(__DRIimage *img, int fd) 402bf215546Sopenharmony_ci{ 403bf215546Sopenharmony_ci validate_fence_fd(fd); 404bf215546Sopenharmony_ci validate_fence_fd(img->in_fence_fd); 405bf215546Sopenharmony_ci sync_accumulate("dri", &img->in_fence_fd, fd); 406bf215546Sopenharmony_ci} 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_cistatic void 409bf215546Sopenharmony_cihandle_in_fence(__DRIcontext *context, __DRIimage *img) 410bf215546Sopenharmony_ci{ 411bf215546Sopenharmony_ci struct dri_context *ctx = dri_context(context); 412bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->st->pipe; 413bf215546Sopenharmony_ci struct pipe_fence_handle *fence; 414bf215546Sopenharmony_ci int fd = img->in_fence_fd; 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci if (fd == -1) 417bf215546Sopenharmony_ci return; 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci validate_fence_fd(fd); 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci img->in_fence_fd = -1; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci pipe->create_fence_fd(pipe, &fence, fd, PIPE_FD_TYPE_NATIVE_SYNC); 424bf215546Sopenharmony_ci pipe->fence_server_sync(pipe, fence); 425bf215546Sopenharmony_ci pipe->screen->fence_reference(pipe->screen, &fence, NULL); 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci close(fd); 428bf215546Sopenharmony_ci} 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci/* 431bf215546Sopenharmony_ci * Backend functions for st_framebuffer interface. 432bf215546Sopenharmony_ci */ 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_cistatic void 435bf215546Sopenharmony_cidri2_allocate_textures(struct dri_context *ctx, 436bf215546Sopenharmony_ci struct dri_drawable *drawable, 437bf215546Sopenharmony_ci const enum st_attachment_type *statts, 438bf215546Sopenharmony_ci unsigned statts_count) 439bf215546Sopenharmony_ci{ 440bf215546Sopenharmony_ci __DRIscreen *sPriv = drawable->sPriv; 441bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = drawable->dPriv; 442bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(sPriv); 443bf215546Sopenharmony_ci struct pipe_resource templ; 444bf215546Sopenharmony_ci boolean alloc_depthstencil = FALSE; 445bf215546Sopenharmony_ci unsigned i, j, bind; 446bf215546Sopenharmony_ci const __DRIimageLoaderExtension *image = sPriv->image.loader; 447bf215546Sopenharmony_ci /* Image specific variables */ 448bf215546Sopenharmony_ci struct __DRIimageList images; 449bf215546Sopenharmony_ci /* Dri2 specific variables */ 450bf215546Sopenharmony_ci __DRIbuffer *buffers = NULL; 451bf215546Sopenharmony_ci struct winsys_handle whandle; 452bf215546Sopenharmony_ci unsigned num_buffers = statts_count; 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci assert(num_buffers <= __DRI_BUFFER_COUNT); 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci /* First get the buffers from the loader */ 457bf215546Sopenharmony_ci if (image) { 458bf215546Sopenharmony_ci if (!dri_image_drawable_get_buffers(drawable, &images, 459bf215546Sopenharmony_ci statts, statts_count)) 460bf215546Sopenharmony_ci return; 461bf215546Sopenharmony_ci } 462bf215546Sopenharmony_ci else { 463bf215546Sopenharmony_ci buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers); 464bf215546Sopenharmony_ci if (!buffers || (drawable->old_num == num_buffers && 465bf215546Sopenharmony_ci drawable->old_w == dri_drawable->w && 466bf215546Sopenharmony_ci drawable->old_h == dri_drawable->h && 467bf215546Sopenharmony_ci memcmp(drawable->old, buffers, 468bf215546Sopenharmony_ci sizeof(__DRIbuffer) * num_buffers) == 0)) 469bf215546Sopenharmony_ci return; 470bf215546Sopenharmony_ci } 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci /* Second clean useless resources*/ 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci /* See if we need a depth-stencil buffer. */ 475bf215546Sopenharmony_ci for (i = 0; i < statts_count; i++) { 476bf215546Sopenharmony_ci if (statts[i] == ST_ATTACHMENT_DEPTH_STENCIL) { 477bf215546Sopenharmony_ci alloc_depthstencil = TRUE; 478bf215546Sopenharmony_ci break; 479bf215546Sopenharmony_ci } 480bf215546Sopenharmony_ci } 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci /* Delete the resources we won't need. */ 483bf215546Sopenharmony_ci for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { 484bf215546Sopenharmony_ci /* Don't delete the depth-stencil buffer, we can reuse it. */ 485bf215546Sopenharmony_ci if (i == ST_ATTACHMENT_DEPTH_STENCIL && alloc_depthstencil) 486bf215546Sopenharmony_ci continue; 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci /* Flush the texture before unreferencing, so that other clients can 489bf215546Sopenharmony_ci * see what the driver has rendered. 490bf215546Sopenharmony_ci */ 491bf215546Sopenharmony_ci if (i != ST_ATTACHMENT_DEPTH_STENCIL && drawable->textures[i]) { 492bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->st->pipe; 493bf215546Sopenharmony_ci pipe->flush_resource(pipe, drawable->textures[i]); 494bf215546Sopenharmony_ci } 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci pipe_resource_reference(&drawable->textures[i], NULL); 497bf215546Sopenharmony_ci } 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci if (drawable->stvis.samples > 1) { 500bf215546Sopenharmony_ci for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { 501bf215546Sopenharmony_ci boolean del = TRUE; 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci /* Don't delete MSAA resources for the attachments which are enabled, 504bf215546Sopenharmony_ci * we can reuse them. */ 505bf215546Sopenharmony_ci for (j = 0; j < statts_count; j++) { 506bf215546Sopenharmony_ci if (i == statts[j]) { 507bf215546Sopenharmony_ci del = FALSE; 508bf215546Sopenharmony_ci break; 509bf215546Sopenharmony_ci } 510bf215546Sopenharmony_ci } 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci if (del) { 513bf215546Sopenharmony_ci pipe_resource_reference(&drawable->msaa_textures[i], NULL); 514bf215546Sopenharmony_ci } 515bf215546Sopenharmony_ci } 516bf215546Sopenharmony_ci } 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci /* Third use the buffers retrieved to fill the drawable info */ 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci memset(&templ, 0, sizeof(templ)); 521bf215546Sopenharmony_ci templ.target = screen->target; 522bf215546Sopenharmony_ci templ.last_level = 0; 523bf215546Sopenharmony_ci templ.depth0 = 1; 524bf215546Sopenharmony_ci templ.array_size = 1; 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci if (image) { 527bf215546Sopenharmony_ci if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) { 528bf215546Sopenharmony_ci struct pipe_resource **buf = 529bf215546Sopenharmony_ci &drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; 530bf215546Sopenharmony_ci struct pipe_resource *texture = images.front->texture; 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci dri_drawable->w = texture->width0; 533bf215546Sopenharmony_ci dri_drawable->h = texture->height0; 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_ci pipe_resource_reference(buf, texture); 536bf215546Sopenharmony_ci handle_in_fence(ctx->cPriv, images.front); 537bf215546Sopenharmony_ci } 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) { 540bf215546Sopenharmony_ci struct pipe_resource **buf = 541bf215546Sopenharmony_ci &drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 542bf215546Sopenharmony_ci struct pipe_resource *texture = images.back->texture; 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci dri_drawable->w = texture->width0; 545bf215546Sopenharmony_ci dri_drawable->h = texture->height0; 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci pipe_resource_reference(buf, texture); 548bf215546Sopenharmony_ci handle_in_fence(ctx->cPriv, images.back); 549bf215546Sopenharmony_ci } 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) { 552bf215546Sopenharmony_ci struct pipe_resource **buf = 553bf215546Sopenharmony_ci &drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 554bf215546Sopenharmony_ci struct pipe_resource *texture = images.back->texture; 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci dri_drawable->w = texture->width0; 557bf215546Sopenharmony_ci dri_drawable->h = texture->height0; 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_ci pipe_resource_reference(buf, texture); 560bf215546Sopenharmony_ci handle_in_fence(ctx->cPriv, images.back); 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ci ctx->is_shared_buffer_bound = true; 563bf215546Sopenharmony_ci } else { 564bf215546Sopenharmony_ci ctx->is_shared_buffer_bound = false; 565bf215546Sopenharmony_ci } 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci /* Note: if there is both a back and a front buffer, 568bf215546Sopenharmony_ci * then they have the same size. 569bf215546Sopenharmony_ci */ 570bf215546Sopenharmony_ci templ.width0 = dri_drawable->w; 571bf215546Sopenharmony_ci templ.height0 = dri_drawable->h; 572bf215546Sopenharmony_ci } 573bf215546Sopenharmony_ci else { 574bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci /* Process DRI-provided buffers and get pipe_resources. */ 577bf215546Sopenharmony_ci for (i = 0; i < num_buffers; i++) { 578bf215546Sopenharmony_ci __DRIbuffer *buf = &buffers[i]; 579bf215546Sopenharmony_ci enum st_attachment_type statt; 580bf215546Sopenharmony_ci enum pipe_format format; 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci switch (buf->attachment) { 583bf215546Sopenharmony_ci case __DRI_BUFFER_FRONT_LEFT: 584bf215546Sopenharmony_ci if (!screen->auto_fake_front) { 585bf215546Sopenharmony_ci continue; /* invalid attachment */ 586bf215546Sopenharmony_ci } 587bf215546Sopenharmony_ci FALLTHROUGH; 588bf215546Sopenharmony_ci case __DRI_BUFFER_FAKE_FRONT_LEFT: 589bf215546Sopenharmony_ci statt = ST_ATTACHMENT_FRONT_LEFT; 590bf215546Sopenharmony_ci break; 591bf215546Sopenharmony_ci case __DRI_BUFFER_BACK_LEFT: 592bf215546Sopenharmony_ci statt = ST_ATTACHMENT_BACK_LEFT; 593bf215546Sopenharmony_ci break; 594bf215546Sopenharmony_ci default: 595bf215546Sopenharmony_ci continue; /* invalid attachment */ 596bf215546Sopenharmony_ci } 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci dri_drawable_get_format(drawable, statt, &format, &bind); 599bf215546Sopenharmony_ci if (format == PIPE_FORMAT_NONE) 600bf215546Sopenharmony_ci continue; 601bf215546Sopenharmony_ci 602bf215546Sopenharmony_ci /* dri2_drawable_get_buffers has already filled dri_drawable->w 603bf215546Sopenharmony_ci * and dri_drawable->h */ 604bf215546Sopenharmony_ci templ.width0 = dri_drawable->w; 605bf215546Sopenharmony_ci templ.height0 = dri_drawable->h; 606bf215546Sopenharmony_ci templ.format = format; 607bf215546Sopenharmony_ci templ.bind = bind; 608bf215546Sopenharmony_ci whandle.handle = buf->name; 609bf215546Sopenharmony_ci whandle.stride = buf->pitch; 610bf215546Sopenharmony_ci whandle.offset = 0; 611bf215546Sopenharmony_ci whandle.format = format; 612bf215546Sopenharmony_ci whandle.modifier = DRM_FORMAT_MOD_INVALID; 613bf215546Sopenharmony_ci if (screen->can_share_buffer) 614bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_SHARED; 615bf215546Sopenharmony_ci else 616bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_KMS; 617bf215546Sopenharmony_ci drawable->textures[statt] = 618bf215546Sopenharmony_ci screen->base.screen->resource_from_handle(screen->base.screen, 619bf215546Sopenharmony_ci &templ, &whandle, 620bf215546Sopenharmony_ci PIPE_HANDLE_USAGE_EXPLICIT_FLUSH); 621bf215546Sopenharmony_ci assert(drawable->textures[statt]); 622bf215546Sopenharmony_ci } 623bf215546Sopenharmony_ci } 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci /* Allocate private MSAA colorbuffers. */ 626bf215546Sopenharmony_ci if (drawable->stvis.samples > 1) { 627bf215546Sopenharmony_ci for (i = 0; i < statts_count; i++) { 628bf215546Sopenharmony_ci enum st_attachment_type statt = statts[i]; 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci if (statt == ST_ATTACHMENT_DEPTH_STENCIL) 631bf215546Sopenharmony_ci continue; 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci if (drawable->textures[statt]) { 634bf215546Sopenharmony_ci templ.format = drawable->textures[statt]->format; 635bf215546Sopenharmony_ci templ.bind = drawable->textures[statt]->bind & 636bf215546Sopenharmony_ci ~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED); 637bf215546Sopenharmony_ci templ.nr_samples = drawable->stvis.samples; 638bf215546Sopenharmony_ci templ.nr_storage_samples = drawable->stvis.samples; 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ci /* Try to reuse the resource. 641bf215546Sopenharmony_ci * (the other resource parameters should be constant) 642bf215546Sopenharmony_ci */ 643bf215546Sopenharmony_ci if (!drawable->msaa_textures[statt] || 644bf215546Sopenharmony_ci drawable->msaa_textures[statt]->width0 != templ.width0 || 645bf215546Sopenharmony_ci drawable->msaa_textures[statt]->height0 != templ.height0) { 646bf215546Sopenharmony_ci /* Allocate a new one. */ 647bf215546Sopenharmony_ci pipe_resource_reference(&drawable->msaa_textures[statt], NULL); 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_ci drawable->msaa_textures[statt] = 650bf215546Sopenharmony_ci screen->base.screen->resource_create(screen->base.screen, 651bf215546Sopenharmony_ci &templ); 652bf215546Sopenharmony_ci assert(drawable->msaa_textures[statt]); 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci /* If there are any MSAA resources, we should initialize them 655bf215546Sopenharmony_ci * such that they contain the same data as the single-sample 656bf215546Sopenharmony_ci * resources we just got from the X server. 657bf215546Sopenharmony_ci * 658bf215546Sopenharmony_ci * The reason for this is that the gallium frontend (and 659bf215546Sopenharmony_ci * therefore the app) can access the MSAA resources only. 660bf215546Sopenharmony_ci * The single-sample resources are not exposed 661bf215546Sopenharmony_ci * to the gallium frontend. 662bf215546Sopenharmony_ci * 663bf215546Sopenharmony_ci */ 664bf215546Sopenharmony_ci dri_pipe_blit(ctx->st->pipe, 665bf215546Sopenharmony_ci drawable->msaa_textures[statt], 666bf215546Sopenharmony_ci drawable->textures[statt]); 667bf215546Sopenharmony_ci } 668bf215546Sopenharmony_ci } 669bf215546Sopenharmony_ci else { 670bf215546Sopenharmony_ci pipe_resource_reference(&drawable->msaa_textures[statt], NULL); 671bf215546Sopenharmony_ci } 672bf215546Sopenharmony_ci } 673bf215546Sopenharmony_ci } 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci /* Allocate a private depth-stencil buffer. */ 676bf215546Sopenharmony_ci if (alloc_depthstencil) { 677bf215546Sopenharmony_ci enum st_attachment_type statt = ST_ATTACHMENT_DEPTH_STENCIL; 678bf215546Sopenharmony_ci struct pipe_resource **zsbuf; 679bf215546Sopenharmony_ci enum pipe_format format; 680bf215546Sopenharmony_ci unsigned bind; 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci dri_drawable_get_format(drawable, statt, &format, &bind); 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci if (format) { 685bf215546Sopenharmony_ci templ.format = format; 686bf215546Sopenharmony_ci templ.bind = bind & ~PIPE_BIND_SHARED; 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci if (drawable->stvis.samples > 1) { 689bf215546Sopenharmony_ci templ.nr_samples = drawable->stvis.samples; 690bf215546Sopenharmony_ci templ.nr_storage_samples = drawable->stvis.samples; 691bf215546Sopenharmony_ci zsbuf = &drawable->msaa_textures[statt]; 692bf215546Sopenharmony_ci } 693bf215546Sopenharmony_ci else { 694bf215546Sopenharmony_ci templ.nr_samples = 0; 695bf215546Sopenharmony_ci templ.nr_storage_samples = 0; 696bf215546Sopenharmony_ci zsbuf = &drawable->textures[statt]; 697bf215546Sopenharmony_ci } 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci /* Try to reuse the resource. 700bf215546Sopenharmony_ci * (the other resource parameters should be constant) 701bf215546Sopenharmony_ci */ 702bf215546Sopenharmony_ci if (!*zsbuf || 703bf215546Sopenharmony_ci (*zsbuf)->width0 != templ.width0 || 704bf215546Sopenharmony_ci (*zsbuf)->height0 != templ.height0) { 705bf215546Sopenharmony_ci /* Allocate a new one. */ 706bf215546Sopenharmony_ci pipe_resource_reference(zsbuf, NULL); 707bf215546Sopenharmony_ci *zsbuf = screen->base.screen->resource_create(screen->base.screen, 708bf215546Sopenharmony_ci &templ); 709bf215546Sopenharmony_ci assert(*zsbuf); 710bf215546Sopenharmony_ci } 711bf215546Sopenharmony_ci } 712bf215546Sopenharmony_ci else { 713bf215546Sopenharmony_ci pipe_resource_reference(&drawable->msaa_textures[statt], NULL); 714bf215546Sopenharmony_ci pipe_resource_reference(&drawable->textures[statt], NULL); 715bf215546Sopenharmony_ci } 716bf215546Sopenharmony_ci } 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ci /* For DRI2, we may get the same buffers again from the server. 719bf215546Sopenharmony_ci * To prevent useless imports of gem names, drawable->old* is used 720bf215546Sopenharmony_ci * to bypass the import if we get the same buffers. This doesn't apply 721bf215546Sopenharmony_ci * to DRI3/Wayland, users of image.loader, since the buffer is managed 722bf215546Sopenharmony_ci * by the client (no import), and the back buffer is going to change 723bf215546Sopenharmony_ci * at every redraw. 724bf215546Sopenharmony_ci */ 725bf215546Sopenharmony_ci if (!image) { 726bf215546Sopenharmony_ci drawable->old_num = num_buffers; 727bf215546Sopenharmony_ci drawable->old_w = dri_drawable->w; 728bf215546Sopenharmony_ci drawable->old_h = dri_drawable->h; 729bf215546Sopenharmony_ci memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * num_buffers); 730bf215546Sopenharmony_ci } 731bf215546Sopenharmony_ci} 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_cistatic bool 734bf215546Sopenharmony_cidri2_flush_frontbuffer(struct dri_context *ctx, 735bf215546Sopenharmony_ci struct dri_drawable *drawable, 736bf215546Sopenharmony_ci enum st_attachment_type statt) 737bf215546Sopenharmony_ci{ 738bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = drawable->dPriv; 739bf215546Sopenharmony_ci const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader; 740bf215546Sopenharmony_ci const __DRIdri2LoaderExtension *loader = drawable->sPriv->dri2.loader; 741bf215546Sopenharmony_ci const __DRImutableRenderBufferLoaderExtension *shared_buffer_loader = 742bf215546Sopenharmony_ci drawable->sPriv->mutableRenderBuffer.loader; 743bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->st->pipe; 744bf215546Sopenharmony_ci struct pipe_fence_handle *fence = NULL; 745bf215546Sopenharmony_ci int fence_fd = -1; 746bf215546Sopenharmony_ci 747bf215546Sopenharmony_ci /* We need to flush for front buffer rendering when either we're using the 748bf215546Sopenharmony_ci * front buffer at the GL API level, or when EGL_KHR_mutable_render_buffer 749bf215546Sopenharmony_ci * has redirected GL_BACK to the front buffer. 750bf215546Sopenharmony_ci */ 751bf215546Sopenharmony_ci if (statt != ST_ATTACHMENT_FRONT_LEFT && 752bf215546Sopenharmony_ci (!ctx->is_shared_buffer_bound || statt != ST_ATTACHMENT_BACK_LEFT)) 753bf215546Sopenharmony_ci return false; 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci if (drawable->stvis.samples > 1) { 756bf215546Sopenharmony_ci /* Resolve the buffer used for front rendering. */ 757bf215546Sopenharmony_ci dri_pipe_blit(ctx->st->pipe, drawable->textures[statt], 758bf215546Sopenharmony_ci drawable->msaa_textures[statt]); 759bf215546Sopenharmony_ci } 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci if (drawable->textures[statt]) { 762bf215546Sopenharmony_ci pipe->flush_resource(pipe, drawable->textures[statt]); 763bf215546Sopenharmony_ci } 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci if (ctx->is_shared_buffer_bound) { 766bf215546Sopenharmony_ci /* is_shared_buffer_bound should only be true with image extension: */ 767bf215546Sopenharmony_ci assert(image); 768bf215546Sopenharmony_ci pipe->flush(pipe, &fence, PIPE_FLUSH_FENCE_FD); 769bf215546Sopenharmony_ci } else { 770bf215546Sopenharmony_ci pipe->flush(pipe, NULL, 0); 771bf215546Sopenharmony_ci } 772bf215546Sopenharmony_ci 773bf215546Sopenharmony_ci if (image) { 774bf215546Sopenharmony_ci image->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); 775bf215546Sopenharmony_ci if (ctx->is_shared_buffer_bound) { 776bf215546Sopenharmony_ci if (fence) 777bf215546Sopenharmony_ci fence_fd = pipe->screen->fence_get_fd(pipe->screen, fence); 778bf215546Sopenharmony_ci 779bf215546Sopenharmony_ci shared_buffer_loader->displaySharedBuffer(dri_drawable, fence_fd, 780bf215546Sopenharmony_ci dri_drawable->loaderPrivate); 781bf215546Sopenharmony_ci 782bf215546Sopenharmony_ci pipe->screen->fence_reference(pipe->screen, &fence, NULL); 783bf215546Sopenharmony_ci } 784bf215546Sopenharmony_ci } 785bf215546Sopenharmony_ci else if (loader->flushFrontBuffer) { 786bf215546Sopenharmony_ci loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); 787bf215546Sopenharmony_ci } 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci return true; 790bf215546Sopenharmony_ci} 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_ci/** 793bf215546Sopenharmony_ci * The struct dri_drawable flush_swapbuffers callback 794bf215546Sopenharmony_ci */ 795bf215546Sopenharmony_cistatic void 796bf215546Sopenharmony_cidri2_flush_swapbuffers(struct dri_context *ctx, 797bf215546Sopenharmony_ci struct dri_drawable *drawable) 798bf215546Sopenharmony_ci{ 799bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = drawable->dPriv; 800bf215546Sopenharmony_ci const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader; 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci if (image && image->base.version >= 3 && image->flushSwapBuffers) { 803bf215546Sopenharmony_ci image->flushSwapBuffers(dri_drawable, dri_drawable->loaderPrivate); 804bf215546Sopenharmony_ci } 805bf215546Sopenharmony_ci} 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_cistatic void 808bf215546Sopenharmony_cidri2_update_tex_buffer(struct dri_drawable *drawable, 809bf215546Sopenharmony_ci struct dri_context *ctx, 810bf215546Sopenharmony_ci struct pipe_resource *res) 811bf215546Sopenharmony_ci{ 812bf215546Sopenharmony_ci /* no-op */ 813bf215546Sopenharmony_ci} 814bf215546Sopenharmony_ci 815bf215546Sopenharmony_cistatic const struct dri2_format_mapping r8_g8b8_mapping = { 816bf215546Sopenharmony_ci DRM_FORMAT_NV12, 817bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_NONE, 818bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_UV, 819bf215546Sopenharmony_ci PIPE_FORMAT_R8_G8B8_420_UNORM, 820bf215546Sopenharmony_ci 2, 821bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, 822bf215546Sopenharmony_ci { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } 823bf215546Sopenharmony_ci}; 824bf215546Sopenharmony_ci 825bf215546Sopenharmony_cistatic const struct dri2_format_mapping r8g8_r8b8_mapping = { 826bf215546Sopenharmony_ci DRM_FORMAT_YUYV, 827bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_NONE, 828bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_XUXV, 829bf215546Sopenharmony_ci PIPE_FORMAT_R8G8_R8B8_UNORM, 2, 830bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, 831bf215546Sopenharmony_ci { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } 832bf215546Sopenharmony_ci}; 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_cistatic const struct dri2_format_mapping g8r8_b8r8_mapping = { 835bf215546Sopenharmony_ci DRM_FORMAT_UYVY, 836bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_NONE, 837bf215546Sopenharmony_ci __DRI_IMAGE_COMPONENTS_Y_XUXV, 838bf215546Sopenharmony_ci PIPE_FORMAT_G8R8_B8R8_UNORM, 2, 839bf215546Sopenharmony_ci { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, 840bf215546Sopenharmony_ci { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } 841bf215546Sopenharmony_ci}; 842bf215546Sopenharmony_ci 843bf215546Sopenharmony_cistatic __DRIimage * 844bf215546Sopenharmony_cidri2_create_image_from_winsys(__DRIscreen *_screen, 845bf215546Sopenharmony_ci int width, int height, const struct dri2_format_mapping *map, 846bf215546Sopenharmony_ci int num_handles, struct winsys_handle *whandle, 847bf215546Sopenharmony_ci unsigned bind, 848bf215546Sopenharmony_ci void *loaderPrivate) 849bf215546Sopenharmony_ci{ 850bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(_screen); 851bf215546Sopenharmony_ci struct pipe_screen *pscreen = screen->base.screen; 852bf215546Sopenharmony_ci __DRIimage *img; 853bf215546Sopenharmony_ci struct pipe_resource templ; 854bf215546Sopenharmony_ci unsigned tex_usage = 0; 855bf215546Sopenharmony_ci int i; 856bf215546Sopenharmony_ci bool use_lowered = false; 857bf215546Sopenharmony_ci const unsigned format_planes = util_format_get_num_planes(map->pipe_format); 858bf215546Sopenharmony_ci 859bf215546Sopenharmony_ci if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, 860bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET)) 861bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_RENDER_TARGET; 862bf215546Sopenharmony_ci if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, 863bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW)) 864bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_SAMPLER_VIEW; 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci /* For NV12, see if we have support for sampling r8_b8g8 */ 867bf215546Sopenharmony_ci if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV12 && 868bf215546Sopenharmony_ci pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8B8_420_UNORM, 869bf215546Sopenharmony_ci screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { 870bf215546Sopenharmony_ci map = &r8_g8b8_mapping; 871bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_SAMPLER_VIEW; 872bf215546Sopenharmony_ci } 873bf215546Sopenharmony_ci 874bf215546Sopenharmony_ci /* If the hardware supports R8G8_R8B8 style subsampled RGB formats, these 875bf215546Sopenharmony_ci * can be used for YUYV and UYVY formats. 876bf215546Sopenharmony_ci */ 877bf215546Sopenharmony_ci if (!tex_usage && map->pipe_format == PIPE_FORMAT_YUYV && 878bf215546Sopenharmony_ci pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8G8_R8B8_UNORM, 879bf215546Sopenharmony_ci screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { 880bf215546Sopenharmony_ci map = &r8g8_r8b8_mapping; 881bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_SAMPLER_VIEW; 882bf215546Sopenharmony_ci } 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_ci if (!tex_usage && map->pipe_format == PIPE_FORMAT_UYVY && 885bf215546Sopenharmony_ci pscreen->is_format_supported(pscreen, PIPE_FORMAT_G8R8_B8R8_UNORM, 886bf215546Sopenharmony_ci screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { 887bf215546Sopenharmony_ci map = &g8r8_b8r8_mapping; 888bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_SAMPLER_VIEW; 889bf215546Sopenharmony_ci } 890bf215546Sopenharmony_ci 891bf215546Sopenharmony_ci if (!tex_usage && util_format_is_yuv(map->pipe_format)) { 892bf215546Sopenharmony_ci /* YUV format sampling can be emulated by the GL gallium frontend by 893bf215546Sopenharmony_ci * using multiple samplers of varying formats. 894bf215546Sopenharmony_ci * If no tex_usage is set and we detect a YUV format, 895bf215546Sopenharmony_ci * test for support of all planes' sampler formats and 896bf215546Sopenharmony_ci * add sampler view usage. 897bf215546Sopenharmony_ci */ 898bf215546Sopenharmony_ci use_lowered = true; 899bf215546Sopenharmony_ci if (dri2_yuv_dma_buf_supported(screen, map)) 900bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_SAMPLER_VIEW; 901bf215546Sopenharmony_ci } 902bf215546Sopenharmony_ci 903bf215546Sopenharmony_ci if (!tex_usage) 904bf215546Sopenharmony_ci return NULL; 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_ci img = CALLOC_STRUCT(__DRIimageRec); 907bf215546Sopenharmony_ci if (!img) 908bf215546Sopenharmony_ci return NULL; 909bf215546Sopenharmony_ci 910bf215546Sopenharmony_ci memset(&templ, 0, sizeof(templ)); 911bf215546Sopenharmony_ci templ.bind = tex_usage | bind; 912bf215546Sopenharmony_ci templ.target = screen->target; 913bf215546Sopenharmony_ci templ.last_level = 0; 914bf215546Sopenharmony_ci templ.depth0 = 1; 915bf215546Sopenharmony_ci templ.array_size = 1; 916bf215546Sopenharmony_ci templ.width0 = width; 917bf215546Sopenharmony_ci templ.height0 = height; 918bf215546Sopenharmony_ci 919bf215546Sopenharmony_ci for (i = num_handles - 1; i >= format_planes; i--) { 920bf215546Sopenharmony_ci struct pipe_resource *tex; 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci templ.next = img->texture; 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci tex = pscreen->resource_from_handle(pscreen, &templ, &whandle[i], 925bf215546Sopenharmony_ci PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); 926bf215546Sopenharmony_ci if (!tex) { 927bf215546Sopenharmony_ci pipe_resource_reference(&img->texture, NULL); 928bf215546Sopenharmony_ci FREE(img); 929bf215546Sopenharmony_ci return NULL; 930bf215546Sopenharmony_ci } 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci img->texture = tex; 933bf215546Sopenharmony_ci } 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci for (i = (use_lowered ? map->nplanes : format_planes) - 1; i >= 0; i--) { 936bf215546Sopenharmony_ci struct pipe_resource *tex; 937bf215546Sopenharmony_ci 938bf215546Sopenharmony_ci templ.next = img->texture; 939bf215546Sopenharmony_ci templ.width0 = width >> map->planes[i].width_shift; 940bf215546Sopenharmony_ci templ.height0 = height >> map->planes[i].height_shift; 941bf215546Sopenharmony_ci if (use_lowered) 942bf215546Sopenharmony_ci templ.format = dri2_get_pipe_format_for_dri_format(map->planes[i].dri_format); 943bf215546Sopenharmony_ci else 944bf215546Sopenharmony_ci templ.format = map->pipe_format; 945bf215546Sopenharmony_ci assert(templ.format != PIPE_FORMAT_NONE); 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci tex = pscreen->resource_from_handle(pscreen, 948bf215546Sopenharmony_ci &templ, &whandle[use_lowered ? map->planes[i].buffer_index : i], 949bf215546Sopenharmony_ci PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); 950bf215546Sopenharmony_ci if (!tex) { 951bf215546Sopenharmony_ci pipe_resource_reference(&img->texture, NULL); 952bf215546Sopenharmony_ci FREE(img); 953bf215546Sopenharmony_ci return NULL; 954bf215546Sopenharmony_ci } 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci /* Reject image creation if there's an inconsistency between 957bf215546Sopenharmony_ci * content protection status of tex and img. 958bf215546Sopenharmony_ci */ 959bf215546Sopenharmony_ci const struct driOptionCache *optionCache = &screen->dev->option_cache; 960bf215546Sopenharmony_ci if (!driQueryOptionb(optionCache, "disable_protected_content_check") && 961bf215546Sopenharmony_ci (tex->bind & PIPE_BIND_PROTECTED) != (bind & PIPE_BIND_PROTECTED)) { 962bf215546Sopenharmony_ci pipe_resource_reference(&img->texture, NULL); 963bf215546Sopenharmony_ci pipe_resource_reference(&tex, NULL); 964bf215546Sopenharmony_ci FREE(img); 965bf215546Sopenharmony_ci return NULL; 966bf215546Sopenharmony_ci } 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_ci img->texture = tex; 969bf215546Sopenharmony_ci } 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ci img->level = 0; 972bf215546Sopenharmony_ci img->layer = 0; 973bf215546Sopenharmony_ci img->use = 0; 974bf215546Sopenharmony_ci img->in_fence_fd = -1; 975bf215546Sopenharmony_ci img->loader_private = loaderPrivate; 976bf215546Sopenharmony_ci img->sPriv = _screen; 977bf215546Sopenharmony_ci 978bf215546Sopenharmony_ci return img; 979bf215546Sopenharmony_ci} 980bf215546Sopenharmony_ci 981bf215546Sopenharmony_cistatic __DRIimage * 982bf215546Sopenharmony_cidri2_create_image_from_name(__DRIscreen *_screen, 983bf215546Sopenharmony_ci int width, int height, int format, 984bf215546Sopenharmony_ci int name, int pitch, void *loaderPrivate) 985bf215546Sopenharmony_ci{ 986bf215546Sopenharmony_ci const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format); 987bf215546Sopenharmony_ci struct winsys_handle whandle; 988bf215546Sopenharmony_ci __DRIimage *img; 989bf215546Sopenharmony_ci 990bf215546Sopenharmony_ci if (!map) 991bf215546Sopenharmony_ci return NULL; 992bf215546Sopenharmony_ci 993bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 994bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_SHARED; 995bf215546Sopenharmony_ci whandle.handle = name; 996bf215546Sopenharmony_ci whandle.format = map->pipe_format; 997bf215546Sopenharmony_ci whandle.modifier = DRM_FORMAT_MOD_INVALID; 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_ci whandle.stride = pitch * util_format_get_blocksize(map->pipe_format); 1000bf215546Sopenharmony_ci 1001bf215546Sopenharmony_ci img = dri2_create_image_from_winsys(_screen, width, height, map, 1002bf215546Sopenharmony_ci 1, &whandle, 0, loaderPrivate); 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci if (!img) 1005bf215546Sopenharmony_ci return NULL; 1006bf215546Sopenharmony_ci 1007bf215546Sopenharmony_ci img->dri_components = map->dri_components; 1008bf215546Sopenharmony_ci img->dri_fourcc = map->dri_fourcc; 1009bf215546Sopenharmony_ci img->dri_format = map->dri_format; 1010bf215546Sopenharmony_ci 1011bf215546Sopenharmony_ci return img; 1012bf215546Sopenharmony_ci} 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_cistatic unsigned 1015bf215546Sopenharmony_cidri2_get_modifier_num_planes(__DRIscreen *_screen, 1016bf215546Sopenharmony_ci uint64_t modifier, int fourcc) 1017bf215546Sopenharmony_ci{ 1018bf215546Sopenharmony_ci struct pipe_screen *pscreen = dri_screen(_screen)->base.screen; 1019bf215546Sopenharmony_ci const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc); 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci if (!map) 1022bf215546Sopenharmony_ci return 0; 1023bf215546Sopenharmony_ci 1024bf215546Sopenharmony_ci switch (modifier) { 1025bf215546Sopenharmony_ci case DRM_FORMAT_MOD_LINEAR: 1026bf215546Sopenharmony_ci /* DRM_FORMAT_MOD_NONE is the same as LINEAR */ 1027bf215546Sopenharmony_ci case DRM_FORMAT_MOD_INVALID: 1028bf215546Sopenharmony_ci return util_format_get_num_planes(map->pipe_format); 1029bf215546Sopenharmony_ci default: 1030bf215546Sopenharmony_ci if (!pscreen->is_dmabuf_modifier_supported || 1031bf215546Sopenharmony_ci !pscreen->is_dmabuf_modifier_supported(pscreen, modifier, 1032bf215546Sopenharmony_ci map->pipe_format, NULL)) { 1033bf215546Sopenharmony_ci return 0; 1034bf215546Sopenharmony_ci } 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci if (pscreen->get_dmabuf_modifier_planes) { 1037bf215546Sopenharmony_ci return pscreen->get_dmabuf_modifier_planes(pscreen, modifier, 1038bf215546Sopenharmony_ci map->pipe_format); 1039bf215546Sopenharmony_ci } 1040bf215546Sopenharmony_ci 1041bf215546Sopenharmony_ci return map->nplanes; 1042bf215546Sopenharmony_ci } 1043bf215546Sopenharmony_ci} 1044bf215546Sopenharmony_ci 1045bf215546Sopenharmony_cistatic __DRIimage * 1046bf215546Sopenharmony_cidri2_create_image_from_fd(__DRIscreen *_screen, 1047bf215546Sopenharmony_ci int width, int height, int fourcc, 1048bf215546Sopenharmony_ci uint64_t modifier, int *fds, int num_fds, 1049bf215546Sopenharmony_ci int *strides, int *offsets, 1050bf215546Sopenharmony_ci unsigned bind, unsigned *error, void *loaderPrivate) 1051bf215546Sopenharmony_ci{ 1052bf215546Sopenharmony_ci struct winsys_handle whandles[4]; 1053bf215546Sopenharmony_ci const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc); 1054bf215546Sopenharmony_ci __DRIimage *img = NULL; 1055bf215546Sopenharmony_ci unsigned err = __DRI_IMAGE_ERROR_SUCCESS; 1056bf215546Sopenharmony_ci int i; 1057bf215546Sopenharmony_ci const int expected_num_fds = dri2_get_modifier_num_planes(_screen, modifier, fourcc); 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci if (!map || expected_num_fds == 0) { 1060bf215546Sopenharmony_ci err = __DRI_IMAGE_ERROR_BAD_MATCH; 1061bf215546Sopenharmony_ci goto exit; 1062bf215546Sopenharmony_ci } 1063bf215546Sopenharmony_ci 1064bf215546Sopenharmony_ci if (num_fds != expected_num_fds) { 1065bf215546Sopenharmony_ci err = __DRI_IMAGE_ERROR_BAD_MATCH; 1066bf215546Sopenharmony_ci goto exit; 1067bf215546Sopenharmony_ci } 1068bf215546Sopenharmony_ci 1069bf215546Sopenharmony_ci memset(whandles, 0, sizeof(whandles)); 1070bf215546Sopenharmony_ci 1071bf215546Sopenharmony_ci for (i = 0; i < num_fds; i++) { 1072bf215546Sopenharmony_ci if (fds[i] < 0) { 1073bf215546Sopenharmony_ci err = __DRI_IMAGE_ERROR_BAD_ALLOC; 1074bf215546Sopenharmony_ci goto exit; 1075bf215546Sopenharmony_ci } 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_ci whandles[i].type = WINSYS_HANDLE_TYPE_FD; 1078bf215546Sopenharmony_ci whandles[i].handle = (unsigned)fds[i]; 1079bf215546Sopenharmony_ci whandles[i].stride = (unsigned)strides[i]; 1080bf215546Sopenharmony_ci whandles[i].offset = (unsigned)offsets[i]; 1081bf215546Sopenharmony_ci whandles[i].format = map->pipe_format; 1082bf215546Sopenharmony_ci whandles[i].modifier = modifier; 1083bf215546Sopenharmony_ci whandles[i].plane = i; 1084bf215546Sopenharmony_ci } 1085bf215546Sopenharmony_ci 1086bf215546Sopenharmony_ci img = dri2_create_image_from_winsys(_screen, width, height, map, 1087bf215546Sopenharmony_ci num_fds, whandles, bind, 1088bf215546Sopenharmony_ci loaderPrivate); 1089bf215546Sopenharmony_ci if(img == NULL) { 1090bf215546Sopenharmony_ci err = __DRI_IMAGE_ERROR_BAD_ALLOC; 1091bf215546Sopenharmony_ci goto exit; 1092bf215546Sopenharmony_ci } 1093bf215546Sopenharmony_ci 1094bf215546Sopenharmony_ci img->dri_components = map->dri_components; 1095bf215546Sopenharmony_ci img->dri_fourcc = fourcc; 1096bf215546Sopenharmony_ci img->dri_format = map->dri_format; 1097bf215546Sopenharmony_ci img->imported_dmabuf = TRUE; 1098bf215546Sopenharmony_ci 1099bf215546Sopenharmony_ciexit: 1100bf215546Sopenharmony_ci if (error) 1101bf215546Sopenharmony_ci *error = err; 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci return img; 1104bf215546Sopenharmony_ci} 1105bf215546Sopenharmony_ci 1106bf215546Sopenharmony_cistatic __DRIimage * 1107bf215546Sopenharmony_cidri2_create_image_common(__DRIscreen *_screen, 1108bf215546Sopenharmony_ci int width, int height, 1109bf215546Sopenharmony_ci int format, unsigned int use, 1110bf215546Sopenharmony_ci const uint64_t *modifiers, 1111bf215546Sopenharmony_ci const unsigned count, 1112bf215546Sopenharmony_ci void *loaderPrivate) 1113bf215546Sopenharmony_ci{ 1114bf215546Sopenharmony_ci const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format); 1115bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(_screen); 1116bf215546Sopenharmony_ci struct pipe_screen *pscreen = screen->base.screen; 1117bf215546Sopenharmony_ci __DRIimage *img; 1118bf215546Sopenharmony_ci struct pipe_resource templ; 1119bf215546Sopenharmony_ci unsigned tex_usage = 0; 1120bf215546Sopenharmony_ci 1121bf215546Sopenharmony_ci if (!map) 1122bf215546Sopenharmony_ci return NULL; 1123bf215546Sopenharmony_ci 1124bf215546Sopenharmony_ci if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 1125bf215546Sopenharmony_ci 0, 0, PIPE_BIND_RENDER_TARGET)) 1126bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_RENDER_TARGET; 1127bf215546Sopenharmony_ci if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 1128bf215546Sopenharmony_ci 0, 0, PIPE_BIND_SAMPLER_VIEW)) 1129bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_SAMPLER_VIEW; 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_ci if (!tex_usage) 1132bf215546Sopenharmony_ci return NULL; 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_SCANOUT) 1135bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_SCANOUT; 1136bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_SHARE) 1137bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_SHARED; 1138bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_LINEAR) 1139bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_LINEAR; 1140bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_CURSOR) { 1141bf215546Sopenharmony_ci if (width != 64 || height != 64) 1142bf215546Sopenharmony_ci return NULL; 1143bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_CURSOR; 1144bf215546Sopenharmony_ci } 1145bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_PROTECTED) 1146bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_PROTECTED; 1147bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_PRIME_BUFFER) 1148bf215546Sopenharmony_ci tex_usage |= PIPE_BIND_PRIME_BLIT_DST; 1149bf215546Sopenharmony_ci 1150bf215546Sopenharmony_ci img = CALLOC_STRUCT(__DRIimageRec); 1151bf215546Sopenharmony_ci if (!img) 1152bf215546Sopenharmony_ci return NULL; 1153bf215546Sopenharmony_ci 1154bf215546Sopenharmony_ci memset(&templ, 0, sizeof(templ)); 1155bf215546Sopenharmony_ci templ.bind = tex_usage; 1156bf215546Sopenharmony_ci templ.format = map->pipe_format; 1157bf215546Sopenharmony_ci templ.target = PIPE_TEXTURE_2D; 1158bf215546Sopenharmony_ci templ.last_level = 0; 1159bf215546Sopenharmony_ci templ.width0 = width; 1160bf215546Sopenharmony_ci templ.height0 = height; 1161bf215546Sopenharmony_ci templ.depth0 = 1; 1162bf215546Sopenharmony_ci templ.array_size = 1; 1163bf215546Sopenharmony_ci 1164bf215546Sopenharmony_ci if (modifiers) 1165bf215546Sopenharmony_ci img->texture = 1166bf215546Sopenharmony_ci screen->base.screen 1167bf215546Sopenharmony_ci ->resource_create_with_modifiers(screen->base.screen, 1168bf215546Sopenharmony_ci &templ, 1169bf215546Sopenharmony_ci modifiers, 1170bf215546Sopenharmony_ci count); 1171bf215546Sopenharmony_ci else 1172bf215546Sopenharmony_ci img->texture = 1173bf215546Sopenharmony_ci screen->base.screen->resource_create(screen->base.screen, &templ); 1174bf215546Sopenharmony_ci if (!img->texture) { 1175bf215546Sopenharmony_ci FREE(img); 1176bf215546Sopenharmony_ci return NULL; 1177bf215546Sopenharmony_ci } 1178bf215546Sopenharmony_ci 1179bf215546Sopenharmony_ci img->level = 0; 1180bf215546Sopenharmony_ci img->layer = 0; 1181bf215546Sopenharmony_ci img->dri_format = format; 1182bf215546Sopenharmony_ci img->dri_fourcc = map->dri_fourcc; 1183bf215546Sopenharmony_ci img->dri_components = 0; 1184bf215546Sopenharmony_ci img->use = use; 1185bf215546Sopenharmony_ci img->in_fence_fd = -1; 1186bf215546Sopenharmony_ci 1187bf215546Sopenharmony_ci img->loader_private = loaderPrivate; 1188bf215546Sopenharmony_ci img->sPriv = _screen; 1189bf215546Sopenharmony_ci return img; 1190bf215546Sopenharmony_ci} 1191bf215546Sopenharmony_ci 1192bf215546Sopenharmony_cistatic __DRIimage * 1193bf215546Sopenharmony_cidri2_create_image(__DRIscreen *_screen, 1194bf215546Sopenharmony_ci int width, int height, int format, 1195bf215546Sopenharmony_ci unsigned int use, void *loaderPrivate) 1196bf215546Sopenharmony_ci{ 1197bf215546Sopenharmony_ci return dri2_create_image_common(_screen, width, height, format, use, 1198bf215546Sopenharmony_ci NULL /* modifiers */, 0 /* count */, 1199bf215546Sopenharmony_ci loaderPrivate); 1200bf215546Sopenharmony_ci} 1201bf215546Sopenharmony_ci 1202bf215546Sopenharmony_cistatic __DRIimage * 1203bf215546Sopenharmony_cidri2_create_image_with_modifiers(__DRIscreen *dri_screen, 1204bf215546Sopenharmony_ci int width, int height, int format, 1205bf215546Sopenharmony_ci const uint64_t *modifiers, 1206bf215546Sopenharmony_ci const unsigned count, 1207bf215546Sopenharmony_ci void *loaderPrivate) 1208bf215546Sopenharmony_ci{ 1209bf215546Sopenharmony_ci return dri2_create_image_common(dri_screen, width, height, format, 1210bf215546Sopenharmony_ci __DRI_IMAGE_USE_SHARE, modifiers, count, 1211bf215546Sopenharmony_ci loaderPrivate); 1212bf215546Sopenharmony_ci} 1213bf215546Sopenharmony_ci 1214bf215546Sopenharmony_cistatic __DRIimage * 1215bf215546Sopenharmony_cidri2_create_image_with_modifiers2(__DRIscreen *dri_screen, 1216bf215546Sopenharmony_ci int width, int height, int format, 1217bf215546Sopenharmony_ci const uint64_t *modifiers, 1218bf215546Sopenharmony_ci const unsigned count, unsigned int use, 1219bf215546Sopenharmony_ci void *loaderPrivate) 1220bf215546Sopenharmony_ci{ 1221bf215546Sopenharmony_ci return dri2_create_image_common(dri_screen, width, height, format, use, 1222bf215546Sopenharmony_ci modifiers, count, loaderPrivate); 1223bf215546Sopenharmony_ci} 1224bf215546Sopenharmony_ci 1225bf215546Sopenharmony_cistatic bool 1226bf215546Sopenharmony_cidri2_query_image_common(__DRIimage *image, int attrib, int *value) 1227bf215546Sopenharmony_ci{ 1228bf215546Sopenharmony_ci switch (attrib) { 1229bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_FORMAT: 1230bf215546Sopenharmony_ci *value = image->dri_format; 1231bf215546Sopenharmony_ci return true; 1232bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_WIDTH: 1233bf215546Sopenharmony_ci *value = image->texture->width0; 1234bf215546Sopenharmony_ci return true; 1235bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_HEIGHT: 1236bf215546Sopenharmony_ci *value = image->texture->height0; 1237bf215546Sopenharmony_ci return true; 1238bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_COMPONENTS: 1239bf215546Sopenharmony_ci if (image->dri_components == 0) 1240bf215546Sopenharmony_ci return false; 1241bf215546Sopenharmony_ci *value = image->dri_components; 1242bf215546Sopenharmony_ci return true; 1243bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_FOURCC: 1244bf215546Sopenharmony_ci if (image->dri_fourcc) { 1245bf215546Sopenharmony_ci *value = image->dri_fourcc; 1246bf215546Sopenharmony_ci } else { 1247bf215546Sopenharmony_ci const struct dri2_format_mapping *map; 1248bf215546Sopenharmony_ci 1249bf215546Sopenharmony_ci map = dri2_get_mapping_by_format(image->dri_format); 1250bf215546Sopenharmony_ci if (!map) 1251bf215546Sopenharmony_ci return false; 1252bf215546Sopenharmony_ci 1253bf215546Sopenharmony_ci *value = map->dri_fourcc; 1254bf215546Sopenharmony_ci } 1255bf215546Sopenharmony_ci return true; 1256bf215546Sopenharmony_ci default: 1257bf215546Sopenharmony_ci return false; 1258bf215546Sopenharmony_ci } 1259bf215546Sopenharmony_ci} 1260bf215546Sopenharmony_ci 1261bf215546Sopenharmony_cistatic bool 1262bf215546Sopenharmony_cidri2_query_image_by_resource_handle(__DRIimage *image, int attrib, int *value) 1263bf215546Sopenharmony_ci{ 1264bf215546Sopenharmony_ci struct pipe_screen *pscreen = image->texture->screen; 1265bf215546Sopenharmony_ci struct winsys_handle whandle; 1266bf215546Sopenharmony_ci struct pipe_resource *tex; 1267bf215546Sopenharmony_ci unsigned usage; 1268bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 1269bf215546Sopenharmony_ci whandle.plane = image->plane; 1270bf215546Sopenharmony_ci int i; 1271bf215546Sopenharmony_ci 1272bf215546Sopenharmony_ci switch (attrib) { 1273bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_STRIDE: 1274bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_OFFSET: 1275bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_HANDLE: 1276bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_KMS; 1277bf215546Sopenharmony_ci break; 1278bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_NAME: 1279bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_SHARED; 1280bf215546Sopenharmony_ci break; 1281bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_FD: 1282bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_FD; 1283bf215546Sopenharmony_ci break; 1284bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_NUM_PLANES: 1285bf215546Sopenharmony_ci for (i = 0, tex = image->texture; tex; tex = tex->next) 1286bf215546Sopenharmony_ci i++; 1287bf215546Sopenharmony_ci *value = i; 1288bf215546Sopenharmony_ci return true; 1289bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER: 1290bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER: 1291bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_KMS; 1292bf215546Sopenharmony_ci whandle.modifier = DRM_FORMAT_MOD_INVALID; 1293bf215546Sopenharmony_ci break; 1294bf215546Sopenharmony_ci default: 1295bf215546Sopenharmony_ci return false; 1296bf215546Sopenharmony_ci } 1297bf215546Sopenharmony_ci 1298bf215546Sopenharmony_ci usage = PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE; 1299bf215546Sopenharmony_ci 1300bf215546Sopenharmony_ci if (image->use & __DRI_IMAGE_USE_BACKBUFFER) 1301bf215546Sopenharmony_ci usage |= PIPE_HANDLE_USAGE_EXPLICIT_FLUSH; 1302bf215546Sopenharmony_ci 1303bf215546Sopenharmony_ci if (!pscreen->resource_get_handle(pscreen, NULL, image->texture, 1304bf215546Sopenharmony_ci &whandle, usage)) 1305bf215546Sopenharmony_ci return false; 1306bf215546Sopenharmony_ci 1307bf215546Sopenharmony_ci switch (attrib) { 1308bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_STRIDE: 1309bf215546Sopenharmony_ci *value = whandle.stride; 1310bf215546Sopenharmony_ci return true; 1311bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_OFFSET: 1312bf215546Sopenharmony_ci *value = whandle.offset; 1313bf215546Sopenharmony_ci return true; 1314bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_HANDLE: 1315bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_NAME: 1316bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_FD: 1317bf215546Sopenharmony_ci *value = whandle.handle; 1318bf215546Sopenharmony_ci return true; 1319bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER: 1320bf215546Sopenharmony_ci if (whandle.modifier == DRM_FORMAT_MOD_INVALID) 1321bf215546Sopenharmony_ci return false; 1322bf215546Sopenharmony_ci *value = (whandle.modifier >> 32) & 0xffffffff; 1323bf215546Sopenharmony_ci return true; 1324bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER: 1325bf215546Sopenharmony_ci if (whandle.modifier == DRM_FORMAT_MOD_INVALID) 1326bf215546Sopenharmony_ci return false; 1327bf215546Sopenharmony_ci *value = whandle.modifier & 0xffffffff; 1328bf215546Sopenharmony_ci return true; 1329bf215546Sopenharmony_ci default: 1330bf215546Sopenharmony_ci return false; 1331bf215546Sopenharmony_ci } 1332bf215546Sopenharmony_ci} 1333bf215546Sopenharmony_ci 1334bf215546Sopenharmony_cistatic bool 1335bf215546Sopenharmony_cidri2_resource_get_param(__DRIimage *image, enum pipe_resource_param param, 1336bf215546Sopenharmony_ci unsigned handle_usage, uint64_t *value) 1337bf215546Sopenharmony_ci{ 1338bf215546Sopenharmony_ci struct pipe_screen *pscreen = image->texture->screen; 1339bf215546Sopenharmony_ci if (!pscreen->resource_get_param) 1340bf215546Sopenharmony_ci return false; 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci if (image->use & __DRI_IMAGE_USE_BACKBUFFER) 1343bf215546Sopenharmony_ci handle_usage |= PIPE_HANDLE_USAGE_EXPLICIT_FLUSH; 1344bf215546Sopenharmony_ci 1345bf215546Sopenharmony_ci return pscreen->resource_get_param(pscreen, NULL, image->texture, 1346bf215546Sopenharmony_ci image->plane, 0, 0, param, handle_usage, 1347bf215546Sopenharmony_ci value); 1348bf215546Sopenharmony_ci} 1349bf215546Sopenharmony_ci 1350bf215546Sopenharmony_cistatic bool 1351bf215546Sopenharmony_cidri2_query_image_by_resource_param(__DRIimage *image, int attrib, int *value) 1352bf215546Sopenharmony_ci{ 1353bf215546Sopenharmony_ci enum pipe_resource_param param; 1354bf215546Sopenharmony_ci uint64_t res_param; 1355bf215546Sopenharmony_ci unsigned handle_usage; 1356bf215546Sopenharmony_ci 1357bf215546Sopenharmony_ci if (!image->texture->screen->resource_get_param) 1358bf215546Sopenharmony_ci return false; 1359bf215546Sopenharmony_ci 1360bf215546Sopenharmony_ci switch (attrib) { 1361bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_STRIDE: 1362bf215546Sopenharmony_ci param = PIPE_RESOURCE_PARAM_STRIDE; 1363bf215546Sopenharmony_ci break; 1364bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_OFFSET: 1365bf215546Sopenharmony_ci param = PIPE_RESOURCE_PARAM_OFFSET; 1366bf215546Sopenharmony_ci break; 1367bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_NUM_PLANES: 1368bf215546Sopenharmony_ci param = PIPE_RESOURCE_PARAM_NPLANES; 1369bf215546Sopenharmony_ci break; 1370bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER: 1371bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER: 1372bf215546Sopenharmony_ci param = PIPE_RESOURCE_PARAM_MODIFIER; 1373bf215546Sopenharmony_ci break; 1374bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_HANDLE: 1375bf215546Sopenharmony_ci param = PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS; 1376bf215546Sopenharmony_ci break; 1377bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_NAME: 1378bf215546Sopenharmony_ci param = PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED; 1379bf215546Sopenharmony_ci break; 1380bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_FD: 1381bf215546Sopenharmony_ci param = PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD; 1382bf215546Sopenharmony_ci break; 1383bf215546Sopenharmony_ci default: 1384bf215546Sopenharmony_ci return false; 1385bf215546Sopenharmony_ci } 1386bf215546Sopenharmony_ci 1387bf215546Sopenharmony_ci handle_usage = PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE; 1388bf215546Sopenharmony_ci 1389bf215546Sopenharmony_ci if (!dri2_resource_get_param(image, param, handle_usage, &res_param)) 1390bf215546Sopenharmony_ci return false; 1391bf215546Sopenharmony_ci 1392bf215546Sopenharmony_ci switch (attrib) { 1393bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_STRIDE: 1394bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_OFFSET: 1395bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_NUM_PLANES: 1396bf215546Sopenharmony_ci if (res_param > INT_MAX) 1397bf215546Sopenharmony_ci return false; 1398bf215546Sopenharmony_ci *value = (int)res_param; 1399bf215546Sopenharmony_ci return true; 1400bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_HANDLE: 1401bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_NAME: 1402bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_FD: 1403bf215546Sopenharmony_ci if (res_param > UINT_MAX) 1404bf215546Sopenharmony_ci return false; 1405bf215546Sopenharmony_ci *value = (int)res_param; 1406bf215546Sopenharmony_ci return true; 1407bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER: 1408bf215546Sopenharmony_ci if (res_param == DRM_FORMAT_MOD_INVALID) 1409bf215546Sopenharmony_ci return false; 1410bf215546Sopenharmony_ci *value = (res_param >> 32) & 0xffffffff; 1411bf215546Sopenharmony_ci return true; 1412bf215546Sopenharmony_ci case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER: 1413bf215546Sopenharmony_ci if (res_param == DRM_FORMAT_MOD_INVALID) 1414bf215546Sopenharmony_ci return false; 1415bf215546Sopenharmony_ci *value = res_param & 0xffffffff; 1416bf215546Sopenharmony_ci return true; 1417bf215546Sopenharmony_ci default: 1418bf215546Sopenharmony_ci return false; 1419bf215546Sopenharmony_ci } 1420bf215546Sopenharmony_ci} 1421bf215546Sopenharmony_ci 1422bf215546Sopenharmony_cistatic GLboolean 1423bf215546Sopenharmony_cidri2_query_image(__DRIimage *image, int attrib, int *value) 1424bf215546Sopenharmony_ci{ 1425bf215546Sopenharmony_ci if (dri2_query_image_common(image, attrib, value)) 1426bf215546Sopenharmony_ci return GL_TRUE; 1427bf215546Sopenharmony_ci else if (dri2_query_image_by_resource_param(image, attrib, value)) 1428bf215546Sopenharmony_ci return GL_TRUE; 1429bf215546Sopenharmony_ci else if (dri2_query_image_by_resource_handle(image, attrib, value)) 1430bf215546Sopenharmony_ci return GL_TRUE; 1431bf215546Sopenharmony_ci else 1432bf215546Sopenharmony_ci return GL_FALSE; 1433bf215546Sopenharmony_ci} 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_cistatic __DRIimage * 1436bf215546Sopenharmony_cidri2_dup_image(__DRIimage *image, void *loaderPrivate) 1437bf215546Sopenharmony_ci{ 1438bf215546Sopenharmony_ci __DRIimage *img; 1439bf215546Sopenharmony_ci 1440bf215546Sopenharmony_ci img = CALLOC_STRUCT(__DRIimageRec); 1441bf215546Sopenharmony_ci if (!img) 1442bf215546Sopenharmony_ci return NULL; 1443bf215546Sopenharmony_ci 1444bf215546Sopenharmony_ci img->texture = NULL; 1445bf215546Sopenharmony_ci pipe_resource_reference(&img->texture, image->texture); 1446bf215546Sopenharmony_ci img->level = image->level; 1447bf215546Sopenharmony_ci img->layer = image->layer; 1448bf215546Sopenharmony_ci img->dri_format = image->dri_format; 1449bf215546Sopenharmony_ci img->internal_format = image->internal_format; 1450bf215546Sopenharmony_ci /* This should be 0 for sub images, but dup is also used for base images. */ 1451bf215546Sopenharmony_ci img->dri_components = image->dri_components; 1452bf215546Sopenharmony_ci img->use = image->use; 1453bf215546Sopenharmony_ci img->in_fence_fd = (image->in_fence_fd > 0) ? 1454bf215546Sopenharmony_ci os_dupfd_cloexec(image->in_fence_fd) : -1; 1455bf215546Sopenharmony_ci img->loader_private = loaderPrivate; 1456bf215546Sopenharmony_ci img->sPriv = image->sPriv; 1457bf215546Sopenharmony_ci 1458bf215546Sopenharmony_ci return img; 1459bf215546Sopenharmony_ci} 1460bf215546Sopenharmony_ci 1461bf215546Sopenharmony_cistatic GLboolean 1462bf215546Sopenharmony_cidri2_validate_usage(__DRIimage *image, unsigned int use) 1463bf215546Sopenharmony_ci{ 1464bf215546Sopenharmony_ci if (!image || !image->texture) 1465bf215546Sopenharmony_ci return false; 1466bf215546Sopenharmony_ci 1467bf215546Sopenharmony_ci struct pipe_screen *screen = image->texture->screen; 1468bf215546Sopenharmony_ci if (!screen->check_resource_capability) 1469bf215546Sopenharmony_ci return true; 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_ci /* We don't want to check these: 1472bf215546Sopenharmony_ci * __DRI_IMAGE_USE_SHARE (all images are shareable) 1473bf215546Sopenharmony_ci * __DRI_IMAGE_USE_BACKBUFFER (all images support this) 1474bf215546Sopenharmony_ci */ 1475bf215546Sopenharmony_ci unsigned bind = 0; 1476bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_SCANOUT) 1477bf215546Sopenharmony_ci bind |= PIPE_BIND_SCANOUT; 1478bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_LINEAR) 1479bf215546Sopenharmony_ci bind |= PIPE_BIND_LINEAR; 1480bf215546Sopenharmony_ci if (use & __DRI_IMAGE_USE_CURSOR) 1481bf215546Sopenharmony_ci bind |= PIPE_BIND_CURSOR; 1482bf215546Sopenharmony_ci 1483bf215546Sopenharmony_ci if (!bind) 1484bf215546Sopenharmony_ci return true; 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci return screen->check_resource_capability(screen, image->texture, bind); 1487bf215546Sopenharmony_ci} 1488bf215546Sopenharmony_ci 1489bf215546Sopenharmony_cistatic __DRIimage * 1490bf215546Sopenharmony_cidri2_from_names(__DRIscreen *screen, int width, int height, int format, 1491bf215546Sopenharmony_ci int *names, int num_names, int *strides, int *offsets, 1492bf215546Sopenharmony_ci void *loaderPrivate) 1493bf215546Sopenharmony_ci{ 1494bf215546Sopenharmony_ci const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format); 1495bf215546Sopenharmony_ci __DRIimage *img; 1496bf215546Sopenharmony_ci struct winsys_handle whandle; 1497bf215546Sopenharmony_ci 1498bf215546Sopenharmony_ci if (!map) 1499bf215546Sopenharmony_ci return NULL; 1500bf215546Sopenharmony_ci 1501bf215546Sopenharmony_ci if (num_names != 1) 1502bf215546Sopenharmony_ci return NULL; 1503bf215546Sopenharmony_ci 1504bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 1505bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_SHARED; 1506bf215546Sopenharmony_ci whandle.handle = names[0]; 1507bf215546Sopenharmony_ci whandle.stride = strides[0]; 1508bf215546Sopenharmony_ci whandle.offset = offsets[0]; 1509bf215546Sopenharmony_ci whandle.format = map->pipe_format; 1510bf215546Sopenharmony_ci whandle.modifier = DRM_FORMAT_MOD_INVALID; 1511bf215546Sopenharmony_ci 1512bf215546Sopenharmony_ci img = dri2_create_image_from_winsys(screen, width, height, map, 1513bf215546Sopenharmony_ci 1, &whandle, 0, loaderPrivate); 1514bf215546Sopenharmony_ci if (img == NULL) 1515bf215546Sopenharmony_ci return NULL; 1516bf215546Sopenharmony_ci 1517bf215546Sopenharmony_ci img->dri_components = map->dri_components; 1518bf215546Sopenharmony_ci img->dri_fourcc = map->dri_fourcc; 1519bf215546Sopenharmony_ci img->dri_format = map->pipe_format; 1520bf215546Sopenharmony_ci 1521bf215546Sopenharmony_ci return img; 1522bf215546Sopenharmony_ci} 1523bf215546Sopenharmony_ci 1524bf215546Sopenharmony_cistatic __DRIimage * 1525bf215546Sopenharmony_cidri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate) 1526bf215546Sopenharmony_ci{ 1527bf215546Sopenharmony_ci __DRIimage *img; 1528bf215546Sopenharmony_ci 1529bf215546Sopenharmony_ci if (plane < 0) { 1530bf215546Sopenharmony_ci return NULL; 1531bf215546Sopenharmony_ci } else if (plane > 0) { 1532bf215546Sopenharmony_ci uint64_t planes; 1533bf215546Sopenharmony_ci if (!dri2_resource_get_param(image, PIPE_RESOURCE_PARAM_NPLANES, 0, 1534bf215546Sopenharmony_ci &planes) || 1535bf215546Sopenharmony_ci plane >= planes) { 1536bf215546Sopenharmony_ci return NULL; 1537bf215546Sopenharmony_ci } 1538bf215546Sopenharmony_ci } 1539bf215546Sopenharmony_ci 1540bf215546Sopenharmony_ci if (image->dri_components == 0) { 1541bf215546Sopenharmony_ci uint64_t modifier; 1542bf215546Sopenharmony_ci if (!dri2_resource_get_param(image, PIPE_RESOURCE_PARAM_MODIFIER, 0, 1543bf215546Sopenharmony_ci &modifier) || 1544bf215546Sopenharmony_ci modifier == DRM_FORMAT_MOD_INVALID) { 1545bf215546Sopenharmony_ci return NULL; 1546bf215546Sopenharmony_ci } 1547bf215546Sopenharmony_ci } 1548bf215546Sopenharmony_ci 1549bf215546Sopenharmony_ci img = dri2_dup_image(image, loaderPrivate); 1550bf215546Sopenharmony_ci if (img == NULL) 1551bf215546Sopenharmony_ci return NULL; 1552bf215546Sopenharmony_ci 1553bf215546Sopenharmony_ci if (img->texture->screen->resource_changed) 1554bf215546Sopenharmony_ci img->texture->screen->resource_changed(img->texture->screen, 1555bf215546Sopenharmony_ci img->texture); 1556bf215546Sopenharmony_ci 1557bf215546Sopenharmony_ci /* set this to 0 for sub images. */ 1558bf215546Sopenharmony_ci img->dri_components = 0; 1559bf215546Sopenharmony_ci img->plane = plane; 1560bf215546Sopenharmony_ci return img; 1561bf215546Sopenharmony_ci} 1562bf215546Sopenharmony_ci 1563bf215546Sopenharmony_cistatic __DRIimage * 1564bf215546Sopenharmony_cidri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc, 1565bf215546Sopenharmony_ci int *fds, int num_fds, int *strides, int *offsets, 1566bf215546Sopenharmony_ci void *loaderPrivate) 1567bf215546Sopenharmony_ci{ 1568bf215546Sopenharmony_ci return dri2_create_image_from_fd(screen, width, height, fourcc, 1569bf215546Sopenharmony_ci DRM_FORMAT_MOD_INVALID, fds, num_fds, 1570bf215546Sopenharmony_ci strides, offsets, 0, NULL, loaderPrivate); 1571bf215546Sopenharmony_ci} 1572bf215546Sopenharmony_ci 1573bf215546Sopenharmony_cistatic __DRIimage * 1574bf215546Sopenharmony_cidri2_from_fds2(__DRIscreen *screen, int width, int height, int fourcc, 1575bf215546Sopenharmony_ci int *fds, int num_fds, uint32_t flags, int *strides, 1576bf215546Sopenharmony_ci int *offsets, void *loaderPrivate) 1577bf215546Sopenharmony_ci{ 1578bf215546Sopenharmony_ci unsigned bind = 0; 1579bf215546Sopenharmony_ci if (flags & __DRI_IMAGE_PROTECTED_CONTENT_FLAG) 1580bf215546Sopenharmony_ci bind |= PIPE_BIND_PROTECTED; 1581bf215546Sopenharmony_ci if (flags & __DRI_IMAGE_PRIME_LINEAR_BUFFER) 1582bf215546Sopenharmony_ci bind |= PIPE_BIND_PRIME_BLIT_DST; 1583bf215546Sopenharmony_ci 1584bf215546Sopenharmony_ci return dri2_create_image_from_fd(screen, width, height, fourcc, 1585bf215546Sopenharmony_ci DRM_FORMAT_MOD_INVALID, fds, num_fds, 1586bf215546Sopenharmony_ci strides, offsets, bind, NULL, loaderPrivate); 1587bf215546Sopenharmony_ci} 1588bf215546Sopenharmony_ci 1589bf215546Sopenharmony_cistatic boolean 1590bf215546Sopenharmony_cidri2_query_dma_buf_modifiers(__DRIscreen *_screen, int fourcc, int max, 1591bf215546Sopenharmony_ci uint64_t *modifiers, unsigned int *external_only, 1592bf215546Sopenharmony_ci int *count) 1593bf215546Sopenharmony_ci{ 1594bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(_screen); 1595bf215546Sopenharmony_ci struct pipe_screen *pscreen = screen->base.screen; 1596bf215546Sopenharmony_ci const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc); 1597bf215546Sopenharmony_ci enum pipe_format format; 1598bf215546Sopenharmony_ci 1599bf215546Sopenharmony_ci if (!map) 1600bf215546Sopenharmony_ci return false; 1601bf215546Sopenharmony_ci 1602bf215546Sopenharmony_ci format = map->pipe_format; 1603bf215546Sopenharmony_ci 1604bf215546Sopenharmony_ci bool native_sampling = pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, 1605bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW); 1606bf215546Sopenharmony_ci if (pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, 1607bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET) || 1608bf215546Sopenharmony_ci native_sampling || 1609bf215546Sopenharmony_ci dri2_yuv_dma_buf_supported(screen, map)) { 1610bf215546Sopenharmony_ci if (pscreen->query_dmabuf_modifiers != NULL) { 1611bf215546Sopenharmony_ci pscreen->query_dmabuf_modifiers(pscreen, format, max, modifiers, 1612bf215546Sopenharmony_ci external_only, count); 1613bf215546Sopenharmony_ci if (!native_sampling && external_only) { 1614bf215546Sopenharmony_ci /* To support it using YUV lowering, we need it to be samplerExternalOES. 1615bf215546Sopenharmony_ci */ 1616bf215546Sopenharmony_ci for (int i = 0; i < *count; i++) 1617bf215546Sopenharmony_ci external_only[i] = true; 1618bf215546Sopenharmony_ci } 1619bf215546Sopenharmony_ci } else { 1620bf215546Sopenharmony_ci *count = 0; 1621bf215546Sopenharmony_ci } 1622bf215546Sopenharmony_ci return true; 1623bf215546Sopenharmony_ci } 1624bf215546Sopenharmony_ci return false; 1625bf215546Sopenharmony_ci} 1626bf215546Sopenharmony_ci 1627bf215546Sopenharmony_cistatic boolean 1628bf215546Sopenharmony_cidri2_query_dma_buf_format_modifier_attribs(__DRIscreen *_screen, 1629bf215546Sopenharmony_ci uint32_t fourcc, uint64_t modifier, 1630bf215546Sopenharmony_ci int attrib, uint64_t *value) 1631bf215546Sopenharmony_ci{ 1632bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(_screen); 1633bf215546Sopenharmony_ci struct pipe_screen *pscreen = screen->base.screen; 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ci if (!pscreen->query_dmabuf_modifiers) 1636bf215546Sopenharmony_ci return false; 1637bf215546Sopenharmony_ci 1638bf215546Sopenharmony_ci switch (attrib) { 1639bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT: { 1640bf215546Sopenharmony_ci uint64_t mod_planes = dri2_get_modifier_num_planes(_screen, modifier, 1641bf215546Sopenharmony_ci fourcc); 1642bf215546Sopenharmony_ci if (mod_planes > 0) 1643bf215546Sopenharmony_ci *value = mod_planes; 1644bf215546Sopenharmony_ci return mod_planes > 0; 1645bf215546Sopenharmony_ci } 1646bf215546Sopenharmony_ci default: 1647bf215546Sopenharmony_ci return false; 1648bf215546Sopenharmony_ci } 1649bf215546Sopenharmony_ci} 1650bf215546Sopenharmony_ci 1651bf215546Sopenharmony_cistatic __DRIimage * 1652bf215546Sopenharmony_cidri2_from_dma_bufs(__DRIscreen *screen, 1653bf215546Sopenharmony_ci int width, int height, int fourcc, 1654bf215546Sopenharmony_ci int *fds, int num_fds, 1655bf215546Sopenharmony_ci int *strides, int *offsets, 1656bf215546Sopenharmony_ci enum __DRIYUVColorSpace yuv_color_space, 1657bf215546Sopenharmony_ci enum __DRISampleRange sample_range, 1658bf215546Sopenharmony_ci enum __DRIChromaSiting horizontal_siting, 1659bf215546Sopenharmony_ci enum __DRIChromaSiting vertical_siting, 1660bf215546Sopenharmony_ci unsigned *error, 1661bf215546Sopenharmony_ci void *loaderPrivate) 1662bf215546Sopenharmony_ci{ 1663bf215546Sopenharmony_ci __DRIimage *img; 1664bf215546Sopenharmony_ci 1665bf215546Sopenharmony_ci img = dri2_create_image_from_fd(screen, width, height, fourcc, 1666bf215546Sopenharmony_ci DRM_FORMAT_MOD_INVALID, fds, num_fds, 1667bf215546Sopenharmony_ci strides, offsets, 0, error, loaderPrivate); 1668bf215546Sopenharmony_ci if (img == NULL) 1669bf215546Sopenharmony_ci return NULL; 1670bf215546Sopenharmony_ci 1671bf215546Sopenharmony_ci img->yuv_color_space = yuv_color_space; 1672bf215546Sopenharmony_ci img->sample_range = sample_range; 1673bf215546Sopenharmony_ci img->horizontal_siting = horizontal_siting; 1674bf215546Sopenharmony_ci img->vertical_siting = vertical_siting; 1675bf215546Sopenharmony_ci 1676bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_SUCCESS; 1677bf215546Sopenharmony_ci return img; 1678bf215546Sopenharmony_ci} 1679bf215546Sopenharmony_ci 1680bf215546Sopenharmony_cistatic __DRIimage * 1681bf215546Sopenharmony_cidri2_from_dma_bufs2(__DRIscreen *screen, 1682bf215546Sopenharmony_ci int width, int height, int fourcc, 1683bf215546Sopenharmony_ci uint64_t modifier, int *fds, int num_fds, 1684bf215546Sopenharmony_ci int *strides, int *offsets, 1685bf215546Sopenharmony_ci enum __DRIYUVColorSpace yuv_color_space, 1686bf215546Sopenharmony_ci enum __DRISampleRange sample_range, 1687bf215546Sopenharmony_ci enum __DRIChromaSiting horizontal_siting, 1688bf215546Sopenharmony_ci enum __DRIChromaSiting vertical_siting, 1689bf215546Sopenharmony_ci unsigned *error, 1690bf215546Sopenharmony_ci void *loaderPrivate) 1691bf215546Sopenharmony_ci{ 1692bf215546Sopenharmony_ci __DRIimage *img; 1693bf215546Sopenharmony_ci 1694bf215546Sopenharmony_ci img = dri2_create_image_from_fd(screen, width, height, fourcc, 1695bf215546Sopenharmony_ci modifier, fds, num_fds, strides, offsets, 1696bf215546Sopenharmony_ci 0, error, loaderPrivate); 1697bf215546Sopenharmony_ci if (img == NULL) 1698bf215546Sopenharmony_ci return NULL; 1699bf215546Sopenharmony_ci 1700bf215546Sopenharmony_ci img->yuv_color_space = yuv_color_space; 1701bf215546Sopenharmony_ci img->sample_range = sample_range; 1702bf215546Sopenharmony_ci img->horizontal_siting = horizontal_siting; 1703bf215546Sopenharmony_ci img->vertical_siting = vertical_siting; 1704bf215546Sopenharmony_ci 1705bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_SUCCESS; 1706bf215546Sopenharmony_ci return img; 1707bf215546Sopenharmony_ci} 1708bf215546Sopenharmony_ci 1709bf215546Sopenharmony_cistatic __DRIimage * 1710bf215546Sopenharmony_cidri2_from_dma_bufs3(__DRIscreen *screen, 1711bf215546Sopenharmony_ci int width, int height, int fourcc, 1712bf215546Sopenharmony_ci uint64_t modifier, int *fds, int num_fds, 1713bf215546Sopenharmony_ci int *strides, int *offsets, 1714bf215546Sopenharmony_ci enum __DRIYUVColorSpace yuv_color_space, 1715bf215546Sopenharmony_ci enum __DRISampleRange sample_range, 1716bf215546Sopenharmony_ci enum __DRIChromaSiting horizontal_siting, 1717bf215546Sopenharmony_ci enum __DRIChromaSiting vertical_siting, 1718bf215546Sopenharmony_ci uint32_t flags, 1719bf215546Sopenharmony_ci unsigned *error, 1720bf215546Sopenharmony_ci void *loaderPrivate) 1721bf215546Sopenharmony_ci{ 1722bf215546Sopenharmony_ci __DRIimage *img; 1723bf215546Sopenharmony_ci 1724bf215546Sopenharmony_ci img = dri2_create_image_from_fd(screen, width, height, fourcc, 1725bf215546Sopenharmony_ci modifier, fds, num_fds, strides, offsets, 1726bf215546Sopenharmony_ci (flags & __DRI_IMAGE_PROTECTED_CONTENT_FLAG) ? 1727bf215546Sopenharmony_ci PIPE_BIND_PROTECTED : 0, 1728bf215546Sopenharmony_ci error, loaderPrivate); 1729bf215546Sopenharmony_ci if (img == NULL) 1730bf215546Sopenharmony_ci return NULL; 1731bf215546Sopenharmony_ci 1732bf215546Sopenharmony_ci img->yuv_color_space = yuv_color_space; 1733bf215546Sopenharmony_ci img->sample_range = sample_range; 1734bf215546Sopenharmony_ci img->horizontal_siting = horizontal_siting; 1735bf215546Sopenharmony_ci img->vertical_siting = vertical_siting; 1736bf215546Sopenharmony_ci 1737bf215546Sopenharmony_ci *error = __DRI_IMAGE_ERROR_SUCCESS; 1738bf215546Sopenharmony_ci return img; 1739bf215546Sopenharmony_ci} 1740bf215546Sopenharmony_ci 1741bf215546Sopenharmony_cistatic void 1742bf215546Sopenharmony_cidri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src, 1743bf215546Sopenharmony_ci int dstx0, int dsty0, int dstwidth, int dstheight, 1744bf215546Sopenharmony_ci int srcx0, int srcy0, int srcwidth, int srcheight, 1745bf215546Sopenharmony_ci int flush_flag) 1746bf215546Sopenharmony_ci{ 1747bf215546Sopenharmony_ci struct dri_context *ctx = dri_context(context); 1748bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->st->pipe; 1749bf215546Sopenharmony_ci struct pipe_screen *screen; 1750bf215546Sopenharmony_ci struct pipe_fence_handle *fence; 1751bf215546Sopenharmony_ci struct pipe_blit_info blit; 1752bf215546Sopenharmony_ci 1753bf215546Sopenharmony_ci if (!dst || !src) 1754bf215546Sopenharmony_ci return; 1755bf215546Sopenharmony_ci 1756bf215546Sopenharmony_ci handle_in_fence(context, dst); 1757bf215546Sopenharmony_ci 1758bf215546Sopenharmony_ci memset(&blit, 0, sizeof(blit)); 1759bf215546Sopenharmony_ci blit.dst.resource = dst->texture; 1760bf215546Sopenharmony_ci blit.dst.box.x = dstx0; 1761bf215546Sopenharmony_ci blit.dst.box.y = dsty0; 1762bf215546Sopenharmony_ci blit.dst.box.width = dstwidth; 1763bf215546Sopenharmony_ci blit.dst.box.height = dstheight; 1764bf215546Sopenharmony_ci blit.dst.box.depth = 1; 1765bf215546Sopenharmony_ci blit.dst.format = dst->texture->format; 1766bf215546Sopenharmony_ci blit.src.resource = src->texture; 1767bf215546Sopenharmony_ci blit.src.box.x = srcx0; 1768bf215546Sopenharmony_ci blit.src.box.y = srcy0; 1769bf215546Sopenharmony_ci blit.src.box.width = srcwidth; 1770bf215546Sopenharmony_ci blit.src.box.height = srcheight; 1771bf215546Sopenharmony_ci blit.src.box.depth = 1; 1772bf215546Sopenharmony_ci blit.src.format = src->texture->format; 1773bf215546Sopenharmony_ci blit.mask = PIPE_MASK_RGBA; 1774bf215546Sopenharmony_ci blit.filter = PIPE_TEX_FILTER_NEAREST; 1775bf215546Sopenharmony_ci 1776bf215546Sopenharmony_ci pipe->blit(pipe, &blit); 1777bf215546Sopenharmony_ci 1778bf215546Sopenharmony_ci if (flush_flag == __BLIT_FLAG_FLUSH) { 1779bf215546Sopenharmony_ci pipe->flush_resource(pipe, dst->texture); 1780bf215546Sopenharmony_ci ctx->st->flush(ctx->st, 0, NULL, NULL, NULL); 1781bf215546Sopenharmony_ci } else if (flush_flag == __BLIT_FLAG_FINISH) { 1782bf215546Sopenharmony_ci screen = dri_screen(ctx->sPriv)->base.screen; 1783bf215546Sopenharmony_ci pipe->flush_resource(pipe, dst->texture); 1784bf215546Sopenharmony_ci ctx->st->flush(ctx->st, 0, &fence, NULL, NULL); 1785bf215546Sopenharmony_ci (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE); 1786bf215546Sopenharmony_ci screen->fence_reference(screen, &fence, NULL); 1787bf215546Sopenharmony_ci } 1788bf215546Sopenharmony_ci} 1789bf215546Sopenharmony_ci 1790bf215546Sopenharmony_cistatic void * 1791bf215546Sopenharmony_cidri2_map_image(__DRIcontext *context, __DRIimage *image, 1792bf215546Sopenharmony_ci int x0, int y0, int width, int height, 1793bf215546Sopenharmony_ci unsigned int flags, int *stride, void **data) 1794bf215546Sopenharmony_ci{ 1795bf215546Sopenharmony_ci struct dri_context *ctx = dri_context(context); 1796bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->st->pipe; 1797bf215546Sopenharmony_ci enum pipe_map_flags pipe_access = 0; 1798bf215546Sopenharmony_ci struct pipe_transfer *trans; 1799bf215546Sopenharmony_ci void *map; 1800bf215546Sopenharmony_ci 1801bf215546Sopenharmony_ci if (!image || !data || *data) 1802bf215546Sopenharmony_ci return NULL; 1803bf215546Sopenharmony_ci 1804bf215546Sopenharmony_ci unsigned plane = image->plane; 1805bf215546Sopenharmony_ci if (plane >= dri2_get_mapping_by_format(image->dri_format)->nplanes) 1806bf215546Sopenharmony_ci return NULL; 1807bf215546Sopenharmony_ci 1808bf215546Sopenharmony_ci handle_in_fence(context, image); 1809bf215546Sopenharmony_ci 1810bf215546Sopenharmony_ci struct pipe_resource *resource = image->texture; 1811bf215546Sopenharmony_ci while (plane--) 1812bf215546Sopenharmony_ci resource = resource->next; 1813bf215546Sopenharmony_ci 1814bf215546Sopenharmony_ci if (flags & __DRI_IMAGE_TRANSFER_READ) 1815bf215546Sopenharmony_ci pipe_access |= PIPE_MAP_READ; 1816bf215546Sopenharmony_ci if (flags & __DRI_IMAGE_TRANSFER_WRITE) 1817bf215546Sopenharmony_ci pipe_access |= PIPE_MAP_WRITE; 1818bf215546Sopenharmony_ci 1819bf215546Sopenharmony_ci map = pipe_texture_map(pipe, resource, 0, 0, pipe_access, x0, y0, 1820bf215546Sopenharmony_ci width, height, &trans); 1821bf215546Sopenharmony_ci if (map) { 1822bf215546Sopenharmony_ci *data = trans; 1823bf215546Sopenharmony_ci *stride = trans->stride; 1824bf215546Sopenharmony_ci } 1825bf215546Sopenharmony_ci 1826bf215546Sopenharmony_ci return map; 1827bf215546Sopenharmony_ci} 1828bf215546Sopenharmony_ci 1829bf215546Sopenharmony_cistatic void 1830bf215546Sopenharmony_cidri2_unmap_image(__DRIcontext *context, __DRIimage *image, void *data) 1831bf215546Sopenharmony_ci{ 1832bf215546Sopenharmony_ci struct dri_context *ctx = dri_context(context); 1833bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->st->pipe; 1834bf215546Sopenharmony_ci 1835bf215546Sopenharmony_ci pipe_texture_unmap(pipe, (struct pipe_transfer *)data); 1836bf215546Sopenharmony_ci} 1837bf215546Sopenharmony_ci 1838bf215546Sopenharmony_cistatic int 1839bf215546Sopenharmony_cidri2_get_capabilities(__DRIscreen *_screen) 1840bf215546Sopenharmony_ci{ 1841bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(_screen); 1842bf215546Sopenharmony_ci 1843bf215546Sopenharmony_ci return (screen->can_share_buffer ? __DRI_IMAGE_CAP_GLOBAL_NAMES : 0); 1844bf215546Sopenharmony_ci} 1845bf215546Sopenharmony_ci 1846bf215546Sopenharmony_ci/* The extension is modified during runtime if DRI_PRIME is detected */ 1847bf215546Sopenharmony_cistatic const __DRIimageExtension dri2ImageExtensionTempl = { 1848bf215546Sopenharmony_ci .base = { __DRI_IMAGE, 21 }, 1849bf215546Sopenharmony_ci 1850bf215546Sopenharmony_ci .createImageFromName = dri2_create_image_from_name, 1851bf215546Sopenharmony_ci .createImageFromRenderbuffer = dri2_create_image_from_renderbuffer, 1852bf215546Sopenharmony_ci .destroyImage = dri2_destroy_image, 1853bf215546Sopenharmony_ci .createImage = dri2_create_image, 1854bf215546Sopenharmony_ci .queryImage = dri2_query_image, 1855bf215546Sopenharmony_ci .dupImage = dri2_dup_image, 1856bf215546Sopenharmony_ci .validateUsage = dri2_validate_usage, 1857bf215546Sopenharmony_ci .createImageFromNames = dri2_from_names, 1858bf215546Sopenharmony_ci .fromPlanar = dri2_from_planar, 1859bf215546Sopenharmony_ci .createImageFromTexture = dri2_create_from_texture, 1860bf215546Sopenharmony_ci .createImageFromFds = NULL, 1861bf215546Sopenharmony_ci .createImageFromFds2 = NULL, 1862bf215546Sopenharmony_ci .createImageFromDmaBufs = NULL, 1863bf215546Sopenharmony_ci .blitImage = dri2_blit_image, 1864bf215546Sopenharmony_ci .getCapabilities = dri2_get_capabilities, 1865bf215546Sopenharmony_ci .mapImage = dri2_map_image, 1866bf215546Sopenharmony_ci .unmapImage = dri2_unmap_image, 1867bf215546Sopenharmony_ci .createImageWithModifiers = NULL, 1868bf215546Sopenharmony_ci .createImageFromDmaBufs2 = NULL, 1869bf215546Sopenharmony_ci .createImageFromDmaBufs3 = NULL, 1870bf215546Sopenharmony_ci .queryDmaBufFormats = NULL, 1871bf215546Sopenharmony_ci .queryDmaBufModifiers = NULL, 1872bf215546Sopenharmony_ci .queryDmaBufFormatModifierAttribs = NULL, 1873bf215546Sopenharmony_ci .createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2, 1874bf215546Sopenharmony_ci .createImageWithModifiers2 = NULL, 1875bf215546Sopenharmony_ci}; 1876bf215546Sopenharmony_ci 1877bf215546Sopenharmony_ciconst __DRIimageExtension driVkImageExtension = { 1878bf215546Sopenharmony_ci .base = { __DRI_IMAGE, 20 }, 1879bf215546Sopenharmony_ci 1880bf215546Sopenharmony_ci .createImageFromName = dri2_create_image_from_name, 1881bf215546Sopenharmony_ci .createImageFromRenderbuffer = dri2_create_image_from_renderbuffer, 1882bf215546Sopenharmony_ci .destroyImage = dri2_destroy_image, 1883bf215546Sopenharmony_ci .createImage = dri2_create_image, 1884bf215546Sopenharmony_ci .queryImage = dri2_query_image, 1885bf215546Sopenharmony_ci .dupImage = dri2_dup_image, 1886bf215546Sopenharmony_ci .validateUsage = dri2_validate_usage, 1887bf215546Sopenharmony_ci .createImageFromNames = dri2_from_names, 1888bf215546Sopenharmony_ci .fromPlanar = dri2_from_planar, 1889bf215546Sopenharmony_ci .createImageFromTexture = dri2_create_from_texture, 1890bf215546Sopenharmony_ci .createImageFromFds = dri2_from_fds, 1891bf215546Sopenharmony_ci .createImageFromFds2 = dri2_from_fds2, 1892bf215546Sopenharmony_ci .createImageFromDmaBufs = dri2_from_dma_bufs, 1893bf215546Sopenharmony_ci .blitImage = dri2_blit_image, 1894bf215546Sopenharmony_ci .getCapabilities = dri2_get_capabilities, 1895bf215546Sopenharmony_ci .mapImage = dri2_map_image, 1896bf215546Sopenharmony_ci .unmapImage = dri2_unmap_image, 1897bf215546Sopenharmony_ci .createImageWithModifiers = dri2_create_image_with_modifiers, 1898bf215546Sopenharmony_ci .createImageFromDmaBufs2 = dri2_from_dma_bufs2, 1899bf215546Sopenharmony_ci .createImageFromDmaBufs3 = dri2_from_dma_bufs3, 1900bf215546Sopenharmony_ci .queryDmaBufFormats = dri2_query_dma_buf_formats, 1901bf215546Sopenharmony_ci .queryDmaBufModifiers = dri2_query_dma_buf_modifiers, 1902bf215546Sopenharmony_ci .queryDmaBufFormatModifierAttribs = dri2_query_dma_buf_format_modifier_attribs, 1903bf215546Sopenharmony_ci .createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2, 1904bf215546Sopenharmony_ci .createImageWithModifiers2 = dri2_create_image_with_modifiers2, 1905bf215546Sopenharmony_ci}; 1906bf215546Sopenharmony_ci 1907bf215546Sopenharmony_ciconst __DRIimageExtension driVkImageExtensionSw = { 1908bf215546Sopenharmony_ci .base = { __DRI_IMAGE, 20 }, 1909bf215546Sopenharmony_ci 1910bf215546Sopenharmony_ci .createImageFromName = dri2_create_image_from_name, 1911bf215546Sopenharmony_ci .createImageFromRenderbuffer = dri2_create_image_from_renderbuffer, 1912bf215546Sopenharmony_ci .destroyImage = dri2_destroy_image, 1913bf215546Sopenharmony_ci .createImage = dri2_create_image, 1914bf215546Sopenharmony_ci .queryImage = dri2_query_image, 1915bf215546Sopenharmony_ci .dupImage = dri2_dup_image, 1916bf215546Sopenharmony_ci .validateUsage = dri2_validate_usage, 1917bf215546Sopenharmony_ci .createImageFromNames = dri2_from_names, 1918bf215546Sopenharmony_ci .fromPlanar = dri2_from_planar, 1919bf215546Sopenharmony_ci .createImageFromTexture = dri2_create_from_texture, 1920bf215546Sopenharmony_ci .createImageFromFds = dri2_from_fds, 1921bf215546Sopenharmony_ci .createImageFromFds2 = dri2_from_fds2, 1922bf215546Sopenharmony_ci .blitImage = dri2_blit_image, 1923bf215546Sopenharmony_ci .getCapabilities = dri2_get_capabilities, 1924bf215546Sopenharmony_ci .mapImage = dri2_map_image, 1925bf215546Sopenharmony_ci .unmapImage = dri2_unmap_image, 1926bf215546Sopenharmony_ci .createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2, 1927bf215546Sopenharmony_ci}; 1928bf215546Sopenharmony_ci 1929bf215546Sopenharmony_cistatic const __DRIrobustnessExtension dri2Robustness = { 1930bf215546Sopenharmony_ci .base = { __DRI2_ROBUSTNESS, 1 } 1931bf215546Sopenharmony_ci}; 1932bf215546Sopenharmony_ci 1933bf215546Sopenharmony_cistatic int 1934bf215546Sopenharmony_cidri2_interop_query_device_info(__DRIcontext *_ctx, 1935bf215546Sopenharmony_ci struct mesa_glinterop_device_info *out) 1936bf215546Sopenharmony_ci{ 1937bf215546Sopenharmony_ci struct pipe_screen *screen = dri_context(_ctx)->st->pipe->screen; 1938bf215546Sopenharmony_ci 1939bf215546Sopenharmony_ci /* There is no version 0, thus we do not support it */ 1940bf215546Sopenharmony_ci if (out->version == 0) 1941bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_VERSION; 1942bf215546Sopenharmony_ci 1943bf215546Sopenharmony_ci out->pci_segment_group = screen->get_param(screen, PIPE_CAP_PCI_GROUP); 1944bf215546Sopenharmony_ci out->pci_bus = screen->get_param(screen, PIPE_CAP_PCI_BUS); 1945bf215546Sopenharmony_ci out->pci_device = screen->get_param(screen, PIPE_CAP_PCI_DEVICE); 1946bf215546Sopenharmony_ci out->pci_function = screen->get_param(screen, PIPE_CAP_PCI_FUNCTION); 1947bf215546Sopenharmony_ci 1948bf215546Sopenharmony_ci out->vendor_id = screen->get_param(screen, PIPE_CAP_VENDOR_ID); 1949bf215546Sopenharmony_ci out->device_id = screen->get_param(screen, PIPE_CAP_DEVICE_ID); 1950bf215546Sopenharmony_ci 1951bf215546Sopenharmony_ci /* Instruct the caller that we support up-to version one of the interface */ 1952bf215546Sopenharmony_ci out->version = 1; 1953bf215546Sopenharmony_ci 1954bf215546Sopenharmony_ci return MESA_GLINTEROP_SUCCESS; 1955bf215546Sopenharmony_ci} 1956bf215546Sopenharmony_ci 1957bf215546Sopenharmony_cistatic int 1958bf215546Sopenharmony_cidri2_interop_export_object(__DRIcontext *_ctx, 1959bf215546Sopenharmony_ci struct mesa_glinterop_export_in *in, 1960bf215546Sopenharmony_ci struct mesa_glinterop_export_out *out) 1961bf215546Sopenharmony_ci{ 1962bf215546Sopenharmony_ci struct st_context_iface *st = dri_context(_ctx)->st; 1963bf215546Sopenharmony_ci struct pipe_screen *screen = st->pipe->screen; 1964bf215546Sopenharmony_ci struct gl_context *ctx = ((struct st_context *)st)->ctx; 1965bf215546Sopenharmony_ci struct pipe_resource *res = NULL; 1966bf215546Sopenharmony_ci struct winsys_handle whandle; 1967bf215546Sopenharmony_ci unsigned target, usage; 1968bf215546Sopenharmony_ci boolean success; 1969bf215546Sopenharmony_ci 1970bf215546Sopenharmony_ci /* There is no version 0, thus we do not support it */ 1971bf215546Sopenharmony_ci if (in->version == 0 || out->version == 0) 1972bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_VERSION; 1973bf215546Sopenharmony_ci 1974bf215546Sopenharmony_ci /* Validate the target. */ 1975bf215546Sopenharmony_ci switch (in->target) { 1976bf215546Sopenharmony_ci case GL_TEXTURE_BUFFER: 1977bf215546Sopenharmony_ci case GL_TEXTURE_1D: 1978bf215546Sopenharmony_ci case GL_TEXTURE_2D: 1979bf215546Sopenharmony_ci case GL_TEXTURE_3D: 1980bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1981bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1982bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1983bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 1984bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1985bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 1986bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1987bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 1988bf215546Sopenharmony_ci case GL_RENDERBUFFER: 1989bf215546Sopenharmony_ci case GL_ARRAY_BUFFER: 1990bf215546Sopenharmony_ci target = in->target; 1991bf215546Sopenharmony_ci break; 1992bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1993bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1994bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1995bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1996bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1997bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1998bf215546Sopenharmony_ci target = GL_TEXTURE_CUBE_MAP; 1999bf215546Sopenharmony_ci break; 2000bf215546Sopenharmony_ci default: 2001bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_TARGET; 2002bf215546Sopenharmony_ci } 2003bf215546Sopenharmony_ci 2004bf215546Sopenharmony_ci /* Validate the simple case of miplevel. */ 2005bf215546Sopenharmony_ci if ((target == GL_RENDERBUFFER || target == GL_ARRAY_BUFFER) && 2006bf215546Sopenharmony_ci in->miplevel != 0) 2007bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_MIP_LEVEL; 2008bf215546Sopenharmony_ci 2009bf215546Sopenharmony_ci /* Validate the OpenGL object and get pipe_resource. */ 2010bf215546Sopenharmony_ci simple_mtx_lock(&ctx->Shared->Mutex); 2011bf215546Sopenharmony_ci 2012bf215546Sopenharmony_ci if (target == GL_ARRAY_BUFFER) { 2013bf215546Sopenharmony_ci /* Buffer objects. 2014bf215546Sopenharmony_ci * 2015bf215546Sopenharmony_ci * The error checking is based on the documentation of 2016bf215546Sopenharmony_ci * clCreateFromGLBuffer from OpenCL 2.0 SDK. 2017bf215546Sopenharmony_ci */ 2018bf215546Sopenharmony_ci struct gl_buffer_object *buf = _mesa_lookup_bufferobj(ctx, in->obj); 2019bf215546Sopenharmony_ci 2020bf215546Sopenharmony_ci /* From OpenCL 2.0 SDK, clCreateFromGLBuffer: 2021bf215546Sopenharmony_ci * "CL_INVALID_GL_OBJECT if bufobj is not a GL buffer object or is 2022bf215546Sopenharmony_ci * a GL buffer object but does not have an existing data store or 2023bf215546Sopenharmony_ci * the size of the buffer is 0." 2024bf215546Sopenharmony_ci */ 2025bf215546Sopenharmony_ci if (!buf || buf->Size == 0) { 2026bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2027bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_OBJECT; 2028bf215546Sopenharmony_ci } 2029bf215546Sopenharmony_ci 2030bf215546Sopenharmony_ci res = buf->buffer; 2031bf215546Sopenharmony_ci if (!res) { 2032bf215546Sopenharmony_ci /* this shouldn't happen */ 2033bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2034bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_OBJECT; 2035bf215546Sopenharmony_ci } 2036bf215546Sopenharmony_ci 2037bf215546Sopenharmony_ci out->buf_offset = 0; 2038bf215546Sopenharmony_ci out->buf_size = buf->Size; 2039bf215546Sopenharmony_ci 2040bf215546Sopenharmony_ci buf->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE; 2041bf215546Sopenharmony_ci } else if (target == GL_RENDERBUFFER) { 2042bf215546Sopenharmony_ci /* Renderbuffers. 2043bf215546Sopenharmony_ci * 2044bf215546Sopenharmony_ci * The error checking is based on the documentation of 2045bf215546Sopenharmony_ci * clCreateFromGLRenderbuffer from OpenCL 2.0 SDK. 2046bf215546Sopenharmony_ci */ 2047bf215546Sopenharmony_ci struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, in->obj); 2048bf215546Sopenharmony_ci 2049bf215546Sopenharmony_ci /* From OpenCL 2.0 SDK, clCreateFromGLRenderbuffer: 2050bf215546Sopenharmony_ci * "CL_INVALID_GL_OBJECT if renderbuffer is not a GL renderbuffer 2051bf215546Sopenharmony_ci * object or if the width or height of renderbuffer is zero." 2052bf215546Sopenharmony_ci */ 2053bf215546Sopenharmony_ci if (!rb || rb->Width == 0 || rb->Height == 0) { 2054bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2055bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_OBJECT; 2056bf215546Sopenharmony_ci } 2057bf215546Sopenharmony_ci 2058bf215546Sopenharmony_ci /* From OpenCL 2.0 SDK, clCreateFromGLRenderbuffer: 2059bf215546Sopenharmony_ci * "CL_INVALID_OPERATION if renderbuffer is a multi-sample GL 2060bf215546Sopenharmony_ci * renderbuffer object." 2061bf215546Sopenharmony_ci */ 2062bf215546Sopenharmony_ci if (rb->NumSamples > 1) { 2063bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2064bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_OPERATION; 2065bf215546Sopenharmony_ci } 2066bf215546Sopenharmony_ci 2067bf215546Sopenharmony_ci /* From OpenCL 2.0 SDK, clCreateFromGLRenderbuffer: 2068bf215546Sopenharmony_ci * "CL_OUT_OF_RESOURCES if there is a failure to allocate resources 2069bf215546Sopenharmony_ci * required by the OpenCL implementation on the device." 2070bf215546Sopenharmony_ci */ 2071bf215546Sopenharmony_ci res = rb->texture; 2072bf215546Sopenharmony_ci if (!res) { 2073bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2074bf215546Sopenharmony_ci return MESA_GLINTEROP_OUT_OF_RESOURCES; 2075bf215546Sopenharmony_ci } 2076bf215546Sopenharmony_ci 2077bf215546Sopenharmony_ci out->internal_format = rb->InternalFormat; 2078bf215546Sopenharmony_ci out->view_minlevel = 0; 2079bf215546Sopenharmony_ci out->view_numlevels = 1; 2080bf215546Sopenharmony_ci out->view_minlayer = 0; 2081bf215546Sopenharmony_ci out->view_numlayers = 1; 2082bf215546Sopenharmony_ci } else { 2083bf215546Sopenharmony_ci /* Texture objects. 2084bf215546Sopenharmony_ci * 2085bf215546Sopenharmony_ci * The error checking is based on the documentation of 2086bf215546Sopenharmony_ci * clCreateFromGLTexture from OpenCL 2.0 SDK. 2087bf215546Sopenharmony_ci */ 2088bf215546Sopenharmony_ci struct gl_texture_object *obj = _mesa_lookup_texture(ctx, in->obj); 2089bf215546Sopenharmony_ci 2090bf215546Sopenharmony_ci if (obj) 2091bf215546Sopenharmony_ci _mesa_test_texobj_completeness(ctx, obj); 2092bf215546Sopenharmony_ci 2093bf215546Sopenharmony_ci /* From OpenCL 2.0 SDK, clCreateFromGLTexture: 2094bf215546Sopenharmony_ci * "CL_INVALID_GL_OBJECT if texture is not a GL texture object whose 2095bf215546Sopenharmony_ci * type matches texture_target, if the specified miplevel of texture 2096bf215546Sopenharmony_ci * is not defined, or if the width or height of the specified 2097bf215546Sopenharmony_ci * miplevel is zero or if the GL texture object is incomplete." 2098bf215546Sopenharmony_ci */ 2099bf215546Sopenharmony_ci if (!obj || 2100bf215546Sopenharmony_ci obj->Target != target || 2101bf215546Sopenharmony_ci !obj->_BaseComplete || 2102bf215546Sopenharmony_ci (in->miplevel > 0 && !obj->_MipmapComplete)) { 2103bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2104bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_OBJECT; 2105bf215546Sopenharmony_ci } 2106bf215546Sopenharmony_ci 2107bf215546Sopenharmony_ci if (target == GL_TEXTURE_BUFFER) { 2108bf215546Sopenharmony_ci struct gl_buffer_object *stBuf = 2109bf215546Sopenharmony_ci obj->BufferObject; 2110bf215546Sopenharmony_ci 2111bf215546Sopenharmony_ci if (!stBuf || !stBuf->buffer) { 2112bf215546Sopenharmony_ci /* this shouldn't happen */ 2113bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2114bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_OBJECT; 2115bf215546Sopenharmony_ci } 2116bf215546Sopenharmony_ci res = stBuf->buffer; 2117bf215546Sopenharmony_ci 2118bf215546Sopenharmony_ci out->internal_format = obj->BufferObjectFormat; 2119bf215546Sopenharmony_ci out->buf_offset = obj->BufferOffset; 2120bf215546Sopenharmony_ci out->buf_size = obj->BufferSize == -1 ? obj->BufferObject->Size : 2121bf215546Sopenharmony_ci obj->BufferSize; 2122bf215546Sopenharmony_ci 2123bf215546Sopenharmony_ci obj->BufferObject->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE; 2124bf215546Sopenharmony_ci } else { 2125bf215546Sopenharmony_ci /* From OpenCL 2.0 SDK, clCreateFromGLTexture: 2126bf215546Sopenharmony_ci * "CL_INVALID_MIP_LEVEL if miplevel is less than the value of 2127bf215546Sopenharmony_ci * levelbase (for OpenGL implementations) or zero (for OpenGL ES 2128bf215546Sopenharmony_ci * implementations); or greater than the value of q (for both OpenGL 2129bf215546Sopenharmony_ci * and OpenGL ES). levelbase and q are defined for the texture in 2130bf215546Sopenharmony_ci * section 3.8.10 (Texture Completeness) of the OpenGL 2.1 2131bf215546Sopenharmony_ci * specification and section 3.7.10 of the OpenGL ES 2.0." 2132bf215546Sopenharmony_ci */ 2133bf215546Sopenharmony_ci if (in->miplevel < obj->Attrib.BaseLevel || in->miplevel > obj->_MaxLevel) { 2134bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2135bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_MIP_LEVEL; 2136bf215546Sopenharmony_ci } 2137bf215546Sopenharmony_ci 2138bf215546Sopenharmony_ci if (!st_finalize_texture(ctx, st->pipe, obj, 0)) { 2139bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2140bf215546Sopenharmony_ci return MESA_GLINTEROP_OUT_OF_RESOURCES; 2141bf215546Sopenharmony_ci } 2142bf215546Sopenharmony_ci 2143bf215546Sopenharmony_ci res = st_get_texobj_resource(obj); 2144bf215546Sopenharmony_ci if (!res) { 2145bf215546Sopenharmony_ci /* Incomplete texture buffer object? This shouldn't really occur. */ 2146bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2147bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_OBJECT; 2148bf215546Sopenharmony_ci } 2149bf215546Sopenharmony_ci 2150bf215546Sopenharmony_ci out->internal_format = obj->Image[0][0]->InternalFormat; 2151bf215546Sopenharmony_ci out->view_minlevel = obj->Attrib.MinLevel; 2152bf215546Sopenharmony_ci out->view_numlevels = obj->Attrib.NumLevels; 2153bf215546Sopenharmony_ci out->view_minlayer = obj->Attrib.MinLayer; 2154bf215546Sopenharmony_ci out->view_numlayers = obj->Attrib.NumLayers; 2155bf215546Sopenharmony_ci } 2156bf215546Sopenharmony_ci } 2157bf215546Sopenharmony_ci 2158bf215546Sopenharmony_ci /* Get the handle. */ 2159bf215546Sopenharmony_ci switch (in->access) { 2160bf215546Sopenharmony_ci case MESA_GLINTEROP_ACCESS_READ_ONLY: 2161bf215546Sopenharmony_ci usage = 0; 2162bf215546Sopenharmony_ci break; 2163bf215546Sopenharmony_ci case MESA_GLINTEROP_ACCESS_READ_WRITE: 2164bf215546Sopenharmony_ci case MESA_GLINTEROP_ACCESS_WRITE_ONLY: 2165bf215546Sopenharmony_ci usage = PIPE_HANDLE_USAGE_SHADER_WRITE; 2166bf215546Sopenharmony_ci break; 2167bf215546Sopenharmony_ci default: 2168bf215546Sopenharmony_ci usage = 0; 2169bf215546Sopenharmony_ci } 2170bf215546Sopenharmony_ci 2171bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 2172bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_FD; 2173bf215546Sopenharmony_ci 2174bf215546Sopenharmony_ci success = screen->resource_get_handle(screen, st->pipe, res, &whandle, 2175bf215546Sopenharmony_ci usage); 2176bf215546Sopenharmony_ci simple_mtx_unlock(&ctx->Shared->Mutex); 2177bf215546Sopenharmony_ci 2178bf215546Sopenharmony_ci if (!success) 2179bf215546Sopenharmony_ci return MESA_GLINTEROP_OUT_OF_HOST_MEMORY; 2180bf215546Sopenharmony_ci 2181bf215546Sopenharmony_ci out->dmabuf_fd = whandle.handle; 2182bf215546Sopenharmony_ci out->out_driver_data_written = 0; 2183bf215546Sopenharmony_ci 2184bf215546Sopenharmony_ci if (res->target == PIPE_BUFFER) 2185bf215546Sopenharmony_ci out->buf_offset += whandle.offset; 2186bf215546Sopenharmony_ci 2187bf215546Sopenharmony_ci /* Instruct the caller that we support up-to version one of the interface */ 2188bf215546Sopenharmony_ci in->version = 1; 2189bf215546Sopenharmony_ci out->version = 1; 2190bf215546Sopenharmony_ci 2191bf215546Sopenharmony_ci return MESA_GLINTEROP_SUCCESS; 2192bf215546Sopenharmony_ci} 2193bf215546Sopenharmony_ci 2194bf215546Sopenharmony_cistatic const __DRI2interopExtension dri2InteropExtension = { 2195bf215546Sopenharmony_ci .base = { __DRI2_INTEROP, 1 }, 2196bf215546Sopenharmony_ci .query_device_info = dri2_interop_query_device_info, 2197bf215546Sopenharmony_ci .export_object = dri2_interop_export_object 2198bf215546Sopenharmony_ci}; 2199bf215546Sopenharmony_ci 2200bf215546Sopenharmony_ci/** 2201bf215546Sopenharmony_ci * \brief the DRI2bufferDamageExtension set_damage_region method 2202bf215546Sopenharmony_ci */ 2203bf215546Sopenharmony_cistatic void 2204bf215546Sopenharmony_cidri2_set_damage_region(__DRIdrawable *dPriv, unsigned int nrects, int *rects) 2205bf215546Sopenharmony_ci{ 2206bf215546Sopenharmony_ci struct dri_drawable *drawable = dri_drawable(dPriv); 2207bf215546Sopenharmony_ci struct pipe_box *boxes = NULL; 2208bf215546Sopenharmony_ci 2209bf215546Sopenharmony_ci if (nrects) { 2210bf215546Sopenharmony_ci boxes = CALLOC(nrects, sizeof(*boxes)); 2211bf215546Sopenharmony_ci assert(boxes); 2212bf215546Sopenharmony_ci 2213bf215546Sopenharmony_ci for (unsigned int i = 0; i < nrects; i++) { 2214bf215546Sopenharmony_ci int *rect = &rects[i * 4]; 2215bf215546Sopenharmony_ci 2216bf215546Sopenharmony_ci u_box_2d(rect[0], rect[1], rect[2], rect[3], &boxes[i]); 2217bf215546Sopenharmony_ci } 2218bf215546Sopenharmony_ci } 2219bf215546Sopenharmony_ci 2220bf215546Sopenharmony_ci FREE(drawable->damage_rects); 2221bf215546Sopenharmony_ci drawable->damage_rects = boxes; 2222bf215546Sopenharmony_ci drawable->num_damage_rects = nrects; 2223bf215546Sopenharmony_ci 2224bf215546Sopenharmony_ci /* Only apply the damage region if the BACK_LEFT texture is up-to-date. */ 2225bf215546Sopenharmony_ci if (drawable->texture_stamp == drawable->dPriv->lastStamp && 2226bf215546Sopenharmony_ci (drawable->texture_mask & (1 << ST_ATTACHMENT_BACK_LEFT))) { 2227bf215546Sopenharmony_ci struct pipe_screen *screen = drawable->screen->base.screen; 2228bf215546Sopenharmony_ci struct pipe_resource *resource; 2229bf215546Sopenharmony_ci 2230bf215546Sopenharmony_ci if (drawable->stvis.samples > 1) 2231bf215546Sopenharmony_ci resource = drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]; 2232bf215546Sopenharmony_ci else 2233bf215546Sopenharmony_ci resource = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 2234bf215546Sopenharmony_ci 2235bf215546Sopenharmony_ci screen->set_damage_region(screen, resource, 2236bf215546Sopenharmony_ci drawable->num_damage_rects, 2237bf215546Sopenharmony_ci drawable->damage_rects); 2238bf215546Sopenharmony_ci } 2239bf215546Sopenharmony_ci} 2240bf215546Sopenharmony_ci 2241bf215546Sopenharmony_cistatic const __DRI2bufferDamageExtension dri2BufferDamageExtensionTempl = { 2242bf215546Sopenharmony_ci .base = { __DRI2_BUFFER_DAMAGE, 1 }, 2243bf215546Sopenharmony_ci}; 2244bf215546Sopenharmony_ci 2245bf215546Sopenharmony_ci/** 2246bf215546Sopenharmony_ci * \brief the DRI2ConfigQueryExtension configQueryb method 2247bf215546Sopenharmony_ci */ 2248bf215546Sopenharmony_cistatic int 2249bf215546Sopenharmony_cidri2GalliumConfigQueryb(__DRIscreen *sPriv, const char *var, 2250bf215546Sopenharmony_ci unsigned char *val) 2251bf215546Sopenharmony_ci{ 2252bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(sPriv); 2253bf215546Sopenharmony_ci 2254bf215546Sopenharmony_ci if (!driCheckOption(&screen->dev->option_cache, var, DRI_BOOL)) 2255bf215546Sopenharmony_ci return dri2ConfigQueryExtension.configQueryb(sPriv, var, val); 2256bf215546Sopenharmony_ci 2257bf215546Sopenharmony_ci *val = driQueryOptionb(&screen->dev->option_cache, var); 2258bf215546Sopenharmony_ci 2259bf215546Sopenharmony_ci return 0; 2260bf215546Sopenharmony_ci} 2261bf215546Sopenharmony_ci 2262bf215546Sopenharmony_ci/** 2263bf215546Sopenharmony_ci * \brief the DRI2ConfigQueryExtension configQueryi method 2264bf215546Sopenharmony_ci */ 2265bf215546Sopenharmony_cistatic int 2266bf215546Sopenharmony_cidri2GalliumConfigQueryi(__DRIscreen *sPriv, const char *var, int *val) 2267bf215546Sopenharmony_ci{ 2268bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(sPriv); 2269bf215546Sopenharmony_ci 2270bf215546Sopenharmony_ci if (!driCheckOption(&screen->dev->option_cache, var, DRI_INT) && 2271bf215546Sopenharmony_ci !driCheckOption(&screen->dev->option_cache, var, DRI_ENUM)) 2272bf215546Sopenharmony_ci return dri2ConfigQueryExtension.configQueryi(sPriv, var, val); 2273bf215546Sopenharmony_ci 2274bf215546Sopenharmony_ci *val = driQueryOptioni(&screen->dev->option_cache, var); 2275bf215546Sopenharmony_ci 2276bf215546Sopenharmony_ci return 0; 2277bf215546Sopenharmony_ci} 2278bf215546Sopenharmony_ci 2279bf215546Sopenharmony_ci/** 2280bf215546Sopenharmony_ci * \brief the DRI2ConfigQueryExtension configQueryf method 2281bf215546Sopenharmony_ci */ 2282bf215546Sopenharmony_cistatic int 2283bf215546Sopenharmony_cidri2GalliumConfigQueryf(__DRIscreen *sPriv, const char *var, float *val) 2284bf215546Sopenharmony_ci{ 2285bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(sPriv); 2286bf215546Sopenharmony_ci 2287bf215546Sopenharmony_ci if (!driCheckOption(&screen->dev->option_cache, var, DRI_FLOAT)) 2288bf215546Sopenharmony_ci return dri2ConfigQueryExtension.configQueryf(sPriv, var, val); 2289bf215546Sopenharmony_ci 2290bf215546Sopenharmony_ci *val = driQueryOptionf(&screen->dev->option_cache, var); 2291bf215546Sopenharmony_ci 2292bf215546Sopenharmony_ci return 0; 2293bf215546Sopenharmony_ci} 2294bf215546Sopenharmony_ci 2295bf215546Sopenharmony_ci/** 2296bf215546Sopenharmony_ci * \brief the DRI2ConfigQueryExtension configQuerys method 2297bf215546Sopenharmony_ci */ 2298bf215546Sopenharmony_cistatic int 2299bf215546Sopenharmony_cidri2GalliumConfigQuerys(__DRIscreen *sPriv, const char *var, char **val) 2300bf215546Sopenharmony_ci{ 2301bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(sPriv); 2302bf215546Sopenharmony_ci 2303bf215546Sopenharmony_ci if (!driCheckOption(&screen->dev->option_cache, var, DRI_STRING)) 2304bf215546Sopenharmony_ci return dri2ConfigQueryExtension.configQuerys(sPriv, var, val); 2305bf215546Sopenharmony_ci 2306bf215546Sopenharmony_ci *val = driQueryOptionstr(&screen->dev->option_cache, var); 2307bf215546Sopenharmony_ci 2308bf215546Sopenharmony_ci return 0; 2309bf215546Sopenharmony_ci} 2310bf215546Sopenharmony_ci 2311bf215546Sopenharmony_ci/** 2312bf215546Sopenharmony_ci * \brief the DRI2ConfigQueryExtension struct. 2313bf215546Sopenharmony_ci * 2314bf215546Sopenharmony_ci * We first query the driver option cache. Then the dri2 option cache. 2315bf215546Sopenharmony_ci */ 2316bf215546Sopenharmony_cistatic const __DRI2configQueryExtension dri2GalliumConfigQueryExtension = { 2317bf215546Sopenharmony_ci .base = { __DRI2_CONFIG_QUERY, 2 }, 2318bf215546Sopenharmony_ci 2319bf215546Sopenharmony_ci .configQueryb = dri2GalliumConfigQueryb, 2320bf215546Sopenharmony_ci .configQueryi = dri2GalliumConfigQueryi, 2321bf215546Sopenharmony_ci .configQueryf = dri2GalliumConfigQueryf, 2322bf215546Sopenharmony_ci .configQuerys = dri2GalliumConfigQuerys, 2323bf215546Sopenharmony_ci}; 2324bf215546Sopenharmony_ci 2325bf215546Sopenharmony_ci/** 2326bf215546Sopenharmony_ci * \brief the DRI2blobExtension set_cache_funcs method 2327bf215546Sopenharmony_ci */ 2328bf215546Sopenharmony_cistatic void 2329bf215546Sopenharmony_ciset_blob_cache_funcs(__DRIscreen *sPriv, __DRIblobCacheSet set, 2330bf215546Sopenharmony_ci __DRIblobCacheGet get) 2331bf215546Sopenharmony_ci{ 2332bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(sPriv); 2333bf215546Sopenharmony_ci struct pipe_screen *pscreen = screen->base.screen; 2334bf215546Sopenharmony_ci 2335bf215546Sopenharmony_ci if (!pscreen->get_disk_shader_cache) 2336bf215546Sopenharmony_ci return; 2337bf215546Sopenharmony_ci 2338bf215546Sopenharmony_ci struct disk_cache *cache = pscreen->get_disk_shader_cache(pscreen); 2339bf215546Sopenharmony_ci 2340bf215546Sopenharmony_ci if (!cache) 2341bf215546Sopenharmony_ci return; 2342bf215546Sopenharmony_ci 2343bf215546Sopenharmony_ci disk_cache_set_callbacks(cache, set, get); 2344bf215546Sopenharmony_ci} 2345bf215546Sopenharmony_ci 2346bf215546Sopenharmony_cistatic const __DRI2blobExtension driBlobExtension = { 2347bf215546Sopenharmony_ci .base = { __DRI2_BLOB, 1 }, 2348bf215546Sopenharmony_ci .set_cache_funcs = set_blob_cache_funcs 2349bf215546Sopenharmony_ci}; 2350bf215546Sopenharmony_ci 2351bf215546Sopenharmony_cistatic const __DRImutableRenderBufferDriverExtension driMutableRenderBufferExtension = { 2352bf215546Sopenharmony_ci .base = { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1 }, 2353bf215546Sopenharmony_ci}; 2354bf215546Sopenharmony_ci 2355bf215546Sopenharmony_ci/* 2356bf215546Sopenharmony_ci * Backend function init_screen. 2357bf215546Sopenharmony_ci */ 2358bf215546Sopenharmony_ci 2359bf215546Sopenharmony_cistatic const __DRIextension *dri_screen_extensions_base[] = { 2360bf215546Sopenharmony_ci &driTexBufferExtension.base, 2361bf215546Sopenharmony_ci &dri2FlushExtension.base, 2362bf215546Sopenharmony_ci &dri2RendererQueryExtension.base, 2363bf215546Sopenharmony_ci &dri2GalliumConfigQueryExtension.base, 2364bf215546Sopenharmony_ci &dri2ThrottleExtension.base, 2365bf215546Sopenharmony_ci &dri2FenceExtension.base, 2366bf215546Sopenharmony_ci &dri2InteropExtension.base, 2367bf215546Sopenharmony_ci &driBlobExtension.base, 2368bf215546Sopenharmony_ci &driMutableRenderBufferExtension.base, 2369bf215546Sopenharmony_ci &dri2FlushControlExtension.base, 2370bf215546Sopenharmony_ci}; 2371bf215546Sopenharmony_ci 2372bf215546Sopenharmony_ci/** 2373bf215546Sopenharmony_ci * Set up the DRI extension list for this screen based on its underlying 2374bf215546Sopenharmony_ci * gallium screen's capabilities. 2375bf215546Sopenharmony_ci */ 2376bf215546Sopenharmony_cistatic void 2377bf215546Sopenharmony_cidri2_init_screen_extensions(struct dri_screen *screen, 2378bf215546Sopenharmony_ci struct pipe_screen *pscreen, 2379bf215546Sopenharmony_ci bool is_kms_screen) 2380bf215546Sopenharmony_ci{ 2381bf215546Sopenharmony_ci const __DRIextension **nExt; 2382bf215546Sopenharmony_ci 2383bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(screen->screen_extensions) >= 2384bf215546Sopenharmony_ci sizeof(dri_screen_extensions_base)); 2385bf215546Sopenharmony_ci memcpy(&screen->screen_extensions, dri_screen_extensions_base, 2386bf215546Sopenharmony_ci sizeof(dri_screen_extensions_base)); 2387bf215546Sopenharmony_ci screen->sPriv->extensions = screen->screen_extensions; 2388bf215546Sopenharmony_ci 2389bf215546Sopenharmony_ci /* Point nExt at the end of the extension list */ 2390bf215546Sopenharmony_ci nExt = &screen->screen_extensions[ARRAY_SIZE(dri_screen_extensions_base)]; 2391bf215546Sopenharmony_ci 2392bf215546Sopenharmony_ci screen->image_extension = dri2ImageExtensionTempl; 2393bf215546Sopenharmony_ci if (pscreen->resource_create_with_modifiers) { 2394bf215546Sopenharmony_ci screen->image_extension.createImageWithModifiers = 2395bf215546Sopenharmony_ci dri2_create_image_with_modifiers; 2396bf215546Sopenharmony_ci screen->image_extension.createImageWithModifiers2 = 2397bf215546Sopenharmony_ci dri2_create_image_with_modifiers2; 2398bf215546Sopenharmony_ci } 2399bf215546Sopenharmony_ci 2400bf215546Sopenharmony_ci if (pscreen->get_param(pscreen, PIPE_CAP_NATIVE_FENCE_FD)) { 2401bf215546Sopenharmony_ci screen->image_extension.setInFenceFd = dri2_set_in_fence_fd; 2402bf215546Sopenharmony_ci } 2403bf215546Sopenharmony_ci 2404bf215546Sopenharmony_ci if (pscreen->get_param(pscreen, PIPE_CAP_DMABUF)) { 2405bf215546Sopenharmony_ci uint64_t cap; 2406bf215546Sopenharmony_ci 2407bf215546Sopenharmony_ci if (drmGetCap(screen->sPriv->fd, DRM_CAP_PRIME, &cap) == 0 && 2408bf215546Sopenharmony_ci (cap & DRM_PRIME_CAP_IMPORT)) { 2409bf215546Sopenharmony_ci screen->image_extension.createImageFromFds = dri2_from_fds; 2410bf215546Sopenharmony_ci screen->image_extension.createImageFromFds2 = dri2_from_fds2; 2411bf215546Sopenharmony_ci screen->image_extension.createImageFromDmaBufs = dri2_from_dma_bufs; 2412bf215546Sopenharmony_ci screen->image_extension.createImageFromDmaBufs2 = dri2_from_dma_bufs2; 2413bf215546Sopenharmony_ci screen->image_extension.createImageFromDmaBufs3 = dri2_from_dma_bufs3; 2414bf215546Sopenharmony_ci screen->image_extension.queryDmaBufFormats = 2415bf215546Sopenharmony_ci dri2_query_dma_buf_formats; 2416bf215546Sopenharmony_ci screen->image_extension.queryDmaBufModifiers = 2417bf215546Sopenharmony_ci dri2_query_dma_buf_modifiers; 2418bf215546Sopenharmony_ci if (!is_kms_screen) { 2419bf215546Sopenharmony_ci screen->image_extension.queryDmaBufFormatModifierAttribs = 2420bf215546Sopenharmony_ci dri2_query_dma_buf_format_modifier_attribs; 2421bf215546Sopenharmony_ci } 2422bf215546Sopenharmony_ci } 2423bf215546Sopenharmony_ci } 2424bf215546Sopenharmony_ci *nExt++ = &screen->image_extension.base; 2425bf215546Sopenharmony_ci 2426bf215546Sopenharmony_ci if (!is_kms_screen) { 2427bf215546Sopenharmony_ci screen->buffer_damage_extension = dri2BufferDamageExtensionTempl; 2428bf215546Sopenharmony_ci if (pscreen->set_damage_region) 2429bf215546Sopenharmony_ci screen->buffer_damage_extension.set_damage_region = 2430bf215546Sopenharmony_ci dri2_set_damage_region; 2431bf215546Sopenharmony_ci *nExt++ = &screen->buffer_damage_extension.base; 2432bf215546Sopenharmony_ci 2433bf215546Sopenharmony_ci if (pscreen->get_param(pscreen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY)) { 2434bf215546Sopenharmony_ci *nExt++ = &dri2Robustness.base; 2435bf215546Sopenharmony_ci screen->has_reset_status_query = true; 2436bf215546Sopenharmony_ci } 2437bf215546Sopenharmony_ci } 2438bf215546Sopenharmony_ci 2439bf215546Sopenharmony_ci /* Ensure the extension list didn't overrun its buffer and is still 2440bf215546Sopenharmony_ci * NULL-terminated */ 2441bf215546Sopenharmony_ci assert(nExt - screen->screen_extensions <= 2442bf215546Sopenharmony_ci ARRAY_SIZE(screen->screen_extensions) - 1); 2443bf215546Sopenharmony_ci assert(!*nExt); 2444bf215546Sopenharmony_ci} 2445bf215546Sopenharmony_ci 2446bf215546Sopenharmony_ci/** 2447bf215546Sopenharmony_ci * This is the driver specific part of the createNewScreen entry point. 2448bf215546Sopenharmony_ci * 2449bf215546Sopenharmony_ci * Returns the struct gl_config supported by this driver. 2450bf215546Sopenharmony_ci */ 2451bf215546Sopenharmony_cistatic const __DRIconfig ** 2452bf215546Sopenharmony_cidri2_init_screen(__DRIscreen * sPriv) 2453bf215546Sopenharmony_ci{ 2454bf215546Sopenharmony_ci const __DRIconfig **configs; 2455bf215546Sopenharmony_ci struct dri_screen *screen; 2456bf215546Sopenharmony_ci struct pipe_screen *pscreen = NULL; 2457bf215546Sopenharmony_ci 2458bf215546Sopenharmony_ci screen = CALLOC_STRUCT(dri_screen); 2459bf215546Sopenharmony_ci if (!screen) 2460bf215546Sopenharmony_ci return NULL; 2461bf215546Sopenharmony_ci 2462bf215546Sopenharmony_ci screen->sPriv = sPriv; 2463bf215546Sopenharmony_ci screen->fd = sPriv->fd; 2464bf215546Sopenharmony_ci (void) mtx_init(&screen->opencl_func_mutex, mtx_plain); 2465bf215546Sopenharmony_ci 2466bf215546Sopenharmony_ci sPriv->driverPrivate = (void *)screen; 2467bf215546Sopenharmony_ci 2468bf215546Sopenharmony_ci if (pipe_loader_drm_probe_fd(&screen->dev, screen->fd)) { 2469bf215546Sopenharmony_ci pscreen = pipe_loader_create_screen(screen->dev); 2470bf215546Sopenharmony_ci dri_init_options(screen); 2471bf215546Sopenharmony_ci } 2472bf215546Sopenharmony_ci 2473bf215546Sopenharmony_ci if (!pscreen) 2474bf215546Sopenharmony_ci goto release_pipe; 2475bf215546Sopenharmony_ci 2476bf215546Sopenharmony_ci screen->throttle = pscreen->get_param(pscreen, PIPE_CAP_THROTTLE); 2477bf215546Sopenharmony_ci 2478bf215546Sopenharmony_ci dri2_init_screen_extensions(screen, pscreen, false); 2479bf215546Sopenharmony_ci 2480bf215546Sopenharmony_ci configs = dri_init_screen_helper(screen, pscreen); 2481bf215546Sopenharmony_ci if (!configs) 2482bf215546Sopenharmony_ci goto destroy_screen; 2483bf215546Sopenharmony_ci 2484bf215546Sopenharmony_ci screen->can_share_buffer = true; 2485bf215546Sopenharmony_ci screen->auto_fake_front = dri_with_format(sPriv); 2486bf215546Sopenharmony_ci screen->lookup_egl_image = dri2_lookup_egl_image; 2487bf215546Sopenharmony_ci 2488bf215546Sopenharmony_ci const __DRIimageLookupExtension *loader = sPriv->dri2.image; 2489bf215546Sopenharmony_ci if (loader && 2490bf215546Sopenharmony_ci loader->base.version >= 2 && 2491bf215546Sopenharmony_ci loader->validateEGLImage && 2492bf215546Sopenharmony_ci loader->lookupEGLImageValidated) { 2493bf215546Sopenharmony_ci screen->validate_egl_image = dri2_validate_egl_image; 2494bf215546Sopenharmony_ci screen->lookup_egl_image_validated = dri2_lookup_egl_image_validated; 2495bf215546Sopenharmony_ci } 2496bf215546Sopenharmony_ci 2497bf215546Sopenharmony_ci return configs; 2498bf215546Sopenharmony_ci 2499bf215546Sopenharmony_cidestroy_screen: 2500bf215546Sopenharmony_ci dri_destroy_screen_helper(screen); 2501bf215546Sopenharmony_ci 2502bf215546Sopenharmony_cirelease_pipe: 2503bf215546Sopenharmony_ci if (screen->dev) 2504bf215546Sopenharmony_ci pipe_loader_release(&screen->dev, 1); 2505bf215546Sopenharmony_ci 2506bf215546Sopenharmony_ci FREE(screen); 2507bf215546Sopenharmony_ci return NULL; 2508bf215546Sopenharmony_ci} 2509bf215546Sopenharmony_ci 2510bf215546Sopenharmony_ci/** 2511bf215546Sopenharmony_ci * This is the driver specific part of the createNewScreen entry point. 2512bf215546Sopenharmony_ci * 2513bf215546Sopenharmony_ci * Returns the struct gl_config supported by this driver. 2514bf215546Sopenharmony_ci */ 2515bf215546Sopenharmony_cistatic const __DRIconfig ** 2516bf215546Sopenharmony_cidri_swrast_kms_init_screen(__DRIscreen * sPriv) 2517bf215546Sopenharmony_ci{ 2518bf215546Sopenharmony_ci#if defined(GALLIUM_SOFTPIPE) 2519bf215546Sopenharmony_ci const __DRIconfig **configs; 2520bf215546Sopenharmony_ci struct dri_screen *screen; 2521bf215546Sopenharmony_ci struct pipe_screen *pscreen = NULL; 2522bf215546Sopenharmony_ci 2523bf215546Sopenharmony_ci screen = CALLOC_STRUCT(dri_screen); 2524bf215546Sopenharmony_ci if (!screen) 2525bf215546Sopenharmony_ci return NULL; 2526bf215546Sopenharmony_ci 2527bf215546Sopenharmony_ci screen->sPriv = sPriv; 2528bf215546Sopenharmony_ci screen->fd = sPriv->fd; 2529bf215546Sopenharmony_ci 2530bf215546Sopenharmony_ci sPriv->driverPrivate = (void *)screen; 2531bf215546Sopenharmony_ci 2532bf215546Sopenharmony_ci#ifdef HAVE_DRISW_KMS 2533bf215546Sopenharmony_ci if (pipe_loader_sw_probe_kms(&screen->dev, screen->fd)) { 2534bf215546Sopenharmony_ci pscreen = pipe_loader_create_screen(screen->dev); 2535bf215546Sopenharmony_ci dri_init_options(screen); 2536bf215546Sopenharmony_ci } 2537bf215546Sopenharmony_ci#endif 2538bf215546Sopenharmony_ci 2539bf215546Sopenharmony_ci if (!pscreen) 2540bf215546Sopenharmony_ci goto release_pipe; 2541bf215546Sopenharmony_ci 2542bf215546Sopenharmony_ci dri2_init_screen_extensions(screen, pscreen, true); 2543bf215546Sopenharmony_ci 2544bf215546Sopenharmony_ci configs = dri_init_screen_helper(screen, pscreen); 2545bf215546Sopenharmony_ci if (!configs) 2546bf215546Sopenharmony_ci goto destroy_screen; 2547bf215546Sopenharmony_ci 2548bf215546Sopenharmony_ci screen->can_share_buffer = false; 2549bf215546Sopenharmony_ci screen->auto_fake_front = dri_with_format(sPriv); 2550bf215546Sopenharmony_ci screen->lookup_egl_image = dri2_lookup_egl_image; 2551bf215546Sopenharmony_ci 2552bf215546Sopenharmony_ci const __DRIimageLookupExtension *loader = sPriv->dri2.image; 2553bf215546Sopenharmony_ci if (loader && 2554bf215546Sopenharmony_ci loader->base.version >= 2 && 2555bf215546Sopenharmony_ci loader->validateEGLImage && 2556bf215546Sopenharmony_ci loader->lookupEGLImageValidated) { 2557bf215546Sopenharmony_ci screen->validate_egl_image = dri2_validate_egl_image; 2558bf215546Sopenharmony_ci screen->lookup_egl_image_validated = dri2_lookup_egl_image_validated; 2559bf215546Sopenharmony_ci } 2560bf215546Sopenharmony_ci 2561bf215546Sopenharmony_ci return configs; 2562bf215546Sopenharmony_ci 2563bf215546Sopenharmony_cidestroy_screen: 2564bf215546Sopenharmony_ci dri_destroy_screen_helper(screen); 2565bf215546Sopenharmony_ci 2566bf215546Sopenharmony_cirelease_pipe: 2567bf215546Sopenharmony_ci if (screen->dev) 2568bf215546Sopenharmony_ci pipe_loader_release(&screen->dev, 1); 2569bf215546Sopenharmony_ci 2570bf215546Sopenharmony_ci FREE(screen); 2571bf215546Sopenharmony_ci#endif // GALLIUM_SOFTPIPE 2572bf215546Sopenharmony_ci return NULL; 2573bf215546Sopenharmony_ci} 2574bf215546Sopenharmony_ci 2575bf215546Sopenharmony_cistatic boolean 2576bf215546Sopenharmony_cidri2_create_buffer(__DRIscreen * sPriv, 2577bf215546Sopenharmony_ci __DRIdrawable * dPriv, 2578bf215546Sopenharmony_ci const struct gl_config * visual, boolean isPixmap) 2579bf215546Sopenharmony_ci{ 2580bf215546Sopenharmony_ci struct dri_drawable *drawable = NULL; 2581bf215546Sopenharmony_ci 2582bf215546Sopenharmony_ci if (!dri_create_buffer(sPriv, dPriv, visual, isPixmap)) 2583bf215546Sopenharmony_ci return FALSE; 2584bf215546Sopenharmony_ci 2585bf215546Sopenharmony_ci drawable = dPriv->driverPrivate; 2586bf215546Sopenharmony_ci 2587bf215546Sopenharmony_ci drawable->allocate_textures = dri2_allocate_textures; 2588bf215546Sopenharmony_ci drawable->flush_frontbuffer = dri2_flush_frontbuffer; 2589bf215546Sopenharmony_ci drawable->update_tex_buffer = dri2_update_tex_buffer; 2590bf215546Sopenharmony_ci drawable->flush_swapbuffers = dri2_flush_swapbuffers; 2591bf215546Sopenharmony_ci 2592bf215546Sopenharmony_ci return TRUE; 2593bf215546Sopenharmony_ci} 2594bf215546Sopenharmony_ci 2595bf215546Sopenharmony_ci/** 2596bf215546Sopenharmony_ci * DRI driver virtual function table. 2597bf215546Sopenharmony_ci * 2598bf215546Sopenharmony_ci * DRI versions differ in their implementation of init_screen and swap_buffers. 2599bf215546Sopenharmony_ci */ 2600bf215546Sopenharmony_ciconst struct __DriverAPIRec galliumdrm_driver_api = { 2601bf215546Sopenharmony_ci .InitScreen = dri2_init_screen, 2602bf215546Sopenharmony_ci .DestroyScreen = dri_destroy_screen, 2603bf215546Sopenharmony_ci .CreateBuffer = dri2_create_buffer, 2604bf215546Sopenharmony_ci .DestroyBuffer = dri_destroy_buffer, 2605bf215546Sopenharmony_ci 2606bf215546Sopenharmony_ci .AllocateBuffer = dri2_allocate_buffer, 2607bf215546Sopenharmony_ci .ReleaseBuffer = dri2_release_buffer, 2608bf215546Sopenharmony_ci}; 2609bf215546Sopenharmony_ci 2610bf215546Sopenharmony_cistatic const struct __DRIDriverVtableExtensionRec galliumdrm_vtable = { 2611bf215546Sopenharmony_ci .base = { __DRI_DRIVER_VTABLE, 1 }, 2612bf215546Sopenharmony_ci .vtable = &galliumdrm_driver_api, 2613bf215546Sopenharmony_ci}; 2614bf215546Sopenharmony_ci 2615bf215546Sopenharmony_ci/** 2616bf215546Sopenharmony_ci * DRI driver virtual function table. 2617bf215546Sopenharmony_ci * 2618bf215546Sopenharmony_ci * KMS/DRM version of the DriverAPI above sporting a different InitScreen 2619bf215546Sopenharmony_ci * hook. The latter is used to explicitly initialise the kms_swrast driver 2620bf215546Sopenharmony_ci * rather than selecting the approapriate driver as suggested by the loader. 2621bf215546Sopenharmony_ci */ 2622bf215546Sopenharmony_ciconst struct __DriverAPIRec dri_swrast_kms_driver_api = { 2623bf215546Sopenharmony_ci .InitScreen = dri_swrast_kms_init_screen, 2624bf215546Sopenharmony_ci .DestroyScreen = dri_destroy_screen, 2625bf215546Sopenharmony_ci .CreateBuffer = dri2_create_buffer, 2626bf215546Sopenharmony_ci .DestroyBuffer = dri_destroy_buffer, 2627bf215546Sopenharmony_ci 2628bf215546Sopenharmony_ci .AllocateBuffer = dri2_allocate_buffer, 2629bf215546Sopenharmony_ci .ReleaseBuffer = dri2_release_buffer, 2630bf215546Sopenharmony_ci}; 2631bf215546Sopenharmony_ci 2632bf215546Sopenharmony_ci/* This is the table of extensions that the loader will dlsym() for. */ 2633bf215546Sopenharmony_ciconst __DRIextension *galliumdrm_driver_extensions[] = { 2634bf215546Sopenharmony_ci &driCoreExtension.base, 2635bf215546Sopenharmony_ci &driImageDriverExtension.base, 2636bf215546Sopenharmony_ci &driDRI2Extension.base, 2637bf215546Sopenharmony_ci &gallium_config_options.base, 2638bf215546Sopenharmony_ci &galliumdrm_vtable.base, 2639bf215546Sopenharmony_ci NULL 2640bf215546Sopenharmony_ci}; 2641bf215546Sopenharmony_ci 2642bf215546Sopenharmony_cistatic const struct __DRIDriverVtableExtensionRec dri_swrast_kms_vtable = { 2643bf215546Sopenharmony_ci .base = { __DRI_DRIVER_VTABLE, 1 }, 2644bf215546Sopenharmony_ci .vtable = &dri_swrast_kms_driver_api, 2645bf215546Sopenharmony_ci}; 2646bf215546Sopenharmony_ci 2647bf215546Sopenharmony_ciconst __DRIextension *dri_swrast_kms_driver_extensions[] = { 2648bf215546Sopenharmony_ci &driCoreExtension.base, 2649bf215546Sopenharmony_ci &driImageDriverExtension.base, 2650bf215546Sopenharmony_ci &swkmsDRI2Extension.base, 2651bf215546Sopenharmony_ci &gallium_config_options.base, 2652bf215546Sopenharmony_ci &dri_swrast_kms_vtable.base, 2653bf215546Sopenharmony_ci NULL 2654bf215546Sopenharmony_ci}; 2655bf215546Sopenharmony_ci 2656bf215546Sopenharmony_ci/* vim: set sw=3 ts=8 sts=3 expandtab: */ 2657