Merge branch 'master' into glsl-pp-rework-2
[mesa.git] / src / mesa / drivers / dri / common / utils.c
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/cpuinfo.h"
36 #include "main/extensions.h"
37 #include "glapi/dispatch.h"
38 #include "utils.h"
39
40
41 unsigned
42 driParseDebugString( const char * debug,
43 const struct dri_debug_control * control )
44 {
45 unsigned flag;
46
47
48 flag = 0;
49 if ( debug != NULL ) {
50 while( control->string != NULL ) {
51 if ( !strcmp( debug, "all" ) ||
52 strstr( debug, control->string ) != NULL ) {
53 flag |= control->flag;
54 }
55
56 control++;
57 }
58 }
59
60 return flag;
61 }
62
63
64
65 /**
66 * Create the \c GL_RENDERER string for DRI drivers.
67 *
68 * Almost all DRI drivers use a \c GL_RENDERER string of the form:
69 *
70 * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
71 *
72 * Using the supplied chip name, driver data, and AGP speed, this function
73 * creates the string.
74 *
75 * \param buffer Buffer to hold the \c GL_RENDERER string.
76 * \param hardware_name Name of the hardware.
77 * \param driver_date Driver date.
78 * \param agp_mode AGP mode (speed).
79 *
80 * \returns
81 * The length of the string stored in \c buffer. This does \b not include
82 * the terminating \c NUL character.
83 */
84 unsigned
85 driGetRendererString( char * buffer, const char * hardware_name,
86 const char * driver_date, GLuint agp_mode )
87 {
88 unsigned offset;
89 char *cpu;
90
91 offset = sprintf( buffer, "Mesa DRI %s %s", hardware_name, driver_date );
92
93 /* Append any AGP-specific information.
94 */
95 switch ( agp_mode ) {
96 case 1:
97 case 2:
98 case 4:
99 case 8:
100 offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode );
101 break;
102
103 default:
104 break;
105 }
106
107 /* Append any CPU-specific information.
108 */
109 cpu = _mesa_get_cpu_string();
110 if (cpu) {
111 offset += sprintf(buffer + offset, " %s", cpu);
112 _mesa_free(cpu);
113 }
114
115 return offset;
116 }
117
118
119
120
121 #define need_GL_ARB_draw_buffers
122 #define need_GL_ARB_multisample
123 #define need_GL_ARB_texture_compression
124 #define need_GL_ARB_transpose_matrix
125 #define need_GL_ARB_vertex_buffer_object
126 #define need_GL_ARB_window_pos
127 #define need_GL_EXT_compiled_vertex_array
128 #define need_GL_EXT_multi_draw_arrays
129 #define need_GL_EXT_polygon_offset
130 #define need_GL_EXT_texture_object
131 #define need_GL_EXT_vertex_array
132 #define need_GL_IBM_multimode_draw_arrays
133 #define need_GL_MESA_window_pos
134
135 /* These are needed in *all* drivers because Mesa internally implements
136 * certain functionality in terms of functions provided by these extensions.
137 * For example, glBlendFunc is implemented by calling glBlendFuncSeparateEXT.
138 */
139 #define need_GL_EXT_blend_func_separate
140 #define need_GL_NV_vertex_program
141
142 #include "main/remap_helper.h"
143
144 static const struct dri_extension all_mesa_extensions[] = {
145 { "GL_ARB_draw_buffers", GL_ARB_draw_buffers_functions },
146 { "GL_ARB_multisample", GL_ARB_multisample_functions },
147 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
148 { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions },
149 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
150 { "GL_ARB_window_pos", GL_ARB_window_pos_functions },
151 { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
152 { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
153 { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
154 { "GL_EXT_polygon_offset", GL_EXT_polygon_offset_functions },
155 { "GL_EXT_texture_object", GL_EXT_texture_object_functions },
156 { "GL_EXT_vertex_array", GL_EXT_vertex_array_functions },
157 { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
158 { "GL_MESA_window_pos", GL_MESA_window_pos_functions },
159 { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
160 { NULL, NULL }
161 };
162
163
164 /**
165 * Enable and map extensions supported by the driver.
166 *
167 * When ctx is NULL, extensions are not enabled, but their functions
168 * are still mapped. When extensions_to_enable is NULL, all static
169 * functions known to mesa core are mapped.
170 *
171 * \bug
172 * ARB_imaging isn't handled properly. In Mesa, enabling ARB_imaging also
173 * enables all the sub-extensions that are folded into it. This means that
174 * we need to add entry-points (via \c driInitSingleExtension) for those
175 * new functions here.
176 */
177 void driInitExtensions( GLcontext * ctx,
178 const struct dri_extension * extensions_to_enable,
179 GLboolean enable_imaging )
180 {
181 static int first_time = 1;
182 unsigned i;
183
184 if ( first_time ) {
185 first_time = 0;
186 driInitExtensions( NULL, all_mesa_extensions, GL_FALSE );
187 }
188
189 if ( (ctx != NULL) && enable_imaging ) {
190 _mesa_enable_imaging_extensions( ctx );
191 }
192
193 /* The caller is too lazy to list any extension */
194 if ( extensions_to_enable == NULL ) {
195 /* Map the static functions. Together with those mapped by remap
196 * table, this should cover everything mesa core knows.
197 */
198 _mesa_map_static_functions();
199 return;
200 }
201
202 for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) {
203 driInitSingleExtension( ctx, & extensions_to_enable[i] );
204 }
205 }
206
207
208
209
210 /**
211 * Enable and map functions for a single extension
212 *
213 * \param ctx Context where extension is to be enabled.
214 * \param ext Extension that is to be enabled.
215 *
216 * \sa driInitExtensions, _mesa_enable_extension, _mesa_map_function_array
217 */
218 void driInitSingleExtension( GLcontext * ctx,
219 const struct dri_extension * ext )
220 {
221 if ( ext->functions != NULL ) {
222 _mesa_map_function_array(ext->functions);
223 }
224
225 if ( ctx != NULL ) {
226 _mesa_enable_extension( ctx, ext->name );
227 }
228 }
229
230
231 /**
232 * Utility function used by drivers to test the verions of other components.
233 *
234 * If one of the version requirements is not met, a message is logged using
235 * \c __driUtilMessage.
236 *
237 * \param driver_name Name of the driver. Used in error messages.
238 * \param driActual Actual DRI version supplied __driCreateNewScreen.
239 * \param driExpected Minimum DRI version required by the driver.
240 * \param ddxActual Actual DDX version supplied __driCreateNewScreen.
241 * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver.
242 * \param drmActual Actual DRM version supplied __driCreateNewScreen.
243 * \param drmExpected Minimum DRM version required by the driver.
244 *
245 * \returns \c GL_TRUE if all version requirements are met. Otherwise,
246 * \c GL_FALSE is returned.
247 *
248 * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2, __driUtilMessage
249 *
250 * \todo
251 * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
252 * function and \c driCheckDriDdxDrmVersions2 should be renamed.
253 */
254 GLboolean
255 driCheckDriDdxDrmVersions3(const char * driver_name,
256 const __DRIversion * driActual,
257 const __DRIversion * driExpected,
258 const __DRIversion * ddxActual,
259 const __DRIutilversion2 * ddxExpected,
260 const __DRIversion * drmActual,
261 const __DRIversion * drmExpected)
262 {
263 static const char format[] = "%s DRI driver expected %s version %d.%d.x "
264 "but got version %d.%d.%d\n";
265 static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x "
266 "but got version %d.%d.%d\n";
267
268
269 /* Check the DRI version */
270 if ( (driActual->major != driExpected->major)
271 || (driActual->minor < driExpected->minor) ) {
272 fprintf(stderr, format, driver_name, "DRI",
273 driExpected->major, driExpected->minor,
274 driActual->major, driActual->minor, driActual->patch);
275 return GL_FALSE;
276 }
277
278 /* Check that the DDX driver version is compatible */
279 /* for miniglx we pass in -1 so we can ignore the DDX version */
280 if ( (ddxActual->major != -1) && ((ddxActual->major < ddxExpected->major_min)
281 || (ddxActual->major > ddxExpected->major_max)
282 || (ddxActual->minor < ddxExpected->minor)) ) {
283 fprintf(stderr, format2, driver_name, "DDX",
284 ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
285 ddxActual->major, ddxActual->minor, ddxActual->patch);
286 return GL_FALSE;
287 }
288
289 /* Check that the DRM driver version is compatible */
290 if ( (drmActual->major != drmExpected->major)
291 || (drmActual->minor < drmExpected->minor) ) {
292 fprintf(stderr, format, driver_name, "DRM",
293 drmExpected->major, drmExpected->minor,
294 drmActual->major, drmActual->minor, drmActual->patch);
295 return GL_FALSE;
296 }
297
298 return GL_TRUE;
299 }
300
301 GLboolean
302 driCheckDriDdxDrmVersions2(const char * driver_name,
303 const __DRIversion * driActual,
304 const __DRIversion * driExpected,
305 const __DRIversion * ddxActual,
306 const __DRIversion * ddxExpected,
307 const __DRIversion * drmActual,
308 const __DRIversion * drmExpected)
309 {
310 __DRIutilversion2 ddx_expected;
311 ddx_expected.major_min = ddxExpected->major;
312 ddx_expected.major_max = ddxExpected->major;
313 ddx_expected.minor = ddxExpected->minor;
314 ddx_expected.patch = ddxExpected->patch;
315 return driCheckDriDdxDrmVersions3(driver_name, driActual,
316 driExpected, ddxActual, & ddx_expected,
317 drmActual, drmExpected);
318 }
319
320 GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
321 GLint *x, GLint *y,
322 GLsizei *width, GLsizei *height )
323 {
324 /* left clipping */
325 if (*x < buffer->_Xmin) {
326 *width -= (buffer->_Xmin - *x);
327 *x = buffer->_Xmin;
328 }
329
330 /* right clipping */
331 if (*x + *width > buffer->_Xmax)
332 *width -= (*x + *width - buffer->_Xmax - 1);
333
334 if (*width <= 0)
335 return GL_FALSE;
336
337 /* bottom clipping */
338 if (*y < buffer->_Ymin) {
339 *height -= (buffer->_Ymin - *y);
340 *y = buffer->_Ymin;
341 }
342
343 /* top clipping */
344 if (*y + *height > buffer->_Ymax)
345 *height -= (*y + *height - buffer->_Ymax - 1);
346
347 if (*height <= 0)
348 return GL_FALSE;
349
350 return GL_TRUE;
351 }
352
353 /**
354 * Creates a set of \c __GLcontextModes that a driver will expose.
355 *
356 * A set of \c __GLcontextModes will be created based on the supplied
357 * parameters. The number of modes processed will be 2 *
358 * \c num_depth_stencil_bits * \c num_db_modes.
359 *
360 * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
361 * \c db_modes, and \c visType into each \c __GLcontextModes element.
362 * However, the meanings of \c fb_format and \c fb_type require further
363 * explanation. The \c fb_format specifies which color components are in
364 * each pixel and what the default order is. For example, \c GL_RGB specifies
365 * that red, green, blue are available and red is in the "most significant"
366 * position and blue is in the "least significant". The \c fb_type specifies
367 * the bit sizes of each component and the actual ordering. For example, if
368 * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
369 * are the blue value, bits [10:5] are the green value, and bits [4:0] are
370 * the red value.
371 *
372 * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
373 * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
374 * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
375 * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
376 * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
377 * still uses 32-bits.
378 *
379 * If in doubt, look at the tables used in the function.
380 *
381 * \param ptr_to_modes Pointer to a pointer to a linked list of
382 * \c __GLcontextModes. Upon completion, a pointer to
383 * the next element to be process will be stored here.
384 * If the function fails and returns \c GL_FALSE, this
385 * value will be unmodified, but some elements in the
386 * linked list may be modified.
387 * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
388 * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
389 * \param fb_type Type of the pixels in the framebuffer. Currently only
390 * \c GL_UNSIGNED_SHORT_5_6_5,
391 * \c GL_UNSIGNED_SHORT_5_6_5_REV,
392 * \c GL_UNSIGNED_INT_8_8_8_8, and
393 * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
394 * \param depth_bits Array of depth buffer sizes to be exposed.
395 * \param stencil_bits Array of stencil buffer sizes to be exposed.
396 * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
397 * \c stencil_bits.
398 * \param db_modes Array of buffer swap modes. If an element has a
399 * value of \c GLX_NONE, then it represents a
400 * single-buffered mode. Other valid values are
401 * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
402 * \c GLX_SWAP_UNDEFINED_OML. See the
403 * GLX_OML_swap_method extension spec for more details.
404 * \param num_db_modes Number of entries in \c db_modes.
405 * \param msaa_samples Array of msaa sample count. 0 represents a visual
406 * without a multisample buffer.
407 * \param num_msaa_modes Number of entries in \c msaa_samples.
408 * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
409 * \c GLX_DIRECT_COLOR.
410 *
411 * \returns
412 * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
413 * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
414 * \c fb_type).
415 *
416 * \todo
417 * There is currently no way to support packed RGB modes (i.e., modes with
418 * exactly 3 bytes per pixel) or floating-point modes. This could probably
419 * be done by creating some new, private enums with clever names likes
420 * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
421 * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
422 */
423 __DRIconfig **
424 driCreateConfigs(GLenum fb_format, GLenum fb_type,
425 const uint8_t * depth_bits, const uint8_t * stencil_bits,
426 unsigned num_depth_stencil_bits,
427 const GLenum * db_modes, unsigned num_db_modes,
428 const uint8_t * msaa_samples, unsigned num_msaa_modes)
429 {
430 static const uint8_t bits_table[4][4] = {
431 /* R G B A */
432 { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
433 { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
434 { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
435 { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
436 };
437
438 static const uint32_t masks_table_rgb[6][4] = {
439 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
440 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
441 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
442 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
443 { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */
444 { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */
445 };
446
447 static const uint32_t masks_table_rgba[6][4] = {
448 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
449 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
450 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
451 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
452 { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */
453 { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
454 };
455
456 static const uint32_t masks_table_bgr[6][4] = {
457 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
458 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
459 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
460 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
461 { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */
462 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
463 };
464
465 static const uint32_t masks_table_bgra[6][4] = {
466 { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
467 { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
468 { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
469 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
470 { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */
471 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
472 };
473
474 static const uint8_t bytes_per_pixel[6] = {
475 1, /* 3_3_2 */
476 1, /* 2_3_3_REV */
477 2, /* 5_6_5 */
478 2, /* 5_6_5_REV */
479 4, /* 8_8_8_8 */
480 4 /* 8_8_8_8_REV */
481 };
482
483 const uint8_t * bits;
484 const uint32_t * masks;
485 int index;
486 __DRIconfig **configs, **c;
487 __GLcontextModes *modes;
488 unsigned i, j, k, h;
489 unsigned num_modes;
490 unsigned num_accum_bits = 2;
491
492 switch ( fb_type ) {
493 case GL_UNSIGNED_BYTE_3_3_2:
494 index = 0;
495 break;
496 case GL_UNSIGNED_BYTE_2_3_3_REV:
497 index = 1;
498 break;
499 case GL_UNSIGNED_SHORT_5_6_5:
500 index = 2;
501 break;
502 case GL_UNSIGNED_SHORT_5_6_5_REV:
503 index = 3;
504 break;
505 case GL_UNSIGNED_INT_8_8_8_8:
506 index = 4;
507 break;
508 case GL_UNSIGNED_INT_8_8_8_8_REV:
509 index = 5;
510 break;
511 default:
512 fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
513 __FUNCTION__, __LINE__, fb_type );
514 return NULL;
515 }
516
517
518 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
519 * the _REV versions.
520 *
521 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
522 */
523
524 switch ( fb_format ) {
525 case GL_RGB:
526 masks = masks_table_rgb[ index ];
527 break;
528
529 case GL_RGBA:
530 masks = masks_table_rgba[ index ];
531 break;
532
533 case GL_BGR:
534 masks = masks_table_bgr[ index ];
535 break;
536
537 case GL_BGRA:
538 masks = masks_table_bgra[ index ];
539 break;
540
541 default:
542 fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
543 __FUNCTION__, __LINE__, fb_format );
544 return NULL;
545 }
546
547 switch ( bytes_per_pixel[ index ] ) {
548 case 1:
549 bits = bits_table[0];
550 break;
551 case 2:
552 bits = bits_table[1];
553 break;
554 default:
555 bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
556 ? bits_table[2]
557 : bits_table[3];
558 break;
559 }
560
561 num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes;
562 configs = _mesa_calloc((num_modes + 1) * sizeof *configs);
563 if (configs == NULL)
564 return NULL;
565
566 c = configs;
567 for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
568 for ( i = 0 ; i < num_db_modes ; i++ ) {
569 for ( h = 0 ; h < num_msaa_modes; h++ ) {
570 for ( j = 0 ; j < num_accum_bits ; j++ ) {
571 *c = _mesa_malloc (sizeof **c);
572 modes = &(*c)->modes;
573 c++;
574
575 memset(modes, 0, sizeof *modes);
576 modes->redBits = bits[0];
577 modes->greenBits = bits[1];
578 modes->blueBits = bits[2];
579 modes->alphaBits = bits[3];
580 modes->redMask = masks[0];
581 modes->greenMask = masks[1];
582 modes->blueMask = masks[2];
583 modes->alphaMask = masks[3];
584 modes->rgbBits = modes->redBits + modes->greenBits
585 + modes->blueBits + modes->alphaBits;
586
587 modes->accumRedBits = 16 * j;
588 modes->accumGreenBits = 16 * j;
589 modes->accumBlueBits = 16 * j;
590 modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
591 modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
592
593 modes->stencilBits = stencil_bits[k];
594 modes->depthBits = depth_bits[k];
595
596 modes->transparentPixel = GLX_NONE;
597 modes->transparentRed = GLX_DONT_CARE;
598 modes->transparentGreen = GLX_DONT_CARE;
599 modes->transparentBlue = GLX_DONT_CARE;
600 modes->transparentAlpha = GLX_DONT_CARE;
601 modes->transparentIndex = GLX_DONT_CARE;
602 modes->visualType = GLX_DONT_CARE;
603 modes->renderType = GLX_RGBA_BIT;
604 modes->drawableType = GLX_WINDOW_BIT;
605 modes->rgbMode = GL_TRUE;
606
607 if ( db_modes[i] == GLX_NONE ) {
608 modes->doubleBufferMode = GL_FALSE;
609 }
610 else {
611 modes->doubleBufferMode = GL_TRUE;
612 modes->swapMethod = db_modes[i];
613 }
614
615 modes->samples = msaa_samples[h];
616 modes->sampleBuffers = modes->samples ? 1 : 0;
617
618
619 modes->haveAccumBuffer = ((modes->accumRedBits +
620 modes->accumGreenBits +
621 modes->accumBlueBits +
622 modes->accumAlphaBits) > 0);
623 modes->haveDepthBuffer = (modes->depthBits > 0);
624 modes->haveStencilBuffer = (modes->stencilBits > 0);
625
626 modes->bindToTextureRgb = GL_TRUE;
627 modes->bindToTextureRgba = GL_TRUE;
628 modes->bindToMipmapTexture = GL_FALSE;
629 modes->bindToTextureTargets = modes->rgbMode ?
630 __DRI_ATTRIB_TEXTURE_1D_BIT |
631 __DRI_ATTRIB_TEXTURE_2D_BIT |
632 __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT :
633 0;
634 }
635 }
636 }
637 }
638 *c = NULL;
639
640 return configs;
641 }
642
643 __DRIconfig **driConcatConfigs(__DRIconfig **a,
644 __DRIconfig **b)
645 {
646 __DRIconfig **all;
647 int i, j, index;
648
649 i = 0;
650 while (a[i] != NULL)
651 i++;
652 j = 0;
653 while (b[j] != NULL)
654 j++;
655
656 all = _mesa_malloc((i + j + 1) * sizeof *all);
657 index = 0;
658 for (i = 0; a[i] != NULL; i++)
659 all[index++] = a[i];
660 for (j = 0; b[j] != NULL; j++)
661 all[index++] = b[j];
662 all[index++] = NULL;
663
664 _mesa_free(a);
665 _mesa_free(b);
666
667 return all;
668 }
669
670 #define __ATTRIB(attrib, field) \
671 { attrib, offsetof(__GLcontextModes, field) }
672
673 static const struct { unsigned int attrib, offset; } attribMap[] = {
674 __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
675 __ATTRIB(__DRI_ATTRIB_LEVEL, level),
676 __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
677 __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
678 __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
679 __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
680 __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
681 __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
682 __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
683 __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
684 __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
685 __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
686 __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
687 __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
688 __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
689 __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
690 __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
691 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
692 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
693 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
694 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
695 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
696 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
697 __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
698 __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
699 __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
700 __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
701 __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
702 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
703 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
704 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
705 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
706 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
707 __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
708 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
709 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
710 __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
711 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
712 __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
713
714 /* The struct field doesn't matter here, these are handled by the
715 * switch in driGetConfigAttribIndex. We need them in the array
716 * so the iterator includes them though.*/
717 __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
718 __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
719 __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
720 };
721
722 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
723
724 static int
725 driGetConfigAttribIndex(const __DRIconfig *config,
726 unsigned int index, unsigned int *value)
727 {
728 switch (attribMap[index].attrib) {
729 case __DRI_ATTRIB_RENDER_TYPE:
730 if (config->modes.rgbMode)
731 *value = __DRI_ATTRIB_RGBA_BIT;
732 else
733 *value = __DRI_ATTRIB_COLOR_INDEX_BIT;
734 break;
735 case __DRI_ATTRIB_CONFIG_CAVEAT:
736 if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
737 *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
738 else if (config->modes.visualRating == GLX_SLOW_CONFIG)
739 *value = __DRI_ATTRIB_SLOW_BIT;
740 else
741 *value = 0;
742 break;
743 case __DRI_ATTRIB_SWAP_METHOD:
744 break;
745
746 case __DRI_ATTRIB_FLOAT_MODE:
747 *value = config->modes.floatMode;
748 break;
749
750 default:
751 *value = *(unsigned int *)
752 ((char *) &config->modes + attribMap[index].offset);
753
754 break;
755 }
756
757 return GL_TRUE;
758 }
759
760 int
761 driGetConfigAttrib(const __DRIconfig *config,
762 unsigned int attrib, unsigned int *value)
763 {
764 int i;
765
766 for (i = 0; i < ARRAY_SIZE(attribMap); i++)
767 if (attribMap[i].attrib == attrib)
768 return driGetConfigAttribIndex(config, i, value);
769
770 return GL_FALSE;
771 }
772
773 int
774 driIndexConfigAttrib(const __DRIconfig *config, int index,
775 unsigned int *attrib, unsigned int *value)
776 {
777 if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
778 *attrib = attribMap[index].attrib;
779 return driGetConfigAttribIndex(config, index, value);
780 }
781
782 return GL_FALSE;
783 }