r300: fix valgrind warnings
[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 int driDispatchRemapTable[ driDispatchRemapTable_size ];
42
43
44 unsigned
45 driParseDebugString( const char * debug,
46 const struct dri_debug_control * control )
47 {
48 unsigned flag;
49
50
51 flag = 0;
52 if ( debug != NULL ) {
53 while( control->string != NULL ) {
54 if ( !strcmp( debug, "all" ) ||
55 strstr( debug, control->string ) != NULL ) {
56 flag |= control->flag;
57 }
58
59 control++;
60 }
61 }
62
63 return flag;
64 }
65
66
67
68 /**
69 * Create the \c GL_RENDERER string for DRI drivers.
70 *
71 * Almost all DRI drivers use a \c GL_RENDERER string of the form:
72 *
73 * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
74 *
75 * Using the supplied chip name, driver data, and AGP speed, this function
76 * creates the string.
77 *
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).
82 *
83 * \returns
84 * The length of the string stored in \c buffer. This does \b not include
85 * the terminating \c NUL character.
86 */
87 unsigned
88 driGetRendererString( char * buffer, const char * hardware_name,
89 const char * driver_date, GLuint agp_mode )
90 {
91 unsigned offset;
92 char *cpu;
93
94 offset = sprintf( buffer, "Mesa DRI %s %s", hardware_name, driver_date );
95
96 /* Append any AGP-specific information.
97 */
98 switch ( agp_mode ) {
99 case 1:
100 case 2:
101 case 4:
102 case 8:
103 offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode );
104 break;
105
106 default:
107 break;
108 }
109
110 /* Append any CPU-specific information.
111 */
112 cpu = _mesa_get_cpu_string();
113 if (cpu) {
114 offset += sprintf(buffer + offset, " %s", cpu);
115 _mesa_free(cpu);
116 }
117
118 return offset;
119 }
120
121
122
123
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
137
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.
141 */
142 #define need_GL_EXT_blend_func_separate
143 #define need_GL_NV_vertex_program
144
145 #include "extension_helper.h"
146
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 },
163 { NULL, NULL }
164 };
165
166
167 /**
168 * Enable extensions supported by the driver.
169 *
170 * \bug
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.
175 */
176 void driInitExtensions( GLcontext * ctx,
177 const struct dri_extension * extensions_to_enable,
178 GLboolean enable_imaging )
179 {
180 static int first_time = 1;
181 unsigned i;
182
183 if ( first_time ) {
184 for ( i = 0 ; i < driDispatchRemapTable_size ; i++ ) {
185 driDispatchRemapTable[i] = -1;
186 }
187
188 first_time = 0;
189 driInitExtensions( ctx, all_mesa_extensions, GL_FALSE );
190 }
191
192 if ( (ctx != NULL) && enable_imaging ) {
193 _mesa_enable_imaging_extensions( ctx );
194 }
195
196 for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) {
197 driInitSingleExtension( ctx, & extensions_to_enable[i] );
198 }
199 }
200
201
202
203
204 /**
205 * Enable and add dispatch functions for a single extension
206 *
207 * \param ctx Context where extension is to be enabled.
208 * \param ext Extension that is to be enabled.
209 *
210 * \sa driInitExtensions, _mesa_enable_extension, _glapi_add_entrypoint
211 *
212 * \todo
213 * Determine if it would be better to use \c strlen instead of the hardcoded
214 * for-loops.
215 */
216 void driInitSingleExtension( GLcontext * ctx,
217 const struct dri_extension * ext )
218 {
219 unsigned i;
220
221
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;
227 unsigned j;
228 unsigned offset;
229
230
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
234 * list.
235 */
236 parameter_signature = str;
237 while ( str[0] != '\0' ) {
238 str++;
239 }
240 str++;
241
242
243 /* Divide the string into the substrings that name each
244 * entry-point for the function.
245 */
246 for ( j = 0 ; j < 16 ; j++ ) {
247 if ( str[0] == '\0' ) {
248 functions[j] = NULL;
249 break;
250 }
251
252 functions[j] = str;
253
254 while ( str[0] != '\0' ) {
255 str++;
256 }
257 str++;
258 }
259
260
261 /* Add each entry-point to the dispatch table.
262 */
263 offset = _glapi_add_dispatch( functions, parameter_signature );
264 if (offset == -1) {
265 #if 0 /* this causes noise with egl */
266 fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed "
267 "to add %s!\n", functions[0]);
268 #endif
269 }
270 else if (ext->functions[i].remap_index != -1) {
271 driDispatchRemapTable[ ext->functions[i].remap_index ] =
272 offset;
273 }
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);
277 }
278 }
279 }
280
281 if ( ctx != NULL ) {
282 _mesa_enable_extension( ctx, ext->name );
283 }
284 }
285
286
287 /**
288 * Utility function used by drivers to test the verions of other components.
289 *
290 * If one of the version requirements is not met, a message is logged using
291 * \c __driUtilMessage.
292 *
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.
300 *
301 * \returns \c GL_TRUE if all version requirements are met. Otherwise,
302 * \c GL_FALSE is returned.
303 *
304 * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2, __driUtilMessage
305 *
306 * \todo
307 * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
308 * function and \c driCheckDriDdxDrmVersions2 should be renamed.
309 */
310 GLboolean
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)
318 {
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";
323
324
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);
331 return GL_FALSE;
332 }
333
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);
342 return GL_FALSE;
343 }
344
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);
351 return GL_FALSE;
352 }
353
354 return GL_TRUE;
355 }
356
357 GLboolean
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)
365 {
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);
374 }
375
376 GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
377 GLint *x, GLint *y,
378 GLsizei *width, GLsizei *height )
379 {
380 /* left clipping */
381 if (*x < buffer->_Xmin) {
382 *width -= (buffer->_Xmin - *x);
383 *x = buffer->_Xmin;
384 }
385
386 /* right clipping */
387 if (*x + *width > buffer->_Xmax)
388 *width -= (*x + *width - buffer->_Xmax - 1);
389
390 if (*width <= 0)
391 return GL_FALSE;
392
393 /* bottom clipping */
394 if (*y < buffer->_Ymin) {
395 *height -= (buffer->_Ymin - *y);
396 *y = buffer->_Ymin;
397 }
398
399 /* top clipping */
400 if (*y + *height > buffer->_Ymax)
401 *height -= (*y + *height - buffer->_Ymax - 1);
402
403 if (*height <= 0)
404 return GL_FALSE;
405
406 return GL_TRUE;
407 }
408
409 /**
410 * Creates a set of \c __GLcontextModes that a driver will expose.
411 *
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.
415 *
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
426 * the red value.
427 *
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.
434 *
435 * If in doubt, look at the tables used in the function.
436 *
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
453 * \c stencil_bits.
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.
466 *
467 * \returns
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
470 * \c fb_type).
471 *
472 * \todo
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.
478 */
479 __DRIconfig **
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)
485 {
486 static const uint8_t bits_table[4][4] = {
487 /* R G B A */
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 */
492 };
493
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 */
501 };
502
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 */
510 };
511
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 */
519 };
520
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 */
528 };
529
530 static const uint8_t bytes_per_pixel[6] = {
531 1, /* 3_3_2 */
532 1, /* 2_3_3_REV */
533 2, /* 5_6_5 */
534 2, /* 5_6_5_REV */
535 4, /* 8_8_8_8 */
536 4 /* 8_8_8_8_REV */
537 };
538
539 const uint8_t * bits;
540 const uint32_t * masks;
541 int index;
542 __DRIconfig **configs, **c;
543 __GLcontextModes *modes;
544 unsigned i, j, k, h;
545 unsigned num_modes;
546 unsigned num_accum_bits = 2;
547
548 switch ( fb_type ) {
549 case GL_UNSIGNED_BYTE_3_3_2:
550 index = 0;
551 break;
552 case GL_UNSIGNED_BYTE_2_3_3_REV:
553 index = 1;
554 break;
555 case GL_UNSIGNED_SHORT_5_6_5:
556 index = 2;
557 break;
558 case GL_UNSIGNED_SHORT_5_6_5_REV:
559 index = 3;
560 break;
561 case GL_UNSIGNED_INT_8_8_8_8:
562 index = 4;
563 break;
564 case GL_UNSIGNED_INT_8_8_8_8_REV:
565 index = 5;
566 break;
567 default:
568 fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
569 __FUNCTION__, __LINE__, fb_type );
570 return NULL;
571 }
572
573
574 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
575 * the _REV versions.
576 *
577 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
578 */
579
580 switch ( fb_format ) {
581 case GL_RGB:
582 masks = masks_table_rgb[ index ];
583 break;
584
585 case GL_RGBA:
586 masks = masks_table_rgba[ index ];
587 break;
588
589 case GL_BGR:
590 masks = masks_table_bgr[ index ];
591 break;
592
593 case GL_BGRA:
594 masks = masks_table_bgra[ index ];
595 break;
596
597 default:
598 fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
599 __FUNCTION__, __LINE__, fb_format );
600 return NULL;
601 }
602
603 switch ( bytes_per_pixel[ index ] ) {
604 case 1:
605 bits = bits_table[0];
606 break;
607 case 2:
608 bits = bits_table[1];
609 break;
610 default:
611 bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
612 ? bits_table[2]
613 : bits_table[3];
614 break;
615 }
616
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);
619 if (configs == NULL)
620 return NULL;
621
622 c = 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;
629 c++;
630
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;
642
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;
648
649 modes->stencilBits = stencil_bits[k];
650 modes->depthBits = depth_bits[k];
651
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;
662
663 if ( db_modes[i] == GLX_NONE ) {
664 modes->doubleBufferMode = GL_FALSE;
665 }
666 else {
667 modes->doubleBufferMode = GL_TRUE;
668 modes->swapMethod = db_modes[i];
669 }
670
671 modes->samples = msaa_samples[h];
672 modes->sampleBuffers = modes->samples ? 1 : 0;
673
674
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);
681
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 :
689 0;
690 }
691 }
692 }
693 }
694 *c = NULL;
695
696 return configs;
697 }
698
699 __DRIconfig **driConcatConfigs(__DRIconfig **a,
700 __DRIconfig **b)
701 {
702 __DRIconfig **all;
703 int i, j, index;
704
705 i = 0;
706 while (a[i] != NULL)
707 i++;
708 j = 0;
709 while (b[j] != NULL)
710 j++;
711
712 all = _mesa_malloc((i + j + 1) * sizeof *all);
713 index = 0;
714 for (i = 0; a[i] != NULL; i++)
715 all[index++] = a[i];
716 for (j = 0; b[j] != NULL; j++)
717 all[index++] = b[j];
718 all[index++] = NULL;
719
720 _mesa_free(a);
721 _mesa_free(b);
722
723 return all;
724 }
725
726 #define __ATTRIB(attrib, field) \
727 { attrib, offsetof(__GLcontextModes, field) }
728
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),
769
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)
776 };
777
778 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
779
780 static int
781 driGetConfigAttribIndex(const __DRIconfig *config,
782 unsigned int index, unsigned int *value)
783 {
784 switch (attribMap[index].attrib) {
785 case __DRI_ATTRIB_RENDER_TYPE:
786 if (config->modes.rgbMode)
787 *value = __DRI_ATTRIB_RGBA_BIT;
788 else
789 *value = __DRI_ATTRIB_COLOR_INDEX_BIT;
790 break;
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;
796 else
797 *value = 0;
798 break;
799 case __DRI_ATTRIB_SWAP_METHOD:
800 break;
801
802 case __DRI_ATTRIB_FLOAT_MODE:
803 *value = config->modes.floatMode;
804 break;
805
806 default:
807 *value = *(unsigned int *)
808 ((char *) &config->modes + attribMap[index].offset);
809
810 break;
811 }
812
813 return GL_TRUE;
814 }
815
816 int
817 driGetConfigAttrib(const __DRIconfig *config,
818 unsigned int attrib, unsigned int *value)
819 {
820 int i;
821
822 for (i = 0; i < ARRAY_SIZE(attribMap); i++)
823 if (attribMap[i].attrib == attrib)
824 return driGetConfigAttribIndex(config, i, value);
825
826 return GL_FALSE;
827 }
828
829 int
830 driIndexConfigAttrib(const __DRIconfig *config, int index,
831 unsigned int *attrib, unsigned int *value)
832 {
833 if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
834 *attrib = attribMap[index].attrib;
835 return driGetConfigAttribIndex(config, index, value);
836 }
837
838 return GL_FALSE;
839 }