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