utils.c revision c1f859d4
1/* 2 * (C) Copyright IBM Corporation 2002, 2004 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file utils.c 27 * Utility functions for DRI drivers. 28 * 29 * \author Ian Romanick <idr@us.ibm.com> 30 */ 31 32#include <string.h> 33#include <stdlib.h> 34#include "main/mtypes.h" 35#include "main/extensions.h" 36#include "glapi/dispatch.h" 37#include "utils.h" 38 39int driDispatchRemapTable[ driDispatchRemapTable_size ]; 40 41#if defined(USE_X86_ASM) 42#include "x86/common_x86_asm.h" 43#endif 44 45#if defined(USE_PPC_ASM) 46#include "ppc/common_ppc_features.h" 47#endif 48 49unsigned 50driParseDebugString( const char * debug, 51 const struct dri_debug_control * control ) 52{ 53 unsigned flag; 54 55 56 flag = 0; 57 if ( debug != NULL ) { 58 while( control->string != NULL ) { 59 if ( !strcmp( debug, "all" ) || 60 strstr( debug, control->string ) != NULL ) { 61 flag |= control->flag; 62 } 63 64 control++; 65 } 66 } 67 68 return flag; 69} 70 71 72 73/** 74 * Create the \c GL_RENDERER string for DRI drivers. 75 * 76 * Almost all DRI drivers use a \c GL_RENDERER string of the form: 77 * 78 * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>" 79 * 80 * Using the supplied chip name, driver data, and AGP speed, this function 81 * creates the string. 82 * 83 * \param buffer Buffer to hold the \c GL_RENDERER string. 84 * \param hardware_name Name of the hardware. 85 * \param driver_date Driver date. 86 * \param agp_mode AGP mode (speed). 87 * 88 * \returns 89 * The length of the string stored in \c buffer. This does \b not include 90 * the terminating \c NUL character. 91 */ 92unsigned 93driGetRendererString( char * buffer, const char * hardware_name, 94 const char * driver_date, GLuint agp_mode ) 95{ 96#define MAX_INFO 4 97 const char * cpu[MAX_INFO]; 98 unsigned next = 0; 99 unsigned i; 100 unsigned offset; 101 102 103 offset = sprintf( buffer, "Mesa DRI %s %s", hardware_name, driver_date ); 104 105 /* Append any AGP-specific information. 106 */ 107 switch ( agp_mode ) { 108 case 1: 109 case 2: 110 case 4: 111 case 8: 112 offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode ); 113 break; 114 115 default: 116 break; 117 } 118 119 /* Append any CPU-specific information. 120 */ 121#ifdef USE_X86_ASM 122 if ( _mesa_x86_cpu_features ) { 123 cpu[next] = " x86"; 124 next++; 125 } 126# ifdef USE_MMX_ASM 127 if ( cpu_has_mmx ) { 128 cpu[next] = (cpu_has_mmxext) ? "/MMX+" : "/MMX"; 129 next++; 130 } 131# endif 132# ifdef USE_3DNOW_ASM 133 if ( cpu_has_3dnow ) { 134 cpu[next] = (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!"; 135 next++; 136 } 137# endif 138# ifdef USE_SSE_ASM 139 if ( cpu_has_xmm ) { 140 cpu[next] = (cpu_has_xmm2) ? "/SSE2" : "/SSE"; 141 next++; 142 } 143# endif 144 145#elif defined(USE_SPARC_ASM) 146 147 cpu[0] = " SPARC"; 148 next = 1; 149 150#elif defined(USE_PPC_ASM) 151 if ( _mesa_ppc_cpu_features ) { 152 cpu[next] = (cpu_has_64) ? " PowerPC 64" : " PowerPC"; 153 next++; 154 } 155 156# ifdef USE_VMX_ASM 157 if ( cpu_has_vmx ) { 158 cpu[next] = "/Altivec"; 159 next++; 160 } 161# endif 162 163 if ( ! cpu_has_fpu ) { 164 cpu[next] = "/No FPU"; 165 next++; 166 } 167#endif 168 169 for ( i = 0 ; i < next ; i++ ) { 170 const size_t len = strlen( cpu[i] ); 171 172 strncpy( & buffer[ offset ], cpu[i], len ); 173 offset += len; 174 } 175 176 return offset; 177} 178 179 180 181 182#define need_GL_ARB_multisample 183#define need_GL_ARB_transpose_matrix 184#define need_GL_ARB_window_pos 185#define need_GL_EXT_compiled_vertex_array 186#define need_GL_EXT_polygon_offset 187#define need_GL_EXT_texture_object 188#define need_GL_EXT_vertex_array 189#define need_GL_MESA_window_pos 190 191/* These are needed in *all* drivers because Mesa internally implements 192 * certain functionality in terms of functions provided by these extensions. 193 * For example, glBlendFunc is implemented by calling glBlendFuncSeparateEXT. 194 */ 195#define need_GL_EXT_blend_func_separate 196#define need_GL_NV_vertex_program 197 198#include "extension_helper.h" 199 200static const struct dri_extension all_mesa_extensions[] = { 201 { "GL_ARB_multisample", GL_ARB_multisample_functions }, 202 { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions }, 203 { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, 204 { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, 205 { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions }, 206 { "GL_EXT_polygon_offset", GL_EXT_polygon_offset_functions }, 207 { "GL_EXT_texture_object", GL_EXT_texture_object_functions }, 208 { "GL_EXT_vertex_array", GL_EXT_vertex_array_functions }, 209 { "GL_MESA_window_pos", GL_MESA_window_pos_functions }, 210 { "GL_NV_vertex_program", GL_NV_vertex_program_functions }, 211 { NULL, NULL } 212}; 213 214 215/** 216 * Enable extensions supported by the driver. 217 * 218 * \bug 219 * ARB_imaging isn't handled properly. In Mesa, enabling ARB_imaging also 220 * enables all the sub-extensions that are folded into it. This means that 221 * we need to add entry-points (via \c driInitSingleExtension) for those 222 * new functions here. 223 */ 224void driInitExtensions( GLcontext * ctx, 225 const struct dri_extension * extensions_to_enable, 226 GLboolean enable_imaging ) 227{ 228 static int first_time = 1; 229 unsigned i; 230 231 if ( first_time ) { 232 for ( i = 0 ; i < driDispatchRemapTable_size ; i++ ) { 233 driDispatchRemapTable[i] = -1; 234 } 235 236 first_time = 0; 237 driInitExtensions( ctx, all_mesa_extensions, GL_FALSE ); 238 } 239 240 if ( (ctx != NULL) && enable_imaging ) { 241 _mesa_enable_imaging_extensions( ctx ); 242 } 243 244 for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) { 245 driInitSingleExtension( ctx, & extensions_to_enable[i] ); 246 } 247} 248 249 250 251 252/** 253 * Enable and add dispatch functions for a single extension 254 * 255 * \param ctx Context where extension is to be enabled. 256 * \param ext Extension that is to be enabled. 257 * 258 * \sa driInitExtensions, _mesa_enable_extension, _glapi_add_entrypoint 259 * 260 * \todo 261 * Determine if it would be better to use \c strlen instead of the hardcoded 262 * for-loops. 263 */ 264void driInitSingleExtension( GLcontext * ctx, 265 const struct dri_extension * ext ) 266{ 267 unsigned i; 268 269 270 if ( ext->functions != NULL ) { 271 for ( i = 0 ; ext->functions[i].strings != NULL ; i++ ) { 272 const char * functions[16]; 273 const char * parameter_signature; 274 const char * str = ext->functions[i].strings; 275 unsigned j; 276 unsigned offset; 277 278 279 /* Separate the parameter signature from the rest of the string. 280 * If the parameter signature is empty (i.e., the string starts 281 * with a NUL character), then the function has a void parameter 282 * list. 283 */ 284 parameter_signature = str; 285 while ( str[0] != '\0' ) { 286 str++; 287 } 288 str++; 289 290 291 /* Divide the string into the substrings that name each 292 * entry-point for the function. 293 */ 294 for ( j = 0 ; j < 16 ; j++ ) { 295 if ( str[0] == '\0' ) { 296 functions[j] = NULL; 297 break; 298 } 299 300 functions[j] = str; 301 302 while ( str[0] != '\0' ) { 303 str++; 304 } 305 str++; 306 } 307 308 309 /* Add each entry-point to the dispatch table. 310 */ 311 offset = _glapi_add_dispatch( functions, parameter_signature ); 312 if (offset == -1) { 313 fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed " 314 "to add %s!\n", functions[0]); 315 } 316 else if (ext->functions[i].remap_index != -1) { 317 driDispatchRemapTable[ ext->functions[i].remap_index ] = 318 offset; 319 } 320 else if (ext->functions[i].offset != offset) { 321 fprintf(stderr, "DISPATCH ERROR! %s -> %u != %u\n", 322 functions[0], offset, ext->functions[i].offset); 323 } 324 } 325 } 326 327 if ( ctx != NULL ) { 328 _mesa_enable_extension( ctx, ext->name ); 329 } 330} 331 332 333/** 334 * Utility function used by drivers to test the verions of other components. 335 * 336 * If one of the version requirements is not met, a message is logged using 337 * \c __driUtilMessage. 338 * 339 * \param driver_name Name of the driver. Used in error messages. 340 * \param driActual Actual DRI version supplied __driCreateNewScreen. 341 * \param driExpected Minimum DRI version required by the driver. 342 * \param ddxActual Actual DDX version supplied __driCreateNewScreen. 343 * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver. 344 * \param drmActual Actual DRM version supplied __driCreateNewScreen. 345 * \param drmExpected Minimum DRM version required by the driver. 346 * 347 * \returns \c GL_TRUE if all version requirements are met. Otherwise, 348 * \c GL_FALSE is returned. 349 * 350 * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2, __driUtilMessage 351 * 352 * \todo 353 * Now that the old \c driCheckDriDdxDrmVersions function is gone, this 354 * function and \c driCheckDriDdxDrmVersions2 should be renamed. 355 */ 356GLboolean 357driCheckDriDdxDrmVersions3(const char * driver_name, 358 const __DRIversion * driActual, 359 const __DRIversion * driExpected, 360 const __DRIversion * ddxActual, 361 const __DRIutilversion2 * ddxExpected, 362 const __DRIversion * drmActual, 363 const __DRIversion * drmExpected) 364{ 365 static const char format[] = "%s DRI driver expected %s version %d.%d.x " 366 "but got version %d.%d.%d\n"; 367 static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x " 368 "but got version %d.%d.%d\n"; 369 370 371 /* Check the DRI version */ 372 if ( (driActual->major != driExpected->major) 373 || (driActual->minor < driExpected->minor) ) { 374 fprintf(stderr, format, driver_name, "DRI", 375 driExpected->major, driExpected->minor, 376 driActual->major, driActual->minor, driActual->patch); 377 return GL_FALSE; 378 } 379 380 /* Check that the DDX driver version is compatible */ 381 /* for miniglx we pass in -1 so we can ignore the DDX version */ 382 if ( (ddxActual->major != -1) && ((ddxActual->major < ddxExpected->major_min) 383 || (ddxActual->major > ddxExpected->major_max) 384 || (ddxActual->minor < ddxExpected->minor)) ) { 385 fprintf(stderr, format2, driver_name, "DDX", 386 ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor, 387 ddxActual->major, ddxActual->minor, ddxActual->patch); 388 return GL_FALSE; 389 } 390 391 /* Check that the DRM driver version is compatible */ 392 if ( (drmActual->major != drmExpected->major) 393 || (drmActual->minor < drmExpected->minor) ) { 394 fprintf(stderr, format, driver_name, "DRM", 395 drmExpected->major, drmExpected->minor, 396 drmActual->major, drmActual->minor, drmActual->patch); 397 return GL_FALSE; 398 } 399 400 return GL_TRUE; 401} 402 403GLboolean 404driCheckDriDdxDrmVersions2(const char * driver_name, 405 const __DRIversion * driActual, 406 const __DRIversion * driExpected, 407 const __DRIversion * ddxActual, 408 const __DRIversion * ddxExpected, 409 const __DRIversion * drmActual, 410 const __DRIversion * drmExpected) 411{ 412 __DRIutilversion2 ddx_expected; 413 ddx_expected.major_min = ddxExpected->major; 414 ddx_expected.major_max = ddxExpected->major; 415 ddx_expected.minor = ddxExpected->minor; 416 ddx_expected.patch = ddxExpected->patch; 417 return driCheckDriDdxDrmVersions3(driver_name, driActual, 418 driExpected, ddxActual, & ddx_expected, 419 drmActual, drmExpected); 420} 421 422GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, 423 GLint *x, GLint *y, 424 GLsizei *width, GLsizei *height ) 425{ 426 /* left clipping */ 427 if (*x < buffer->_Xmin) { 428 *width -= (buffer->_Xmin - *x); 429 *x = buffer->_Xmin; 430 } 431 432 /* right clipping */ 433 if (*x + *width > buffer->_Xmax) 434 *width -= (*x + *width - buffer->_Xmax - 1); 435 436 if (*width <= 0) 437 return GL_FALSE; 438 439 /* bottom clipping */ 440 if (*y < buffer->_Ymin) { 441 *height -= (buffer->_Ymin - *y); 442 *y = buffer->_Ymin; 443 } 444 445 /* top clipping */ 446 if (*y + *height > buffer->_Ymax) 447 *height -= (*y + *height - buffer->_Ymax - 1); 448 449 if (*height <= 0) 450 return GL_FALSE; 451 452 return GL_TRUE; 453} 454 455/** 456 * Creates a set of \c __GLcontextModes that a driver will expose. 457 * 458 * A set of \c __GLcontextModes will be created based on the supplied 459 * parameters. The number of modes processed will be 2 * 460 * \c num_depth_stencil_bits * \c num_db_modes. 461 * 462 * For the most part, data is just copied from \c depth_bits, \c stencil_bits, 463 * \c db_modes, and \c visType into each \c __GLcontextModes element. 464 * However, the meanings of \c fb_format and \c fb_type require further 465 * explanation. The \c fb_format specifies which color components are in 466 * each pixel and what the default order is. For example, \c GL_RGB specifies 467 * that red, green, blue are available and red is in the "most significant" 468 * position and blue is in the "least significant". The \c fb_type specifies 469 * the bit sizes of each component and the actual ordering. For example, if 470 * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11] 471 * are the blue value, bits [10:5] are the green value, and bits [4:0] are 472 * the red value. 473 * 474 * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either 475 * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the 476 * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or 477 * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as 478 * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8 479 * still uses 32-bits. 480 * 481 * If in doubt, look at the tables used in the function. 482 * 483 * \param ptr_to_modes Pointer to a pointer to a linked list of 484 * \c __GLcontextModes. Upon completion, a pointer to 485 * the next element to be process will be stored here. 486 * If the function fails and returns \c GL_FALSE, this 487 * value will be unmodified, but some elements in the 488 * linked list may be modified. 489 * \param fb_format Format of the framebuffer. Currently only \c GL_RGB, 490 * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported. 491 * \param fb_type Type of the pixels in the framebuffer. Currently only 492 * \c GL_UNSIGNED_SHORT_5_6_5, 493 * \c GL_UNSIGNED_SHORT_5_6_5_REV, 494 * \c GL_UNSIGNED_INT_8_8_8_8, and 495 * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported. 496 * \param depth_bits Array of depth buffer sizes to be exposed. 497 * \param stencil_bits Array of stencil buffer sizes to be exposed. 498 * \param num_depth_stencil_bits Number of entries in both \c depth_bits and 499 * \c stencil_bits. 500 * \param db_modes Array of buffer swap modes. If an element has a 501 * value of \c GLX_NONE, then it represents a 502 * single-buffered mode. Other valid values are 503 * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and 504 * \c GLX_SWAP_UNDEFINED_OML. See the 505 * GLX_OML_swap_method extension spec for more details. 506 * \param num_db_modes Number of entries in \c db_modes. 507 * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or 508 * \c GLX_DIRECT_COLOR. 509 * 510 * \returns 511 * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only 512 * cause of failure is a bad parameter (i.e., unsupported \c fb_format or 513 * \c fb_type). 514 * 515 * \todo 516 * There is currently no way to support packed RGB modes (i.e., modes with 517 * exactly 3 bytes per pixel) or floating-point modes. This could probably 518 * be done by creating some new, private enums with clever names likes 519 * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, 520 * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it. 521 */ 522__DRIconfig ** 523driCreateConfigs(GLenum fb_format, GLenum fb_type, 524 const uint8_t * depth_bits, const uint8_t * stencil_bits, 525 unsigned num_depth_stencil_bits, 526 const GLenum * db_modes, unsigned num_db_modes) 527{ 528 static const uint8_t bits_table[4][4] = { 529 /* R G B A */ 530 { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */ 531 { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */ 532 { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */ 533 { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */ 534 }; 535 536 static const uint32_t masks_table_rgb[6][4] = { 537 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ 538 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ 539 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ 540 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ 541 { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */ 542 { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */ 543 }; 544 545 static const uint32_t masks_table_rgba[6][4] = { 546 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ 547 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ 548 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ 549 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ 550 { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */ 551 { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */ 552 }; 553 554 static const uint32_t masks_table_bgr[6][4] = { 555 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ 556 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ 557 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ 558 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ 559 { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */ 560 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */ 561 }; 562 563 static const uint32_t masks_table_bgra[6][4] = { 564 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ 565 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ 566 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ 567 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ 568 { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */ 569 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */ 570 }; 571 572 static const uint8_t bytes_per_pixel[6] = { 573 1, /* 3_3_2 */ 574 1, /* 2_3_3_REV */ 575 2, /* 5_6_5 */ 576 2, /* 5_6_5_REV */ 577 4, /* 8_8_8_8 */ 578 4 /* 8_8_8_8_REV */ 579 }; 580 581 const uint8_t * bits; 582 const uint32_t * masks; 583 int index; 584 __DRIconfig **configs, **c; 585 __GLcontextModes *modes; 586 unsigned i; 587 unsigned j; 588 unsigned k; 589 unsigned num_modes; 590 unsigned num_accum_bits = 2; 591 592 switch ( fb_type ) { 593 case GL_UNSIGNED_BYTE_3_3_2: 594 index = 0; 595 break; 596 case GL_UNSIGNED_BYTE_2_3_3_REV: 597 index = 1; 598 break; 599 case GL_UNSIGNED_SHORT_5_6_5: 600 index = 2; 601 break; 602 case GL_UNSIGNED_SHORT_5_6_5_REV: 603 index = 3; 604 break; 605 case GL_UNSIGNED_INT_8_8_8_8: 606 index = 4; 607 break; 608 case GL_UNSIGNED_INT_8_8_8_8_REV: 609 index = 5; 610 break; 611 default: 612 fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n", 613 __FUNCTION__, __LINE__, fb_type ); 614 return NULL; 615 } 616 617 618 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and 619 * the _REV versions. 620 * 621 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA. 622 */ 623 624 switch ( fb_format ) { 625 case GL_RGB: 626 masks = masks_table_rgb[ index ]; 627 break; 628 629 case GL_RGBA: 630 masks = masks_table_rgba[ index ]; 631 break; 632 633 case GL_BGR: 634 masks = masks_table_bgr[ index ]; 635 break; 636 637 case GL_BGRA: 638 masks = masks_table_bgra[ index ]; 639 break; 640 641 default: 642 fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n", 643 __FUNCTION__, __LINE__, fb_format ); 644 return NULL; 645 } 646 647 switch ( bytes_per_pixel[ index ] ) { 648 case 1: 649 bits = bits_table[0]; 650 break; 651 case 2: 652 bits = bits_table[1]; 653 break; 654 default: 655 bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR)) 656 ? bits_table[2] 657 : bits_table[3]; 658 break; 659 } 660 661 num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits; 662 configs = _mesa_calloc((num_modes + 1) * sizeof *configs); 663 if (configs == NULL) 664 return NULL; 665 666 c = configs; 667 for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { 668 for ( i = 0 ; i < num_db_modes ; i++ ) { 669 for ( j = 0 ; j < num_accum_bits ; j++ ) { 670 *c = _mesa_malloc (sizeof **c); 671 modes = &(*c)->modes; 672 c++; 673 674 memset(modes, 0, sizeof *modes); 675 modes->redBits = bits[0]; 676 modes->greenBits = bits[1]; 677 modes->blueBits = bits[2]; 678 modes->alphaBits = bits[3]; 679 modes->redMask = masks[0]; 680 modes->greenMask = masks[1]; 681 modes->blueMask = masks[2]; 682 modes->alphaMask = masks[3]; 683 modes->rgbBits = modes->redBits + modes->greenBits 684 + modes->blueBits + modes->alphaBits; 685 686 modes->accumRedBits = 16 * j; 687 modes->accumGreenBits = 16 * j; 688 modes->accumBlueBits = 16 * j; 689 modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; 690 modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; 691 692 modes->stencilBits = stencil_bits[k]; 693 modes->depthBits = depth_bits[k]; 694 695 modes->transparentPixel = GLX_NONE; 696 modes->transparentRed = GLX_DONT_CARE; 697 modes->transparentGreen = GLX_DONT_CARE; 698 modes->transparentBlue = GLX_DONT_CARE; 699 modes->transparentAlpha = GLX_DONT_CARE; 700 modes->transparentIndex = GLX_DONT_CARE; 701 modes->visualType = GLX_DONT_CARE; 702 modes->renderType = GLX_RGBA_BIT; 703 modes->drawableType = GLX_WINDOW_BIT; 704 modes->rgbMode = GL_TRUE; 705 706 if ( db_modes[i] == GLX_NONE ) { 707 modes->doubleBufferMode = GL_FALSE; 708 } 709 else { 710 modes->doubleBufferMode = GL_TRUE; 711 modes->swapMethod = db_modes[i]; 712 } 713 714 modes->haveAccumBuffer = ((modes->accumRedBits + 715 modes->accumGreenBits + 716 modes->accumBlueBits + 717 modes->accumAlphaBits) > 0); 718 modes->haveDepthBuffer = (modes->depthBits > 0); 719 modes->haveStencilBuffer = (modes->stencilBits > 0); 720 721 modes->bindToTextureRgb = GL_TRUE; 722 modes->bindToTextureRgba = GL_TRUE; 723 modes->bindToMipmapTexture = GL_FALSE; 724 modes->bindToTextureTargets = modes->rgbMode ? 725 __DRI_ATTRIB_TEXTURE_1D_BIT | 726 __DRI_ATTRIB_TEXTURE_2D_BIT | 727 __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT : 728 0; 729 } 730 } 731 } 732 *c = NULL; 733 734 return configs; 735} 736 737const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b) 738{ 739 const __DRIconfig **all; 740 int i, j, index; 741 742 i = 0; 743 while (a[i] != NULL) 744 i++; 745 j = 0; 746 while (b[j] != NULL) 747 j++; 748 749 all = _mesa_malloc((i + j + 1) * sizeof *all); 750 index = 0; 751 for (i = 0; a[i] != NULL; i++) 752 all[index++] = a[i]; 753 for (j = 0; b[j] != NULL; j++) 754 all[index++] = b[j]; 755 all[index++] = NULL; 756 757 _mesa_free(a); 758 _mesa_free(b); 759 760 return all; 761} 762 763#define __ATTRIB(attrib, field) \ 764 { attrib, offsetof(__GLcontextModes, field) } 765 766static const struct { unsigned int attrib, offset; } attribMap[] = { 767 __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), 768 __ATTRIB(__DRI_ATTRIB_LEVEL, level), 769 __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), 770 __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), 771 __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), 772 __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), 773 __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), 774 __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), 775 __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), 776 __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), 777 __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), 778 __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), 779 __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), 780 __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), 781 __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), 782 __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), 783 __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), 784 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), 785 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), 786 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), 787 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), 788 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), 789 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), 790 __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode), 791 __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), 792 __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), 793 __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), 794 __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), 795 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), 796 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), 797 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), 798 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), 799 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), 800 __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), 801 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), 802 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), 803 __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), 804 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets), 805 __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), 806 807 /* The struct field doesn't matter here, these are handled by the 808 * switch in driGetConfigAttribIndex. We need them in the array 809 * so the iterator includes them though.*/ 810 __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level), 811 __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level), 812 __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level) 813}; 814 815#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) 816 817static int 818driGetConfigAttribIndex(const __DRIconfig *config, 819 unsigned int index, unsigned int *value) 820{ 821 switch (attribMap[index].attrib) { 822 case __DRI_ATTRIB_RENDER_TYPE: 823 if (config->modes.rgbMode) 824 *value = __DRI_ATTRIB_RGBA_BIT; 825 else 826 *value = __DRI_ATTRIB_COLOR_INDEX_BIT; 827 break; 828 case __DRI_ATTRIB_CONFIG_CAVEAT: 829 if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG) 830 *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG; 831 else if (config->modes.visualRating == GLX_SLOW_CONFIG) 832 *value = __DRI_ATTRIB_SLOW_BIT; 833 else 834 *value = 0; 835 break; 836 case __DRI_ATTRIB_SWAP_METHOD: 837 break; 838 839 case __DRI_ATTRIB_FLOAT_MODE: 840 *value = config->modes.floatMode; 841 break; 842 843 default: 844 *value = *(unsigned int *) 845 ((char *) &config->modes + attribMap[index].offset); 846 847 break; 848 } 849 850 return GL_TRUE; 851} 852 853int 854driGetConfigAttrib(const __DRIconfig *config, 855 unsigned int attrib, unsigned int *value) 856{ 857 int i; 858 859 for (i = 0; i < ARRAY_SIZE(attribMap); i++) 860 if (attribMap[i].attrib == attrib) 861 return driGetConfigAttribIndex(config, i, value); 862 863 return GL_FALSE; 864} 865 866int 867driIndexConfigAttrib(const __DRIconfig *config, int index, 868 unsigned int *attrib, unsigned int *value) 869{ 870 if (index >= 0 && index < ARRAY_SIZE(attribMap)) { 871 *attrib = attribMap[index].attrib; 872 return driGetConfigAttribIndex(config, index, value); 873 } 874 875 return GL_FALSE; 876} 877