1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009, VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci/* 28bf215546Sopenharmony_ci * Author: Keith Whitwell <keithw@vmware.com> 29bf215546Sopenharmony_ci * Author: Jakob Bornecrantz <wallbraker@gmail.com> 30bf215546Sopenharmony_ci */ 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "dri_screen.h" 33bf215546Sopenharmony_ci#include "dri_context.h" 34bf215546Sopenharmony_ci#include "dri_helpers.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci#include "util/u_inlines.h" 37bf215546Sopenharmony_ci#include "pipe/p_screen.h" 38bf215546Sopenharmony_ci#include "pipe/p_format.h" 39bf215546Sopenharmony_ci#include "pipe-loader/pipe_loader.h" 40bf215546Sopenharmony_ci#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ 41bf215546Sopenharmony_ci#include "frontend/drm_driver.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#include "util/u_debug.h" 44bf215546Sopenharmony_ci#include "util/u_driconf.h" 45bf215546Sopenharmony_ci#include "util/format/u_format_s3tc.h" 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci#define MSAA_VISUAL_MAX_SAMPLES 32 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci#undef false 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ciconst __DRIconfigOptionsExtension gallium_config_options = { 52bf215546Sopenharmony_ci .base = { __DRI_CONFIG_OPTIONS, 2 }, 53bf215546Sopenharmony_ci .getXml = pipe_loader_get_driinfo_xml 54bf215546Sopenharmony_ci}; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci#define false 0 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_civoid 59bf215546Sopenharmony_cidri_init_options(struct dri_screen *screen) 60bf215546Sopenharmony_ci{ 61bf215546Sopenharmony_ci pipe_loader_config_options(screen->dev); 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci struct st_config_options *options = &screen->options; 64bf215546Sopenharmony_ci const struct driOptionCache *optionCache = &screen->dev->option_cache; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci u_driconf_fill_st_options(options, optionCache); 67bf215546Sopenharmony_ci} 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_cistatic unsigned 70bf215546Sopenharmony_cidri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap) 71bf215546Sopenharmony_ci{ 72bf215546Sopenharmony_ci const __DRIdri2LoaderExtension *dri2_loader = screen->sPriv->dri2.loader; 73bf215546Sopenharmony_ci const __DRIimageLoaderExtension *image_loader = screen->sPriv->image.loader; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci if (dri2_loader && dri2_loader->base.version >= 4 && 76bf215546Sopenharmony_ci dri2_loader->getCapability) 77bf215546Sopenharmony_ci return dri2_loader->getCapability(screen->sPriv->loaderPrivate, cap); 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci if (image_loader && image_loader->base.version >= 2 && 80bf215546Sopenharmony_ci image_loader->getCapability) 81bf215546Sopenharmony_ci return image_loader->getCapability(screen->sPriv->loaderPrivate, cap); 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci return 0; 84bf215546Sopenharmony_ci} 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci/** 87bf215546Sopenharmony_ci * Creates a set of \c struct gl_config that a driver will expose. 88bf215546Sopenharmony_ci * 89bf215546Sopenharmony_ci * A set of \c struct gl_config will be created based on the supplied 90bf215546Sopenharmony_ci * parameters. The number of modes processed will be 2 * 91bf215546Sopenharmony_ci * \c num_depth_stencil_bits * \c num_db_modes. 92bf215546Sopenharmony_ci * 93bf215546Sopenharmony_ci * For the most part, data is just copied from \c depth_bits, \c stencil_bits, 94bf215546Sopenharmony_ci * \c db_modes, and \c visType into each \c struct gl_config element. 95bf215546Sopenharmony_ci * However, the meanings of \c fb_format and \c fb_type require further 96bf215546Sopenharmony_ci * explanation. The \c fb_format specifies which color components are in 97bf215546Sopenharmony_ci * each pixel and what the default order is. For example, \c GL_RGB specifies 98bf215546Sopenharmony_ci * that red, green, blue are available and red is in the "most significant" 99bf215546Sopenharmony_ci * position and blue is in the "least significant". The \c fb_type specifies 100bf215546Sopenharmony_ci * the bit sizes of each component and the actual ordering. For example, if 101bf215546Sopenharmony_ci * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11] 102bf215546Sopenharmony_ci * are the blue value, bits [10:5] are the green value, and bits [4:0] are 103bf215546Sopenharmony_ci * the red value. 104bf215546Sopenharmony_ci * 105bf215546Sopenharmony_ci * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either 106bf215546Sopenharmony_ci * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the 107bf215546Sopenharmony_ci * \c struct gl_config structure is \b identical to the \c GL_RGBA or 108bf215546Sopenharmony_ci * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as 109bf215546Sopenharmony_ci * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8 110bf215546Sopenharmony_ci * still uses 32-bits. 111bf215546Sopenharmony_ci * 112bf215546Sopenharmony_ci * If in doubt, look at the tables used in the function. 113bf215546Sopenharmony_ci * 114bf215546Sopenharmony_ci * \param ptr_to_modes Pointer to a pointer to a linked list of 115bf215546Sopenharmony_ci * \c struct gl_config. Upon completion, a pointer to 116bf215546Sopenharmony_ci * the next element to be process will be stored here. 117bf215546Sopenharmony_ci * If the function fails and returns \c GL_FALSE, this 118bf215546Sopenharmony_ci * value will be unmodified, but some elements in the 119bf215546Sopenharmony_ci * linked list may be modified. 120bf215546Sopenharmony_ci * \param format Mesa mesa_format enum describing the pixel format 121bf215546Sopenharmony_ci * \param depth_bits Array of depth buffer sizes to be exposed. 122bf215546Sopenharmony_ci * \param stencil_bits Array of stencil buffer sizes to be exposed. 123bf215546Sopenharmony_ci * \param num_depth_stencil_bits Number of entries in both \c depth_bits and 124bf215546Sopenharmony_ci * \c stencil_bits. 125bf215546Sopenharmony_ci * \param db_modes Array of buffer swap modes. If an element has a 126bf215546Sopenharmony_ci * value of \c __DRI_ATTRIB_SWAP_NONE, then it 127bf215546Sopenharmony_ci * represents a single-buffered mode. Other valid 128bf215546Sopenharmony_ci * values are \c __DRI_ATTRIB_SWAP_EXCHANGE, 129bf215546Sopenharmony_ci * \c __DRI_ATTRIB_SWAP_COPY, and \c __DRI_ATTRIB_SWAP_UNDEFINED. 130bf215546Sopenharmony_ci * They represent the respective GLX values as in 131bf215546Sopenharmony_ci * the GLX_OML_swap_method extension spec. 132bf215546Sopenharmony_ci * \param num_db_modes Number of entries in \c db_modes. 133bf215546Sopenharmony_ci * \param msaa_samples Array of msaa sample count. 0 represents a visual 134bf215546Sopenharmony_ci * without a multisample buffer. 135bf215546Sopenharmony_ci * \param num_msaa_modes Number of entries in \c msaa_samples. 136bf215546Sopenharmony_ci * \param enable_accum Add an accum buffer to the configs 137bf215546Sopenharmony_ci * \param color_depth_match Whether the color depth must match the zs depth 138bf215546Sopenharmony_ci * This forces 32-bit color to have 24-bit depth, and 139bf215546Sopenharmony_ci * 16-bit color to have 16-bit depth. 140bf215546Sopenharmony_ci * 141bf215546Sopenharmony_ci * \returns 142bf215546Sopenharmony_ci * Pointer to any array of pointers to the \c __DRIconfig structures created 143bf215546Sopenharmony_ci * for the specified formats. If there is an error, \c NULL is returned. 144bf215546Sopenharmony_ci * Currently the only cause of failure is a bad parameter (i.e., unsupported 145bf215546Sopenharmony_ci * \c format). 146bf215546Sopenharmony_ci */ 147bf215546Sopenharmony_cistatic __DRIconfig ** 148bf215546Sopenharmony_cidriCreateConfigs(mesa_format format, 149bf215546Sopenharmony_ci const uint8_t * depth_bits, const uint8_t * stencil_bits, 150bf215546Sopenharmony_ci unsigned num_depth_stencil_bits, 151bf215546Sopenharmony_ci const GLenum * db_modes, unsigned num_db_modes, 152bf215546Sopenharmony_ci const uint8_t * msaa_samples, unsigned num_msaa_modes, 153bf215546Sopenharmony_ci GLboolean enable_accum, GLboolean color_depth_match) 154bf215546Sopenharmony_ci{ 155bf215546Sopenharmony_ci static const struct { 156bf215546Sopenharmony_ci uint32_t masks[4]; 157bf215546Sopenharmony_ci int shifts[4]; 158bf215546Sopenharmony_ci } format_table[] = { 159bf215546Sopenharmony_ci /* MESA_FORMAT_B5G6R5_UNORM */ 160bf215546Sopenharmony_ci {{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, 161bf215546Sopenharmony_ci { 11, 5, 0, -1 }}, 162bf215546Sopenharmony_ci /* MESA_FORMAT_B8G8R8X8_UNORM */ 163bf215546Sopenharmony_ci {{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, 164bf215546Sopenharmony_ci { 16, 8, 0, -1 }}, 165bf215546Sopenharmony_ci /* MESA_FORMAT_B8G8R8A8_UNORM */ 166bf215546Sopenharmony_ci {{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, 167bf215546Sopenharmony_ci { 16, 8, 0, 24 }}, 168bf215546Sopenharmony_ci /* MESA_FORMAT_B10G10R10X2_UNORM */ 169bf215546Sopenharmony_ci {{ 0x3FF00000, 0x000FFC00, 0x000003FF, 0x00000000 }, 170bf215546Sopenharmony_ci { 20, 10, 0, -1 }}, 171bf215546Sopenharmony_ci /* MESA_FORMAT_B10G10R10A2_UNORM */ 172bf215546Sopenharmony_ci {{ 0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000 }, 173bf215546Sopenharmony_ci { 20, 10, 0, 30 }}, 174bf215546Sopenharmony_ci /* MESA_FORMAT_R8G8B8A8_UNORM */ 175bf215546Sopenharmony_ci {{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, 176bf215546Sopenharmony_ci { 0, 8, 16, 24 }}, 177bf215546Sopenharmony_ci /* MESA_FORMAT_R8G8B8X8_UNORM */ 178bf215546Sopenharmony_ci {{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }, 179bf215546Sopenharmony_ci { 0, 8, 16, -1 }}, 180bf215546Sopenharmony_ci /* MESA_FORMAT_R10G10B10X2_UNORM */ 181bf215546Sopenharmony_ci {{ 0x000003FF, 0x000FFC00, 0x3FF00000, 0x00000000 }, 182bf215546Sopenharmony_ci { 0, 10, 20, -1 }}, 183bf215546Sopenharmony_ci /* MESA_FORMAT_R10G10B10A2_UNORM */ 184bf215546Sopenharmony_ci {{ 0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000 }, 185bf215546Sopenharmony_ci { 0, 10, 20, 30 }}, 186bf215546Sopenharmony_ci /* MESA_FORMAT_RGBX_FLOAT16 */ 187bf215546Sopenharmony_ci {{ 0, 0, 0, 0}, 188bf215546Sopenharmony_ci { 0, 16, 32, -1 }}, 189bf215546Sopenharmony_ci /* MESA_FORMAT_RGBA_FLOAT16 */ 190bf215546Sopenharmony_ci {{ 0, 0, 0, 0}, 191bf215546Sopenharmony_ci { 0, 16, 32, 48 }}, 192bf215546Sopenharmony_ci }; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci const uint32_t * masks; 195bf215546Sopenharmony_ci const int * shifts; 196bf215546Sopenharmony_ci __DRIconfig **configs, **c; 197bf215546Sopenharmony_ci struct gl_config *modes; 198bf215546Sopenharmony_ci unsigned i, j, k, h; 199bf215546Sopenharmony_ci unsigned num_modes; 200bf215546Sopenharmony_ci unsigned num_accum_bits = (enable_accum) ? 2 : 1; 201bf215546Sopenharmony_ci int red_bits; 202bf215546Sopenharmony_ci int green_bits; 203bf215546Sopenharmony_ci int blue_bits; 204bf215546Sopenharmony_ci int alpha_bits; 205bf215546Sopenharmony_ci bool is_srgb; 206bf215546Sopenharmony_ci bool is_float; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci switch (format) { 209bf215546Sopenharmony_ci case MESA_FORMAT_B5G6R5_UNORM: 210bf215546Sopenharmony_ci masks = format_table[0].masks; 211bf215546Sopenharmony_ci shifts = format_table[0].shifts; 212bf215546Sopenharmony_ci break; 213bf215546Sopenharmony_ci case MESA_FORMAT_B8G8R8X8_UNORM: 214bf215546Sopenharmony_ci case MESA_FORMAT_B8G8R8X8_SRGB: 215bf215546Sopenharmony_ci masks = format_table[1].masks; 216bf215546Sopenharmony_ci shifts = format_table[1].shifts; 217bf215546Sopenharmony_ci break; 218bf215546Sopenharmony_ci case MESA_FORMAT_B8G8R8A8_UNORM: 219bf215546Sopenharmony_ci case MESA_FORMAT_B8G8R8A8_SRGB: 220bf215546Sopenharmony_ci masks = format_table[2].masks; 221bf215546Sopenharmony_ci shifts = format_table[2].shifts; 222bf215546Sopenharmony_ci break; 223bf215546Sopenharmony_ci case MESA_FORMAT_R8G8B8A8_UNORM: 224bf215546Sopenharmony_ci case MESA_FORMAT_R8G8B8A8_SRGB: 225bf215546Sopenharmony_ci masks = format_table[5].masks; 226bf215546Sopenharmony_ci shifts = format_table[5].shifts; 227bf215546Sopenharmony_ci break; 228bf215546Sopenharmony_ci case MESA_FORMAT_R8G8B8X8_UNORM: 229bf215546Sopenharmony_ci case MESA_FORMAT_R8G8B8X8_SRGB: 230bf215546Sopenharmony_ci masks = format_table[6].masks; 231bf215546Sopenharmony_ci shifts = format_table[6].shifts; 232bf215546Sopenharmony_ci break; 233bf215546Sopenharmony_ci case MESA_FORMAT_B10G10R10X2_UNORM: 234bf215546Sopenharmony_ci masks = format_table[3].masks; 235bf215546Sopenharmony_ci shifts = format_table[3].shifts; 236bf215546Sopenharmony_ci break; 237bf215546Sopenharmony_ci case MESA_FORMAT_B10G10R10A2_UNORM: 238bf215546Sopenharmony_ci masks = format_table[4].masks; 239bf215546Sopenharmony_ci shifts = format_table[4].shifts; 240bf215546Sopenharmony_ci break; 241bf215546Sopenharmony_ci case MESA_FORMAT_RGBX_FLOAT16: 242bf215546Sopenharmony_ci masks = format_table[9].masks; 243bf215546Sopenharmony_ci shifts = format_table[9].shifts; 244bf215546Sopenharmony_ci break; 245bf215546Sopenharmony_ci case MESA_FORMAT_RGBA_FLOAT16: 246bf215546Sopenharmony_ci masks = format_table[10].masks; 247bf215546Sopenharmony_ci shifts = format_table[10].shifts; 248bf215546Sopenharmony_ci break; 249bf215546Sopenharmony_ci case MESA_FORMAT_R10G10B10X2_UNORM: 250bf215546Sopenharmony_ci masks = format_table[7].masks; 251bf215546Sopenharmony_ci shifts = format_table[7].shifts; 252bf215546Sopenharmony_ci break; 253bf215546Sopenharmony_ci case MESA_FORMAT_R10G10B10A2_UNORM: 254bf215546Sopenharmony_ci masks = format_table[8].masks; 255bf215546Sopenharmony_ci shifts = format_table[8].shifts; 256bf215546Sopenharmony_ci break; 257bf215546Sopenharmony_ci default: 258bf215546Sopenharmony_ci fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n", 259bf215546Sopenharmony_ci __func__, __LINE__, 260bf215546Sopenharmony_ci _mesa_get_format_name(format), format); 261bf215546Sopenharmony_ci return NULL; 262bf215546Sopenharmony_ci } 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci red_bits = _mesa_get_format_bits(format, GL_RED_BITS); 265bf215546Sopenharmony_ci green_bits = _mesa_get_format_bits(format, GL_GREEN_BITS); 266bf215546Sopenharmony_ci blue_bits = _mesa_get_format_bits(format, GL_BLUE_BITS); 267bf215546Sopenharmony_ci alpha_bits = _mesa_get_format_bits(format, GL_ALPHA_BITS); 268bf215546Sopenharmony_ci is_srgb = _mesa_is_format_srgb(format); 269bf215546Sopenharmony_ci is_float = _mesa_get_format_datatype(format) == GL_FLOAT; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes; 272bf215546Sopenharmony_ci configs = calloc(num_modes + 1, sizeof *configs); 273bf215546Sopenharmony_ci if (configs == NULL) 274bf215546Sopenharmony_ci return NULL; 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci c = configs; 277bf215546Sopenharmony_ci for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { 278bf215546Sopenharmony_ci for ( i = 0 ; i < num_db_modes ; i++ ) { 279bf215546Sopenharmony_ci for ( h = 0 ; h < num_msaa_modes; h++ ) { 280bf215546Sopenharmony_ci for ( j = 0 ; j < num_accum_bits ; j++ ) { 281bf215546Sopenharmony_ci if (color_depth_match && 282bf215546Sopenharmony_ci (depth_bits[k] || stencil_bits[k])) { 283bf215546Sopenharmony_ci /* Depth can really only be 0, 16, 24, or 32. A 32-bit 284bf215546Sopenharmony_ci * color format still matches 24-bit depth, as there 285bf215546Sopenharmony_ci * is an implicit 8-bit stencil. So really we just 286bf215546Sopenharmony_ci * need to make sure that color/depth are both 16 or 287bf215546Sopenharmony_ci * both non-16. 288bf215546Sopenharmony_ci */ 289bf215546Sopenharmony_ci if ((depth_bits[k] + stencil_bits[k] == 16) != 290bf215546Sopenharmony_ci (red_bits + green_bits + blue_bits + alpha_bits == 16)) 291bf215546Sopenharmony_ci continue; 292bf215546Sopenharmony_ci } 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci *c = malloc (sizeof **c); 295bf215546Sopenharmony_ci modes = &(*c)->modes; 296bf215546Sopenharmony_ci c++; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci memset(modes, 0, sizeof *modes); 299bf215546Sopenharmony_ci modes->floatMode = is_float; 300bf215546Sopenharmony_ci modes->redBits = red_bits; 301bf215546Sopenharmony_ci modes->greenBits = green_bits; 302bf215546Sopenharmony_ci modes->blueBits = blue_bits; 303bf215546Sopenharmony_ci modes->alphaBits = alpha_bits; 304bf215546Sopenharmony_ci modes->redMask = masks[0]; 305bf215546Sopenharmony_ci modes->greenMask = masks[1]; 306bf215546Sopenharmony_ci modes->blueMask = masks[2]; 307bf215546Sopenharmony_ci modes->alphaMask = masks[3]; 308bf215546Sopenharmony_ci modes->redShift = shifts[0]; 309bf215546Sopenharmony_ci modes->greenShift = shifts[1]; 310bf215546Sopenharmony_ci modes->blueShift = shifts[2]; 311bf215546Sopenharmony_ci modes->alphaShift = shifts[3]; 312bf215546Sopenharmony_ci modes->rgbBits = modes->redBits + modes->greenBits 313bf215546Sopenharmony_ci + modes->blueBits + modes->alphaBits; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci modes->accumRedBits = 16 * j; 316bf215546Sopenharmony_ci modes->accumGreenBits = 16 * j; 317bf215546Sopenharmony_ci modes->accumBlueBits = 16 * j; 318bf215546Sopenharmony_ci modes->accumAlphaBits = 16 * j; 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci modes->stencilBits = stencil_bits[k]; 321bf215546Sopenharmony_ci modes->depthBits = depth_bits[k]; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci if (db_modes[i] == __DRI_ATTRIB_SWAP_NONE) { 324bf215546Sopenharmony_ci modes->doubleBufferMode = GL_FALSE; 325bf215546Sopenharmony_ci modes->swapMethod = __DRI_ATTRIB_SWAP_UNDEFINED; 326bf215546Sopenharmony_ci } 327bf215546Sopenharmony_ci else { 328bf215546Sopenharmony_ci modes->doubleBufferMode = GL_TRUE; 329bf215546Sopenharmony_ci modes->swapMethod = db_modes[i]; 330bf215546Sopenharmony_ci } 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci modes->samples = msaa_samples[h]; 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci modes->sRGBCapable = is_srgb; 335bf215546Sopenharmony_ci } 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci } 339bf215546Sopenharmony_ci *c = NULL; 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci return configs; 342bf215546Sopenharmony_ci} 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_cistatic __DRIconfig ** 345bf215546Sopenharmony_cidriConcatConfigs(__DRIconfig **a, __DRIconfig **b) 346bf215546Sopenharmony_ci{ 347bf215546Sopenharmony_ci __DRIconfig **all; 348bf215546Sopenharmony_ci int i, j, index; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci if (a == NULL || a[0] == NULL) 351bf215546Sopenharmony_ci return b; 352bf215546Sopenharmony_ci else if (b == NULL || b[0] == NULL) 353bf215546Sopenharmony_ci return a; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci i = 0; 356bf215546Sopenharmony_ci while (a[i] != NULL) 357bf215546Sopenharmony_ci i++; 358bf215546Sopenharmony_ci j = 0; 359bf215546Sopenharmony_ci while (b[j] != NULL) 360bf215546Sopenharmony_ci j++; 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci all = malloc((i + j + 1) * sizeof *all); 363bf215546Sopenharmony_ci index = 0; 364bf215546Sopenharmony_ci for (i = 0; a[i] != NULL; i++) 365bf215546Sopenharmony_ci all[index++] = a[i]; 366bf215546Sopenharmony_ci for (j = 0; b[j] != NULL; j++) 367bf215546Sopenharmony_ci all[index++] = b[j]; 368bf215546Sopenharmony_ci all[index++] = NULL; 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci free(a); 371bf215546Sopenharmony_ci free(b); 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci return all; 374bf215546Sopenharmony_ci} 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_cistatic const __DRIconfig ** 378bf215546Sopenharmony_cidri_fill_in_modes(struct dri_screen *screen) 379bf215546Sopenharmony_ci{ 380bf215546Sopenharmony_ci static const mesa_format mesa_formats[] = { 381bf215546Sopenharmony_ci MESA_FORMAT_B10G10R10A2_UNORM, 382bf215546Sopenharmony_ci MESA_FORMAT_B10G10R10X2_UNORM, 383bf215546Sopenharmony_ci MESA_FORMAT_R10G10B10A2_UNORM, 384bf215546Sopenharmony_ci MESA_FORMAT_R10G10B10X2_UNORM, 385bf215546Sopenharmony_ci MESA_FORMAT_B8G8R8A8_UNORM, 386bf215546Sopenharmony_ci MESA_FORMAT_B8G8R8X8_UNORM, 387bf215546Sopenharmony_ci MESA_FORMAT_B8G8R8A8_SRGB, 388bf215546Sopenharmony_ci MESA_FORMAT_B8G8R8X8_SRGB, 389bf215546Sopenharmony_ci MESA_FORMAT_B5G6R5_UNORM, 390bf215546Sopenharmony_ci MESA_FORMAT_RGBA_FLOAT16, 391bf215546Sopenharmony_ci MESA_FORMAT_RGBX_FLOAT16, 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci /* The 32-bit RGBA format must not precede the 32-bit BGRA format. 394bf215546Sopenharmony_ci * Likewise for RGBX and BGRX. Otherwise, the GLX client and the GLX 395bf215546Sopenharmony_ci * server may disagree on which format the GLXFBConfig represents, 396bf215546Sopenharmony_ci * resulting in swapped color channels. 397bf215546Sopenharmony_ci * 398bf215546Sopenharmony_ci * The problem, as of 2017-05-30: 399bf215546Sopenharmony_ci * When matching a GLXFBConfig to a __DRIconfig, GLX ignores the channel 400bf215546Sopenharmony_ci * order and chooses the first __DRIconfig with the expected channel 401bf215546Sopenharmony_ci * sizes. Specifically, GLX compares the GLXFBConfig's and __DRIconfig's 402bf215546Sopenharmony_ci * __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK. 403bf215546Sopenharmony_ci * 404bf215546Sopenharmony_ci * EGL does not suffer from this problem. It correctly compares the 405bf215546Sopenharmony_ci * channel masks when matching EGLConfig to __DRIconfig. 406bf215546Sopenharmony_ci */ 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci /* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */ 409bf215546Sopenharmony_ci MESA_FORMAT_R8G8B8A8_UNORM, 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci /* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */ 412bf215546Sopenharmony_ci MESA_FORMAT_R8G8B8X8_UNORM, 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci /* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */ 415bf215546Sopenharmony_ci MESA_FORMAT_R8G8B8A8_SRGB, 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci /* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */ 418bf215546Sopenharmony_ci MESA_FORMAT_R8G8B8X8_SRGB, 419bf215546Sopenharmony_ci }; 420bf215546Sopenharmony_ci static const enum pipe_format pipe_formats[] = { 421bf215546Sopenharmony_ci PIPE_FORMAT_B10G10R10A2_UNORM, 422bf215546Sopenharmony_ci PIPE_FORMAT_B10G10R10X2_UNORM, 423bf215546Sopenharmony_ci PIPE_FORMAT_R10G10B10A2_UNORM, 424bf215546Sopenharmony_ci PIPE_FORMAT_R10G10B10X2_UNORM, 425bf215546Sopenharmony_ci PIPE_FORMAT_BGRA8888_UNORM, 426bf215546Sopenharmony_ci PIPE_FORMAT_BGRX8888_UNORM, 427bf215546Sopenharmony_ci PIPE_FORMAT_BGRA8888_SRGB, 428bf215546Sopenharmony_ci PIPE_FORMAT_BGRX8888_SRGB, 429bf215546Sopenharmony_ci PIPE_FORMAT_B5G6R5_UNORM, 430bf215546Sopenharmony_ci PIPE_FORMAT_R16G16B16A16_FLOAT, 431bf215546Sopenharmony_ci PIPE_FORMAT_R16G16B16X16_FLOAT, 432bf215546Sopenharmony_ci PIPE_FORMAT_RGBA8888_UNORM, 433bf215546Sopenharmony_ci PIPE_FORMAT_RGBX8888_UNORM, 434bf215546Sopenharmony_ci PIPE_FORMAT_RGBA8888_SRGB, 435bf215546Sopenharmony_ci PIPE_FORMAT_RGBX8888_SRGB, 436bf215546Sopenharmony_ci }; 437bf215546Sopenharmony_ci mesa_format format; 438bf215546Sopenharmony_ci __DRIconfig **configs = NULL; 439bf215546Sopenharmony_ci uint8_t depth_bits_array[5]; 440bf215546Sopenharmony_ci uint8_t stencil_bits_array[5]; 441bf215546Sopenharmony_ci unsigned depth_buffer_factor; 442bf215546Sopenharmony_ci unsigned msaa_samples_max; 443bf215546Sopenharmony_ci unsigned i; 444bf215546Sopenharmony_ci struct pipe_screen *p_screen = screen->base.screen; 445bf215546Sopenharmony_ci bool pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32; 446bf215546Sopenharmony_ci bool mixed_color_depth; 447bf215546Sopenharmony_ci bool allow_rgba_ordering; 448bf215546Sopenharmony_ci bool allow_rgb10; 449bf215546Sopenharmony_ci bool allow_fp16; 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci static const GLenum back_buffer_modes[] = { 452bf215546Sopenharmony_ci __DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED, 453bf215546Sopenharmony_ci __DRI_ATTRIB_SWAP_COPY 454bf215546Sopenharmony_ci }; 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci if (driQueryOptionb(&screen->dev->option_cache, "always_have_depth_buffer")) { 457bf215546Sopenharmony_ci /* all visuals will have a depth buffer */ 458bf215546Sopenharmony_ci depth_buffer_factor = 0; 459bf215546Sopenharmony_ci } 460bf215546Sopenharmony_ci else { 461bf215546Sopenharmony_ci depth_bits_array[0] = 0; 462bf215546Sopenharmony_ci stencil_bits_array[0] = 0; 463bf215546Sopenharmony_ci depth_buffer_factor = 1; 464bf215546Sopenharmony_ci } 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci allow_rgba_ordering = dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING); 467bf215546Sopenharmony_ci allow_rgb10 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb10_configs"); 468bf215546Sopenharmony_ci allow_fp16 = dri_loader_get_cap(screen, DRI_LOADER_CAP_FP16); 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci msaa_samples_max = (screen->st_api->feature_mask & ST_API_FEATURE_MS_VISUALS_MASK) 471bf215546Sopenharmony_ci ? MSAA_VISUAL_MAX_SAMPLES : 1; 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ci pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, 474bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 475bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL); 476bf215546Sopenharmony_ci pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, 477bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 478bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL); 479bf215546Sopenharmony_ci pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_UINT, 480bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 481bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL); 482bf215546Sopenharmony_ci pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_UINT_Z24_UNORM, 483bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 484bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL); 485bf215546Sopenharmony_ci pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, 486bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 487bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL); 488bf215546Sopenharmony_ci pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, 489bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 490bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL); 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci if (pf_z16) { 493bf215546Sopenharmony_ci depth_bits_array[depth_buffer_factor] = 16; 494bf215546Sopenharmony_ci stencil_bits_array[depth_buffer_factor++] = 0; 495bf215546Sopenharmony_ci } 496bf215546Sopenharmony_ci if (pf_x8z24 || pf_z24x8) { 497bf215546Sopenharmony_ci depth_bits_array[depth_buffer_factor] = 24; 498bf215546Sopenharmony_ci stencil_bits_array[depth_buffer_factor++] = 0; 499bf215546Sopenharmony_ci screen->d_depth_bits_last = pf_x8z24; 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci if (pf_s8z24 || pf_z24s8) { 502bf215546Sopenharmony_ci depth_bits_array[depth_buffer_factor] = 24; 503bf215546Sopenharmony_ci stencil_bits_array[depth_buffer_factor++] = 8; 504bf215546Sopenharmony_ci screen->sd_depth_bits_last = pf_s8z24; 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci if (pf_z32) { 507bf215546Sopenharmony_ci depth_bits_array[depth_buffer_factor] = 32; 508bf215546Sopenharmony_ci stencil_bits_array[depth_buffer_factor++] = 0; 509bf215546Sopenharmony_ci } 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci mixed_color_depth = 512bf215546Sopenharmony_ci p_screen->get_param(p_screen, PIPE_CAP_MIXED_COLOR_DEPTH_BITS); 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci assert(ARRAY_SIZE(mesa_formats) == ARRAY_SIZE(pipe_formats)); 515bf215546Sopenharmony_ci 516bf215546Sopenharmony_ci /* Add configs. */ 517bf215546Sopenharmony_ci for (format = 0; format < ARRAY_SIZE(mesa_formats); format++) { 518bf215546Sopenharmony_ci __DRIconfig **new_configs = NULL; 519bf215546Sopenharmony_ci unsigned num_msaa_modes = 0; /* includes a single-sample mode */ 520bf215546Sopenharmony_ci uint8_t msaa_modes[MSAA_VISUAL_MAX_SAMPLES]; 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ci /* Expose only BGRA ordering if the loader doesn't support RGBA ordering. */ 523bf215546Sopenharmony_ci if (!allow_rgba_ordering && 524bf215546Sopenharmony_ci (mesa_formats[format] == MESA_FORMAT_R8G8B8A8_UNORM || 525bf215546Sopenharmony_ci mesa_formats[format] == MESA_FORMAT_R8G8B8X8_UNORM || 526bf215546Sopenharmony_ci mesa_formats[format] == MESA_FORMAT_R8G8B8A8_SRGB || 527bf215546Sopenharmony_ci mesa_formats[format] == MESA_FORMAT_R8G8B8X8_SRGB)) 528bf215546Sopenharmony_ci continue; 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci if (!allow_rgb10 && 531bf215546Sopenharmony_ci (mesa_formats[format] == MESA_FORMAT_B10G10R10A2_UNORM || 532bf215546Sopenharmony_ci mesa_formats[format] == MESA_FORMAT_B10G10R10X2_UNORM || 533bf215546Sopenharmony_ci mesa_formats[format] == MESA_FORMAT_R10G10B10A2_UNORM || 534bf215546Sopenharmony_ci mesa_formats[format] == MESA_FORMAT_R10G10B10X2_UNORM)) 535bf215546Sopenharmony_ci continue; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci if (!allow_fp16 && 538bf215546Sopenharmony_ci (mesa_formats[format] == MESA_FORMAT_RGBA_FLOAT16 || 539bf215546Sopenharmony_ci mesa_formats[format] == MESA_FORMAT_RGBX_FLOAT16)) 540bf215546Sopenharmony_ci continue; 541bf215546Sopenharmony_ci 542bf215546Sopenharmony_ci if (!p_screen->is_format_supported(p_screen, pipe_formats[format], 543bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 544bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET | 545bf215546Sopenharmony_ci PIPE_BIND_DISPLAY_TARGET)) 546bf215546Sopenharmony_ci continue; 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci for (i = 1; i <= msaa_samples_max; i++) { 549bf215546Sopenharmony_ci int samples = i > 1 ? i : 0; 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci if (p_screen->is_format_supported(p_screen, pipe_formats[format], 552bf215546Sopenharmony_ci PIPE_TEXTURE_2D, samples, samples, 553bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET)) { 554bf215546Sopenharmony_ci msaa_modes[num_msaa_modes++] = samples; 555bf215546Sopenharmony_ci } 556bf215546Sopenharmony_ci } 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci if (num_msaa_modes) { 559bf215546Sopenharmony_ci /* Single-sample configs with an accumulation buffer. */ 560bf215546Sopenharmony_ci new_configs = driCreateConfigs(mesa_formats[format], 561bf215546Sopenharmony_ci depth_bits_array, stencil_bits_array, 562bf215546Sopenharmony_ci depth_buffer_factor, back_buffer_modes, 563bf215546Sopenharmony_ci ARRAY_SIZE(back_buffer_modes), 564bf215546Sopenharmony_ci msaa_modes, 1, 565bf215546Sopenharmony_ci GL_TRUE, !mixed_color_depth); 566bf215546Sopenharmony_ci configs = driConcatConfigs(configs, new_configs); 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_ci /* Multi-sample configs without an accumulation buffer. */ 569bf215546Sopenharmony_ci if (num_msaa_modes > 1) { 570bf215546Sopenharmony_ci new_configs = driCreateConfigs(mesa_formats[format], 571bf215546Sopenharmony_ci depth_bits_array, stencil_bits_array, 572bf215546Sopenharmony_ci depth_buffer_factor, back_buffer_modes, 573bf215546Sopenharmony_ci ARRAY_SIZE(back_buffer_modes), 574bf215546Sopenharmony_ci msaa_modes+1, num_msaa_modes-1, 575bf215546Sopenharmony_ci GL_FALSE, !mixed_color_depth); 576bf215546Sopenharmony_ci configs = driConcatConfigs(configs, new_configs); 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci } 579bf215546Sopenharmony_ci } 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci if (configs == NULL) { 582bf215546Sopenharmony_ci debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__); 583bf215546Sopenharmony_ci return NULL; 584bf215546Sopenharmony_ci } 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci return (const __DRIconfig **)configs; 587bf215546Sopenharmony_ci} 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci/** 590bf215546Sopenharmony_ci * Roughly the converse of dri_fill_in_modes. 591bf215546Sopenharmony_ci */ 592bf215546Sopenharmony_civoid 593bf215546Sopenharmony_cidri_fill_st_visual(struct st_visual *stvis, 594bf215546Sopenharmony_ci const struct dri_screen *screen, 595bf215546Sopenharmony_ci const struct gl_config *mode) 596bf215546Sopenharmony_ci{ 597bf215546Sopenharmony_ci memset(stvis, 0, sizeof(*stvis)); 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci if (!mode) 600bf215546Sopenharmony_ci return; 601bf215546Sopenharmony_ci 602bf215546Sopenharmony_ci /* Deduce the color format. */ 603bf215546Sopenharmony_ci switch (mode->redMask) { 604bf215546Sopenharmony_ci case 0: 605bf215546Sopenharmony_ci /* Formats > 32 bpp */ 606bf215546Sopenharmony_ci assert(mode->floatMode); 607bf215546Sopenharmony_ci if (mode->alphaShift > -1) { 608bf215546Sopenharmony_ci assert(mode->alphaShift == 48); 609bf215546Sopenharmony_ci stvis->color_format = PIPE_FORMAT_R16G16B16A16_FLOAT; 610bf215546Sopenharmony_ci } else { 611bf215546Sopenharmony_ci stvis->color_format = PIPE_FORMAT_R16G16B16X16_FLOAT; 612bf215546Sopenharmony_ci } 613bf215546Sopenharmony_ci break; 614bf215546Sopenharmony_ci 615bf215546Sopenharmony_ci case 0x3FF00000: 616bf215546Sopenharmony_ci if (mode->alphaMask) { 617bf215546Sopenharmony_ci assert(mode->alphaMask == 0xC0000000); 618bf215546Sopenharmony_ci stvis->color_format = PIPE_FORMAT_B10G10R10A2_UNORM; 619bf215546Sopenharmony_ci } else { 620bf215546Sopenharmony_ci stvis->color_format = PIPE_FORMAT_B10G10R10X2_UNORM; 621bf215546Sopenharmony_ci } 622bf215546Sopenharmony_ci break; 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci case 0x000003FF: 625bf215546Sopenharmony_ci if (mode->alphaMask) { 626bf215546Sopenharmony_ci assert(mode->alphaMask == 0xC0000000); 627bf215546Sopenharmony_ci stvis->color_format = PIPE_FORMAT_R10G10B10A2_UNORM; 628bf215546Sopenharmony_ci } else { 629bf215546Sopenharmony_ci stvis->color_format = PIPE_FORMAT_R10G10B10X2_UNORM; 630bf215546Sopenharmony_ci } 631bf215546Sopenharmony_ci break; 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci case 0x00FF0000: 634bf215546Sopenharmony_ci if (mode->alphaMask) { 635bf215546Sopenharmony_ci assert(mode->alphaMask == 0xFF000000); 636bf215546Sopenharmony_ci stvis->color_format = mode->sRGBCapable ? 637bf215546Sopenharmony_ci PIPE_FORMAT_BGRA8888_SRGB : 638bf215546Sopenharmony_ci PIPE_FORMAT_BGRA8888_UNORM; 639bf215546Sopenharmony_ci } else { 640bf215546Sopenharmony_ci stvis->color_format = mode->sRGBCapable ? 641bf215546Sopenharmony_ci PIPE_FORMAT_BGRX8888_SRGB : 642bf215546Sopenharmony_ci PIPE_FORMAT_BGRX8888_UNORM; 643bf215546Sopenharmony_ci } 644bf215546Sopenharmony_ci break; 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci case 0x000000FF: 647bf215546Sopenharmony_ci if (mode->alphaMask) { 648bf215546Sopenharmony_ci assert(mode->alphaMask == 0xFF000000); 649bf215546Sopenharmony_ci stvis->color_format = mode->sRGBCapable ? 650bf215546Sopenharmony_ci PIPE_FORMAT_RGBA8888_SRGB : 651bf215546Sopenharmony_ci PIPE_FORMAT_RGBA8888_UNORM; 652bf215546Sopenharmony_ci } else { 653bf215546Sopenharmony_ci stvis->color_format = mode->sRGBCapable ? 654bf215546Sopenharmony_ci PIPE_FORMAT_RGBX8888_SRGB : 655bf215546Sopenharmony_ci PIPE_FORMAT_RGBX8888_UNORM; 656bf215546Sopenharmony_ci } 657bf215546Sopenharmony_ci break; 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci case 0x0000F800: 660bf215546Sopenharmony_ci stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM; 661bf215546Sopenharmony_ci break; 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci default: 664bf215546Sopenharmony_ci assert(!"unsupported visual: invalid red mask"); 665bf215546Sopenharmony_ci return; 666bf215546Sopenharmony_ci } 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci if (mode->samples > 0) { 669bf215546Sopenharmony_ci if (debug_get_bool_option("DRI_NO_MSAA", false)) 670bf215546Sopenharmony_ci stvis->samples = 0; 671bf215546Sopenharmony_ci else 672bf215546Sopenharmony_ci stvis->samples = mode->samples; 673bf215546Sopenharmony_ci } 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci switch (mode->depthBits) { 676bf215546Sopenharmony_ci default: 677bf215546Sopenharmony_ci case 0: 678bf215546Sopenharmony_ci stvis->depth_stencil_format = PIPE_FORMAT_NONE; 679bf215546Sopenharmony_ci break; 680bf215546Sopenharmony_ci case 16: 681bf215546Sopenharmony_ci stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM; 682bf215546Sopenharmony_ci break; 683bf215546Sopenharmony_ci case 24: 684bf215546Sopenharmony_ci if (mode->stencilBits == 0) { 685bf215546Sopenharmony_ci stvis->depth_stencil_format = (screen->d_depth_bits_last) ? 686bf215546Sopenharmony_ci PIPE_FORMAT_Z24X8_UNORM: 687bf215546Sopenharmony_ci PIPE_FORMAT_X8Z24_UNORM; 688bf215546Sopenharmony_ci } else { 689bf215546Sopenharmony_ci stvis->depth_stencil_format = (screen->sd_depth_bits_last) ? 690bf215546Sopenharmony_ci PIPE_FORMAT_Z24_UNORM_S8_UINT: 691bf215546Sopenharmony_ci PIPE_FORMAT_S8_UINT_Z24_UNORM; 692bf215546Sopenharmony_ci } 693bf215546Sopenharmony_ci break; 694bf215546Sopenharmony_ci case 32: 695bf215546Sopenharmony_ci stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM; 696bf215546Sopenharmony_ci break; 697bf215546Sopenharmony_ci } 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci stvis->accum_format = (mode->accumRedBits > 0) ? 700bf215546Sopenharmony_ci PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ci stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; 703bf215546Sopenharmony_ci if (mode->doubleBufferMode) { 704bf215546Sopenharmony_ci stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; 705bf215546Sopenharmony_ci } 706bf215546Sopenharmony_ci if (mode->stereoMode) { 707bf215546Sopenharmony_ci stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; 708bf215546Sopenharmony_ci if (mode->doubleBufferMode) 709bf215546Sopenharmony_ci stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; 710bf215546Sopenharmony_ci } 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci if (mode->depthBits > 0 || mode->stencilBits > 0) 713bf215546Sopenharmony_ci stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; 714bf215546Sopenharmony_ci /* let the gallium frontend allocate the accum buffer */ 715bf215546Sopenharmony_ci} 716bf215546Sopenharmony_ci 717bf215546Sopenharmony_cistatic bool 718bf215546Sopenharmony_cidri_get_egl_image(struct st_manager *smapi, 719bf215546Sopenharmony_ci void *egl_image, 720bf215546Sopenharmony_ci struct st_egl_image *stimg) 721bf215546Sopenharmony_ci{ 722bf215546Sopenharmony_ci struct dri_screen *screen = (struct dri_screen *)smapi; 723bf215546Sopenharmony_ci __DRIimage *img = NULL; 724bf215546Sopenharmony_ci const struct dri2_format_mapping *map; 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci if (screen->lookup_egl_image_validated) { 727bf215546Sopenharmony_ci img = screen->lookup_egl_image_validated(screen, egl_image); 728bf215546Sopenharmony_ci } else if (screen->lookup_egl_image) { 729bf215546Sopenharmony_ci img = screen->lookup_egl_image(screen, egl_image); 730bf215546Sopenharmony_ci } 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_ci if (!img) 733bf215546Sopenharmony_ci return FALSE; 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci stimg->texture = NULL; 736bf215546Sopenharmony_ci pipe_resource_reference(&stimg->texture, img->texture); 737bf215546Sopenharmony_ci map = dri2_get_mapping_by_fourcc(img->dri_fourcc); 738bf215546Sopenharmony_ci stimg->format = map ? map->pipe_format : img->texture->format; 739bf215546Sopenharmony_ci stimg->level = img->level; 740bf215546Sopenharmony_ci stimg->layer = img->layer; 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_ci if (img->imported_dmabuf && map) { 743bf215546Sopenharmony_ci /* Guess sized internal format for dma-bufs. Could be used 744bf215546Sopenharmony_ci * by EXT_EGL_image_storage. 745bf215546Sopenharmony_ci */ 746bf215546Sopenharmony_ci mesa_format mesa_format = driImageFormatToGLFormat(map->dri_format); 747bf215546Sopenharmony_ci stimg->internalformat = driGLFormatToSizedInternalGLFormat(mesa_format); 748bf215546Sopenharmony_ci } else { 749bf215546Sopenharmony_ci stimg->internalformat = img->internal_format; 750bf215546Sopenharmony_ci } 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci stimg->yuv_color_space = img->yuv_color_space; 753bf215546Sopenharmony_ci stimg->yuv_range = img->sample_range; 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci return TRUE; 756bf215546Sopenharmony_ci} 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_cistatic bool 759bf215546Sopenharmony_cidri_validate_egl_image(struct st_manager *smapi, 760bf215546Sopenharmony_ci void *egl_image) 761bf215546Sopenharmony_ci{ 762bf215546Sopenharmony_ci struct dri_screen *screen = (struct dri_screen *)smapi; 763bf215546Sopenharmony_ci 764bf215546Sopenharmony_ci return screen->validate_egl_image(screen, egl_image); 765bf215546Sopenharmony_ci} 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_cistatic int 768bf215546Sopenharmony_cidri_get_param(struct st_manager *smapi, 769bf215546Sopenharmony_ci enum st_manager_param param) 770bf215546Sopenharmony_ci{ 771bf215546Sopenharmony_ci return 0; 772bf215546Sopenharmony_ci} 773bf215546Sopenharmony_ci 774bf215546Sopenharmony_civoid 775bf215546Sopenharmony_cidri_destroy_screen_helper(struct dri_screen * screen) 776bf215546Sopenharmony_ci{ 777bf215546Sopenharmony_ci if (screen->base.destroy) 778bf215546Sopenharmony_ci screen->base.destroy(&screen->base); 779bf215546Sopenharmony_ci 780bf215546Sopenharmony_ci if (screen->st_api && screen->st_api->destroy) 781bf215546Sopenharmony_ci screen->st_api->destroy(screen->st_api); 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci if (screen->base.screen) 784bf215546Sopenharmony_ci screen->base.screen->destroy(screen->base.screen); 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_ci mtx_destroy(&screen->opencl_func_mutex); 787bf215546Sopenharmony_ci} 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_civoid 790bf215546Sopenharmony_cidri_destroy_screen(__DRIscreen * sPriv) 791bf215546Sopenharmony_ci{ 792bf215546Sopenharmony_ci struct dri_screen *screen = dri_screen(sPriv); 793bf215546Sopenharmony_ci 794bf215546Sopenharmony_ci dri_destroy_screen_helper(screen); 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci pipe_loader_release(&screen->dev, 1); 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci free(screen->options.force_gl_vendor); 799bf215546Sopenharmony_ci free(screen->options.force_gl_renderer); 800bf215546Sopenharmony_ci free(screen->options.mesa_extension_override); 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci /* The caller in dri_util preserves the fd ownership */ 803bf215546Sopenharmony_ci free(screen); 804bf215546Sopenharmony_ci sPriv->driverPrivate = NULL; 805bf215546Sopenharmony_ci sPriv->extensions = NULL; 806bf215546Sopenharmony_ci} 807bf215546Sopenharmony_ci 808bf215546Sopenharmony_cistatic void 809bf215546Sopenharmony_cidri_postprocessing_init(struct dri_screen *screen) 810bf215546Sopenharmony_ci{ 811bf215546Sopenharmony_ci unsigned i; 812bf215546Sopenharmony_ci 813bf215546Sopenharmony_ci for (i = 0; i < PP_FILTERS; i++) { 814bf215546Sopenharmony_ci screen->pp_enabled[i] = driQueryOptioni(&screen->dev->option_cache, 815bf215546Sopenharmony_ci pp_filters[i].name); 816bf215546Sopenharmony_ci } 817bf215546Sopenharmony_ci} 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_cistatic void 820bf215546Sopenharmony_cidri_set_background_context(struct st_context_iface *st, 821bf215546Sopenharmony_ci struct util_queue_monitoring *queue_info) 822bf215546Sopenharmony_ci{ 823bf215546Sopenharmony_ci struct dri_context *ctx = (struct dri_context *)st->st_manager_private; 824bf215546Sopenharmony_ci const __DRIbackgroundCallableExtension *backgroundCallable = 825bf215546Sopenharmony_ci ctx->sPriv->dri2.backgroundCallable; 826bf215546Sopenharmony_ci 827bf215546Sopenharmony_ci /* Note: Mesa will only call this function if GL multithreading is enabled 828bf215546Sopenharmony_ci * We only do that if the loader exposed the __DRI_BACKGROUND_CALLABLE 829bf215546Sopenharmony_ci * extension. So we know that backgroundCallable is not NULL. 830bf215546Sopenharmony_ci */ 831bf215546Sopenharmony_ci assert(backgroundCallable); 832bf215546Sopenharmony_ci backgroundCallable->setBackgroundContext(ctx->cPriv->loaderPrivate); 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci if (ctx->hud) 835bf215546Sopenharmony_ci hud_add_queue_for_monitoring(ctx->hud, queue_info); 836bf215546Sopenharmony_ci} 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ciconst __DRIconfig ** 839bf215546Sopenharmony_cidri_init_screen_helper(struct dri_screen *screen, 840bf215546Sopenharmony_ci struct pipe_screen *pscreen) 841bf215546Sopenharmony_ci{ 842bf215546Sopenharmony_ci screen->base.screen = pscreen; 843bf215546Sopenharmony_ci screen->base.get_egl_image = dri_get_egl_image; 844bf215546Sopenharmony_ci screen->base.get_param = dri_get_param; 845bf215546Sopenharmony_ci screen->base.set_background_context = dri_set_background_context; 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci if (screen->validate_egl_image) 848bf215546Sopenharmony_ci screen->base.validate_egl_image = dri_validate_egl_image; 849bf215546Sopenharmony_ci 850bf215546Sopenharmony_ci screen->st_api = st_gl_api_create(); 851bf215546Sopenharmony_ci if (!screen->st_api) 852bf215546Sopenharmony_ci return NULL; 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) 855bf215546Sopenharmony_ci screen->target = PIPE_TEXTURE_2D; 856bf215546Sopenharmony_ci else 857bf215546Sopenharmony_ci screen->target = PIPE_TEXTURE_RECT; 858bf215546Sopenharmony_ci 859bf215546Sopenharmony_ci dri_postprocessing_init(screen); 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci screen->st_api->query_versions(screen->st_api, &screen->base, 862bf215546Sopenharmony_ci &screen->options, 863bf215546Sopenharmony_ci &screen->sPriv->max_gl_core_version, 864bf215546Sopenharmony_ci &screen->sPriv->max_gl_compat_version, 865bf215546Sopenharmony_ci &screen->sPriv->max_gl_es1_version, 866bf215546Sopenharmony_ci &screen->sPriv->max_gl_es2_version); 867bf215546Sopenharmony_ci 868bf215546Sopenharmony_ci return dri_fill_in_modes(screen); 869bf215546Sopenharmony_ci} 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ci/* vim: set sw=3 ts=8 sts=3 expandtab: */ 872