1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright 2009, VMware, Inc. 5848b8605Smrg * All Rights Reserved. 6848b8605Smrg * Copyright (C) 2010 LunarG Inc. 7848b8605Smrg * 8848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 9848b8605Smrg * copy of this software and associated documentation files (the "Software"), 10848b8605Smrg * to deal in the Software without restriction, including without limitation 11848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 13848b8605Smrg * Software is furnished to do so, subject to the following conditions: 14848b8605Smrg * 15848b8605Smrg * The above copyright notice and this permission notice shall be included 16848b8605Smrg * in all copies or substantial portions of the Software. 17848b8605Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 25848b8605Smrg * 26848b8605Smrg * Authors: 27848b8605Smrg * Keith Whitwell <keithw@vmware.com> Jakob Bornecrantz 28848b8605Smrg * <wallbraker@gmail.com> Chia-I Wu <olv@lunarg.com> 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg#include <xf86drm.h> 32b8e80941Smrg#include "GL/mesa_glinterop.h" 33848b8605Smrg#include "util/u_memory.h" 34848b8605Smrg#include "util/u_inlines.h" 35848b8605Smrg#include "util/u_format.h" 36848b8605Smrg#include "util/u_debug.h" 37848b8605Smrg#include "state_tracker/drm_driver.h" 38b8e80941Smrg#include "state_tracker/st_cb_bufferobjects.h" 39b8e80941Smrg#include "state_tracker/st_cb_fbo.h" 40b8e80941Smrg#include "state_tracker/st_cb_texture.h" 41848b8605Smrg#include "state_tracker/st_texture.h" 42848b8605Smrg#include "state_tracker/st_context.h" 43848b8605Smrg#include "pipe-loader/pipe_loader.h" 44b8e80941Smrg#include "main/bufferobj.h" 45848b8605Smrg#include "main/texobj.h" 46848b8605Smrg 47b8e80941Smrg#include "dri_util.h" 48b8e80941Smrg 49b8e80941Smrg#include "dri_helpers.h" 50848b8605Smrg#include "dri_drawable.h" 51848b8605Smrg#include "dri_query_renderer.h" 52848b8605Smrg 53b8e80941Smrg#include "drm-uapi/drm_fourcc.h" 54b8e80941Smrg 55b8e80941Smrgstruct dri2_buffer 56848b8605Smrg{ 57b8e80941Smrg __DRIbuffer base; 58b8e80941Smrg struct pipe_resource *resource; 59b8e80941Smrg}; 60b8e80941Smrg 61b8e80941Smrgstatic inline struct dri2_buffer * 62b8e80941Smrgdri2_buffer(__DRIbuffer * driBufferPriv) 63b8e80941Smrg{ 64b8e80941Smrg return (struct dri2_buffer *) driBufferPriv; 65b8e80941Smrg} 66b8e80941Smrg 67b8e80941Smrgstruct dri2_format_mapping { 68b8e80941Smrg int dri_fourcc; 69b8e80941Smrg int dri_format; 70848b8605Smrg int dri_components; 71b8e80941Smrg enum pipe_format pipe_format; 72b8e80941Smrg}; 73b8e80941Smrg 74b8e80941Smrgstatic const struct dri2_format_mapping dri2_format_table[] = { 75b8e80941Smrg { __DRI_IMAGE_FOURCC_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 76b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B10G10R10A2_UNORM }, 77b8e80941Smrg { __DRI_IMAGE_FOURCC_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 78b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B10G10R10X2_UNORM }, 79b8e80941Smrg { __DRI_IMAGE_FOURCC_ABGR2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 80b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R10G10B10A2_UNORM }, 81b8e80941Smrg { __DRI_IMAGE_FOURCC_XBGR2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 82b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R10G10B10X2_UNORM }, 83b8e80941Smrg { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_FORMAT_ARGB8888, 84b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_UNORM }, 85b8e80941Smrg { __DRI_IMAGE_FOURCC_ABGR8888, __DRI_IMAGE_FORMAT_ABGR8888, 86b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_RGBA8888_UNORM }, 87b8e80941Smrg { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_FORMAT_SARGB8, 88b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_SRGB }, 89b8e80941Smrg { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888, 90b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_BGRX8888_UNORM }, 91b8e80941Smrg { __DRI_IMAGE_FOURCC_XBGR8888, __DRI_IMAGE_FORMAT_XBGR8888, 92b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_RGBX8888_UNORM }, 93b8e80941Smrg { __DRI_IMAGE_FOURCC_ARGB1555, __DRI_IMAGE_FORMAT_ARGB1555, 94b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B5G5R5A1_UNORM }, 95b8e80941Smrg { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_FORMAT_RGB565, 96b8e80941Smrg __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B5G6R5_UNORM }, 97b8e80941Smrg { __DRI_IMAGE_FOURCC_R8, __DRI_IMAGE_FORMAT_R8, 98b8e80941Smrg __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R8_UNORM }, 99b8e80941Smrg { __DRI_IMAGE_FOURCC_R16, __DRI_IMAGE_FORMAT_R16, 100b8e80941Smrg __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R16_UNORM }, 101b8e80941Smrg { __DRI_IMAGE_FOURCC_GR88, __DRI_IMAGE_FORMAT_GR88, 102b8e80941Smrg __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG88_UNORM }, 103b8e80941Smrg { __DRI_IMAGE_FOURCC_GR1616, __DRI_IMAGE_FORMAT_GR88, 104b8e80941Smrg __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG1616_UNORM }, 105b8e80941Smrg { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_FORMAT_NONE, 106b8e80941Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV }, 107b8e80941Smrg { __DRI_IMAGE_FOURCC_YVU420, __DRI_IMAGE_FORMAT_NONE, 108b8e80941Smrg __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_YV12 }, 109b8e80941Smrg { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_FORMAT_NONE, 110b8e80941Smrg __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12 }, 111b8e80941Smrg { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_FORMAT_YUYV, 112b8e80941Smrg __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_YUYV }, 113b8e80941Smrg { __DRI_IMAGE_FOURCC_UYVY, __DRI_IMAGE_FORMAT_UYVY, 114b8e80941Smrg __DRI_IMAGE_COMPONENTS_Y_UXVX, PIPE_FORMAT_UYVY }, 115b8e80941Smrg}; 116b8e80941Smrg 117b8e80941Smrgstatic const struct dri2_format_mapping * 118b8e80941Smrgdri2_get_mapping_by_fourcc(int fourcc) { 119b8e80941Smrg for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { 120b8e80941Smrg if (dri2_format_table[i].dri_fourcc == fourcc) 121b8e80941Smrg return &dri2_format_table[i]; 122848b8605Smrg } 123b8e80941Smrg 124b8e80941Smrg return NULL; 125b8e80941Smrg} 126b8e80941Smrg 127b8e80941Smrgstatic const struct dri2_format_mapping * 128b8e80941Smrgdri2_get_mapping_by_format(int format) { 129b8e80941Smrg for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) { 130b8e80941Smrg if (dri2_format_table[i].dri_format == format) 131b8e80941Smrg return &dri2_format_table[i]; 132b8e80941Smrg } 133b8e80941Smrg 134b8e80941Smrg return NULL; 135848b8605Smrg} 136848b8605Smrg 137848b8605Smrg/** 138848b8605Smrg * DRI2 flush extension. 139848b8605Smrg */ 140848b8605Smrgstatic void 141848b8605Smrgdri2_flush_drawable(__DRIdrawable *dPriv) 142848b8605Smrg{ 143848b8605Smrg dri_flush(dPriv->driContextPriv, dPriv, __DRI2_FLUSH_DRAWABLE, -1); 144848b8605Smrg} 145848b8605Smrg 146848b8605Smrgstatic void 147848b8605Smrgdri2_invalidate_drawable(__DRIdrawable *dPriv) 148848b8605Smrg{ 149848b8605Smrg struct dri_drawable *drawable = dri_drawable(dPriv); 150848b8605Smrg 151848b8605Smrg dri2InvalidateDrawable(dPriv); 152848b8605Smrg drawable->dPriv->lastStamp = drawable->dPriv->dri2.stamp; 153b8e80941Smrg drawable->texture_mask = 0; 154848b8605Smrg 155848b8605Smrg p_atomic_inc(&drawable->base.stamp); 156848b8605Smrg} 157848b8605Smrg 158848b8605Smrgstatic const __DRI2flushExtension dri2FlushExtension = { 159848b8605Smrg .base = { __DRI2_FLUSH, 4 }, 160848b8605Smrg 161848b8605Smrg .flush = dri2_flush_drawable, 162848b8605Smrg .invalidate = dri2_invalidate_drawable, 163848b8605Smrg .flush_with_flags = dri_flush, 164848b8605Smrg}; 165848b8605Smrg 166848b8605Smrg/** 167848b8605Smrg * Retrieve __DRIbuffer from the DRI loader. 168848b8605Smrg */ 169848b8605Smrgstatic __DRIbuffer * 170848b8605Smrgdri2_drawable_get_buffers(struct dri_drawable *drawable, 171848b8605Smrg const enum st_attachment_type *atts, 172848b8605Smrg unsigned *count) 173848b8605Smrg{ 174848b8605Smrg __DRIdrawable *dri_drawable = drawable->dPriv; 175848b8605Smrg const __DRIdri2LoaderExtension *loader = drawable->sPriv->dri2.loader; 176848b8605Smrg boolean with_format; 177848b8605Smrg __DRIbuffer *buffers; 178848b8605Smrg int num_buffers; 179848b8605Smrg unsigned attachments[10]; 180848b8605Smrg unsigned num_attachments, i; 181848b8605Smrg 182848b8605Smrg assert(loader); 183848b8605Smrg with_format = dri_with_format(drawable->sPriv); 184848b8605Smrg 185848b8605Smrg num_attachments = 0; 186848b8605Smrg 187848b8605Smrg /* for Xserver 1.6.0 (DRI2 version 1) we always need to ask for the front */ 188848b8605Smrg if (!with_format) 189848b8605Smrg attachments[num_attachments++] = __DRI_BUFFER_FRONT_LEFT; 190848b8605Smrg 191848b8605Smrg for (i = 0; i < *count; i++) { 192848b8605Smrg enum pipe_format format; 193848b8605Smrg unsigned bind; 194848b8605Smrg int att, depth; 195848b8605Smrg 196848b8605Smrg dri_drawable_get_format(drawable, atts[i], &format, &bind); 197848b8605Smrg if (format == PIPE_FORMAT_NONE) 198848b8605Smrg continue; 199848b8605Smrg 200848b8605Smrg switch (atts[i]) { 201848b8605Smrg case ST_ATTACHMENT_FRONT_LEFT: 202848b8605Smrg /* already added */ 203848b8605Smrg if (!with_format) 204848b8605Smrg continue; 205848b8605Smrg att = __DRI_BUFFER_FRONT_LEFT; 206848b8605Smrg break; 207848b8605Smrg case ST_ATTACHMENT_BACK_LEFT: 208848b8605Smrg att = __DRI_BUFFER_BACK_LEFT; 209848b8605Smrg break; 210848b8605Smrg case ST_ATTACHMENT_FRONT_RIGHT: 211848b8605Smrg att = __DRI_BUFFER_FRONT_RIGHT; 212848b8605Smrg break; 213848b8605Smrg case ST_ATTACHMENT_BACK_RIGHT: 214848b8605Smrg att = __DRI_BUFFER_BACK_RIGHT; 215848b8605Smrg break; 216848b8605Smrg default: 217848b8605Smrg continue; 218848b8605Smrg } 219848b8605Smrg 220848b8605Smrg /* 221848b8605Smrg * In this switch statement we must support all formats that 222848b8605Smrg * may occur as the stvis->color_format. 223848b8605Smrg */ 224848b8605Smrg switch(format) { 225b8e80941Smrg case PIPE_FORMAT_B10G10R10A2_UNORM: 226b8e80941Smrg case PIPE_FORMAT_R10G10B10A2_UNORM: 227b8e80941Smrg case PIPE_FORMAT_BGRA8888_UNORM: 228b8e80941Smrg case PIPE_FORMAT_RGBA8888_UNORM: 229848b8605Smrg depth = 32; 230848b8605Smrg break; 231b8e80941Smrg case PIPE_FORMAT_R10G10B10X2_UNORM: 232b8e80941Smrg case PIPE_FORMAT_B10G10R10X2_UNORM: 233b8e80941Smrg depth = 30; 234b8e80941Smrg break; 235b8e80941Smrg case PIPE_FORMAT_BGRX8888_UNORM: 236b8e80941Smrg case PIPE_FORMAT_RGBX8888_UNORM: 237848b8605Smrg depth = 24; 238848b8605Smrg break; 239848b8605Smrg case PIPE_FORMAT_B5G6R5_UNORM: 240848b8605Smrg depth = 16; 241848b8605Smrg break; 242848b8605Smrg default: 243848b8605Smrg depth = util_format_get_blocksizebits(format); 244848b8605Smrg assert(!"Unexpected format in dri2_drawable_get_buffers()"); 245848b8605Smrg } 246848b8605Smrg 247848b8605Smrg attachments[num_attachments++] = att; 248848b8605Smrg if (with_format) { 249848b8605Smrg attachments[num_attachments++] = depth; 250848b8605Smrg } 251848b8605Smrg } 252848b8605Smrg 253848b8605Smrg if (with_format) { 254848b8605Smrg num_attachments /= 2; 255848b8605Smrg buffers = loader->getBuffersWithFormat(dri_drawable, 256848b8605Smrg &dri_drawable->w, &dri_drawable->h, 257848b8605Smrg attachments, num_attachments, 258848b8605Smrg &num_buffers, dri_drawable->loaderPrivate); 259848b8605Smrg } 260848b8605Smrg else { 261848b8605Smrg buffers = loader->getBuffers(dri_drawable, 262848b8605Smrg &dri_drawable->w, &dri_drawable->h, 263848b8605Smrg attachments, num_attachments, 264848b8605Smrg &num_buffers, dri_drawable->loaderPrivate); 265848b8605Smrg } 266848b8605Smrg 267848b8605Smrg if (buffers) 268848b8605Smrg *count = num_buffers; 269848b8605Smrg 270848b8605Smrg return buffers; 271848b8605Smrg} 272848b8605Smrg 273848b8605Smrgstatic bool 274848b8605Smrgdri_image_drawable_get_buffers(struct dri_drawable *drawable, 275848b8605Smrg struct __DRIimageList *images, 276848b8605Smrg const enum st_attachment_type *statts, 277848b8605Smrg unsigned statts_count) 278848b8605Smrg{ 279848b8605Smrg __DRIdrawable *dPriv = drawable->dPriv; 280848b8605Smrg __DRIscreen *sPriv = drawable->sPriv; 281848b8605Smrg unsigned int image_format = __DRI_IMAGE_FORMAT_NONE; 282848b8605Smrg enum pipe_format pf; 283848b8605Smrg uint32_t buffer_mask = 0; 284848b8605Smrg unsigned i, bind; 285848b8605Smrg 286848b8605Smrg for (i = 0; i < statts_count; i++) { 287848b8605Smrg dri_drawable_get_format(drawable, statts[i], &pf, &bind); 288848b8605Smrg if (pf == PIPE_FORMAT_NONE) 289848b8605Smrg continue; 290848b8605Smrg 291848b8605Smrg switch (statts[i]) { 292848b8605Smrg case ST_ATTACHMENT_FRONT_LEFT: 293848b8605Smrg buffer_mask |= __DRI_IMAGE_BUFFER_FRONT; 294848b8605Smrg break; 295848b8605Smrg case ST_ATTACHMENT_BACK_LEFT: 296848b8605Smrg buffer_mask |= __DRI_IMAGE_BUFFER_BACK; 297848b8605Smrg break; 298848b8605Smrg default: 299848b8605Smrg continue; 300848b8605Smrg } 301848b8605Smrg 302848b8605Smrg switch (pf) { 303b8e80941Smrg case PIPE_FORMAT_B5G5R5A1_UNORM: 304b8e80941Smrg image_format = __DRI_IMAGE_FORMAT_ARGB1555; 305b8e80941Smrg break; 306848b8605Smrg case PIPE_FORMAT_B5G6R5_UNORM: 307848b8605Smrg image_format = __DRI_IMAGE_FORMAT_RGB565; 308848b8605Smrg break; 309b8e80941Smrg case PIPE_FORMAT_BGRX8888_UNORM: 310848b8605Smrg image_format = __DRI_IMAGE_FORMAT_XRGB8888; 311848b8605Smrg break; 312b8e80941Smrg case PIPE_FORMAT_BGRA8888_UNORM: 313848b8605Smrg image_format = __DRI_IMAGE_FORMAT_ARGB8888; 314848b8605Smrg break; 315b8e80941Smrg case PIPE_FORMAT_RGBX8888_UNORM: 316b8e80941Smrg image_format = __DRI_IMAGE_FORMAT_XBGR8888; 317b8e80941Smrg break; 318b8e80941Smrg case PIPE_FORMAT_RGBA8888_UNORM: 319848b8605Smrg image_format = __DRI_IMAGE_FORMAT_ABGR8888; 320848b8605Smrg break; 321b8e80941Smrg case PIPE_FORMAT_B10G10R10X2_UNORM: 322b8e80941Smrg image_format = __DRI_IMAGE_FORMAT_XRGB2101010; 323b8e80941Smrg break; 324b8e80941Smrg case PIPE_FORMAT_B10G10R10A2_UNORM: 325b8e80941Smrg image_format = __DRI_IMAGE_FORMAT_ARGB2101010; 326b8e80941Smrg break; 327b8e80941Smrg case PIPE_FORMAT_R10G10B10X2_UNORM: 328b8e80941Smrg image_format = __DRI_IMAGE_FORMAT_XBGR2101010; 329b8e80941Smrg break; 330b8e80941Smrg case PIPE_FORMAT_R10G10B10A2_UNORM: 331b8e80941Smrg image_format = __DRI_IMAGE_FORMAT_ABGR2101010; 332b8e80941Smrg break; 333848b8605Smrg default: 334848b8605Smrg image_format = __DRI_IMAGE_FORMAT_NONE; 335848b8605Smrg break; 336848b8605Smrg } 337848b8605Smrg } 338848b8605Smrg 339848b8605Smrg return (*sPriv->image.loader->getBuffers) (dPriv, image_format, 340848b8605Smrg (uint32_t *) &drawable->base.stamp, 341848b8605Smrg dPriv->loaderPrivate, buffer_mask, 342848b8605Smrg images); 343848b8605Smrg} 344848b8605Smrg 345848b8605Smrgstatic __DRIbuffer * 346848b8605Smrgdri2_allocate_buffer(__DRIscreen *sPriv, 347848b8605Smrg unsigned attachment, unsigned format, 348848b8605Smrg int width, int height) 349848b8605Smrg{ 350848b8605Smrg struct dri_screen *screen = dri_screen(sPriv); 351848b8605Smrg struct dri2_buffer *buffer; 352848b8605Smrg struct pipe_resource templ; 353848b8605Smrg enum pipe_format pf; 354848b8605Smrg unsigned bind = 0; 355848b8605Smrg struct winsys_handle whandle; 356848b8605Smrg 357848b8605Smrg switch (attachment) { 358848b8605Smrg case __DRI_BUFFER_FRONT_LEFT: 359848b8605Smrg case __DRI_BUFFER_FAKE_FRONT_LEFT: 360848b8605Smrg bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; 361848b8605Smrg break; 362848b8605Smrg case __DRI_BUFFER_BACK_LEFT: 363848b8605Smrg bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; 364848b8605Smrg break; 365848b8605Smrg case __DRI_BUFFER_DEPTH: 366848b8605Smrg case __DRI_BUFFER_DEPTH_STENCIL: 367848b8605Smrg case __DRI_BUFFER_STENCIL: 368848b8605Smrg bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */ 369848b8605Smrg break; 370848b8605Smrg } 371848b8605Smrg 372848b8605Smrg /* because we get the handle and stride */ 373848b8605Smrg bind |= PIPE_BIND_SHARED; 374848b8605Smrg 375848b8605Smrg switch (format) { 376848b8605Smrg case 32: 377b8e80941Smrg pf = PIPE_FORMAT_BGRA8888_UNORM; 378b8e80941Smrg break; 379b8e80941Smrg case 30: 380b8e80941Smrg pf = PIPE_FORMAT_B10G10R10X2_UNORM; 381848b8605Smrg break; 382848b8605Smrg case 24: 383b8e80941Smrg pf = PIPE_FORMAT_BGRX8888_UNORM; 384848b8605Smrg break; 385848b8605Smrg case 16: 386848b8605Smrg pf = PIPE_FORMAT_Z16_UNORM; 387848b8605Smrg break; 388848b8605Smrg default: 389848b8605Smrg return NULL; 390848b8605Smrg } 391848b8605Smrg 392848b8605Smrg buffer = CALLOC_STRUCT(dri2_buffer); 393848b8605Smrg if (!buffer) 394848b8605Smrg return NULL; 395848b8605Smrg 396848b8605Smrg memset(&templ, 0, sizeof(templ)); 397848b8605Smrg templ.bind = bind; 398848b8605Smrg templ.format = pf; 399848b8605Smrg templ.target = PIPE_TEXTURE_2D; 400848b8605Smrg templ.last_level = 0; 401848b8605Smrg templ.width0 = width; 402848b8605Smrg templ.height0 = height; 403848b8605Smrg templ.depth0 = 1; 404848b8605Smrg templ.array_size = 1; 405848b8605Smrg 406848b8605Smrg buffer->resource = 407848b8605Smrg screen->base.screen->resource_create(screen->base.screen, &templ); 408848b8605Smrg if (!buffer->resource) { 409848b8605Smrg FREE(buffer); 410848b8605Smrg return NULL; 411848b8605Smrg } 412848b8605Smrg 413848b8605Smrg memset(&whandle, 0, sizeof(whandle)); 414848b8605Smrg if (screen->can_share_buffer) 415b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_SHARED; 416848b8605Smrg else 417b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_KMS; 418848b8605Smrg 419b8e80941Smrg screen->base.screen->resource_get_handle(screen->base.screen, NULL, 420b8e80941Smrg buffer->resource, &whandle, 421b8e80941Smrg PIPE_HANDLE_USAGE_EXPLICIT_FLUSH); 422848b8605Smrg 423848b8605Smrg buffer->base.attachment = attachment; 424848b8605Smrg buffer->base.name = whandle.handle; 425848b8605Smrg buffer->base.cpp = util_format_get_blocksize(pf); 426848b8605Smrg buffer->base.pitch = whandle.stride; 427848b8605Smrg 428848b8605Smrg return &buffer->base; 429848b8605Smrg} 430848b8605Smrg 431848b8605Smrgstatic void 432848b8605Smrgdri2_release_buffer(__DRIscreen *sPriv, __DRIbuffer *bPriv) 433848b8605Smrg{ 434848b8605Smrg struct dri2_buffer *buffer = dri2_buffer(bPriv); 435848b8605Smrg 436848b8605Smrg pipe_resource_reference(&buffer->resource, NULL); 437848b8605Smrg FREE(buffer); 438848b8605Smrg} 439848b8605Smrg 440848b8605Smrg/* 441848b8605Smrg * Backend functions for st_framebuffer interface. 442848b8605Smrg */ 443848b8605Smrg 444848b8605Smrgstatic void 445848b8605Smrgdri2_allocate_textures(struct dri_context *ctx, 446848b8605Smrg struct dri_drawable *drawable, 447848b8605Smrg const enum st_attachment_type *statts, 448848b8605Smrg unsigned statts_count) 449848b8605Smrg{ 450848b8605Smrg __DRIscreen *sPriv = drawable->sPriv; 451848b8605Smrg __DRIdrawable *dri_drawable = drawable->dPriv; 452848b8605Smrg struct dri_screen *screen = dri_screen(sPriv); 453848b8605Smrg struct pipe_resource templ; 454848b8605Smrg boolean alloc_depthstencil = FALSE; 455848b8605Smrg unsigned i, j, bind; 456848b8605Smrg const __DRIimageLoaderExtension *image = sPriv->image.loader; 457848b8605Smrg /* Image specific variables */ 458848b8605Smrg struct __DRIimageList images; 459848b8605Smrg /* Dri2 specific variables */ 460b8e80941Smrg __DRIbuffer *buffers = NULL; 461848b8605Smrg struct winsys_handle whandle; 462848b8605Smrg unsigned num_buffers = statts_count; 463848b8605Smrg 464848b8605Smrg /* First get the buffers from the loader */ 465848b8605Smrg if (image) { 466848b8605Smrg if (!dri_image_drawable_get_buffers(drawable, &images, 467848b8605Smrg statts, statts_count)) 468848b8605Smrg return; 469848b8605Smrg } 470848b8605Smrg else { 471848b8605Smrg buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers); 472848b8605Smrg if (!buffers || (drawable->old_num == num_buffers && 473848b8605Smrg drawable->old_w == dri_drawable->w && 474848b8605Smrg drawable->old_h == dri_drawable->h && 475848b8605Smrg memcmp(drawable->old, buffers, 476848b8605Smrg sizeof(__DRIbuffer) * num_buffers) == 0)) 477848b8605Smrg return; 478848b8605Smrg } 479848b8605Smrg 480848b8605Smrg /* Second clean useless resources*/ 481848b8605Smrg 482848b8605Smrg /* See if we need a depth-stencil buffer. */ 483848b8605Smrg for (i = 0; i < statts_count; i++) { 484848b8605Smrg if (statts[i] == ST_ATTACHMENT_DEPTH_STENCIL) { 485848b8605Smrg alloc_depthstencil = TRUE; 486848b8605Smrg break; 487848b8605Smrg } 488848b8605Smrg } 489848b8605Smrg 490848b8605Smrg /* Delete the resources we won't need. */ 491848b8605Smrg for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { 492848b8605Smrg /* Don't delete the depth-stencil buffer, we can reuse it. */ 493848b8605Smrg if (i == ST_ATTACHMENT_DEPTH_STENCIL && alloc_depthstencil) 494848b8605Smrg continue; 495848b8605Smrg 496848b8605Smrg /* Flush the texture before unreferencing, so that other clients can 497848b8605Smrg * see what the driver has rendered. 498848b8605Smrg */ 499848b8605Smrg if (i != ST_ATTACHMENT_DEPTH_STENCIL && drawable->textures[i]) { 500848b8605Smrg struct pipe_context *pipe = ctx->st->pipe; 501848b8605Smrg pipe->flush_resource(pipe, drawable->textures[i]); 502848b8605Smrg } 503848b8605Smrg 504848b8605Smrg pipe_resource_reference(&drawable->textures[i], NULL); 505848b8605Smrg } 506848b8605Smrg 507848b8605Smrg if (drawable->stvis.samples > 1) { 508848b8605Smrg for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { 509848b8605Smrg boolean del = TRUE; 510848b8605Smrg 511848b8605Smrg /* Don't delete MSAA resources for the attachments which are enabled, 512848b8605Smrg * we can reuse them. */ 513848b8605Smrg for (j = 0; j < statts_count; j++) { 514848b8605Smrg if (i == statts[j]) { 515848b8605Smrg del = FALSE; 516848b8605Smrg break; 517848b8605Smrg } 518848b8605Smrg } 519848b8605Smrg 520848b8605Smrg if (del) { 521848b8605Smrg pipe_resource_reference(&drawable->msaa_textures[i], NULL); 522848b8605Smrg } 523848b8605Smrg } 524848b8605Smrg } 525848b8605Smrg 526848b8605Smrg /* Third use the buffers retrieved to fill the drawable info */ 527848b8605Smrg 528848b8605Smrg memset(&templ, 0, sizeof(templ)); 529848b8605Smrg templ.target = screen->target; 530848b8605Smrg templ.last_level = 0; 531848b8605Smrg templ.depth0 = 1; 532848b8605Smrg templ.array_size = 1; 533848b8605Smrg 534848b8605Smrg if (image) { 535848b8605Smrg if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) { 536848b8605Smrg struct pipe_resource **buf = 537848b8605Smrg &drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; 538848b8605Smrg struct pipe_resource *texture = images.front->texture; 539848b8605Smrg 540848b8605Smrg dri_drawable->w = texture->width0; 541848b8605Smrg dri_drawable->h = texture->height0; 542848b8605Smrg 543848b8605Smrg pipe_resource_reference(buf, texture); 544848b8605Smrg } 545848b8605Smrg 546848b8605Smrg if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) { 547848b8605Smrg struct pipe_resource **buf = 548848b8605Smrg &drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 549848b8605Smrg struct pipe_resource *texture = images.back->texture; 550848b8605Smrg 551848b8605Smrg dri_drawable->w = texture->width0; 552848b8605Smrg dri_drawable->h = texture->height0; 553848b8605Smrg 554848b8605Smrg pipe_resource_reference(buf, texture); 555848b8605Smrg } 556848b8605Smrg 557848b8605Smrg /* Note: if there is both a back and a front buffer, 558848b8605Smrg * then they have the same size. 559848b8605Smrg */ 560848b8605Smrg templ.width0 = dri_drawable->w; 561848b8605Smrg templ.height0 = dri_drawable->h; 562848b8605Smrg } 563848b8605Smrg else { 564848b8605Smrg memset(&whandle, 0, sizeof(whandle)); 565848b8605Smrg 566848b8605Smrg /* Process DRI-provided buffers and get pipe_resources. */ 567848b8605Smrg for (i = 0; i < num_buffers; i++) { 568848b8605Smrg __DRIbuffer *buf = &buffers[i]; 569848b8605Smrg enum st_attachment_type statt; 570848b8605Smrg enum pipe_format format; 571848b8605Smrg 572848b8605Smrg switch (buf->attachment) { 573848b8605Smrg case __DRI_BUFFER_FRONT_LEFT: 574848b8605Smrg if (!screen->auto_fake_front) { 575848b8605Smrg continue; /* invalid attachment */ 576848b8605Smrg } 577848b8605Smrg /* fallthrough */ 578848b8605Smrg case __DRI_BUFFER_FAKE_FRONT_LEFT: 579848b8605Smrg statt = ST_ATTACHMENT_FRONT_LEFT; 580848b8605Smrg break; 581848b8605Smrg case __DRI_BUFFER_BACK_LEFT: 582848b8605Smrg statt = ST_ATTACHMENT_BACK_LEFT; 583848b8605Smrg break; 584848b8605Smrg default: 585848b8605Smrg continue; /* invalid attachment */ 586848b8605Smrg } 587848b8605Smrg 588848b8605Smrg dri_drawable_get_format(drawable, statt, &format, &bind); 589848b8605Smrg if (format == PIPE_FORMAT_NONE) 590848b8605Smrg continue; 591848b8605Smrg 592848b8605Smrg /* dri2_drawable_get_buffers has already filled dri_drawable->w 593848b8605Smrg * and dri_drawable->h */ 594848b8605Smrg templ.width0 = dri_drawable->w; 595848b8605Smrg templ.height0 = dri_drawable->h; 596848b8605Smrg templ.format = format; 597848b8605Smrg templ.bind = bind; 598848b8605Smrg whandle.handle = buf->name; 599848b8605Smrg whandle.stride = buf->pitch; 600b8e80941Smrg whandle.offset = 0; 601b8e80941Smrg whandle.modifier = DRM_FORMAT_MOD_INVALID; 602848b8605Smrg if (screen->can_share_buffer) 603b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_SHARED; 604848b8605Smrg else 605b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_KMS; 606848b8605Smrg drawable->textures[statt] = 607848b8605Smrg screen->base.screen->resource_from_handle(screen->base.screen, 608b8e80941Smrg &templ, &whandle, 609b8e80941Smrg PIPE_HANDLE_USAGE_EXPLICIT_FLUSH); 610848b8605Smrg assert(drawable->textures[statt]); 611848b8605Smrg } 612848b8605Smrg } 613848b8605Smrg 614848b8605Smrg /* Allocate private MSAA colorbuffers. */ 615848b8605Smrg if (drawable->stvis.samples > 1) { 616848b8605Smrg for (i = 0; i < statts_count; i++) { 617848b8605Smrg enum st_attachment_type statt = statts[i]; 618848b8605Smrg 619848b8605Smrg if (statt == ST_ATTACHMENT_DEPTH_STENCIL) 620848b8605Smrg continue; 621848b8605Smrg 622848b8605Smrg if (drawable->textures[statt]) { 623848b8605Smrg templ.format = drawable->textures[statt]->format; 624b8e80941Smrg templ.bind = drawable->textures[statt]->bind & 625b8e80941Smrg ~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED); 626848b8605Smrg templ.nr_samples = drawable->stvis.samples; 627b8e80941Smrg templ.nr_storage_samples = drawable->stvis.samples; 628848b8605Smrg 629848b8605Smrg /* Try to reuse the resource. 630848b8605Smrg * (the other resource parameters should be constant) 631848b8605Smrg */ 632848b8605Smrg if (!drawable->msaa_textures[statt] || 633848b8605Smrg drawable->msaa_textures[statt]->width0 != templ.width0 || 634848b8605Smrg drawable->msaa_textures[statt]->height0 != templ.height0) { 635848b8605Smrg /* Allocate a new one. */ 636848b8605Smrg pipe_resource_reference(&drawable->msaa_textures[statt], NULL); 637848b8605Smrg 638848b8605Smrg drawable->msaa_textures[statt] = 639848b8605Smrg screen->base.screen->resource_create(screen->base.screen, 640848b8605Smrg &templ); 641848b8605Smrg assert(drawable->msaa_textures[statt]); 642848b8605Smrg 643848b8605Smrg /* If there are any MSAA resources, we should initialize them 644848b8605Smrg * such that they contain the same data as the single-sample 645848b8605Smrg * resources we just got from the X server. 646848b8605Smrg * 647848b8605Smrg * The reason for this is that the state tracker (and 648848b8605Smrg * therefore the app) can access the MSAA resources only. 649848b8605Smrg * The single-sample resources are not exposed 650848b8605Smrg * to the state tracker. 651848b8605Smrg * 652848b8605Smrg */ 653848b8605Smrg dri_pipe_blit(ctx->st->pipe, 654848b8605Smrg drawable->msaa_textures[statt], 655848b8605Smrg drawable->textures[statt]); 656848b8605Smrg } 657848b8605Smrg } 658848b8605Smrg else { 659848b8605Smrg pipe_resource_reference(&drawable->msaa_textures[statt], NULL); 660848b8605Smrg } 661848b8605Smrg } 662848b8605Smrg } 663848b8605Smrg 664848b8605Smrg /* Allocate a private depth-stencil buffer. */ 665848b8605Smrg if (alloc_depthstencil) { 666848b8605Smrg enum st_attachment_type statt = ST_ATTACHMENT_DEPTH_STENCIL; 667848b8605Smrg struct pipe_resource **zsbuf; 668848b8605Smrg enum pipe_format format; 669848b8605Smrg unsigned bind; 670848b8605Smrg 671848b8605Smrg dri_drawable_get_format(drawable, statt, &format, &bind); 672848b8605Smrg 673848b8605Smrg if (format) { 674848b8605Smrg templ.format = format; 675b8e80941Smrg templ.bind = bind & ~PIPE_BIND_SHARED; 676848b8605Smrg 677848b8605Smrg if (drawable->stvis.samples > 1) { 678848b8605Smrg templ.nr_samples = drawable->stvis.samples; 679b8e80941Smrg templ.nr_storage_samples = drawable->stvis.samples; 680848b8605Smrg zsbuf = &drawable->msaa_textures[statt]; 681848b8605Smrg } 682848b8605Smrg else { 683848b8605Smrg templ.nr_samples = 0; 684b8e80941Smrg templ.nr_storage_samples = 0; 685848b8605Smrg zsbuf = &drawable->textures[statt]; 686848b8605Smrg } 687848b8605Smrg 688848b8605Smrg /* Try to reuse the resource. 689848b8605Smrg * (the other resource parameters should be constant) 690848b8605Smrg */ 691848b8605Smrg if (!*zsbuf || 692848b8605Smrg (*zsbuf)->width0 != templ.width0 || 693848b8605Smrg (*zsbuf)->height0 != templ.height0) { 694848b8605Smrg /* Allocate a new one. */ 695848b8605Smrg pipe_resource_reference(zsbuf, NULL); 696848b8605Smrg *zsbuf = screen->base.screen->resource_create(screen->base.screen, 697848b8605Smrg &templ); 698848b8605Smrg assert(*zsbuf); 699848b8605Smrg } 700848b8605Smrg } 701848b8605Smrg else { 702848b8605Smrg pipe_resource_reference(&drawable->msaa_textures[statt], NULL); 703848b8605Smrg pipe_resource_reference(&drawable->textures[statt], NULL); 704848b8605Smrg } 705848b8605Smrg } 706848b8605Smrg 707848b8605Smrg /* For DRI2, we may get the same buffers again from the server. 708848b8605Smrg * To prevent useless imports of gem names, drawable->old* is used 709848b8605Smrg * to bypass the import if we get the same buffers. This doesn't apply 710848b8605Smrg * to DRI3/Wayland, users of image.loader, since the buffer is managed 711848b8605Smrg * by the client (no import), and the back buffer is going to change 712848b8605Smrg * at every redraw. 713848b8605Smrg */ 714848b8605Smrg if (!image) { 715848b8605Smrg drawable->old_num = num_buffers; 716848b8605Smrg drawable->old_w = dri_drawable->w; 717848b8605Smrg drawable->old_h = dri_drawable->h; 718848b8605Smrg memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * num_buffers); 719848b8605Smrg } 720848b8605Smrg} 721848b8605Smrg 722848b8605Smrgstatic void 723848b8605Smrgdri2_flush_frontbuffer(struct dri_context *ctx, 724848b8605Smrg struct dri_drawable *drawable, 725848b8605Smrg enum st_attachment_type statt) 726848b8605Smrg{ 727848b8605Smrg __DRIdrawable *dri_drawable = drawable->dPriv; 728848b8605Smrg const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader; 729848b8605Smrg const __DRIdri2LoaderExtension *loader = drawable->sPriv->dri2.loader; 730848b8605Smrg struct pipe_context *pipe = ctx->st->pipe; 731848b8605Smrg 732848b8605Smrg if (statt != ST_ATTACHMENT_FRONT_LEFT) 733848b8605Smrg return; 734848b8605Smrg 735848b8605Smrg if (drawable->stvis.samples > 1) { 736848b8605Smrg /* Resolve the front buffer. */ 737848b8605Smrg dri_pipe_blit(ctx->st->pipe, 738848b8605Smrg drawable->textures[ST_ATTACHMENT_FRONT_LEFT], 739848b8605Smrg drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]); 740848b8605Smrg } 741848b8605Smrg 742848b8605Smrg if (drawable->textures[ST_ATTACHMENT_FRONT_LEFT]) { 743848b8605Smrg pipe->flush_resource(pipe, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]); 744848b8605Smrg } 745848b8605Smrg 746848b8605Smrg pipe->flush(pipe, NULL, 0); 747848b8605Smrg 748848b8605Smrg if (image) { 749848b8605Smrg image->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); 750848b8605Smrg } 751848b8605Smrg else if (loader->flushFrontBuffer) { 752848b8605Smrg loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); 753848b8605Smrg } 754848b8605Smrg} 755848b8605Smrg 756b8e80941Smrg/** 757b8e80941Smrg * The struct dri_drawable flush_swapbuffers callback 758b8e80941Smrg */ 759b8e80941Smrgstatic void 760b8e80941Smrgdri2_flush_swapbuffers(struct dri_context *ctx, 761b8e80941Smrg struct dri_drawable *drawable) 762b8e80941Smrg{ 763b8e80941Smrg __DRIdrawable *dri_drawable = drawable->dPriv; 764b8e80941Smrg const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader; 765b8e80941Smrg 766b8e80941Smrg if (image && image->base.version >= 3 && image->flushSwapBuffers) { 767b8e80941Smrg image->flushSwapBuffers(dri_drawable, dri_drawable->loaderPrivate); 768b8e80941Smrg } 769b8e80941Smrg} 770b8e80941Smrg 771848b8605Smrgstatic void 772848b8605Smrgdri2_update_tex_buffer(struct dri_drawable *drawable, 773848b8605Smrg struct dri_context *ctx, 774848b8605Smrg struct pipe_resource *res) 775848b8605Smrg{ 776848b8605Smrg /* no-op */ 777848b8605Smrg} 778848b8605Smrg 779848b8605Smrgstatic __DRIimage * 780848b8605Smrgdri2_create_image_from_winsys(__DRIscreen *_screen, 781b8e80941Smrg int width, int height, enum pipe_format pf, 782b8e80941Smrg int num_handles, struct winsys_handle *whandle, 783848b8605Smrg void *loaderPrivate) 784848b8605Smrg{ 785848b8605Smrg struct dri_screen *screen = dri_screen(_screen); 786b8e80941Smrg struct pipe_screen *pscreen = screen->base.screen; 787848b8605Smrg __DRIimage *img; 788848b8605Smrg struct pipe_resource templ; 789b8e80941Smrg unsigned tex_usage = 0; 790b8e80941Smrg int i; 791b8e80941Smrg 792b8e80941Smrg if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0, 793b8e80941Smrg PIPE_BIND_RENDER_TARGET)) 794b8e80941Smrg tex_usage |= PIPE_BIND_RENDER_TARGET; 795b8e80941Smrg if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0, 796b8e80941Smrg PIPE_BIND_SAMPLER_VIEW)) 797b8e80941Smrg tex_usage |= PIPE_BIND_SAMPLER_VIEW; 798b8e80941Smrg 799b8e80941Smrg if (!tex_usage && util_format_is_yuv(pf)) { 800b8e80941Smrg /* YUV format sampling can be emulated by the Mesa state tracker by 801b8e80941Smrg * using multiple R8/RG88 samplers. So try to rewrite the pipe format. 802b8e80941Smrg */ 803b8e80941Smrg pf = PIPE_FORMAT_R8_UNORM; 804848b8605Smrg 805b8e80941Smrg if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0, 806b8e80941Smrg PIPE_BIND_SAMPLER_VIEW)) 807b8e80941Smrg tex_usage |= PIPE_BIND_SAMPLER_VIEW; 808848b8605Smrg } 809b8e80941Smrg 810b8e80941Smrg if (!tex_usage) 811848b8605Smrg return NULL; 812848b8605Smrg 813848b8605Smrg img = CALLOC_STRUCT(__DRIimageRec); 814848b8605Smrg if (!img) 815848b8605Smrg return NULL; 816848b8605Smrg 817848b8605Smrg memset(&templ, 0, sizeof(templ)); 818848b8605Smrg templ.bind = tex_usage; 819848b8605Smrg templ.target = screen->target; 820848b8605Smrg templ.last_level = 0; 821848b8605Smrg templ.depth0 = 1; 822848b8605Smrg templ.array_size = 1; 823848b8605Smrg 824b8e80941Smrg for (i = num_handles - 1; i >= 0; i--) { 825b8e80941Smrg struct pipe_resource *tex; 826848b8605Smrg 827b8e80941Smrg /* TODO: something a lot less ugly */ 828b8e80941Smrg switch (i) { 829b8e80941Smrg case 0: 830b8e80941Smrg templ.width0 = width; 831b8e80941Smrg templ.height0 = height; 832b8e80941Smrg templ.format = pf; 833b8e80941Smrg break; 834b8e80941Smrg case 1: 835b8e80941Smrg templ.width0 = width / 2; 836b8e80941Smrg templ.height0 = height / 2; 837b8e80941Smrg templ.format = (num_handles == 2) ? 838b8e80941Smrg PIPE_FORMAT_RG88_UNORM : /* NV12, etc */ 839b8e80941Smrg PIPE_FORMAT_R8_UNORM; /* I420, etc */ 840b8e80941Smrg break; 841b8e80941Smrg case 2: 842b8e80941Smrg templ.width0 = width / 2; 843b8e80941Smrg templ.height0 = height / 2; 844b8e80941Smrg templ.format = PIPE_FORMAT_R8_UNORM; 845b8e80941Smrg break; 846b8e80941Smrg default: 847b8e80941Smrg unreachable("too many planes!"); 848b8e80941Smrg } 849b8e80941Smrg 850b8e80941Smrg tex = pscreen->resource_from_handle(pscreen, 851b8e80941Smrg &templ, &whandle[i], PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); 852b8e80941Smrg if (!tex) { 853b8e80941Smrg pipe_resource_reference(&img->texture, NULL); 854b8e80941Smrg FREE(img); 855b8e80941Smrg return NULL; 856b8e80941Smrg } 857b8e80941Smrg 858b8e80941Smrg tex->next = img->texture; 859b8e80941Smrg img->texture = tex; 860848b8605Smrg } 861848b8605Smrg 862848b8605Smrg img->level = 0; 863848b8605Smrg img->layer = 0; 864b8e80941Smrg img->use = 0; 865848b8605Smrg img->loader_private = loaderPrivate; 866848b8605Smrg 867848b8605Smrg return img; 868848b8605Smrg} 869848b8605Smrg 870848b8605Smrgstatic __DRIimage * 871848b8605Smrgdri2_create_image_from_name(__DRIscreen *_screen, 872848b8605Smrg int width, int height, int format, 873848b8605Smrg int name, int pitch, void *loaderPrivate) 874848b8605Smrg{ 875b8e80941Smrg const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format); 876848b8605Smrg struct winsys_handle whandle; 877b8e80941Smrg __DRIimage *img; 878b8e80941Smrg 879b8e80941Smrg if (!map) 880b8e80941Smrg return NULL; 881848b8605Smrg 882848b8605Smrg memset(&whandle, 0, sizeof(whandle)); 883b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_SHARED; 884848b8605Smrg whandle.handle = name; 885b8e80941Smrg whandle.modifier = DRM_FORMAT_MOD_INVALID; 886848b8605Smrg 887b8e80941Smrg whandle.stride = pitch * util_format_get_blocksize(map->pipe_format); 888848b8605Smrg 889b8e80941Smrg img = dri2_create_image_from_winsys(_screen, width, height, map->pipe_format, 890b8e80941Smrg 1, &whandle, loaderPrivate); 891848b8605Smrg 892b8e80941Smrg if (!img) 893848b8605Smrg return NULL; 894848b8605Smrg 895b8e80941Smrg img->dri_components = map->dri_components; 896b8e80941Smrg img->dri_fourcc = map->dri_fourcc; 897b8e80941Smrg img->dri_format = map->dri_format; 898848b8605Smrg 899b8e80941Smrg return img; 900848b8605Smrg} 901848b8605Smrg 902848b8605Smrgstatic __DRIimage * 903b8e80941Smrgdri2_create_image_from_fd(__DRIscreen *_screen, 904b8e80941Smrg int width, int height, int fourcc, 905b8e80941Smrg uint64_t modifier, int *fds, int num_fds, 906b8e80941Smrg int *strides, int *offsets, unsigned *error, 907b8e80941Smrg void *loaderPrivate) 908848b8605Smrg{ 909b8e80941Smrg struct winsys_handle whandles[3]; 910b8e80941Smrg const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc); 911b8e80941Smrg __DRIimage *img = NULL; 912b8e80941Smrg unsigned err = __DRI_IMAGE_ERROR_SUCCESS; 913b8e80941Smrg int expected_num_fds, i; 914b8e80941Smrg 915b8e80941Smrg if (!map) { 916b8e80941Smrg err = __DRI_IMAGE_ERROR_BAD_MATCH; 917b8e80941Smrg goto exit; 918b8e80941Smrg } 919848b8605Smrg 920b8e80941Smrg switch (fourcc) { 921b8e80941Smrg case __DRI_IMAGE_FOURCC_YUV420: 922b8e80941Smrg case __DRI_IMAGE_FOURCC_YVU420: 923b8e80941Smrg expected_num_fds = 3; 924b8e80941Smrg break; 925b8e80941Smrg case __DRI_IMAGE_FOURCC_NV12: 926b8e80941Smrg expected_num_fds = 2; 927b8e80941Smrg break; 928b8e80941Smrg default: 929b8e80941Smrg expected_num_fds = 1; 930b8e80941Smrg break; 931b8e80941Smrg } 932848b8605Smrg 933b8e80941Smrg if (num_fds != expected_num_fds) { 934b8e80941Smrg err = __DRI_IMAGE_ERROR_BAD_MATCH; 935b8e80941Smrg goto exit; 936b8e80941Smrg } 937b8e80941Smrg 938b8e80941Smrg memset(whandles, 0, sizeof(whandles)); 939b8e80941Smrg 940b8e80941Smrg for (i = 0; i < num_fds; i++) { 941b8e80941Smrg if (fds[i] < 0) { 942b8e80941Smrg err = __DRI_IMAGE_ERROR_BAD_ALLOC; 943b8e80941Smrg goto exit; 944b8e80941Smrg } 945b8e80941Smrg 946b8e80941Smrg whandles[i].type = WINSYS_HANDLE_TYPE_FD; 947b8e80941Smrg whandles[i].handle = (unsigned)fds[i]; 948b8e80941Smrg whandles[i].stride = (unsigned)strides[i]; 949b8e80941Smrg whandles[i].offset = (unsigned)offsets[i]; 950b8e80941Smrg whandles[i].modifier = modifier; 951b8e80941Smrg } 952b8e80941Smrg 953b8e80941Smrg if (fourcc == __DRI_IMAGE_FOURCC_YVU420) { 954b8e80941Smrg /* convert to YUV420 by swapping 2nd and 3rd planes: */ 955b8e80941Smrg struct winsys_handle tmp = whandles[1]; 956b8e80941Smrg whandles[1] = whandles[2]; 957b8e80941Smrg whandles[2] = tmp; 958b8e80941Smrg fourcc = __DRI_IMAGE_FOURCC_YUV420; 959b8e80941Smrg map = dri2_get_mapping_by_fourcc(fourcc); 960b8e80941Smrg } 961b8e80941Smrg 962b8e80941Smrg img = dri2_create_image_from_winsys(_screen, width, height, map->pipe_format, 963b8e80941Smrg num_fds, whandles, loaderPrivate); 964b8e80941Smrg if(img == NULL) { 965b8e80941Smrg err = __DRI_IMAGE_ERROR_BAD_ALLOC; 966b8e80941Smrg goto exit; 967b8e80941Smrg } 968b8e80941Smrg 969b8e80941Smrg img->dri_components = map->dri_components; 970b8e80941Smrg img->dri_fourcc = fourcc; 971b8e80941Smrg img->dri_format = map->dri_format; 972b8e80941Smrg 973b8e80941Smrgexit: 974b8e80941Smrg if (error) 975b8e80941Smrg *error = err; 976b8e80941Smrg 977b8e80941Smrg return img; 978848b8605Smrg} 979848b8605Smrg 980848b8605Smrgstatic __DRIimage * 981b8e80941Smrgdri2_create_image_common(__DRIscreen *_screen, 982b8e80941Smrg int width, int height, 983b8e80941Smrg int format, unsigned int use, 984b8e80941Smrg const uint64_t *modifiers, 985b8e80941Smrg const unsigned count, 986b8e80941Smrg void *loaderPrivate) 987848b8605Smrg{ 988b8e80941Smrg const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format); 989848b8605Smrg struct dri_screen *screen = dri_screen(_screen); 990848b8605Smrg __DRIimage *img; 991848b8605Smrg struct pipe_resource templ; 992848b8605Smrg unsigned tex_usage; 993b8e80941Smrg 994b8e80941Smrg if (!map) 995b8e80941Smrg return NULL; 996848b8605Smrg 997848b8605Smrg tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; 998b8e80941Smrg 999848b8605Smrg if (use & __DRI_IMAGE_USE_SCANOUT) 1000848b8605Smrg tex_usage |= PIPE_BIND_SCANOUT; 1001848b8605Smrg if (use & __DRI_IMAGE_USE_SHARE) 1002848b8605Smrg tex_usage |= PIPE_BIND_SHARED; 1003848b8605Smrg if (use & __DRI_IMAGE_USE_LINEAR) 1004848b8605Smrg tex_usage |= PIPE_BIND_LINEAR; 1005848b8605Smrg if (use & __DRI_IMAGE_USE_CURSOR) { 1006848b8605Smrg if (width != 64 || height != 64) 1007848b8605Smrg return NULL; 1008848b8605Smrg tex_usage |= PIPE_BIND_CURSOR; 1009848b8605Smrg } 1010848b8605Smrg 1011848b8605Smrg img = CALLOC_STRUCT(__DRIimageRec); 1012848b8605Smrg if (!img) 1013848b8605Smrg return NULL; 1014848b8605Smrg 1015848b8605Smrg memset(&templ, 0, sizeof(templ)); 1016848b8605Smrg templ.bind = tex_usage; 1017b8e80941Smrg templ.format = map->pipe_format; 1018848b8605Smrg templ.target = PIPE_TEXTURE_2D; 1019848b8605Smrg templ.last_level = 0; 1020848b8605Smrg templ.width0 = width; 1021848b8605Smrg templ.height0 = height; 1022848b8605Smrg templ.depth0 = 1; 1023848b8605Smrg templ.array_size = 1; 1024848b8605Smrg 1025b8e80941Smrg if (modifiers) 1026b8e80941Smrg img->texture = 1027b8e80941Smrg screen->base.screen 1028b8e80941Smrg ->resource_create_with_modifiers(screen->base.screen, 1029b8e80941Smrg &templ, 1030b8e80941Smrg modifiers, 1031b8e80941Smrg count); 1032b8e80941Smrg else 1033b8e80941Smrg img->texture = 1034b8e80941Smrg screen->base.screen->resource_create(screen->base.screen, &templ); 1035848b8605Smrg if (!img->texture) { 1036848b8605Smrg FREE(img); 1037848b8605Smrg return NULL; 1038848b8605Smrg } 1039848b8605Smrg 1040848b8605Smrg img->level = 0; 1041848b8605Smrg img->layer = 0; 1042848b8605Smrg img->dri_format = format; 1043b8e80941Smrg img->dri_fourcc = map->dri_fourcc; 1044848b8605Smrg img->dri_components = 0; 1045b8e80941Smrg img->use = use; 1046848b8605Smrg 1047848b8605Smrg img->loader_private = loaderPrivate; 1048848b8605Smrg return img; 1049848b8605Smrg} 1050848b8605Smrg 1051b8e80941Smrgstatic __DRIimage * 1052b8e80941Smrgdri2_create_image(__DRIscreen *_screen, 1053b8e80941Smrg int width, int height, int format, 1054b8e80941Smrg unsigned int use, void *loaderPrivate) 1055b8e80941Smrg{ 1056b8e80941Smrg return dri2_create_image_common(_screen, width, height, format, use, 1057b8e80941Smrg NULL /* modifiers */, 0 /* count */, 1058b8e80941Smrg loaderPrivate); 1059b8e80941Smrg} 1060b8e80941Smrg 1061b8e80941Smrgstatic __DRIimage * 1062b8e80941Smrgdri2_create_image_with_modifiers(__DRIscreen *dri_screen, 1063b8e80941Smrg int width, int height, int format, 1064b8e80941Smrg const uint64_t *modifiers, 1065b8e80941Smrg const unsigned count, 1066b8e80941Smrg void *loaderPrivate) 1067b8e80941Smrg{ 1068b8e80941Smrg return dri2_create_image_common(dri_screen, width, height, format, 1069b8e80941Smrg __DRI_IMAGE_USE_SHARE, modifiers, count, 1070b8e80941Smrg loaderPrivate); 1071b8e80941Smrg} 1072b8e80941Smrg 1073848b8605Smrgstatic GLboolean 1074848b8605Smrgdri2_query_image(__DRIimage *image, int attrib, int *value) 1075848b8605Smrg{ 1076848b8605Smrg struct winsys_handle whandle; 1077b8e80941Smrg unsigned usage; 1078b8e80941Smrg 1079b8e80941Smrg if (image->use & __DRI_IMAGE_USE_BACKBUFFER) 1080b8e80941Smrg usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH; 1081b8e80941Smrg else 1082b8e80941Smrg usage = PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE; 1083b8e80941Smrg 1084848b8605Smrg memset(&whandle, 0, sizeof(whandle)); 1085848b8605Smrg 1086848b8605Smrg switch (attrib) { 1087848b8605Smrg case __DRI_IMAGE_ATTRIB_STRIDE: 1088b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_KMS; 1089b8e80941Smrg if (!image->texture->screen->resource_get_handle(image->texture->screen, 1090b8e80941Smrg NULL, image->texture, &whandle, usage)) 1091b8e80941Smrg return GL_FALSE; 1092848b8605Smrg *value = whandle.stride; 1093848b8605Smrg return GL_TRUE; 1094b8e80941Smrg case __DRI_IMAGE_ATTRIB_OFFSET: 1095b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_KMS; 1096b8e80941Smrg if (!image->texture->screen->resource_get_handle(image->texture->screen, 1097b8e80941Smrg NULL, image->texture, &whandle, usage)) 1098b8e80941Smrg return GL_FALSE; 1099b8e80941Smrg *value = whandle.offset; 1100b8e80941Smrg return GL_TRUE; 1101848b8605Smrg case __DRI_IMAGE_ATTRIB_HANDLE: 1102b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_KMS; 1103b8e80941Smrg if (!image->texture->screen->resource_get_handle(image->texture->screen, 1104b8e80941Smrg NULL, image->texture, &whandle, usage)) 1105b8e80941Smrg return GL_FALSE; 1106848b8605Smrg *value = whandle.handle; 1107848b8605Smrg return GL_TRUE; 1108848b8605Smrg case __DRI_IMAGE_ATTRIB_NAME: 1109b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_SHARED; 1110b8e80941Smrg if (!image->texture->screen->resource_get_handle(image->texture->screen, 1111b8e80941Smrg NULL, image->texture, &whandle, usage)) 1112b8e80941Smrg return GL_FALSE; 1113848b8605Smrg *value = whandle.handle; 1114848b8605Smrg return GL_TRUE; 1115848b8605Smrg case __DRI_IMAGE_ATTRIB_FD: 1116b8e80941Smrg whandle.type= WINSYS_HANDLE_TYPE_FD; 1117b8e80941Smrg if (!image->texture->screen->resource_get_handle(image->texture->screen, 1118b8e80941Smrg NULL, image->texture, &whandle, usage)) 1119b8e80941Smrg return GL_FALSE; 1120b8e80941Smrg 1121848b8605Smrg *value = whandle.handle; 1122848b8605Smrg return GL_TRUE; 1123848b8605Smrg case __DRI_IMAGE_ATTRIB_FORMAT: 1124848b8605Smrg *value = image->dri_format; 1125848b8605Smrg return GL_TRUE; 1126848b8605Smrg case __DRI_IMAGE_ATTRIB_WIDTH: 1127848b8605Smrg *value = image->texture->width0; 1128848b8605Smrg return GL_TRUE; 1129848b8605Smrg case __DRI_IMAGE_ATTRIB_HEIGHT: 1130848b8605Smrg *value = image->texture->height0; 1131848b8605Smrg return GL_TRUE; 1132848b8605Smrg case __DRI_IMAGE_ATTRIB_COMPONENTS: 1133848b8605Smrg if (image->dri_components == 0) 1134848b8605Smrg return GL_FALSE; 1135848b8605Smrg *value = image->dri_components; 1136848b8605Smrg return GL_TRUE; 1137b8e80941Smrg case __DRI_IMAGE_ATTRIB_FOURCC: 1138b8e80941Smrg if (image->dri_fourcc) { 1139b8e80941Smrg *value = image->dri_fourcc; 1140b8e80941Smrg } else { 1141b8e80941Smrg const struct dri2_format_mapping *map; 1142b8e80941Smrg 1143b8e80941Smrg map = dri2_get_mapping_by_format(image->dri_format); 1144b8e80941Smrg if (!map) 1145b8e80941Smrg return GL_FALSE; 1146b8e80941Smrg 1147b8e80941Smrg *value = map->dri_fourcc; 1148b8e80941Smrg } 1149b8e80941Smrg return GL_TRUE; 1150b8e80941Smrg case __DRI_IMAGE_ATTRIB_NUM_PLANES: 1151b8e80941Smrg *value = 1; 1152b8e80941Smrg return GL_TRUE; 1153b8e80941Smrg case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER: 1154b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_KMS; 1155b8e80941Smrg whandle.modifier = DRM_FORMAT_MOD_INVALID; 1156b8e80941Smrg if (!image->texture->screen->resource_get_handle(image->texture->screen, 1157b8e80941Smrg NULL, image->texture, &whandle, usage)) 1158b8e80941Smrg return GL_FALSE; 1159b8e80941Smrg if (whandle.modifier == DRM_FORMAT_MOD_INVALID) 1160b8e80941Smrg return GL_FALSE; 1161b8e80941Smrg *value = (whandle.modifier >> 32) & 0xffffffff; 1162b8e80941Smrg return GL_TRUE; 1163b8e80941Smrg case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER: 1164b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_KMS; 1165b8e80941Smrg whandle.modifier = DRM_FORMAT_MOD_INVALID; 1166b8e80941Smrg if (!image->texture->screen->resource_get_handle(image->texture->screen, 1167b8e80941Smrg NULL, image->texture, &whandle, usage)) 1168b8e80941Smrg return GL_FALSE; 1169b8e80941Smrg if (whandle.modifier == DRM_FORMAT_MOD_INVALID) 1170b8e80941Smrg return GL_FALSE; 1171b8e80941Smrg *value = whandle.modifier & 0xffffffff; 1172b8e80941Smrg return GL_TRUE; 1173848b8605Smrg default: 1174848b8605Smrg return GL_FALSE; 1175848b8605Smrg } 1176848b8605Smrg} 1177848b8605Smrg 1178848b8605Smrgstatic __DRIimage * 1179848b8605Smrgdri2_dup_image(__DRIimage *image, void *loaderPrivate) 1180848b8605Smrg{ 1181848b8605Smrg __DRIimage *img; 1182848b8605Smrg 1183848b8605Smrg img = CALLOC_STRUCT(__DRIimageRec); 1184848b8605Smrg if (!img) 1185848b8605Smrg return NULL; 1186848b8605Smrg 1187848b8605Smrg img->texture = NULL; 1188848b8605Smrg pipe_resource_reference(&img->texture, image->texture); 1189848b8605Smrg img->level = image->level; 1190848b8605Smrg img->layer = image->layer; 1191848b8605Smrg img->dri_format = image->dri_format; 1192848b8605Smrg /* This should be 0 for sub images, but dup is also used for base images. */ 1193848b8605Smrg img->dri_components = image->dri_components; 1194848b8605Smrg img->loader_private = loaderPrivate; 1195848b8605Smrg 1196848b8605Smrg return img; 1197848b8605Smrg} 1198848b8605Smrg 1199848b8605Smrgstatic GLboolean 1200848b8605Smrgdri2_validate_usage(__DRIimage *image, unsigned int use) 1201848b8605Smrg{ 1202b8e80941Smrg if (!image || !image->texture) 1203b8e80941Smrg return false; 1204b8e80941Smrg 1205b8e80941Smrg struct pipe_screen *screen = image->texture->screen; 1206b8e80941Smrg if (!screen->check_resource_capability) 1207b8e80941Smrg return true; 1208b8e80941Smrg 1209b8e80941Smrg /* We don't want to check these: 1210b8e80941Smrg * __DRI_IMAGE_USE_SHARE (all images are shareable) 1211b8e80941Smrg * __DRI_IMAGE_USE_BACKBUFFER (all images support this) 1212848b8605Smrg */ 1213b8e80941Smrg unsigned bind = 0; 1214b8e80941Smrg if (use & __DRI_IMAGE_USE_SCANOUT) 1215b8e80941Smrg bind |= PIPE_BIND_SCANOUT; 1216b8e80941Smrg if (use & __DRI_IMAGE_USE_LINEAR) 1217b8e80941Smrg bind |= PIPE_BIND_LINEAR; 1218b8e80941Smrg if (use & __DRI_IMAGE_USE_CURSOR) 1219b8e80941Smrg bind |= PIPE_BIND_CURSOR; 1220b8e80941Smrg 1221b8e80941Smrg if (!bind) 1222b8e80941Smrg return true; 1223b8e80941Smrg 1224b8e80941Smrg return screen->check_resource_capability(screen, image->texture, bind); 1225848b8605Smrg} 1226848b8605Smrg 1227848b8605Smrgstatic __DRIimage * 1228848b8605Smrgdri2_from_names(__DRIscreen *screen, int width, int height, int format, 1229848b8605Smrg int *names, int num_names, int *strides, int *offsets, 1230848b8605Smrg void *loaderPrivate) 1231848b8605Smrg{ 1232b8e80941Smrg const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format); 1233848b8605Smrg __DRIimage *img; 1234b8e80941Smrg struct winsys_handle whandle; 1235848b8605Smrg 1236b8e80941Smrg if (!map) 1237848b8605Smrg return NULL; 1238848b8605Smrg 1239b8e80941Smrg if (num_names != 1) 1240848b8605Smrg return NULL; 1241848b8605Smrg 1242b8e80941Smrg memset(&whandle, 0, sizeof(whandle)); 1243b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_SHARED; 1244b8e80941Smrg whandle.handle = names[0]; 1245b8e80941Smrg whandle.stride = strides[0]; 1246b8e80941Smrg whandle.offset = offsets[0]; 1247b8e80941Smrg whandle.modifier = DRM_FORMAT_MOD_INVALID; 1248b8e80941Smrg 1249b8e80941Smrg img = dri2_create_image_from_winsys(screen, width, height, map->pipe_format, 1250b8e80941Smrg 1, &whandle, loaderPrivate); 1251848b8605Smrg if (img == NULL) 1252848b8605Smrg return NULL; 1253848b8605Smrg 1254b8e80941Smrg img->dri_components = map->dri_components; 1255b8e80941Smrg img->dri_fourcc = map->dri_fourcc; 1256b8e80941Smrg img->dri_format = map->pipe_format; 1257b8e80941Smrg 1258848b8605Smrg return img; 1259848b8605Smrg} 1260848b8605Smrg 1261848b8605Smrgstatic __DRIimage * 1262848b8605Smrgdri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate) 1263848b8605Smrg{ 1264848b8605Smrg __DRIimage *img; 1265848b8605Smrg 1266848b8605Smrg if (plane != 0) 1267848b8605Smrg return NULL; 1268848b8605Smrg 1269848b8605Smrg if (image->dri_components == 0) 1270848b8605Smrg return NULL; 1271848b8605Smrg 1272848b8605Smrg img = dri2_dup_image(image, loaderPrivate); 1273848b8605Smrg if (img == NULL) 1274848b8605Smrg return NULL; 1275848b8605Smrg 1276b8e80941Smrg if (img->texture->screen->resource_changed) 1277b8e80941Smrg img->texture->screen->resource_changed(img->texture->screen, 1278b8e80941Smrg img->texture); 1279b8e80941Smrg 1280848b8605Smrg /* set this to 0 for sub images. */ 1281848b8605Smrg img->dri_components = 0; 1282848b8605Smrg return img; 1283848b8605Smrg} 1284848b8605Smrg 1285848b8605Smrgstatic __DRIimage * 1286848b8605Smrgdri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc, 1287848b8605Smrg int *fds, int num_fds, int *strides, int *offsets, 1288848b8605Smrg void *loaderPrivate) 1289848b8605Smrg{ 1290b8e80941Smrg return dri2_create_image_from_fd(screen, width, height, fourcc, 1291b8e80941Smrg DRM_FORMAT_MOD_INVALID, fds, num_fds, 1292b8e80941Smrg strides, offsets, NULL, loaderPrivate); 1293b8e80941Smrg} 1294848b8605Smrg 1295b8e80941Smrgstatic boolean 1296b8e80941Smrgdri2_query_dma_buf_formats(__DRIscreen *_screen, int max, int *formats, 1297b8e80941Smrg int *count) 1298b8e80941Smrg{ 1299b8e80941Smrg struct dri_screen *screen = dri_screen(_screen); 1300b8e80941Smrg struct pipe_screen *pscreen = screen->base.screen; 1301b8e80941Smrg int i, j; 1302848b8605Smrg 1303b8e80941Smrg for (i = 0, j = 0; (i < ARRAY_SIZE(dri2_format_table)) && 1304b8e80941Smrg (j < max || max == 0); i++) { 1305b8e80941Smrg const struct dri2_format_mapping *map = &dri2_format_table[i]; 1306848b8605Smrg 1307b8e80941Smrg /* The sRGB format is not a real FourCC as defined by drm_fourcc.h, so we 1308b8e80941Smrg * must not leak it out to clients. 1309b8e80941Smrg */ 1310b8e80941Smrg if (dri2_format_table[i].dri_fourcc == __DRI_IMAGE_FOURCC_SARGB8888) 1311b8e80941Smrg continue; 1312848b8605Smrg 1313b8e80941Smrg if (pscreen->is_format_supported(pscreen, map->pipe_format, 1314b8e80941Smrg screen->target, 0, 0, 1315b8e80941Smrg PIPE_BIND_RENDER_TARGET) || 1316b8e80941Smrg pscreen->is_format_supported(pscreen, map->pipe_format, 1317b8e80941Smrg screen->target, 0, 0, 1318b8e80941Smrg PIPE_BIND_SAMPLER_VIEW)) { 1319b8e80941Smrg if (j < max) 1320b8e80941Smrg formats[j] = map->dri_fourcc; 1321b8e80941Smrg j++; 1322b8e80941Smrg } 1323b8e80941Smrg } 1324b8e80941Smrg *count = j; 1325b8e80941Smrg return true; 1326b8e80941Smrg} 1327848b8605Smrg 1328b8e80941Smrgstatic boolean 1329b8e80941Smrgdri2_query_dma_buf_modifiers(__DRIscreen *_screen, int fourcc, int max, 1330b8e80941Smrg uint64_t *modifiers, unsigned int *external_only, 1331b8e80941Smrg int *count) 1332b8e80941Smrg{ 1333b8e80941Smrg struct dri_screen *screen = dri_screen(_screen); 1334b8e80941Smrg struct pipe_screen *pscreen = screen->base.screen; 1335b8e80941Smrg const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc); 1336b8e80941Smrg enum pipe_format format; 1337b8e80941Smrg 1338b8e80941Smrg if (!map) 1339b8e80941Smrg return false; 1340b8e80941Smrg 1341b8e80941Smrg format = map->pipe_format; 1342b8e80941Smrg 1343b8e80941Smrg if (pscreen->query_dmabuf_modifiers != NULL && 1344b8e80941Smrg (pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, 1345b8e80941Smrg PIPE_BIND_RENDER_TARGET) || 1346b8e80941Smrg pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, 1347b8e80941Smrg PIPE_BIND_SAMPLER_VIEW))) { 1348b8e80941Smrg pscreen->query_dmabuf_modifiers(pscreen, format, max, modifiers, 1349b8e80941Smrg external_only, count); 1350b8e80941Smrg return true; 1351b8e80941Smrg } 1352b8e80941Smrg return false; 1353848b8605Smrg} 1354848b8605Smrg 1355848b8605Smrgstatic __DRIimage * 1356848b8605Smrgdri2_from_dma_bufs(__DRIscreen *screen, 1357848b8605Smrg int width, int height, int fourcc, 1358848b8605Smrg int *fds, int num_fds, 1359848b8605Smrg int *strides, int *offsets, 1360848b8605Smrg enum __DRIYUVColorSpace yuv_color_space, 1361848b8605Smrg enum __DRISampleRange sample_range, 1362848b8605Smrg enum __DRIChromaSiting horizontal_siting, 1363848b8605Smrg enum __DRIChromaSiting vertical_siting, 1364848b8605Smrg unsigned *error, 1365848b8605Smrg void *loaderPrivate) 1366848b8605Smrg{ 1367848b8605Smrg __DRIimage *img; 1368848b8605Smrg 1369b8e80941Smrg img = dri2_create_image_from_fd(screen, width, height, fourcc, 1370b8e80941Smrg DRM_FORMAT_MOD_INVALID, fds, num_fds, 1371b8e80941Smrg strides, offsets, error, loaderPrivate); 1372b8e80941Smrg if (img == NULL) 1373848b8605Smrg return NULL; 1374848b8605Smrg 1375b8e80941Smrg img->yuv_color_space = yuv_color_space; 1376b8e80941Smrg img->sample_range = sample_range; 1377b8e80941Smrg img->horizontal_siting = horizontal_siting; 1378b8e80941Smrg img->vertical_siting = vertical_siting; 1379848b8605Smrg 1380b8e80941Smrg *error = __DRI_IMAGE_ERROR_SUCCESS; 1381b8e80941Smrg return img; 1382b8e80941Smrg} 1383b8e80941Smrg 1384b8e80941Smrgstatic __DRIimage * 1385b8e80941Smrgdri2_from_dma_bufs2(__DRIscreen *screen, 1386b8e80941Smrg int width, int height, int fourcc, 1387b8e80941Smrg uint64_t modifier, int *fds, int num_fds, 1388b8e80941Smrg int *strides, int *offsets, 1389b8e80941Smrg enum __DRIYUVColorSpace yuv_color_space, 1390b8e80941Smrg enum __DRISampleRange sample_range, 1391b8e80941Smrg enum __DRIChromaSiting horizontal_siting, 1392b8e80941Smrg enum __DRIChromaSiting vertical_siting, 1393b8e80941Smrg unsigned *error, 1394b8e80941Smrg void *loaderPrivate) 1395b8e80941Smrg{ 1396b8e80941Smrg __DRIimage *img; 1397848b8605Smrg 1398b8e80941Smrg img = dri2_create_image_from_fd(screen, width, height, fourcc, 1399b8e80941Smrg modifier, fds, num_fds, strides, offsets, 1400b8e80941Smrg error, loaderPrivate); 1401b8e80941Smrg if (img == NULL) 1402848b8605Smrg return NULL; 1403848b8605Smrg 1404848b8605Smrg img->yuv_color_space = yuv_color_space; 1405848b8605Smrg img->sample_range = sample_range; 1406848b8605Smrg img->horizontal_siting = horizontal_siting; 1407848b8605Smrg img->vertical_siting = vertical_siting; 1408848b8605Smrg 1409848b8605Smrg *error = __DRI_IMAGE_ERROR_SUCCESS; 1410848b8605Smrg return img; 1411848b8605Smrg} 1412848b8605Smrg 1413848b8605Smrgstatic void 1414848b8605Smrgdri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src, 1415848b8605Smrg int dstx0, int dsty0, int dstwidth, int dstheight, 1416848b8605Smrg int srcx0, int srcy0, int srcwidth, int srcheight, 1417848b8605Smrg int flush_flag) 1418848b8605Smrg{ 1419848b8605Smrg struct dri_context *ctx = dri_context(context); 1420848b8605Smrg struct pipe_context *pipe = ctx->st->pipe; 1421848b8605Smrg struct pipe_screen *screen; 1422848b8605Smrg struct pipe_fence_handle *fence; 1423848b8605Smrg struct pipe_blit_info blit; 1424848b8605Smrg 1425848b8605Smrg if (!dst || !src) 1426848b8605Smrg return; 1427848b8605Smrg 1428848b8605Smrg memset(&blit, 0, sizeof(blit)); 1429848b8605Smrg blit.dst.resource = dst->texture; 1430848b8605Smrg blit.dst.box.x = dstx0; 1431848b8605Smrg blit.dst.box.y = dsty0; 1432848b8605Smrg blit.dst.box.width = dstwidth; 1433848b8605Smrg blit.dst.box.height = dstheight; 1434848b8605Smrg blit.dst.box.depth = 1; 1435848b8605Smrg blit.dst.format = dst->texture->format; 1436848b8605Smrg blit.src.resource = src->texture; 1437848b8605Smrg blit.src.box.x = srcx0; 1438848b8605Smrg blit.src.box.y = srcy0; 1439848b8605Smrg blit.src.box.width = srcwidth; 1440848b8605Smrg blit.src.box.height = srcheight; 1441848b8605Smrg blit.src.box.depth = 1; 1442848b8605Smrg blit.src.format = src->texture->format; 1443848b8605Smrg blit.mask = PIPE_MASK_RGBA; 1444848b8605Smrg blit.filter = PIPE_TEX_FILTER_NEAREST; 1445848b8605Smrg 1446848b8605Smrg pipe->blit(pipe, &blit); 1447848b8605Smrg 1448848b8605Smrg if (flush_flag == __BLIT_FLAG_FLUSH) { 1449848b8605Smrg pipe->flush_resource(pipe, dst->texture); 1450848b8605Smrg ctx->st->flush(ctx->st, 0, NULL); 1451848b8605Smrg } else if (flush_flag == __BLIT_FLAG_FINISH) { 1452848b8605Smrg screen = dri_screen(ctx->sPriv)->base.screen; 1453848b8605Smrg pipe->flush_resource(pipe, dst->texture); 1454848b8605Smrg ctx->st->flush(ctx->st, 0, &fence); 1455b8e80941Smrg (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE); 1456848b8605Smrg screen->fence_reference(screen, &fence, NULL); 1457848b8605Smrg } 1458848b8605Smrg} 1459848b8605Smrg 1460b8e80941Smrgstatic void * 1461b8e80941Smrgdri2_map_image(__DRIcontext *context, __DRIimage *image, 1462b8e80941Smrg int x0, int y0, int width, int height, 1463b8e80941Smrg unsigned int flags, int *stride, void **data) 1464b8e80941Smrg{ 1465b8e80941Smrg struct dri_context *ctx = dri_context(context); 1466b8e80941Smrg struct pipe_context *pipe = ctx->st->pipe; 1467b8e80941Smrg enum pipe_transfer_usage pipe_access = 0; 1468b8e80941Smrg struct pipe_transfer *trans; 1469b8e80941Smrg void *map; 1470b8e80941Smrg 1471b8e80941Smrg if (!image || !data || *data) 1472b8e80941Smrg return NULL; 1473b8e80941Smrg 1474b8e80941Smrg if (flags & __DRI_IMAGE_TRANSFER_READ) 1475b8e80941Smrg pipe_access |= PIPE_TRANSFER_READ; 1476b8e80941Smrg if (flags & __DRI_IMAGE_TRANSFER_WRITE) 1477b8e80941Smrg pipe_access |= PIPE_TRANSFER_WRITE; 1478b8e80941Smrg 1479b8e80941Smrg map = pipe_transfer_map(pipe, image->texture, 1480b8e80941Smrg 0, 0, pipe_access, x0, y0, width, height, 1481b8e80941Smrg &trans); 1482b8e80941Smrg if (map) { 1483b8e80941Smrg *data = trans; 1484b8e80941Smrg *stride = trans->stride; 1485b8e80941Smrg } 1486b8e80941Smrg 1487b8e80941Smrg return map; 1488b8e80941Smrg} 1489b8e80941Smrg 1490848b8605Smrgstatic void 1491b8e80941Smrgdri2_unmap_image(__DRIcontext *context, __DRIimage *image, void *data) 1492848b8605Smrg{ 1493b8e80941Smrg struct dri_context *ctx = dri_context(context); 1494b8e80941Smrg struct pipe_context *pipe = ctx->st->pipe; 1495b8e80941Smrg 1496b8e80941Smrg pipe_transfer_unmap(pipe, (struct pipe_transfer *)data); 1497848b8605Smrg} 1498848b8605Smrg 1499848b8605Smrgstatic int 1500848b8605Smrgdri2_get_capabilities(__DRIscreen *_screen) 1501848b8605Smrg{ 1502848b8605Smrg struct dri_screen *screen = dri_screen(_screen); 1503848b8605Smrg 1504848b8605Smrg return (screen->can_share_buffer ? __DRI_IMAGE_CAP_GLOBAL_NAMES : 0); 1505848b8605Smrg} 1506848b8605Smrg 1507848b8605Smrg/* The extension is modified during runtime if DRI_PRIME is detected */ 1508848b8605Smrgstatic __DRIimageExtension dri2ImageExtension = { 1509b8e80941Smrg .base = { __DRI_IMAGE, 17 }, 1510848b8605Smrg 1511848b8605Smrg .createImageFromName = dri2_create_image_from_name, 1512848b8605Smrg .createImageFromRenderbuffer = dri2_create_image_from_renderbuffer, 1513848b8605Smrg .destroyImage = dri2_destroy_image, 1514848b8605Smrg .createImage = dri2_create_image, 1515848b8605Smrg .queryImage = dri2_query_image, 1516848b8605Smrg .dupImage = dri2_dup_image, 1517848b8605Smrg .validateUsage = dri2_validate_usage, 1518848b8605Smrg .createImageFromNames = dri2_from_names, 1519848b8605Smrg .fromPlanar = dri2_from_planar, 1520848b8605Smrg .createImageFromTexture = dri2_create_from_texture, 1521848b8605Smrg .createImageFromFds = NULL, 1522848b8605Smrg .createImageFromDmaBufs = NULL, 1523848b8605Smrg .blitImage = dri2_blit_image, 1524848b8605Smrg .getCapabilities = dri2_get_capabilities, 1525b8e80941Smrg .mapImage = dri2_map_image, 1526b8e80941Smrg .unmapImage = dri2_unmap_image, 1527b8e80941Smrg .createImageWithModifiers = NULL, 1528b8e80941Smrg .createImageFromDmaBufs2 = NULL, 1529b8e80941Smrg .queryDmaBufFormats = NULL, 1530b8e80941Smrg .queryDmaBufModifiers = NULL, 1531b8e80941Smrg .queryDmaBufFormatModifierAttribs = NULL, 1532b8e80941Smrg .createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2, 1533b8e80941Smrg}; 1534b8e80941Smrg 1535b8e80941Smrgstatic const __DRIrobustnessExtension dri2Robustness = { 1536b8e80941Smrg .base = { __DRI2_ROBUSTNESS, 1 } 1537b8e80941Smrg}; 1538b8e80941Smrg 1539b8e80941Smrgstatic int 1540b8e80941Smrgdri2_interop_query_device_info(__DRIcontext *_ctx, 1541b8e80941Smrg struct mesa_glinterop_device_info *out) 1542b8e80941Smrg{ 1543b8e80941Smrg struct pipe_screen *screen = dri_context(_ctx)->st->pipe->screen; 1544b8e80941Smrg 1545b8e80941Smrg /* There is no version 0, thus we do not support it */ 1546b8e80941Smrg if (out->version == 0) 1547b8e80941Smrg return MESA_GLINTEROP_INVALID_VERSION; 1548b8e80941Smrg 1549b8e80941Smrg out->pci_segment_group = screen->get_param(screen, PIPE_CAP_PCI_GROUP); 1550b8e80941Smrg out->pci_bus = screen->get_param(screen, PIPE_CAP_PCI_BUS); 1551b8e80941Smrg out->pci_device = screen->get_param(screen, PIPE_CAP_PCI_DEVICE); 1552b8e80941Smrg out->pci_function = screen->get_param(screen, PIPE_CAP_PCI_FUNCTION); 1553b8e80941Smrg 1554b8e80941Smrg out->vendor_id = screen->get_param(screen, PIPE_CAP_VENDOR_ID); 1555b8e80941Smrg out->device_id = screen->get_param(screen, PIPE_CAP_DEVICE_ID); 1556b8e80941Smrg 1557b8e80941Smrg /* Instruct the caller that we support up-to version one of the interface */ 1558b8e80941Smrg out->version = 1; 1559b8e80941Smrg 1560b8e80941Smrg return MESA_GLINTEROP_SUCCESS; 1561b8e80941Smrg} 1562b8e80941Smrg 1563b8e80941Smrgstatic int 1564b8e80941Smrgdri2_interop_export_object(__DRIcontext *_ctx, 1565b8e80941Smrg struct mesa_glinterop_export_in *in, 1566b8e80941Smrg struct mesa_glinterop_export_out *out) 1567b8e80941Smrg{ 1568b8e80941Smrg struct st_context_iface *st = dri_context(_ctx)->st; 1569b8e80941Smrg struct pipe_screen *screen = st->pipe->screen; 1570b8e80941Smrg struct gl_context *ctx = ((struct st_context *)st)->ctx; 1571b8e80941Smrg struct pipe_resource *res = NULL; 1572b8e80941Smrg struct winsys_handle whandle; 1573b8e80941Smrg unsigned target, usage; 1574b8e80941Smrg boolean success; 1575b8e80941Smrg 1576b8e80941Smrg /* There is no version 0, thus we do not support it */ 1577b8e80941Smrg if (in->version == 0 || out->version == 0) 1578b8e80941Smrg return MESA_GLINTEROP_INVALID_VERSION; 1579b8e80941Smrg 1580b8e80941Smrg /* Validate the target. */ 1581b8e80941Smrg switch (in->target) { 1582b8e80941Smrg case GL_TEXTURE_BUFFER: 1583b8e80941Smrg case GL_TEXTURE_1D: 1584b8e80941Smrg case GL_TEXTURE_2D: 1585b8e80941Smrg case GL_TEXTURE_3D: 1586b8e80941Smrg case GL_TEXTURE_RECTANGLE: 1587b8e80941Smrg case GL_TEXTURE_1D_ARRAY: 1588b8e80941Smrg case GL_TEXTURE_2D_ARRAY: 1589b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 1590b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 1591b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE: 1592b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1593b8e80941Smrg case GL_TEXTURE_EXTERNAL_OES: 1594b8e80941Smrg case GL_RENDERBUFFER: 1595b8e80941Smrg case GL_ARRAY_BUFFER: 1596b8e80941Smrg target = in->target; 1597b8e80941Smrg break; 1598b8e80941Smrg case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1599b8e80941Smrg case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1600b8e80941Smrg case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1601b8e80941Smrg case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1602b8e80941Smrg case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1603b8e80941Smrg case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1604b8e80941Smrg target = GL_TEXTURE_CUBE_MAP; 1605b8e80941Smrg break; 1606b8e80941Smrg default: 1607b8e80941Smrg return MESA_GLINTEROP_INVALID_TARGET; 1608b8e80941Smrg } 1609b8e80941Smrg 1610b8e80941Smrg /* Validate the simple case of miplevel. */ 1611b8e80941Smrg if ((target == GL_RENDERBUFFER || target == GL_ARRAY_BUFFER) && 1612b8e80941Smrg in->miplevel != 0) 1613b8e80941Smrg return MESA_GLINTEROP_INVALID_MIP_LEVEL; 1614b8e80941Smrg 1615b8e80941Smrg /* Validate the OpenGL object and get pipe_resource. */ 1616b8e80941Smrg simple_mtx_lock(&ctx->Shared->Mutex); 1617b8e80941Smrg 1618b8e80941Smrg if (target == GL_ARRAY_BUFFER) { 1619b8e80941Smrg /* Buffer objects. 1620b8e80941Smrg * 1621b8e80941Smrg * The error checking is based on the documentation of 1622b8e80941Smrg * clCreateFromGLBuffer from OpenCL 2.0 SDK. 1623b8e80941Smrg */ 1624b8e80941Smrg struct gl_buffer_object *buf = _mesa_lookup_bufferobj(ctx, in->obj); 1625b8e80941Smrg 1626b8e80941Smrg /* From OpenCL 2.0 SDK, clCreateFromGLBuffer: 1627b8e80941Smrg * "CL_INVALID_GL_OBJECT if bufobj is not a GL buffer object or is 1628b8e80941Smrg * a GL buffer object but does not have an existing data store or 1629b8e80941Smrg * the size of the buffer is 0." 1630b8e80941Smrg */ 1631b8e80941Smrg if (!buf || buf->Size == 0) { 1632b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1633b8e80941Smrg return MESA_GLINTEROP_INVALID_OBJECT; 1634b8e80941Smrg } 1635b8e80941Smrg 1636b8e80941Smrg res = st_buffer_object(buf)->buffer; 1637b8e80941Smrg if (!res) { 1638b8e80941Smrg /* this shouldn't happen */ 1639b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1640b8e80941Smrg return MESA_GLINTEROP_INVALID_OBJECT; 1641b8e80941Smrg } 1642b8e80941Smrg 1643b8e80941Smrg out->buf_offset = 0; 1644b8e80941Smrg out->buf_size = buf->Size; 1645b8e80941Smrg 1646b8e80941Smrg buf->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE; 1647b8e80941Smrg } else if (target == GL_RENDERBUFFER) { 1648b8e80941Smrg /* Renderbuffers. 1649b8e80941Smrg * 1650b8e80941Smrg * The error checking is based on the documentation of 1651b8e80941Smrg * clCreateFromGLRenderbuffer from OpenCL 2.0 SDK. 1652b8e80941Smrg */ 1653b8e80941Smrg struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, in->obj); 1654b8e80941Smrg 1655b8e80941Smrg /* From OpenCL 2.0 SDK, clCreateFromGLRenderbuffer: 1656b8e80941Smrg * "CL_INVALID_GL_OBJECT if renderbuffer is not a GL renderbuffer 1657b8e80941Smrg * object or if the width or height of renderbuffer is zero." 1658b8e80941Smrg */ 1659b8e80941Smrg if (!rb || rb->Width == 0 || rb->Height == 0) { 1660b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1661b8e80941Smrg return MESA_GLINTEROP_INVALID_OBJECT; 1662b8e80941Smrg } 1663b8e80941Smrg 1664b8e80941Smrg /* From OpenCL 2.0 SDK, clCreateFromGLRenderbuffer: 1665b8e80941Smrg * "CL_INVALID_OPERATION if renderbuffer is a multi-sample GL 1666b8e80941Smrg * renderbuffer object." 1667b8e80941Smrg */ 1668b8e80941Smrg if (rb->NumSamples > 1) { 1669b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1670b8e80941Smrg return MESA_GLINTEROP_INVALID_OPERATION; 1671b8e80941Smrg } 1672b8e80941Smrg 1673b8e80941Smrg /* From OpenCL 2.0 SDK, clCreateFromGLRenderbuffer: 1674b8e80941Smrg * "CL_OUT_OF_RESOURCES if there is a failure to allocate resources 1675b8e80941Smrg * required by the OpenCL implementation on the device." 1676b8e80941Smrg */ 1677b8e80941Smrg res = st_renderbuffer(rb)->texture; 1678b8e80941Smrg if (!res) { 1679b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1680b8e80941Smrg return MESA_GLINTEROP_OUT_OF_RESOURCES; 1681b8e80941Smrg } 1682b8e80941Smrg 1683b8e80941Smrg out->internal_format = rb->InternalFormat; 1684b8e80941Smrg out->view_minlevel = 0; 1685b8e80941Smrg out->view_numlevels = 1; 1686b8e80941Smrg out->view_minlayer = 0; 1687b8e80941Smrg out->view_numlayers = 1; 1688b8e80941Smrg } else { 1689b8e80941Smrg /* Texture objects. 1690b8e80941Smrg * 1691b8e80941Smrg * The error checking is based on the documentation of 1692b8e80941Smrg * clCreateFromGLTexture from OpenCL 2.0 SDK. 1693b8e80941Smrg */ 1694b8e80941Smrg struct gl_texture_object *obj = _mesa_lookup_texture(ctx, in->obj); 1695b8e80941Smrg 1696b8e80941Smrg if (obj) 1697b8e80941Smrg _mesa_test_texobj_completeness(ctx, obj); 1698b8e80941Smrg 1699b8e80941Smrg /* From OpenCL 2.0 SDK, clCreateFromGLTexture: 1700b8e80941Smrg * "CL_INVALID_GL_OBJECT if texture is not a GL texture object whose 1701b8e80941Smrg * type matches texture_target, if the specified miplevel of texture 1702b8e80941Smrg * is not defined, or if the width or height of the specified 1703b8e80941Smrg * miplevel is zero or if the GL texture object is incomplete." 1704b8e80941Smrg */ 1705b8e80941Smrg if (!obj || 1706b8e80941Smrg obj->Target != target || 1707b8e80941Smrg !obj->_BaseComplete || 1708b8e80941Smrg (in->miplevel > 0 && !obj->_MipmapComplete)) { 1709b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1710b8e80941Smrg return MESA_GLINTEROP_INVALID_OBJECT; 1711b8e80941Smrg } 1712b8e80941Smrg 1713b8e80941Smrg if (target == GL_TEXTURE_BUFFER) { 1714b8e80941Smrg struct st_buffer_object *stBuf = 1715b8e80941Smrg st_buffer_object(obj->BufferObject); 1716b8e80941Smrg 1717b8e80941Smrg if (!stBuf || !stBuf->buffer) { 1718b8e80941Smrg /* this shouldn't happen */ 1719b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1720b8e80941Smrg return MESA_GLINTEROP_INVALID_OBJECT; 1721b8e80941Smrg } 1722b8e80941Smrg res = stBuf->buffer; 1723b8e80941Smrg 1724b8e80941Smrg out->internal_format = obj->BufferObjectFormat; 1725b8e80941Smrg out->buf_offset = obj->BufferOffset; 1726b8e80941Smrg out->buf_size = obj->BufferSize == -1 ? obj->BufferObject->Size : 1727b8e80941Smrg obj->BufferSize; 1728b8e80941Smrg 1729b8e80941Smrg obj->BufferObject->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE; 1730b8e80941Smrg } else { 1731b8e80941Smrg /* From OpenCL 2.0 SDK, clCreateFromGLTexture: 1732b8e80941Smrg * "CL_INVALID_MIP_LEVEL if miplevel is less than the value of 1733b8e80941Smrg * levelbase (for OpenGL implementations) or zero (for OpenGL ES 1734b8e80941Smrg * implementations); or greater than the value of q (for both OpenGL 1735b8e80941Smrg * and OpenGL ES). levelbase and q are defined for the texture in 1736b8e80941Smrg * section 3.8.10 (Texture Completeness) of the OpenGL 2.1 1737b8e80941Smrg * specification and section 3.7.10 of the OpenGL ES 2.0." 1738b8e80941Smrg */ 1739b8e80941Smrg if (in->miplevel < obj->BaseLevel || in->miplevel > obj->_MaxLevel) { 1740b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1741b8e80941Smrg return MESA_GLINTEROP_INVALID_MIP_LEVEL; 1742b8e80941Smrg } 1743b8e80941Smrg 1744b8e80941Smrg if (!st_finalize_texture(ctx, st->pipe, obj, 0)) { 1745b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1746b8e80941Smrg return MESA_GLINTEROP_OUT_OF_RESOURCES; 1747b8e80941Smrg } 1748b8e80941Smrg 1749b8e80941Smrg res = st_get_texobj_resource(obj); 1750b8e80941Smrg if (!res) { 1751b8e80941Smrg /* Incomplete texture buffer object? This shouldn't really occur. */ 1752b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1753b8e80941Smrg return MESA_GLINTEROP_INVALID_OBJECT; 1754b8e80941Smrg } 1755b8e80941Smrg 1756b8e80941Smrg out->internal_format = obj->Image[0][0]->InternalFormat; 1757b8e80941Smrg out->view_minlevel = obj->MinLevel; 1758b8e80941Smrg out->view_numlevels = obj->NumLevels; 1759b8e80941Smrg out->view_minlayer = obj->MinLayer; 1760b8e80941Smrg out->view_numlayers = obj->NumLayers; 1761b8e80941Smrg } 1762b8e80941Smrg } 1763b8e80941Smrg 1764b8e80941Smrg /* Get the handle. */ 1765b8e80941Smrg switch (in->access) { 1766b8e80941Smrg case MESA_GLINTEROP_ACCESS_READ_ONLY: 1767b8e80941Smrg usage = 0; 1768b8e80941Smrg break; 1769b8e80941Smrg case MESA_GLINTEROP_ACCESS_READ_WRITE: 1770b8e80941Smrg case MESA_GLINTEROP_ACCESS_WRITE_ONLY: 1771b8e80941Smrg usage = PIPE_HANDLE_USAGE_SHADER_WRITE; 1772b8e80941Smrg break; 1773b8e80941Smrg default: 1774b8e80941Smrg usage = 0; 1775b8e80941Smrg } 1776b8e80941Smrg 1777b8e80941Smrg memset(&whandle, 0, sizeof(whandle)); 1778b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_FD; 1779b8e80941Smrg 1780b8e80941Smrg success = screen->resource_get_handle(screen, st->pipe, res, &whandle, 1781b8e80941Smrg usage); 1782b8e80941Smrg simple_mtx_unlock(&ctx->Shared->Mutex); 1783b8e80941Smrg 1784b8e80941Smrg if (!success) 1785b8e80941Smrg return MESA_GLINTEROP_OUT_OF_HOST_MEMORY; 1786b8e80941Smrg 1787b8e80941Smrg out->dmabuf_fd = whandle.handle; 1788b8e80941Smrg out->out_driver_data_written = 0; 1789b8e80941Smrg 1790b8e80941Smrg if (res->target == PIPE_BUFFER) 1791b8e80941Smrg out->buf_offset += whandle.offset; 1792b8e80941Smrg 1793b8e80941Smrg /* Instruct the caller that we support up-to version one of the interface */ 1794b8e80941Smrg in->version = 1; 1795b8e80941Smrg out->version = 1; 1796b8e80941Smrg 1797b8e80941Smrg return MESA_GLINTEROP_SUCCESS; 1798b8e80941Smrg} 1799b8e80941Smrg 1800b8e80941Smrgstatic const __DRI2interopExtension dri2InteropExtension = { 1801b8e80941Smrg .base = { __DRI2_INTEROP, 1 }, 1802b8e80941Smrg .query_device_info = dri2_interop_query_device_info, 1803b8e80941Smrg .export_object = dri2_interop_export_object 1804b8e80941Smrg}; 1805b8e80941Smrg 1806b8e80941Smrg/** 1807b8e80941Smrg * \brief the DRI2ConfigQueryExtension configQueryb method 1808b8e80941Smrg */ 1809b8e80941Smrgstatic int 1810b8e80941Smrgdri2GalliumConfigQueryb(__DRIscreen *sPriv, const char *var, 1811b8e80941Smrg unsigned char *val) 1812b8e80941Smrg{ 1813b8e80941Smrg struct dri_screen *screen = dri_screen(sPriv); 1814b8e80941Smrg 1815b8e80941Smrg if (!driCheckOption(&screen->dev->option_cache, var, DRI_BOOL)) 1816b8e80941Smrg return dri2ConfigQueryExtension.configQueryb(sPriv, var, val); 1817b8e80941Smrg 1818b8e80941Smrg *val = driQueryOptionb(&screen->dev->option_cache, var); 1819b8e80941Smrg 1820b8e80941Smrg return 0; 1821b8e80941Smrg} 1822b8e80941Smrg 1823b8e80941Smrg/** 1824b8e80941Smrg * \brief the DRI2ConfigQueryExtension configQueryi method 1825b8e80941Smrg */ 1826b8e80941Smrgstatic int 1827b8e80941Smrgdri2GalliumConfigQueryi(__DRIscreen *sPriv, const char *var, int *val) 1828b8e80941Smrg{ 1829b8e80941Smrg struct dri_screen *screen = dri_screen(sPriv); 1830b8e80941Smrg 1831b8e80941Smrg if (!driCheckOption(&screen->dev->option_cache, var, DRI_INT) && 1832b8e80941Smrg !driCheckOption(&screen->dev->option_cache, var, DRI_ENUM)) 1833b8e80941Smrg return dri2ConfigQueryExtension.configQueryi(sPriv, var, val); 1834b8e80941Smrg 1835b8e80941Smrg *val = driQueryOptioni(&screen->dev->option_cache, var); 1836b8e80941Smrg 1837b8e80941Smrg return 0; 1838b8e80941Smrg} 1839b8e80941Smrg 1840b8e80941Smrg/** 1841b8e80941Smrg * \brief the DRI2ConfigQueryExtension configQueryf method 1842b8e80941Smrg */ 1843b8e80941Smrgstatic int 1844b8e80941Smrgdri2GalliumConfigQueryf(__DRIscreen *sPriv, const char *var, float *val) 1845b8e80941Smrg{ 1846b8e80941Smrg struct dri_screen *screen = dri_screen(sPriv); 1847b8e80941Smrg 1848b8e80941Smrg if (!driCheckOption(&screen->dev->option_cache, var, DRI_FLOAT)) 1849b8e80941Smrg return dri2ConfigQueryExtension.configQueryf(sPriv, var, val); 1850b8e80941Smrg 1851b8e80941Smrg *val = driQueryOptionf(&screen->dev->option_cache, var); 1852b8e80941Smrg 1853b8e80941Smrg return 0; 1854b8e80941Smrg} 1855b8e80941Smrg 1856b8e80941Smrg/** 1857b8e80941Smrg * \brief the DRI2ConfigQueryExtension struct. 1858b8e80941Smrg * 1859b8e80941Smrg * We first query the driver option cache. Then the dri2 option cache. 1860b8e80941Smrg */ 1861b8e80941Smrgstatic const __DRI2configQueryExtension dri2GalliumConfigQueryExtension = { 1862b8e80941Smrg .base = { __DRI2_CONFIG_QUERY, 1 }, 1863b8e80941Smrg 1864b8e80941Smrg .configQueryb = dri2GalliumConfigQueryb, 1865b8e80941Smrg .configQueryi = dri2GalliumConfigQueryi, 1866b8e80941Smrg .configQueryf = dri2GalliumConfigQueryf, 1867848b8605Smrg}; 1868848b8605Smrg 1869848b8605Smrg/* 1870848b8605Smrg * Backend function init_screen. 1871848b8605Smrg */ 1872848b8605Smrg 1873848b8605Smrgstatic const __DRIextension *dri_screen_extensions[] = { 1874848b8605Smrg &driTexBufferExtension.base, 1875848b8605Smrg &dri2FlushExtension.base, 1876848b8605Smrg &dri2ImageExtension.base, 1877848b8605Smrg &dri2RendererQueryExtension.base, 1878b8e80941Smrg &dri2GalliumConfigQueryExtension.base, 1879848b8605Smrg &dri2ThrottleExtension.base, 1880b8e80941Smrg &dri2FenceExtension.base, 1881b8e80941Smrg &dri2InteropExtension.base, 1882b8e80941Smrg &dri2NoErrorExtension.base, 1883b8e80941Smrg NULL 1884b8e80941Smrg}; 1885b8e80941Smrg 1886b8e80941Smrgstatic const __DRIextension *dri_robust_screen_extensions[] = { 1887b8e80941Smrg &driTexBufferExtension.base, 1888b8e80941Smrg &dri2FlushExtension.base, 1889b8e80941Smrg &dri2ImageExtension.base, 1890b8e80941Smrg &dri2RendererQueryExtension.base, 1891b8e80941Smrg &dri2GalliumConfigQueryExtension.base, 1892b8e80941Smrg &dri2ThrottleExtension.base, 1893b8e80941Smrg &dri2FenceExtension.base, 1894b8e80941Smrg &dri2InteropExtension.base, 1895b8e80941Smrg &dri2Robustness.base, 1896b8e80941Smrg &dri2NoErrorExtension.base, 1897848b8605Smrg NULL 1898848b8605Smrg}; 1899848b8605Smrg 1900848b8605Smrg/** 1901848b8605Smrg * This is the driver specific part of the createNewScreen entry point. 1902848b8605Smrg * 1903848b8605Smrg * Returns the struct gl_config supported by this driver. 1904848b8605Smrg */ 1905848b8605Smrgstatic const __DRIconfig ** 1906848b8605Smrgdri2_init_screen(__DRIscreen * sPriv) 1907848b8605Smrg{ 1908848b8605Smrg const __DRIconfig **configs; 1909848b8605Smrg struct dri_screen *screen; 1910848b8605Smrg struct pipe_screen *pscreen = NULL; 1911848b8605Smrg 1912848b8605Smrg screen = CALLOC_STRUCT(dri_screen); 1913848b8605Smrg if (!screen) 1914848b8605Smrg return NULL; 1915848b8605Smrg 1916848b8605Smrg screen->sPriv = sPriv; 1917848b8605Smrg screen->fd = sPriv->fd; 1918b8e80941Smrg (void) mtx_init(&screen->opencl_func_mutex, mtx_plain); 1919848b8605Smrg 1920848b8605Smrg sPriv->driverPrivate = (void *)screen; 1921848b8605Smrg 1922b8e80941Smrg if (pipe_loader_drm_probe_fd(&screen->dev, screen->fd)) { 1923b8e80941Smrg dri_init_options(screen); 1924848b8605Smrg 1925b8e80941Smrg pscreen = pipe_loader_create_screen(screen->dev); 1926848b8605Smrg } 1927848b8605Smrg 1928b8e80941Smrg if (!pscreen) 1929b8e80941Smrg goto release_pipe; 1930b8e80941Smrg 1931b8e80941Smrg screen->default_throttle_frames = 1932b8e80941Smrg pscreen->get_param(pscreen, PIPE_CAP_MAX_FRAMES_IN_FLIGHT); 1933848b8605Smrg 1934b8e80941Smrg if (pscreen->resource_create_with_modifiers) 1935b8e80941Smrg dri2ImageExtension.createImageWithModifiers = 1936b8e80941Smrg dri2_create_image_with_modifiers; 1937b8e80941Smrg 1938b8e80941Smrg if (pscreen->get_param(pscreen, PIPE_CAP_DMABUF)) { 1939848b8605Smrg uint64_t cap; 1940848b8605Smrg 1941848b8605Smrg if (drmGetCap(sPriv->fd, DRM_CAP_PRIME, &cap) == 0 && 1942848b8605Smrg (cap & DRM_PRIME_CAP_IMPORT)) { 1943848b8605Smrg dri2ImageExtension.createImageFromFds = dri2_from_fds; 1944848b8605Smrg dri2ImageExtension.createImageFromDmaBufs = dri2_from_dma_bufs; 1945b8e80941Smrg dri2ImageExtension.createImageFromDmaBufs2 = dri2_from_dma_bufs2; 1946b8e80941Smrg if (pscreen->query_dmabuf_modifiers) { 1947b8e80941Smrg dri2ImageExtension.queryDmaBufFormats = dri2_query_dma_buf_formats; 1948b8e80941Smrg dri2ImageExtension.queryDmaBufModifiers = 1949b8e80941Smrg dri2_query_dma_buf_modifiers; 1950b8e80941Smrg } 1951848b8605Smrg } 1952848b8605Smrg } 1953848b8605Smrg 1954b8e80941Smrg if (pscreen->get_param(pscreen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY)) { 1955b8e80941Smrg sPriv->extensions = dri_robust_screen_extensions; 1956b8e80941Smrg screen->has_reset_status_query = true; 1957b8e80941Smrg } 1958b8e80941Smrg else 1959b8e80941Smrg sPriv->extensions = dri_screen_extensions; 1960848b8605Smrg 1961b8e80941Smrg configs = dri_init_screen_helper(screen, pscreen); 1962848b8605Smrg if (!configs) 1963b8e80941Smrg goto destroy_screen; 1964848b8605Smrg 1965848b8605Smrg screen->can_share_buffer = true; 1966848b8605Smrg screen->auto_fake_front = dri_with_format(sPriv); 1967848b8605Smrg screen->broken_invalidate = !sPriv->dri2.useInvalidate; 1968848b8605Smrg screen->lookup_egl_image = dri2_lookup_egl_image; 1969848b8605Smrg 1970848b8605Smrg return configs; 1971b8e80941Smrg 1972b8e80941Smrgdestroy_screen: 1973848b8605Smrg dri_destroy_screen_helper(screen); 1974b8e80941Smrg 1975b8e80941Smrgrelease_pipe: 1976848b8605Smrg if (screen->dev) 1977848b8605Smrg pipe_loader_release(&screen->dev, 1); 1978b8e80941Smrg 1979848b8605Smrg FREE(screen); 1980848b8605Smrg return NULL; 1981848b8605Smrg} 1982848b8605Smrg 1983848b8605Smrg/** 1984848b8605Smrg * This is the driver specific part of the createNewScreen entry point. 1985848b8605Smrg * 1986848b8605Smrg * Returns the struct gl_config supported by this driver. 1987848b8605Smrg */ 1988848b8605Smrgstatic const __DRIconfig ** 1989848b8605Smrgdri_kms_init_screen(__DRIscreen * sPriv) 1990848b8605Smrg{ 1991848b8605Smrg#if defined(GALLIUM_SOFTPIPE) 1992848b8605Smrg const __DRIconfig **configs; 1993848b8605Smrg struct dri_screen *screen; 1994848b8605Smrg struct pipe_screen *pscreen = NULL; 1995848b8605Smrg uint64_t cap; 1996848b8605Smrg 1997848b8605Smrg screen = CALLOC_STRUCT(dri_screen); 1998848b8605Smrg if (!screen) 1999848b8605Smrg return NULL; 2000848b8605Smrg 2001848b8605Smrg screen->sPriv = sPriv; 2002848b8605Smrg screen->fd = sPriv->fd; 2003848b8605Smrg 2004848b8605Smrg sPriv->driverPrivate = (void *)screen; 2005848b8605Smrg 2006b8e80941Smrg if (pipe_loader_sw_probe_kms(&screen->dev, screen->fd)) { 2007b8e80941Smrg dri_init_options(screen); 2008b8e80941Smrg pscreen = pipe_loader_create_screen(screen->dev); 2009b8e80941Smrg } 2010b8e80941Smrg 2011b8e80941Smrg if (!pscreen) 2012b8e80941Smrg goto release_pipe; 2013b8e80941Smrg 2014b8e80941Smrg if (pscreen->resource_create_with_modifiers) 2015b8e80941Smrg dri2ImageExtension.createImageWithModifiers = 2016b8e80941Smrg dri2_create_image_with_modifiers; 2017848b8605Smrg 2018848b8605Smrg if (drmGetCap(sPriv->fd, DRM_CAP_PRIME, &cap) == 0 && 2019848b8605Smrg (cap & DRM_PRIME_CAP_IMPORT)) { 2020848b8605Smrg dri2ImageExtension.createImageFromFds = dri2_from_fds; 2021848b8605Smrg dri2ImageExtension.createImageFromDmaBufs = dri2_from_dma_bufs; 2022b8e80941Smrg dri2ImageExtension.createImageFromDmaBufs2 = dri2_from_dma_bufs2; 2023b8e80941Smrg if (pscreen->query_dmabuf_modifiers) { 2024b8e80941Smrg dri2ImageExtension.queryDmaBufFormats = dri2_query_dma_buf_formats; 2025b8e80941Smrg dri2ImageExtension.queryDmaBufModifiers = dri2_query_dma_buf_modifiers; 2026b8e80941Smrg } 2027848b8605Smrg } 2028848b8605Smrg 2029848b8605Smrg sPriv->extensions = dri_screen_extensions; 2030848b8605Smrg 2031b8e80941Smrg configs = dri_init_screen_helper(screen, pscreen); 2032848b8605Smrg if (!configs) 2033b8e80941Smrg goto destroy_screen; 2034848b8605Smrg 2035848b8605Smrg screen->can_share_buffer = false; 2036848b8605Smrg screen->auto_fake_front = dri_with_format(sPriv); 2037848b8605Smrg screen->broken_invalidate = !sPriv->dri2.useInvalidate; 2038848b8605Smrg screen->lookup_egl_image = dri2_lookup_egl_image; 2039848b8605Smrg 2040848b8605Smrg return configs; 2041b8e80941Smrg 2042b8e80941Smrgdestroy_screen: 2043848b8605Smrg dri_destroy_screen_helper(screen); 2044b8e80941Smrg 2045b8e80941Smrgrelease_pipe: 2046b8e80941Smrg if (screen->dev) 2047b8e80941Smrg pipe_loader_release(&screen->dev, 1); 2048b8e80941Smrg 2049848b8605Smrg FREE(screen); 2050848b8605Smrg#endif // GALLIUM_SOFTPIPE 2051848b8605Smrg return NULL; 2052848b8605Smrg} 2053848b8605Smrg 2054848b8605Smrgstatic boolean 2055848b8605Smrgdri2_create_buffer(__DRIscreen * sPriv, 2056848b8605Smrg __DRIdrawable * dPriv, 2057848b8605Smrg const struct gl_config * visual, boolean isPixmap) 2058848b8605Smrg{ 2059848b8605Smrg struct dri_drawable *drawable = NULL; 2060848b8605Smrg 2061848b8605Smrg if (!dri_create_buffer(sPriv, dPriv, visual, isPixmap)) 2062848b8605Smrg return FALSE; 2063848b8605Smrg 2064848b8605Smrg drawable = dPriv->driverPrivate; 2065848b8605Smrg 2066848b8605Smrg drawable->allocate_textures = dri2_allocate_textures; 2067848b8605Smrg drawable->flush_frontbuffer = dri2_flush_frontbuffer; 2068848b8605Smrg drawable->update_tex_buffer = dri2_update_tex_buffer; 2069b8e80941Smrg drawable->flush_swapbuffers = dri2_flush_swapbuffers; 2070848b8605Smrg 2071848b8605Smrg return TRUE; 2072848b8605Smrg} 2073848b8605Smrg 2074848b8605Smrg/** 2075848b8605Smrg * DRI driver virtual function table. 2076848b8605Smrg * 2077848b8605Smrg * DRI versions differ in their implementation of init_screen and swap_buffers. 2078848b8605Smrg */ 2079848b8605Smrgconst struct __DriverAPIRec galliumdrm_driver_api = { 2080848b8605Smrg .InitScreen = dri2_init_screen, 2081848b8605Smrg .DestroyScreen = dri_destroy_screen, 2082848b8605Smrg .CreateContext = dri_create_context, 2083848b8605Smrg .DestroyContext = dri_destroy_context, 2084848b8605Smrg .CreateBuffer = dri2_create_buffer, 2085848b8605Smrg .DestroyBuffer = dri_destroy_buffer, 2086848b8605Smrg .MakeCurrent = dri_make_current, 2087848b8605Smrg .UnbindContext = dri_unbind_context, 2088848b8605Smrg 2089848b8605Smrg .AllocateBuffer = dri2_allocate_buffer, 2090848b8605Smrg .ReleaseBuffer = dri2_release_buffer, 2091848b8605Smrg}; 2092848b8605Smrg 2093848b8605Smrg/** 2094848b8605Smrg * DRI driver virtual function table. 2095848b8605Smrg * 2096848b8605Smrg * KMS/DRM version of the DriverAPI above sporting a different InitScreen 2097848b8605Smrg * hook. The latter is used to explicitly initialise the kms_swrast driver 2098848b8605Smrg * rather than selecting the approapriate driver as suggested by the loader. 2099848b8605Smrg */ 2100848b8605Smrgconst struct __DriverAPIRec dri_kms_driver_api = { 2101848b8605Smrg .InitScreen = dri_kms_init_screen, 2102848b8605Smrg .DestroyScreen = dri_destroy_screen, 2103848b8605Smrg .CreateContext = dri_create_context, 2104848b8605Smrg .DestroyContext = dri_destroy_context, 2105848b8605Smrg .CreateBuffer = dri2_create_buffer, 2106848b8605Smrg .DestroyBuffer = dri_destroy_buffer, 2107848b8605Smrg .MakeCurrent = dri_make_current, 2108848b8605Smrg .UnbindContext = dri_unbind_context, 2109848b8605Smrg 2110848b8605Smrg .AllocateBuffer = dri2_allocate_buffer, 2111848b8605Smrg .ReleaseBuffer = dri2_release_buffer, 2112848b8605Smrg}; 2113848b8605Smrg 2114848b8605Smrg/* This is the table of extensions that the loader will dlsym() for. */ 2115848b8605Smrgconst __DRIextension *galliumdrm_driver_extensions[] = { 2116848b8605Smrg &driCoreExtension.base, 2117848b8605Smrg &driImageDriverExtension.base, 2118848b8605Smrg &driDRI2Extension.base, 2119848b8605Smrg &gallium_config_options.base, 2120848b8605Smrg NULL 2121848b8605Smrg}; 2122848b8605Smrg 2123848b8605Smrg/* vim: set sw=3 ts=8 sts=3 expandtab: */ 2124