xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/dri/dri2.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Copyright 2009, VMware, Inc.
5*61046927SAndroid Build Coastguard Worker  * All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker  * Copyright (C) 2010 LunarG Inc.
7*61046927SAndroid Build Coastguard Worker  *
8*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
9*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
10*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
11*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
13*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included
16*61046927SAndroid Build Coastguard Worker  * in all copies or substantial portions of the Software.
17*61046927SAndroid Build Coastguard Worker  *
18*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22*61046927SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23*61046927SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24*61046927SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
25*61046927SAndroid Build Coastguard Worker  *
26*61046927SAndroid Build Coastguard Worker  * Authors:
27*61046927SAndroid Build Coastguard Worker  *    Keith Whitwell <[email protected]> Jakob Bornecrantz
28*61046927SAndroid Build Coastguard Worker  *    <[email protected]> Chia-I Wu <[email protected]>
29*61046927SAndroid Build Coastguard Worker  */
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker #include "util/libdrm.h"
32*61046927SAndroid Build Coastguard Worker #include "git_sha1.h"
33*61046927SAndroid Build Coastguard Worker #include "GL/mesa_glinterop.h"
34*61046927SAndroid Build Coastguard Worker #include "mesa_interface.h"
35*61046927SAndroid Build Coastguard Worker #include "util/disk_cache.h"
36*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
37*61046927SAndroid Build Coastguard Worker #include "util/u_inlines.h"
38*61046927SAndroid Build Coastguard Worker #include "util/format/u_format.h"
39*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
40*61046927SAndroid Build Coastguard Worker #include "util/libsync.h"
41*61046927SAndroid Build Coastguard Worker #include "util/os_file.h"
42*61046927SAndroid Build Coastguard Worker #include "util/log.h"
43*61046927SAndroid Build Coastguard Worker #include "frontend/drm_driver.h"
44*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_format.h"
45*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_texture.h"
46*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_texture.h"
47*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_context.h"
48*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_interop.h"
49*61046927SAndroid Build Coastguard Worker #include "pipe-loader/pipe_loader.h"
50*61046927SAndroid Build Coastguard Worker #include "main/bufferobj.h"
51*61046927SAndroid Build Coastguard Worker #include "main/texobj.h"
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker #include "dri_util.h"
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker #include "dri_helpers.h"
56*61046927SAndroid Build Coastguard Worker #include "dri_drawable.h"
57*61046927SAndroid Build Coastguard Worker #include "dri_query_renderer.h"
58*61046927SAndroid Build Coastguard Worker #include "loader_dri_helper.h"
59*61046927SAndroid Build Coastguard Worker 
60*61046927SAndroid Build Coastguard Worker #include "drm-uapi/drm_fourcc.h"
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker struct dri2_buffer
63*61046927SAndroid Build Coastguard Worker {
64*61046927SAndroid Build Coastguard Worker    __DRIbuffer base;
65*61046927SAndroid Build Coastguard Worker    struct pipe_resource *resource;
66*61046927SAndroid Build Coastguard Worker };
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker static inline struct dri2_buffer *
dri2_buffer(__DRIbuffer * driBufferPriv)69*61046927SAndroid Build Coastguard Worker dri2_buffer(__DRIbuffer * driBufferPriv)
70*61046927SAndroid Build Coastguard Worker {
71*61046927SAndroid Build Coastguard Worker    return (struct dri2_buffer *) driBufferPriv;
72*61046927SAndroid Build Coastguard Worker }
73*61046927SAndroid Build Coastguard Worker 
74*61046927SAndroid Build Coastguard Worker /**
75*61046927SAndroid Build Coastguard Worker  * Invalidate the drawable.
76*61046927SAndroid Build Coastguard Worker  *
77*61046927SAndroid Build Coastguard Worker  * How we get here is listed below.
78*61046927SAndroid Build Coastguard Worker  *
79*61046927SAndroid Build Coastguard Worker  * 1. Called by these SwapBuffers implementations where the context is known:
80*61046927SAndroid Build Coastguard Worker  *       loader_dri3_swap_buffers_msc
81*61046927SAndroid Build Coastguard Worker  *       EGL: droid_swap_buffers
82*61046927SAndroid Build Coastguard Worker  *       EGL: dri2_drm_swap_buffers
83*61046927SAndroid Build Coastguard Worker  *       EGL: dri2_wl_swap_buffers_with_damage
84*61046927SAndroid Build Coastguard Worker  *       EGL: dri2_x11_swap_buffers_msc
85*61046927SAndroid Build Coastguard Worker  *
86*61046927SAndroid Build Coastguard Worker  * 2. Other callers where the context is known:
87*61046927SAndroid Build Coastguard Worker  *       st_manager_flush_frontbuffer -> dri2_flush_frontbuffer
88*61046927SAndroid Build Coastguard Worker  *          -> EGL droid_display_shared_buffer
89*61046927SAndroid Build Coastguard Worker  *
90*61046927SAndroid Build Coastguard Worker  * 3. Other callers where the context is unknown:
91*61046927SAndroid Build Coastguard Worker  *       loader: dri3_handle_present_event - XCB_PRESENT_CONFIGURE_NOTIFY
92*61046927SAndroid Build Coastguard Worker  *       eglQuerySurface -> dri3_query_surface
93*61046927SAndroid Build Coastguard Worker  *          -> loader_dri3_update_drawable_geometry
94*61046927SAndroid Build Coastguard Worker  *       EGL: wl_egl_window::resize_callback (called outside Mesa)
95*61046927SAndroid Build Coastguard Worker  */
96*61046927SAndroid Build Coastguard Worker void
dri_invalidate_drawable(__DRIdrawable * dPriv)97*61046927SAndroid Build Coastguard Worker dri_invalidate_drawable(__DRIdrawable *dPriv)
98*61046927SAndroid Build Coastguard Worker {
99*61046927SAndroid Build Coastguard Worker    struct dri_drawable *drawable = dri_drawable(dPriv);
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    drawable->lastStamp++;
102*61046927SAndroid Build Coastguard Worker    drawable->texture_mask = 0; /* mark all attachments as invalid */
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker    p_atomic_inc(&drawable->base.stamp);
105*61046927SAndroid Build Coastguard Worker }
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker /**
108*61046927SAndroid Build Coastguard Worker  * Retrieve __DRIbuffer from the DRI loader.
109*61046927SAndroid Build Coastguard Worker  */
110*61046927SAndroid Build Coastguard Worker static __DRIbuffer *
dri2_drawable_get_buffers(struct dri_drawable * drawable,const enum st_attachment_type * atts,unsigned * count)111*61046927SAndroid Build Coastguard Worker dri2_drawable_get_buffers(struct dri_drawable *drawable,
112*61046927SAndroid Build Coastguard Worker                           const enum st_attachment_type *atts,
113*61046927SAndroid Build Coastguard Worker                           unsigned *count)
114*61046927SAndroid Build Coastguard Worker {
115*61046927SAndroid Build Coastguard Worker    const __DRIdri2LoaderExtension *loader = drawable->screen->dri2.loader;
116*61046927SAndroid Build Coastguard Worker    bool with_format;
117*61046927SAndroid Build Coastguard Worker    __DRIbuffer *buffers;
118*61046927SAndroid Build Coastguard Worker    int num_buffers;
119*61046927SAndroid Build Coastguard Worker    unsigned attachments[__DRI_BUFFER_COUNT];
120*61046927SAndroid Build Coastguard Worker    unsigned num_attachments, i;
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker    assert(loader);
123*61046927SAndroid Build Coastguard Worker    assert(*count <= __DRI_BUFFER_COUNT);
124*61046927SAndroid Build Coastguard Worker    with_format = dri_with_format(drawable->screen);
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker    num_attachments = 0;
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    /* for Xserver 1.6.0 (DRI2 version 1) we always need to ask for the front */
129*61046927SAndroid Build Coastguard Worker    if (!with_format)
130*61046927SAndroid Build Coastguard Worker       attachments[num_attachments++] = __DRI_BUFFER_FRONT_LEFT;
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    for (i = 0; i < *count; i++) {
133*61046927SAndroid Build Coastguard Worker       enum pipe_format format;
134*61046927SAndroid Build Coastguard Worker       unsigned bind;
135*61046927SAndroid Build Coastguard Worker       int att, depth;
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker       dri_drawable_get_format(drawable, atts[i], &format, &bind);
138*61046927SAndroid Build Coastguard Worker       if (format == PIPE_FORMAT_NONE)
139*61046927SAndroid Build Coastguard Worker          continue;
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker       switch (atts[i]) {
142*61046927SAndroid Build Coastguard Worker       case ST_ATTACHMENT_FRONT_LEFT:
143*61046927SAndroid Build Coastguard Worker          /* already added */
144*61046927SAndroid Build Coastguard Worker          if (!with_format)
145*61046927SAndroid Build Coastguard Worker             continue;
146*61046927SAndroid Build Coastguard Worker          att = __DRI_BUFFER_FRONT_LEFT;
147*61046927SAndroid Build Coastguard Worker          break;
148*61046927SAndroid Build Coastguard Worker       case ST_ATTACHMENT_BACK_LEFT:
149*61046927SAndroid Build Coastguard Worker          att = __DRI_BUFFER_BACK_LEFT;
150*61046927SAndroid Build Coastguard Worker          break;
151*61046927SAndroid Build Coastguard Worker       case ST_ATTACHMENT_FRONT_RIGHT:
152*61046927SAndroid Build Coastguard Worker          att = __DRI_BUFFER_FRONT_RIGHT;
153*61046927SAndroid Build Coastguard Worker          break;
154*61046927SAndroid Build Coastguard Worker       case ST_ATTACHMENT_BACK_RIGHT:
155*61046927SAndroid Build Coastguard Worker          att = __DRI_BUFFER_BACK_RIGHT;
156*61046927SAndroid Build Coastguard Worker          break;
157*61046927SAndroid Build Coastguard Worker       default:
158*61046927SAndroid Build Coastguard Worker          continue;
159*61046927SAndroid Build Coastguard Worker       }
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker       /*
162*61046927SAndroid Build Coastguard Worker        * In this switch statement we must support all formats that
163*61046927SAndroid Build Coastguard Worker        * may occur as the stvis->color_format.
164*61046927SAndroid Build Coastguard Worker        */
165*61046927SAndroid Build Coastguard Worker       switch(format) {
166*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_R16G16B16A16_FLOAT:
167*61046927SAndroid Build Coastguard Worker          depth = 64;
168*61046927SAndroid Build Coastguard Worker          break;
169*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_R16G16B16X16_FLOAT:
170*61046927SAndroid Build Coastguard Worker          depth = 48;
171*61046927SAndroid Build Coastguard Worker          break;
172*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_B10G10R10A2_UNORM:
173*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_R10G10B10A2_UNORM:
174*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_BGRA8888_UNORM:
175*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_RGBA8888_UNORM:
176*61046927SAndroid Build Coastguard Worker 	 depth = 32;
177*61046927SAndroid Build Coastguard Worker 	 break;
178*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_R10G10B10X2_UNORM:
179*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_B10G10R10X2_UNORM:
180*61046927SAndroid Build Coastguard Worker          depth = 30;
181*61046927SAndroid Build Coastguard Worker          break;
182*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_BGRX8888_UNORM:
183*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_RGBX8888_UNORM:
184*61046927SAndroid Build Coastguard Worker 	 depth = 24;
185*61046927SAndroid Build Coastguard Worker 	 break;
186*61046927SAndroid Build Coastguard Worker       case PIPE_FORMAT_B5G6R5_UNORM:
187*61046927SAndroid Build Coastguard Worker 	 depth = 16;
188*61046927SAndroid Build Coastguard Worker 	 break;
189*61046927SAndroid Build Coastguard Worker       default:
190*61046927SAndroid Build Coastguard Worker 	 depth = util_format_get_blocksizebits(format);
191*61046927SAndroid Build Coastguard Worker 	 assert(!"Unexpected format in dri2_drawable_get_buffers()");
192*61046927SAndroid Build Coastguard Worker       }
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker       attachments[num_attachments++] = att;
195*61046927SAndroid Build Coastguard Worker       if (with_format) {
196*61046927SAndroid Build Coastguard Worker          attachments[num_attachments++] = depth;
197*61046927SAndroid Build Coastguard Worker       }
198*61046927SAndroid Build Coastguard Worker    }
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker    if (with_format) {
201*61046927SAndroid Build Coastguard Worker       num_attachments /= 2;
202*61046927SAndroid Build Coastguard Worker       buffers = loader->getBuffersWithFormat(opaque_dri_drawable(drawable),
203*61046927SAndroid Build Coastguard Worker             &drawable->w, &drawable->h,
204*61046927SAndroid Build Coastguard Worker             attachments, num_attachments,
205*61046927SAndroid Build Coastguard Worker             &num_buffers, drawable->loaderPrivate);
206*61046927SAndroid Build Coastguard Worker    }
207*61046927SAndroid Build Coastguard Worker    else {
208*61046927SAndroid Build Coastguard Worker       buffers = loader->getBuffers(opaque_dri_drawable(drawable),
209*61046927SAndroid Build Coastguard Worker             &drawable->w, &drawable->h,
210*61046927SAndroid Build Coastguard Worker             attachments, num_attachments,
211*61046927SAndroid Build Coastguard Worker             &num_buffers, drawable->loaderPrivate);
212*61046927SAndroid Build Coastguard Worker    }
213*61046927SAndroid Build Coastguard Worker 
214*61046927SAndroid Build Coastguard Worker    if (buffers)
215*61046927SAndroid Build Coastguard Worker       *count = num_buffers;
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker    return buffers;
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker bool
221*61046927SAndroid Build Coastguard Worker dri_image_drawable_get_buffers(struct dri_drawable *drawable,
222*61046927SAndroid Build Coastguard Worker                                struct __DRIimageList *images,
223*61046927SAndroid Build Coastguard Worker                                const enum st_attachment_type *statts,
224*61046927SAndroid Build Coastguard Worker                                unsigned statts_count);
225*61046927SAndroid Build Coastguard Worker bool
dri_image_drawable_get_buffers(struct dri_drawable * drawable,struct __DRIimageList * images,const enum st_attachment_type * statts,unsigned statts_count)226*61046927SAndroid Build Coastguard Worker dri_image_drawable_get_buffers(struct dri_drawable *drawable,
227*61046927SAndroid Build Coastguard Worker                                struct __DRIimageList *images,
228*61046927SAndroid Build Coastguard Worker                                const enum st_attachment_type *statts,
229*61046927SAndroid Build Coastguard Worker                                unsigned statts_count)
230*61046927SAndroid Build Coastguard Worker {
231*61046927SAndroid Build Coastguard Worker    enum pipe_format color_format = PIPE_FORMAT_NONE;
232*61046927SAndroid Build Coastguard Worker    uint32_t buffer_mask = 0;
233*61046927SAndroid Build Coastguard Worker    unsigned i;
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker    for (i = 0; i < statts_count; i++) {
236*61046927SAndroid Build Coastguard Worker       enum pipe_format pf;
237*61046927SAndroid Build Coastguard Worker       unsigned bind;
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker       dri_drawable_get_format(drawable, statts[i], &pf, &bind);
240*61046927SAndroid Build Coastguard Worker       if (pf == PIPE_FORMAT_NONE)
241*61046927SAndroid Build Coastguard Worker          continue;
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker       switch (statts[i]) {
244*61046927SAndroid Build Coastguard Worker       case ST_ATTACHMENT_FRONT_LEFT:
245*61046927SAndroid Build Coastguard Worker          buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
246*61046927SAndroid Build Coastguard Worker          color_format = pf;
247*61046927SAndroid Build Coastguard Worker          break;
248*61046927SAndroid Build Coastguard Worker       case ST_ATTACHMENT_BACK_LEFT:
249*61046927SAndroid Build Coastguard Worker          buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
250*61046927SAndroid Build Coastguard Worker          color_format = pf;
251*61046927SAndroid Build Coastguard Worker          break;
252*61046927SAndroid Build Coastguard Worker       default:
253*61046927SAndroid Build Coastguard Worker          break;
254*61046927SAndroid Build Coastguard Worker       }
255*61046927SAndroid Build Coastguard Worker    }
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker    /* Stamp usage behavior in the getBuffers callback:
258*61046927SAndroid Build Coastguard Worker     *
259*61046927SAndroid Build Coastguard Worker     * 1. DRI3 (EGL and GLX):
260*61046927SAndroid Build Coastguard Worker     *       This calls loader_dri3_get_buffers, which saves the stamp pointer
261*61046927SAndroid Build Coastguard Worker     *       in loader_dri3_drawable::stamp, which is only changed (incremented)
262*61046927SAndroid Build Coastguard Worker     *       by loader_dri3_swap_buffers_msc.
263*61046927SAndroid Build Coastguard Worker     *
264*61046927SAndroid Build Coastguard Worker     * 2. EGL Android, Device, Surfaceless, Wayland:
265*61046927SAndroid Build Coastguard Worker     *       The stamp is unused.
266*61046927SAndroid Build Coastguard Worker     *
267*61046927SAndroid Build Coastguard Worker     * How do we get here:
268*61046927SAndroid Build Coastguard Worker     *    dri_set_tex_buffer2 (GLX_EXT_texture_from_pixmap)
269*61046927SAndroid Build Coastguard Worker     *    st_api_make_current
270*61046927SAndroid Build Coastguard Worker     *    st_manager_validate_framebuffers (part of st_validate_state)
271*61046927SAndroid Build Coastguard Worker     */
272*61046927SAndroid Build Coastguard Worker    return drawable->screen->image.loader->getBuffers(
273*61046927SAndroid Build Coastguard Worker                                           opaque_dri_drawable(drawable),
274*61046927SAndroid Build Coastguard Worker                                           color_format,
275*61046927SAndroid Build Coastguard Worker                                           (uint32_t *)&drawable->base.stamp,
276*61046927SAndroid Build Coastguard Worker                                           drawable->loaderPrivate, buffer_mask,
277*61046927SAndroid Build Coastguard Worker                                           images);
278*61046927SAndroid Build Coastguard Worker }
279*61046927SAndroid Build Coastguard Worker 
280*61046927SAndroid Build Coastguard Worker static __DRIbuffer *
dri2_allocate_buffer(struct dri_screen * screen,unsigned attachment,unsigned format,int width,int height)281*61046927SAndroid Build Coastguard Worker dri2_allocate_buffer(struct dri_screen *screen,
282*61046927SAndroid Build Coastguard Worker                      unsigned attachment, unsigned format,
283*61046927SAndroid Build Coastguard Worker                      int width, int height)
284*61046927SAndroid Build Coastguard Worker {
285*61046927SAndroid Build Coastguard Worker    struct dri2_buffer *buffer;
286*61046927SAndroid Build Coastguard Worker    struct pipe_resource templ;
287*61046927SAndroid Build Coastguard Worker    enum pipe_format pf;
288*61046927SAndroid Build Coastguard Worker    unsigned bind = 0;
289*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandle;
290*61046927SAndroid Build Coastguard Worker 
291*61046927SAndroid Build Coastguard Worker    /* struct pipe_resource height0 is 16-bit, avoid overflow */
292*61046927SAndroid Build Coastguard Worker    if (height > 0xffff)
293*61046927SAndroid Build Coastguard Worker       return NULL;
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker    switch (attachment) {
296*61046927SAndroid Build Coastguard Worker       case __DRI_BUFFER_FRONT_LEFT:
297*61046927SAndroid Build Coastguard Worker       case __DRI_BUFFER_FAKE_FRONT_LEFT:
298*61046927SAndroid Build Coastguard Worker          bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
299*61046927SAndroid Build Coastguard Worker          break;
300*61046927SAndroid Build Coastguard Worker       case __DRI_BUFFER_BACK_LEFT:
301*61046927SAndroid Build Coastguard Worker          bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
302*61046927SAndroid Build Coastguard Worker          break;
303*61046927SAndroid Build Coastguard Worker       case __DRI_BUFFER_DEPTH:
304*61046927SAndroid Build Coastguard Worker       case __DRI_BUFFER_DEPTH_STENCIL:
305*61046927SAndroid Build Coastguard Worker       case __DRI_BUFFER_STENCIL:
306*61046927SAndroid Build Coastguard Worker             bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */
307*61046927SAndroid Build Coastguard Worker          break;
308*61046927SAndroid Build Coastguard Worker    }
309*61046927SAndroid Build Coastguard Worker 
310*61046927SAndroid Build Coastguard Worker    /* because we get the handle and stride */
311*61046927SAndroid Build Coastguard Worker    bind |= PIPE_BIND_SHARED;
312*61046927SAndroid Build Coastguard Worker 
313*61046927SAndroid Build Coastguard Worker    switch (format) {
314*61046927SAndroid Build Coastguard Worker       case 64:
315*61046927SAndroid Build Coastguard Worker          pf = PIPE_FORMAT_R16G16B16A16_FLOAT;
316*61046927SAndroid Build Coastguard Worker          break;
317*61046927SAndroid Build Coastguard Worker       case 48:
318*61046927SAndroid Build Coastguard Worker          pf = PIPE_FORMAT_R16G16B16X16_FLOAT;
319*61046927SAndroid Build Coastguard Worker          break;
320*61046927SAndroid Build Coastguard Worker       case 32:
321*61046927SAndroid Build Coastguard Worker          pf = PIPE_FORMAT_BGRA8888_UNORM;
322*61046927SAndroid Build Coastguard Worker          break;
323*61046927SAndroid Build Coastguard Worker       case 30:
324*61046927SAndroid Build Coastguard Worker          pf = PIPE_FORMAT_B10G10R10X2_UNORM;
325*61046927SAndroid Build Coastguard Worker          break;
326*61046927SAndroid Build Coastguard Worker       case 24:
327*61046927SAndroid Build Coastguard Worker          pf = PIPE_FORMAT_BGRX8888_UNORM;
328*61046927SAndroid Build Coastguard Worker          break;
329*61046927SAndroid Build Coastguard Worker       case 16:
330*61046927SAndroid Build Coastguard Worker          pf = PIPE_FORMAT_Z16_UNORM;
331*61046927SAndroid Build Coastguard Worker          break;
332*61046927SAndroid Build Coastguard Worker       default:
333*61046927SAndroid Build Coastguard Worker          return NULL;
334*61046927SAndroid Build Coastguard Worker    }
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker    buffer = CALLOC_STRUCT(dri2_buffer);
337*61046927SAndroid Build Coastguard Worker    if (!buffer)
338*61046927SAndroid Build Coastguard Worker       return NULL;
339*61046927SAndroid Build Coastguard Worker 
340*61046927SAndroid Build Coastguard Worker    memset(&templ, 0, sizeof(templ));
341*61046927SAndroid Build Coastguard Worker    templ.bind = bind;
342*61046927SAndroid Build Coastguard Worker    templ.format = pf;
343*61046927SAndroid Build Coastguard Worker    templ.target = PIPE_TEXTURE_2D;
344*61046927SAndroid Build Coastguard Worker    templ.last_level = 0;
345*61046927SAndroid Build Coastguard Worker    templ.width0 = width;
346*61046927SAndroid Build Coastguard Worker    templ.height0 = height;
347*61046927SAndroid Build Coastguard Worker    templ.depth0 = 1;
348*61046927SAndroid Build Coastguard Worker    templ.array_size = 1;
349*61046927SAndroid Build Coastguard Worker 
350*61046927SAndroid Build Coastguard Worker    buffer->resource =
351*61046927SAndroid Build Coastguard Worker       screen->base.screen->resource_create(screen->base.screen, &templ);
352*61046927SAndroid Build Coastguard Worker    if (!buffer->resource) {
353*61046927SAndroid Build Coastguard Worker       FREE(buffer);
354*61046927SAndroid Build Coastguard Worker       return NULL;
355*61046927SAndroid Build Coastguard Worker    }
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker    memset(&whandle, 0, sizeof(whandle));
358*61046927SAndroid Build Coastguard Worker    if (screen->can_share_buffer)
359*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_SHARED;
360*61046927SAndroid Build Coastguard Worker    else
361*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_KMS;
362*61046927SAndroid Build Coastguard Worker 
363*61046927SAndroid Build Coastguard Worker    screen->base.screen->resource_get_handle(screen->base.screen, NULL,
364*61046927SAndroid Build Coastguard Worker          buffer->resource, &whandle,
365*61046927SAndroid Build Coastguard Worker          PIPE_HANDLE_USAGE_EXPLICIT_FLUSH);
366*61046927SAndroid Build Coastguard Worker 
367*61046927SAndroid Build Coastguard Worker    buffer->base.attachment = attachment;
368*61046927SAndroid Build Coastguard Worker    buffer->base.name = whandle.handle;
369*61046927SAndroid Build Coastguard Worker    buffer->base.cpp = util_format_get_blocksize(pf);
370*61046927SAndroid Build Coastguard Worker    buffer->base.pitch = whandle.stride;
371*61046927SAndroid Build Coastguard Worker 
372*61046927SAndroid Build Coastguard Worker    return &buffer->base;
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker 
375*61046927SAndroid Build Coastguard Worker static void
dri2_release_buffer(__DRIbuffer * bPriv)376*61046927SAndroid Build Coastguard Worker dri2_release_buffer(__DRIbuffer *bPriv)
377*61046927SAndroid Build Coastguard Worker {
378*61046927SAndroid Build Coastguard Worker    struct dri2_buffer *buffer = dri2_buffer(bPriv);
379*61046927SAndroid Build Coastguard Worker 
380*61046927SAndroid Build Coastguard Worker    pipe_resource_reference(&buffer->resource, NULL);
381*61046927SAndroid Build Coastguard Worker    FREE(buffer);
382*61046927SAndroid Build Coastguard Worker }
383*61046927SAndroid Build Coastguard Worker 
384*61046927SAndroid Build Coastguard Worker void
dri2_set_in_fence_fd(__DRIimage * img,int fd)385*61046927SAndroid Build Coastguard Worker dri2_set_in_fence_fd(__DRIimage *img, int fd)
386*61046927SAndroid Build Coastguard Worker {
387*61046927SAndroid Build Coastguard Worker    validate_fence_fd(fd);
388*61046927SAndroid Build Coastguard Worker    validate_fence_fd(img->in_fence_fd);
389*61046927SAndroid Build Coastguard Worker    sync_accumulate("dri", &img->in_fence_fd, fd);
390*61046927SAndroid Build Coastguard Worker }
391*61046927SAndroid Build Coastguard Worker 
392*61046927SAndroid Build Coastguard Worker /*
393*61046927SAndroid Build Coastguard Worker  * Backend functions for pipe_frontend_drawable.
394*61046927SAndroid Build Coastguard Worker  */
395*61046927SAndroid Build Coastguard Worker 
396*61046927SAndroid Build Coastguard Worker static void
dri2_allocate_textures(struct dri_context * ctx,struct dri_drawable * drawable,const enum st_attachment_type * statts,unsigned statts_count)397*61046927SAndroid Build Coastguard Worker dri2_allocate_textures(struct dri_context *ctx,
398*61046927SAndroid Build Coastguard Worker                        struct dri_drawable *drawable,
399*61046927SAndroid Build Coastguard Worker                        const enum st_attachment_type *statts,
400*61046927SAndroid Build Coastguard Worker                        unsigned statts_count)
401*61046927SAndroid Build Coastguard Worker {
402*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = drawable->screen;
403*61046927SAndroid Build Coastguard Worker    struct pipe_resource templ;
404*61046927SAndroid Build Coastguard Worker    bool alloc_depthstencil = false;
405*61046927SAndroid Build Coastguard Worker    unsigned i, j, bind;
406*61046927SAndroid Build Coastguard Worker    const __DRIimageLoaderExtension *image = screen->image.loader;
407*61046927SAndroid Build Coastguard Worker    /* Image specific variables */
408*61046927SAndroid Build Coastguard Worker    struct __DRIimageList images;
409*61046927SAndroid Build Coastguard Worker    /* Dri2 specific variables */
410*61046927SAndroid Build Coastguard Worker    __DRIbuffer *buffers = NULL;
411*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandle;
412*61046927SAndroid Build Coastguard Worker    unsigned num_buffers = statts_count;
413*61046927SAndroid Build Coastguard Worker 
414*61046927SAndroid Build Coastguard Worker    assert(num_buffers <= __DRI_BUFFER_COUNT);
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker    /* Wait for glthread to finish because we can't use pipe_context from
417*61046927SAndroid Build Coastguard Worker     * multiple threads.
418*61046927SAndroid Build Coastguard Worker     */
419*61046927SAndroid Build Coastguard Worker    _mesa_glthread_finish(ctx->st->ctx);
420*61046927SAndroid Build Coastguard Worker 
421*61046927SAndroid Build Coastguard Worker    /* First get the buffers from the loader */
422*61046927SAndroid Build Coastguard Worker    if (image) {
423*61046927SAndroid Build Coastguard Worker       if (!dri_image_drawable_get_buffers(drawable, &images,
424*61046927SAndroid Build Coastguard Worker                                           statts, statts_count))
425*61046927SAndroid Build Coastguard Worker          return;
426*61046927SAndroid Build Coastguard Worker    }
427*61046927SAndroid Build Coastguard Worker    else {
428*61046927SAndroid Build Coastguard Worker       buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers);
429*61046927SAndroid Build Coastguard Worker       if (!buffers || (drawable->old_num == num_buffers &&
430*61046927SAndroid Build Coastguard Worker                        drawable->old_w == drawable->w &&
431*61046927SAndroid Build Coastguard Worker                        drawable->old_h == drawable->h &&
432*61046927SAndroid Build Coastguard Worker                        memcmp(drawable->old, buffers,
433*61046927SAndroid Build Coastguard Worker                               sizeof(__DRIbuffer) * num_buffers) == 0))
434*61046927SAndroid Build Coastguard Worker          return;
435*61046927SAndroid Build Coastguard Worker    }
436*61046927SAndroid Build Coastguard Worker 
437*61046927SAndroid Build Coastguard Worker    /* Second clean useless resources*/
438*61046927SAndroid Build Coastguard Worker 
439*61046927SAndroid Build Coastguard Worker    /* See if we need a depth-stencil buffer. */
440*61046927SAndroid Build Coastguard Worker    for (i = 0; i < statts_count; i++) {
441*61046927SAndroid Build Coastguard Worker       if (statts[i] == ST_ATTACHMENT_DEPTH_STENCIL) {
442*61046927SAndroid Build Coastguard Worker          alloc_depthstencil = true;
443*61046927SAndroid Build Coastguard Worker          break;
444*61046927SAndroid Build Coastguard Worker       }
445*61046927SAndroid Build Coastguard Worker    }
446*61046927SAndroid Build Coastguard Worker 
447*61046927SAndroid Build Coastguard Worker    /* Delete the resources we won't need. */
448*61046927SAndroid Build Coastguard Worker    for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
449*61046927SAndroid Build Coastguard Worker       /* Don't delete the depth-stencil buffer, we can reuse it. */
450*61046927SAndroid Build Coastguard Worker       if (i == ST_ATTACHMENT_DEPTH_STENCIL && alloc_depthstencil)
451*61046927SAndroid Build Coastguard Worker          continue;
452*61046927SAndroid Build Coastguard Worker 
453*61046927SAndroid Build Coastguard Worker       /* Flush the texture before unreferencing, so that other clients can
454*61046927SAndroid Build Coastguard Worker        * see what the driver has rendered.
455*61046927SAndroid Build Coastguard Worker        */
456*61046927SAndroid Build Coastguard Worker       if (i != ST_ATTACHMENT_DEPTH_STENCIL && drawable->textures[i]) {
457*61046927SAndroid Build Coastguard Worker          struct pipe_context *pipe = ctx->st->pipe;
458*61046927SAndroid Build Coastguard Worker          pipe->flush_resource(pipe, drawable->textures[i]);
459*61046927SAndroid Build Coastguard Worker       }
460*61046927SAndroid Build Coastguard Worker 
461*61046927SAndroid Build Coastguard Worker       pipe_resource_reference(&drawable->textures[i], NULL);
462*61046927SAndroid Build Coastguard Worker    }
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker    if (drawable->stvis.samples > 1) {
465*61046927SAndroid Build Coastguard Worker       for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
466*61046927SAndroid Build Coastguard Worker          bool del = true;
467*61046927SAndroid Build Coastguard Worker 
468*61046927SAndroid Build Coastguard Worker          /* Don't delete MSAA resources for the attachments which are enabled,
469*61046927SAndroid Build Coastguard Worker           * we can reuse them. */
470*61046927SAndroid Build Coastguard Worker          for (j = 0; j < statts_count; j++) {
471*61046927SAndroid Build Coastguard Worker             if (i == statts[j]) {
472*61046927SAndroid Build Coastguard Worker                del = false;
473*61046927SAndroid Build Coastguard Worker                break;
474*61046927SAndroid Build Coastguard Worker             }
475*61046927SAndroid Build Coastguard Worker          }
476*61046927SAndroid Build Coastguard Worker 
477*61046927SAndroid Build Coastguard Worker          if (del) {
478*61046927SAndroid Build Coastguard Worker             pipe_resource_reference(&drawable->msaa_textures[i], NULL);
479*61046927SAndroid Build Coastguard Worker          }
480*61046927SAndroid Build Coastguard Worker       }
481*61046927SAndroid Build Coastguard Worker    }
482*61046927SAndroid Build Coastguard Worker 
483*61046927SAndroid Build Coastguard Worker    /* Third use the buffers retrieved to fill the drawable info */
484*61046927SAndroid Build Coastguard Worker 
485*61046927SAndroid Build Coastguard Worker    memset(&templ, 0, sizeof(templ));
486*61046927SAndroid Build Coastguard Worker    templ.target = screen->target;
487*61046927SAndroid Build Coastguard Worker    templ.last_level = 0;
488*61046927SAndroid Build Coastguard Worker    templ.depth0 = 1;
489*61046927SAndroid Build Coastguard Worker    templ.array_size = 1;
490*61046927SAndroid Build Coastguard Worker 
491*61046927SAndroid Build Coastguard Worker    if (image) {
492*61046927SAndroid Build Coastguard Worker       if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
493*61046927SAndroid Build Coastguard Worker          struct pipe_resource **buf =
494*61046927SAndroid Build Coastguard Worker             &drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
495*61046927SAndroid Build Coastguard Worker          struct pipe_resource *texture = images.front->texture;
496*61046927SAndroid Build Coastguard Worker 
497*61046927SAndroid Build Coastguard Worker          drawable->w = texture->width0;
498*61046927SAndroid Build Coastguard Worker          drawable->h = texture->height0;
499*61046927SAndroid Build Coastguard Worker 
500*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(buf, texture);
501*61046927SAndroid Build Coastguard Worker          dri_image_fence_sync(ctx, images.front);
502*61046927SAndroid Build Coastguard Worker       }
503*61046927SAndroid Build Coastguard Worker 
504*61046927SAndroid Build Coastguard Worker       if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
505*61046927SAndroid Build Coastguard Worker          struct pipe_resource **buf =
506*61046927SAndroid Build Coastguard Worker             &drawable->textures[ST_ATTACHMENT_BACK_LEFT];
507*61046927SAndroid Build Coastguard Worker          struct pipe_resource *texture = images.back->texture;
508*61046927SAndroid Build Coastguard Worker 
509*61046927SAndroid Build Coastguard Worker          drawable->w = texture->width0;
510*61046927SAndroid Build Coastguard Worker          drawable->h = texture->height0;
511*61046927SAndroid Build Coastguard Worker 
512*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(buf, texture);
513*61046927SAndroid Build Coastguard Worker          dri_image_fence_sync(ctx, images.back);
514*61046927SAndroid Build Coastguard Worker       }
515*61046927SAndroid Build Coastguard Worker 
516*61046927SAndroid Build Coastguard Worker       if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) {
517*61046927SAndroid Build Coastguard Worker          struct pipe_resource **buf =
518*61046927SAndroid Build Coastguard Worker             &drawable->textures[ST_ATTACHMENT_BACK_LEFT];
519*61046927SAndroid Build Coastguard Worker          struct pipe_resource *texture = images.back->texture;
520*61046927SAndroid Build Coastguard Worker 
521*61046927SAndroid Build Coastguard Worker          drawable->w = texture->width0;
522*61046927SAndroid Build Coastguard Worker          drawable->h = texture->height0;
523*61046927SAndroid Build Coastguard Worker 
524*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(buf, texture);
525*61046927SAndroid Build Coastguard Worker          dri_image_fence_sync(ctx, images.back);
526*61046927SAndroid Build Coastguard Worker 
527*61046927SAndroid Build Coastguard Worker          ctx->is_shared_buffer_bound = true;
528*61046927SAndroid Build Coastguard Worker       } else {
529*61046927SAndroid Build Coastguard Worker          ctx->is_shared_buffer_bound = false;
530*61046927SAndroid Build Coastguard Worker       }
531*61046927SAndroid Build Coastguard Worker 
532*61046927SAndroid Build Coastguard Worker       /* Note: if there is both a back and a front buffer,
533*61046927SAndroid Build Coastguard Worker        * then they have the same size.
534*61046927SAndroid Build Coastguard Worker        */
535*61046927SAndroid Build Coastguard Worker       templ.width0 = drawable->w;
536*61046927SAndroid Build Coastguard Worker       templ.height0 = drawable->h;
537*61046927SAndroid Build Coastguard Worker    }
538*61046927SAndroid Build Coastguard Worker    else {
539*61046927SAndroid Build Coastguard Worker       memset(&whandle, 0, sizeof(whandle));
540*61046927SAndroid Build Coastguard Worker 
541*61046927SAndroid Build Coastguard Worker       /* Process DRI-provided buffers and get pipe_resources. */
542*61046927SAndroid Build Coastguard Worker       for (i = 0; i < num_buffers; i++) {
543*61046927SAndroid Build Coastguard Worker          __DRIbuffer *buf = &buffers[i];
544*61046927SAndroid Build Coastguard Worker          enum st_attachment_type statt;
545*61046927SAndroid Build Coastguard Worker          enum pipe_format format;
546*61046927SAndroid Build Coastguard Worker 
547*61046927SAndroid Build Coastguard Worker          switch (buf->attachment) {
548*61046927SAndroid Build Coastguard Worker          case __DRI_BUFFER_FRONT_LEFT:
549*61046927SAndroid Build Coastguard Worker             if (!screen->auto_fake_front) {
550*61046927SAndroid Build Coastguard Worker                continue; /* invalid attachment */
551*61046927SAndroid Build Coastguard Worker             }
552*61046927SAndroid Build Coastguard Worker             FALLTHROUGH;
553*61046927SAndroid Build Coastguard Worker          case __DRI_BUFFER_FAKE_FRONT_LEFT:
554*61046927SAndroid Build Coastguard Worker             statt = ST_ATTACHMENT_FRONT_LEFT;
555*61046927SAndroid Build Coastguard Worker             break;
556*61046927SAndroid Build Coastguard Worker          case __DRI_BUFFER_BACK_LEFT:
557*61046927SAndroid Build Coastguard Worker             statt = ST_ATTACHMENT_BACK_LEFT;
558*61046927SAndroid Build Coastguard Worker             break;
559*61046927SAndroid Build Coastguard Worker          default:
560*61046927SAndroid Build Coastguard Worker             continue; /* invalid attachment */
561*61046927SAndroid Build Coastguard Worker          }
562*61046927SAndroid Build Coastguard Worker 
563*61046927SAndroid Build Coastguard Worker          dri_drawable_get_format(drawable, statt, &format, &bind);
564*61046927SAndroid Build Coastguard Worker          if (format == PIPE_FORMAT_NONE)
565*61046927SAndroid Build Coastguard Worker             continue;
566*61046927SAndroid Build Coastguard Worker 
567*61046927SAndroid Build Coastguard Worker          /* dri2_drawable_get_buffers has already filled dri_drawable->w
568*61046927SAndroid Build Coastguard Worker           * and dri_drawable->h */
569*61046927SAndroid Build Coastguard Worker          templ.width0 = drawable->w;
570*61046927SAndroid Build Coastguard Worker          templ.height0 = drawable->h;
571*61046927SAndroid Build Coastguard Worker          templ.format = format;
572*61046927SAndroid Build Coastguard Worker          templ.bind = bind;
573*61046927SAndroid Build Coastguard Worker          whandle.handle = buf->name;
574*61046927SAndroid Build Coastguard Worker          whandle.stride = buf->pitch;
575*61046927SAndroid Build Coastguard Worker          whandle.offset = 0;
576*61046927SAndroid Build Coastguard Worker          whandle.format = format;
577*61046927SAndroid Build Coastguard Worker          whandle.modifier = DRM_FORMAT_MOD_INVALID;
578*61046927SAndroid Build Coastguard Worker          if (screen->can_share_buffer)
579*61046927SAndroid Build Coastguard Worker             whandle.type = WINSYS_HANDLE_TYPE_SHARED;
580*61046927SAndroid Build Coastguard Worker          else
581*61046927SAndroid Build Coastguard Worker             whandle.type = WINSYS_HANDLE_TYPE_KMS;
582*61046927SAndroid Build Coastguard Worker          drawable->textures[statt] =
583*61046927SAndroid Build Coastguard Worker             screen->base.screen->resource_from_handle(screen->base.screen,
584*61046927SAndroid Build Coastguard Worker                   &templ, &whandle,
585*61046927SAndroid Build Coastguard Worker                   PIPE_HANDLE_USAGE_EXPLICIT_FLUSH);
586*61046927SAndroid Build Coastguard Worker          assert(drawable->textures[statt]);
587*61046927SAndroid Build Coastguard Worker       }
588*61046927SAndroid Build Coastguard Worker    }
589*61046927SAndroid Build Coastguard Worker 
590*61046927SAndroid Build Coastguard Worker    /* Allocate private MSAA colorbuffers. */
591*61046927SAndroid Build Coastguard Worker    if (drawable->stvis.samples > 1) {
592*61046927SAndroid Build Coastguard Worker       for (i = 0; i < statts_count; i++) {
593*61046927SAndroid Build Coastguard Worker          enum st_attachment_type statt = statts[i];
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker          if (statt == ST_ATTACHMENT_DEPTH_STENCIL)
596*61046927SAndroid Build Coastguard Worker             continue;
597*61046927SAndroid Build Coastguard Worker 
598*61046927SAndroid Build Coastguard Worker          if (drawable->textures[statt]) {
599*61046927SAndroid Build Coastguard Worker             templ.format = drawable->textures[statt]->format;
600*61046927SAndroid Build Coastguard Worker             templ.bind = drawable->textures[statt]->bind &
601*61046927SAndroid Build Coastguard Worker                          ~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED);
602*61046927SAndroid Build Coastguard Worker             templ.nr_samples = drawable->stvis.samples;
603*61046927SAndroid Build Coastguard Worker             templ.nr_storage_samples = drawable->stvis.samples;
604*61046927SAndroid Build Coastguard Worker 
605*61046927SAndroid Build Coastguard Worker             /* Try to reuse the resource.
606*61046927SAndroid Build Coastguard Worker              * (the other resource parameters should be constant)
607*61046927SAndroid Build Coastguard Worker              */
608*61046927SAndroid Build Coastguard Worker             if (!drawable->msaa_textures[statt] ||
609*61046927SAndroid Build Coastguard Worker                 drawable->msaa_textures[statt]->width0 != templ.width0 ||
610*61046927SAndroid Build Coastguard Worker                 drawable->msaa_textures[statt]->height0 != templ.height0) {
611*61046927SAndroid Build Coastguard Worker                /* Allocate a new one. */
612*61046927SAndroid Build Coastguard Worker                pipe_resource_reference(&drawable->msaa_textures[statt], NULL);
613*61046927SAndroid Build Coastguard Worker 
614*61046927SAndroid Build Coastguard Worker                drawable->msaa_textures[statt] =
615*61046927SAndroid Build Coastguard Worker                   screen->base.screen->resource_create(screen->base.screen,
616*61046927SAndroid Build Coastguard Worker                                                        &templ);
617*61046927SAndroid Build Coastguard Worker                assert(drawable->msaa_textures[statt]);
618*61046927SAndroid Build Coastguard Worker 
619*61046927SAndroid Build Coastguard Worker                /* If there are any MSAA resources, we should initialize them
620*61046927SAndroid Build Coastguard Worker                 * such that they contain the same data as the single-sample
621*61046927SAndroid Build Coastguard Worker                 * resources we just got from the X server.
622*61046927SAndroid Build Coastguard Worker                 *
623*61046927SAndroid Build Coastguard Worker                 * The reason for this is that the gallium frontend (and
624*61046927SAndroid Build Coastguard Worker                 * therefore the app) can access the MSAA resources only.
625*61046927SAndroid Build Coastguard Worker                 * The single-sample resources are not exposed
626*61046927SAndroid Build Coastguard Worker                 * to the gallium frontend.
627*61046927SAndroid Build Coastguard Worker                 *
628*61046927SAndroid Build Coastguard Worker                 */
629*61046927SAndroid Build Coastguard Worker                dri_pipe_blit(ctx->st->pipe,
630*61046927SAndroid Build Coastguard Worker                              drawable->msaa_textures[statt],
631*61046927SAndroid Build Coastguard Worker                              drawable->textures[statt]);
632*61046927SAndroid Build Coastguard Worker             }
633*61046927SAndroid Build Coastguard Worker          }
634*61046927SAndroid Build Coastguard Worker          else {
635*61046927SAndroid Build Coastguard Worker             pipe_resource_reference(&drawable->msaa_textures[statt], NULL);
636*61046927SAndroid Build Coastguard Worker          }
637*61046927SAndroid Build Coastguard Worker       }
638*61046927SAndroid Build Coastguard Worker    }
639*61046927SAndroid Build Coastguard Worker 
640*61046927SAndroid Build Coastguard Worker    /* Allocate a private depth-stencil buffer. */
641*61046927SAndroid Build Coastguard Worker    if (alloc_depthstencil) {
642*61046927SAndroid Build Coastguard Worker       enum st_attachment_type statt = ST_ATTACHMENT_DEPTH_STENCIL;
643*61046927SAndroid Build Coastguard Worker       struct pipe_resource **zsbuf;
644*61046927SAndroid Build Coastguard Worker       enum pipe_format format;
645*61046927SAndroid Build Coastguard Worker       unsigned bind;
646*61046927SAndroid Build Coastguard Worker 
647*61046927SAndroid Build Coastguard Worker       dri_drawable_get_format(drawable, statt, &format, &bind);
648*61046927SAndroid Build Coastguard Worker 
649*61046927SAndroid Build Coastguard Worker       if (format) {
650*61046927SAndroid Build Coastguard Worker          templ.format = format;
651*61046927SAndroid Build Coastguard Worker          templ.bind = bind & ~PIPE_BIND_SHARED;
652*61046927SAndroid Build Coastguard Worker 
653*61046927SAndroid Build Coastguard Worker          if (drawable->stvis.samples > 1) {
654*61046927SAndroid Build Coastguard Worker             templ.nr_samples = drawable->stvis.samples;
655*61046927SAndroid Build Coastguard Worker             templ.nr_storage_samples = drawable->stvis.samples;
656*61046927SAndroid Build Coastguard Worker             zsbuf = &drawable->msaa_textures[statt];
657*61046927SAndroid Build Coastguard Worker          }
658*61046927SAndroid Build Coastguard Worker          else {
659*61046927SAndroid Build Coastguard Worker             templ.nr_samples = 0;
660*61046927SAndroid Build Coastguard Worker             templ.nr_storage_samples = 0;
661*61046927SAndroid Build Coastguard Worker             zsbuf = &drawable->textures[statt];
662*61046927SAndroid Build Coastguard Worker          }
663*61046927SAndroid Build Coastguard Worker 
664*61046927SAndroid Build Coastguard Worker          /* Try to reuse the resource.
665*61046927SAndroid Build Coastguard Worker           * (the other resource parameters should be constant)
666*61046927SAndroid Build Coastguard Worker           */
667*61046927SAndroid Build Coastguard Worker          if (!*zsbuf ||
668*61046927SAndroid Build Coastguard Worker              (*zsbuf)->width0 != templ.width0 ||
669*61046927SAndroid Build Coastguard Worker              (*zsbuf)->height0 != templ.height0) {
670*61046927SAndroid Build Coastguard Worker             /* Allocate a new one. */
671*61046927SAndroid Build Coastguard Worker             pipe_resource_reference(zsbuf, NULL);
672*61046927SAndroid Build Coastguard Worker             *zsbuf = screen->base.screen->resource_create(screen->base.screen,
673*61046927SAndroid Build Coastguard Worker                                                           &templ);
674*61046927SAndroid Build Coastguard Worker             assert(*zsbuf);
675*61046927SAndroid Build Coastguard Worker          }
676*61046927SAndroid Build Coastguard Worker       }
677*61046927SAndroid Build Coastguard Worker       else {
678*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(&drawable->msaa_textures[statt], NULL);
679*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(&drawable->textures[statt], NULL);
680*61046927SAndroid Build Coastguard Worker       }
681*61046927SAndroid Build Coastguard Worker    }
682*61046927SAndroid Build Coastguard Worker 
683*61046927SAndroid Build Coastguard Worker    /* For DRI2, we may get the same buffers again from the server.
684*61046927SAndroid Build Coastguard Worker     * To prevent useless imports of gem names, drawable->old* is used
685*61046927SAndroid Build Coastguard Worker     * to bypass the import if we get the same buffers. This doesn't apply
686*61046927SAndroid Build Coastguard Worker     * to DRI3/Wayland, users of image.loader, since the buffer is managed
687*61046927SAndroid Build Coastguard Worker     * by the client (no import), and the back buffer is going to change
688*61046927SAndroid Build Coastguard Worker     * at every redraw.
689*61046927SAndroid Build Coastguard Worker     */
690*61046927SAndroid Build Coastguard Worker    if (!image) {
691*61046927SAndroid Build Coastguard Worker       drawable->old_num = num_buffers;
692*61046927SAndroid Build Coastguard Worker       drawable->old_w = drawable->w;
693*61046927SAndroid Build Coastguard Worker       drawable->old_h = drawable->h;
694*61046927SAndroid Build Coastguard Worker       memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * num_buffers);
695*61046927SAndroid Build Coastguard Worker    }
696*61046927SAndroid Build Coastguard Worker }
697*61046927SAndroid Build Coastguard Worker 
698*61046927SAndroid Build Coastguard Worker static bool
dri2_flush_frontbuffer(struct dri_context * ctx,struct dri_drawable * drawable,enum st_attachment_type statt)699*61046927SAndroid Build Coastguard Worker dri2_flush_frontbuffer(struct dri_context *ctx,
700*61046927SAndroid Build Coastguard Worker                        struct dri_drawable *drawable,
701*61046927SAndroid Build Coastguard Worker                        enum st_attachment_type statt)
702*61046927SAndroid Build Coastguard Worker {
703*61046927SAndroid Build Coastguard Worker    const __DRIimageLoaderExtension *image = drawable->screen->image.loader;
704*61046927SAndroid Build Coastguard Worker    const __DRIdri2LoaderExtension *loader = drawable->screen->dri2.loader;
705*61046927SAndroid Build Coastguard Worker    const __DRImutableRenderBufferLoaderExtension *shared_buffer_loader =
706*61046927SAndroid Build Coastguard Worker       drawable->screen->mutableRenderBuffer.loader;
707*61046927SAndroid Build Coastguard Worker    struct pipe_context *pipe = ctx->st->pipe;
708*61046927SAndroid Build Coastguard Worker    struct pipe_fence_handle *fence = NULL;
709*61046927SAndroid Build Coastguard Worker    int fence_fd = -1;
710*61046927SAndroid Build Coastguard Worker 
711*61046927SAndroid Build Coastguard Worker    /* We need to flush for front buffer rendering when either we're using the
712*61046927SAndroid Build Coastguard Worker     * front buffer at the GL API level, or when EGL_KHR_mutable_render_buffer
713*61046927SAndroid Build Coastguard Worker     * has redirected GL_BACK to the front buffer.
714*61046927SAndroid Build Coastguard Worker     */
715*61046927SAndroid Build Coastguard Worker    if (statt != ST_ATTACHMENT_FRONT_LEFT &&
716*61046927SAndroid Build Coastguard Worker        (!ctx->is_shared_buffer_bound || statt != ST_ATTACHMENT_BACK_LEFT))
717*61046927SAndroid Build Coastguard Worker          return false;
718*61046927SAndroid Build Coastguard Worker 
719*61046927SAndroid Build Coastguard Worker    /* Wait for glthread to finish because we can't use pipe_context from
720*61046927SAndroid Build Coastguard Worker     * multiple threads.
721*61046927SAndroid Build Coastguard Worker     */
722*61046927SAndroid Build Coastguard Worker    _mesa_glthread_finish(ctx->st->ctx);
723*61046927SAndroid Build Coastguard Worker 
724*61046927SAndroid Build Coastguard Worker    if (drawable->stvis.samples > 1) {
725*61046927SAndroid Build Coastguard Worker       /* Resolve the buffer used for front rendering. */
726*61046927SAndroid Build Coastguard Worker       dri_pipe_blit(ctx->st->pipe, drawable->textures[statt],
727*61046927SAndroid Build Coastguard Worker                     drawable->msaa_textures[statt]);
728*61046927SAndroid Build Coastguard Worker    }
729*61046927SAndroid Build Coastguard Worker 
730*61046927SAndroid Build Coastguard Worker    if (drawable->textures[statt]) {
731*61046927SAndroid Build Coastguard Worker       pipe->flush_resource(pipe, drawable->textures[statt]);
732*61046927SAndroid Build Coastguard Worker    }
733*61046927SAndroid Build Coastguard Worker 
734*61046927SAndroid Build Coastguard Worker    if (ctx->is_shared_buffer_bound) {
735*61046927SAndroid Build Coastguard Worker       /* is_shared_buffer_bound should only be true with image extension: */
736*61046927SAndroid Build Coastguard Worker       assert(image);
737*61046927SAndroid Build Coastguard Worker       pipe->flush(pipe, &fence, PIPE_FLUSH_FENCE_FD);
738*61046927SAndroid Build Coastguard Worker    } else {
739*61046927SAndroid Build Coastguard Worker       pipe->flush(pipe, NULL, 0);
740*61046927SAndroid Build Coastguard Worker    }
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker    if (image) {
743*61046927SAndroid Build Coastguard Worker       image->flushFrontBuffer(opaque_dri_drawable(drawable),
744*61046927SAndroid Build Coastguard Worker                               drawable->loaderPrivate);
745*61046927SAndroid Build Coastguard Worker       if (ctx->is_shared_buffer_bound) {
746*61046927SAndroid Build Coastguard Worker          if (fence)
747*61046927SAndroid Build Coastguard Worker             fence_fd = pipe->screen->fence_get_fd(pipe->screen, fence);
748*61046927SAndroid Build Coastguard Worker 
749*61046927SAndroid Build Coastguard Worker          shared_buffer_loader->displaySharedBuffer(opaque_dri_drawable(drawable),
750*61046927SAndroid Build Coastguard Worker                                                    fence_fd,
751*61046927SAndroid Build Coastguard Worker                                                    drawable->loaderPrivate);
752*61046927SAndroid Build Coastguard Worker 
753*61046927SAndroid Build Coastguard Worker          pipe->screen->fence_reference(pipe->screen, &fence, NULL);
754*61046927SAndroid Build Coastguard Worker       }
755*61046927SAndroid Build Coastguard Worker    }
756*61046927SAndroid Build Coastguard Worker    else if (loader->flushFrontBuffer) {
757*61046927SAndroid Build Coastguard Worker       loader->flushFrontBuffer(opaque_dri_drawable(drawable),
758*61046927SAndroid Build Coastguard Worker                                drawable->loaderPrivate);
759*61046927SAndroid Build Coastguard Worker    }
760*61046927SAndroid Build Coastguard Worker 
761*61046927SAndroid Build Coastguard Worker    return true;
762*61046927SAndroid Build Coastguard Worker }
763*61046927SAndroid Build Coastguard Worker 
764*61046927SAndroid Build Coastguard Worker /**
765*61046927SAndroid Build Coastguard Worker  * The struct dri_drawable flush_swapbuffers callback
766*61046927SAndroid Build Coastguard Worker  */
767*61046927SAndroid Build Coastguard Worker static void
dri2_flush_swapbuffers(struct dri_context * ctx,struct dri_drawable * drawable)768*61046927SAndroid Build Coastguard Worker dri2_flush_swapbuffers(struct dri_context *ctx,
769*61046927SAndroid Build Coastguard Worker                        struct dri_drawable *drawable)
770*61046927SAndroid Build Coastguard Worker {
771*61046927SAndroid Build Coastguard Worker    const __DRIimageLoaderExtension *image = drawable->screen->image.loader;
772*61046927SAndroid Build Coastguard Worker 
773*61046927SAndroid Build Coastguard Worker    if (image && image->flushSwapBuffers) {
774*61046927SAndroid Build Coastguard Worker       image->flushSwapBuffers(opaque_dri_drawable(drawable),
775*61046927SAndroid Build Coastguard Worker                               drawable->loaderPrivate);
776*61046927SAndroid Build Coastguard Worker    }
777*61046927SAndroid Build Coastguard Worker }
778*61046927SAndroid Build Coastguard Worker 
779*61046927SAndroid Build Coastguard Worker static void
dri2_update_tex_buffer(struct dri_drawable * drawable,struct dri_context * ctx,struct pipe_resource * res)780*61046927SAndroid Build Coastguard Worker dri2_update_tex_buffer(struct dri_drawable *drawable,
781*61046927SAndroid Build Coastguard Worker                        struct dri_context *ctx,
782*61046927SAndroid Build Coastguard Worker                        struct pipe_resource *res)
783*61046927SAndroid Build Coastguard Worker {
784*61046927SAndroid Build Coastguard Worker    /* no-op */
785*61046927SAndroid Build Coastguard Worker }
786*61046927SAndroid Build Coastguard Worker 
787*61046927SAndroid Build Coastguard Worker static const struct dri2_format_mapping r8_b8_g8_mapping = {
788*61046927SAndroid Build Coastguard Worker    DRM_FORMAT_YVU420,
789*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_FORMAT_NONE,
790*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_COMPONENTS_Y_U_V,
791*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_R8_B8_G8_420_UNORM,
792*61046927SAndroid Build Coastguard Worker    3,
793*61046927SAndroid Build Coastguard Worker    { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
794*61046927SAndroid Build Coastguard Worker      { 2, 1, 1, __DRI_IMAGE_FORMAT_R8 },
795*61046927SAndroid Build Coastguard Worker      { 1, 1, 1, __DRI_IMAGE_FORMAT_R8 } }
796*61046927SAndroid Build Coastguard Worker };
797*61046927SAndroid Build Coastguard Worker 
798*61046927SAndroid Build Coastguard Worker static const struct dri2_format_mapping r8_g8_b8_mapping = {
799*61046927SAndroid Build Coastguard Worker    DRM_FORMAT_YUV420,
800*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_FORMAT_NONE,
801*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_COMPONENTS_Y_U_V,
802*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_R8_G8_B8_420_UNORM,
803*61046927SAndroid Build Coastguard Worker    3,
804*61046927SAndroid Build Coastguard Worker    { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
805*61046927SAndroid Build Coastguard Worker      { 1, 1, 1, __DRI_IMAGE_FORMAT_R8 },
806*61046927SAndroid Build Coastguard Worker      { 2, 1, 1, __DRI_IMAGE_FORMAT_R8 } }
807*61046927SAndroid Build Coastguard Worker };
808*61046927SAndroid Build Coastguard Worker 
809*61046927SAndroid Build Coastguard Worker static const struct dri2_format_mapping r8_g8b8_mapping = {
810*61046927SAndroid Build Coastguard Worker    DRM_FORMAT_NV12,
811*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_FORMAT_NONE,
812*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_COMPONENTS_Y_UV,
813*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_R8_G8B8_420_UNORM,
814*61046927SAndroid Build Coastguard Worker    2,
815*61046927SAndroid Build Coastguard Worker    { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
816*61046927SAndroid Build Coastguard Worker      { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } }
817*61046927SAndroid Build Coastguard Worker };
818*61046927SAndroid Build Coastguard Worker 
819*61046927SAndroid Build Coastguard Worker static const struct dri2_format_mapping r8_b8g8_mapping = {
820*61046927SAndroid Build Coastguard Worker    DRM_FORMAT_NV21,
821*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_FORMAT_NONE,
822*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_COMPONENTS_Y_UV,
823*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_R8_B8G8_420_UNORM,
824*61046927SAndroid Build Coastguard Worker    2,
825*61046927SAndroid Build Coastguard Worker    { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
826*61046927SAndroid Build Coastguard Worker      { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } }
827*61046927SAndroid Build Coastguard Worker };
828*61046927SAndroid Build Coastguard Worker 
829*61046927SAndroid Build Coastguard Worker static const struct dri2_format_mapping r8g8_r8b8_mapping = {
830*61046927SAndroid Build Coastguard Worker    DRM_FORMAT_YUYV,
831*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_FORMAT_NONE,
832*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_COMPONENTS_Y_XUXV,
833*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_R8G8_R8B8_UNORM, 2,
834*61046927SAndroid Build Coastguard Worker    { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
835*61046927SAndroid Build Coastguard Worker      { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } }
836*61046927SAndroid Build Coastguard Worker };
837*61046927SAndroid Build Coastguard Worker 
838*61046927SAndroid Build Coastguard Worker static const struct dri2_format_mapping r8b8_r8g8_mapping = {
839*61046927SAndroid Build Coastguard Worker    DRM_FORMAT_YVYU,
840*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_FORMAT_NONE,
841*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_COMPONENTS_Y_XUXV,
842*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_R8B8_R8G8_UNORM, 2,
843*61046927SAndroid Build Coastguard Worker    { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
844*61046927SAndroid Build Coastguard Worker      { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } }
845*61046927SAndroid Build Coastguard Worker };
846*61046927SAndroid Build Coastguard Worker 
847*61046927SAndroid Build Coastguard Worker static const struct dri2_format_mapping b8r8_g8r8_mapping = {
848*61046927SAndroid Build Coastguard Worker    DRM_FORMAT_VYUY,
849*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_FORMAT_NONE,
850*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_COMPONENTS_Y_XUXV,
851*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_B8R8_G8R8_UNORM, 2,
852*61046927SAndroid Build Coastguard Worker    { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
853*61046927SAndroid Build Coastguard Worker      { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } }
854*61046927SAndroid Build Coastguard Worker };
855*61046927SAndroid Build Coastguard Worker 
856*61046927SAndroid Build Coastguard Worker static const struct dri2_format_mapping g8r8_b8r8_mapping = {
857*61046927SAndroid Build Coastguard Worker    DRM_FORMAT_UYVY,
858*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_FORMAT_NONE,
859*61046927SAndroid Build Coastguard Worker    __DRI_IMAGE_COMPONENTS_Y_XUXV,
860*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_G8R8_B8R8_UNORM, 2,
861*61046927SAndroid Build Coastguard Worker    { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
862*61046927SAndroid Build Coastguard Worker      { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } }
863*61046927SAndroid Build Coastguard Worker };
864*61046927SAndroid Build Coastguard Worker 
865*61046927SAndroid Build Coastguard Worker static enum __DRIFixedRateCompression
to_dri_compression_rate(uint32_t rate)866*61046927SAndroid Build Coastguard Worker to_dri_compression_rate(uint32_t rate)
867*61046927SAndroid Build Coastguard Worker {
868*61046927SAndroid Build Coastguard Worker    switch (rate) {
869*61046927SAndroid Build Coastguard Worker    case PIPE_COMPRESSION_FIXED_RATE_NONE:
870*61046927SAndroid Build Coastguard Worker       return __DRI_FIXED_RATE_COMPRESSION_NONE;
871*61046927SAndroid Build Coastguard Worker    case PIPE_COMPRESSION_FIXED_RATE_DEFAULT:
872*61046927SAndroid Build Coastguard Worker       return __DRI_FIXED_RATE_COMPRESSION_DEFAULT;
873*61046927SAndroid Build Coastguard Worker    case 1: return __DRI_FIXED_RATE_COMPRESSION_1BPC;
874*61046927SAndroid Build Coastguard Worker    case 2: return __DRI_FIXED_RATE_COMPRESSION_2BPC;
875*61046927SAndroid Build Coastguard Worker    case 3: return __DRI_FIXED_RATE_COMPRESSION_3BPC;
876*61046927SAndroid Build Coastguard Worker    case 4: return __DRI_FIXED_RATE_COMPRESSION_4BPC;
877*61046927SAndroid Build Coastguard Worker    case 5: return __DRI_FIXED_RATE_COMPRESSION_5BPC;
878*61046927SAndroid Build Coastguard Worker    case 6: return __DRI_FIXED_RATE_COMPRESSION_6BPC;
879*61046927SAndroid Build Coastguard Worker    case 7: return __DRI_FIXED_RATE_COMPRESSION_7BPC;
880*61046927SAndroid Build Coastguard Worker    case 8: return __DRI_FIXED_RATE_COMPRESSION_8BPC;
881*61046927SAndroid Build Coastguard Worker    case 9: return __DRI_FIXED_RATE_COMPRESSION_9BPC;
882*61046927SAndroid Build Coastguard Worker    case 10: return __DRI_FIXED_RATE_COMPRESSION_10BPC;
883*61046927SAndroid Build Coastguard Worker    case 11: return __DRI_FIXED_RATE_COMPRESSION_11BPC;
884*61046927SAndroid Build Coastguard Worker    case 12: return __DRI_FIXED_RATE_COMPRESSION_12BPC;
885*61046927SAndroid Build Coastguard Worker    default:
886*61046927SAndroid Build Coastguard Worker       unreachable("invalid compression fixed-rate value");
887*61046927SAndroid Build Coastguard Worker    }
888*61046927SAndroid Build Coastguard Worker }
889*61046927SAndroid Build Coastguard Worker 
890*61046927SAndroid Build Coastguard Worker static uint32_t
from_dri_compression_rate(enum __DRIFixedRateCompression rate)891*61046927SAndroid Build Coastguard Worker from_dri_compression_rate(enum __DRIFixedRateCompression rate)
892*61046927SAndroid Build Coastguard Worker {
893*61046927SAndroid Build Coastguard Worker    switch (rate) {
894*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_NONE:
895*61046927SAndroid Build Coastguard Worker       return PIPE_COMPRESSION_FIXED_RATE_NONE;
896*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_DEFAULT:
897*61046927SAndroid Build Coastguard Worker       return PIPE_COMPRESSION_FIXED_RATE_DEFAULT;
898*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_1BPC: return 1;
899*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_2BPC: return 2;
900*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_3BPC: return 3;
901*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_4BPC: return 4;
902*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_5BPC: return 5;
903*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_6BPC: return 6;
904*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_7BPC: return 7;
905*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_8BPC: return 8;
906*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_9BPC: return 9;
907*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_10BPC: return 10;
908*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_11BPC: return 11;
909*61046927SAndroid Build Coastguard Worker    case __DRI_FIXED_RATE_COMPRESSION_12BPC: return 12;
910*61046927SAndroid Build Coastguard Worker    default:
911*61046927SAndroid Build Coastguard Worker       unreachable("invalid compression fixed-rate value");
912*61046927SAndroid Build Coastguard Worker    }
913*61046927SAndroid Build Coastguard Worker }
914*61046927SAndroid Build Coastguard Worker 
915*61046927SAndroid Build Coastguard Worker static __DRIimage *
dri_create_image_from_winsys(__DRIscreen * _screen,int width,int height,const struct dri2_format_mapping * map,int num_handles,struct winsys_handle * whandle,unsigned bind,void * loaderPrivate)916*61046927SAndroid Build Coastguard Worker dri_create_image_from_winsys(__DRIscreen *_screen,
917*61046927SAndroid Build Coastguard Worker                               int width, int height, const struct dri2_format_mapping *map,
918*61046927SAndroid Build Coastguard Worker                               int num_handles, struct winsys_handle *whandle,
919*61046927SAndroid Build Coastguard Worker                               unsigned bind,
920*61046927SAndroid Build Coastguard Worker                               void *loaderPrivate)
921*61046927SAndroid Build Coastguard Worker {
922*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = dri_screen(_screen);
923*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = screen->base.screen;
924*61046927SAndroid Build Coastguard Worker    __DRIimage *img;
925*61046927SAndroid Build Coastguard Worker    struct pipe_resource templ;
926*61046927SAndroid Build Coastguard Worker    unsigned tex_usage = 0;
927*61046927SAndroid Build Coastguard Worker    int i;
928*61046927SAndroid Build Coastguard Worker    bool use_lowered = false;
929*61046927SAndroid Build Coastguard Worker    const unsigned format_planes = util_format_get_num_planes(map->pipe_format);
930*61046927SAndroid Build Coastguard Worker 
931*61046927SAndroid Build Coastguard Worker    if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0,
932*61046927SAndroid Build Coastguard Worker                                     PIPE_BIND_RENDER_TARGET))
933*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_RENDER_TARGET;
934*61046927SAndroid Build Coastguard Worker    if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0,
935*61046927SAndroid Build Coastguard Worker                                     PIPE_BIND_SAMPLER_VIEW))
936*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
937*61046927SAndroid Build Coastguard Worker 
938*61046927SAndroid Build Coastguard Worker    /* For NV12, see if we have support for sampling r8_g8b8 */
939*61046927SAndroid Build Coastguard Worker    if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV12 &&
940*61046927SAndroid Build Coastguard Worker        pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8B8_420_UNORM,
941*61046927SAndroid Build Coastguard Worker                                     screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
942*61046927SAndroid Build Coastguard Worker       map = &r8_g8b8_mapping;
943*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
944*61046927SAndroid Build Coastguard Worker    }
945*61046927SAndroid Build Coastguard Worker 
946*61046927SAndroid Build Coastguard Worker    /* For NV21, see if we have support for sampling r8_b8g8 */
947*61046927SAndroid Build Coastguard Worker    if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV21 &&
948*61046927SAndroid Build Coastguard Worker        pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_B8G8_420_UNORM,
949*61046927SAndroid Build Coastguard Worker                                     screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
950*61046927SAndroid Build Coastguard Worker       map = &r8_b8g8_mapping;
951*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
952*61046927SAndroid Build Coastguard Worker    }
953*61046927SAndroid Build Coastguard Worker 
954*61046927SAndroid Build Coastguard Worker    /* For YV12 and I420, see if we have support for sampling r8_b8_g8 or r8_g8_b8 */
955*61046927SAndroid Build Coastguard Worker    if (!tex_usage && map->pipe_format == PIPE_FORMAT_IYUV) {
956*61046927SAndroid Build Coastguard Worker       if (map->dri_fourcc == DRM_FORMAT_YUV420 &&
957*61046927SAndroid Build Coastguard Worker           pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8_B8_420_UNORM,
958*61046927SAndroid Build Coastguard Worker                                        screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
959*61046927SAndroid Build Coastguard Worker          map = &r8_g8_b8_mapping;
960*61046927SAndroid Build Coastguard Worker          tex_usage |= PIPE_BIND_SAMPLER_VIEW;
961*61046927SAndroid Build Coastguard Worker       } else if (map->dri_fourcc == DRM_FORMAT_YVU420 &&
962*61046927SAndroid Build Coastguard Worker           pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_B8_G8_420_UNORM,
963*61046927SAndroid Build Coastguard Worker                                        screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
964*61046927SAndroid Build Coastguard Worker          map = &r8_b8_g8_mapping;
965*61046927SAndroid Build Coastguard Worker          tex_usage |= PIPE_BIND_SAMPLER_VIEW;
966*61046927SAndroid Build Coastguard Worker       }
967*61046927SAndroid Build Coastguard Worker    }
968*61046927SAndroid Build Coastguard Worker 
969*61046927SAndroid Build Coastguard Worker    /* If the hardware supports R8G8_R8B8 style subsampled RGB formats, these
970*61046927SAndroid Build Coastguard Worker     * can be used for YUYV and UYVY formats.
971*61046927SAndroid Build Coastguard Worker     */
972*61046927SAndroid Build Coastguard Worker    if (!tex_usage && map->pipe_format == PIPE_FORMAT_YUYV &&
973*61046927SAndroid Build Coastguard Worker        pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8G8_R8B8_UNORM,
974*61046927SAndroid Build Coastguard Worker                                     screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
975*61046927SAndroid Build Coastguard Worker       map = &r8g8_r8b8_mapping;
976*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
977*61046927SAndroid Build Coastguard Worker    }
978*61046927SAndroid Build Coastguard Worker 
979*61046927SAndroid Build Coastguard Worker    if (!tex_usage && map->pipe_format == PIPE_FORMAT_YVYU &&
980*61046927SAndroid Build Coastguard Worker        pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8B8_R8G8_UNORM,
981*61046927SAndroid Build Coastguard Worker                                     screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
982*61046927SAndroid Build Coastguard Worker       map = &r8b8_r8g8_mapping;
983*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
984*61046927SAndroid Build Coastguard Worker    }
985*61046927SAndroid Build Coastguard Worker 
986*61046927SAndroid Build Coastguard Worker    if (!tex_usage && map->pipe_format == PIPE_FORMAT_UYVY &&
987*61046927SAndroid Build Coastguard Worker        pscreen->is_format_supported(pscreen, PIPE_FORMAT_G8R8_B8R8_UNORM,
988*61046927SAndroid Build Coastguard Worker                                     screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
989*61046927SAndroid Build Coastguard Worker       map = &g8r8_b8r8_mapping;
990*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
991*61046927SAndroid Build Coastguard Worker    }
992*61046927SAndroid Build Coastguard Worker 
993*61046927SAndroid Build Coastguard Worker    if (!tex_usage && map->pipe_format == PIPE_FORMAT_VYUY &&
994*61046927SAndroid Build Coastguard Worker        pscreen->is_format_supported(pscreen, PIPE_FORMAT_B8R8_G8R8_UNORM,
995*61046927SAndroid Build Coastguard Worker                                     screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
996*61046927SAndroid Build Coastguard Worker       map = &b8r8_g8r8_mapping;
997*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
998*61046927SAndroid Build Coastguard Worker    }
999*61046927SAndroid Build Coastguard Worker 
1000*61046927SAndroid Build Coastguard Worker    if (!tex_usage && util_format_is_yuv(map->pipe_format)) {
1001*61046927SAndroid Build Coastguard Worker       /* YUV format sampling can be emulated by the GL gallium frontend by
1002*61046927SAndroid Build Coastguard Worker        * using multiple samplers of varying formats.
1003*61046927SAndroid Build Coastguard Worker        * If no tex_usage is set and we detect a YUV format,
1004*61046927SAndroid Build Coastguard Worker        * test for support of all planes' sampler formats and
1005*61046927SAndroid Build Coastguard Worker        * add sampler view usage.
1006*61046927SAndroid Build Coastguard Worker        */
1007*61046927SAndroid Build Coastguard Worker       use_lowered = true;
1008*61046927SAndroid Build Coastguard Worker       if (dri2_yuv_dma_buf_supported(screen, map))
1009*61046927SAndroid Build Coastguard Worker          tex_usage |= PIPE_BIND_SAMPLER_VIEW;
1010*61046927SAndroid Build Coastguard Worker    }
1011*61046927SAndroid Build Coastguard Worker 
1012*61046927SAndroid Build Coastguard Worker    if (!tex_usage)
1013*61046927SAndroid Build Coastguard Worker       return NULL;
1014*61046927SAndroid Build Coastguard Worker 
1015*61046927SAndroid Build Coastguard Worker    img = CALLOC_STRUCT(__DRIimageRec);
1016*61046927SAndroid Build Coastguard Worker    if (!img)
1017*61046927SAndroid Build Coastguard Worker       return NULL;
1018*61046927SAndroid Build Coastguard Worker 
1019*61046927SAndroid Build Coastguard Worker    memset(&templ, 0, sizeof(templ));
1020*61046927SAndroid Build Coastguard Worker    templ.bind = tex_usage | bind;
1021*61046927SAndroid Build Coastguard Worker    templ.target = screen->target;
1022*61046927SAndroid Build Coastguard Worker    templ.last_level = 0;
1023*61046927SAndroid Build Coastguard Worker    templ.depth0 = 1;
1024*61046927SAndroid Build Coastguard Worker    templ.array_size = 1;
1025*61046927SAndroid Build Coastguard Worker    templ.width0 = width;
1026*61046927SAndroid Build Coastguard Worker    templ.height0 = height;
1027*61046927SAndroid Build Coastguard Worker 
1028*61046927SAndroid Build Coastguard Worker    for (i = num_handles - 1; i >= format_planes; i--) {
1029*61046927SAndroid Build Coastguard Worker       struct pipe_resource *tex;
1030*61046927SAndroid Build Coastguard Worker 
1031*61046927SAndroid Build Coastguard Worker       templ.next = img->texture;
1032*61046927SAndroid Build Coastguard Worker 
1033*61046927SAndroid Build Coastguard Worker       tex = pscreen->resource_from_handle(pscreen, &templ, &whandle[i],
1034*61046927SAndroid Build Coastguard Worker                                           PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
1035*61046927SAndroid Build Coastguard Worker       if (!tex) {
1036*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(&img->texture, NULL);
1037*61046927SAndroid Build Coastguard Worker          FREE(img);
1038*61046927SAndroid Build Coastguard Worker          return NULL;
1039*61046927SAndroid Build Coastguard Worker       }
1040*61046927SAndroid Build Coastguard Worker 
1041*61046927SAndroid Build Coastguard Worker       img->texture = tex;
1042*61046927SAndroid Build Coastguard Worker    }
1043*61046927SAndroid Build Coastguard Worker 
1044*61046927SAndroid Build Coastguard Worker    for (i = (use_lowered ? map->nplanes : format_planes) - 1; i >= 0; i--) {
1045*61046927SAndroid Build Coastguard Worker       struct pipe_resource *tex;
1046*61046927SAndroid Build Coastguard Worker 
1047*61046927SAndroid Build Coastguard Worker       templ.next = img->texture;
1048*61046927SAndroid Build Coastguard Worker       templ.width0 = width >> map->planes[i].width_shift;
1049*61046927SAndroid Build Coastguard Worker       templ.height0 = height >> map->planes[i].height_shift;
1050*61046927SAndroid Build Coastguard Worker       if (use_lowered)
1051*61046927SAndroid Build Coastguard Worker          templ.format = dri2_get_pipe_format_for_dri_format(map->planes[i].dri_format);
1052*61046927SAndroid Build Coastguard Worker       else
1053*61046927SAndroid Build Coastguard Worker          templ.format = map->pipe_format;
1054*61046927SAndroid Build Coastguard Worker       assert(templ.format != PIPE_FORMAT_NONE);
1055*61046927SAndroid Build Coastguard Worker 
1056*61046927SAndroid Build Coastguard Worker       tex = pscreen->resource_from_handle(pscreen,
1057*61046927SAndroid Build Coastguard Worker                &templ, &whandle[use_lowered ? map->planes[i].buffer_index : i],
1058*61046927SAndroid Build Coastguard Worker                PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
1059*61046927SAndroid Build Coastguard Worker       if (!tex) {
1060*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(&img->texture, NULL);
1061*61046927SAndroid Build Coastguard Worker          FREE(img);
1062*61046927SAndroid Build Coastguard Worker          return NULL;
1063*61046927SAndroid Build Coastguard Worker       }
1064*61046927SAndroid Build Coastguard Worker 
1065*61046927SAndroid Build Coastguard Worker       /* Reject image creation if there's an inconsistency between
1066*61046927SAndroid Build Coastguard Worker        * content protection status of tex and img.
1067*61046927SAndroid Build Coastguard Worker        */
1068*61046927SAndroid Build Coastguard Worker       const struct driOptionCache *optionCache = &screen->dev->option_cache;
1069*61046927SAndroid Build Coastguard Worker       if (driQueryOptionb(optionCache, "force_protected_content_check") &&
1070*61046927SAndroid Build Coastguard Worker           (tex->bind & PIPE_BIND_PROTECTED) != (bind & PIPE_BIND_PROTECTED)) {
1071*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(&img->texture, NULL);
1072*61046927SAndroid Build Coastguard Worker          pipe_resource_reference(&tex, NULL);
1073*61046927SAndroid Build Coastguard Worker          FREE(img);
1074*61046927SAndroid Build Coastguard Worker          return NULL;
1075*61046927SAndroid Build Coastguard Worker       }
1076*61046927SAndroid Build Coastguard Worker 
1077*61046927SAndroid Build Coastguard Worker       img->texture = tex;
1078*61046927SAndroid Build Coastguard Worker    }
1079*61046927SAndroid Build Coastguard Worker 
1080*61046927SAndroid Build Coastguard Worker    img->level = 0;
1081*61046927SAndroid Build Coastguard Worker    img->layer = 0;
1082*61046927SAndroid Build Coastguard Worker    img->use = 0;
1083*61046927SAndroid Build Coastguard Worker    img->in_fence_fd = -1;
1084*61046927SAndroid Build Coastguard Worker    img->loader_private = loaderPrivate;
1085*61046927SAndroid Build Coastguard Worker    img->screen = screen;
1086*61046927SAndroid Build Coastguard Worker 
1087*61046927SAndroid Build Coastguard Worker    return img;
1088*61046927SAndroid Build Coastguard Worker }
1089*61046927SAndroid Build Coastguard Worker 
1090*61046927SAndroid Build Coastguard Worker static unsigned
dri2_get_modifier_num_planes(__DRIscreen * _screen,uint64_t modifier,int fourcc)1091*61046927SAndroid Build Coastguard Worker dri2_get_modifier_num_planes(__DRIscreen *_screen,
1092*61046927SAndroid Build Coastguard Worker                              uint64_t modifier, int fourcc)
1093*61046927SAndroid Build Coastguard Worker {
1094*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = dri_screen(_screen)->base.screen;
1095*61046927SAndroid Build Coastguard Worker    const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
1096*61046927SAndroid Build Coastguard Worker 
1097*61046927SAndroid Build Coastguard Worker    if (!map)
1098*61046927SAndroid Build Coastguard Worker       return 0;
1099*61046927SAndroid Build Coastguard Worker 
1100*61046927SAndroid Build Coastguard Worker    switch (modifier) {
1101*61046927SAndroid Build Coastguard Worker    case DRM_FORMAT_MOD_LINEAR:
1102*61046927SAndroid Build Coastguard Worker    /* DRM_FORMAT_MOD_NONE is the same as LINEAR */
1103*61046927SAndroid Build Coastguard Worker    case DRM_FORMAT_MOD_INVALID:
1104*61046927SAndroid Build Coastguard Worker       return util_format_get_num_planes(map->pipe_format);
1105*61046927SAndroid Build Coastguard Worker    default:
1106*61046927SAndroid Build Coastguard Worker       if (!pscreen->is_dmabuf_modifier_supported ||
1107*61046927SAndroid Build Coastguard Worker           !pscreen->is_dmabuf_modifier_supported(pscreen, modifier,
1108*61046927SAndroid Build Coastguard Worker                                                  map->pipe_format, NULL)) {
1109*61046927SAndroid Build Coastguard Worker          return 0;
1110*61046927SAndroid Build Coastguard Worker       }
1111*61046927SAndroid Build Coastguard Worker 
1112*61046927SAndroid Build Coastguard Worker       if (pscreen->get_dmabuf_modifier_planes) {
1113*61046927SAndroid Build Coastguard Worker          return pscreen->get_dmabuf_modifier_planes(pscreen, modifier,
1114*61046927SAndroid Build Coastguard Worker                                                     map->pipe_format);
1115*61046927SAndroid Build Coastguard Worker       }
1116*61046927SAndroid Build Coastguard Worker 
1117*61046927SAndroid Build Coastguard Worker       return map->nplanes;
1118*61046927SAndroid Build Coastguard Worker    }
1119*61046927SAndroid Build Coastguard Worker }
1120*61046927SAndroid Build Coastguard Worker 
1121*61046927SAndroid Build Coastguard Worker __DRIimage *
dri_create_image(__DRIscreen * _screen,int width,int height,int format,const uint64_t * modifiers,const unsigned _count,unsigned int use,void * loaderPrivate)1122*61046927SAndroid Build Coastguard Worker dri_create_image(__DRIscreen *_screen,
1123*61046927SAndroid Build Coastguard Worker                   int width, int height,
1124*61046927SAndroid Build Coastguard Worker                   int format,
1125*61046927SAndroid Build Coastguard Worker                   const uint64_t *modifiers,
1126*61046927SAndroid Build Coastguard Worker                   const unsigned _count,
1127*61046927SAndroid Build Coastguard Worker                   unsigned int use,
1128*61046927SAndroid Build Coastguard Worker                   void *loaderPrivate)
1129*61046927SAndroid Build Coastguard Worker {
1130*61046927SAndroid Build Coastguard Worker    const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format);
1131*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = dri_screen(_screen);
1132*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = screen->base.screen;
1133*61046927SAndroid Build Coastguard Worker    __DRIimage *img;
1134*61046927SAndroid Build Coastguard Worker    struct pipe_resource templ;
1135*61046927SAndroid Build Coastguard Worker    unsigned tex_usage = 0;
1136*61046927SAndroid Build Coastguard Worker    unsigned count = _count;
1137*61046927SAndroid Build Coastguard Worker 
1138*61046927SAndroid Build Coastguard Worker    if (!map)
1139*61046927SAndroid Build Coastguard Worker       return NULL;
1140*61046927SAndroid Build Coastguard Worker 
1141*61046927SAndroid Build Coastguard Worker    if (count == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID) {
1142*61046927SAndroid Build Coastguard Worker       count = 0;
1143*61046927SAndroid Build Coastguard Worker       modifiers = NULL;
1144*61046927SAndroid Build Coastguard Worker    }
1145*61046927SAndroid Build Coastguard Worker 
1146*61046927SAndroid Build Coastguard Worker    if (!pscreen->resource_create_with_modifiers && count > 0) {
1147*61046927SAndroid Build Coastguard Worker       bool invalid_ok = false;
1148*61046927SAndroid Build Coastguard Worker       bool linear_ok = false;
1149*61046927SAndroid Build Coastguard Worker 
1150*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < _count; i++) {
1151*61046927SAndroid Build Coastguard Worker          if (modifiers[i] == DRM_FORMAT_MOD_LINEAR)
1152*61046927SAndroid Build Coastguard Worker             linear_ok = true;
1153*61046927SAndroid Build Coastguard Worker          else if (modifiers[i] == DRM_FORMAT_MOD_INVALID)
1154*61046927SAndroid Build Coastguard Worker             invalid_ok = true;
1155*61046927SAndroid Build Coastguard Worker       }
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker       if (invalid_ok) {
1158*61046927SAndroid Build Coastguard Worker          count = 0;
1159*61046927SAndroid Build Coastguard Worker          modifiers = NULL;
1160*61046927SAndroid Build Coastguard Worker       } else if (linear_ok) {
1161*61046927SAndroid Build Coastguard Worker          count = 0;
1162*61046927SAndroid Build Coastguard Worker          modifiers = NULL;
1163*61046927SAndroid Build Coastguard Worker          use |= __DRI_IMAGE_USE_LINEAR;
1164*61046927SAndroid Build Coastguard Worker       } else {
1165*61046927SAndroid Build Coastguard Worker          return NULL;
1166*61046927SAndroid Build Coastguard Worker       }
1167*61046927SAndroid Build Coastguard Worker    }
1168*61046927SAndroid Build Coastguard Worker 
1169*61046927SAndroid Build Coastguard Worker    if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target,
1170*61046927SAndroid Build Coastguard Worker                                     0, 0, PIPE_BIND_RENDER_TARGET))
1171*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_RENDER_TARGET;
1172*61046927SAndroid Build Coastguard Worker    if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target,
1173*61046927SAndroid Build Coastguard Worker                                     0, 0, PIPE_BIND_SAMPLER_VIEW))
1174*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
1175*61046927SAndroid Build Coastguard Worker 
1176*61046927SAndroid Build Coastguard Worker    if (!tex_usage)
1177*61046927SAndroid Build Coastguard Worker       return NULL;
1178*61046927SAndroid Build Coastguard Worker 
1179*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_SCANOUT)
1180*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SCANOUT;
1181*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_SHARE)
1182*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_SHARED;
1183*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_LINEAR)
1184*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_LINEAR;
1185*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_CURSOR) {
1186*61046927SAndroid Build Coastguard Worker       if (width != 64 || height != 64)
1187*61046927SAndroid Build Coastguard Worker          return NULL;
1188*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_CURSOR;
1189*61046927SAndroid Build Coastguard Worker    }
1190*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_PROTECTED)
1191*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_PROTECTED;
1192*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_PRIME_BUFFER)
1193*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_PRIME_BLIT_DST;
1194*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_FRONT_RENDERING)
1195*61046927SAndroid Build Coastguard Worker       tex_usage |= PIPE_BIND_USE_FRONT_RENDERING;
1196*61046927SAndroid Build Coastguard Worker 
1197*61046927SAndroid Build Coastguard Worker    img = CALLOC_STRUCT(__DRIimageRec);
1198*61046927SAndroid Build Coastguard Worker    if (!img)
1199*61046927SAndroid Build Coastguard Worker       return NULL;
1200*61046927SAndroid Build Coastguard Worker 
1201*61046927SAndroid Build Coastguard Worker    memset(&templ, 0, sizeof(templ));
1202*61046927SAndroid Build Coastguard Worker    templ.bind = tex_usage;
1203*61046927SAndroid Build Coastguard Worker    templ.format = map->pipe_format;
1204*61046927SAndroid Build Coastguard Worker    templ.target = PIPE_TEXTURE_2D;
1205*61046927SAndroid Build Coastguard Worker    templ.last_level = 0;
1206*61046927SAndroid Build Coastguard Worker    templ.width0 = width;
1207*61046927SAndroid Build Coastguard Worker    templ.height0 = height;
1208*61046927SAndroid Build Coastguard Worker    templ.depth0 = 1;
1209*61046927SAndroid Build Coastguard Worker    templ.array_size = 1;
1210*61046927SAndroid Build Coastguard Worker 
1211*61046927SAndroid Build Coastguard Worker    if (modifiers)
1212*61046927SAndroid Build Coastguard Worker       img->texture =
1213*61046927SAndroid Build Coastguard Worker          screen->base.screen
1214*61046927SAndroid Build Coastguard Worker             ->resource_create_with_modifiers(screen->base.screen,
1215*61046927SAndroid Build Coastguard Worker                                              &templ,
1216*61046927SAndroid Build Coastguard Worker                                              modifiers,
1217*61046927SAndroid Build Coastguard Worker                                              count);
1218*61046927SAndroid Build Coastguard Worker    else
1219*61046927SAndroid Build Coastguard Worker       img->texture =
1220*61046927SAndroid Build Coastguard Worker          screen->base.screen->resource_create(screen->base.screen, &templ);
1221*61046927SAndroid Build Coastguard Worker    if (!img->texture) {
1222*61046927SAndroid Build Coastguard Worker       FREE(img);
1223*61046927SAndroid Build Coastguard Worker       return NULL;
1224*61046927SAndroid Build Coastguard Worker    }
1225*61046927SAndroid Build Coastguard Worker 
1226*61046927SAndroid Build Coastguard Worker    img->level = 0;
1227*61046927SAndroid Build Coastguard Worker    img->layer = 0;
1228*61046927SAndroid Build Coastguard Worker    img->dri_format = format;
1229*61046927SAndroid Build Coastguard Worker    img->dri_fourcc = map->dri_fourcc;
1230*61046927SAndroid Build Coastguard Worker    img->dri_components = 0;
1231*61046927SAndroid Build Coastguard Worker    img->use = use;
1232*61046927SAndroid Build Coastguard Worker    img->in_fence_fd = -1;
1233*61046927SAndroid Build Coastguard Worker 
1234*61046927SAndroid Build Coastguard Worker    img->loader_private = loaderPrivate;
1235*61046927SAndroid Build Coastguard Worker    img->screen = screen;
1236*61046927SAndroid Build Coastguard Worker    return img;
1237*61046927SAndroid Build Coastguard Worker }
1238*61046927SAndroid Build Coastguard Worker 
1239*61046927SAndroid Build Coastguard Worker static bool
dri2_query_image_common(__DRIimage * image,int attrib,int * value)1240*61046927SAndroid Build Coastguard Worker dri2_query_image_common(__DRIimage *image, int attrib, int *value)
1241*61046927SAndroid Build Coastguard Worker {
1242*61046927SAndroid Build Coastguard Worker    switch (attrib) {
1243*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_WIDTH:
1244*61046927SAndroid Build Coastguard Worker       *value = image->texture->width0;
1245*61046927SAndroid Build Coastguard Worker       return true;
1246*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_HEIGHT:
1247*61046927SAndroid Build Coastguard Worker       *value = image->texture->height0;
1248*61046927SAndroid Build Coastguard Worker       return true;
1249*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_COMPONENTS:
1250*61046927SAndroid Build Coastguard Worker       if (image->dri_components == 0)
1251*61046927SAndroid Build Coastguard Worker          return false;
1252*61046927SAndroid Build Coastguard Worker       *value = image->dri_components;
1253*61046927SAndroid Build Coastguard Worker       return true;
1254*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_FOURCC:
1255*61046927SAndroid Build Coastguard Worker       if (image->dri_fourcc) {
1256*61046927SAndroid Build Coastguard Worker          *value = image->dri_fourcc;
1257*61046927SAndroid Build Coastguard Worker       } else {
1258*61046927SAndroid Build Coastguard Worker          const struct dri2_format_mapping *map;
1259*61046927SAndroid Build Coastguard Worker 
1260*61046927SAndroid Build Coastguard Worker          map = dri2_get_mapping_by_format(image->dri_format);
1261*61046927SAndroid Build Coastguard Worker          if (!map)
1262*61046927SAndroid Build Coastguard Worker             return false;
1263*61046927SAndroid Build Coastguard Worker 
1264*61046927SAndroid Build Coastguard Worker          *value = map->dri_fourcc;
1265*61046927SAndroid Build Coastguard Worker       }
1266*61046927SAndroid Build Coastguard Worker       return true;
1267*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_COMPRESSION_RATE:
1268*61046927SAndroid Build Coastguard Worker       if (!image->texture)
1269*61046927SAndroid Build Coastguard Worker          *value = __DRI_FIXED_RATE_COMPRESSION_NONE;
1270*61046927SAndroid Build Coastguard Worker       else
1271*61046927SAndroid Build Coastguard Worker          *value = to_dri_compression_rate(image->texture->compression_rate);
1272*61046927SAndroid Build Coastguard Worker       return true;
1273*61046927SAndroid Build Coastguard Worker 
1274*61046927SAndroid Build Coastguard Worker    default:
1275*61046927SAndroid Build Coastguard Worker       return false;
1276*61046927SAndroid Build Coastguard Worker    }
1277*61046927SAndroid Build Coastguard Worker }
1278*61046927SAndroid Build Coastguard Worker 
1279*61046927SAndroid Build Coastguard Worker static bool
dri2_query_image_by_resource_handle(__DRIimage * image,int attrib,int * value)1280*61046927SAndroid Build Coastguard Worker dri2_query_image_by_resource_handle(__DRIimage *image, int attrib, int *value)
1281*61046927SAndroid Build Coastguard Worker {
1282*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = image->texture->screen;
1283*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandle;
1284*61046927SAndroid Build Coastguard Worker    struct pipe_resource *tex;
1285*61046927SAndroid Build Coastguard Worker    unsigned usage;
1286*61046927SAndroid Build Coastguard Worker    memset(&whandle, 0, sizeof(whandle));
1287*61046927SAndroid Build Coastguard Worker    whandle.plane = image->plane;
1288*61046927SAndroid Build Coastguard Worker    int i;
1289*61046927SAndroid Build Coastguard Worker 
1290*61046927SAndroid Build Coastguard Worker    switch (attrib) {
1291*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_STRIDE:
1292*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_OFFSET:
1293*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_HANDLE:
1294*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_KMS;
1295*61046927SAndroid Build Coastguard Worker       break;
1296*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_NAME:
1297*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_SHARED;
1298*61046927SAndroid Build Coastguard Worker       break;
1299*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_FD:
1300*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_FD;
1301*61046927SAndroid Build Coastguard Worker       break;
1302*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_NUM_PLANES:
1303*61046927SAndroid Build Coastguard Worker       for (i = 0, tex = image->texture; tex; tex = tex->next)
1304*61046927SAndroid Build Coastguard Worker          i++;
1305*61046927SAndroid Build Coastguard Worker       *value = i;
1306*61046927SAndroid Build Coastguard Worker       return true;
1307*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
1308*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
1309*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_KMS;
1310*61046927SAndroid Build Coastguard Worker       whandle.modifier = DRM_FORMAT_MOD_INVALID;
1311*61046927SAndroid Build Coastguard Worker       break;
1312*61046927SAndroid Build Coastguard Worker    default:
1313*61046927SAndroid Build Coastguard Worker       return false;
1314*61046927SAndroid Build Coastguard Worker    }
1315*61046927SAndroid Build Coastguard Worker 
1316*61046927SAndroid Build Coastguard Worker    usage = PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE;
1317*61046927SAndroid Build Coastguard Worker 
1318*61046927SAndroid Build Coastguard Worker    if (image->use & __DRI_IMAGE_USE_BACKBUFFER)
1319*61046927SAndroid Build Coastguard Worker       usage |= PIPE_HANDLE_USAGE_EXPLICIT_FLUSH;
1320*61046927SAndroid Build Coastguard Worker 
1321*61046927SAndroid Build Coastguard Worker    if (!pscreen->resource_get_handle(pscreen, NULL, image->texture,
1322*61046927SAndroid Build Coastguard Worker                                      &whandle, usage))
1323*61046927SAndroid Build Coastguard Worker       return false;
1324*61046927SAndroid Build Coastguard Worker 
1325*61046927SAndroid Build Coastguard Worker    switch (attrib) {
1326*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_STRIDE:
1327*61046927SAndroid Build Coastguard Worker       *value = whandle.stride;
1328*61046927SAndroid Build Coastguard Worker       return true;
1329*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_OFFSET:
1330*61046927SAndroid Build Coastguard Worker       *value = whandle.offset;
1331*61046927SAndroid Build Coastguard Worker       return true;
1332*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_HANDLE:
1333*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_NAME:
1334*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_FD:
1335*61046927SAndroid Build Coastguard Worker       *value = whandle.handle;
1336*61046927SAndroid Build Coastguard Worker       return true;
1337*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
1338*61046927SAndroid Build Coastguard Worker       if (whandle.modifier == DRM_FORMAT_MOD_INVALID)
1339*61046927SAndroid Build Coastguard Worker          return false;
1340*61046927SAndroid Build Coastguard Worker       *value = (whandle.modifier >> 32) & 0xffffffff;
1341*61046927SAndroid Build Coastguard Worker       return true;
1342*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
1343*61046927SAndroid Build Coastguard Worker       if (whandle.modifier == DRM_FORMAT_MOD_INVALID)
1344*61046927SAndroid Build Coastguard Worker          return false;
1345*61046927SAndroid Build Coastguard Worker       *value = whandle.modifier & 0xffffffff;
1346*61046927SAndroid Build Coastguard Worker       return true;
1347*61046927SAndroid Build Coastguard Worker    default:
1348*61046927SAndroid Build Coastguard Worker       return false;
1349*61046927SAndroid Build Coastguard Worker    }
1350*61046927SAndroid Build Coastguard Worker }
1351*61046927SAndroid Build Coastguard Worker 
1352*61046927SAndroid Build Coastguard Worker static bool
dri2_resource_get_param(__DRIimage * image,enum pipe_resource_param param,unsigned handle_usage,uint64_t * value)1353*61046927SAndroid Build Coastguard Worker dri2_resource_get_param(__DRIimage *image, enum pipe_resource_param param,
1354*61046927SAndroid Build Coastguard Worker                         unsigned handle_usage, uint64_t *value)
1355*61046927SAndroid Build Coastguard Worker {
1356*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = image->texture->screen;
1357*61046927SAndroid Build Coastguard Worker    if (!pscreen->resource_get_param)
1358*61046927SAndroid Build Coastguard Worker       return false;
1359*61046927SAndroid Build Coastguard Worker 
1360*61046927SAndroid Build Coastguard Worker    if (image->use & __DRI_IMAGE_USE_BACKBUFFER)
1361*61046927SAndroid Build Coastguard Worker       handle_usage |= PIPE_HANDLE_USAGE_EXPLICIT_FLUSH;
1362*61046927SAndroid Build Coastguard Worker 
1363*61046927SAndroid Build Coastguard Worker    return pscreen->resource_get_param(pscreen, NULL, image->texture,
1364*61046927SAndroid Build Coastguard Worker                                       image->plane, 0, 0, param, handle_usage,
1365*61046927SAndroid Build Coastguard Worker                                       value);
1366*61046927SAndroid Build Coastguard Worker }
1367*61046927SAndroid Build Coastguard Worker 
1368*61046927SAndroid Build Coastguard Worker static bool
dri2_query_image_by_resource_param(__DRIimage * image,int attrib,int * value)1369*61046927SAndroid Build Coastguard Worker dri2_query_image_by_resource_param(__DRIimage *image, int attrib, int *value)
1370*61046927SAndroid Build Coastguard Worker {
1371*61046927SAndroid Build Coastguard Worker    enum pipe_resource_param param;
1372*61046927SAndroid Build Coastguard Worker    uint64_t res_param;
1373*61046927SAndroid Build Coastguard Worker    unsigned handle_usage;
1374*61046927SAndroid Build Coastguard Worker 
1375*61046927SAndroid Build Coastguard Worker    if (!image->texture->screen->resource_get_param)
1376*61046927SAndroid Build Coastguard Worker       return false;
1377*61046927SAndroid Build Coastguard Worker 
1378*61046927SAndroid Build Coastguard Worker    switch (attrib) {
1379*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_STRIDE:
1380*61046927SAndroid Build Coastguard Worker       param = PIPE_RESOURCE_PARAM_STRIDE;
1381*61046927SAndroid Build Coastguard Worker       break;
1382*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_OFFSET:
1383*61046927SAndroid Build Coastguard Worker       param = PIPE_RESOURCE_PARAM_OFFSET;
1384*61046927SAndroid Build Coastguard Worker       break;
1385*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_NUM_PLANES:
1386*61046927SAndroid Build Coastguard Worker       param = PIPE_RESOURCE_PARAM_NPLANES;
1387*61046927SAndroid Build Coastguard Worker       break;
1388*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
1389*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
1390*61046927SAndroid Build Coastguard Worker       param = PIPE_RESOURCE_PARAM_MODIFIER;
1391*61046927SAndroid Build Coastguard Worker       break;
1392*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_HANDLE:
1393*61046927SAndroid Build Coastguard Worker       param = PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS;
1394*61046927SAndroid Build Coastguard Worker       break;
1395*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_NAME:
1396*61046927SAndroid Build Coastguard Worker       param = PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED;
1397*61046927SAndroid Build Coastguard Worker       break;
1398*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_FD:
1399*61046927SAndroid Build Coastguard Worker       param = PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD;
1400*61046927SAndroid Build Coastguard Worker       break;
1401*61046927SAndroid Build Coastguard Worker    default:
1402*61046927SAndroid Build Coastguard Worker       return false;
1403*61046927SAndroid Build Coastguard Worker    }
1404*61046927SAndroid Build Coastguard Worker 
1405*61046927SAndroid Build Coastguard Worker    handle_usage = PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE;
1406*61046927SAndroid Build Coastguard Worker 
1407*61046927SAndroid Build Coastguard Worker    if (!dri2_resource_get_param(image, param, handle_usage, &res_param))
1408*61046927SAndroid Build Coastguard Worker       return false;
1409*61046927SAndroid Build Coastguard Worker 
1410*61046927SAndroid Build Coastguard Worker    switch (attrib) {
1411*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_STRIDE:
1412*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_OFFSET:
1413*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_NUM_PLANES:
1414*61046927SAndroid Build Coastguard Worker       if (res_param > INT_MAX)
1415*61046927SAndroid Build Coastguard Worker          return false;
1416*61046927SAndroid Build Coastguard Worker       *value = (int)res_param;
1417*61046927SAndroid Build Coastguard Worker       return true;
1418*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_HANDLE:
1419*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_NAME:
1420*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_FD:
1421*61046927SAndroid Build Coastguard Worker       if (res_param > UINT_MAX)
1422*61046927SAndroid Build Coastguard Worker          return false;
1423*61046927SAndroid Build Coastguard Worker       *value = (int)res_param;
1424*61046927SAndroid Build Coastguard Worker       return true;
1425*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
1426*61046927SAndroid Build Coastguard Worker       if (res_param == DRM_FORMAT_MOD_INVALID)
1427*61046927SAndroid Build Coastguard Worker          return false;
1428*61046927SAndroid Build Coastguard Worker       *value = (res_param >> 32) & 0xffffffff;
1429*61046927SAndroid Build Coastguard Worker       return true;
1430*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
1431*61046927SAndroid Build Coastguard Worker       if (res_param == DRM_FORMAT_MOD_INVALID)
1432*61046927SAndroid Build Coastguard Worker          return false;
1433*61046927SAndroid Build Coastguard Worker       *value = res_param & 0xffffffff;
1434*61046927SAndroid Build Coastguard Worker       return true;
1435*61046927SAndroid Build Coastguard Worker    default:
1436*61046927SAndroid Build Coastguard Worker       return false;
1437*61046927SAndroid Build Coastguard Worker    }
1438*61046927SAndroid Build Coastguard Worker }
1439*61046927SAndroid Build Coastguard Worker 
1440*61046927SAndroid Build Coastguard Worker GLboolean
dri2_query_image(__DRIimage * image,int attrib,int * value)1441*61046927SAndroid Build Coastguard Worker dri2_query_image(__DRIimage *image, int attrib, int *value)
1442*61046927SAndroid Build Coastguard Worker {
1443*61046927SAndroid Build Coastguard Worker    if (dri2_query_image_common(image, attrib, value))
1444*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1445*61046927SAndroid Build Coastguard Worker    else if (dri2_query_image_by_resource_param(image, attrib, value))
1446*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1447*61046927SAndroid Build Coastguard Worker    else if (dri2_query_image_by_resource_handle(image, attrib, value))
1448*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1449*61046927SAndroid Build Coastguard Worker    else
1450*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
1451*61046927SAndroid Build Coastguard Worker }
1452*61046927SAndroid Build Coastguard Worker 
1453*61046927SAndroid Build Coastguard Worker __DRIimage *
dri2_dup_image(__DRIimage * image,void * loaderPrivate)1454*61046927SAndroid Build Coastguard Worker dri2_dup_image(__DRIimage *image, void *loaderPrivate)
1455*61046927SAndroid Build Coastguard Worker {
1456*61046927SAndroid Build Coastguard Worker    __DRIimage *img;
1457*61046927SAndroid Build Coastguard Worker 
1458*61046927SAndroid Build Coastguard Worker    img = CALLOC_STRUCT(__DRIimageRec);
1459*61046927SAndroid Build Coastguard Worker    if (!img)
1460*61046927SAndroid Build Coastguard Worker       return NULL;
1461*61046927SAndroid Build Coastguard Worker 
1462*61046927SAndroid Build Coastguard Worker    img->texture = NULL;
1463*61046927SAndroid Build Coastguard Worker    pipe_resource_reference(&img->texture, image->texture);
1464*61046927SAndroid Build Coastguard Worker    img->level = image->level;
1465*61046927SAndroid Build Coastguard Worker    img->layer = image->layer;
1466*61046927SAndroid Build Coastguard Worker    img->dri_format = image->dri_format;
1467*61046927SAndroid Build Coastguard Worker    img->internal_format = image->internal_format;
1468*61046927SAndroid Build Coastguard Worker    /* This should be 0 for sub images, but dup is also used for base images. */
1469*61046927SAndroid Build Coastguard Worker    img->dri_components = image->dri_components;
1470*61046927SAndroid Build Coastguard Worker    img->use = image->use;
1471*61046927SAndroid Build Coastguard Worker    img->in_fence_fd = (image->in_fence_fd > 0) ?
1472*61046927SAndroid Build Coastguard Worker          os_dupfd_cloexec(image->in_fence_fd) : -1;
1473*61046927SAndroid Build Coastguard Worker    img->loader_private = loaderPrivate;
1474*61046927SAndroid Build Coastguard Worker    img->screen = image->screen;
1475*61046927SAndroid Build Coastguard Worker 
1476*61046927SAndroid Build Coastguard Worker    return img;
1477*61046927SAndroid Build Coastguard Worker }
1478*61046927SAndroid Build Coastguard Worker 
1479*61046927SAndroid Build Coastguard Worker GLboolean
dri2_validate_usage(__DRIimage * image,unsigned int use)1480*61046927SAndroid Build Coastguard Worker dri2_validate_usage(__DRIimage *image, unsigned int use)
1481*61046927SAndroid Build Coastguard Worker {
1482*61046927SAndroid Build Coastguard Worker    if (!image || !image->texture)
1483*61046927SAndroid Build Coastguard Worker       return false;
1484*61046927SAndroid Build Coastguard Worker 
1485*61046927SAndroid Build Coastguard Worker    struct pipe_screen *screen = image->texture->screen;
1486*61046927SAndroid Build Coastguard Worker    if (!screen->check_resource_capability)
1487*61046927SAndroid Build Coastguard Worker       return true;
1488*61046927SAndroid Build Coastguard Worker 
1489*61046927SAndroid Build Coastguard Worker    /* We don't want to check these:
1490*61046927SAndroid Build Coastguard Worker     *   __DRI_IMAGE_USE_SHARE (all images are shareable)
1491*61046927SAndroid Build Coastguard Worker     *   __DRI_IMAGE_USE_BACKBUFFER (all images support this)
1492*61046927SAndroid Build Coastguard Worker     */
1493*61046927SAndroid Build Coastguard Worker    unsigned bind = 0;
1494*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_SCANOUT)
1495*61046927SAndroid Build Coastguard Worker       bind |= PIPE_BIND_SCANOUT;
1496*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_LINEAR)
1497*61046927SAndroid Build Coastguard Worker       bind |= PIPE_BIND_LINEAR;
1498*61046927SAndroid Build Coastguard Worker    if (use & __DRI_IMAGE_USE_CURSOR)
1499*61046927SAndroid Build Coastguard Worker       bind |= PIPE_BIND_CURSOR;
1500*61046927SAndroid Build Coastguard Worker 
1501*61046927SAndroid Build Coastguard Worker    if (!bind)
1502*61046927SAndroid Build Coastguard Worker       return true;
1503*61046927SAndroid Build Coastguard Worker 
1504*61046927SAndroid Build Coastguard Worker    return screen->check_resource_capability(screen, image->texture, bind);
1505*61046927SAndroid Build Coastguard Worker }
1506*61046927SAndroid Build Coastguard Worker 
1507*61046927SAndroid Build Coastguard Worker __DRIimage *
dri2_from_names(__DRIscreen * screen,int width,int height,int fourcc,int * names,int num_names,int * strides,int * offsets,void * loaderPrivate)1508*61046927SAndroid Build Coastguard Worker dri2_from_names(__DRIscreen *screen, int width, int height, int fourcc,
1509*61046927SAndroid Build Coastguard Worker                 int *names, int num_names, int *strides, int *offsets,
1510*61046927SAndroid Build Coastguard Worker                 void *loaderPrivate)
1511*61046927SAndroid Build Coastguard Worker {
1512*61046927SAndroid Build Coastguard Worker    const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
1513*61046927SAndroid Build Coastguard Worker    __DRIimage *img;
1514*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandle;
1515*61046927SAndroid Build Coastguard Worker 
1516*61046927SAndroid Build Coastguard Worker    if (!map)
1517*61046927SAndroid Build Coastguard Worker       return NULL;
1518*61046927SAndroid Build Coastguard Worker 
1519*61046927SAndroid Build Coastguard Worker    if (num_names != 1)
1520*61046927SAndroid Build Coastguard Worker       return NULL;
1521*61046927SAndroid Build Coastguard Worker 
1522*61046927SAndroid Build Coastguard Worker    memset(&whandle, 0, sizeof(whandle));
1523*61046927SAndroid Build Coastguard Worker    whandle.type = WINSYS_HANDLE_TYPE_SHARED;
1524*61046927SAndroid Build Coastguard Worker    whandle.handle = names[0];
1525*61046927SAndroid Build Coastguard Worker    whandle.stride = strides[0];
1526*61046927SAndroid Build Coastguard Worker    whandle.offset = offsets[0];
1527*61046927SAndroid Build Coastguard Worker    whandle.format = map->pipe_format;
1528*61046927SAndroid Build Coastguard Worker    whandle.modifier = DRM_FORMAT_MOD_INVALID;
1529*61046927SAndroid Build Coastguard Worker 
1530*61046927SAndroid Build Coastguard Worker    img = dri_create_image_from_winsys(screen, width, height, map,
1531*61046927SAndroid Build Coastguard Worker                                        1, &whandle, 0, loaderPrivate);
1532*61046927SAndroid Build Coastguard Worker    if (img == NULL)
1533*61046927SAndroid Build Coastguard Worker       return NULL;
1534*61046927SAndroid Build Coastguard Worker 
1535*61046927SAndroid Build Coastguard Worker    img->dri_components = map->dri_components;
1536*61046927SAndroid Build Coastguard Worker    img->dri_fourcc = map->dri_fourcc;
1537*61046927SAndroid Build Coastguard Worker    img->dri_format = map->dri_format;
1538*61046927SAndroid Build Coastguard Worker 
1539*61046927SAndroid Build Coastguard Worker    return img;
1540*61046927SAndroid Build Coastguard Worker }
1541*61046927SAndroid Build Coastguard Worker 
1542*61046927SAndroid Build Coastguard Worker __DRIimage *
dri2_from_planar(__DRIimage * image,int plane,void * loaderPrivate)1543*61046927SAndroid Build Coastguard Worker dri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate)
1544*61046927SAndroid Build Coastguard Worker {
1545*61046927SAndroid Build Coastguard Worker    __DRIimage *img;
1546*61046927SAndroid Build Coastguard Worker 
1547*61046927SAndroid Build Coastguard Worker    if (plane < 0) {
1548*61046927SAndroid Build Coastguard Worker       return NULL;
1549*61046927SAndroid Build Coastguard Worker    } else if (plane > 0) {
1550*61046927SAndroid Build Coastguard Worker       uint64_t planes;
1551*61046927SAndroid Build Coastguard Worker       if (!dri2_resource_get_param(image, PIPE_RESOURCE_PARAM_NPLANES, 0,
1552*61046927SAndroid Build Coastguard Worker                                    &planes) ||
1553*61046927SAndroid Build Coastguard Worker           plane >= planes) {
1554*61046927SAndroid Build Coastguard Worker          return NULL;
1555*61046927SAndroid Build Coastguard Worker       }
1556*61046927SAndroid Build Coastguard Worker    }
1557*61046927SAndroid Build Coastguard Worker 
1558*61046927SAndroid Build Coastguard Worker    if (image->dri_components == 0) {
1559*61046927SAndroid Build Coastguard Worker       uint64_t modifier;
1560*61046927SAndroid Build Coastguard Worker       if (!dri2_resource_get_param(image, PIPE_RESOURCE_PARAM_MODIFIER, 0,
1561*61046927SAndroid Build Coastguard Worker                                    &modifier) ||
1562*61046927SAndroid Build Coastguard Worker           modifier == DRM_FORMAT_MOD_INVALID) {
1563*61046927SAndroid Build Coastguard Worker          return NULL;
1564*61046927SAndroid Build Coastguard Worker       }
1565*61046927SAndroid Build Coastguard Worker    }
1566*61046927SAndroid Build Coastguard Worker 
1567*61046927SAndroid Build Coastguard Worker    img = dri2_dup_image(image, loaderPrivate);
1568*61046927SAndroid Build Coastguard Worker    if (img == NULL)
1569*61046927SAndroid Build Coastguard Worker       return NULL;
1570*61046927SAndroid Build Coastguard Worker 
1571*61046927SAndroid Build Coastguard Worker    if (img->texture->screen->resource_changed)
1572*61046927SAndroid Build Coastguard Worker       img->texture->screen->resource_changed(img->texture->screen,
1573*61046927SAndroid Build Coastguard Worker                                              img->texture);
1574*61046927SAndroid Build Coastguard Worker 
1575*61046927SAndroid Build Coastguard Worker    /* set this to 0 for sub images. */
1576*61046927SAndroid Build Coastguard Worker    img->dri_components = 0;
1577*61046927SAndroid Build Coastguard Worker    img->plane = plane;
1578*61046927SAndroid Build Coastguard Worker    return img;
1579*61046927SAndroid Build Coastguard Worker }
1580*61046927SAndroid Build Coastguard Worker 
1581*61046927SAndroid Build Coastguard Worker bool
dri_query_dma_buf_modifiers(__DRIscreen * _screen,int fourcc,int max,uint64_t * modifiers,unsigned int * external_only,int * count)1582*61046927SAndroid Build Coastguard Worker dri_query_dma_buf_modifiers(__DRIscreen *_screen, int fourcc, int max,
1583*61046927SAndroid Build Coastguard Worker                              uint64_t *modifiers, unsigned int *external_only,
1584*61046927SAndroid Build Coastguard Worker                              int *count)
1585*61046927SAndroid Build Coastguard Worker {
1586*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = dri_screen(_screen);
1587*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = screen->base.screen;
1588*61046927SAndroid Build Coastguard Worker    const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
1589*61046927SAndroid Build Coastguard Worker    enum pipe_format format;
1590*61046927SAndroid Build Coastguard Worker 
1591*61046927SAndroid Build Coastguard Worker    if (!map)
1592*61046927SAndroid Build Coastguard Worker       return false;
1593*61046927SAndroid Build Coastguard Worker 
1594*61046927SAndroid Build Coastguard Worker    format = map->pipe_format;
1595*61046927SAndroid Build Coastguard Worker 
1596*61046927SAndroid Build Coastguard Worker    bool native_sampling = pscreen->is_format_supported(pscreen, format, screen->target, 0, 0,
1597*61046927SAndroid Build Coastguard Worker                                                        PIPE_BIND_SAMPLER_VIEW);
1598*61046927SAndroid Build Coastguard Worker    if (pscreen->is_format_supported(pscreen, format, screen->target, 0, 0,
1599*61046927SAndroid Build Coastguard Worker                                     PIPE_BIND_RENDER_TARGET) ||
1600*61046927SAndroid Build Coastguard Worker        native_sampling ||
1601*61046927SAndroid Build Coastguard Worker        dri2_yuv_dma_buf_supported(screen, map))  {
1602*61046927SAndroid Build Coastguard Worker       if (pscreen->query_dmabuf_modifiers != NULL) {
1603*61046927SAndroid Build Coastguard Worker          pscreen->query_dmabuf_modifiers(pscreen, format, max, modifiers,
1604*61046927SAndroid Build Coastguard Worker                                          external_only, count);
1605*61046927SAndroid Build Coastguard Worker          if (!native_sampling && external_only) {
1606*61046927SAndroid Build Coastguard Worker             /* To support it using YUV lowering, we need it to be samplerExternalOES.
1607*61046927SAndroid Build Coastguard Worker              */
1608*61046927SAndroid Build Coastguard Worker             for (int i = 0; i < *count; i++)
1609*61046927SAndroid Build Coastguard Worker                external_only[i] = true;
1610*61046927SAndroid Build Coastguard Worker          }
1611*61046927SAndroid Build Coastguard Worker       } else {
1612*61046927SAndroid Build Coastguard Worker          *count = 0;
1613*61046927SAndroid Build Coastguard Worker       }
1614*61046927SAndroid Build Coastguard Worker       return true;
1615*61046927SAndroid Build Coastguard Worker    }
1616*61046927SAndroid Build Coastguard Worker    return false;
1617*61046927SAndroid Build Coastguard Worker }
1618*61046927SAndroid Build Coastguard Worker 
1619*61046927SAndroid Build Coastguard Worker bool
dri2_query_dma_buf_format_modifier_attribs(__DRIscreen * _screen,uint32_t fourcc,uint64_t modifier,int attrib,uint64_t * value)1620*61046927SAndroid Build Coastguard Worker dri2_query_dma_buf_format_modifier_attribs(__DRIscreen *_screen,
1621*61046927SAndroid Build Coastguard Worker                                            uint32_t fourcc, uint64_t modifier,
1622*61046927SAndroid Build Coastguard Worker                                            int attrib, uint64_t *value)
1623*61046927SAndroid Build Coastguard Worker {
1624*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = dri_screen(_screen);
1625*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = screen->base.screen;
1626*61046927SAndroid Build Coastguard Worker 
1627*61046927SAndroid Build Coastguard Worker    if (!pscreen->query_dmabuf_modifiers)
1628*61046927SAndroid Build Coastguard Worker       return false;
1629*61046927SAndroid Build Coastguard Worker 
1630*61046927SAndroid Build Coastguard Worker    switch (attrib) {
1631*61046927SAndroid Build Coastguard Worker    case __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT: {
1632*61046927SAndroid Build Coastguard Worker       uint64_t mod_planes = dri2_get_modifier_num_planes(_screen, modifier,
1633*61046927SAndroid Build Coastguard Worker                                                          fourcc);
1634*61046927SAndroid Build Coastguard Worker       if (mod_planes > 0)
1635*61046927SAndroid Build Coastguard Worker          *value = mod_planes;
1636*61046927SAndroid Build Coastguard Worker       return mod_planes > 0;
1637*61046927SAndroid Build Coastguard Worker    }
1638*61046927SAndroid Build Coastguard Worker    default:
1639*61046927SAndroid Build Coastguard Worker       return false;
1640*61046927SAndroid Build Coastguard Worker    }
1641*61046927SAndroid Build Coastguard Worker }
1642*61046927SAndroid Build Coastguard Worker 
1643*61046927SAndroid Build Coastguard Worker __DRIimage *
dri2_from_dma_bufs(__DRIscreen * screen,int width,int height,int fourcc,uint64_t modifier,int * fds,int num_fds,int * strides,int * offsets,enum __DRIYUVColorSpace yuv_color_space,enum __DRISampleRange sample_range,enum __DRIChromaSiting horizontal_siting,enum __DRIChromaSiting vertical_siting,uint32_t dri_flags,unsigned * error,void * loaderPrivate)1644*61046927SAndroid Build Coastguard Worker dri2_from_dma_bufs(__DRIscreen *screen,
1645*61046927SAndroid Build Coastguard Worker                     int width, int height, int fourcc,
1646*61046927SAndroid Build Coastguard Worker                     uint64_t modifier, int *fds, int num_fds,
1647*61046927SAndroid Build Coastguard Worker                     int *strides, int *offsets,
1648*61046927SAndroid Build Coastguard Worker                     enum __DRIYUVColorSpace yuv_color_space,
1649*61046927SAndroid Build Coastguard Worker                     enum __DRISampleRange sample_range,
1650*61046927SAndroid Build Coastguard Worker                     enum __DRIChromaSiting horizontal_siting,
1651*61046927SAndroid Build Coastguard Worker                     enum __DRIChromaSiting vertical_siting,
1652*61046927SAndroid Build Coastguard Worker                     uint32_t dri_flags,
1653*61046927SAndroid Build Coastguard Worker                     unsigned *error,
1654*61046927SAndroid Build Coastguard Worker                     void *loaderPrivate)
1655*61046927SAndroid Build Coastguard Worker {
1656*61046927SAndroid Build Coastguard Worker    __DRIimage *img;
1657*61046927SAndroid Build Coastguard Worker    const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
1658*61046927SAndroid Build Coastguard Worker 
1659*61046927SAndroid Build Coastguard Worker    if (!dri_screen(screen)->dmabuf_import) {
1660*61046927SAndroid Build Coastguard Worker       if (error)
1661*61046927SAndroid Build Coastguard Worker          *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
1662*61046927SAndroid Build Coastguard Worker       return NULL;
1663*61046927SAndroid Build Coastguard Worker    }
1664*61046927SAndroid Build Coastguard Worker 
1665*61046927SAndroid Build Coastguard Worker    unsigned err = __DRI_IMAGE_ERROR_SUCCESS;
1666*61046927SAndroid Build Coastguard Worker    /* Allow a NULL error arg since many callers don't care. */
1667*61046927SAndroid Build Coastguard Worker    unsigned unused_error;
1668*61046927SAndroid Build Coastguard Worker    if (!error)
1669*61046927SAndroid Build Coastguard Worker       error = &unused_error;
1670*61046927SAndroid Build Coastguard Worker 
1671*61046927SAndroid Build Coastguard Worker    uint32_t flags = 0;
1672*61046927SAndroid Build Coastguard Worker    if (dri_flags & __DRI_IMAGE_PROTECTED_CONTENT_FLAG)
1673*61046927SAndroid Build Coastguard Worker       flags |= PIPE_BIND_PROTECTED;
1674*61046927SAndroid Build Coastguard Worker    if (dri_flags & __DRI_IMAGE_PRIME_LINEAR_BUFFER)
1675*61046927SAndroid Build Coastguard Worker       flags |= PIPE_BIND_PRIME_BLIT_DST;
1676*61046927SAndroid Build Coastguard Worker 
1677*61046927SAndroid Build Coastguard Worker    const int expected_num_fds = dri2_get_modifier_num_planes(screen, modifier, fourcc);
1678*61046927SAndroid Build Coastguard Worker    if (!map || expected_num_fds == 0) {
1679*61046927SAndroid Build Coastguard Worker       err = __DRI_IMAGE_ERROR_BAD_MATCH;
1680*61046927SAndroid Build Coastguard Worker       goto exit;
1681*61046927SAndroid Build Coastguard Worker    }
1682*61046927SAndroid Build Coastguard Worker 
1683*61046927SAndroid Build Coastguard Worker    if (num_fds != expected_num_fds) {
1684*61046927SAndroid Build Coastguard Worker       err = __DRI_IMAGE_ERROR_BAD_MATCH;
1685*61046927SAndroid Build Coastguard Worker       goto exit;
1686*61046927SAndroid Build Coastguard Worker    }
1687*61046927SAndroid Build Coastguard Worker 
1688*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandles[4];
1689*61046927SAndroid Build Coastguard Worker    memset(whandles, 0, sizeof(whandles));
1690*61046927SAndroid Build Coastguard Worker 
1691*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < num_fds; i++) {
1692*61046927SAndroid Build Coastguard Worker       if (fds[i] < 0) {
1693*61046927SAndroid Build Coastguard Worker          err = __DRI_IMAGE_ERROR_BAD_ALLOC;
1694*61046927SAndroid Build Coastguard Worker          goto exit;
1695*61046927SAndroid Build Coastguard Worker       }
1696*61046927SAndroid Build Coastguard Worker 
1697*61046927SAndroid Build Coastguard Worker       whandles[i].type = WINSYS_HANDLE_TYPE_FD;
1698*61046927SAndroid Build Coastguard Worker       whandles[i].handle = (unsigned)fds[i];
1699*61046927SAndroid Build Coastguard Worker       whandles[i].stride = (unsigned)strides[i];
1700*61046927SAndroid Build Coastguard Worker       whandles[i].offset = (unsigned)offsets[i];
1701*61046927SAndroid Build Coastguard Worker       whandles[i].format = map->pipe_format;
1702*61046927SAndroid Build Coastguard Worker       whandles[i].modifier = modifier;
1703*61046927SAndroid Build Coastguard Worker       whandles[i].plane = i;
1704*61046927SAndroid Build Coastguard Worker    }
1705*61046927SAndroid Build Coastguard Worker 
1706*61046927SAndroid Build Coastguard Worker    img = dri_create_image_from_winsys(screen, width, height, map,
1707*61046927SAndroid Build Coastguard Worker                                        num_fds, whandles, flags,
1708*61046927SAndroid Build Coastguard Worker                                        loaderPrivate);
1709*61046927SAndroid Build Coastguard Worker    if (img == NULL) {
1710*61046927SAndroid Build Coastguard Worker       err = __DRI_IMAGE_ERROR_BAD_ALLOC;
1711*61046927SAndroid Build Coastguard Worker       goto exit;
1712*61046927SAndroid Build Coastguard Worker    }
1713*61046927SAndroid Build Coastguard Worker 
1714*61046927SAndroid Build Coastguard Worker    img->dri_components = map->dri_components;
1715*61046927SAndroid Build Coastguard Worker    img->dri_fourcc = fourcc;
1716*61046927SAndroid Build Coastguard Worker    img->dri_format = map->dri_format;
1717*61046927SAndroid Build Coastguard Worker    img->imported_dmabuf = true;
1718*61046927SAndroid Build Coastguard Worker    img->yuv_color_space = yuv_color_space;
1719*61046927SAndroid Build Coastguard Worker    img->sample_range = sample_range;
1720*61046927SAndroid Build Coastguard Worker    img->horizontal_siting = horizontal_siting;
1721*61046927SAndroid Build Coastguard Worker    img->vertical_siting = vertical_siting;
1722*61046927SAndroid Build Coastguard Worker 
1723*61046927SAndroid Build Coastguard Worker    *error = __DRI_IMAGE_ERROR_SUCCESS;
1724*61046927SAndroid Build Coastguard Worker    return img;
1725*61046927SAndroid Build Coastguard Worker 
1726*61046927SAndroid Build Coastguard Worker exit:
1727*61046927SAndroid Build Coastguard Worker    *error = err;
1728*61046927SAndroid Build Coastguard Worker    return NULL;
1729*61046927SAndroid Build Coastguard Worker }
1730*61046927SAndroid Build Coastguard Worker 
1731*61046927SAndroid Build Coastguard Worker bool
dri2_query_compression_rates(__DRIscreen * _screen,const __DRIconfig * config,int max,enum __DRIFixedRateCompression * rates,int * count)1732*61046927SAndroid Build Coastguard Worker dri2_query_compression_rates(__DRIscreen *_screen, const __DRIconfig *config, int max,
1733*61046927SAndroid Build Coastguard Worker                              enum __DRIFixedRateCompression *rates, int *count)
1734*61046927SAndroid Build Coastguard Worker {
1735*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = dri_screen(_screen);
1736*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = screen->base.screen;
1737*61046927SAndroid Build Coastguard Worker    struct gl_config *gl_config = (struct gl_config *) config;
1738*61046927SAndroid Build Coastguard Worker    enum pipe_format format = gl_config->color_format;
1739*61046927SAndroid Build Coastguard Worker    uint32_t pipe_rates[max];
1740*61046927SAndroid Build Coastguard Worker 
1741*61046927SAndroid Build Coastguard Worker    if (!pscreen->is_format_supported(pscreen, format, screen->target, 0, 0,
1742*61046927SAndroid Build Coastguard Worker                                      PIPE_BIND_RENDER_TARGET))
1743*61046927SAndroid Build Coastguard Worker       return false;
1744*61046927SAndroid Build Coastguard Worker 
1745*61046927SAndroid Build Coastguard Worker    if (pscreen->query_compression_rates != NULL) {
1746*61046927SAndroid Build Coastguard Worker       pscreen->query_compression_rates(pscreen, format, max, pipe_rates, count);
1747*61046927SAndroid Build Coastguard Worker       for (int i = 0; i < *count && i < max; ++i)
1748*61046927SAndroid Build Coastguard Worker          rates[i] = to_dri_compression_rate(pipe_rates[i]);
1749*61046927SAndroid Build Coastguard Worker    } else {
1750*61046927SAndroid Build Coastguard Worker       *count = 0;
1751*61046927SAndroid Build Coastguard Worker    }
1752*61046927SAndroid Build Coastguard Worker 
1753*61046927SAndroid Build Coastguard Worker    return true;
1754*61046927SAndroid Build Coastguard Worker }
1755*61046927SAndroid Build Coastguard Worker 
1756*61046927SAndroid Build Coastguard Worker bool
dri2_query_compression_modifiers(__DRIscreen * _screen,uint32_t fourcc,enum __DRIFixedRateCompression rate,int max,uint64_t * modifiers,int * count)1757*61046927SAndroid Build Coastguard Worker dri2_query_compression_modifiers(__DRIscreen *_screen, uint32_t fourcc,
1758*61046927SAndroid Build Coastguard Worker                                  enum __DRIFixedRateCompression rate, int max,
1759*61046927SAndroid Build Coastguard Worker                                  uint64_t *modifiers, int *count)
1760*61046927SAndroid Build Coastguard Worker {
1761*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = dri_screen(_screen);
1762*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = screen->base.screen;
1763*61046927SAndroid Build Coastguard Worker    const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
1764*61046927SAndroid Build Coastguard Worker    uint32_t pipe_rate = from_dri_compression_rate(rate);
1765*61046927SAndroid Build Coastguard Worker 
1766*61046927SAndroid Build Coastguard Worker    if (!map)
1767*61046927SAndroid Build Coastguard Worker       return false;
1768*61046927SAndroid Build Coastguard Worker 
1769*61046927SAndroid Build Coastguard Worker    if (!pscreen->is_format_supported(pscreen, map->pipe_format, screen->target,
1770*61046927SAndroid Build Coastguard Worker                                      0, 0, PIPE_BIND_RENDER_TARGET))
1771*61046927SAndroid Build Coastguard Worker       return false;
1772*61046927SAndroid Build Coastguard Worker 
1773*61046927SAndroid Build Coastguard Worker    if (pscreen->query_compression_modifiers != NULL) {
1774*61046927SAndroid Build Coastguard Worker       pscreen->query_compression_modifiers(pscreen, map->pipe_format, pipe_rate,
1775*61046927SAndroid Build Coastguard Worker                                            max, modifiers, count);
1776*61046927SAndroid Build Coastguard Worker    } else {
1777*61046927SAndroid Build Coastguard Worker       *count = 0;
1778*61046927SAndroid Build Coastguard Worker    }
1779*61046927SAndroid Build Coastguard Worker 
1780*61046927SAndroid Build Coastguard Worker    return true;
1781*61046927SAndroid Build Coastguard Worker }
1782*61046927SAndroid Build Coastguard Worker 
1783*61046927SAndroid Build Coastguard Worker void
dri2_blit_image(__DRIcontext * context,__DRIimage * dst,__DRIimage * src,int dstx0,int dsty0,int dstwidth,int dstheight,int srcx0,int srcy0,int srcwidth,int srcheight,int flush_flag)1784*61046927SAndroid Build Coastguard Worker dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src,
1785*61046927SAndroid Build Coastguard Worker                 int dstx0, int dsty0, int dstwidth, int dstheight,
1786*61046927SAndroid Build Coastguard Worker                 int srcx0, int srcy0, int srcwidth, int srcheight,
1787*61046927SAndroid Build Coastguard Worker                 int flush_flag)
1788*61046927SAndroid Build Coastguard Worker {
1789*61046927SAndroid Build Coastguard Worker    struct dri_context *ctx = dri_context(context);
1790*61046927SAndroid Build Coastguard Worker    struct pipe_context *pipe = ctx->st->pipe;
1791*61046927SAndroid Build Coastguard Worker    struct pipe_screen *screen;
1792*61046927SAndroid Build Coastguard Worker    struct pipe_fence_handle *fence;
1793*61046927SAndroid Build Coastguard Worker    struct pipe_blit_info blit;
1794*61046927SAndroid Build Coastguard Worker 
1795*61046927SAndroid Build Coastguard Worker    if (!dst || !src)
1796*61046927SAndroid Build Coastguard Worker       return;
1797*61046927SAndroid Build Coastguard Worker 
1798*61046927SAndroid Build Coastguard Worker    /* Wait for glthread to finish because we can't use pipe_context from
1799*61046927SAndroid Build Coastguard Worker     * multiple threads.
1800*61046927SAndroid Build Coastguard Worker     */
1801*61046927SAndroid Build Coastguard Worker    _mesa_glthread_finish(ctx->st->ctx);
1802*61046927SAndroid Build Coastguard Worker 
1803*61046927SAndroid Build Coastguard Worker    dri_image_fence_sync(ctx, dst);
1804*61046927SAndroid Build Coastguard Worker 
1805*61046927SAndroid Build Coastguard Worker    memset(&blit, 0, sizeof(blit));
1806*61046927SAndroid Build Coastguard Worker    blit.dst.resource = dst->texture;
1807*61046927SAndroid Build Coastguard Worker    blit.dst.box.x = dstx0;
1808*61046927SAndroid Build Coastguard Worker    blit.dst.box.y = dsty0;
1809*61046927SAndroid Build Coastguard Worker    blit.dst.box.width = dstwidth;
1810*61046927SAndroid Build Coastguard Worker    blit.dst.box.height = dstheight;
1811*61046927SAndroid Build Coastguard Worker    blit.dst.box.depth = 1;
1812*61046927SAndroid Build Coastguard Worker    blit.dst.format = dst->texture->format;
1813*61046927SAndroid Build Coastguard Worker    blit.src.resource = src->texture;
1814*61046927SAndroid Build Coastguard Worker    blit.src.box.x = srcx0;
1815*61046927SAndroid Build Coastguard Worker    blit.src.box.y = srcy0;
1816*61046927SAndroid Build Coastguard Worker    blit.src.box.width = srcwidth;
1817*61046927SAndroid Build Coastguard Worker    blit.src.box.height = srcheight;
1818*61046927SAndroid Build Coastguard Worker    blit.src.box.depth = 1;
1819*61046927SAndroid Build Coastguard Worker    blit.src.format = src->texture->format;
1820*61046927SAndroid Build Coastguard Worker    blit.mask = PIPE_MASK_RGBA;
1821*61046927SAndroid Build Coastguard Worker    blit.filter = PIPE_TEX_FILTER_NEAREST;
1822*61046927SAndroid Build Coastguard Worker 
1823*61046927SAndroid Build Coastguard Worker    pipe->blit(pipe, &blit);
1824*61046927SAndroid Build Coastguard Worker 
1825*61046927SAndroid Build Coastguard Worker    if (flush_flag == __BLIT_FLAG_FLUSH) {
1826*61046927SAndroid Build Coastguard Worker       pipe->flush_resource(pipe, dst->texture);
1827*61046927SAndroid Build Coastguard Worker       st_context_flush(ctx->st, 0, NULL, NULL, NULL);
1828*61046927SAndroid Build Coastguard Worker    } else if (flush_flag == __BLIT_FLAG_FINISH) {
1829*61046927SAndroid Build Coastguard Worker       screen = ctx->screen->base.screen;
1830*61046927SAndroid Build Coastguard Worker       pipe->flush_resource(pipe, dst->texture);
1831*61046927SAndroid Build Coastguard Worker       st_context_flush(ctx->st, 0, &fence, NULL, NULL);
1832*61046927SAndroid Build Coastguard Worker       (void) screen->fence_finish(screen, NULL, fence, OS_TIMEOUT_INFINITE);
1833*61046927SAndroid Build Coastguard Worker       screen->fence_reference(screen, &fence, NULL);
1834*61046927SAndroid Build Coastguard Worker    }
1835*61046927SAndroid Build Coastguard Worker }
1836*61046927SAndroid Build Coastguard Worker 
1837*61046927SAndroid Build Coastguard Worker void *
dri2_map_image(__DRIcontext * context,__DRIimage * image,int x0,int y0,int width,int height,unsigned int flags,int * stride,void ** data)1838*61046927SAndroid Build Coastguard Worker dri2_map_image(__DRIcontext *context, __DRIimage *image,
1839*61046927SAndroid Build Coastguard Worker                 int x0, int y0, int width, int height,
1840*61046927SAndroid Build Coastguard Worker                 unsigned int flags, int *stride, void **data)
1841*61046927SAndroid Build Coastguard Worker {
1842*61046927SAndroid Build Coastguard Worker    struct dri_context *ctx = dri_context(context);
1843*61046927SAndroid Build Coastguard Worker    struct pipe_context *pipe = ctx->st->pipe;
1844*61046927SAndroid Build Coastguard Worker    enum pipe_map_flags pipe_access = 0;
1845*61046927SAndroid Build Coastguard Worker    struct pipe_transfer *trans;
1846*61046927SAndroid Build Coastguard Worker    void *map;
1847*61046927SAndroid Build Coastguard Worker 
1848*61046927SAndroid Build Coastguard Worker    if (!image || !data || *data)
1849*61046927SAndroid Build Coastguard Worker       return NULL;
1850*61046927SAndroid Build Coastguard Worker 
1851*61046927SAndroid Build Coastguard Worker    unsigned plane = image->plane;
1852*61046927SAndroid Build Coastguard Worker    if (plane >= dri2_get_mapping_by_format(image->dri_format)->nplanes)
1853*61046927SAndroid Build Coastguard Worker       return NULL;
1854*61046927SAndroid Build Coastguard Worker 
1855*61046927SAndroid Build Coastguard Worker    /* Wait for glthread to finish because we can't use pipe_context from
1856*61046927SAndroid Build Coastguard Worker     * multiple threads.
1857*61046927SAndroid Build Coastguard Worker     */
1858*61046927SAndroid Build Coastguard Worker    _mesa_glthread_finish(ctx->st->ctx);
1859*61046927SAndroid Build Coastguard Worker 
1860*61046927SAndroid Build Coastguard Worker    dri_image_fence_sync(ctx, image);
1861*61046927SAndroid Build Coastguard Worker 
1862*61046927SAndroid Build Coastguard Worker    struct pipe_resource *resource = image->texture;
1863*61046927SAndroid Build Coastguard Worker    while (plane--)
1864*61046927SAndroid Build Coastguard Worker       resource = resource->next;
1865*61046927SAndroid Build Coastguard Worker 
1866*61046927SAndroid Build Coastguard Worker    if (flags & __DRI_IMAGE_TRANSFER_READ)
1867*61046927SAndroid Build Coastguard Worker          pipe_access |= PIPE_MAP_READ;
1868*61046927SAndroid Build Coastguard Worker    if (flags & __DRI_IMAGE_TRANSFER_WRITE)
1869*61046927SAndroid Build Coastguard Worker          pipe_access |= PIPE_MAP_WRITE;
1870*61046927SAndroid Build Coastguard Worker 
1871*61046927SAndroid Build Coastguard Worker    map = pipe_texture_map(pipe, resource, 0, 0, pipe_access, x0, y0,
1872*61046927SAndroid Build Coastguard Worker                            width, height, &trans);
1873*61046927SAndroid Build Coastguard Worker    if (map) {
1874*61046927SAndroid Build Coastguard Worker       *data = trans;
1875*61046927SAndroid Build Coastguard Worker       *stride = trans->stride;
1876*61046927SAndroid Build Coastguard Worker    }
1877*61046927SAndroid Build Coastguard Worker 
1878*61046927SAndroid Build Coastguard Worker    return map;
1879*61046927SAndroid Build Coastguard Worker }
1880*61046927SAndroid Build Coastguard Worker 
1881*61046927SAndroid Build Coastguard Worker void
dri2_unmap_image(__DRIcontext * context,__DRIimage * image,void * data)1882*61046927SAndroid Build Coastguard Worker dri2_unmap_image(__DRIcontext *context, __DRIimage *image, void *data)
1883*61046927SAndroid Build Coastguard Worker {
1884*61046927SAndroid Build Coastguard Worker    struct dri_context *ctx = dri_context(context);
1885*61046927SAndroid Build Coastguard Worker    struct pipe_context *pipe = ctx->st->pipe;
1886*61046927SAndroid Build Coastguard Worker 
1887*61046927SAndroid Build Coastguard Worker    /* Wait for glthread to finish because we can't use pipe_context from
1888*61046927SAndroid Build Coastguard Worker     * multiple threads.
1889*61046927SAndroid Build Coastguard Worker     */
1890*61046927SAndroid Build Coastguard Worker    _mesa_glthread_finish(ctx->st->ctx);
1891*61046927SAndroid Build Coastguard Worker 
1892*61046927SAndroid Build Coastguard Worker    pipe_texture_unmap(pipe, (struct pipe_transfer *)data);
1893*61046927SAndroid Build Coastguard Worker }
1894*61046927SAndroid Build Coastguard Worker 
1895*61046927SAndroid Build Coastguard Worker int
dri2_get_capabilities(__DRIscreen * _screen)1896*61046927SAndroid Build Coastguard Worker dri2_get_capabilities(__DRIscreen *_screen)
1897*61046927SAndroid Build Coastguard Worker {
1898*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = dri_screen(_screen);
1899*61046927SAndroid Build Coastguard Worker 
1900*61046927SAndroid Build Coastguard Worker    return (screen->can_share_buffer ? __DRI_IMAGE_CAP_GLOBAL_NAMES : 0);
1901*61046927SAndroid Build Coastguard Worker }
1902*61046927SAndroid Build Coastguard Worker 
1903*61046927SAndroid Build Coastguard Worker int
dri_interop_query_device_info(__DRIcontext * _ctx,struct mesa_glinterop_device_info * out)1904*61046927SAndroid Build Coastguard Worker dri_interop_query_device_info(__DRIcontext *_ctx,
1905*61046927SAndroid Build Coastguard Worker                                struct mesa_glinterop_device_info *out)
1906*61046927SAndroid Build Coastguard Worker {
1907*61046927SAndroid Build Coastguard Worker    return st_interop_query_device_info(dri_context(_ctx)->st, out);
1908*61046927SAndroid Build Coastguard Worker }
1909*61046927SAndroid Build Coastguard Worker 
1910*61046927SAndroid Build Coastguard Worker int
dri_interop_export_object(__DRIcontext * _ctx,struct mesa_glinterop_export_in * in,struct mesa_glinterop_export_out * out)1911*61046927SAndroid Build Coastguard Worker dri_interop_export_object(__DRIcontext *_ctx,
1912*61046927SAndroid Build Coastguard Worker                            struct mesa_glinterop_export_in *in,
1913*61046927SAndroid Build Coastguard Worker                            struct mesa_glinterop_export_out *out)
1914*61046927SAndroid Build Coastguard Worker {
1915*61046927SAndroid Build Coastguard Worker    return st_interop_export_object(dri_context(_ctx)->st, in, out);
1916*61046927SAndroid Build Coastguard Worker }
1917*61046927SAndroid Build Coastguard Worker 
1918*61046927SAndroid Build Coastguard Worker int
dri_interop_flush_objects(__DRIcontext * _ctx,unsigned count,struct mesa_glinterop_export_in * objects,struct mesa_glinterop_flush_out * out)1919*61046927SAndroid Build Coastguard Worker dri_interop_flush_objects(__DRIcontext *_ctx,
1920*61046927SAndroid Build Coastguard Worker                            unsigned count, struct mesa_glinterop_export_in *objects,
1921*61046927SAndroid Build Coastguard Worker                            struct mesa_glinterop_flush_out *out)
1922*61046927SAndroid Build Coastguard Worker {
1923*61046927SAndroid Build Coastguard Worker    return st_interop_flush_objects(dri_context(_ctx)->st, count, objects, out);
1924*61046927SAndroid Build Coastguard Worker }
1925*61046927SAndroid Build Coastguard Worker 
1926*61046927SAndroid Build Coastguard Worker /**
1927*61046927SAndroid Build Coastguard Worker  * \brief the DRI2bufferDamageExtension set_damage_region method
1928*61046927SAndroid Build Coastguard Worker  */
1929*61046927SAndroid Build Coastguard Worker void
dri_set_damage_region(__DRIdrawable * dPriv,unsigned int nrects,int * rects)1930*61046927SAndroid Build Coastguard Worker dri_set_damage_region(__DRIdrawable *dPriv, unsigned int nrects, int *rects)
1931*61046927SAndroid Build Coastguard Worker {
1932*61046927SAndroid Build Coastguard Worker    struct dri_drawable *drawable = dri_drawable(dPriv);
1933*61046927SAndroid Build Coastguard Worker    struct pipe_box *boxes = NULL;
1934*61046927SAndroid Build Coastguard Worker 
1935*61046927SAndroid Build Coastguard Worker    if (nrects) {
1936*61046927SAndroid Build Coastguard Worker       boxes = CALLOC(nrects, sizeof(*boxes));
1937*61046927SAndroid Build Coastguard Worker       assert(boxes);
1938*61046927SAndroid Build Coastguard Worker 
1939*61046927SAndroid Build Coastguard Worker       for (unsigned int i = 0; i < nrects; i++) {
1940*61046927SAndroid Build Coastguard Worker          int *rect = &rects[i * 4];
1941*61046927SAndroid Build Coastguard Worker 
1942*61046927SAndroid Build Coastguard Worker          u_box_2d(rect[0], rect[1], rect[2], rect[3], &boxes[i]);
1943*61046927SAndroid Build Coastguard Worker       }
1944*61046927SAndroid Build Coastguard Worker    }
1945*61046927SAndroid Build Coastguard Worker 
1946*61046927SAndroid Build Coastguard Worker    FREE(drawable->damage_rects);
1947*61046927SAndroid Build Coastguard Worker    drawable->damage_rects = boxes;
1948*61046927SAndroid Build Coastguard Worker    drawable->num_damage_rects = nrects;
1949*61046927SAndroid Build Coastguard Worker 
1950*61046927SAndroid Build Coastguard Worker    /* Only apply the damage region if the BACK_LEFT texture is up-to-date. */
1951*61046927SAndroid Build Coastguard Worker    if (drawable->texture_stamp == drawable->lastStamp &&
1952*61046927SAndroid Build Coastguard Worker        (drawable->texture_mask & (1 << ST_ATTACHMENT_BACK_LEFT))) {
1953*61046927SAndroid Build Coastguard Worker       struct pipe_screen *screen = drawable->screen->base.screen;
1954*61046927SAndroid Build Coastguard Worker       struct pipe_resource *resource;
1955*61046927SAndroid Build Coastguard Worker 
1956*61046927SAndroid Build Coastguard Worker       if (drawable->stvis.samples > 1)
1957*61046927SAndroid Build Coastguard Worker          resource = drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT];
1958*61046927SAndroid Build Coastguard Worker       else
1959*61046927SAndroid Build Coastguard Worker          resource = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
1960*61046927SAndroid Build Coastguard Worker 
1961*61046927SAndroid Build Coastguard Worker       screen->set_damage_region(screen, resource,
1962*61046927SAndroid Build Coastguard Worker                                 drawable->num_damage_rects,
1963*61046927SAndroid Build Coastguard Worker                                 drawable->damage_rects);
1964*61046927SAndroid Build Coastguard Worker    }
1965*61046927SAndroid Build Coastguard Worker }
1966*61046927SAndroid Build Coastguard Worker 
1967*61046927SAndroid Build Coastguard Worker /**
1968*61046927SAndroid Build Coastguard Worker  * \brief the DRI2blobExtension set_cache_funcs method
1969*61046927SAndroid Build Coastguard Worker  */
1970*61046927SAndroid Build Coastguard Worker void
dri_set_blob_cache_funcs(__DRIscreen * sPriv,__DRIblobCacheSet set,__DRIblobCacheGet get)1971*61046927SAndroid Build Coastguard Worker dri_set_blob_cache_funcs(__DRIscreen *sPriv, __DRIblobCacheSet set,
1972*61046927SAndroid Build Coastguard Worker                          __DRIblobCacheGet get)
1973*61046927SAndroid Build Coastguard Worker {
1974*61046927SAndroid Build Coastguard Worker    struct dri_screen *screen = dri_screen(sPriv);
1975*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = screen->base.screen;
1976*61046927SAndroid Build Coastguard Worker 
1977*61046927SAndroid Build Coastguard Worker    if (!pscreen->get_disk_shader_cache)
1978*61046927SAndroid Build Coastguard Worker       return;
1979*61046927SAndroid Build Coastguard Worker 
1980*61046927SAndroid Build Coastguard Worker    struct disk_cache *cache = pscreen->get_disk_shader_cache(pscreen);
1981*61046927SAndroid Build Coastguard Worker 
1982*61046927SAndroid Build Coastguard Worker    if (!cache)
1983*61046927SAndroid Build Coastguard Worker       return;
1984*61046927SAndroid Build Coastguard Worker 
1985*61046927SAndroid Build Coastguard Worker    disk_cache_set_callbacks(cache, set, get);
1986*61046927SAndroid Build Coastguard Worker }
1987*61046927SAndroid Build Coastguard Worker 
1988*61046927SAndroid Build Coastguard Worker /*
1989*61046927SAndroid Build Coastguard Worker  * Backend function init_screen.
1990*61046927SAndroid Build Coastguard Worker  */
1991*61046927SAndroid Build Coastguard Worker 
1992*61046927SAndroid Build Coastguard Worker void
dri2_init_drawable(struct dri_drawable * drawable,bool isPixmap,int alphaBits)1993*61046927SAndroid Build Coastguard Worker dri2_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits)
1994*61046927SAndroid Build Coastguard Worker {
1995*61046927SAndroid Build Coastguard Worker    drawable->allocate_textures = dri2_allocate_textures;
1996*61046927SAndroid Build Coastguard Worker    drawable->flush_frontbuffer = dri2_flush_frontbuffer;
1997*61046927SAndroid Build Coastguard Worker    drawable->update_tex_buffer = dri2_update_tex_buffer;
1998*61046927SAndroid Build Coastguard Worker    drawable->flush_swapbuffers = dri2_flush_swapbuffers;
1999*61046927SAndroid Build Coastguard Worker }
2000*61046927SAndroid Build Coastguard Worker 
2001*61046927SAndroid Build Coastguard Worker /**
2002*61046927SAndroid Build Coastguard Worker  * This is the driver specific part of the createNewScreen entry point.
2003*61046927SAndroid Build Coastguard Worker  *
2004*61046927SAndroid Build Coastguard Worker  * Returns the struct gl_config supported by this driver.
2005*61046927SAndroid Build Coastguard Worker  */
2006*61046927SAndroid Build Coastguard Worker struct pipe_screen *
dri2_init_screen(struct dri_screen * screen,bool driver_name_is_inferred)2007*61046927SAndroid Build Coastguard Worker dri2_init_screen(struct dri_screen *screen, bool driver_name_is_inferred)
2008*61046927SAndroid Build Coastguard Worker {
2009*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = NULL;
2010*61046927SAndroid Build Coastguard Worker 
2011*61046927SAndroid Build Coastguard Worker    screen->can_share_buffer = true;
2012*61046927SAndroid Build Coastguard Worker    screen->auto_fake_front = dri_with_format(screen);
2013*61046927SAndroid Build Coastguard Worker 
2014*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
2015*61046927SAndroid Build Coastguard Worker    if (pipe_loader_drm_probe_fd(&screen->dev, screen->fd, false))
2016*61046927SAndroid Build Coastguard Worker       pscreen = pipe_loader_create_screen(screen->dev, driver_name_is_inferred);
2017*61046927SAndroid Build Coastguard Worker #endif
2018*61046927SAndroid Build Coastguard Worker 
2019*61046927SAndroid Build Coastguard Worker    return pscreen;
2020*61046927SAndroid Build Coastguard Worker }
2021*61046927SAndroid Build Coastguard Worker 
2022*61046927SAndroid Build Coastguard Worker /**
2023*61046927SAndroid Build Coastguard Worker  * This is the driver specific part of the createNewScreen entry point.
2024*61046927SAndroid Build Coastguard Worker  *
2025*61046927SAndroid Build Coastguard Worker  * Returns the struct gl_config supported by this driver.
2026*61046927SAndroid Build Coastguard Worker  */
2027*61046927SAndroid Build Coastguard Worker struct pipe_screen *
dri_swrast_kms_init_screen(struct dri_screen * screen,bool driver_name_is_inferred)2028*61046927SAndroid Build Coastguard Worker dri_swrast_kms_init_screen(struct dri_screen *screen, bool driver_name_is_inferred)
2029*61046927SAndroid Build Coastguard Worker {
2030*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = NULL;
2031*61046927SAndroid Build Coastguard Worker    screen->can_share_buffer = false;
2032*61046927SAndroid Build Coastguard Worker    screen->auto_fake_front = dri_with_format(screen);
2033*61046927SAndroid Build Coastguard Worker 
2034*61046927SAndroid Build Coastguard Worker #if defined(HAVE_DRISW_KMS) && defined(HAVE_SWRAST)
2035*61046927SAndroid Build Coastguard Worker    if (pipe_loader_sw_probe_kms(&screen->dev, screen->fd))
2036*61046927SAndroid Build Coastguard Worker       pscreen = pipe_loader_create_screen(screen->dev, driver_name_is_inferred);
2037*61046927SAndroid Build Coastguard Worker #endif
2038*61046927SAndroid Build Coastguard Worker 
2039*61046927SAndroid Build Coastguard Worker    return pscreen;
2040*61046927SAndroid Build Coastguard Worker }
2041*61046927SAndroid Build Coastguard Worker 
2042*61046927SAndroid Build Coastguard Worker int
dri_query_compatible_render_only_device_fd(int kms_only_fd)2043*61046927SAndroid Build Coastguard Worker dri_query_compatible_render_only_device_fd(int kms_only_fd)
2044*61046927SAndroid Build Coastguard Worker {
2045*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
2046*61046927SAndroid Build Coastguard Worker    return pipe_loader_get_compatible_render_capable_device_fd(kms_only_fd);
2047*61046927SAndroid Build Coastguard Worker #else
2048*61046927SAndroid Build Coastguard Worker    return -1;
2049*61046927SAndroid Build Coastguard Worker #endif
2050*61046927SAndroid Build Coastguard Worker }
2051*61046927SAndroid Build Coastguard Worker /* vim: set sw=3 ts=8 sts=3 expandtab: */
2052