2 * (C) Copyright IBM Corporation 2002, 2004
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:
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
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.
27 * Utility functions for DRI drivers.
29 * \author Ian Romanick <idr@us.ibm.com>
34 #include "main/mtypes.h"
35 #include "main/cpuinfo.h"
36 #include "main/extensions.h"
37 #include "glapi/dispatch.h"
41 int driDispatchRemapTable
[ driDispatchRemapTable_size
];
45 driParseDebugString( const char * debug
,
46 const struct dri_debug_control
* control
)
52 if ( debug
!= NULL
) {
53 while( control
->string
!= NULL
) {
54 if ( !strcmp( debug
, "all" ) ||
55 strstr( debug
, control
->string
) != NULL
) {
56 flag
|= control
->flag
;
69 * Create the \c GL_RENDERER string for DRI drivers.
71 * Almost all DRI drivers use a \c GL_RENDERER string of the form:
73 * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
75 * Using the supplied chip name, driver data, and AGP speed, this function
78 * \param buffer Buffer to hold the \c GL_RENDERER string.
79 * \param hardware_name Name of the hardware.
80 * \param driver_date Driver date.
81 * \param agp_mode AGP mode (speed).
84 * The length of the string stored in \c buffer. This does \b not include
85 * the terminating \c NUL character.
88 driGetRendererString( char * buffer
, const char * hardware_name
,
89 const char * driver_date
, GLuint agp_mode
)
94 offset
= sprintf( buffer
, "Mesa DRI %s %s", hardware_name
, driver_date
);
96 /* Append any AGP-specific information.
103 offset
+= sprintf( & buffer
[ offset
], " AGP %ux", agp_mode
);
110 /* Append any CPU-specific information.
112 cpu
= _mesa_get_cpu_string();
114 offset
+= sprintf(buffer
+ offset
, " %s", cpu
);
124 #define need_GL_ARB_draw_buffers
125 #define need_GL_ARB_multisample
126 #define need_GL_ARB_texture_compression
127 #define need_GL_ARB_transpose_matrix
128 #define need_GL_ARB_vertex_buffer_object
129 #define need_GL_ARB_window_pos
130 #define need_GL_EXT_compiled_vertex_array
131 #define need_GL_EXT_multi_draw_arrays
132 #define need_GL_EXT_polygon_offset
133 #define need_GL_EXT_texture_object
134 #define need_GL_EXT_vertex_array
135 #define need_GL_IBM_multimode_draw_arrays
136 #define need_GL_MESA_window_pos
138 /* These are needed in *all* drivers because Mesa internally implements
139 * certain functionality in terms of functions provided by these extensions.
140 * For example, glBlendFunc is implemented by calling glBlendFuncSeparateEXT.
142 #define need_GL_EXT_blend_func_separate
143 #define need_GL_NV_vertex_program
145 #include "extension_helper.h"
147 static const struct dri_extension all_mesa_extensions
[] = {
148 { "GL_ARB_draw_buffers", GL_ARB_draw_buffers_functions
},
149 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
150 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions
},
151 { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions
},
152 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions
},
153 { "GL_ARB_window_pos", GL_ARB_window_pos_functions
},
154 { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions
},
155 { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions
},
156 { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions
},
157 { "GL_EXT_polygon_offset", GL_EXT_polygon_offset_functions
},
158 { "GL_EXT_texture_object", GL_EXT_texture_object_functions
},
159 { "GL_EXT_vertex_array", GL_EXT_vertex_array_functions
},
160 { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions
},
161 { "GL_MESA_window_pos", GL_MESA_window_pos_functions
},
162 { "GL_NV_vertex_program", GL_NV_vertex_program_functions
},
168 * Enable extensions supported by the driver.
171 * ARB_imaging isn't handled properly. In Mesa, enabling ARB_imaging also
172 * enables all the sub-extensions that are folded into it. This means that
173 * we need to add entry-points (via \c driInitSingleExtension) for those
174 * new functions here.
176 void driInitExtensions( GLcontext
* ctx
,
177 const struct dri_extension
* extensions_to_enable
,
178 GLboolean enable_imaging
)
180 static int first_time
= 1;
184 for ( i
= 0 ; i
< driDispatchRemapTable_size
; i
++ ) {
185 driDispatchRemapTable
[i
] = -1;
189 driInitExtensions( ctx
, all_mesa_extensions
, GL_FALSE
);
192 if ( (ctx
!= NULL
) && enable_imaging
) {
193 _mesa_enable_imaging_extensions( ctx
);
196 for ( i
= 0 ; extensions_to_enable
[i
].name
!= NULL
; i
++ ) {
197 driInitSingleExtension( ctx
, & extensions_to_enable
[i
] );
205 * Enable and add dispatch functions for a single extension
207 * \param ctx Context where extension is to be enabled.
208 * \param ext Extension that is to be enabled.
210 * \sa driInitExtensions, _mesa_enable_extension, _glapi_add_entrypoint
213 * Determine if it would be better to use \c strlen instead of the hardcoded
216 void driInitSingleExtension( GLcontext
* ctx
,
217 const struct dri_extension
* ext
)
222 if ( ext
->functions
!= NULL
) {
223 for ( i
= 0 ; ext
->functions
[i
].strings
!= NULL
; i
++ ) {
224 const char * functions
[16];
225 const char * parameter_signature
;
226 const char * str
= ext
->functions
[i
].strings
;
231 /* Separate the parameter signature from the rest of the string.
232 * If the parameter signature is empty (i.e., the string starts
233 * with a NUL character), then the function has a void parameter
236 parameter_signature
= str
;
237 while ( str
[0] != '\0' ) {
243 /* Divide the string into the substrings that name each
244 * entry-point for the function.
246 for ( j
= 0 ; j
< 16 ; j
++ ) {
247 if ( str
[0] == '\0' ) {
254 while ( str
[0] != '\0' ) {
261 /* Add each entry-point to the dispatch table.
263 offset
= _glapi_add_dispatch( functions
, parameter_signature
);
265 #if 0 /* this causes noise with egl */
266 fprintf(stderr
, "DISPATCH ERROR! _glapi_add_dispatch failed "
267 "to add %s!\n", functions
[0]);
270 else if (ext
->functions
[i
].remap_index
!= -1) {
271 driDispatchRemapTable
[ ext
->functions
[i
].remap_index
] =
274 else if (ext
->functions
[i
].offset
!= offset
) {
275 fprintf(stderr
, "DISPATCH ERROR! %s -> %u != %u\n",
276 functions
[0], offset
, ext
->functions
[i
].offset
);
282 _mesa_enable_extension( ctx
, ext
->name
);
288 * Utility function used by drivers to test the verions of other components.
290 * If one of the version requirements is not met, a message is logged using
291 * \c __driUtilMessage.
293 * \param driver_name Name of the driver. Used in error messages.
294 * \param driActual Actual DRI version supplied __driCreateNewScreen.
295 * \param driExpected Minimum DRI version required by the driver.
296 * \param ddxActual Actual DDX version supplied __driCreateNewScreen.
297 * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver.
298 * \param drmActual Actual DRM version supplied __driCreateNewScreen.
299 * \param drmExpected Minimum DRM version required by the driver.
301 * \returns \c GL_TRUE if all version requirements are met. Otherwise,
302 * \c GL_FALSE is returned.
304 * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2, __driUtilMessage
307 * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
308 * function and \c driCheckDriDdxDrmVersions2 should be renamed.
311 driCheckDriDdxDrmVersions3(const char * driver_name
,
312 const __DRIversion
* driActual
,
313 const __DRIversion
* driExpected
,
314 const __DRIversion
* ddxActual
,
315 const __DRIutilversion2
* ddxExpected
,
316 const __DRIversion
* drmActual
,
317 const __DRIversion
* drmExpected
)
319 static const char format
[] = "%s DRI driver expected %s version %d.%d.x "
320 "but got version %d.%d.%d\n";
321 static const char format2
[] = "%s DRI driver expected %s version %d-%d.%d.x "
322 "but got version %d.%d.%d\n";
325 /* Check the DRI version */
326 if ( (driActual
->major
!= driExpected
->major
)
327 || (driActual
->minor
< driExpected
->minor
) ) {
328 fprintf(stderr
, format
, driver_name
, "DRI",
329 driExpected
->major
, driExpected
->minor
,
330 driActual
->major
, driActual
->minor
, driActual
->patch
);
334 /* Check that the DDX driver version is compatible */
335 /* for miniglx we pass in -1 so we can ignore the DDX version */
336 if ( (ddxActual
->major
!= -1) && ((ddxActual
->major
< ddxExpected
->major_min
)
337 || (ddxActual
->major
> ddxExpected
->major_max
)
338 || (ddxActual
->minor
< ddxExpected
->minor
)) ) {
339 fprintf(stderr
, format2
, driver_name
, "DDX",
340 ddxExpected
->major_min
, ddxExpected
->major_max
, ddxExpected
->minor
,
341 ddxActual
->major
, ddxActual
->minor
, ddxActual
->patch
);
345 /* Check that the DRM driver version is compatible */
346 if ( (drmActual
->major
!= drmExpected
->major
)
347 || (drmActual
->minor
< drmExpected
->minor
) ) {
348 fprintf(stderr
, format
, driver_name
, "DRM",
349 drmExpected
->major
, drmExpected
->minor
,
350 drmActual
->major
, drmActual
->minor
, drmActual
->patch
);
358 driCheckDriDdxDrmVersions2(const char * driver_name
,
359 const __DRIversion
* driActual
,
360 const __DRIversion
* driExpected
,
361 const __DRIversion
* ddxActual
,
362 const __DRIversion
* ddxExpected
,
363 const __DRIversion
* drmActual
,
364 const __DRIversion
* drmExpected
)
366 __DRIutilversion2 ddx_expected
;
367 ddx_expected
.major_min
= ddxExpected
->major
;
368 ddx_expected
.major_max
= ddxExpected
->major
;
369 ddx_expected
.minor
= ddxExpected
->minor
;
370 ddx_expected
.patch
= ddxExpected
->patch
;
371 return driCheckDriDdxDrmVersions3(driver_name
, driActual
,
372 driExpected
, ddxActual
, & ddx_expected
,
373 drmActual
, drmExpected
);
376 GLboolean
driClipRectToFramebuffer( const GLframebuffer
*buffer
,
378 GLsizei
*width
, GLsizei
*height
)
381 if (*x
< buffer
->_Xmin
) {
382 *width
-= (buffer
->_Xmin
- *x
);
387 if (*x
+ *width
> buffer
->_Xmax
)
388 *width
-= (*x
+ *width
- buffer
->_Xmax
- 1);
393 /* bottom clipping */
394 if (*y
< buffer
->_Ymin
) {
395 *height
-= (buffer
->_Ymin
- *y
);
400 if (*y
+ *height
> buffer
->_Ymax
)
401 *height
-= (*y
+ *height
- buffer
->_Ymax
- 1);
410 * Creates a set of \c __GLcontextModes that a driver will expose.
412 * A set of \c __GLcontextModes will be created based on the supplied
413 * parameters. The number of modes processed will be 2 *
414 * \c num_depth_stencil_bits * \c num_db_modes.
416 * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
417 * \c db_modes, and \c visType into each \c __GLcontextModes element.
418 * However, the meanings of \c fb_format and \c fb_type require further
419 * explanation. The \c fb_format specifies which color components are in
420 * each pixel and what the default order is. For example, \c GL_RGB specifies
421 * that red, green, blue are available and red is in the "most significant"
422 * position and blue is in the "least significant". The \c fb_type specifies
423 * the bit sizes of each component and the actual ordering. For example, if
424 * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
425 * are the blue value, bits [10:5] are the green value, and bits [4:0] are
428 * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
429 * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
430 * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
431 * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
432 * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
433 * still uses 32-bits.
435 * If in doubt, look at the tables used in the function.
437 * \param ptr_to_modes Pointer to a pointer to a linked list of
438 * \c __GLcontextModes. Upon completion, a pointer to
439 * the next element to be process will be stored here.
440 * If the function fails and returns \c GL_FALSE, this
441 * value will be unmodified, but some elements in the
442 * linked list may be modified.
443 * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
444 * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
445 * \param fb_type Type of the pixels in the framebuffer. Currently only
446 * \c GL_UNSIGNED_SHORT_5_6_5,
447 * \c GL_UNSIGNED_SHORT_5_6_5_REV,
448 * \c GL_UNSIGNED_INT_8_8_8_8, and
449 * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
450 * \param depth_bits Array of depth buffer sizes to be exposed.
451 * \param stencil_bits Array of stencil buffer sizes to be exposed.
452 * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
454 * \param db_modes Array of buffer swap modes. If an element has a
455 * value of \c GLX_NONE, then it represents a
456 * single-buffered mode. Other valid values are
457 * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
458 * \c GLX_SWAP_UNDEFINED_OML. See the
459 * GLX_OML_swap_method extension spec for more details.
460 * \param num_db_modes Number of entries in \c db_modes.
461 * \param msaa_samples Array of msaa sample count. 0 represents a visual
462 * without a multisample buffer.
463 * \param num_msaa_modes Number of entries in \c msaa_samples.
464 * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
465 * \c GLX_DIRECT_COLOR.
468 * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
469 * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
473 * There is currently no way to support packed RGB modes (i.e., modes with
474 * exactly 3 bytes per pixel) or floating-point modes. This could probably
475 * be done by creating some new, private enums with clever names likes
476 * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
477 * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
480 driCreateConfigs(GLenum fb_format
, GLenum fb_type
,
481 const uint8_t * depth_bits
, const uint8_t * stencil_bits
,
482 unsigned num_depth_stencil_bits
,
483 const GLenum
* db_modes
, unsigned num_db_modes
,
484 const uint8_t * msaa_samples
, unsigned num_msaa_modes
)
486 static const uint8_t bits_table
[4][4] = {
488 { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
489 { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
490 { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
491 { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
494 static const uint32_t masks_table_rgb
[6][4] = {
495 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
496 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
497 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
498 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
499 { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */
500 { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */
503 static const uint32_t masks_table_rgba
[6][4] = {
504 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
505 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
506 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
507 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
508 { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */
509 { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
512 static const uint32_t masks_table_bgr
[6][4] = {
513 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
514 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
515 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
516 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
517 { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */
518 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
521 static const uint32_t masks_table_bgra
[6][4] = {
522 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
523 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
524 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
525 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
526 { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */
527 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
530 static const uint8_t bytes_per_pixel
[6] = {
539 const uint8_t * bits
;
540 const uint32_t * masks
;
542 __DRIconfig
**configs
, **c
;
543 __GLcontextModes
*modes
;
546 unsigned num_accum_bits
= 2;
549 case GL_UNSIGNED_BYTE_3_3_2
:
552 case GL_UNSIGNED_BYTE_2_3_3_REV
:
555 case GL_UNSIGNED_SHORT_5_6_5
:
558 case GL_UNSIGNED_SHORT_5_6_5_REV
:
561 case GL_UNSIGNED_INT_8_8_8_8
:
564 case GL_UNSIGNED_INT_8_8_8_8_REV
:
568 fprintf( stderr
, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
569 __FUNCTION__
, __LINE__
, fb_type
);
574 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
577 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
580 switch ( fb_format
) {
582 masks
= masks_table_rgb
[ index
];
586 masks
= masks_table_rgba
[ index
];
590 masks
= masks_table_bgr
[ index
];
594 masks
= masks_table_bgra
[ index
];
598 fprintf( stderr
, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
599 __FUNCTION__
, __LINE__
, fb_format
);
603 switch ( bytes_per_pixel
[ index
] ) {
605 bits
= bits_table
[0];
608 bits
= bits_table
[1];
611 bits
= ((fb_format
== GL_RGB
) || (fb_format
== GL_BGR
))
617 num_modes
= num_depth_stencil_bits
* num_db_modes
* num_accum_bits
* num_msaa_modes
;
618 configs
= _mesa_calloc((num_modes
+ 1) * sizeof *configs
);
623 for ( k
= 0 ; k
< num_depth_stencil_bits
; k
++ ) {
624 for ( i
= 0 ; i
< num_db_modes
; i
++ ) {
625 for ( h
= 0 ; h
< num_msaa_modes
; h
++ ) {
626 for ( j
= 0 ; j
< num_accum_bits
; j
++ ) {
627 *c
= _mesa_malloc (sizeof **c
);
628 modes
= &(*c
)->modes
;
631 memset(modes
, 0, sizeof *modes
);
632 modes
->redBits
= bits
[0];
633 modes
->greenBits
= bits
[1];
634 modes
->blueBits
= bits
[2];
635 modes
->alphaBits
= bits
[3];
636 modes
->redMask
= masks
[0];
637 modes
->greenMask
= masks
[1];
638 modes
->blueMask
= masks
[2];
639 modes
->alphaMask
= masks
[3];
640 modes
->rgbBits
= modes
->redBits
+ modes
->greenBits
641 + modes
->blueBits
+ modes
->alphaBits
;
643 modes
->accumRedBits
= 16 * j
;
644 modes
->accumGreenBits
= 16 * j
;
645 modes
->accumBlueBits
= 16 * j
;
646 modes
->accumAlphaBits
= (masks
[3] != 0) ? 16 * j
: 0;
647 modes
->visualRating
= (j
== 0) ? GLX_NONE
: GLX_SLOW_CONFIG
;
649 modes
->stencilBits
= stencil_bits
[k
];
650 modes
->depthBits
= depth_bits
[k
];
652 modes
->transparentPixel
= GLX_NONE
;
653 modes
->transparentRed
= GLX_DONT_CARE
;
654 modes
->transparentGreen
= GLX_DONT_CARE
;
655 modes
->transparentBlue
= GLX_DONT_CARE
;
656 modes
->transparentAlpha
= GLX_DONT_CARE
;
657 modes
->transparentIndex
= GLX_DONT_CARE
;
658 modes
->visualType
= GLX_DONT_CARE
;
659 modes
->renderType
= GLX_RGBA_BIT
;
660 modes
->drawableType
= GLX_WINDOW_BIT
;
661 modes
->rgbMode
= GL_TRUE
;
663 if ( db_modes
[i
] == GLX_NONE
) {
664 modes
->doubleBufferMode
= GL_FALSE
;
667 modes
->doubleBufferMode
= GL_TRUE
;
668 modes
->swapMethod
= db_modes
[i
];
671 modes
->samples
= msaa_samples
[h
];
672 modes
->sampleBuffers
= modes
->samples
? 1 : 0;
675 modes
->haveAccumBuffer
= ((modes
->accumRedBits
+
676 modes
->accumGreenBits
+
677 modes
->accumBlueBits
+
678 modes
->accumAlphaBits
) > 0);
679 modes
->haveDepthBuffer
= (modes
->depthBits
> 0);
680 modes
->haveStencilBuffer
= (modes
->stencilBits
> 0);
682 modes
->bindToTextureRgb
= GL_TRUE
;
683 modes
->bindToTextureRgba
= GL_TRUE
;
684 modes
->bindToMipmapTexture
= GL_FALSE
;
685 modes
->bindToTextureTargets
= modes
->rgbMode
?
686 __DRI_ATTRIB_TEXTURE_1D_BIT
|
687 __DRI_ATTRIB_TEXTURE_2D_BIT
|
688 __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT
:
699 __DRIconfig
**driConcatConfigs(__DRIconfig
**a
,
712 all
= _mesa_malloc((i
+ j
+ 1) * sizeof *all
);
714 for (i
= 0; a
[i
] != NULL
; i
++)
716 for (j
= 0; b
[j
] != NULL
; j
++)
726 #define __ATTRIB(attrib, field) \
727 { attrib, offsetof(__GLcontextModes, field) }
729 static const struct { unsigned int attrib
, offset
; } attribMap
[] = {
730 __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE
, rgbBits
),
731 __ATTRIB(__DRI_ATTRIB_LEVEL
, level
),
732 __ATTRIB(__DRI_ATTRIB_RED_SIZE
, redBits
),
733 __ATTRIB(__DRI_ATTRIB_GREEN_SIZE
, greenBits
),
734 __ATTRIB(__DRI_ATTRIB_BLUE_SIZE
, blueBits
),
735 __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE
, alphaBits
),
736 __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE
, depthBits
),
737 __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE
, stencilBits
),
738 __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE
, accumRedBits
),
739 __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE
, accumGreenBits
),
740 __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE
, accumBlueBits
),
741 __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE
, accumAlphaBits
),
742 __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS
, sampleBuffers
),
743 __ATTRIB(__DRI_ATTRIB_SAMPLES
, samples
),
744 __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER
, doubleBufferMode
),
745 __ATTRIB(__DRI_ATTRIB_STEREO
, stereoMode
),
746 __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS
, numAuxBuffers
),
747 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE
, transparentPixel
),
748 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE
, transparentPixel
),
749 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE
, transparentRed
),
750 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE
, transparentGreen
),
751 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE
, transparentBlue
),
752 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE
, transparentAlpha
),
753 __ATTRIB(__DRI_ATTRIB_FLOAT_MODE
, floatMode
),
754 __ATTRIB(__DRI_ATTRIB_RED_MASK
, redMask
),
755 __ATTRIB(__DRI_ATTRIB_GREEN_MASK
, greenMask
),
756 __ATTRIB(__DRI_ATTRIB_BLUE_MASK
, blueMask
),
757 __ATTRIB(__DRI_ATTRIB_ALPHA_MASK
, alphaMask
),
758 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH
, maxPbufferWidth
),
759 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT
, maxPbufferHeight
),
760 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS
, maxPbufferPixels
),
761 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH
, optimalPbufferWidth
),
762 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT
, optimalPbufferHeight
),
763 __ATTRIB(__DRI_ATTRIB_SWAP_METHOD
, swapMethod
),
764 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB
, bindToTextureRgb
),
765 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA
, bindToTextureRgba
),
766 __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE
, bindToMipmapTexture
),
767 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS
, bindToTextureTargets
),
768 __ATTRIB(__DRI_ATTRIB_YINVERTED
, yInverted
),
770 /* The struct field doesn't matter here, these are handled by the
771 * switch in driGetConfigAttribIndex. We need them in the array
772 * so the iterator includes them though.*/
773 __ATTRIB(__DRI_ATTRIB_RENDER_TYPE
, level
),
774 __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT
, level
),
775 __ATTRIB(__DRI_ATTRIB_SWAP_METHOD
, level
)
778 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
781 driGetConfigAttribIndex(const __DRIconfig
*config
,
782 unsigned int index
, unsigned int *value
)
784 switch (attribMap
[index
].attrib
) {
785 case __DRI_ATTRIB_RENDER_TYPE
:
786 if (config
->modes
.rgbMode
)
787 *value
= __DRI_ATTRIB_RGBA_BIT
;
789 *value
= __DRI_ATTRIB_COLOR_INDEX_BIT
;
791 case __DRI_ATTRIB_CONFIG_CAVEAT
:
792 if (config
->modes
.visualRating
== GLX_NON_CONFORMANT_CONFIG
)
793 *value
= __DRI_ATTRIB_NON_CONFORMANT_CONFIG
;
794 else if (config
->modes
.visualRating
== GLX_SLOW_CONFIG
)
795 *value
= __DRI_ATTRIB_SLOW_BIT
;
799 case __DRI_ATTRIB_SWAP_METHOD
:
802 case __DRI_ATTRIB_FLOAT_MODE
:
803 *value
= config
->modes
.floatMode
;
807 *value
= *(unsigned int *)
808 ((char *) &config
->modes
+ attribMap
[index
].offset
);
817 driGetConfigAttrib(const __DRIconfig
*config
,
818 unsigned int attrib
, unsigned int *value
)
822 for (i
= 0; i
< ARRAY_SIZE(attribMap
); i
++)
823 if (attribMap
[i
].attrib
== attrib
)
824 return driGetConfigAttribIndex(config
, i
, value
);
830 driIndexConfigAttrib(const __DRIconfig
*config
, int index
,
831 unsigned int *attrib
, unsigned int *value
)
833 if (index
>= 0 && index
< ARRAY_SIZE(attribMap
)) {
834 *attrib
= attribMap
[index
].attrib
;
835 return driGetConfigAttribIndex(config
, index
, value
);