1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * (C) Copyright IBM Corporation 2002, 2004 3bf215546Sopenharmony_ci * All Rights Reserved. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 9bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 10bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci/** 26bf215546Sopenharmony_ci * \file dri_util.c 27bf215546Sopenharmony_ci * DRI utility functions. 28bf215546Sopenharmony_ci * 29bf215546Sopenharmony_ci * This module acts as glue between GLX and the actual hardware driver. A DRI 30bf215546Sopenharmony_ci * driver doesn't really \e have to use any of this - it's optional. But, some 31bf215546Sopenharmony_ci * useful stuff is done here that otherwise would have to be duplicated in most 32bf215546Sopenharmony_ci * drivers. 33bf215546Sopenharmony_ci * 34bf215546Sopenharmony_ci * Basically, these utility functions take care of some of the dirty details of 35bf215546Sopenharmony_ci * screen initialization, context creation, context binding, DRM setup, etc. 36bf215546Sopenharmony_ci * 37bf215546Sopenharmony_ci * These functions are compiled into each DRI driver so libGL.so knows nothing 38bf215546Sopenharmony_ci * about them. 39bf215546Sopenharmony_ci */ 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#include <stdbool.h> 43bf215546Sopenharmony_ci#include "dri_util.h" 44bf215546Sopenharmony_ci#include "dri_context.h" 45bf215546Sopenharmony_ci#include "dri_screen.h" 46bf215546Sopenharmony_ci#include "util/u_endian.h" 47bf215546Sopenharmony_ci#include "util/driconf.h" 48bf215546Sopenharmony_ci#include "main/framebuffer.h" 49bf215546Sopenharmony_ci#include "main/version.h" 50bf215546Sopenharmony_ci#include "main/debug_output.h" 51bf215546Sopenharmony_ci#include "main/errors.h" 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cidriOptionDescription __dri2ConfigOptions[] = { 54bf215546Sopenharmony_ci DRI_CONF_SECTION_DEBUG 55bf215546Sopenharmony_ci DRI_CONF_GLX_EXTENSION_OVERRIDE() 56bf215546Sopenharmony_ci DRI_CONF_INDIRECT_GL_EXTENSION_OVERRIDE() 57bf215546Sopenharmony_ci DRI_CONF_SECTION_END 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci DRI_CONF_SECTION_PERFORMANCE 60bf215546Sopenharmony_ci DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1) 61bf215546Sopenharmony_ci DRI_CONF_SECTION_END 62bf215546Sopenharmony_ci}; 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci/*****************************************************************/ 65bf215546Sopenharmony_ci/** \name Screen handling functions */ 66bf215546Sopenharmony_ci/*****************************************************************/ 67bf215546Sopenharmony_ci/*@{*/ 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_cistatic void 70bf215546Sopenharmony_cisetupLoaderExtensions(__DRIscreen *psp, 71bf215546Sopenharmony_ci const __DRIextension **extensions) 72bf215546Sopenharmony_ci{ 73bf215546Sopenharmony_ci int i; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci for (i = 0; extensions[i]; i++) { 76bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0) 77bf215546Sopenharmony_ci psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i]; 78bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0) 79bf215546Sopenharmony_ci psp->dri2.image = (__DRIimageLookupExtension *) extensions[i]; 80bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0) 81bf215546Sopenharmony_ci psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i]; 82bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, __DRI_BACKGROUND_CALLABLE) == 0) 83bf215546Sopenharmony_ci psp->dri2.backgroundCallable = (__DRIbackgroundCallableExtension *) extensions[i]; 84bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) 85bf215546Sopenharmony_ci psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; 86bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0) 87bf215546Sopenharmony_ci psp->image.loader = (__DRIimageLoaderExtension *) extensions[i]; 88bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, __DRI_MUTABLE_RENDER_BUFFER_LOADER) == 0) 89bf215546Sopenharmony_ci psp->mutableRenderBuffer.loader = (__DRImutableRenderBufferLoaderExtension *) extensions[i]; 90bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, __DRI_KOPPER_LOADER) == 0) 91bf215546Sopenharmony_ci psp->kopper_loader = (__DRIkopperLoaderExtension *) extensions[i]; 92bf215546Sopenharmony_ci } 93bf215546Sopenharmony_ci} 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci/** 96bf215546Sopenharmony_ci * This is the first entrypoint in the driver called by the DRI driver loader 97bf215546Sopenharmony_ci * after dlopen()ing it. 98bf215546Sopenharmony_ci * 99bf215546Sopenharmony_ci * It's used to create global state for the driver across contexts on the same 100bf215546Sopenharmony_ci * Display. 101bf215546Sopenharmony_ci */ 102bf215546Sopenharmony_cistatic __DRIscreen * 103bf215546Sopenharmony_cidriCreateNewScreen2(int scrn, int fd, 104bf215546Sopenharmony_ci const __DRIextension **extensions, 105bf215546Sopenharmony_ci const __DRIextension **driver_extensions, 106bf215546Sopenharmony_ci const __DRIconfig ***driver_configs, void *data) 107bf215546Sopenharmony_ci{ 108bf215546Sopenharmony_ci static const __DRIextension *emptyExtensionList[] = { NULL }; 109bf215546Sopenharmony_ci __DRIscreen *psp; 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci psp = calloc(1, sizeof(*psp)); 112bf215546Sopenharmony_ci if (!psp) 113bf215546Sopenharmony_ci return NULL; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci assert(driver_extensions); 116bf215546Sopenharmony_ci for (int i = 0; driver_extensions[i]; i++) { 117bf215546Sopenharmony_ci if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) { 118bf215546Sopenharmony_ci psp->driver = 119bf215546Sopenharmony_ci ((__DRIDriverVtableExtension *)driver_extensions[i])->vtable; 120bf215546Sopenharmony_ci } 121bf215546Sopenharmony_ci } 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci setupLoaderExtensions(psp, extensions); 124bf215546Sopenharmony_ci // dri2 drivers require working invalidate 125bf215546Sopenharmony_ci if (fd != -1 && !psp->dri2.useInvalidate) { 126bf215546Sopenharmony_ci free(psp); 127bf215546Sopenharmony_ci return NULL; 128bf215546Sopenharmony_ci } 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci psp->loaderPrivate = data; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci psp->extensions = emptyExtensionList; 133bf215546Sopenharmony_ci psp->fd = fd; 134bf215546Sopenharmony_ci psp->myNum = scrn; 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci /* Option parsing before ->InitScreen(), as some options apply there. */ 137bf215546Sopenharmony_ci driParseOptionInfo(&psp->optionInfo, 138bf215546Sopenharmony_ci __dri2ConfigOptions, ARRAY_SIZE(__dri2ConfigOptions)); 139bf215546Sopenharmony_ci driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, 140bf215546Sopenharmony_ci "dri2", NULL, NULL, NULL, 0, NULL, 0); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci *driver_configs = psp->driver->InitScreen(psp); 143bf215546Sopenharmony_ci if (*driver_configs == NULL) { 144bf215546Sopenharmony_ci free(psp); 145bf215546Sopenharmony_ci return NULL; 146bf215546Sopenharmony_ci } 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci struct gl_constants consts = { 0 }; 149bf215546Sopenharmony_ci gl_api api; 150bf215546Sopenharmony_ci unsigned version; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci api = API_OPENGLES2; 153bf215546Sopenharmony_ci if (_mesa_override_gl_version_contextless(&consts, &api, &version)) 154bf215546Sopenharmony_ci psp->max_gl_es2_version = version; 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci api = API_OPENGL_COMPAT; 157bf215546Sopenharmony_ci if (_mesa_override_gl_version_contextless(&consts, &api, &version)) { 158bf215546Sopenharmony_ci psp->max_gl_core_version = version; 159bf215546Sopenharmony_ci if (api == API_OPENGL_COMPAT) 160bf215546Sopenharmony_ci psp->max_gl_compat_version = version; 161bf215546Sopenharmony_ci } 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci psp->api_mask = 0; 164bf215546Sopenharmony_ci if (psp->max_gl_compat_version > 0) 165bf215546Sopenharmony_ci psp->api_mask |= (1 << __DRI_API_OPENGL); 166bf215546Sopenharmony_ci if (psp->max_gl_core_version > 0) 167bf215546Sopenharmony_ci psp->api_mask |= (1 << __DRI_API_OPENGL_CORE); 168bf215546Sopenharmony_ci if (psp->max_gl_es1_version > 0) 169bf215546Sopenharmony_ci psp->api_mask |= (1 << __DRI_API_GLES); 170bf215546Sopenharmony_ci if (psp->max_gl_es2_version > 0) 171bf215546Sopenharmony_ci psp->api_mask |= (1 << __DRI_API_GLES2); 172bf215546Sopenharmony_ci if (psp->max_gl_es2_version >= 30) 173bf215546Sopenharmony_ci psp->api_mask |= (1 << __DRI_API_GLES3); 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci return psp; 176bf215546Sopenharmony_ci} 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_cistatic __DRIscreen * 179bf215546Sopenharmony_cidri2CreateNewScreen(int scrn, int fd, 180bf215546Sopenharmony_ci const __DRIextension **extensions, 181bf215546Sopenharmony_ci const __DRIconfig ***driver_configs, void *data) 182bf215546Sopenharmony_ci{ 183bf215546Sopenharmony_ci return driCreateNewScreen2(scrn, fd, extensions, 184bf215546Sopenharmony_ci galliumdrm_driver_extensions, 185bf215546Sopenharmony_ci driver_configs, data); 186bf215546Sopenharmony_ci} 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_cistatic __DRIscreen * 189bf215546Sopenharmony_ciswkmsCreateNewScreen(int scrn, int fd, 190bf215546Sopenharmony_ci const __DRIextension **extensions, 191bf215546Sopenharmony_ci const __DRIconfig ***driver_configs, void *data) 192bf215546Sopenharmony_ci{ 193bf215546Sopenharmony_ci return driCreateNewScreen2(scrn, fd, extensions, 194bf215546Sopenharmony_ci dri_swrast_kms_driver_extensions, 195bf215546Sopenharmony_ci driver_configs, data); 196bf215546Sopenharmony_ci} 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci/** swrast driver createNewScreen entrypoint. */ 199bf215546Sopenharmony_cistatic __DRIscreen * 200bf215546Sopenharmony_cidriSWRastCreateNewScreen(int scrn, const __DRIextension **extensions, 201bf215546Sopenharmony_ci const __DRIconfig ***driver_configs, void *data) 202bf215546Sopenharmony_ci{ 203bf215546Sopenharmony_ci return driCreateNewScreen2(scrn, -1, extensions, 204bf215546Sopenharmony_ci galliumsw_driver_extensions, 205bf215546Sopenharmony_ci driver_configs, data); 206bf215546Sopenharmony_ci} 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_cistatic __DRIscreen * 209bf215546Sopenharmony_cidriSWRastCreateNewScreen2(int scrn, const __DRIextension **extensions, 210bf215546Sopenharmony_ci const __DRIextension **driver_extensions, 211bf215546Sopenharmony_ci const __DRIconfig ***driver_configs, void *data) 212bf215546Sopenharmony_ci{ 213bf215546Sopenharmony_ci return driCreateNewScreen2(scrn, -1, extensions, driver_extensions, 214bf215546Sopenharmony_ci driver_configs, data); 215bf215546Sopenharmony_ci} 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci/** 218bf215546Sopenharmony_ci * Destroy the per-screen private information. 219bf215546Sopenharmony_ci * 220bf215546Sopenharmony_ci * \internal 221bf215546Sopenharmony_ci * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls 222bf215546Sopenharmony_ci * drmClose(), and finally frees \p screenPrivate. 223bf215546Sopenharmony_ci */ 224bf215546Sopenharmony_cistatic void driDestroyScreen(__DRIscreen *psp) 225bf215546Sopenharmony_ci{ 226bf215546Sopenharmony_ci if (psp) { 227bf215546Sopenharmony_ci /* No interaction with the X-server is possible at this point. This 228bf215546Sopenharmony_ci * routine is called after XCloseDisplay, so there is no protocol 229bf215546Sopenharmony_ci * stream open to the X-server anymore. 230bf215546Sopenharmony_ci */ 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci psp->driver->DestroyScreen(psp); 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci driDestroyOptionCache(&psp->optionCache); 235bf215546Sopenharmony_ci driDestroyOptionInfo(&psp->optionInfo); 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci free(psp); 238bf215546Sopenharmony_ci } 239bf215546Sopenharmony_ci} 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_cistatic const __DRIextension **driGetExtensions(__DRIscreen *psp) 242bf215546Sopenharmony_ci{ 243bf215546Sopenharmony_ci return psp->extensions; 244bf215546Sopenharmony_ci} 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci/*@}*/ 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci/* WARNING: HACK: Local defines to avoid pulling glx.h. 249bf215546Sopenharmony_ci */ 250bf215546Sopenharmony_ci#define GLX_NONE 0x8000 251bf215546Sopenharmony_ci#define GLX_DONT_CARE 0xFFFFFFFF 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci#define __ATTRIB(attrib, field) case attrib: *value = config->modes.field; break 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci/** 256bf215546Sopenharmony_ci * Return the value of a configuration attribute. The attribute is 257bf215546Sopenharmony_ci * indicated by the index. 258bf215546Sopenharmony_ci */ 259bf215546Sopenharmony_cistatic int 260bf215546Sopenharmony_cidriGetConfigAttribIndex(const __DRIconfig *config, 261bf215546Sopenharmony_ci unsigned int index, unsigned int *value) 262bf215546Sopenharmony_ci{ 263bf215546Sopenharmony_ci switch (index + 1) { 264bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits); 265bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits); 266bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits); 267bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits); 268bf215546Sopenharmony_ci case __DRI_ATTRIB_LEVEL: 269bf215546Sopenharmony_ci case __DRI_ATTRIB_LUMINANCE_SIZE: 270bf215546Sopenharmony_ci case __DRI_ATTRIB_AUX_BUFFERS: 271bf215546Sopenharmony_ci *value = 0; 272bf215546Sopenharmony_ci break; 273bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits); 274bf215546Sopenharmony_ci case __DRI_ATTRIB_ALPHA_MASK_SIZE: 275bf215546Sopenharmony_ci /* I have no idea what this value was ever meant to mean, it's 276bf215546Sopenharmony_ci * never been set to anything, just say 0. 277bf215546Sopenharmony_ci */ 278bf215546Sopenharmony_ci *value = 0; 279bf215546Sopenharmony_ci break; 280bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits); 281bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits); 282bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits); 283bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits); 284bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits); 285bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits); 286bf215546Sopenharmony_ci case __DRI_ATTRIB_SAMPLE_BUFFERS: 287bf215546Sopenharmony_ci *value = !!config->modes.samples; 288bf215546Sopenharmony_ci break; 289bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_SAMPLES, samples); 290bf215546Sopenharmony_ci case __DRI_ATTRIB_RENDER_TYPE: 291bf215546Sopenharmony_ci /* no support for color index mode */ 292bf215546Sopenharmony_ci *value = __DRI_ATTRIB_RGBA_BIT; 293bf215546Sopenharmony_ci if (config->modes.floatMode) 294bf215546Sopenharmony_ci *value |= __DRI_ATTRIB_FLOAT_BIT; 295bf215546Sopenharmony_ci break; 296bf215546Sopenharmony_ci case __DRI_ATTRIB_CONFIG_CAVEAT: 297bf215546Sopenharmony_ci if (config->modes.accumRedBits != 0) 298bf215546Sopenharmony_ci *value = __DRI_ATTRIB_SLOW_BIT; 299bf215546Sopenharmony_ci else 300bf215546Sopenharmony_ci *value = 0; 301bf215546Sopenharmony_ci break; 302bf215546Sopenharmony_ci case __DRI_ATTRIB_CONFORMANT: 303bf215546Sopenharmony_ci *value = GL_TRUE; 304bf215546Sopenharmony_ci break; 305bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode); 306bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode); 307bf215546Sopenharmony_ci case __DRI_ATTRIB_TRANSPARENT_TYPE: 308bf215546Sopenharmony_ci case __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE: /* horrible bc hack */ 309bf215546Sopenharmony_ci *value = GLX_NONE; 310bf215546Sopenharmony_ci break; 311bf215546Sopenharmony_ci case __DRI_ATTRIB_TRANSPARENT_RED_VALUE: 312bf215546Sopenharmony_ci case __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE: 313bf215546Sopenharmony_ci case __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE: 314bf215546Sopenharmony_ci case __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE: 315bf215546Sopenharmony_ci *value = GLX_DONT_CARE; 316bf215546Sopenharmony_ci break; 317bf215546Sopenharmony_ci case __DRI_ATTRIB_FLOAT_MODE: 318bf215546Sopenharmony_ci *value = config->modes.floatMode; 319bf215546Sopenharmony_ci break; 320bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask); 321bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask); 322bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask); 323bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask); 324bf215546Sopenharmony_ci case __DRI_ATTRIB_MAX_PBUFFER_WIDTH: 325bf215546Sopenharmony_ci case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT: 326bf215546Sopenharmony_ci case __DRI_ATTRIB_MAX_PBUFFER_PIXELS: 327bf215546Sopenharmony_ci case __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH: 328bf215546Sopenharmony_ci case __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT: 329bf215546Sopenharmony_ci case __DRI_ATTRIB_VISUAL_SELECT_GROUP: 330bf215546Sopenharmony_ci *value = 0; 331bf215546Sopenharmony_ci break; 332bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod); 333bf215546Sopenharmony_ci case __DRI_ATTRIB_MAX_SWAP_INTERVAL: 334bf215546Sopenharmony_ci *value = INT_MAX; 335bf215546Sopenharmony_ci break; 336bf215546Sopenharmony_ci case __DRI_ATTRIB_MIN_SWAP_INTERVAL: 337bf215546Sopenharmony_ci *value = 0; 338bf215546Sopenharmony_ci break; 339bf215546Sopenharmony_ci case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB: 340bf215546Sopenharmony_ci case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA: 341bf215546Sopenharmony_ci case __DRI_ATTRIB_YINVERTED: 342bf215546Sopenharmony_ci *value = GL_TRUE; 343bf215546Sopenharmony_ci break; 344bf215546Sopenharmony_ci case __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE: 345bf215546Sopenharmony_ci *value = GL_FALSE; 346bf215546Sopenharmony_ci break; 347bf215546Sopenharmony_ci case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS: 348bf215546Sopenharmony_ci *value = __DRI_ATTRIB_TEXTURE_1D_BIT | 349bf215546Sopenharmony_ci __DRI_ATTRIB_TEXTURE_2D_BIT | 350bf215546Sopenharmony_ci __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT; 351bf215546Sopenharmony_ci break; 352bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable); 353bf215546Sopenharmony_ci case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER: 354bf215546Sopenharmony_ci *value = GL_FALSE; 355bf215546Sopenharmony_ci break; 356bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_RED_SHIFT, redShift); 357bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_GREEN_SHIFT, greenShift); 358bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_BLUE_SHIFT, blueShift); 359bf215546Sopenharmony_ci __ATTRIB(__DRI_ATTRIB_ALPHA_SHIFT, alphaShift); 360bf215546Sopenharmony_ci default: 361bf215546Sopenharmony_ci /* XXX log an error or smth */ 362bf215546Sopenharmony_ci return GL_FALSE; 363bf215546Sopenharmony_ci } 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci return GL_TRUE; 366bf215546Sopenharmony_ci} 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci/** 369bf215546Sopenharmony_ci * Get the value of a configuration attribute. 370bf215546Sopenharmony_ci * \param attrib the attribute (one of the _DRI_ATTRIB_x tokens) 371bf215546Sopenharmony_ci * \param value returns the attribute's value 372bf215546Sopenharmony_ci * \return 1 for success, 0 for failure 373bf215546Sopenharmony_ci */ 374bf215546Sopenharmony_cistatic int 375bf215546Sopenharmony_cidriGetConfigAttrib(const __DRIconfig *config, 376bf215546Sopenharmony_ci unsigned int attrib, unsigned int *value) 377bf215546Sopenharmony_ci{ 378bf215546Sopenharmony_ci return driGetConfigAttribIndex(config, attrib - 1, value); 379bf215546Sopenharmony_ci} 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci/** 382bf215546Sopenharmony_ci * Get a configuration attribute name and value, given an index. 383bf215546Sopenharmony_ci * \param index which field of the __DRIconfig to query 384bf215546Sopenharmony_ci * \param attrib returns the attribute name (one of the _DRI_ATTRIB_x tokens) 385bf215546Sopenharmony_ci * \param value returns the attribute's value 386bf215546Sopenharmony_ci * \return 1 for success, 0 for failure 387bf215546Sopenharmony_ci */ 388bf215546Sopenharmony_cistatic int 389bf215546Sopenharmony_cidriIndexConfigAttrib(const __DRIconfig *config, int index, 390bf215546Sopenharmony_ci unsigned int *attrib, unsigned int *value) 391bf215546Sopenharmony_ci{ 392bf215546Sopenharmony_ci if (driGetConfigAttribIndex(config, index, value)) { 393bf215546Sopenharmony_ci *attrib = index + 1; 394bf215546Sopenharmony_ci return GL_TRUE; 395bf215546Sopenharmony_ci } 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci return GL_FALSE; 398bf215546Sopenharmony_ci} 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_cistatic bool 401bf215546Sopenharmony_civalidate_context_version(__DRIscreen *screen, 402bf215546Sopenharmony_ci int mesa_api, 403bf215546Sopenharmony_ci unsigned major_version, 404bf215546Sopenharmony_ci unsigned minor_version, 405bf215546Sopenharmony_ci unsigned *dri_ctx_error) 406bf215546Sopenharmony_ci{ 407bf215546Sopenharmony_ci unsigned req_version = 10 * major_version + minor_version; 408bf215546Sopenharmony_ci unsigned max_version = 0; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci switch (mesa_api) { 411bf215546Sopenharmony_ci case API_OPENGL_COMPAT: 412bf215546Sopenharmony_ci max_version = screen->max_gl_compat_version; 413bf215546Sopenharmony_ci break; 414bf215546Sopenharmony_ci case API_OPENGL_CORE: 415bf215546Sopenharmony_ci max_version = screen->max_gl_core_version; 416bf215546Sopenharmony_ci break; 417bf215546Sopenharmony_ci case API_OPENGLES: 418bf215546Sopenharmony_ci max_version = screen->max_gl_es1_version; 419bf215546Sopenharmony_ci break; 420bf215546Sopenharmony_ci case API_OPENGLES2: 421bf215546Sopenharmony_ci max_version = screen->max_gl_es2_version; 422bf215546Sopenharmony_ci break; 423bf215546Sopenharmony_ci default: 424bf215546Sopenharmony_ci max_version = 0; 425bf215546Sopenharmony_ci break; 426bf215546Sopenharmony_ci } 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci if (max_version == 0) { 429bf215546Sopenharmony_ci *dri_ctx_error = __DRI_CTX_ERROR_BAD_API; 430bf215546Sopenharmony_ci return false; 431bf215546Sopenharmony_ci } else if (req_version > max_version) { 432bf215546Sopenharmony_ci *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION; 433bf215546Sopenharmony_ci return false; 434bf215546Sopenharmony_ci } 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci return true; 437bf215546Sopenharmony_ci} 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci/*****************************************************************/ 440bf215546Sopenharmony_ci/** \name Context handling functions */ 441bf215546Sopenharmony_ci/*****************************************************************/ 442bf215546Sopenharmony_ci/*@{*/ 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_cistatic __DRIcontext * 445bf215546Sopenharmony_cidriCreateContextAttribs(__DRIscreen *screen, int api, 446bf215546Sopenharmony_ci const __DRIconfig *config, 447bf215546Sopenharmony_ci __DRIcontext *shared, 448bf215546Sopenharmony_ci unsigned num_attribs, 449bf215546Sopenharmony_ci const uint32_t *attribs, 450bf215546Sopenharmony_ci unsigned *error, 451bf215546Sopenharmony_ci void *data) 452bf215546Sopenharmony_ci{ 453bf215546Sopenharmony_ci __DRIcontext *context; 454bf215546Sopenharmony_ci const struct gl_config *modes = (config != NULL) ? &config->modes : NULL; 455bf215546Sopenharmony_ci void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; 456bf215546Sopenharmony_ci gl_api mesa_api; 457bf215546Sopenharmony_ci struct __DriverContextConfig ctx_config; 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci ctx_config.major_version = 1; 460bf215546Sopenharmony_ci ctx_config.minor_version = 0; 461bf215546Sopenharmony_ci ctx_config.flags = 0; 462bf215546Sopenharmony_ci ctx_config.attribute_mask = 0; 463bf215546Sopenharmony_ci ctx_config.priority = __DRI_CTX_PRIORITY_MEDIUM; 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci assert((num_attribs == 0) || (attribs != NULL)); 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci if (!(screen->api_mask & (1 << api))) { 468bf215546Sopenharmony_ci *error = __DRI_CTX_ERROR_BAD_API; 469bf215546Sopenharmony_ci return NULL; 470bf215546Sopenharmony_ci } 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci switch (api) { 473bf215546Sopenharmony_ci case __DRI_API_OPENGL: 474bf215546Sopenharmony_ci mesa_api = API_OPENGL_COMPAT; 475bf215546Sopenharmony_ci break; 476bf215546Sopenharmony_ci case __DRI_API_GLES: 477bf215546Sopenharmony_ci mesa_api = API_OPENGLES; 478bf215546Sopenharmony_ci break; 479bf215546Sopenharmony_ci case __DRI_API_GLES2: 480bf215546Sopenharmony_ci case __DRI_API_GLES3: 481bf215546Sopenharmony_ci mesa_api = API_OPENGLES2; 482bf215546Sopenharmony_ci break; 483bf215546Sopenharmony_ci case __DRI_API_OPENGL_CORE: 484bf215546Sopenharmony_ci mesa_api = API_OPENGL_CORE; 485bf215546Sopenharmony_ci break; 486bf215546Sopenharmony_ci default: 487bf215546Sopenharmony_ci *error = __DRI_CTX_ERROR_BAD_API; 488bf215546Sopenharmony_ci return NULL; 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci for (unsigned i = 0; i < num_attribs; i++) { 492bf215546Sopenharmony_ci switch (attribs[i * 2]) { 493bf215546Sopenharmony_ci case __DRI_CTX_ATTRIB_MAJOR_VERSION: 494bf215546Sopenharmony_ci ctx_config.major_version = attribs[i * 2 + 1]; 495bf215546Sopenharmony_ci break; 496bf215546Sopenharmony_ci case __DRI_CTX_ATTRIB_MINOR_VERSION: 497bf215546Sopenharmony_ci ctx_config.minor_version = attribs[i * 2 + 1]; 498bf215546Sopenharmony_ci break; 499bf215546Sopenharmony_ci case __DRI_CTX_ATTRIB_FLAGS: 500bf215546Sopenharmony_ci ctx_config.flags = attribs[i * 2 + 1]; 501bf215546Sopenharmony_ci break; 502bf215546Sopenharmony_ci case __DRI_CTX_ATTRIB_RESET_STRATEGY: 503bf215546Sopenharmony_ci if (attribs[i * 2 + 1] != __DRI_CTX_RESET_NO_NOTIFICATION) { 504bf215546Sopenharmony_ci ctx_config.attribute_mask |= 505bf215546Sopenharmony_ci __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY; 506bf215546Sopenharmony_ci ctx_config.reset_strategy = attribs[i * 2 + 1]; 507bf215546Sopenharmony_ci } else { 508bf215546Sopenharmony_ci ctx_config.attribute_mask &= 509bf215546Sopenharmony_ci ~__DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY; 510bf215546Sopenharmony_ci } 511bf215546Sopenharmony_ci break; 512bf215546Sopenharmony_ci case __DRI_CTX_ATTRIB_PRIORITY: 513bf215546Sopenharmony_ci ctx_config.attribute_mask |= __DRIVER_CONTEXT_ATTRIB_PRIORITY; 514bf215546Sopenharmony_ci ctx_config.priority = attribs[i * 2 + 1]; 515bf215546Sopenharmony_ci break; 516bf215546Sopenharmony_ci case __DRI_CTX_ATTRIB_RELEASE_BEHAVIOR: 517bf215546Sopenharmony_ci if (attribs[i * 2 + 1] != __DRI_CTX_RELEASE_BEHAVIOR_FLUSH) { 518bf215546Sopenharmony_ci ctx_config.attribute_mask |= 519bf215546Sopenharmony_ci __DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR; 520bf215546Sopenharmony_ci ctx_config.release_behavior = attribs[i * 2 + 1]; 521bf215546Sopenharmony_ci } else { 522bf215546Sopenharmony_ci ctx_config.attribute_mask &= 523bf215546Sopenharmony_ci ~__DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR; 524bf215546Sopenharmony_ci } 525bf215546Sopenharmony_ci break; 526bf215546Sopenharmony_ci case __DRI_CTX_ATTRIB_NO_ERROR: 527bf215546Sopenharmony_ci if (attribs[i * 2 + 1] != 0) { 528bf215546Sopenharmony_ci ctx_config.attribute_mask |= 529bf215546Sopenharmony_ci __DRIVER_CONTEXT_ATTRIB_NO_ERROR; 530bf215546Sopenharmony_ci ctx_config.no_error = attribs[i * 2 + 1]; 531bf215546Sopenharmony_ci } else { 532bf215546Sopenharmony_ci ctx_config.attribute_mask &= 533bf215546Sopenharmony_ci ~__DRIVER_CONTEXT_ATTRIB_NO_ERROR; 534bf215546Sopenharmony_ci } 535bf215546Sopenharmony_ci break; 536bf215546Sopenharmony_ci default: 537bf215546Sopenharmony_ci /* We can't create a context that satisfies the requirements of an 538bf215546Sopenharmony_ci * attribute that we don't understand. Return failure. 539bf215546Sopenharmony_ci */ 540bf215546Sopenharmony_ci assert(!"Should not get here."); 541bf215546Sopenharmony_ci *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE; 542bf215546Sopenharmony_ci return NULL; 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci } 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci /* The specific Mesa driver may not support the GL_ARB_compatibilty 547bf215546Sopenharmony_ci * extension or the compatibility profile. In that case, we treat an 548bf215546Sopenharmony_ci * API_OPENGL_COMPAT 3.1 as API_OPENGL_CORE. We reject API_OPENGL_COMPAT 549bf215546Sopenharmony_ci * 3.2+ in any case. 550bf215546Sopenharmony_ci */ 551bf215546Sopenharmony_ci if (mesa_api == API_OPENGL_COMPAT && 552bf215546Sopenharmony_ci ctx_config.major_version == 3 && ctx_config.minor_version == 1 && 553bf215546Sopenharmony_ci screen->max_gl_compat_version < 31) 554bf215546Sopenharmony_ci mesa_api = API_OPENGL_CORE; 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci /* The latest version of EGL_KHR_create_context spec says: 557bf215546Sopenharmony_ci * 558bf215546Sopenharmony_ci * "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in 559bf215546Sopenharmony_ci * EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created. 560bf215546Sopenharmony_ci * [...] This bit is supported for OpenGL and OpenGL ES contexts. 561bf215546Sopenharmony_ci * 562bf215546Sopenharmony_ci * No other EGL_CONTEXT_OPENGL_*_BIT is legal for an ES context. 563bf215546Sopenharmony_ci * 564bf215546Sopenharmony_ci * However, Mesa's EGL layer translates the context attribute 565bf215546Sopenharmony_ci * EGL_CONTEXT_OPENGL_ROBUST_ACCESS into the context flag 566bf215546Sopenharmony_ci * __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS. That attribute is legal for ES 567bf215546Sopenharmony_ci * (with EGL 1.5 or EGL_EXT_create_context_robustness) and GL (only with 568bf215546Sopenharmony_ci * EGL 1.5). 569bf215546Sopenharmony_ci * 570bf215546Sopenharmony_ci * From the EGL_EXT_create_context_robustness spec: 571bf215546Sopenharmony_ci * 572bf215546Sopenharmony_ci * This extension is written against the OpenGL ES 2.0 Specification 573bf215546Sopenharmony_ci * but can apply to OpenGL ES 1.1 and up. 574bf215546Sopenharmony_ci * 575bf215546Sopenharmony_ci * From the EGL 1.5 (2014.08.27) spec, p55: 576bf215546Sopenharmony_ci * 577bf215546Sopenharmony_ci * If the EGL_CONTEXT_OPENGL_ROBUST_ACCESS attribute is set to 578bf215546Sopenharmony_ci * EGL_TRUE, a context supporting robust buffer access will be created. 579bf215546Sopenharmony_ci * OpenGL contexts must support the GL_ARB_robustness extension, or 580bf215546Sopenharmony_ci * equivalent core API functional- ity. OpenGL ES contexts must support 581bf215546Sopenharmony_ci * the GL_EXT_robustness extension, or equivalent core API 582bf215546Sopenharmony_ci * functionality. 583bf215546Sopenharmony_ci */ 584bf215546Sopenharmony_ci if (mesa_api != API_OPENGL_COMPAT 585bf215546Sopenharmony_ci && mesa_api != API_OPENGL_CORE 586bf215546Sopenharmony_ci && (ctx_config.flags & ~(__DRI_CTX_FLAG_DEBUG | 587bf215546Sopenharmony_ci __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS))) { 588bf215546Sopenharmony_ci *error = __DRI_CTX_ERROR_BAD_FLAG; 589bf215546Sopenharmony_ci return NULL; 590bf215546Sopenharmony_ci } 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci /* There are no forward-compatible contexts before OpenGL 3.0. The 593bf215546Sopenharmony_ci * GLX_ARB_create_context spec says: 594bf215546Sopenharmony_ci * 595bf215546Sopenharmony_ci * "Forward-compatible contexts are defined only for OpenGL versions 596bf215546Sopenharmony_ci * 3.0 and later." 597bf215546Sopenharmony_ci * 598bf215546Sopenharmony_ci * Forward-looking contexts are supported by silently converting the 599bf215546Sopenharmony_ci * requested API to API_OPENGL_CORE. 600bf215546Sopenharmony_ci * 601bf215546Sopenharmony_ci * In Mesa, a debug context is the same as a regular context. 602bf215546Sopenharmony_ci */ 603bf215546Sopenharmony_ci if ((ctx_config.flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) { 604bf215546Sopenharmony_ci mesa_api = API_OPENGL_CORE; 605bf215546Sopenharmony_ci } 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci const uint32_t allowed_flags = (__DRI_CTX_FLAG_DEBUG 608bf215546Sopenharmony_ci | __DRI_CTX_FLAG_FORWARD_COMPATIBLE 609bf215546Sopenharmony_ci | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS 610bf215546Sopenharmony_ci | __DRI_CTX_FLAG_RESET_ISOLATION); 611bf215546Sopenharmony_ci if (ctx_config.flags & ~allowed_flags) { 612bf215546Sopenharmony_ci *error = __DRI_CTX_ERROR_UNKNOWN_FLAG; 613bf215546Sopenharmony_ci return NULL; 614bf215546Sopenharmony_ci } 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci if (!validate_context_version(screen, mesa_api, 617bf215546Sopenharmony_ci ctx_config.major_version, 618bf215546Sopenharmony_ci ctx_config.minor_version, 619bf215546Sopenharmony_ci error)) 620bf215546Sopenharmony_ci return NULL; 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci context = calloc(1, sizeof *context); 623bf215546Sopenharmony_ci if (!context) { 624bf215546Sopenharmony_ci *error = __DRI_CTX_ERROR_NO_MEMORY; 625bf215546Sopenharmony_ci return NULL; 626bf215546Sopenharmony_ci } 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci context->loaderPrivate = data; 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci context->driScreenPriv = screen; 631bf215546Sopenharmony_ci context->driDrawablePriv = NULL; 632bf215546Sopenharmony_ci context->driReadablePriv = NULL; 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci if (!dri_create_context(mesa_api, modes, context, &ctx_config, error, 635bf215546Sopenharmony_ci shareCtx)) { 636bf215546Sopenharmony_ci free(context); 637bf215546Sopenharmony_ci return NULL; 638bf215546Sopenharmony_ci } 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ci *error = __DRI_CTX_ERROR_SUCCESS; 641bf215546Sopenharmony_ci return context; 642bf215546Sopenharmony_ci} 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_cistatic __DRIcontext * 645bf215546Sopenharmony_cidriCreateNewContextForAPI(__DRIscreen *screen, int api, 646bf215546Sopenharmony_ci const __DRIconfig *config, 647bf215546Sopenharmony_ci __DRIcontext *shared, void *data) 648bf215546Sopenharmony_ci{ 649bf215546Sopenharmony_ci unsigned error; 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci return driCreateContextAttribs(screen, api, config, shared, 0, NULL, 652bf215546Sopenharmony_ci &error, data); 653bf215546Sopenharmony_ci} 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_cistatic __DRIcontext * 656bf215546Sopenharmony_cidriCreateNewContext(__DRIscreen *screen, const __DRIconfig *config, 657bf215546Sopenharmony_ci __DRIcontext *shared, void *data) 658bf215546Sopenharmony_ci{ 659bf215546Sopenharmony_ci return driCreateNewContextForAPI(screen, __DRI_API_OPENGL, 660bf215546Sopenharmony_ci config, shared, data); 661bf215546Sopenharmony_ci} 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci/** 664bf215546Sopenharmony_ci * Destroy the per-context private information. 665bf215546Sopenharmony_ci * 666bf215546Sopenharmony_ci * \internal 667bf215546Sopenharmony_ci * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls 668bf215546Sopenharmony_ci * drmDestroyContext(), and finally frees \p contextPrivate. 669bf215546Sopenharmony_ci */ 670bf215546Sopenharmony_cistatic void 671bf215546Sopenharmony_cidriDestroyContext(__DRIcontext *pcp) 672bf215546Sopenharmony_ci{ 673bf215546Sopenharmony_ci if (pcp) { 674bf215546Sopenharmony_ci dri_destroy_context(pcp); 675bf215546Sopenharmony_ci free(pcp); 676bf215546Sopenharmony_ci } 677bf215546Sopenharmony_ci} 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_cistatic int 680bf215546Sopenharmony_cidriCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) 681bf215546Sopenharmony_ci{ 682bf215546Sopenharmony_ci (void) dest; 683bf215546Sopenharmony_ci (void) src; 684bf215546Sopenharmony_ci (void) mask; 685bf215546Sopenharmony_ci return GL_FALSE; 686bf215546Sopenharmony_ci} 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci/*@}*/ 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci/*****************************************************************/ 692bf215546Sopenharmony_ci/** \name Context (un)binding functions */ 693bf215546Sopenharmony_ci/*****************************************************************/ 694bf215546Sopenharmony_ci/*@{*/ 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_cistatic void dri_get_drawable(__DRIdrawable *pdp); 697bf215546Sopenharmony_cistatic void dri_put_drawable(__DRIdrawable *pdp); 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci/** 700bf215546Sopenharmony_ci * This function takes both a read buffer and a draw buffer. This is needed 701bf215546Sopenharmony_ci * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent 702bf215546Sopenharmony_ci * function. 703bf215546Sopenharmony_ci */ 704bf215546Sopenharmony_cistatic int driBindContext(__DRIcontext *pcp, 705bf215546Sopenharmony_ci __DRIdrawable *pdp, 706bf215546Sopenharmony_ci __DRIdrawable *prp) 707bf215546Sopenharmony_ci{ 708bf215546Sopenharmony_ci /* 709bf215546Sopenharmony_ci ** Assume error checking is done properly in glXMakeCurrent before 710bf215546Sopenharmony_ci ** calling driUnbindContext. 711bf215546Sopenharmony_ci */ 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_ci if (!pcp) 714bf215546Sopenharmony_ci return GL_FALSE; 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci /* Bind the drawable to the context */ 717bf215546Sopenharmony_ci pcp->driDrawablePriv = pdp; 718bf215546Sopenharmony_ci pcp->driReadablePriv = prp; 719bf215546Sopenharmony_ci if (pdp) { 720bf215546Sopenharmony_ci pdp->driContextPriv = pcp; 721bf215546Sopenharmony_ci dri_get_drawable(pdp); 722bf215546Sopenharmony_ci } 723bf215546Sopenharmony_ci if (prp && pdp != prp) { 724bf215546Sopenharmony_ci dri_get_drawable(prp); 725bf215546Sopenharmony_ci } 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_ci return dri_make_current(pcp, pdp, prp); 728bf215546Sopenharmony_ci} 729bf215546Sopenharmony_ci 730bf215546Sopenharmony_ci/** 731bf215546Sopenharmony_ci * Unbind context. 732bf215546Sopenharmony_ci * 733bf215546Sopenharmony_ci * \param scrn the screen. 734bf215546Sopenharmony_ci * \param gc context. 735bf215546Sopenharmony_ci * 736bf215546Sopenharmony_ci * \return \c GL_TRUE on success, or \c GL_FALSE on failure. 737bf215546Sopenharmony_ci * 738bf215546Sopenharmony_ci * \internal 739bf215546Sopenharmony_ci * This function calls __DriverAPIRec::UnbindContext, and then decrements 740bf215546Sopenharmony_ci * __DRIdrawableRec::refcount which must be non-zero for a successful 741bf215546Sopenharmony_ci * return. 742bf215546Sopenharmony_ci * 743bf215546Sopenharmony_ci * While casting the opaque private pointers associated with the parameters 744bf215546Sopenharmony_ci * into their respective real types it also assures they are not \c NULL. 745bf215546Sopenharmony_ci */ 746bf215546Sopenharmony_cistatic int driUnbindContext(__DRIcontext *pcp) 747bf215546Sopenharmony_ci{ 748bf215546Sopenharmony_ci __DRIdrawable *pdp; 749bf215546Sopenharmony_ci __DRIdrawable *prp; 750bf215546Sopenharmony_ci 751bf215546Sopenharmony_ci /* 752bf215546Sopenharmony_ci ** Assume error checking is done properly in glXMakeCurrent before 753bf215546Sopenharmony_ci ** calling driUnbindContext. 754bf215546Sopenharmony_ci */ 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci if (pcp == NULL) 757bf215546Sopenharmony_ci return GL_FALSE; 758bf215546Sopenharmony_ci 759bf215546Sopenharmony_ci /* 760bf215546Sopenharmony_ci ** Call dri_unbind_context before checking for valid drawables 761bf215546Sopenharmony_ci ** to handle surfaceless contexts properly. 762bf215546Sopenharmony_ci */ 763bf215546Sopenharmony_ci dri_unbind_context(pcp); 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci pdp = pcp->driDrawablePriv; 766bf215546Sopenharmony_ci prp = pcp->driReadablePriv; 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci /* already unbound */ 769bf215546Sopenharmony_ci if (!pdp && !prp) 770bf215546Sopenharmony_ci return GL_TRUE; 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_ci assert(pdp); 773bf215546Sopenharmony_ci if (pdp->refcount == 0) { 774bf215546Sopenharmony_ci /* ERROR!!! */ 775bf215546Sopenharmony_ci return GL_FALSE; 776bf215546Sopenharmony_ci } 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci dri_put_drawable(pdp); 779bf215546Sopenharmony_ci 780bf215546Sopenharmony_ci if (prp != pdp) { 781bf215546Sopenharmony_ci if (prp->refcount == 0) { 782bf215546Sopenharmony_ci /* ERROR!!! */ 783bf215546Sopenharmony_ci return GL_FALSE; 784bf215546Sopenharmony_ci } 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_ci dri_put_drawable(prp); 787bf215546Sopenharmony_ci } 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci pcp->driDrawablePriv = NULL; 790bf215546Sopenharmony_ci pcp->driReadablePriv = NULL; 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_ci return GL_TRUE; 793bf215546Sopenharmony_ci} 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_ci/*@}*/ 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_cistatic void dri_get_drawable(__DRIdrawable *pdp) 799bf215546Sopenharmony_ci{ 800bf215546Sopenharmony_ci pdp->refcount++; 801bf215546Sopenharmony_ci} 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_cistatic void dri_put_drawable(__DRIdrawable *pdp) 804bf215546Sopenharmony_ci{ 805bf215546Sopenharmony_ci if (pdp) { 806bf215546Sopenharmony_ci pdp->refcount--; 807bf215546Sopenharmony_ci if (pdp->refcount) 808bf215546Sopenharmony_ci return; 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci pdp->driScreenPriv->driver->DestroyBuffer(pdp); 811bf215546Sopenharmony_ci free(pdp); 812bf215546Sopenharmony_ci } 813bf215546Sopenharmony_ci} 814bf215546Sopenharmony_ci 815bf215546Sopenharmony_cistatic __DRIdrawable * 816bf215546Sopenharmony_cidriCreateNewDrawable(__DRIscreen *screen, 817bf215546Sopenharmony_ci const __DRIconfig *config, 818bf215546Sopenharmony_ci void *data) 819bf215546Sopenharmony_ci{ 820bf215546Sopenharmony_ci __DRIdrawable *pdraw; 821bf215546Sopenharmony_ci 822bf215546Sopenharmony_ci assert(data != NULL); 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci pdraw = malloc(sizeof *pdraw); 825bf215546Sopenharmony_ci if (!pdraw) 826bf215546Sopenharmony_ci return NULL; 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci pdraw->loaderPrivate = data; 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_ci pdraw->driScreenPriv = screen; 831bf215546Sopenharmony_ci pdraw->driContextPriv = NULL; 832bf215546Sopenharmony_ci pdraw->refcount = 0; 833bf215546Sopenharmony_ci pdraw->lastStamp = 0; 834bf215546Sopenharmony_ci pdraw->w = 0; 835bf215546Sopenharmony_ci pdraw->h = 0; 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ci dri_get_drawable(pdraw); 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci if (!screen->driver->CreateBuffer(screen, pdraw, &config->modes, 840bf215546Sopenharmony_ci GL_FALSE)) { 841bf215546Sopenharmony_ci free(pdraw); 842bf215546Sopenharmony_ci return NULL; 843bf215546Sopenharmony_ci } 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci pdraw->dri2.stamp = pdraw->lastStamp + 1; 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci return pdraw; 848bf215546Sopenharmony_ci} 849bf215546Sopenharmony_ci 850bf215546Sopenharmony_cistatic void 851bf215546Sopenharmony_cidriDestroyDrawable(__DRIdrawable *pdp) 852bf215546Sopenharmony_ci{ 853bf215546Sopenharmony_ci /* 854bf215546Sopenharmony_ci * The loader's data structures are going away, even if pdp itself stays 855bf215546Sopenharmony_ci * around for the time being because it is currently bound. This happens 856bf215546Sopenharmony_ci * when a currently bound GLX pixmap is destroyed. 857bf215546Sopenharmony_ci * 858bf215546Sopenharmony_ci * Clear out the pointer back into the loader's data structures to avoid 859bf215546Sopenharmony_ci * accessing an outdated pointer. 860bf215546Sopenharmony_ci */ 861bf215546Sopenharmony_ci pdp->loaderPrivate = NULL; 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci dri_put_drawable(pdp); 864bf215546Sopenharmony_ci} 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_cistatic __DRIbuffer * 867bf215546Sopenharmony_cidri2AllocateBuffer(__DRIscreen *screen, 868bf215546Sopenharmony_ci unsigned int attachment, unsigned int format, 869bf215546Sopenharmony_ci int width, int height) 870bf215546Sopenharmony_ci{ 871bf215546Sopenharmony_ci return screen->driver->AllocateBuffer(screen, attachment, format, 872bf215546Sopenharmony_ci width, height); 873bf215546Sopenharmony_ci} 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_cistatic void 876bf215546Sopenharmony_cidri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer) 877bf215546Sopenharmony_ci{ 878bf215546Sopenharmony_ci screen->driver->ReleaseBuffer(screen, buffer); 879bf215546Sopenharmony_ci} 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_cistatic int 883bf215546Sopenharmony_cidri2ConfigQueryb(__DRIscreen *screen, const char *var, unsigned char *val) 884bf215546Sopenharmony_ci{ 885bf215546Sopenharmony_ci if (!driCheckOption(&screen->optionCache, var, DRI_BOOL)) 886bf215546Sopenharmony_ci return -1; 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_ci *val = driQueryOptionb(&screen->optionCache, var); 889bf215546Sopenharmony_ci 890bf215546Sopenharmony_ci return 0; 891bf215546Sopenharmony_ci} 892bf215546Sopenharmony_ci 893bf215546Sopenharmony_cistatic int 894bf215546Sopenharmony_cidri2ConfigQueryi(__DRIscreen *screen, const char *var, int *val) 895bf215546Sopenharmony_ci{ 896bf215546Sopenharmony_ci if (!driCheckOption(&screen->optionCache, var, DRI_INT) && 897bf215546Sopenharmony_ci !driCheckOption(&screen->optionCache, var, DRI_ENUM)) 898bf215546Sopenharmony_ci return -1; 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_ci *val = driQueryOptioni(&screen->optionCache, var); 901bf215546Sopenharmony_ci 902bf215546Sopenharmony_ci return 0; 903bf215546Sopenharmony_ci} 904bf215546Sopenharmony_ci 905bf215546Sopenharmony_cistatic int 906bf215546Sopenharmony_cidri2ConfigQueryf(__DRIscreen *screen, const char *var, float *val) 907bf215546Sopenharmony_ci{ 908bf215546Sopenharmony_ci if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT)) 909bf215546Sopenharmony_ci return -1; 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_ci *val = driQueryOptionf(&screen->optionCache, var); 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci return 0; 914bf215546Sopenharmony_ci} 915bf215546Sopenharmony_ci 916bf215546Sopenharmony_cistatic int 917bf215546Sopenharmony_cidri2ConfigQuerys(__DRIscreen *screen, const char *var, char **val) 918bf215546Sopenharmony_ci{ 919bf215546Sopenharmony_ci if (!driCheckOption(&screen->optionCache, var, DRI_STRING)) 920bf215546Sopenharmony_ci return -1; 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci *val = driQueryOptionstr(&screen->optionCache, var); 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci return 0; 925bf215546Sopenharmony_ci} 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_cistatic unsigned int 928bf215546Sopenharmony_cidriGetAPIMask(__DRIscreen *screen) 929bf215546Sopenharmony_ci{ 930bf215546Sopenharmony_ci return screen->api_mask; 931bf215546Sopenharmony_ci} 932bf215546Sopenharmony_ci 933bf215546Sopenharmony_ci/** 934bf215546Sopenharmony_ci * swrast swapbuffers entrypoint. 935bf215546Sopenharmony_ci * 936bf215546Sopenharmony_ci * DRI2 implements this inside the loader with only flushes handled by the 937bf215546Sopenharmony_ci * driver. 938bf215546Sopenharmony_ci */ 939bf215546Sopenharmony_cistatic void 940bf215546Sopenharmony_cidriSwapBuffers(__DRIdrawable *pdp) 941bf215546Sopenharmony_ci{ 942bf215546Sopenharmony_ci assert(pdp->driScreenPriv->swrast_loader); 943bf215546Sopenharmony_ci 944bf215546Sopenharmony_ci pdp->driScreenPriv->driver->SwapBuffers(pdp); 945bf215546Sopenharmony_ci} 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci/** Core interface */ 948bf215546Sopenharmony_ciconst __DRIcoreExtension driCoreExtension = { 949bf215546Sopenharmony_ci .base = { __DRI_CORE, 2 }, 950bf215546Sopenharmony_ci 951bf215546Sopenharmony_ci .createNewScreen = NULL, 952bf215546Sopenharmony_ci .destroyScreen = driDestroyScreen, 953bf215546Sopenharmony_ci .getExtensions = driGetExtensions, 954bf215546Sopenharmony_ci .getConfigAttrib = driGetConfigAttrib, 955bf215546Sopenharmony_ci .indexConfigAttrib = driIndexConfigAttrib, 956bf215546Sopenharmony_ci .createNewDrawable = NULL, 957bf215546Sopenharmony_ci .destroyDrawable = driDestroyDrawable, 958bf215546Sopenharmony_ci .swapBuffers = driSwapBuffers, /* swrast */ 959bf215546Sopenharmony_ci .createNewContext = driCreateNewContext, /* swrast */ 960bf215546Sopenharmony_ci .copyContext = driCopyContext, 961bf215546Sopenharmony_ci .destroyContext = driDestroyContext, 962bf215546Sopenharmony_ci .bindContext = driBindContext, 963bf215546Sopenharmony_ci .unbindContext = driUnbindContext 964bf215546Sopenharmony_ci}; 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci#if HAVE_DRI2 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_ci/** DRI2 interface */ 969bf215546Sopenharmony_ciconst __DRIdri2Extension driDRI2Extension = { 970bf215546Sopenharmony_ci .base = { __DRI_DRI2, 4 }, 971bf215546Sopenharmony_ci 972bf215546Sopenharmony_ci .createNewScreen = dri2CreateNewScreen, 973bf215546Sopenharmony_ci .createNewDrawable = driCreateNewDrawable, 974bf215546Sopenharmony_ci .createNewContext = driCreateNewContext, 975bf215546Sopenharmony_ci .getAPIMask = driGetAPIMask, 976bf215546Sopenharmony_ci .createNewContextForAPI = driCreateNewContextForAPI, 977bf215546Sopenharmony_ci .allocateBuffer = dri2AllocateBuffer, 978bf215546Sopenharmony_ci .releaseBuffer = dri2ReleaseBuffer, 979bf215546Sopenharmony_ci .createContextAttribs = driCreateContextAttribs, 980bf215546Sopenharmony_ci .createNewScreen2 = driCreateNewScreen2, 981bf215546Sopenharmony_ci}; 982bf215546Sopenharmony_ci 983bf215546Sopenharmony_ciconst __DRIdri2Extension swkmsDRI2Extension = { 984bf215546Sopenharmony_ci .base = { __DRI_DRI2, 4 }, 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_ci .createNewScreen = swkmsCreateNewScreen, 987bf215546Sopenharmony_ci .createNewDrawable = driCreateNewDrawable, 988bf215546Sopenharmony_ci .createNewContext = driCreateNewContext, 989bf215546Sopenharmony_ci .getAPIMask = driGetAPIMask, 990bf215546Sopenharmony_ci .createNewContextForAPI = driCreateNewContextForAPI, 991bf215546Sopenharmony_ci .allocateBuffer = dri2AllocateBuffer, 992bf215546Sopenharmony_ci .releaseBuffer = dri2ReleaseBuffer, 993bf215546Sopenharmony_ci .createContextAttribs = driCreateContextAttribs, 994bf215546Sopenharmony_ci .createNewScreen2 = driCreateNewScreen2, 995bf215546Sopenharmony_ci}; 996bf215546Sopenharmony_ci 997bf215546Sopenharmony_ci#endif 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_ciconst __DRIswrastExtension driSWRastExtension = { 1000bf215546Sopenharmony_ci .base = { __DRI_SWRAST, 4 }, 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci .createNewScreen = driSWRastCreateNewScreen, 1003bf215546Sopenharmony_ci .createNewDrawable = driCreateNewDrawable, 1004bf215546Sopenharmony_ci .createNewContextForAPI = driCreateNewContextForAPI, 1005bf215546Sopenharmony_ci .createContextAttribs = driCreateContextAttribs, 1006bf215546Sopenharmony_ci .createNewScreen2 = driSWRastCreateNewScreen2, 1007bf215546Sopenharmony_ci}; 1008bf215546Sopenharmony_ci 1009bf215546Sopenharmony_ciconst __DRI2configQueryExtension dri2ConfigQueryExtension = { 1010bf215546Sopenharmony_ci .base = { __DRI2_CONFIG_QUERY, 2 }, 1011bf215546Sopenharmony_ci 1012bf215546Sopenharmony_ci .configQueryb = dri2ConfigQueryb, 1013bf215546Sopenharmony_ci .configQueryi = dri2ConfigQueryi, 1014bf215546Sopenharmony_ci .configQueryf = dri2ConfigQueryf, 1015bf215546Sopenharmony_ci .configQuerys = dri2ConfigQuerys, 1016bf215546Sopenharmony_ci}; 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_ciconst __DRI2flushControlExtension dri2FlushControlExtension = { 1019bf215546Sopenharmony_ci .base = { __DRI2_FLUSH_CONTROL, 1 } 1020bf215546Sopenharmony_ci}; 1021bf215546Sopenharmony_ci 1022bf215546Sopenharmony_ci/* 1023bf215546Sopenharmony_ci * Note: the first match is returned, which is important for formats like 1024bf215546Sopenharmony_ci * __DRI_IMAGE_FORMAT_R8 which maps to both MESA_FORMAT_{R,L}_UNORM8 1025bf215546Sopenharmony_ci */ 1026bf215546Sopenharmony_cistatic const struct { 1027bf215546Sopenharmony_ci uint32_t image_format; 1028bf215546Sopenharmony_ci mesa_format mesa_format; 1029bf215546Sopenharmony_ci GLenum internal_format; 1030bf215546Sopenharmony_ci} format_mapping[] = { 1031bf215546Sopenharmony_ci { 1032bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_RGB565, 1033bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_B5G6R5_UNORM, 1034bf215546Sopenharmony_ci .internal_format = GL_RGB565, 1035bf215546Sopenharmony_ci }, 1036bf215546Sopenharmony_ci { 1037bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_ARGB1555, 1038bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_B5G5R5A1_UNORM, 1039bf215546Sopenharmony_ci .internal_format = GL_RGB5_A1, 1040bf215546Sopenharmony_ci }, 1041bf215546Sopenharmony_ci { 1042bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_XRGB8888, 1043bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_B8G8R8X8_UNORM, 1044bf215546Sopenharmony_ci .internal_format = GL_RGB8, 1045bf215546Sopenharmony_ci }, 1046bf215546Sopenharmony_ci { 1047bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_ABGR16161616F, 1048bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_RGBA_FLOAT16, 1049bf215546Sopenharmony_ci .internal_format = GL_RGBA16F, 1050bf215546Sopenharmony_ci }, 1051bf215546Sopenharmony_ci { 1052bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_XBGR16161616F, 1053bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_RGBX_FLOAT16, 1054bf215546Sopenharmony_ci .internal_format = GL_RGBA16F, 1055bf215546Sopenharmony_ci }, 1056bf215546Sopenharmony_ci { 1057bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_ABGR16161616, 1058bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_RGBA_UNORM16, 1059bf215546Sopenharmony_ci .internal_format = GL_RGBA16, 1060bf215546Sopenharmony_ci }, 1061bf215546Sopenharmony_ci { 1062bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_XBGR16161616, 1063bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_RGBX_UNORM16, 1064bf215546Sopenharmony_ci .internal_format = GL_RGBA16, 1065bf215546Sopenharmony_ci }, 1066bf215546Sopenharmony_ci { 1067bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_ARGB2101010, 1068bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_B10G10R10A2_UNORM, 1069bf215546Sopenharmony_ci .internal_format = GL_RGB10_A2, 1070bf215546Sopenharmony_ci }, 1071bf215546Sopenharmony_ci { 1072bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_XRGB2101010, 1073bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_B10G10R10X2_UNORM, 1074bf215546Sopenharmony_ci .internal_format = GL_RGB10_A2, 1075bf215546Sopenharmony_ci }, 1076bf215546Sopenharmony_ci { 1077bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_ABGR2101010, 1078bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_R10G10B10A2_UNORM, 1079bf215546Sopenharmony_ci .internal_format = GL_RGB10_A2, 1080bf215546Sopenharmony_ci }, 1081bf215546Sopenharmony_ci { 1082bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_XBGR2101010, 1083bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_R10G10B10X2_UNORM, 1084bf215546Sopenharmony_ci .internal_format = GL_RGB10_A2, 1085bf215546Sopenharmony_ci }, 1086bf215546Sopenharmony_ci { 1087bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_ARGB8888, 1088bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_B8G8R8A8_UNORM, 1089bf215546Sopenharmony_ci .internal_format = GL_RGBA8, 1090bf215546Sopenharmony_ci }, 1091bf215546Sopenharmony_ci { 1092bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_ABGR8888, 1093bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_R8G8B8A8_UNORM, 1094bf215546Sopenharmony_ci .internal_format = GL_RGBA8, 1095bf215546Sopenharmony_ci }, 1096bf215546Sopenharmony_ci { 1097bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_XBGR8888, 1098bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_R8G8B8X8_UNORM, 1099bf215546Sopenharmony_ci .internal_format = GL_RGB8, 1100bf215546Sopenharmony_ci }, 1101bf215546Sopenharmony_ci { 1102bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_R8, 1103bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_R_UNORM8, 1104bf215546Sopenharmony_ci .internal_format = GL_R8, 1105bf215546Sopenharmony_ci }, 1106bf215546Sopenharmony_ci { 1107bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_R8, 1108bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_L_UNORM8, 1109bf215546Sopenharmony_ci .internal_format = GL_R8, 1110bf215546Sopenharmony_ci }, 1111bf215546Sopenharmony_ci#if UTIL_ARCH_LITTLE_ENDIAN 1112bf215546Sopenharmony_ci { 1113bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_GR88, 1114bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_RG_UNORM8, 1115bf215546Sopenharmony_ci .internal_format = GL_RG8, 1116bf215546Sopenharmony_ci }, 1117bf215546Sopenharmony_ci { 1118bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_GR88, 1119bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_LA_UNORM8, 1120bf215546Sopenharmony_ci .internal_format = GL_RG8, 1121bf215546Sopenharmony_ci }, 1122bf215546Sopenharmony_ci#endif 1123bf215546Sopenharmony_ci { 1124bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_SABGR8, 1125bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_R8G8B8A8_SRGB, 1126bf215546Sopenharmony_ci .internal_format = GL_SRGB8_ALPHA8, 1127bf215546Sopenharmony_ci }, 1128bf215546Sopenharmony_ci { 1129bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_SARGB8, 1130bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_B8G8R8A8_SRGB, 1131bf215546Sopenharmony_ci .internal_format = GL_SRGB8_ALPHA8, 1132bf215546Sopenharmony_ci }, 1133bf215546Sopenharmony_ci { 1134bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_SXRGB8, 1135bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_B8G8R8X8_SRGB, 1136bf215546Sopenharmony_ci .internal_format = GL_SRGB8_ALPHA8, 1137bf215546Sopenharmony_ci }, 1138bf215546Sopenharmony_ci { 1139bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_R16, 1140bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_R_UNORM16, 1141bf215546Sopenharmony_ci .internal_format = GL_R16, 1142bf215546Sopenharmony_ci }, 1143bf215546Sopenharmony_ci { 1144bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_R16, 1145bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_L_UNORM16, 1146bf215546Sopenharmony_ci .internal_format = GL_R16, 1147bf215546Sopenharmony_ci }, 1148bf215546Sopenharmony_ci#if UTIL_ARCH_LITTLE_ENDIAN 1149bf215546Sopenharmony_ci { 1150bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_GR1616, 1151bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_RG_UNORM16, 1152bf215546Sopenharmony_ci .internal_format = GL_RG16, 1153bf215546Sopenharmony_ci }, 1154bf215546Sopenharmony_ci { 1155bf215546Sopenharmony_ci .image_format = __DRI_IMAGE_FORMAT_GR1616, 1156bf215546Sopenharmony_ci .mesa_format = MESA_FORMAT_LA_UNORM16, 1157bf215546Sopenharmony_ci .internal_format = GL_RG16, 1158bf215546Sopenharmony_ci }, 1159bf215546Sopenharmony_ci#endif 1160bf215546Sopenharmony_ci}; 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ciuint32_t 1163bf215546Sopenharmony_cidriGLFormatToImageFormat(mesa_format format) 1164bf215546Sopenharmony_ci{ 1165bf215546Sopenharmony_ci for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++) 1166bf215546Sopenharmony_ci if (format_mapping[i].mesa_format == format) 1167bf215546Sopenharmony_ci return format_mapping[i].image_format; 1168bf215546Sopenharmony_ci 1169bf215546Sopenharmony_ci return __DRI_IMAGE_FORMAT_NONE; 1170bf215546Sopenharmony_ci} 1171bf215546Sopenharmony_ci 1172bf215546Sopenharmony_ciuint32_t 1173bf215546Sopenharmony_cidriGLFormatToSizedInternalGLFormat(mesa_format format) 1174bf215546Sopenharmony_ci{ 1175bf215546Sopenharmony_ci for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++) 1176bf215546Sopenharmony_ci if (format_mapping[i].mesa_format == format) 1177bf215546Sopenharmony_ci return format_mapping[i].internal_format; 1178bf215546Sopenharmony_ci 1179bf215546Sopenharmony_ci return GL_NONE; 1180bf215546Sopenharmony_ci} 1181bf215546Sopenharmony_ci 1182bf215546Sopenharmony_cimesa_format 1183bf215546Sopenharmony_cidriImageFormatToGLFormat(uint32_t image_format) 1184bf215546Sopenharmony_ci{ 1185bf215546Sopenharmony_ci for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++) 1186bf215546Sopenharmony_ci if (format_mapping[i].image_format == image_format) 1187bf215546Sopenharmony_ci return format_mapping[i].mesa_format; 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 1190bf215546Sopenharmony_ci} 1191bf215546Sopenharmony_ci 1192bf215546Sopenharmony_ci/** Image driver interface */ 1193bf215546Sopenharmony_ciconst __DRIimageDriverExtension driImageDriverExtension = { 1194bf215546Sopenharmony_ci .base = { __DRI_IMAGE_DRIVER, 1 }, 1195bf215546Sopenharmony_ci 1196bf215546Sopenharmony_ci .createNewScreen2 = driCreateNewScreen2, 1197bf215546Sopenharmony_ci .createNewDrawable = driCreateNewDrawable, 1198bf215546Sopenharmony_ci .getAPIMask = driGetAPIMask, 1199bf215546Sopenharmony_ci .createContextAttribs = driCreateContextAttribs, 1200bf215546Sopenharmony_ci}; 1201