1848b8605Smrg/* 2848b8605Smrg * (C) Copyright IBM Corporation 2002, 2004 3848b8605Smrg * All Rights Reserved. 4848b8605Smrg * 5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6848b8605Smrg * copy of this software and associated documentation files (the "Software"), 7848b8605Smrg * to deal in the Software without restriction, including without limitation 8848b8605Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 9848b8605Smrg * license, and/or sell copies of the Software, and to permit persons to whom 10848b8605Smrg * the Software is furnished to do so, subject to the following conditions: 11848b8605Smrg * 12848b8605Smrg * The above copyright notice and this permission notice (including the next 13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 14848b8605Smrg * Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg/** 26848b8605Smrg * \file utils.c 27848b8605Smrg * Utility functions for DRI drivers. 28848b8605Smrg * 29848b8605Smrg * \author Ian Romanick <idr@us.ibm.com> 30848b8605Smrg */ 31848b8605Smrg 32848b8605Smrg#include <string.h> 33b8e80941Smrg#include <stdio.h> 34848b8605Smrg#include <stdlib.h> 35848b8605Smrg#include <stdbool.h> 36848b8605Smrg#include <stdint.h> 37848b8605Smrg#include "main/macros.h" 38848b8605Smrg#include "main/mtypes.h" 39848b8605Smrg#include "main/cpuinfo.h" 40848b8605Smrg#include "main/extensions.h" 41848b8605Smrg#include "utils.h" 42848b8605Smrg#include "dri_util.h" 43848b8605Smrg 44b8e80941Smrg/* WARNING: HACK: Local defines to avoid pulling glx.h. 45b8e80941Smrg * 46b8e80941Smrg * Any parts of this file that use the following defines are either partial or 47b8e80941Smrg * entirely broken wrt EGL. 48b8e80941Smrg * 49b8e80941Smrg * For example any getConfigAttrib() or indexConfigAttrib() query from EGL for 50b8e80941Smrg * SLOW or NON_CONFORMANT_CONFIG will not work as expected since the EGL tokens 51b8e80941Smrg * are different from the GLX ones. 52b8e80941Smrg */ 53b8e80941Smrg#define GLX_NONE 0x8000 54b8e80941Smrg#define GLX_SLOW_CONFIG 0x8001 55b8e80941Smrg#define GLX_NON_CONFORMANT_CONFIG 0x800D 56b8e80941Smrg#define GLX_DONT_CARE 0xFFFFFFFF 57848b8605Smrg 58848b8605Smrg/** 59848b8605Smrg * Create the \c GL_RENDERER string for DRI drivers. 60848b8605Smrg * 61848b8605Smrg * Almost all DRI drivers use a \c GL_RENDERER string of the form: 62848b8605Smrg * 63848b8605Smrg * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>" 64848b8605Smrg * 65848b8605Smrg * Using the supplied chip name, driver data, and AGP speed, this function 66848b8605Smrg * creates the string. 67848b8605Smrg * 68848b8605Smrg * \param buffer Buffer to hold the \c GL_RENDERER string. 69848b8605Smrg * \param hardware_name Name of the hardware. 70848b8605Smrg * \param agp_mode AGP mode (speed). 71848b8605Smrg * 72848b8605Smrg * \returns 73848b8605Smrg * The length of the string stored in \c buffer. This does \b not include 74848b8605Smrg * the terminating \c NUL character. 75848b8605Smrg */ 76848b8605Smrgunsigned 77848b8605SmrgdriGetRendererString( char * buffer, const char * hardware_name, 78848b8605Smrg GLuint agp_mode ) 79848b8605Smrg{ 80848b8605Smrg unsigned offset; 81848b8605Smrg char *cpu; 82848b8605Smrg 83848b8605Smrg offset = sprintf( buffer, "Mesa DRI %s", hardware_name ); 84848b8605Smrg 85848b8605Smrg /* Append any AGP-specific information. 86848b8605Smrg */ 87848b8605Smrg switch ( agp_mode ) { 88848b8605Smrg case 1: 89848b8605Smrg case 2: 90848b8605Smrg case 4: 91848b8605Smrg case 8: 92848b8605Smrg offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode ); 93848b8605Smrg break; 94848b8605Smrg 95848b8605Smrg default: 96848b8605Smrg break; 97848b8605Smrg } 98848b8605Smrg 99848b8605Smrg /* Append any CPU-specific information. 100848b8605Smrg */ 101848b8605Smrg cpu = _mesa_get_cpu_string(); 102848b8605Smrg if (cpu) { 103848b8605Smrg offset += sprintf(buffer + offset, " %s", cpu); 104848b8605Smrg free(cpu); 105848b8605Smrg } 106848b8605Smrg 107848b8605Smrg return offset; 108848b8605Smrg} 109848b8605Smrg 110848b8605Smrg 111848b8605Smrg/** 112848b8605Smrg * Creates a set of \c struct gl_config that a driver will expose. 113848b8605Smrg * 114848b8605Smrg * A set of \c struct gl_config will be created based on the supplied 115848b8605Smrg * parameters. The number of modes processed will be 2 * 116848b8605Smrg * \c num_depth_stencil_bits * \c num_db_modes. 117848b8605Smrg * 118848b8605Smrg * For the most part, data is just copied from \c depth_bits, \c stencil_bits, 119848b8605Smrg * \c db_modes, and \c visType into each \c struct gl_config element. 120848b8605Smrg * However, the meanings of \c fb_format and \c fb_type require further 121848b8605Smrg * explanation. The \c fb_format specifies which color components are in 122848b8605Smrg * each pixel and what the default order is. For example, \c GL_RGB specifies 123848b8605Smrg * that red, green, blue are available and red is in the "most significant" 124848b8605Smrg * position and blue is in the "least significant". The \c fb_type specifies 125848b8605Smrg * the bit sizes of each component and the actual ordering. For example, if 126848b8605Smrg * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11] 127848b8605Smrg * are the blue value, bits [10:5] are the green value, and bits [4:0] are 128848b8605Smrg * the red value. 129848b8605Smrg * 130848b8605Smrg * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either 131848b8605Smrg * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the 132848b8605Smrg * \c struct gl_config structure is \b identical to the \c GL_RGBA or 133848b8605Smrg * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as 134848b8605Smrg * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8 135848b8605Smrg * still uses 32-bits. 136848b8605Smrg * 137848b8605Smrg * If in doubt, look at the tables used in the function. 138848b8605Smrg * 139848b8605Smrg * \param ptr_to_modes Pointer to a pointer to a linked list of 140848b8605Smrg * \c struct gl_config. Upon completion, a pointer to 141848b8605Smrg * the next element to be process will be stored here. 142848b8605Smrg * If the function fails and returns \c GL_FALSE, this 143848b8605Smrg * value will be unmodified, but some elements in the 144848b8605Smrg * linked list may be modified. 145848b8605Smrg * \param format Mesa mesa_format enum describing the pixel format 146848b8605Smrg * \param depth_bits Array of depth buffer sizes to be exposed. 147848b8605Smrg * \param stencil_bits Array of stencil buffer sizes to be exposed. 148848b8605Smrg * \param num_depth_stencil_bits Number of entries in both \c depth_bits and 149848b8605Smrg * \c stencil_bits. 150848b8605Smrg * \param db_modes Array of buffer swap modes. If an element has a 151b8e80941Smrg * value of \c __DRI_ATTRIB_SWAP_NONE, then it 152b8e80941Smrg * represents a single-buffered mode. Other valid 153b8e80941Smrg * values are \c __DRI_ATTRIB_SWAP_EXCHANGE, 154b8e80941Smrg * \c __DRI_ATTRIB_SWAP_COPY, and \c __DRI_ATTRIB_SWAP_UNDEFINED. 155b8e80941Smrg * They represent the respective GLX values as in 156b8e80941Smrg * the GLX_OML_swap_method extension spec. 157848b8605Smrg * \param num_db_modes Number of entries in \c db_modes. 158848b8605Smrg * \param msaa_samples Array of msaa sample count. 0 represents a visual 159848b8605Smrg * without a multisample buffer. 160848b8605Smrg * \param num_msaa_modes Number of entries in \c msaa_samples. 161b8e80941Smrg * \param enable_accum Add an accum buffer to the configs 162b8e80941Smrg * \param color_depth_match Whether the color depth must match the zs depth 163b8e80941Smrg * This forces 32-bit color to have 24-bit depth, and 164b8e80941Smrg * 16-bit color to have 16-bit depth. 165b8e80941Smrg * \param mutable_render_buffer Enable __DRI_ATTRIB_MUTABLE_RENDER_BUFFER, 166b8e80941Smrg * which translates to 167b8e80941Smrg * EGL_MUTABLE_RENDER_BUFFER_BIT_KHR. 168b8e80941Smrg * 169848b8605Smrg * \returns 170848b8605Smrg * Pointer to any array of pointers to the \c __DRIconfig structures created 171848b8605Smrg * for the specified formats. If there is an error, \c NULL is returned. 172848b8605Smrg * Currently the only cause of failure is a bad parameter (i.e., unsupported 173848b8605Smrg * \c format). 174848b8605Smrg */ 175848b8605Smrg__DRIconfig ** 176848b8605SmrgdriCreateConfigs(mesa_format format, 177848b8605Smrg const uint8_t * depth_bits, const uint8_t * stencil_bits, 178848b8605Smrg unsigned num_depth_stencil_bits, 179848b8605Smrg const GLenum * db_modes, unsigned num_db_modes, 180848b8605Smrg const uint8_t * msaa_samples, unsigned num_msaa_modes, 181b8e80941Smrg GLboolean enable_accum, GLboolean color_depth_match, 182b8e80941Smrg GLboolean mutable_render_buffer) 183848b8605Smrg{ 184848b8605Smrg static const uint32_t masks_table[][4] = { 185848b8605Smrg /* MESA_FORMAT_B5G6R5_UNORM */ 186848b8605Smrg { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, 187848b8605Smrg /* MESA_FORMAT_B8G8R8X8_UNORM */ 188848b8605Smrg { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, 189848b8605Smrg /* MESA_FORMAT_B8G8R8A8_UNORM */ 190848b8605Smrg { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, 191848b8605Smrg /* MESA_FORMAT_B10G10R10X2_UNORM */ 192848b8605Smrg { 0x3FF00000, 0x000FFC00, 0x000003FF, 0x00000000 }, 193848b8605Smrg /* MESA_FORMAT_B10G10R10A2_UNORM */ 194848b8605Smrg { 0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000 }, 195b8e80941Smrg /* MESA_FORMAT_R8G8B8A8_UNORM */ 196b8e80941Smrg { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, 197b8e80941Smrg /* MESA_FORMAT_R8G8B8X8_UNORM */ 198b8e80941Smrg { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }, 199b8e80941Smrg /* MESA_FORMAT_R10G10B10X2_UNORM */ 200b8e80941Smrg { 0x000003FF, 0x000FFC00, 0x3FF00000, 0x00000000 }, 201b8e80941Smrg /* MESA_FORMAT_R10G10B10A2_UNORM */ 202b8e80941Smrg { 0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000 }, 203848b8605Smrg }; 204848b8605Smrg 205848b8605Smrg const uint32_t * masks; 206848b8605Smrg __DRIconfig **configs, **c; 207848b8605Smrg struct gl_config *modes; 208848b8605Smrg unsigned i, j, k, h; 209848b8605Smrg unsigned num_modes; 210848b8605Smrg unsigned num_accum_bits = (enable_accum) ? 2 : 1; 211848b8605Smrg int red_bits; 212848b8605Smrg int green_bits; 213848b8605Smrg int blue_bits; 214848b8605Smrg int alpha_bits; 215848b8605Smrg bool is_srgb; 216848b8605Smrg 217848b8605Smrg switch (format) { 218848b8605Smrg case MESA_FORMAT_B5G6R5_UNORM: 219848b8605Smrg masks = masks_table[0]; 220848b8605Smrg break; 221848b8605Smrg case MESA_FORMAT_B8G8R8X8_UNORM: 222b8e80941Smrg case MESA_FORMAT_B8G8R8X8_SRGB: 223848b8605Smrg masks = masks_table[1]; 224848b8605Smrg break; 225848b8605Smrg case MESA_FORMAT_B8G8R8A8_UNORM: 226848b8605Smrg case MESA_FORMAT_B8G8R8A8_SRGB: 227848b8605Smrg masks = masks_table[2]; 228848b8605Smrg break; 229b8e80941Smrg case MESA_FORMAT_R8G8B8A8_UNORM: 230b8e80941Smrg case MESA_FORMAT_R8G8B8A8_SRGB: 231b8e80941Smrg masks = masks_table[5]; 232b8e80941Smrg break; 233b8e80941Smrg case MESA_FORMAT_R8G8B8X8_UNORM: 234b8e80941Smrg masks = masks_table[6]; 235b8e80941Smrg break; 236848b8605Smrg case MESA_FORMAT_B10G10R10X2_UNORM: 237848b8605Smrg masks = masks_table[3]; 238848b8605Smrg break; 239848b8605Smrg case MESA_FORMAT_B10G10R10A2_UNORM: 240848b8605Smrg masks = masks_table[4]; 241848b8605Smrg break; 242b8e80941Smrg case MESA_FORMAT_R10G10B10X2_UNORM: 243b8e80941Smrg masks = masks_table[7]; 244b8e80941Smrg break; 245b8e80941Smrg case MESA_FORMAT_R10G10B10A2_UNORM: 246b8e80941Smrg masks = masks_table[8]; 247b8e80941Smrg break; 248848b8605Smrg default: 249848b8605Smrg fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n", 250b8e80941Smrg __func__, __LINE__, 251848b8605Smrg _mesa_get_format_name(format), format); 252848b8605Smrg return NULL; 253848b8605Smrg } 254848b8605Smrg 255848b8605Smrg red_bits = _mesa_get_format_bits(format, GL_RED_BITS); 256848b8605Smrg green_bits = _mesa_get_format_bits(format, GL_GREEN_BITS); 257848b8605Smrg blue_bits = _mesa_get_format_bits(format, GL_BLUE_BITS); 258848b8605Smrg alpha_bits = _mesa_get_format_bits(format, GL_ALPHA_BITS); 259848b8605Smrg is_srgb = _mesa_get_format_color_encoding(format) == GL_SRGB; 260848b8605Smrg 261848b8605Smrg num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes; 262b8e80941Smrg configs = calloc(num_modes + 1, sizeof *configs); 263848b8605Smrg if (configs == NULL) 264848b8605Smrg return NULL; 265848b8605Smrg 266848b8605Smrg c = configs; 267848b8605Smrg for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { 268848b8605Smrg for ( i = 0 ; i < num_db_modes ; i++ ) { 269848b8605Smrg for ( h = 0 ; h < num_msaa_modes; h++ ) { 270848b8605Smrg for ( j = 0 ; j < num_accum_bits ; j++ ) { 271b8e80941Smrg if (color_depth_match && 272b8e80941Smrg (depth_bits[k] || stencil_bits[k])) { 273b8e80941Smrg /* Depth can really only be 0, 16, 24, or 32. A 32-bit 274b8e80941Smrg * color format still matches 24-bit depth, as there 275b8e80941Smrg * is an implicit 8-bit stencil. So really we just 276b8e80941Smrg * need to make sure that color/depth are both 16 or 277b8e80941Smrg * both non-16. 278b8e80941Smrg */ 279b8e80941Smrg if ((depth_bits[k] + stencil_bits[k] == 16) != 280b8e80941Smrg (red_bits + green_bits + blue_bits + alpha_bits == 16)) 281b8e80941Smrg continue; 282b8e80941Smrg } 283b8e80941Smrg 284848b8605Smrg *c = malloc (sizeof **c); 285848b8605Smrg modes = &(*c)->modes; 286848b8605Smrg c++; 287848b8605Smrg 288848b8605Smrg memset(modes, 0, sizeof *modes); 289848b8605Smrg modes->redBits = red_bits; 290848b8605Smrg modes->greenBits = green_bits; 291848b8605Smrg modes->blueBits = blue_bits; 292848b8605Smrg modes->alphaBits = alpha_bits; 293848b8605Smrg modes->redMask = masks[0]; 294848b8605Smrg modes->greenMask = masks[1]; 295848b8605Smrg modes->blueMask = masks[2]; 296848b8605Smrg modes->alphaMask = masks[3]; 297848b8605Smrg modes->rgbBits = modes->redBits + modes->greenBits 298848b8605Smrg + modes->blueBits + modes->alphaBits; 299848b8605Smrg 300848b8605Smrg modes->accumRedBits = 16 * j; 301848b8605Smrg modes->accumGreenBits = 16 * j; 302848b8605Smrg modes->accumBlueBits = 16 * j; 303848b8605Smrg modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; 304848b8605Smrg modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; 305848b8605Smrg 306848b8605Smrg modes->stencilBits = stencil_bits[k]; 307848b8605Smrg modes->depthBits = depth_bits[k]; 308848b8605Smrg 309848b8605Smrg modes->transparentPixel = GLX_NONE; 310848b8605Smrg modes->transparentRed = GLX_DONT_CARE; 311848b8605Smrg modes->transparentGreen = GLX_DONT_CARE; 312848b8605Smrg modes->transparentBlue = GLX_DONT_CARE; 313848b8605Smrg modes->transparentAlpha = GLX_DONT_CARE; 314848b8605Smrg modes->transparentIndex = GLX_DONT_CARE; 315848b8605Smrg modes->rgbMode = GL_TRUE; 316848b8605Smrg 317b8e80941Smrg if (db_modes[i] == __DRI_ATTRIB_SWAP_NONE) { 318848b8605Smrg modes->doubleBufferMode = GL_FALSE; 319b8e80941Smrg modes->swapMethod = __DRI_ATTRIB_SWAP_UNDEFINED; 320848b8605Smrg } 321848b8605Smrg else { 322848b8605Smrg modes->doubleBufferMode = GL_TRUE; 323848b8605Smrg modes->swapMethod = db_modes[i]; 324848b8605Smrg } 325848b8605Smrg 326848b8605Smrg modes->samples = msaa_samples[h]; 327848b8605Smrg modes->sampleBuffers = modes->samples ? 1 : 0; 328848b8605Smrg 329848b8605Smrg 330848b8605Smrg modes->haveAccumBuffer = ((modes->accumRedBits + 331848b8605Smrg modes->accumGreenBits + 332848b8605Smrg modes->accumBlueBits + 333848b8605Smrg modes->accumAlphaBits) > 0); 334848b8605Smrg modes->haveDepthBuffer = (modes->depthBits > 0); 335848b8605Smrg modes->haveStencilBuffer = (modes->stencilBits > 0); 336848b8605Smrg 337848b8605Smrg modes->bindToTextureRgb = GL_TRUE; 338848b8605Smrg modes->bindToTextureRgba = GL_TRUE; 339848b8605Smrg modes->bindToMipmapTexture = GL_FALSE; 340848b8605Smrg modes->bindToTextureTargets = 341848b8605Smrg __DRI_ATTRIB_TEXTURE_1D_BIT | 342848b8605Smrg __DRI_ATTRIB_TEXTURE_2D_BIT | 343848b8605Smrg __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT; 344848b8605Smrg 345848b8605Smrg modes->yInverted = GL_TRUE; 346848b8605Smrg modes->sRGBCapable = is_srgb; 347b8e80941Smrg modes->mutableRenderBuffer = mutable_render_buffer; 348848b8605Smrg } 349848b8605Smrg } 350848b8605Smrg } 351848b8605Smrg } 352848b8605Smrg *c = NULL; 353848b8605Smrg 354848b8605Smrg return configs; 355848b8605Smrg} 356848b8605Smrg 357848b8605Smrg__DRIconfig **driConcatConfigs(__DRIconfig **a, 358848b8605Smrg __DRIconfig **b) 359848b8605Smrg{ 360848b8605Smrg __DRIconfig **all; 361848b8605Smrg int i, j, index; 362848b8605Smrg 363848b8605Smrg if (a == NULL || a[0] == NULL) 364848b8605Smrg return b; 365848b8605Smrg else if (b == NULL || b[0] == NULL) 366848b8605Smrg return a; 367848b8605Smrg 368848b8605Smrg i = 0; 369848b8605Smrg while (a[i] != NULL) 370848b8605Smrg i++; 371848b8605Smrg j = 0; 372848b8605Smrg while (b[j] != NULL) 373848b8605Smrg j++; 374848b8605Smrg 375848b8605Smrg all = malloc((i + j + 1) * sizeof *all); 376848b8605Smrg index = 0; 377848b8605Smrg for (i = 0; a[i] != NULL; i++) 378848b8605Smrg all[index++] = a[i]; 379848b8605Smrg for (j = 0; b[j] != NULL; j++) 380848b8605Smrg all[index++] = b[j]; 381848b8605Smrg all[index++] = NULL; 382848b8605Smrg 383848b8605Smrg free(a); 384848b8605Smrg free(b); 385848b8605Smrg 386848b8605Smrg return all; 387848b8605Smrg} 388848b8605Smrg 389848b8605Smrg#define __ATTRIB(attrib, field) \ 390848b8605Smrg { attrib, offsetof(struct gl_config, field) } 391848b8605Smrg 392848b8605Smrgstatic const struct { unsigned int attrib, offset; } attribMap[] = { 393848b8605Smrg __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), 394848b8605Smrg __ATTRIB(__DRI_ATTRIB_LEVEL, level), 395848b8605Smrg __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), 396848b8605Smrg __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), 397848b8605Smrg __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), 398848b8605Smrg __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), 399848b8605Smrg __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), 400848b8605Smrg __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), 401848b8605Smrg __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), 402848b8605Smrg __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), 403848b8605Smrg __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), 404848b8605Smrg __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), 405848b8605Smrg __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), 406848b8605Smrg __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), 407848b8605Smrg __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), 408848b8605Smrg __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), 409848b8605Smrg __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), 410848b8605Smrg __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), 411848b8605Smrg __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), 412848b8605Smrg __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), 413848b8605Smrg __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), 414848b8605Smrg __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), 415848b8605Smrg __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), 416848b8605Smrg __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), 417848b8605Smrg __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), 418848b8605Smrg __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), 419848b8605Smrg __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), 420848b8605Smrg __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), 421848b8605Smrg __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), 422848b8605Smrg __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), 423848b8605Smrg __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), 424848b8605Smrg __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), 425848b8605Smrg __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), 426848b8605Smrg __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), 427848b8605Smrg __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), 428848b8605Smrg __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), 429848b8605Smrg __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets), 430848b8605Smrg __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), 431848b8605Smrg __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable), 432b8e80941Smrg __ATTRIB(__DRI_ATTRIB_MUTABLE_RENDER_BUFFER, mutableRenderBuffer), 433848b8605Smrg 434848b8605Smrg /* The struct field doesn't matter here, these are handled by the 435848b8605Smrg * switch in driGetConfigAttribIndex. We need them in the array 436848b8605Smrg * so the iterator includes them though.*/ 437848b8605Smrg __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level), 438848b8605Smrg __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level), 439848b8605Smrg}; 440848b8605Smrg 441848b8605Smrg 442848b8605Smrg/** 443848b8605Smrg * Return the value of a configuration attribute. The attribute is 444848b8605Smrg * indicated by the index. 445848b8605Smrg */ 446848b8605Smrgstatic int 447848b8605SmrgdriGetConfigAttribIndex(const __DRIconfig *config, 448848b8605Smrg unsigned int index, unsigned int *value) 449848b8605Smrg{ 450848b8605Smrg switch (attribMap[index].attrib) { 451848b8605Smrg case __DRI_ATTRIB_RENDER_TYPE: 452848b8605Smrg /* no support for color index mode */ 453848b8605Smrg *value = __DRI_ATTRIB_RGBA_BIT; 454848b8605Smrg break; 455848b8605Smrg case __DRI_ATTRIB_CONFIG_CAVEAT: 456848b8605Smrg if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG) 457848b8605Smrg *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG; 458848b8605Smrg else if (config->modes.visualRating == GLX_SLOW_CONFIG) 459848b8605Smrg *value = __DRI_ATTRIB_SLOW_BIT; 460848b8605Smrg else 461848b8605Smrg *value = 0; 462848b8605Smrg break; 463848b8605Smrg default: 464848b8605Smrg /* any other int-sized field */ 465848b8605Smrg *value = *(unsigned int *) 466848b8605Smrg ((char *) &config->modes + attribMap[index].offset); 467848b8605Smrg 468848b8605Smrg break; 469848b8605Smrg } 470848b8605Smrg 471848b8605Smrg return GL_TRUE; 472848b8605Smrg} 473848b8605Smrg 474848b8605Smrg 475848b8605Smrg/** 476848b8605Smrg * Get the value of a configuration attribute. 477848b8605Smrg * \param attrib the attribute (one of the _DRI_ATTRIB_x tokens) 478848b8605Smrg * \param value returns the attribute's value 479848b8605Smrg * \return 1 for success, 0 for failure 480848b8605Smrg */ 481848b8605Smrgint 482848b8605SmrgdriGetConfigAttrib(const __DRIconfig *config, 483848b8605Smrg unsigned int attrib, unsigned int *value) 484848b8605Smrg{ 485b8e80941Smrg unsigned i; 486848b8605Smrg 487848b8605Smrg for (i = 0; i < ARRAY_SIZE(attribMap); i++) 488848b8605Smrg if (attribMap[i].attrib == attrib) 489848b8605Smrg return driGetConfigAttribIndex(config, i, value); 490848b8605Smrg 491848b8605Smrg return GL_FALSE; 492848b8605Smrg} 493848b8605Smrg 494848b8605Smrg 495848b8605Smrg/** 496848b8605Smrg * Get a configuration attribute name and value, given an index. 497848b8605Smrg * \param index which field of the __DRIconfig to query 498848b8605Smrg * \param attrib returns the attribute name (one of the _DRI_ATTRIB_x tokens) 499848b8605Smrg * \param value returns the attribute's value 500848b8605Smrg * \return 1 for success, 0 for failure 501848b8605Smrg */ 502848b8605Smrgint 503848b8605SmrgdriIndexConfigAttrib(const __DRIconfig *config, int index, 504848b8605Smrg unsigned int *attrib, unsigned int *value) 505848b8605Smrg{ 506848b8605Smrg if (index >= 0 && index < ARRAY_SIZE(attribMap)) { 507848b8605Smrg *attrib = attribMap[index].attrib; 508848b8605Smrg return driGetConfigAttribIndex(config, index, value); 509848b8605Smrg } 510848b8605Smrg 511848b8605Smrg return GL_FALSE; 512848b8605Smrg} 513848b8605Smrg 514848b8605Smrg/** 515848b8605Smrg * Implement queries for values that are common across all Mesa drivers 516848b8605Smrg * 517848b8605Smrg * Currently only the following queries are supported by this function: 518848b8605Smrg * 519848b8605Smrg * - \c __DRI2_RENDERER_VERSION 520b8e80941Smrg * - \c __DRI2_RENDERER_PREFERRED_PROFILE 521848b8605Smrg * - \c __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION 522848b8605Smrg * - \c __DRI2_RENDERER_OPENGL_COMPATIBLITY_PROFILE_VERSION 523848b8605Smrg * - \c __DRI2_RENDERER_ES_PROFILE_VERSION 524848b8605Smrg * - \c __DRI2_RENDERER_ES2_PROFILE_VERSION 525848b8605Smrg * 526848b8605Smrg * \returns 527848b8605Smrg * Zero if a recognized value of \c param is supplied, -1 otherwise. 528848b8605Smrg */ 529848b8605Smrgint 530848b8605SmrgdriQueryRendererIntegerCommon(__DRIscreen *psp, int param, unsigned int *value) 531848b8605Smrg{ 532848b8605Smrg switch (param) { 533848b8605Smrg case __DRI2_RENDERER_VERSION: { 534848b8605Smrg static const char *const ver = PACKAGE_VERSION; 535848b8605Smrg char *endptr; 536848b8605Smrg int v[3]; 537848b8605Smrg 538848b8605Smrg v[0] = strtol(ver, &endptr, 10); 539848b8605Smrg assert(endptr[0] == '.'); 540848b8605Smrg if (endptr[0] != '.') 541848b8605Smrg return -1; 542848b8605Smrg 543848b8605Smrg v[1] = strtol(endptr + 1, &endptr, 10); 544848b8605Smrg assert(endptr[0] == '.'); 545848b8605Smrg if (endptr[0] != '.') 546848b8605Smrg return -1; 547848b8605Smrg 548848b8605Smrg v[2] = strtol(endptr + 1, &endptr, 10); 549848b8605Smrg 550848b8605Smrg value[0] = v[0]; 551848b8605Smrg value[1] = v[1]; 552848b8605Smrg value[2] = v[2]; 553848b8605Smrg return 0; 554848b8605Smrg } 555848b8605Smrg case __DRI2_RENDERER_PREFERRED_PROFILE: 556848b8605Smrg value[0] = (psp->max_gl_core_version != 0) 557848b8605Smrg ? (1U << __DRI_API_OPENGL_CORE) : (1U << __DRI_API_OPENGL); 558848b8605Smrg return 0; 559848b8605Smrg case __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION: 560848b8605Smrg value[0] = psp->max_gl_core_version / 10; 561848b8605Smrg value[1] = psp->max_gl_core_version % 10; 562848b8605Smrg return 0; 563848b8605Smrg case __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION: 564848b8605Smrg value[0] = psp->max_gl_compat_version / 10; 565848b8605Smrg value[1] = psp->max_gl_compat_version % 10; 566848b8605Smrg return 0; 567848b8605Smrg case __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION: 568848b8605Smrg value[0] = psp->max_gl_es1_version / 10; 569848b8605Smrg value[1] = psp->max_gl_es1_version % 10; 570848b8605Smrg return 0; 571848b8605Smrg case __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION: 572848b8605Smrg value[0] = psp->max_gl_es2_version / 10; 573848b8605Smrg value[1] = psp->max_gl_es2_version % 10; 574848b8605Smrg return 0; 575848b8605Smrg default: 576848b8605Smrg break; 577848b8605Smrg } 578848b8605Smrg 579848b8605Smrg return -1; 580848b8605Smrg} 581