Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 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 |
||
30 | */ |
||
31 | |||
32 | #include |
||
33 | #include |
||
34 | #include |
||
35 | #include |
||
36 | #include |
||
37 | #include "main/macros.h" |
||
38 | #include "main/mtypes.h" |
||
39 | #include "main/cpuinfo.h" |
||
40 | #include "main/extensions.h" |
||
41 | #include "utils.h" |
||
42 | #include "dri_util.h" |
||
43 | |||
44 | |||
45 | uint64_t |
||
46 | driParseDebugString( const char * debug, |
||
47 | const struct dri_debug_control * control ) |
||
48 | { |
||
49 | uint64_t flag = 0; |
||
50 | |||
51 | if ( debug != NULL ) { |
||
52 | while( control->string != NULL ) { |
||
53 | if ( !strcmp( debug, "all" ) || |
||
54 | strstr( debug, control->string ) != NULL ) { |
||
55 | flag |= control->flag; |
||
56 | } |
||
57 | |||
58 | control++; |
||
59 | } |
||
60 | } |
||
61 | |||
62 | return flag; |
||
63 | } |
||
64 | |||
65 | |||
66 | |||
67 | /** |
||
68 | * Create the \c GL_RENDERER string for DRI drivers. |
||
69 | * |
||
70 | * Almost all DRI drivers use a \c GL_RENDERER string of the form: |
||
71 | * |
||
72 | * "Mesa DRI |
||
73 | * |
||
74 | * Using the supplied chip name, driver data, and AGP speed, this function |
||
75 | * creates the string. |
||
76 | * |
||
77 | * \param buffer Buffer to hold the \c GL_RENDERER string. |
||
78 | * \param hardware_name Name of the hardware. |
||
79 | * \param agp_mode AGP mode (speed). |
||
80 | * |
||
81 | * \returns |
||
82 | * The length of the string stored in \c buffer. This does \b not include |
||
83 | * the terminating \c NUL character. |
||
84 | */ |
||
85 | unsigned |
||
86 | driGetRendererString( char * buffer, const char * hardware_name, |
||
87 | GLuint agp_mode ) |
||
88 | { |
||
89 | unsigned offset; |
||
90 | char *cpu; |
||
91 | |||
92 | offset = sprintf( buffer, "Mesa DRI %s", hardware_name ); |
||
93 | |||
94 | /* Append any AGP-specific information. |
||
95 | */ |
||
96 | switch ( agp_mode ) { |
||
97 | case 1: |
||
98 | case 2: |
||
99 | case 4: |
||
100 | case 8: |
||
101 | offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode ); |
||
102 | break; |
||
103 | |||
104 | default: |
||
105 | break; |
||
106 | } |
||
107 | |||
108 | /* Append any CPU-specific information. |
||
109 | */ |
||
110 | cpu = _mesa_get_cpu_string(); |
||
111 | if (cpu) { |
||
112 | offset += sprintf(buffer + offset, " %s", cpu); |
||
113 | free(cpu); |
||
114 | } |
||
115 | |||
116 | return offset; |
||
117 | } |
||
118 | |||
119 | |||
120 | /** |
||
121 | * Creates a set of \c struct gl_config that a driver will expose. |
||
122 | * |
||
123 | * A set of \c struct gl_config will be created based on the supplied |
||
124 | * parameters. The number of modes processed will be 2 * |
||
125 | * \c num_depth_stencil_bits * \c num_db_modes. |
||
126 | * |
||
127 | * For the most part, data is just copied from \c depth_bits, \c stencil_bits, |
||
128 | * \c db_modes, and \c visType into each \c struct gl_config element. |
||
129 | * However, the meanings of \c fb_format and \c fb_type require further |
||
130 | * explanation. The \c fb_format specifies which color components are in |
||
131 | * each pixel and what the default order is. For example, \c GL_RGB specifies |
||
132 | * that red, green, blue are available and red is in the "most significant" |
||
133 | * position and blue is in the "least significant". The \c fb_type specifies |
||
134 | * the bit sizes of each component and the actual ordering. For example, if |
||
135 | * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11] |
||
136 | * are the blue value, bits [10:5] are the green value, and bits [4:0] are |
||
137 | * the red value. |
||
138 | * |
||
139 | * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either |
||
140 | * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the |
||
141 | * \c struct gl_config structure is \b identical to the \c GL_RGBA or |
||
142 | * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as |
||
143 | * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8 |
||
144 | * still uses 32-bits. |
||
145 | * |
||
146 | * If in doubt, look at the tables used in the function. |
||
147 | * |
||
148 | * \param ptr_to_modes Pointer to a pointer to a linked list of |
||
149 | * \c struct gl_config. Upon completion, a pointer to |
||
150 | * the next element to be process will be stored here. |
||
151 | * If the function fails and returns \c GL_FALSE, this |
||
152 | * value will be unmodified, but some elements in the |
||
153 | * linked list may be modified. |
||
154 | * \param format Mesa mesa_format enum describing the pixel format |
||
155 | * \param depth_bits Array of depth buffer sizes to be exposed. |
||
156 | * \param stencil_bits Array of stencil buffer sizes to be exposed. |
||
157 | * \param num_depth_stencil_bits Number of entries in both \c depth_bits and |
||
158 | * \c stencil_bits. |
||
159 | * \param db_modes Array of buffer swap modes. If an element has a |
||
160 | * value of \c GLX_NONE, then it represents a |
||
161 | * single-buffered mode. Other valid values are |
||
162 | * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and |
||
163 | * \c GLX_SWAP_UNDEFINED_OML. See the |
||
164 | * GLX_OML_swap_method extension spec for more details. |
||
165 | * \param num_db_modes Number of entries in \c db_modes. |
||
166 | * \param msaa_samples Array of msaa sample count. 0 represents a visual |
||
167 | * without a multisample buffer. |
||
168 | * \param num_msaa_modes Number of entries in \c msaa_samples. |
||
169 | * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or |
||
170 | * \c GLX_DIRECT_COLOR. |
||
171 | * |
||
172 | * \returns |
||
173 | * Pointer to any array of pointers to the \c __DRIconfig structures created |
||
174 | * for the specified formats. If there is an error, \c NULL is returned. |
||
175 | * Currently the only cause of failure is a bad parameter (i.e., unsupported |
||
176 | * \c format). |
||
177 | */ |
||
178 | __DRIconfig ** |
||
179 | driCreateConfigs(mesa_format format, |
||
180 | const uint8_t * depth_bits, const uint8_t * stencil_bits, |
||
181 | unsigned num_depth_stencil_bits, |
||
182 | const GLenum * db_modes, unsigned num_db_modes, |
||
183 | const uint8_t * msaa_samples, unsigned num_msaa_modes, |
||
184 | GLboolean enable_accum) |
||
185 | { |
||
186 | static const uint32_t masks_table[][4] = { |
||
187 | /* MESA_FORMAT_B5G6R5_UNORM */ |
||
188 | { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, |
||
189 | /* MESA_FORMAT_B8G8R8X8_UNORM */ |
||
190 | { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, |
||
191 | /* MESA_FORMAT_B8G8R8A8_UNORM */ |
||
192 | { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, |
||
193 | /* MESA_FORMAT_B10G10R10X2_UNORM */ |
||
194 | { 0x3FF00000, 0x000FFC00, 0x000003FF, 0x00000000 }, |
||
195 | /* MESA_FORMAT_B10G10R10A2_UNORM */ |
||
196 | { 0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000 }, |
||
197 | }; |
||
198 | |||
199 | const uint32_t * masks; |
||
200 | __DRIconfig **configs, **c; |
||
201 | struct gl_config *modes; |
||
202 | unsigned i, j, k, h; |
||
203 | unsigned num_modes; |
||
204 | unsigned num_accum_bits = (enable_accum) ? 2 : 1; |
||
205 | int red_bits; |
||
206 | int green_bits; |
||
207 | int blue_bits; |
||
208 | int alpha_bits; |
||
209 | bool is_srgb; |
||
210 | |||
211 | switch (format) { |
||
212 | case MESA_FORMAT_B5G6R5_UNORM: |
||
213 | masks = masks_table[0]; |
||
214 | break; |
||
215 | case MESA_FORMAT_B8G8R8X8_UNORM: |
||
216 | masks = masks_table[1]; |
||
217 | break; |
||
218 | case MESA_FORMAT_B8G8R8A8_UNORM: |
||
219 | case MESA_FORMAT_B8G8R8A8_SRGB: |
||
220 | masks = masks_table[2]; |
||
221 | break; |
||
222 | case MESA_FORMAT_B10G10R10X2_UNORM: |
||
223 | masks = masks_table[3]; |
||
224 | break; |
||
225 | case MESA_FORMAT_B10G10R10A2_UNORM: |
||
226 | masks = masks_table[4]; |
||
227 | break; |
||
228 | default: |
||
229 | fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n", |
||
230 | __func__, __LINE__, |
||
231 | _mesa_get_format_name(format), format); |
||
232 | return NULL; |
||
233 | } |
||
234 | |||
235 | red_bits = _mesa_get_format_bits(format, GL_RED_BITS); |
||
236 | green_bits = _mesa_get_format_bits(format, GL_GREEN_BITS); |
||
237 | blue_bits = _mesa_get_format_bits(format, GL_BLUE_BITS); |
||
238 | alpha_bits = _mesa_get_format_bits(format, GL_ALPHA_BITS); |
||
239 | is_srgb = _mesa_get_format_color_encoding(format) == GL_SRGB; |
||
240 | |||
241 | num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes; |
||
242 | configs = calloc(num_modes + 1, sizeof *configs); |
||
243 | if (configs == NULL) |
||
244 | return NULL; |
||
245 | |||
246 | c = configs; |
||
247 | for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { |
||
248 | for ( i = 0 ; i < num_db_modes ; i++ ) { |
||
249 | for ( h = 0 ; h < num_msaa_modes; h++ ) { |
||
250 | for ( j = 0 ; j < num_accum_bits ; j++ ) { |
||
251 | *c = malloc (sizeof **c); |
||
252 | modes = &(*c)->modes; |
||
253 | c++; |
||
254 | |||
255 | memset(modes, 0, sizeof *modes); |
||
256 | modes->redBits = red_bits; |
||
257 | modes->greenBits = green_bits; |
||
258 | modes->blueBits = blue_bits; |
||
259 | modes->alphaBits = alpha_bits; |
||
260 | modes->redMask = masks[0]; |
||
261 | modes->greenMask = masks[1]; |
||
262 | modes->blueMask = masks[2]; |
||
263 | modes->alphaMask = masks[3]; |
||
264 | modes->rgbBits = modes->redBits + modes->greenBits |
||
265 | + modes->blueBits + modes->alphaBits; |
||
266 | |||
267 | modes->accumRedBits = 16 * j; |
||
268 | modes->accumGreenBits = 16 * j; |
||
269 | modes->accumBlueBits = 16 * j; |
||
270 | modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; |
||
271 | modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; |
||
272 | |||
273 | modes->stencilBits = stencil_bits[k]; |
||
274 | modes->depthBits = depth_bits[k]; |
||
275 | |||
276 | modes->transparentPixel = GLX_NONE; |
||
277 | modes->transparentRed = GLX_DONT_CARE; |
||
278 | modes->transparentGreen = GLX_DONT_CARE; |
||
279 | modes->transparentBlue = GLX_DONT_CARE; |
||
280 | modes->transparentAlpha = GLX_DONT_CARE; |
||
281 | modes->transparentIndex = GLX_DONT_CARE; |
||
282 | modes->rgbMode = GL_TRUE; |
||
283 | |||
284 | if ( db_modes[i] == GLX_NONE ) { |
||
285 | modes->doubleBufferMode = GL_FALSE; |
||
286 | } |
||
287 | else { |
||
288 | modes->doubleBufferMode = GL_TRUE; |
||
289 | modes->swapMethod = db_modes[i]; |
||
290 | } |
||
291 | |||
292 | modes->samples = msaa_samples[h]; |
||
293 | modes->sampleBuffers = modes->samples ? 1 : 0; |
||
294 | |||
295 | |||
296 | modes->haveAccumBuffer = ((modes->accumRedBits + |
||
297 | modes->accumGreenBits + |
||
298 | modes->accumBlueBits + |
||
299 | modes->accumAlphaBits) > 0); |
||
300 | modes->haveDepthBuffer = (modes->depthBits > 0); |
||
301 | modes->haveStencilBuffer = (modes->stencilBits > 0); |
||
302 | |||
303 | modes->bindToTextureRgb = GL_TRUE; |
||
304 | modes->bindToTextureRgba = GL_TRUE; |
||
305 | modes->bindToMipmapTexture = GL_FALSE; |
||
306 | modes->bindToTextureTargets = |
||
307 | __DRI_ATTRIB_TEXTURE_1D_BIT | |
||
308 | __DRI_ATTRIB_TEXTURE_2D_BIT | |
||
309 | __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT; |
||
310 | |||
311 | modes->yInverted = GL_TRUE; |
||
312 | modes->sRGBCapable = is_srgb; |
||
313 | } |
||
314 | } |
||
315 | } |
||
316 | } |
||
317 | *c = NULL; |
||
318 | |||
319 | return configs; |
||
320 | } |
||
321 | |||
322 | __DRIconfig **driConcatConfigs(__DRIconfig **a, |
||
323 | __DRIconfig **b) |
||
324 | { |
||
325 | __DRIconfig **all; |
||
326 | int i, j, index; |
||
327 | |||
328 | if (a == NULL || a[0] == NULL) |
||
329 | return b; |
||
330 | else if (b == NULL || b[0] == NULL) |
||
331 | return a; |
||
332 | |||
333 | i = 0; |
||
334 | while (a[i] != NULL) |
||
335 | i++; |
||
336 | j = 0; |
||
337 | while (b[j] != NULL) |
||
338 | j++; |
||
339 | |||
340 | all = malloc((i + j + 1) * sizeof *all); |
||
341 | index = 0; |
||
342 | for (i = 0; a[i] != NULL; i++) |
||
343 | all[index++] = a[i]; |
||
344 | for (j = 0; b[j] != NULL; j++) |
||
345 | all[index++] = b[j]; |
||
346 | all[index++] = NULL; |
||
347 | |||
348 | free(a); |
||
349 | free(b); |
||
350 | |||
351 | return all; |
||
352 | } |
||
353 | |||
354 | #define __ATTRIB(attrib, field) \ |
||
355 | { attrib, offsetof(struct gl_config, field) } |
||
356 | |||
357 | static const struct { unsigned int attrib, offset; } attribMap[] = { |
||
358 | __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), |
||
359 | __ATTRIB(__DRI_ATTRIB_LEVEL, level), |
||
360 | __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), |
||
361 | __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), |
||
362 | __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), |
||
363 | __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), |
||
364 | __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), |
||
365 | __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), |
||
366 | __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), |
||
367 | __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), |
||
368 | __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), |
||
369 | __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), |
||
370 | __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), |
||
371 | __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), |
||
372 | __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), |
||
373 | __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), |
||
374 | __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), |
||
375 | __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), |
||
376 | __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), |
||
377 | __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), |
||
378 | __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), |
||
379 | __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), |
||
380 | __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), |
||
381 | __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), |
||
382 | __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), |
||
383 | __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), |
||
384 | __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), |
||
385 | __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), |
||
386 | __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), |
||
387 | __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), |
||
388 | __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), |
||
389 | __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), |
||
390 | __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), |
||
391 | __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), |
||
392 | __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), |
||
393 | __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), |
||
394 | __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets), |
||
395 | __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), |
||
396 | __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable), |
||
397 | |||
398 | /* The struct field doesn't matter here, these are handled by the |
||
399 | * switch in driGetConfigAttribIndex. We need them in the array |
||
400 | * so the iterator includes them though.*/ |
||
401 | __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level), |
||
402 | __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level), |
||
403 | __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level) |
||
404 | }; |
||
405 | |||
406 | |||
407 | /** |
||
408 | * Return the value of a configuration attribute. The attribute is |
||
409 | * indicated by the index. |
||
410 | */ |
||
411 | static int |
||
412 | driGetConfigAttribIndex(const __DRIconfig *config, |
||
413 | unsigned int index, unsigned int *value) |
||
414 | { |
||
415 | switch (attribMap[index].attrib) { |
||
416 | case __DRI_ATTRIB_RENDER_TYPE: |
||
417 | /* no support for color index mode */ |
||
418 | *value = __DRI_ATTRIB_RGBA_BIT; |
||
419 | break; |
||
420 | case __DRI_ATTRIB_CONFIG_CAVEAT: |
||
421 | if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG) |
||
422 | *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG; |
||
423 | else if (config->modes.visualRating == GLX_SLOW_CONFIG) |
||
424 | *value = __DRI_ATTRIB_SLOW_BIT; |
||
425 | else |
||
426 | *value = 0; |
||
427 | break; |
||
428 | case __DRI_ATTRIB_SWAP_METHOD: |
||
429 | /* XXX no return value??? */ |
||
430 | break; |
||
431 | |||
432 | default: |
||
433 | /* any other int-sized field */ |
||
434 | *value = *(unsigned int *) |
||
435 | ((char *) &config->modes + attribMap[index].offset); |
||
436 | |||
437 | break; |
||
438 | } |
||
439 | |||
440 | return GL_TRUE; |
||
441 | } |
||
442 | |||
443 | |||
444 | /** |
||
445 | * Get the value of a configuration attribute. |
||
446 | * \param attrib the attribute (one of the _DRI_ATTRIB_x tokens) |
||
447 | * \param value returns the attribute's value |
||
448 | * \return 1 for success, 0 for failure |
||
449 | */ |
||
450 | int |
||
451 | driGetConfigAttrib(const __DRIconfig *config, |
||
452 | unsigned int attrib, unsigned int *value) |
||
453 | { |
||
454 | int i; |
||
455 | |||
456 | for (i = 0; i < ARRAY_SIZE(attribMap); i++) |
||
457 | if (attribMap[i].attrib == attrib) |
||
458 | return driGetConfigAttribIndex(config, i, value); |
||
459 | |||
460 | return GL_FALSE; |
||
461 | } |
||
462 | |||
463 | |||
464 | /** |
||
465 | * Get a configuration attribute name and value, given an index. |
||
466 | * \param index which field of the __DRIconfig to query |
||
467 | * \param attrib returns the attribute name (one of the _DRI_ATTRIB_x tokens) |
||
468 | * \param value returns the attribute's value |
||
469 | * \return 1 for success, 0 for failure |
||
470 | */ |
||
471 | int |
||
472 | driIndexConfigAttrib(const __DRIconfig *config, int index, |
||
473 | unsigned int *attrib, unsigned int *value) |
||
474 | { |
||
475 | if (index >= 0 && index < ARRAY_SIZE(attribMap)) { |
||
476 | *attrib = attribMap[index].attrib; |
||
477 | return driGetConfigAttribIndex(config, index, value); |
||
478 | } |
||
479 | |||
480 | return GL_FALSE; |
||
481 | } |
||
482 | |||
483 | /** |
||
484 | * Implement queries for values that are common across all Mesa drivers |
||
485 | * |
||
486 | * Currently only the following queries are supported by this function: |
||
487 | * |
||
488 | * - \c __DRI2_RENDERER_VERSION |
||
489 | * - \c __DRI2_RENDERER_PREFERRED_PROFILE |
||
490 | * - \c __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION |
||
491 | * - \c __DRI2_RENDERER_OPENGL_COMPATIBLITY_PROFILE_VERSION |
||
492 | * - \c __DRI2_RENDERER_ES_PROFILE_VERSION |
||
493 | * - \c __DRI2_RENDERER_ES2_PROFILE_VERSION |
||
494 | * |
||
495 | * \returns |
||
496 | * Zero if a recognized value of \c param is supplied, -1 otherwise. |
||
497 | */ |
||
498 | int |
||
499 | driQueryRendererIntegerCommon(__DRIscreen *psp, int param, unsigned int *value) |
||
500 | { |
||
501 | switch (param) { |
||
502 | case __DRI2_RENDERER_VERSION: { |
||
503 | static const char *const ver = PACKAGE_VERSION; |
||
504 | char *endptr; |
||
505 | int v[3]; |
||
506 | |||
507 | v[0] = strtol(ver, &endptr, 10); |
||
508 | assert(endptr[0] == '.'); |
||
509 | if (endptr[0] != '.') |
||
510 | return -1; |
||
511 | |||
512 | v[1] = strtol(endptr + 1, &endptr, 10); |
||
513 | assert(endptr[0] == '.'); |
||
514 | if (endptr[0] != '.') |
||
515 | return -1; |
||
516 | |||
517 | v[2] = strtol(endptr + 1, &endptr, 10); |
||
518 | |||
519 | value[0] = v[0]; |
||
520 | value[1] = v[1]; |
||
521 | value[2] = v[2]; |
||
522 | return 0; |
||
523 | } |
||
524 | case __DRI2_RENDERER_PREFERRED_PROFILE: |
||
525 | value[0] = (psp->max_gl_core_version != 0) |
||
526 | ? (1U << __DRI_API_OPENGL_CORE) : (1U << __DRI_API_OPENGL); |
||
527 | return 0; |
||
528 | case __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION: |
||
529 | value[0] = psp->max_gl_core_version / 10; |
||
530 | value[1] = psp->max_gl_core_version % 10; |
||
531 | return 0; |
||
532 | case __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION: |
||
533 | value[0] = psp->max_gl_compat_version / 10; |
||
534 | value[1] = psp->max_gl_compat_version % 10; |
||
535 | return 0; |
||
536 | case __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION: |
||
537 | value[0] = psp->max_gl_es1_version / 10; |
||
538 | value[1] = psp->max_gl_es1_version % 10; |
||
539 | return 0; |
||
540 | case __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION: |
||
541 | value[0] = psp->max_gl_es2_version / 10; |
||
542 | value[1] = psp->max_gl_es2_version % 10; |
||
543 | return 0; |
||
544 | default: |
||
545 | break; |
||
546 | } |
||
547 | |||
548 | return -1; |
||
549 | }><>><>>>>>>> |