1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2010  VMware, Inc.  All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26#include <stdio.h>
27#include "context.h"
28#include "imports.h"
29#include "mtypes.h"
30#include "version.h"
31#include "git_sha1.h"
32
33/**
34 * Scans 'string' to see if it ends with 'ending'.
35 */
36static bool
37check_for_ending(const char *string, const char *ending)
38{
39   const size_t len1 = strlen(string);
40   const size_t len2 = strlen(ending);
41
42   if (len2 > len1)
43      return false;
44
45   return strcmp(string + (len1 - len2), ending) == 0;
46}
47
48/**
49 * Returns the gl override data
50 *
51 * version > 0 indicates there is an override requested
52 * fwd_context is only valid if version > 0
53 */
54static void
55get_gl_override(gl_api api, int *version, bool *fwd_context,
56                bool *compat_context)
57{
58   const char *env_var = (api == API_OPENGL_CORE || api == API_OPENGL_COMPAT)
59      ? "MESA_GL_VERSION_OVERRIDE" : "MESA_GLES_VERSION_OVERRIDE";
60   const char *version_str;
61   int major, minor, n;
62   static struct override_info {
63      int version;
64      bool fc_suffix;
65      bool compat_suffix;
66   } override[] = {
67      [API_OPENGL_COMPAT] = { -1, false, false},
68      [API_OPENGLES]      = { -1, false, false},
69      [API_OPENGLES2]     = { -1, false, false},
70      [API_OPENGL_CORE]   = { -1, false, false},
71   };
72
73   STATIC_ASSERT(ARRAY_SIZE(override) == API_OPENGL_LAST + 1);
74
75   if (api == API_OPENGLES)
76      goto exit;
77
78   if (override[api].version < 0) {
79      override[api].version = 0;
80
81      version_str = getenv(env_var);
82      if (version_str) {
83         override[api].fc_suffix = check_for_ending(version_str, "FC");
84         override[api].compat_suffix = check_for_ending(version_str, "COMPAT");
85
86         n = sscanf(version_str, "%u.%u", &major, &minor);
87         if (n != 2) {
88            fprintf(stderr, "error: invalid value for %s: %s\n",
89                    env_var, version_str);
90            override[api].version = 0;
91         } else {
92            override[api].version = major * 10 + minor;
93
94            /* There is no such thing as compatibility or forward-compatible for
95             * OpenGL ES 2.0 or 3.x APIs.
96             */
97            if ((override[api].version < 30 && override[api].fc_suffix) ||
98                (api == API_OPENGLES2 && (override[api].fc_suffix ||
99                                          override[api].compat_suffix))) {
100               fprintf(stderr, "error: invalid value for %s: %s\n",
101                       env_var, version_str);
102            }
103         }
104      }
105   }
106
107exit:
108   *version = override[api].version;
109   *fwd_context = override[api].fc_suffix;
110   *compat_context = override[api].compat_suffix;
111}
112
113/**
114 * Builds the Mesa version string.
115 */
116static void
117create_version_string(struct gl_context *ctx, const char *prefix)
118{
119   static const int max = 100;
120
121   ctx->VersionString = malloc(max);
122   if (ctx->VersionString) {
123      _mesa_snprintf(ctx->VersionString, max,
124		     "%s%u.%u%s Mesa " PACKAGE_VERSION MESA_GIT_SHA1,
125		     prefix,
126		     ctx->Version / 10, ctx->Version % 10,
127		     (ctx->API == API_OPENGL_CORE) ? " (Core Profile)" :
128                     (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 32) ?
129                        " (Compatibility Profile)" : ""
130		     );
131   }
132}
133
134/**
135 * Override the context's version and/or API type if the environment variables
136 * MESA_GL_VERSION_OVERRIDE or MESA_GLES_VERSION_OVERRIDE are set.
137 *
138 * Example uses of MESA_GL_VERSION_OVERRIDE:
139 *
140 * 2.1: select a compatibility (non-Core) profile with GL version 2.1.
141 * 3.0: select a compatibility (non-Core) profile with GL version 3.0.
142 * 3.0FC: select a Core+Forward Compatible profile with GL version 3.0.
143 * 3.1: select GL version 3.1 with GL_ARB_compatibility enabled per the driver default.
144 * 3.1FC: select GL version 3.1 with forward compatibility and GL_ARB_compatibility disabled.
145 * 3.1COMPAT: select GL version 3.1 with GL_ARB_compatibility enabled.
146 * X.Y: override GL version to X.Y without changing the profile.
147 * X.YFC: select a Core+Forward Compatible profile with GL version X.Y.
148 * X.YCOMPAT: select a Compatibility profile with GL version X.Y.
149 *
150 * Example uses of MESA_GLES_VERSION_OVERRIDE:
151 *
152 * 2.0: select GLES version 2.0.
153 * 3.0: select GLES version 3.0.
154 * 3.1: select GLES version 3.1.
155 */
156bool
157_mesa_override_gl_version_contextless(struct gl_constants *consts,
158                                      gl_api *apiOut, GLuint *versionOut)
159{
160   int version;
161   bool fwd_context, compat_context;
162
163   get_gl_override(*apiOut, &version, &fwd_context, &compat_context);
164
165   if (version > 0) {
166      *versionOut = version;
167
168      /* Modify the API and context flags as needed. */
169      if (*apiOut == API_OPENGL_CORE || *apiOut == API_OPENGL_COMPAT) {
170         if (version >= 30 && fwd_context) {
171            *apiOut = API_OPENGL_CORE;
172            consts->ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
173         } else if (compat_context) {
174            *apiOut = API_OPENGL_COMPAT;
175         }
176      }
177
178      return true;
179   }
180   return false;
181}
182
183void
184_mesa_override_gl_version(struct gl_context *ctx)
185{
186   if (_mesa_override_gl_version_contextless(&ctx->Const, &ctx->API,
187                                             &ctx->Version)) {
188      /* We need to include API in version string for OpenGL ES, otherwise
189       * application can not detect GLES via glGetString(GL_VERSION) query.
190       *
191       * From OpenGL ES 3.2 spec, Page 436:
192       *
193       *     "The VERSION string is laid out as follows:
194       *
195       *     OpenGL ES N.M vendor-specific information"
196       *
197       * From OpenGL 4.5 spec, Page 538:
198       *
199       *     "The VERSION and SHADING_LANGUAGE_VERSION strings are laid out as
200       *     follows:
201       *
202       *     <version number><space><vendor-specific information>"
203       */
204      create_version_string(ctx, _mesa_is_gles(ctx) ? "OpenGL ES " : "");
205      ctx->Extensions.Version = ctx->Version;
206   }
207}
208
209/**
210 * Override the context's GLSL version if the environment variable
211 * MESA_GLSL_VERSION_OVERRIDE is set. Valid values for
212 * MESA_GLSL_VERSION_OVERRIDE are integers, such as "130".
213 */
214void
215_mesa_override_glsl_version(struct gl_constants *consts)
216{
217   const char *env_var = "MESA_GLSL_VERSION_OVERRIDE";
218   const char *version;
219   int n;
220
221   version = getenv(env_var);
222   if (!version) {
223      return;
224   }
225
226   n = sscanf(version, "%u", &consts->GLSLVersion);
227   if (n != 1) {
228      fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version);
229      return;
230   }
231}
232
233/**
234 * Examine enabled GL extensions to determine GL version.
235 */
236static GLuint
237compute_version(const struct gl_extensions *extensions,
238                const struct gl_constants *consts, gl_api api)
239{
240   GLuint major, minor, version;
241
242   const bool ver_1_3 = (extensions->ARB_texture_border_clamp &&
243                         extensions->ARB_texture_cube_map &&
244                         extensions->ARB_texture_env_combine &&
245                         extensions->ARB_texture_env_dot3);
246   const bool ver_1_4 = (ver_1_3 &&
247                         extensions->ARB_depth_texture &&
248                         extensions->ARB_shadow &&
249                         extensions->ARB_texture_env_crossbar &&
250                         extensions->EXT_blend_color &&
251                         extensions->EXT_blend_func_separate &&
252                         extensions->EXT_blend_minmax &&
253                         extensions->EXT_point_parameters);
254   const bool ver_1_5 = (ver_1_4 &&
255                         extensions->ARB_occlusion_query);
256   const bool ver_2_0 = (ver_1_5 &&
257                         extensions->ARB_point_sprite &&
258                         extensions->ARB_vertex_shader &&
259                         extensions->ARB_fragment_shader &&
260                         extensions->ARB_texture_non_power_of_two &&
261                         extensions->EXT_blend_equation_separate &&
262                         extensions->EXT_stencil_two_side);
263   const bool ver_2_1 = (ver_2_0 &&
264                         extensions->EXT_pixel_buffer_object &&
265                         extensions->EXT_texture_sRGB);
266   const bool ver_3_0 = (ver_2_1 &&
267                         consts->GLSLVersion >= 130 &&
268                         (consts->MaxSamples >= 4 || consts->FakeSWMSAA) &&
269                         (api == API_OPENGL_CORE ||
270                          extensions->ARB_color_buffer_float) &&
271                         extensions->ARB_depth_buffer_float &&
272                         extensions->ARB_half_float_vertex &&
273                         extensions->ARB_map_buffer_range &&
274                         extensions->ARB_shader_texture_lod &&
275                         extensions->ARB_texture_float &&
276                         extensions->ARB_texture_rg &&
277                         extensions->ARB_texture_compression_rgtc &&
278                         extensions->EXT_draw_buffers2 &&
279                         extensions->ARB_framebuffer_object &&
280                         extensions->EXT_framebuffer_sRGB &&
281                         extensions->EXT_packed_float &&
282                         extensions->EXT_texture_array &&
283                         extensions->EXT_texture_shared_exponent &&
284                         extensions->EXT_transform_feedback &&
285                         extensions->NV_conditional_render);
286   const bool ver_3_1 = (ver_3_0 &&
287                         consts->GLSLVersion >= 140 &&
288                         extensions->ARB_draw_instanced &&
289                         extensions->ARB_texture_buffer_object &&
290                         extensions->ARB_uniform_buffer_object &&
291                         extensions->EXT_texture_snorm &&
292                         extensions->NV_primitive_restart &&
293                         extensions->NV_texture_rectangle &&
294                         consts->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits >= 16);
295   const bool ver_3_2 = (ver_3_1 &&
296                         consts->GLSLVersion >= 150 &&
297                         extensions->ARB_depth_clamp &&
298                         extensions->ARB_draw_elements_base_vertex &&
299                         extensions->ARB_fragment_coord_conventions &&
300                         extensions->EXT_provoking_vertex &&
301                         extensions->ARB_seamless_cube_map &&
302                         extensions->ARB_sync &&
303                         extensions->ARB_texture_multisample &&
304                         extensions->EXT_vertex_array_bgra);
305   const bool ver_3_3 = (ver_3_2 &&
306                         consts->GLSLVersion >= 330 &&
307                         extensions->ARB_blend_func_extended &&
308                         extensions->ARB_explicit_attrib_location &&
309                         extensions->ARB_instanced_arrays &&
310                         extensions->ARB_occlusion_query2 &&
311                         extensions->ARB_shader_bit_encoding &&
312                         extensions->ARB_texture_rgb10_a2ui &&
313                         extensions->ARB_timer_query &&
314                         extensions->ARB_vertex_type_2_10_10_10_rev &&
315                         extensions->EXT_texture_swizzle);
316   /* ARB_sampler_objects is always enabled in mesa */
317
318   const bool ver_4_0 = (ver_3_3 &&
319                         consts->GLSLVersion >= 400 &&
320                         extensions->ARB_draw_buffers_blend &&
321                         extensions->ARB_draw_indirect &&
322                         extensions->ARB_gpu_shader5 &&
323                         extensions->ARB_gpu_shader_fp64 &&
324                         extensions->ARB_sample_shading &&
325                         extensions->ARB_tessellation_shader &&
326                         extensions->ARB_texture_buffer_object_rgb32 &&
327                         extensions->ARB_texture_cube_map_array &&
328                         extensions->ARB_texture_query_lod &&
329                         extensions->ARB_transform_feedback2 &&
330                         extensions->ARB_transform_feedback3);
331   const bool ver_4_1 = (ver_4_0 &&
332                         consts->GLSLVersion >= 410 &&
333                         extensions->ARB_ES2_compatibility &&
334                         extensions->ARB_shader_precision &&
335                         extensions->ARB_vertex_attrib_64bit &&
336                         extensions->ARB_viewport_array);
337   const bool ver_4_2 = (ver_4_1 &&
338                         consts->GLSLVersion >= 420 &&
339                         extensions->ARB_base_instance &&
340                         extensions->ARB_conservative_depth &&
341                         extensions->ARB_internalformat_query &&
342                         extensions->ARB_shader_atomic_counters &&
343                         extensions->ARB_shader_image_load_store &&
344                         extensions->ARB_shading_language_420pack &&
345                         extensions->ARB_shading_language_packing &&
346                         extensions->ARB_texture_compression_bptc &&
347                         extensions->ARB_transform_feedback_instanced);
348   const bool ver_4_3 = (ver_4_2 &&
349                         consts->GLSLVersion >= 430 &&
350                         consts->Program[MESA_SHADER_VERTEX].MaxUniformBlocks >= 14 &&
351                         extensions->ARB_ES3_compatibility &&
352                         extensions->ARB_arrays_of_arrays &&
353                         extensions->ARB_compute_shader &&
354                         extensions->ARB_copy_image &&
355                         extensions->ARB_explicit_uniform_location &&
356                         extensions->ARB_fragment_layer_viewport &&
357                         extensions->ARB_framebuffer_no_attachments &&
358                         extensions->ARB_internalformat_query2 &&
359                         extensions->ARB_robust_buffer_access_behavior &&
360                         extensions->ARB_shader_image_size &&
361                         extensions->ARB_shader_storage_buffer_object &&
362                         extensions->ARB_stencil_texturing &&
363                         extensions->ARB_texture_buffer_range &&
364                         extensions->ARB_texture_query_levels &&
365                         extensions->ARB_texture_view);
366   const bool ver_4_4 = (ver_4_3 &&
367                         consts->GLSLVersion >= 440 &&
368                         consts->MaxVertexAttribStride >= 2048 &&
369                         extensions->ARB_buffer_storage &&
370                         extensions->ARB_clear_texture &&
371                         extensions->ARB_enhanced_layouts &&
372                         extensions->ARB_query_buffer_object &&
373                         extensions->ARB_texture_mirror_clamp_to_edge &&
374                         extensions->ARB_texture_stencil8 &&
375                         extensions->ARB_vertex_type_10f_11f_11f_rev);
376   const bool ver_4_5 = (ver_4_4 &&
377                         consts->GLSLVersion >= 450 &&
378                         extensions->ARB_ES3_1_compatibility &&
379                         extensions->ARB_clip_control &&
380                         extensions->ARB_conditional_render_inverted &&
381                         extensions->ARB_cull_distance &&
382                         extensions->ARB_derivative_control &&
383                         extensions->ARB_shader_texture_image_samples &&
384                         extensions->NV_texture_barrier);
385   const bool ver_4_6 = (ver_4_5 &&
386                         consts->GLSLVersion >= 460 &&
387                         /* extensions->ARB_gl_spirv */ 0 &&
388                         /* extensions->ARB_spirv_extensions */ 0 &&
389                         extensions->ARB_indirect_parameters &&
390                         extensions->ARB_pipeline_statistics_query &&
391                         extensions->ARB_polygon_offset_clamp &&
392                         extensions->ARB_shader_atomic_counter_ops &&
393                         extensions->ARB_shader_draw_parameters &&
394                         extensions->ARB_shader_group_vote &&
395                         extensions->ARB_texture_filter_anisotropic &&
396                         extensions->ARB_transform_feedback_overflow_query);
397
398   if (ver_4_6) {
399      major = 4;
400      minor = 6;
401   }
402   else if (ver_4_5) {
403      major = 4;
404      minor = 5;
405   }
406   else if (ver_4_4) {
407      major = 4;
408      minor = 4;
409   }
410   else if (ver_4_3) {
411      major = 4;
412      minor = 3;
413   }
414   else if (ver_4_2) {
415      major = 4;
416      minor = 2;
417   }
418   else if (ver_4_1) {
419      major = 4;
420      minor = 1;
421   }
422   else if (ver_4_0) {
423      major = 4;
424      minor = 0;
425   }
426   else if (ver_3_3) {
427      major = 3;
428      minor = 3;
429   }
430   else if (ver_3_2) {
431      major = 3;
432      minor = 2;
433   }
434   else if (ver_3_1) {
435      major = 3;
436      minor = 1;
437   }
438   else if (ver_3_0) {
439      major = 3;
440      minor = 0;
441   }
442   else if (ver_2_1) {
443      major = 2;
444      minor = 1;
445   }
446   else if (ver_2_0) {
447      major = 2;
448      minor = 0;
449   }
450   else if (ver_1_5) {
451      major = 1;
452      minor = 5;
453   }
454   else if (ver_1_4) {
455      major = 1;
456      minor = 4;
457   }
458   else if (ver_1_3) {
459      major = 1;
460      minor = 3;
461   }
462   else {
463      major = 1;
464      minor = 2;
465   }
466
467   version = major * 10 + minor;
468
469   if (api == API_OPENGL_CORE && version < 31)
470      return 0;
471
472   return version;
473}
474
475static GLuint
476compute_version_es1(const struct gl_extensions *extensions)
477{
478   /* OpenGL ES 1.0 is derived from OpenGL 1.3 */
479   const bool ver_1_0 = (extensions->ARB_texture_env_combine &&
480                         extensions->ARB_texture_env_dot3);
481   /* OpenGL ES 1.1 is derived from OpenGL 1.5 */
482   const bool ver_1_1 = (ver_1_0 &&
483                         extensions->EXT_point_parameters);
484
485   if (ver_1_1) {
486      return 11;
487   } else if (ver_1_0) {
488      return 10;
489   } else {
490      return 0;
491   }
492}
493
494static GLuint
495compute_version_es2(const struct gl_extensions *extensions,
496                    const struct gl_constants *consts)
497{
498   /* OpenGL ES 2.0 is derived from OpenGL 2.0 */
499   const bool ver_2_0 = (extensions->ARB_texture_cube_map &&
500                         extensions->EXT_blend_color &&
501                         extensions->EXT_blend_func_separate &&
502                         extensions->EXT_blend_minmax &&
503                         extensions->ARB_vertex_shader &&
504                         extensions->ARB_fragment_shader &&
505                         extensions->ARB_texture_non_power_of_two &&
506                         extensions->EXT_blend_equation_separate);
507   /* FINISHME: This list isn't quite right. */
508   const bool ver_3_0 = (extensions->ARB_half_float_vertex &&
509                         extensions->ARB_internalformat_query &&
510                         extensions->ARB_map_buffer_range &&
511                         extensions->ARB_shader_texture_lod &&
512                         extensions->OES_texture_float &&
513                         extensions->OES_texture_half_float &&
514                         extensions->OES_texture_half_float_linear &&
515                         extensions->ARB_texture_rg &&
516                         extensions->ARB_depth_buffer_float &&
517                         extensions->ARB_framebuffer_object &&
518                         extensions->EXT_sRGB &&
519                         extensions->EXT_packed_float &&
520                         extensions->EXT_texture_array &&
521                         extensions->EXT_texture_shared_exponent &&
522                         extensions->EXT_texture_sRGB &&
523                         extensions->EXT_transform_feedback &&
524                         extensions->ARB_draw_instanced &&
525                         extensions->ARB_uniform_buffer_object &&
526                         extensions->EXT_texture_snorm &&
527                         extensions->NV_primitive_restart &&
528                         extensions->OES_depth_texture_cube_map &&
529                         extensions->EXT_texture_type_2_10_10_10_REV);
530   const bool es31_compute_shader =
531      consts->MaxComputeWorkGroupInvocations >= 128;
532   const bool ver_3_1 = (ver_3_0 &&
533                         consts->MaxVertexAttribStride >= 2048 &&
534                         extensions->ARB_arrays_of_arrays &&
535                         es31_compute_shader &&
536                         extensions->ARB_draw_indirect &&
537                         extensions->ARB_explicit_uniform_location &&
538                         extensions->ARB_framebuffer_no_attachments &&
539                         extensions->ARB_shader_atomic_counters &&
540                         extensions->ARB_shader_image_load_store &&
541                         extensions->ARB_shader_image_size &&
542                         extensions->ARB_shader_storage_buffer_object &&
543                         extensions->ARB_shading_language_packing &&
544                         extensions->ARB_stencil_texturing &&
545                         extensions->ARB_texture_multisample &&
546                         extensions->ARB_texture_gather &&
547                         extensions->MESA_shader_integer_functions &&
548                         extensions->EXT_shader_integer_mix);
549   const bool ver_3_2 = (ver_3_1 &&
550                         extensions->EXT_draw_buffers2 &&
551                         extensions->KHR_blend_equation_advanced &&
552                         extensions->KHR_robustness &&
553                         extensions->KHR_texture_compression_astc_ldr &&
554                         extensions->OES_copy_image &&
555                         extensions->ARB_draw_buffers_blend &&
556                         extensions->ARB_draw_elements_base_vertex &&
557                         extensions->OES_geometry_shader &&
558                         extensions->OES_primitive_bounding_box &&
559                         extensions->OES_sample_variables &&
560                         extensions->ARB_tessellation_shader &&
561                         extensions->ARB_texture_border_clamp &&
562                         extensions->OES_texture_buffer &&
563                         extensions->OES_texture_cube_map_array &&
564                         extensions->ARB_texture_stencil8);
565
566   if (ver_3_2) {
567      return 32;
568   } else if (ver_3_1) {
569      return 31;
570   } else if (ver_3_0) {
571      return 30;
572   } else if (ver_2_0) {
573      return 20;
574   } else {
575      return 0;
576   }
577}
578
579GLuint
580_mesa_get_version(const struct gl_extensions *extensions,
581                  struct gl_constants *consts, gl_api api)
582{
583   switch (api) {
584   case API_OPENGL_COMPAT:
585      /* Disable higher GLSL versions for legacy contexts.
586       * This disallows creation of higher compatibility contexts. */
587      if (!consts->AllowHigherCompatVersion) {
588         consts->GLSLVersion = consts->GLSLVersionCompat;
589      }
590      /* fall through */
591   case API_OPENGL_CORE:
592      return compute_version(extensions, consts, api);
593   case API_OPENGLES:
594      return compute_version_es1(extensions);
595   case API_OPENGLES2:
596      return compute_version_es2(extensions, consts);
597   }
598   return 0;
599}
600
601/**
602 * Set the context's Version and VersionString fields.
603 * This should only be called once as part of context initialization
604 * or to perform version check for GLX_ARB_create_context_profile.
605 */
606void
607_mesa_compute_version(struct gl_context *ctx)
608{
609   if (ctx->Version)
610      goto done;
611
612   ctx->Version = _mesa_get_version(&ctx->Extensions, &ctx->Const, ctx->API);
613   ctx->Extensions.Version = ctx->Version;
614
615   /* Make sure that the GLSL version lines up with the GL version. In some
616    * cases it can be too high, e.g. if an extension is missing.
617    */
618   if (_mesa_is_desktop_gl(ctx)) {
619      switch (ctx->Version) {
620      case 20:
621         /* fall-through, GLSL 1.20 is the minimum we support */
622      case 21:
623         ctx->Const.GLSLVersion = 120;
624         break;
625      case 30:
626         ctx->Const.GLSLVersion = 130;
627         break;
628      case 31:
629         ctx->Const.GLSLVersion = 140;
630         break;
631      case 32:
632         ctx->Const.GLSLVersion = 150;
633         break;
634      default:
635         if (ctx->Version >= 33)
636            ctx->Const.GLSLVersion = ctx->Version * 10;
637         break;
638      }
639   }
640
641   switch (ctx->API) {
642   case API_OPENGL_COMPAT:
643   case API_OPENGL_CORE:
644      create_version_string(ctx, "");
645      break;
646
647   case API_OPENGLES:
648      if (!ctx->Version) {
649         _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support.");
650         return;
651      }
652      create_version_string(ctx, "OpenGL ES-CM ");
653      break;
654
655   case API_OPENGLES2:
656      if (!ctx->Version) {
657         _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support.");
658         return;
659      }
660      create_version_string(ctx, "OpenGL ES ");
661      break;
662   }
663
664done:
665   if (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 31)
666      ctx->Extensions.ARB_compatibility = GL_TRUE;
667}
668
669
670void
671_mesa_get_driver_uuid(struct gl_context *ctx, GLint *uuid)
672{
673   ctx->Driver.GetDriverUuid(ctx, (char*) uuid);
674}
675
676void
677_mesa_get_device_uuid(struct gl_context *ctx, GLint *uuid)
678{
679   ctx->Driver.GetDeviceUuid(ctx, (char*) uuid);
680}
681
682/**
683 * Get the i-th GLSL version string.  If index=0, return the most recent
684 * supported version.
685 * \param ctx context to query
686 * \param index  which version string to return, or -1 if none
687 * \param versionOut returns the vesrion string
688 * \return total number of shading language versions.
689 */
690int
691_mesa_get_shading_language_version(const struct gl_context *ctx,
692                                   int index,
693                                   char **versionOut)
694{
695   int n = 0;
696
697#define GLSL_VERSION(S) \
698   if (n++ == index) \
699      *versionOut = S
700
701   /* GLSL core */
702   if (ctx->Const.GLSLVersion >= 460)
703      GLSL_VERSION("460");
704   if (ctx->Const.GLSLVersion >= 450)
705      GLSL_VERSION("450");
706   if (ctx->Const.GLSLVersion >= 440)
707      GLSL_VERSION("440");
708   if (ctx->Const.GLSLVersion >= 430)
709      GLSL_VERSION("430");
710   if (ctx->Const.GLSLVersion >= 420)
711      GLSL_VERSION("420");
712   if (ctx->Const.GLSLVersion >= 410)
713      GLSL_VERSION("410");
714   if (ctx->Const.GLSLVersion >= 400)
715      GLSL_VERSION("400");
716   if (ctx->Const.GLSLVersion >= 330)
717      GLSL_VERSION("330");
718   if (ctx->Const.GLSLVersion >= 150)
719      GLSL_VERSION("150");
720   if (ctx->Const.GLSLVersion >= 140)
721      GLSL_VERSION("140");
722   if (ctx->Const.GLSLVersion >= 130)
723      GLSL_VERSION("130");
724   if (ctx->Const.GLSLVersion >= 120)
725      GLSL_VERSION("120");
726   /* The GL spec says to return the empty string for GLSL 1.10 */
727   if (ctx->Const.GLSLVersion >= 110)
728      GLSL_VERSION("");
729
730   /* GLSL es */
731   if ((ctx->API == API_OPENGLES2 && ctx->Version >= 32) ||
732        ctx->Extensions.ARB_ES3_2_compatibility)
733      GLSL_VERSION("320 es");
734   if (_mesa_is_gles31(ctx) || ctx->Extensions.ARB_ES3_1_compatibility)
735      GLSL_VERSION("310 es");
736   if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility)
737      GLSL_VERSION("300 es");
738   if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility)
739      GLSL_VERSION("100");
740
741#undef GLSL_VERSION
742
743   return n;
744}
745