[27866] | 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 "mtypes.h"
|
---|
| 35 | #include "extensions.h"
|
---|
| 36 | #include "utils.h"
|
---|
| 37 | #include "dispatch.h"
|
---|
| 38 |
|
---|
| 39 | int 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 |
|
---|
| 49 | unsigned
|
---|
| 50 | driParseDebugString( 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 | */
|
---|
| 92 | unsigned
|
---|
| 93 | driGetRendererString( 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 |
|
---|
| 200 | static 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 | */
|
---|
| 224 | void 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 | */
|
---|
| 264 | void 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 | /**
|
---|
[33540] | 334 | * Utility function used by drivers to test the versions of other components.
|
---|
[27866] | 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 | */
|
---|
| 356 | GLboolean
|
---|
| 357 | driCheckDriDdxDrmVersions3(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 |
|
---|
| 403 | GLboolean
|
---|
| 404 | driCheckDriDdxDrmVersions2(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 |
|
---|
| 422 | GLboolean 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 | *
|
---|
[33540] | 474 | * One subtle issue is the combination of \c GL_RGB or \c GL_BGR and either
|
---|
[27866] | 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 **
|
---|
| 523 | driCreateConfigs(GLenum fb_format, GLenum fb_type,
|
---|
| 524 | const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
|
---|
| 525 | unsigned num_depth_stencil_bits,
|
---|
| 526 | const GLenum * db_modes, unsigned num_db_modes)
|
---|
| 527 | {
|
---|
| 528 | static const u_int8_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 u_int32_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 u_int32_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 u_int32_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 u_int32_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 u_int8_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 u_int8_t * bits;
|
---|
| 582 | const u_int32_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 |
|
---|
| 737 | const __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 |
|
---|
| 766 | static 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 |
|
---|
| 817 | static int
|
---|
| 818 | driGetConfigAttribIndex(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 |
|
---|
| 853 | int
|
---|
| 854 | driGetConfigAttrib(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 |
|
---|
| 866 | int
|
---|
| 867 | driIndexConfigAttrib(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 | }
|
---|