1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2020 Red Hat, Inc. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "util/format/u_format.h" 25bf215546Sopenharmony_ci#include "util/u_memory.h" 26bf215546Sopenharmony_ci#include "util/u_inlines.h" 27bf215546Sopenharmony_ci#include "util/u_box.h" 28bf215546Sopenharmony_ci#include "util/log.h" 29bf215546Sopenharmony_ci#include "pipe/p_context.h" 30bf215546Sopenharmony_ci#include "pipe-loader/pipe_loader.h" 31bf215546Sopenharmony_ci#include "state_tracker/st_context.h" 32bf215546Sopenharmony_ci#include "os/os_process.h" 33bf215546Sopenharmony_ci#include "zink/zink_public.h" 34bf215546Sopenharmony_ci#include "zink/zink_kopper.h" 35bf215546Sopenharmony_ci#include "driver_trace/tr_screen.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "dri_screen.h" 38bf215546Sopenharmony_ci#include "dri_context.h" 39bf215546Sopenharmony_ci#include "dri_drawable.h" 40bf215546Sopenharmony_ci#include "dri_helpers.h" 41bf215546Sopenharmony_ci#include "dri_query_renderer.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#include <vulkan/vulkan.h> 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_XCB_KHR 46bf215546Sopenharmony_ci#include <xcb/xcb.h> 47bf215546Sopenharmony_ci#include <xcb/dri3.h> 48bf215546Sopenharmony_ci#include <xcb/present.h> 49bf215546Sopenharmony_ci#include <xcb/xfixes.h> 50bf215546Sopenharmony_ci#include "util/libsync.h" 51bf215546Sopenharmony_ci#include <X11/Xlib-xcb.h> 52bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 53bf215546Sopenharmony_ci#endif 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_cistruct kopper_drawable { 56bf215546Sopenharmony_ci struct dri_drawable base; 57bf215546Sopenharmony_ci struct kopper_loader_info info; 58bf215546Sopenharmony_ci __DRIimage *image; //texture_from_pixmap 59bf215546Sopenharmony_ci bool is_window; 60bf215546Sopenharmony_ci}; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_cistruct kopper_screen { 63bf215546Sopenharmony_ci struct dri_screen base; 64bf215546Sopenharmony_ci struct pipe_screen *screen; //unwrapped 65bf215546Sopenharmony_ci bool has_dmabuf; 66bf215546Sopenharmony_ci bool has_modifiers; 67bf215546Sopenharmony_ci bool is_sw; 68bf215546Sopenharmony_ci}; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ciextern const __DRIimageExtension driVkImageExtension; 71bf215546Sopenharmony_ciextern const __DRIimageExtension driVkImageExtensionSw; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_cistatic void 74bf215546Sopenharmony_cikopper_flush_drawable(__DRIdrawable *dPriv) 75bf215546Sopenharmony_ci{ 76bf215546Sopenharmony_ci dri_flush(dPriv->driContextPriv, dPriv, __DRI2_FLUSH_DRAWABLE, -1); 77bf215546Sopenharmony_ci} 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_cistatic inline void 80bf215546Sopenharmony_cikopper_invalidate_drawable(__DRIdrawable *dPriv) 81bf215546Sopenharmony_ci{ 82bf215546Sopenharmony_ci struct dri_drawable *drawable = dri_drawable(dPriv); 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci drawable->texture_stamp = dPriv->lastStamp - 1; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci p_atomic_inc(&drawable->base.stamp); 87bf215546Sopenharmony_ci} 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_cistatic const __DRI2flushExtension driVkFlushExtension = { 90bf215546Sopenharmony_ci .base = { __DRI2_FLUSH, 4 }, 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci .flush = kopper_flush_drawable, 93bf215546Sopenharmony_ci .invalidate = kopper_invalidate_drawable, 94bf215546Sopenharmony_ci .flush_with_flags = dri_flush, 95bf215546Sopenharmony_ci}; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_cistatic const __DRIrobustnessExtension dri2Robustness = { 98bf215546Sopenharmony_ci .base = { __DRI2_ROBUSTNESS, 1 } 99bf215546Sopenharmony_ci}; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ciconst __DRIkopperExtension driKopperExtension; 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_cistatic const __DRIextension *drivk_screen_extensions[] = { 104bf215546Sopenharmony_ci &driTexBufferExtension.base, 105bf215546Sopenharmony_ci &dri2RendererQueryExtension.base, 106bf215546Sopenharmony_ci &dri2ConfigQueryExtension.base, 107bf215546Sopenharmony_ci &dri2FenceExtension.base, 108bf215546Sopenharmony_ci &dri2Robustness.base, 109bf215546Sopenharmony_ci &driVkImageExtension.base, 110bf215546Sopenharmony_ci &dri2FlushControlExtension.base, 111bf215546Sopenharmony_ci &driVkFlushExtension.base, 112bf215546Sopenharmony_ci &driKopperExtension.base, 113bf215546Sopenharmony_ci NULL 114bf215546Sopenharmony_ci}; 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_cistatic const __DRIextension *drivk_sw_screen_extensions[] = { 117bf215546Sopenharmony_ci &driTexBufferExtension.base, 118bf215546Sopenharmony_ci &dri2RendererQueryExtension.base, 119bf215546Sopenharmony_ci &dri2ConfigQueryExtension.base, 120bf215546Sopenharmony_ci &dri2FenceExtension.base, 121bf215546Sopenharmony_ci &dri2Robustness.base, 122bf215546Sopenharmony_ci &driVkImageExtensionSw.base, 123bf215546Sopenharmony_ci &dri2FlushControlExtension.base, 124bf215546Sopenharmony_ci &driVkFlushExtension.base, 125bf215546Sopenharmony_ci NULL 126bf215546Sopenharmony_ci}; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_cistatic const __DRIconfig ** 129bf215546Sopenharmony_cikopper_init_screen(__DRIscreen * sPriv) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci const __DRIconfig **configs; 132bf215546Sopenharmony_ci struct dri_screen *screen; 133bf215546Sopenharmony_ci struct kopper_screen *kscreen; 134bf215546Sopenharmony_ci struct pipe_screen *pscreen = NULL; 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci if (!sPriv->kopper_loader) { 137bf215546Sopenharmony_ci fprintf(stderr, "mesa: Kopper interface not found!\n" 138bf215546Sopenharmony_ci " Ensure the versions of %s built with this version of Zink are\n" 139bf215546Sopenharmony_ci " in your library path!\n", KOPPER_LIB_NAMES); 140bf215546Sopenharmony_ci return NULL; 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci kscreen = CALLOC_STRUCT(kopper_screen); 143bf215546Sopenharmony_ci if (!kscreen) 144bf215546Sopenharmony_ci return NULL; 145bf215546Sopenharmony_ci screen = &kscreen->base; 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci screen->sPriv = sPriv; 148bf215546Sopenharmony_ci screen->fd = sPriv->fd; 149bf215546Sopenharmony_ci screen->can_share_buffer = true; 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci sPriv->driverPrivate = (void *)kscreen; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci bool success; 154bf215546Sopenharmony_ci if (screen->fd != -1) 155bf215546Sopenharmony_ci success = pipe_loader_drm_probe_fd(&screen->dev, screen->fd); 156bf215546Sopenharmony_ci else 157bf215546Sopenharmony_ci success = pipe_loader_vk_probe_dri(&screen->dev, NULL); 158bf215546Sopenharmony_ci if (success) { 159bf215546Sopenharmony_ci pscreen = pipe_loader_create_screen(screen->dev); 160bf215546Sopenharmony_ci dri_init_options(screen); 161bf215546Sopenharmony_ci } 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci if (!pscreen) 164bf215546Sopenharmony_ci goto fail; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci kscreen->screen = trace_screen_unwrap(pscreen); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci configs = dri_init_screen_helper(screen, pscreen); 169bf215546Sopenharmony_ci if (!configs) 170bf215546Sopenharmony_ci goto fail; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci assert(pscreen->get_param(pscreen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY)); 173bf215546Sopenharmony_ci screen->has_reset_status_query = true; 174bf215546Sopenharmony_ci screen->lookup_egl_image = dri2_lookup_egl_image; 175bf215546Sopenharmony_ci kscreen->has_dmabuf = pscreen->get_param(pscreen, PIPE_CAP_DMABUF); 176bf215546Sopenharmony_ci kscreen->has_modifiers = pscreen->query_dmabuf_modifiers != NULL; 177bf215546Sopenharmony_ci kscreen->is_sw = zink_kopper_is_cpu(pscreen); 178bf215546Sopenharmony_ci if (kscreen->has_dmabuf) 179bf215546Sopenharmony_ci sPriv->extensions = drivk_screen_extensions; 180bf215546Sopenharmony_ci else 181bf215546Sopenharmony_ci sPriv->extensions = drivk_sw_screen_extensions; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci const __DRIimageLookupExtension *image = sPriv->dri2.image; 184bf215546Sopenharmony_ci if (image && 185bf215546Sopenharmony_ci image->base.version >= 2 && 186bf215546Sopenharmony_ci image->validateEGLImage && 187bf215546Sopenharmony_ci image->lookupEGLImageValidated) { 188bf215546Sopenharmony_ci screen->validate_egl_image = dri2_validate_egl_image; 189bf215546Sopenharmony_ci screen->lookup_egl_image_validated = dri2_lookup_egl_image_validated; 190bf215546Sopenharmony_ci } 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci return configs; 193bf215546Sopenharmony_cifail: 194bf215546Sopenharmony_ci dri_destroy_screen_helper(screen); 195bf215546Sopenharmony_ci if (screen->dev) 196bf215546Sopenharmony_ci pipe_loader_release(&screen->dev, 1); 197bf215546Sopenharmony_ci FREE(screen); 198bf215546Sopenharmony_ci return NULL; 199bf215546Sopenharmony_ci} 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci// copypasta alert 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_cistatic inline void 204bf215546Sopenharmony_cidrisw_present_texture(struct pipe_context *pipe, __DRIdrawable *dPriv, 205bf215546Sopenharmony_ci struct pipe_resource *ptex, struct pipe_box *sub_box) 206bf215546Sopenharmony_ci{ 207bf215546Sopenharmony_ci struct dri_drawable *drawable = dri_drawable(dPriv); 208bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(drawable->sPriv); 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci screen->base.screen->flush_frontbuffer(screen->base.screen, pipe, ptex, 0, 0, drawable, sub_box); 211bf215546Sopenharmony_ci} 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ciextern bool 214bf215546Sopenharmony_cidri_image_drawable_get_buffers(struct dri_drawable *drawable, 215bf215546Sopenharmony_ci struct __DRIimageList *images, 216bf215546Sopenharmony_ci const enum st_attachment_type *statts, 217bf215546Sopenharmony_ci unsigned statts_count); 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_XCB_KHR 220bf215546Sopenharmony_cistatic int 221bf215546Sopenharmony_ciget_dri_format(enum pipe_format pf) 222bf215546Sopenharmony_ci{ 223bf215546Sopenharmony_ci int image_format; 224bf215546Sopenharmony_ci switch (pf) { 225bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16A16_FLOAT: 226bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ABGR16161616F; 227bf215546Sopenharmony_ci break; 228bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16X16_FLOAT: 229bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XBGR16161616F; 230bf215546Sopenharmony_ci break; 231bf215546Sopenharmony_ci case PIPE_FORMAT_B5G5R5A1_UNORM: 232bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ARGB1555; 233bf215546Sopenharmony_ci break; 234bf215546Sopenharmony_ci case PIPE_FORMAT_B5G6R5_UNORM: 235bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_RGB565; 236bf215546Sopenharmony_ci break; 237bf215546Sopenharmony_ci case PIPE_FORMAT_BGRX8888_UNORM: 238bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XRGB8888; 239bf215546Sopenharmony_ci break; 240bf215546Sopenharmony_ci case PIPE_FORMAT_BGRA8888_UNORM: 241bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ARGB8888; 242bf215546Sopenharmony_ci break; 243bf215546Sopenharmony_ci case PIPE_FORMAT_RGBX8888_UNORM: 244bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XBGR8888; 245bf215546Sopenharmony_ci break; 246bf215546Sopenharmony_ci case PIPE_FORMAT_RGBA8888_UNORM: 247bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ABGR8888; 248bf215546Sopenharmony_ci break; 249bf215546Sopenharmony_ci case PIPE_FORMAT_B10G10R10X2_UNORM: 250bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XRGB2101010; 251bf215546Sopenharmony_ci break; 252bf215546Sopenharmony_ci case PIPE_FORMAT_B10G10R10A2_UNORM: 253bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ARGB2101010; 254bf215546Sopenharmony_ci break; 255bf215546Sopenharmony_ci case PIPE_FORMAT_R10G10B10X2_UNORM: 256bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_XBGR2101010; 257bf215546Sopenharmony_ci break; 258bf215546Sopenharmony_ci case PIPE_FORMAT_R10G10B10A2_UNORM: 259bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_ABGR2101010; 260bf215546Sopenharmony_ci break; 261bf215546Sopenharmony_ci default: 262bf215546Sopenharmony_ci image_format = __DRI_IMAGE_FORMAT_NONE; 263bf215546Sopenharmony_ci break; 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci return image_format; 266bf215546Sopenharmony_ci} 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci/* the DRIimage createImage function takes __DRI_IMAGE_FORMAT codes, while 269bf215546Sopenharmony_ci * the createImageFromFds call takes DRM_FORMAT codes. To avoid 270bf215546Sopenharmony_ci * complete confusion, just deal in __DRI_IMAGE_FORMAT codes for now and 271bf215546Sopenharmony_ci * translate to DRM_FORMAT codes in the call to createImageFromFds 272bf215546Sopenharmony_ci */ 273bf215546Sopenharmony_cistatic int 274bf215546Sopenharmony_ciimage_format_to_fourcc(int format) 275bf215546Sopenharmony_ci{ 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci /* Convert from __DRI_IMAGE_FORMAT to DRM_FORMAT (sigh) */ 278bf215546Sopenharmony_ci switch (format) { 279bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_SARGB8: return __DRI_IMAGE_FOURCC_SARGB8888; 280bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_SABGR8: return __DRI_IMAGE_FOURCC_SABGR8888; 281bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_SXRGB8: return __DRI_IMAGE_FOURCC_SXRGB8888; 282bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_RGB565: return DRM_FORMAT_RGB565; 283bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_XRGB8888: return DRM_FORMAT_XRGB8888; 284bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_ARGB8888: return DRM_FORMAT_ARGB8888; 285bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_ABGR8888: return DRM_FORMAT_ABGR8888; 286bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_XBGR8888: return DRM_FORMAT_XBGR8888; 287bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_XRGB2101010: return DRM_FORMAT_XRGB2101010; 288bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_ARGB2101010: return DRM_FORMAT_ARGB2101010; 289bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_XBGR2101010: return DRM_FORMAT_XBGR2101010; 290bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_ABGR2101010: return DRM_FORMAT_ABGR2101010; 291bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_XBGR16161616F: return DRM_FORMAT_XBGR16161616F; 292bf215546Sopenharmony_ci case __DRI_IMAGE_FORMAT_ABGR16161616F: return DRM_FORMAT_ABGR16161616F; 293bf215546Sopenharmony_ci } 294bf215546Sopenharmony_ci return 0; 295bf215546Sopenharmony_ci} 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci#ifdef HAVE_DRI3_MODIFIERS 298bf215546Sopenharmony_cistatic __DRIimage * 299bf215546Sopenharmony_cidri3_create_image_from_buffers(xcb_connection_t *c, 300bf215546Sopenharmony_ci xcb_dri3_buffers_from_pixmap_reply_t *bp_reply, 301bf215546Sopenharmony_ci unsigned int format, 302bf215546Sopenharmony_ci __DRIscreen *dri_screen, 303bf215546Sopenharmony_ci const __DRIimageExtension *image, 304bf215546Sopenharmony_ci void *loaderPrivate) 305bf215546Sopenharmony_ci{ 306bf215546Sopenharmony_ci __DRIimage *ret; 307bf215546Sopenharmony_ci int *fds; 308bf215546Sopenharmony_ci uint32_t *strides_in, *offsets_in; 309bf215546Sopenharmony_ci int strides[4], offsets[4]; 310bf215546Sopenharmony_ci unsigned error; 311bf215546Sopenharmony_ci int i; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci if (bp_reply->nfd > 4) 314bf215546Sopenharmony_ci return NULL; 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci fds = xcb_dri3_buffers_from_pixmap_reply_fds(c, bp_reply); 317bf215546Sopenharmony_ci strides_in = xcb_dri3_buffers_from_pixmap_strides(bp_reply); 318bf215546Sopenharmony_ci offsets_in = xcb_dri3_buffers_from_pixmap_offsets(bp_reply); 319bf215546Sopenharmony_ci for (i = 0; i < bp_reply->nfd; i++) { 320bf215546Sopenharmony_ci strides[i] = strides_in[i]; 321bf215546Sopenharmony_ci offsets[i] = offsets_in[i]; 322bf215546Sopenharmony_ci } 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci ret = image->createImageFromDmaBufs2(dri_screen, 325bf215546Sopenharmony_ci bp_reply->width, 326bf215546Sopenharmony_ci bp_reply->height, 327bf215546Sopenharmony_ci image_format_to_fourcc(format), 328bf215546Sopenharmony_ci bp_reply->modifier, 329bf215546Sopenharmony_ci fds, bp_reply->nfd, 330bf215546Sopenharmony_ci strides, offsets, 331bf215546Sopenharmony_ci 0, 0, 0, 0, /* UNDEFINED */ 332bf215546Sopenharmony_ci &error, loaderPrivate); 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci for (i = 0; i < bp_reply->nfd; i++) 335bf215546Sopenharmony_ci close(fds[i]); 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci return ret; 338bf215546Sopenharmony_ci} 339bf215546Sopenharmony_ci#endif 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_cistatic __DRIimage * 342bf215546Sopenharmony_cidri3_create_image(xcb_connection_t *c, 343bf215546Sopenharmony_ci xcb_dri3_buffer_from_pixmap_reply_t *bp_reply, 344bf215546Sopenharmony_ci unsigned int format, 345bf215546Sopenharmony_ci __DRIscreen *dri_screen, 346bf215546Sopenharmony_ci const __DRIimageExtension *image, 347bf215546Sopenharmony_ci void *loaderPrivate) 348bf215546Sopenharmony_ci{ 349bf215546Sopenharmony_ci int *fds; 350bf215546Sopenharmony_ci __DRIimage *image_planar, *ret; 351bf215546Sopenharmony_ci int stride, offset; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci /* Get an FD for the pixmap object 354bf215546Sopenharmony_ci */ 355bf215546Sopenharmony_ci fds = xcb_dri3_buffer_from_pixmap_reply_fds(c, bp_reply); 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci stride = bp_reply->stride; 358bf215546Sopenharmony_ci offset = 0; 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci /* createImageFromFds creates a wrapper __DRIimage structure which 361bf215546Sopenharmony_ci * can deal with multiple planes for things like Yuv images. So, once 362bf215546Sopenharmony_ci * we've gotten the planar wrapper, pull the single plane out of it and 363bf215546Sopenharmony_ci * discard the wrapper. 364bf215546Sopenharmony_ci */ 365bf215546Sopenharmony_ci image_planar = image->createImageFromFds(dri_screen, 366bf215546Sopenharmony_ci bp_reply->width, 367bf215546Sopenharmony_ci bp_reply->height, 368bf215546Sopenharmony_ci image_format_to_fourcc(format), 369bf215546Sopenharmony_ci fds, 1, 370bf215546Sopenharmony_ci &stride, &offset, loaderPrivate); 371bf215546Sopenharmony_ci close(fds[0]); 372bf215546Sopenharmony_ci if (!image_planar) 373bf215546Sopenharmony_ci return NULL; 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci ret = image->fromPlanar(image_planar, 0, loaderPrivate); 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci if (!ret) 378bf215546Sopenharmony_ci ret = image_planar; 379bf215546Sopenharmony_ci else 380bf215546Sopenharmony_ci image->destroyImage(image_planar); 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci return ret; 383bf215546Sopenharmony_ci} 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_cistatic void 387bf215546Sopenharmony_cihandle_in_fence(__DRIcontext *context, __DRIimage *img) 388bf215546Sopenharmony_ci{ 389bf215546Sopenharmony_ci struct dri_context *ctx = dri_context(context); 390bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->st->pipe; 391bf215546Sopenharmony_ci struct pipe_fence_handle *fence; 392bf215546Sopenharmony_ci int fd = img->in_fence_fd; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci if (fd == -1) 395bf215546Sopenharmony_ci return; 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci validate_fence_fd(fd); 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci img->in_fence_fd = -1; 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci pipe->create_fence_fd(pipe, &fence, fd, PIPE_FD_TYPE_NATIVE_SYNC); 402bf215546Sopenharmony_ci pipe->fence_server_sync(pipe, fence); 403bf215546Sopenharmony_ci pipe->screen->fence_reference(pipe->screen, &fence, NULL); 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci close(fd); 406bf215546Sopenharmony_ci} 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci/** kopper_get_pixmap_buffer 409bf215546Sopenharmony_ci * 410bf215546Sopenharmony_ci * Get the DRM object for a pixmap from the X server and 411bf215546Sopenharmony_ci * wrap that with a __DRIimage structure using createImageFromFds 412bf215546Sopenharmony_ci */ 413bf215546Sopenharmony_cistatic struct pipe_resource * 414bf215546Sopenharmony_cikopper_get_pixmap_buffer(struct kopper_drawable *cdraw, 415bf215546Sopenharmony_ci enum pipe_format pf) 416bf215546Sopenharmony_ci{ 417bf215546Sopenharmony_ci xcb_drawable_t pixmap; 418bf215546Sopenharmony_ci int width; 419bf215546Sopenharmony_ci int height; 420bf215546Sopenharmony_ci int format = get_dri_format(pf); 421bf215546Sopenharmony_ci __DRIscreen *cur_screen; 422bf215546Sopenharmony_ci struct kopper_loader_info *info = &cdraw->info; 423bf215546Sopenharmony_ci assert(info->bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR); 424bf215546Sopenharmony_ci xcb_connection_t *conn = info->xcb.connection; 425bf215546Sopenharmony_ci pixmap = info->xcb.window; 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci if (cdraw->image) 428bf215546Sopenharmony_ci return cdraw->image->texture; 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci /* FIXME: probably broken for OBS studio? 431bf215546Sopenharmony_ci * see dri3_get_pixmap_buffer() 432bf215546Sopenharmony_ci */ 433bf215546Sopenharmony_ci cur_screen = cdraw->base.sPriv; 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci#ifdef HAVE_DRI3_MODIFIERS 436bf215546Sopenharmony_ci struct kopper_screen *kscreen = (struct kopper_screen*)cur_screen->driverPrivate; 437bf215546Sopenharmony_ci if (kscreen->has_modifiers) { 438bf215546Sopenharmony_ci xcb_dri3_buffers_from_pixmap_cookie_t bps_cookie; 439bf215546Sopenharmony_ci xcb_dri3_buffers_from_pixmap_reply_t *bps_reply; 440bf215546Sopenharmony_ci xcb_generic_error_t *error; 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ci bps_cookie = xcb_dri3_buffers_from_pixmap(conn, pixmap); 443bf215546Sopenharmony_ci bps_reply = xcb_dri3_buffers_from_pixmap_reply(conn, bps_cookie, &error); 444bf215546Sopenharmony_ci if (!bps_reply) { 445bf215546Sopenharmony_ci mesa_loge("kopper: could not create texture from pixmap (%u)", error->error_code); 446bf215546Sopenharmony_ci return NULL; 447bf215546Sopenharmony_ci } 448bf215546Sopenharmony_ci cdraw->image = 449bf215546Sopenharmony_ci dri3_create_image_from_buffers(conn, bps_reply, format, 450bf215546Sopenharmony_ci cur_screen, &driVkImageExtension, 451bf215546Sopenharmony_ci cdraw); 452bf215546Sopenharmony_ci width = bps_reply->width; 453bf215546Sopenharmony_ci height = bps_reply->height; 454bf215546Sopenharmony_ci free(bps_reply); 455bf215546Sopenharmony_ci } else 456bf215546Sopenharmony_ci#endif 457bf215546Sopenharmony_ci { 458bf215546Sopenharmony_ci xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie; 459bf215546Sopenharmony_ci xcb_dri3_buffer_from_pixmap_reply_t *bp_reply; 460bf215546Sopenharmony_ci xcb_generic_error_t *error; 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci bp_cookie = xcb_dri3_buffer_from_pixmap(conn, pixmap); 463bf215546Sopenharmony_ci bp_reply = xcb_dri3_buffer_from_pixmap_reply(conn, bp_cookie, &error); 464bf215546Sopenharmony_ci if (!bp_reply) { 465bf215546Sopenharmony_ci mesa_loge("kopper: could not create texture from pixmap (%u)", error->error_code); 466bf215546Sopenharmony_ci return NULL; 467bf215546Sopenharmony_ci } 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci cdraw->image = dri3_create_image(conn, bp_reply, format, 470bf215546Sopenharmony_ci cur_screen, &driVkImageExtension, 471bf215546Sopenharmony_ci cdraw); 472bf215546Sopenharmony_ci width = bp_reply->width; 473bf215546Sopenharmony_ci height = bp_reply->height; 474bf215546Sopenharmony_ci free(bp_reply); 475bf215546Sopenharmony_ci } 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci cdraw->base.dPriv->w = width; 478bf215546Sopenharmony_ci cdraw->base.dPriv->h = height; 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci return cdraw->image->texture; 481bf215546Sopenharmony_ci} 482bf215546Sopenharmony_ci#endif //VK_USE_PLATFORM_XCB_KHR 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_cistatic void 485bf215546Sopenharmony_cikopper_allocate_textures(struct dri_context *ctx, 486bf215546Sopenharmony_ci struct dri_drawable *drawable, 487bf215546Sopenharmony_ci const enum st_attachment_type *statts, 488bf215546Sopenharmony_ci unsigned statts_count) 489bf215546Sopenharmony_ci{ 490bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(drawable->sPriv); 491bf215546Sopenharmony_ci struct pipe_resource templ; 492bf215546Sopenharmony_ci unsigned width, height; 493bf215546Sopenharmony_ci boolean resized; 494bf215546Sopenharmony_ci unsigned i; 495bf215546Sopenharmony_ci struct __DRIimageList images; 496bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = drawable->dPriv; 497bf215546Sopenharmony_ci const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader; 498bf215546Sopenharmony_ci struct kopper_drawable *cdraw = (struct kopper_drawable *)drawable; 499bf215546Sopenharmony_ci struct kopper_screen *kscreen = (struct kopper_screen*)drawable->sPriv->driverPrivate; 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci bool is_window = cdraw->is_window; 502bf215546Sopenharmony_ci bool is_pixmap = !is_window && cdraw->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci width = drawable->dPriv->w; 505bf215546Sopenharmony_ci height = drawable->dPriv->h; 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci resized = (drawable->old_w != width || 508bf215546Sopenharmony_ci drawable->old_h != height); 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci /* First get the buffers from the loader */ 511bf215546Sopenharmony_ci if (image) { 512bf215546Sopenharmony_ci if (!dri_image_drawable_get_buffers(drawable, &images, 513bf215546Sopenharmony_ci statts, statts_count)) 514bf215546Sopenharmony_ci return; 515bf215546Sopenharmony_ci } 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci if (image) { 518bf215546Sopenharmony_ci if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) { 519bf215546Sopenharmony_ci struct pipe_resource **buf = 520bf215546Sopenharmony_ci &drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; 521bf215546Sopenharmony_ci struct pipe_resource *texture = images.front->texture; 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci dri_drawable->w = texture->width0; 524bf215546Sopenharmony_ci dri_drawable->h = texture->height0; 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci pipe_resource_reference(buf, texture); 527bf215546Sopenharmony_ci } 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) { 530bf215546Sopenharmony_ci struct pipe_resource **buf = 531bf215546Sopenharmony_ci &drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 532bf215546Sopenharmony_ci struct pipe_resource *texture = images.back->texture; 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci dri_drawable->w = texture->width0; 535bf215546Sopenharmony_ci dri_drawable->h = texture->height0; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci pipe_resource_reference(buf, texture); 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) { 541bf215546Sopenharmony_ci struct pipe_resource **buf = 542bf215546Sopenharmony_ci &drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 543bf215546Sopenharmony_ci struct pipe_resource *texture = images.back->texture; 544bf215546Sopenharmony_ci 545bf215546Sopenharmony_ci dri_drawable->w = texture->width0; 546bf215546Sopenharmony_ci dri_drawable->h = texture->height0; 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci pipe_resource_reference(buf, texture); 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci ctx->is_shared_buffer_bound = true; 551bf215546Sopenharmony_ci } else { 552bf215546Sopenharmony_ci ctx->is_shared_buffer_bound = false; 553bf215546Sopenharmony_ci } 554bf215546Sopenharmony_ci } else { 555bf215546Sopenharmony_ci /* remove outdated textures */ 556bf215546Sopenharmony_ci if (resized) { 557bf215546Sopenharmony_ci for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { 558bf215546Sopenharmony_ci if (drawable->textures[i] && i < ST_ATTACHMENT_DEPTH_STENCIL && !is_pixmap) { 559bf215546Sopenharmony_ci drawable->textures[i]->width0 = width; 560bf215546Sopenharmony_ci drawable->textures[i]->height0 = height; 561bf215546Sopenharmony_ci /* force all contexts to revalidate framebuffer */ 562bf215546Sopenharmony_ci p_atomic_inc(&drawable->base.stamp); 563bf215546Sopenharmony_ci } else 564bf215546Sopenharmony_ci pipe_resource_reference(&drawable->textures[i], NULL); 565bf215546Sopenharmony_ci pipe_resource_reference(&drawable->msaa_textures[i], NULL); 566bf215546Sopenharmony_ci if (is_pixmap && i == ST_ATTACHMENT_FRONT_LEFT) { 567bf215546Sopenharmony_ci FREE(cdraw->image); 568bf215546Sopenharmony_ci cdraw->image = NULL; 569bf215546Sopenharmony_ci } 570bf215546Sopenharmony_ci } 571bf215546Sopenharmony_ci } 572bf215546Sopenharmony_ci } 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci drawable->old_w = width; 575bf215546Sopenharmony_ci drawable->old_h = height; 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_ci memset(&templ, 0, sizeof(templ)); 578bf215546Sopenharmony_ci templ.target = screen->target; 579bf215546Sopenharmony_ci templ.width0 = width; 580bf215546Sopenharmony_ci templ.height0 = height; 581bf215546Sopenharmony_ci templ.depth0 = 1; 582bf215546Sopenharmony_ci templ.array_size = 1; 583bf215546Sopenharmony_ci templ.last_level = 0; 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci#if 0 586bf215546Sopenharmony_ciXXX do this once swapinterval is hooked up 587bf215546Sopenharmony_ci /* pixmaps always have front buffers. 588bf215546Sopenharmony_ci * Exchange swaps also mandate fake front buffers. 589bf215546Sopenharmony_ci */ 590bf215546Sopenharmony_ci if (draw->type != LOADER_DRI3_DRAWABLE_WINDOW || 591bf215546Sopenharmony_ci draw->swap_method == __DRI_ATTRIB_SWAP_EXCHANGE) 592bf215546Sopenharmony_ci buffer_mask |= __DRI_IMAGE_BUFFER_FRONT; 593bf215546Sopenharmony_ci#endif 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci uint32_t attachments = 0; 596bf215546Sopenharmony_ci for (i = 0; i < statts_count; i++) 597bf215546Sopenharmony_ci attachments |= BITFIELD_BIT(statts[i]); 598bf215546Sopenharmony_ci bool front_only = attachments & ST_ATTACHMENT_FRONT_LEFT_MASK && !(attachments & ST_ATTACHMENT_BACK_LEFT_MASK); 599bf215546Sopenharmony_ci 600bf215546Sopenharmony_ci for (i = 0; i < statts_count; i++) { 601bf215546Sopenharmony_ci enum pipe_format format; 602bf215546Sopenharmony_ci unsigned bind; 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci dri_drawable_get_format(drawable, statts[i], &format, &bind); 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci /* the texture already exists or not requested */ 607bf215546Sopenharmony_ci if (!drawable->textures[statts[i]]) { 608bf215546Sopenharmony_ci if (statts[i] == ST_ATTACHMENT_BACK_LEFT || 609bf215546Sopenharmony_ci statts[i] == ST_ATTACHMENT_DEPTH_STENCIL || 610bf215546Sopenharmony_ci (statts[i] == ST_ATTACHMENT_FRONT_LEFT && front_only)) 611bf215546Sopenharmony_ci bind |= PIPE_BIND_DISPLAY_TARGET; 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci if (format == PIPE_FORMAT_NONE) 614bf215546Sopenharmony_ci continue; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci templ.format = format; 617bf215546Sopenharmony_ci templ.bind = bind; 618bf215546Sopenharmony_ci templ.nr_samples = 0; 619bf215546Sopenharmony_ci templ.nr_storage_samples = 0; 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci if (statts[i] < ST_ATTACHMENT_DEPTH_STENCIL && is_window) { 622bf215546Sopenharmony_ci void *data; 623bf215546Sopenharmony_ci if (statts[i] == ST_ATTACHMENT_BACK_LEFT || (statts[i] == ST_ATTACHMENT_FRONT_LEFT && front_only)) 624bf215546Sopenharmony_ci data = &cdraw->info; 625bf215546Sopenharmony_ci else 626bf215546Sopenharmony_ci data = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 627bf215546Sopenharmony_ci assert(data); 628bf215546Sopenharmony_ci drawable->textures[statts[i]] = 629bf215546Sopenharmony_ci screen->base.screen->resource_create_drawable(screen->base.screen, &templ, data); 630bf215546Sopenharmony_ci } 631bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_XCB_KHR 632bf215546Sopenharmony_ci else if (is_pixmap && statts[i] == ST_ATTACHMENT_FRONT_LEFT && !kscreen->is_sw) { 633bf215546Sopenharmony_ci drawable->textures[statts[i]] = kopper_get_pixmap_buffer(cdraw, format); 634bf215546Sopenharmony_ci handle_in_fence(ctx->cPriv, cdraw->image); 635bf215546Sopenharmony_ci } 636bf215546Sopenharmony_ci#endif 637bf215546Sopenharmony_ci else { 638bf215546Sopenharmony_ci drawable->textures[statts[i]] = 639bf215546Sopenharmony_ci screen->base.screen->resource_create(screen->base.screen, &templ); 640bf215546Sopenharmony_ci } 641bf215546Sopenharmony_ci } 642bf215546Sopenharmony_ci if (drawable->stvis.samples > 1 && !drawable->msaa_textures[statts[i]]) { 643bf215546Sopenharmony_ci templ.bind = templ.bind & 644bf215546Sopenharmony_ci ~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_DISPLAY_TARGET); 645bf215546Sopenharmony_ci templ.nr_samples = drawable->stvis.samples; 646bf215546Sopenharmony_ci templ.nr_storage_samples = drawable->stvis.samples; 647bf215546Sopenharmony_ci drawable->msaa_textures[statts[i]] = 648bf215546Sopenharmony_ci screen->base.screen->resource_create(screen->base.screen, &templ); 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ci dri_pipe_blit(ctx->st->pipe, 651bf215546Sopenharmony_ci drawable->msaa_textures[statts[i]], 652bf215546Sopenharmony_ci drawable->textures[statts[i]]); 653bf215546Sopenharmony_ci } 654bf215546Sopenharmony_ci } 655bf215546Sopenharmony_ci} 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_cistatic inline void 658bf215546Sopenharmony_ciget_drawable_info(__DRIdrawable *dPriv, int *x, int *y, int *w, int *h) 659bf215546Sopenharmony_ci{ 660bf215546Sopenharmony_ci __DRIscreen *sPriv = dPriv->driScreenPriv; 661bf215546Sopenharmony_ci const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci if (loader) 664bf215546Sopenharmony_ci loader->getDrawableInfo(dPriv, 665bf215546Sopenharmony_ci x, y, w, h, 666bf215546Sopenharmony_ci dPriv->loaderPrivate); 667bf215546Sopenharmony_ci} 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_cistatic void 670bf215546Sopenharmony_cikopper_update_drawable_info(struct dri_drawable *drawable) 671bf215546Sopenharmony_ci{ 672bf215546Sopenharmony_ci __DRIdrawable *dPriv = drawable->dPriv; 673bf215546Sopenharmony_ci __DRIscreen *sPriv = dPriv->driScreenPriv; 674bf215546Sopenharmony_ci struct kopper_drawable *cdraw = (struct kopper_drawable *)drawable; 675bf215546Sopenharmony_ci bool is_window = cdraw->info.bos.sType != 0; 676bf215546Sopenharmony_ci int x, y; 677bf215546Sopenharmony_ci struct kopper_screen *kscreen = (struct kopper_screen*)sPriv->driverPrivate; 678bf215546Sopenharmony_ci struct pipe_screen *screen = kscreen->screen; 679bf215546Sopenharmony_ci struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ? 680bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_BACK_LEFT] : 681bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci bool do_kopper_update = is_window && ptex && kscreen->base.fd == -1; 684bf215546Sopenharmony_ci if (cdraw->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR && do_kopper_update) 685bf215546Sopenharmony_ci zink_kopper_update(screen, ptex, &dPriv->w, &dPriv->h); 686bf215546Sopenharmony_ci else 687bf215546Sopenharmony_ci get_drawable_info(dPriv, &x, &y, &dPriv->w, &dPriv->h); 688bf215546Sopenharmony_ci} 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_cistatic inline void 691bf215546Sopenharmony_cikopper_present_texture(struct pipe_context *pipe, __DRIdrawable *dPriv, 692bf215546Sopenharmony_ci struct pipe_resource *ptex, struct pipe_box *sub_box) 693bf215546Sopenharmony_ci{ 694bf215546Sopenharmony_ci struct dri_drawable *drawable = dri_drawable(dPriv); 695bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(drawable->sPriv); 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_ci screen->base.screen->flush_frontbuffer(screen->base.screen, pipe, ptex, 0, 0, drawable, sub_box); 698bf215546Sopenharmony_ci} 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_cistatic inline void 701bf215546Sopenharmony_cikopper_copy_to_front(struct pipe_context *pipe, 702bf215546Sopenharmony_ci __DRIdrawable * dPriv, 703bf215546Sopenharmony_ci struct pipe_resource *ptex) 704bf215546Sopenharmony_ci{ 705bf215546Sopenharmony_ci kopper_present_texture(pipe, dPriv, ptex, NULL); 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci kopper_invalidate_drawable(dPriv); 708bf215546Sopenharmony_ci} 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_cistatic bool 711bf215546Sopenharmony_cikopper_flush_frontbuffer(struct dri_context *ctx, 712bf215546Sopenharmony_ci struct dri_drawable *drawable, 713bf215546Sopenharmony_ci enum st_attachment_type statt) 714bf215546Sopenharmony_ci{ 715bf215546Sopenharmony_ci struct pipe_resource *ptex; 716bf215546Sopenharmony_ci 717bf215546Sopenharmony_ci if (!ctx || statt != ST_ATTACHMENT_FRONT_LEFT) 718bf215546Sopenharmony_ci return false; 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci if (drawable) { 721bf215546Sopenharmony_ci /* prevent recursion */ 722bf215546Sopenharmony_ci if (drawable->flushing) 723bf215546Sopenharmony_ci return true; 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci drawable->flushing = true; 726bf215546Sopenharmony_ci } 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ci if (drawable->stvis.samples > 1) { 729bf215546Sopenharmony_ci /* Resolve the front buffer. */ 730bf215546Sopenharmony_ci dri_pipe_blit(ctx->st->pipe, 731bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_FRONT_LEFT], 732bf215546Sopenharmony_ci drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]); 733bf215546Sopenharmony_ci } 734bf215546Sopenharmony_ci ptex = drawable->textures[statt]; 735bf215546Sopenharmony_ci 736bf215546Sopenharmony_ci if (ptex) { 737bf215546Sopenharmony_ci ctx->st->pipe->flush_resource(ctx->st->pipe, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]); 738bf215546Sopenharmony_ci struct pipe_screen *screen = drawable->screen->base.screen; 739bf215546Sopenharmony_ci struct st_context_iface *st; 740bf215546Sopenharmony_ci struct pipe_fence_handle *new_fence = NULL; 741bf215546Sopenharmony_ci st = ctx->st; 742bf215546Sopenharmony_ci if (st->thread_finish) 743bf215546Sopenharmony_ci st->thread_finish(st); 744bf215546Sopenharmony_ci 745bf215546Sopenharmony_ci st->flush(st, ST_FLUSH_FRONT, &new_fence, NULL, NULL); 746bf215546Sopenharmony_ci if (drawable) { 747bf215546Sopenharmony_ci drawable->flushing = false; 748bf215546Sopenharmony_ci } 749bf215546Sopenharmony_ci /* throttle on the previous fence */ 750bf215546Sopenharmony_ci if (drawable->throttle_fence) { 751bf215546Sopenharmony_ci screen->fence_finish(screen, NULL, drawable->throttle_fence, PIPE_TIMEOUT_INFINITE); 752bf215546Sopenharmony_ci screen->fence_reference(screen, &drawable->throttle_fence, NULL); 753bf215546Sopenharmony_ci } 754bf215546Sopenharmony_ci drawable->throttle_fence = new_fence; 755bf215546Sopenharmony_ci kopper_copy_to_front(st->pipe, ctx->dPriv, ptex); 756bf215546Sopenharmony_ci } 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ci return true; 759bf215546Sopenharmony_ci} 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_cistatic inline void 762bf215546Sopenharmony_ciget_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data) 763bf215546Sopenharmony_ci{ 764bf215546Sopenharmony_ci __DRIscreen *sPriv = dPriv->driScreenPriv; 765bf215546Sopenharmony_ci const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_ci loader->getImage(dPriv, 768bf215546Sopenharmony_ci x, y, width, height, 769bf215546Sopenharmony_ci data, dPriv->loaderPrivate); 770bf215546Sopenharmony_ci} 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_cistatic inline bool 773bf215546Sopenharmony_ciget_image_shm(__DRIdrawable *dPriv, int x, int y, int width, int height, 774bf215546Sopenharmony_ci struct pipe_resource *res) 775bf215546Sopenharmony_ci{ 776bf215546Sopenharmony_ci __DRIscreen *sPriv = dPriv->driScreenPriv; 777bf215546Sopenharmony_ci const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 778bf215546Sopenharmony_ci struct winsys_handle whandle; 779bf215546Sopenharmony_ci 780bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_SHMID; 781bf215546Sopenharmony_ci 782bf215546Sopenharmony_ci if (loader->base.version < 4 || !loader->getImageShm) 783bf215546Sopenharmony_ci return FALSE; 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci if (!res->screen->resource_get_handle(res->screen, NULL, res, &whandle, PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)) 786bf215546Sopenharmony_ci return FALSE; 787bf215546Sopenharmony_ci 788bf215546Sopenharmony_ci if (loader->base.version > 5 && loader->getImageShm2) 789bf215546Sopenharmony_ci return loader->getImageShm2(dPriv, x, y, width, height, whandle.handle, dPriv->loaderPrivate); 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_ci loader->getImageShm(dPriv, x, y, width, height, whandle.handle, dPriv->loaderPrivate); 792bf215546Sopenharmony_ci return TRUE; 793bf215546Sopenharmony_ci} 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_cistatic void 796bf215546Sopenharmony_cikopper_update_tex_buffer(struct dri_drawable *drawable, 797bf215546Sopenharmony_ci struct dri_context *ctx, 798bf215546Sopenharmony_ci struct pipe_resource *res) 799bf215546Sopenharmony_ci{ 800bf215546Sopenharmony_ci __DRIdrawable *dPriv = drawable->dPriv; 801bf215546Sopenharmony_ci __DRIscreen *sPriv = dPriv->driScreenPriv; 802bf215546Sopenharmony_ci struct kopper_screen *kscreen = (struct kopper_screen*)sPriv->driverPrivate; 803bf215546Sopenharmony_ci struct kopper_drawable *cdraw = (struct kopper_drawable *)drawable; 804bf215546Sopenharmony_ci struct st_context *st_ctx = (struct st_context *)ctx->st; 805bf215546Sopenharmony_ci struct pipe_context *pipe = st_ctx->pipe; 806bf215546Sopenharmony_ci struct pipe_transfer *transfer; 807bf215546Sopenharmony_ci char *map; 808bf215546Sopenharmony_ci int x, y, w, h; 809bf215546Sopenharmony_ci int ximage_stride, line; 810bf215546Sopenharmony_ci if (kscreen->has_dmabuf || cdraw->is_window || cdraw->info.bos.sType != VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) 811bf215546Sopenharmony_ci return; 812bf215546Sopenharmony_ci int cpp = util_format_get_blocksize(res->format); 813bf215546Sopenharmony_ci 814bf215546Sopenharmony_ci get_drawable_info(dPriv, &x, &y, &w, &h); 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci map = pipe_texture_map(pipe, res, 817bf215546Sopenharmony_ci 0, 0, // level, layer, 818bf215546Sopenharmony_ci PIPE_MAP_WRITE, 819bf215546Sopenharmony_ci x, y, w, h, &transfer); 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci /* Copy the Drawable content to the mapped texture buffer */ 822bf215546Sopenharmony_ci if (!get_image_shm(dPriv, x, y, w, h, res)) 823bf215546Sopenharmony_ci get_image(dPriv, x, y, w, h, map); 824bf215546Sopenharmony_ci 825bf215546Sopenharmony_ci /* The pipe transfer has a pitch rounded up to the nearest 64 pixels. 826bf215546Sopenharmony_ci get_image() has a pitch rounded up to 4 bytes. */ 827bf215546Sopenharmony_ci ximage_stride = ((w * cpp) + 3) & -4; 828bf215546Sopenharmony_ci for (line = h-1; line; --line) { 829bf215546Sopenharmony_ci memmove(&map[line * transfer->stride], 830bf215546Sopenharmony_ci &map[line * ximage_stride], 831bf215546Sopenharmony_ci ximage_stride); 832bf215546Sopenharmony_ci } 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci pipe_texture_unmap(pipe, transfer); 835bf215546Sopenharmony_ci} 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_cistatic void 838bf215546Sopenharmony_cikopper_flush_swapbuffers(struct dri_context *ctx, 839bf215546Sopenharmony_ci struct dri_drawable *drawable) 840bf215546Sopenharmony_ci{ 841bf215546Sopenharmony_ci /* does this actually need to do anything? */ 842bf215546Sopenharmony_ci} 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_ci// XXX this frees its second argument as a side effect - regardless of success 845bf215546Sopenharmony_ci// - since the point is to use it as the superclass initializer before we add 846bf215546Sopenharmony_ci// our own state. kindagross but easier than fixing the object model first. 847bf215546Sopenharmony_cistatic struct kopper_drawable * 848bf215546Sopenharmony_cikopper_create_drawable(__DRIdrawable *dPriv, struct dri_drawable *base) 849bf215546Sopenharmony_ci{ 850bf215546Sopenharmony_ci struct kopper_drawable *_ret = CALLOC_STRUCT(kopper_drawable); 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci if (!_ret) 853bf215546Sopenharmony_ci goto out; 854bf215546Sopenharmony_ci struct dri_drawable *ret = &_ret->base; 855bf215546Sopenharmony_ci 856bf215546Sopenharmony_ci // copy all the elements 857bf215546Sopenharmony_ci *ret = *base; 858bf215546Sopenharmony_ci 859bf215546Sopenharmony_ci // relocate references to the old struct 860bf215546Sopenharmony_ci ret->base.visual = &ret->stvis; 861bf215546Sopenharmony_ci ret->base.st_manager_private = (void *) ret; 862bf215546Sopenharmony_ci dPriv->driverPrivate = ret; 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci // and fill in the vtable 865bf215546Sopenharmony_ci ret->allocate_textures = kopper_allocate_textures; 866bf215546Sopenharmony_ci ret->update_drawable_info = kopper_update_drawable_info; 867bf215546Sopenharmony_ci ret->flush_frontbuffer = kopper_flush_frontbuffer; 868bf215546Sopenharmony_ci ret->update_tex_buffer = kopper_update_tex_buffer; 869bf215546Sopenharmony_ci ret->flush_swapbuffers = kopper_flush_swapbuffers; 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ciout: 872bf215546Sopenharmony_ci free(base); 873bf215546Sopenharmony_ci return _ret; 874bf215546Sopenharmony_ci} 875bf215546Sopenharmony_ci 876bf215546Sopenharmony_cistatic boolean 877bf215546Sopenharmony_cikopper_create_buffer(__DRIscreen * sPriv, 878bf215546Sopenharmony_ci __DRIdrawable * dPriv, 879bf215546Sopenharmony_ci const struct gl_config *visual, boolean isPixmap) 880bf215546Sopenharmony_ci{ 881bf215546Sopenharmony_ci struct kopper_drawable *drawable = NULL; 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci /* always pass !pixmap because it isn't "handled" or relevant */ 884bf215546Sopenharmony_ci if (!dri_create_buffer(sPriv, dPriv, visual, false)) 885bf215546Sopenharmony_ci return FALSE; 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_ci drawable = kopper_create_drawable(dPriv, dPriv->driverPrivate); 888bf215546Sopenharmony_ci if (!drawable) 889bf215546Sopenharmony_ci return FALSE; 890bf215546Sopenharmony_ci 891bf215546Sopenharmony_ci drawable->info.has_alpha = visual->alphaBits > 0; 892bf215546Sopenharmony_ci if (sPriv->kopper_loader->SetSurfaceCreateInfo) 893bf215546Sopenharmony_ci sPriv->kopper_loader->SetSurfaceCreateInfo(dPriv->loaderPrivate, 894bf215546Sopenharmony_ci &drawable->info); 895bf215546Sopenharmony_ci drawable->is_window = !isPixmap && drawable->info.bos.sType != 0; 896bf215546Sopenharmony_ci 897bf215546Sopenharmony_ci return TRUE; 898bf215546Sopenharmony_ci} 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_cistatic int64_t 901bf215546Sopenharmony_cikopperSwapBuffers(__DRIdrawable *dPriv) 902bf215546Sopenharmony_ci{ 903bf215546Sopenharmony_ci struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv); 904bf215546Sopenharmony_ci struct dri_drawable *drawable = dri_drawable(dPriv); 905bf215546Sopenharmony_ci struct kopper_drawable *kdraw = (struct kopper_drawable *)drawable; 906bf215546Sopenharmony_ci struct pipe_resource *ptex; 907bf215546Sopenharmony_ci 908bf215546Sopenharmony_ci if (!ctx) 909bf215546Sopenharmony_ci return 0; 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_ci ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 912bf215546Sopenharmony_ci if (!ptex) 913bf215546Sopenharmony_ci return 0; 914bf215546Sopenharmony_ci 915bf215546Sopenharmony_ci drawable->texture_stamp = dPriv->lastStamp - 1; 916bf215546Sopenharmony_ci dri_flush(ctx->cPriv, dPriv, __DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT, __DRI2_THROTTLE_SWAPBUFFER); 917bf215546Sopenharmony_ci kopper_copy_to_front(ctx->st->pipe, dPriv, ptex); 918bf215546Sopenharmony_ci if (kdraw->is_window && !zink_kopper_check(ptex)) 919bf215546Sopenharmony_ci return -1; 920bf215546Sopenharmony_ci if (!drawable->textures[ST_ATTACHMENT_FRONT_LEFT]) { 921bf215546Sopenharmony_ci return 0; 922bf215546Sopenharmony_ci } 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci /* have to manually swap the pointers here to make frontbuffer readback work */ 925bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_BACK_LEFT] = drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; 926bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_FRONT_LEFT] = ptex; 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci return 0; 929bf215546Sopenharmony_ci} 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_cistatic void 932bf215546Sopenharmony_cikopper_swap_buffers(__DRIdrawable *dPriv) 933bf215546Sopenharmony_ci{ 934bf215546Sopenharmony_ci kopperSwapBuffers(dPriv); 935bf215546Sopenharmony_ci} 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_cistatic __DRIdrawable * 938bf215546Sopenharmony_cikopperCreateNewDrawable(__DRIscreen *screen, 939bf215546Sopenharmony_ci const __DRIconfig *config, 940bf215546Sopenharmony_ci void *data, 941bf215546Sopenharmony_ci int is_pixmap) 942bf215546Sopenharmony_ci{ 943bf215546Sopenharmony_ci __DRIdrawable *pdraw; 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_ci assert(data != NULL); 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci pdraw = malloc(sizeof *pdraw); 948bf215546Sopenharmony_ci if (!pdraw) 949bf215546Sopenharmony_ci return NULL; 950bf215546Sopenharmony_ci 951bf215546Sopenharmony_ci pdraw->loaderPrivate = data; 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_ci pdraw->driScreenPriv = screen; 954bf215546Sopenharmony_ci pdraw->driContextPriv = NULL; 955bf215546Sopenharmony_ci pdraw->refcount = 0; 956bf215546Sopenharmony_ci pdraw->lastStamp = 0; 957bf215546Sopenharmony_ci pdraw->w = 0; 958bf215546Sopenharmony_ci pdraw->h = 0; 959bf215546Sopenharmony_ci 960bf215546Sopenharmony_ci //dri_get_drawable(pdraw); 961bf215546Sopenharmony_ci pdraw->refcount++; 962bf215546Sopenharmony_ci 963bf215546Sopenharmony_ci if (!screen->driver->CreateBuffer(screen, pdraw, &config->modes, 964bf215546Sopenharmony_ci is_pixmap)) { 965bf215546Sopenharmony_ci free(pdraw); 966bf215546Sopenharmony_ci return NULL; 967bf215546Sopenharmony_ci } 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_ci pdraw->dri2.stamp = pdraw->lastStamp + 1; 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ci return pdraw; 972bf215546Sopenharmony_ci} 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_cistatic void 975bf215546Sopenharmony_cikopperSetSwapInterval(__DRIdrawable *dPriv, int interval) 976bf215546Sopenharmony_ci{ 977bf215546Sopenharmony_ci struct dri_drawable *drawable = dri_drawable(dPriv); 978bf215546Sopenharmony_ci struct kopper_drawable *cdraw = (struct kopper_drawable *)drawable; 979bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(drawable->sPriv); 980bf215546Sopenharmony_ci struct kopper_screen *kscreen = (struct kopper_screen *)screen; 981bf215546Sopenharmony_ci struct pipe_screen *pscreen = kscreen->screen; 982bf215546Sopenharmony_ci struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ? 983bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_BACK_LEFT] : 984bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_ci /* the conditional is because we can be called before buffer allocation. If 987bf215546Sopenharmony_ci * we're before allocation, then the initial_swap_interval will be used when 988bf215546Sopenharmony_ci * the swapchain is eventually created. 989bf215546Sopenharmony_ci */ 990bf215546Sopenharmony_ci if (ptex) 991bf215546Sopenharmony_ci zink_kopper_set_swap_interval(pscreen, ptex, interval); 992bf215546Sopenharmony_ci cdraw->info.initial_swap_interval = interval; 993bf215546Sopenharmony_ci} 994bf215546Sopenharmony_ci 995bf215546Sopenharmony_cistatic int 996bf215546Sopenharmony_cikopperQueryBufferAge(__DRIdrawable *dPriv) 997bf215546Sopenharmony_ci{ 998bf215546Sopenharmony_ci struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv); 999bf215546Sopenharmony_ci struct dri_drawable *drawable = dri_drawable(dPriv); 1000bf215546Sopenharmony_ci struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ? 1001bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_BACK_LEFT] : 1002bf215546Sopenharmony_ci drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci return zink_kopper_query_buffer_age(ctx->st->pipe, ptex); 1005bf215546Sopenharmony_ci} 1006bf215546Sopenharmony_ci 1007bf215546Sopenharmony_ciconst __DRIkopperExtension driKopperExtension = { 1008bf215546Sopenharmony_ci .base = { __DRI_KOPPER, 1 }, 1009bf215546Sopenharmony_ci .createNewDrawable = kopperCreateNewDrawable, 1010bf215546Sopenharmony_ci .swapBuffers = kopperSwapBuffers, 1011bf215546Sopenharmony_ci .setSwapInterval = kopperSetSwapInterval, 1012bf215546Sopenharmony_ci .queryBufferAge = kopperQueryBufferAge, 1013bf215546Sopenharmony_ci}; 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ciconst struct __DriverAPIRec galliumvk_driver_api = { 1016bf215546Sopenharmony_ci .InitScreen = kopper_init_screen, 1017bf215546Sopenharmony_ci .DestroyScreen = dri_destroy_screen, 1018bf215546Sopenharmony_ci .CreateBuffer = kopper_create_buffer, 1019bf215546Sopenharmony_ci .DestroyBuffer = dri_destroy_buffer, 1020bf215546Sopenharmony_ci .SwapBuffers = kopper_swap_buffers, 1021bf215546Sopenharmony_ci .CopySubBuffer = NULL, 1022bf215546Sopenharmony_ci}; 1023bf215546Sopenharmony_ci 1024bf215546Sopenharmony_cistatic const struct __DRIDriverVtableExtensionRec galliumvk_vtable = { 1025bf215546Sopenharmony_ci .base = { __DRI_DRIVER_VTABLE, 1 }, 1026bf215546Sopenharmony_ci .vtable = &galliumvk_driver_api, 1027bf215546Sopenharmony_ci}; 1028bf215546Sopenharmony_ci 1029bf215546Sopenharmony_ciconst __DRIextension *galliumvk_driver_extensions[] = { 1030bf215546Sopenharmony_ci &driCoreExtension.base, 1031bf215546Sopenharmony_ci &driSWRastExtension.base, 1032bf215546Sopenharmony_ci &driDRI2Extension.base, 1033bf215546Sopenharmony_ci &driImageDriverExtension.base, 1034bf215546Sopenharmony_ci &driKopperExtension.base, 1035bf215546Sopenharmony_ci &gallium_config_options.base, 1036bf215546Sopenharmony_ci &galliumvk_vtable.base, 1037bf215546Sopenharmony_ci NULL 1038bf215546Sopenharmony_ci}; 1039bf215546Sopenharmony_ci 1040bf215546Sopenharmony_ci/* vim: set sw=3 ts=8 sts=3 expandtab: */ 1041