version.c revision 01e04c3f
1cdc920a0Smrg/*
2cdc920a0Smrg * Mesa 3-D graphics library
3cdc920a0Smrg *
4cdc920a0Smrg * Copyright (C) 2010  VMware, Inc.  All Rights Reserved.
5cdc920a0Smrg *
6cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7cdc920a0Smrg * copy of this software and associated documentation files (the "Software"),
8cdc920a0Smrg * to deal in the Software without restriction, including without limitation
9cdc920a0Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10cdc920a0Smrg * and/or sell copies of the Software, and to permit persons to whom the
11cdc920a0Smrg * Software is furnished to do so, subject to the following conditions:
12cdc920a0Smrg *
13cdc920a0Smrg * The above copyright notice and this permission notice shall be included
14cdc920a0Smrg * in all copies or substantial portions of the Software.
15cdc920a0Smrg *
16cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17cdc920a0Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18cdc920a0Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
23cdc920a0Smrg */
24cdc920a0Smrg
25cdc920a0Smrg
2601e04c3fSmrg#include <stdio.h>
2701e04c3fSmrg#include "context.h"
283464ebd5Sriastradh#include "imports.h"
293464ebd5Sriastradh#include "mtypes.h"
30cdc920a0Smrg#include "version.h"
313464ebd5Sriastradh#include "git_sha1.h"
32cdc920a0Smrg
33af69d88dSmrg/**
34af69d88dSmrg * Scans 'string' to see if it ends with 'ending'.
35af69d88dSmrg */
3601e04c3fSmrgstatic bool
37af69d88dSmrgcheck_for_ending(const char *string, const char *ending)
38af69d88dSmrg{
3901e04c3fSmrg   const size_t len1 = strlen(string);
4001e04c3fSmrg   const size_t len2 = strlen(ending);
41cdc920a0Smrg
4201e04c3fSmrg   if (len2 > len1)
4301e04c3fSmrg      return false;
44af69d88dSmrg
4501e04c3fSmrg   return strcmp(string + (len1 - len2), ending) == 0;
46af69d88dSmrg}
47cdc920a0Smrg
48cdc920a0Smrg/**
49af69d88dSmrg * Returns the gl override data
50af69d88dSmrg *
51af69d88dSmrg * version > 0 indicates there is an override requested
52af69d88dSmrg * fwd_context is only valid if version > 0
53cdc920a0Smrg */
54cdc920a0Smrgstatic void
5501e04c3fSmrgget_gl_override(gl_api api, int *version, bool *fwd_context,
5601e04c3fSmrg                bool *compat_context)
57af69d88dSmrg{
5801e04c3fSmrg   const char *env_var = (api == API_OPENGL_CORE || api == API_OPENGL_COMPAT)
5901e04c3fSmrg      ? "MESA_GL_VERSION_OVERRIDE" : "MESA_GLES_VERSION_OVERRIDE";
60af69d88dSmrg   const char *version_str;
61af69d88dSmrg   int major, minor, n;
6201e04c3fSmrg   static struct override_info {
6301e04c3fSmrg      int version;
6401e04c3fSmrg      bool fc_suffix;
6501e04c3fSmrg      bool compat_suffix;
6601e04c3fSmrg   } override[] = {
6701e04c3fSmrg      [API_OPENGL_COMPAT] = { -1, false, false},
6801e04c3fSmrg      [API_OPENGLES]      = { -1, false, false},
6901e04c3fSmrg      [API_OPENGLES2]     = { -1, false, false},
7001e04c3fSmrg      [API_OPENGL_CORE]   = { -1, false, false},
7101e04c3fSmrg   };
72af69d88dSmrg
7301e04c3fSmrg   STATIC_ASSERT(ARRAY_SIZE(override) == API_OPENGL_LAST + 1);
7401e04c3fSmrg
7501e04c3fSmrg   if (api == API_OPENGLES)
7601e04c3fSmrg      goto exit;
7701e04c3fSmrg
7801e04c3fSmrg   if (override[api].version < 0) {
7901e04c3fSmrg      override[api].version = 0;
80af69d88dSmrg
81af69d88dSmrg      version_str = getenv(env_var);
82af69d88dSmrg      if (version_str) {
8301e04c3fSmrg         override[api].fc_suffix = check_for_ending(version_str, "FC");
8401e04c3fSmrg         override[api].compat_suffix = check_for_ending(version_str, "COMPAT");
85af69d88dSmrg
86af69d88dSmrg         n = sscanf(version_str, "%u.%u", &major, &minor);
87af69d88dSmrg         if (n != 2) {
8801e04c3fSmrg            fprintf(stderr, "error: invalid value for %s: %s\n",
8901e04c3fSmrg                    env_var, version_str);
9001e04c3fSmrg            override[api].version = 0;
91af69d88dSmrg         } else {
9201e04c3fSmrg            override[api].version = major * 10 + minor;
9301e04c3fSmrg
9401e04c3fSmrg            /* There is no such thing as compatibility or forward-compatible for
9501e04c3fSmrg             * OpenGL ES 2.0 or 3.x APIs.
9601e04c3fSmrg             */
9701e04c3fSmrg            if ((override[api].version < 30 && override[api].fc_suffix) ||
9801e04c3fSmrg                (api == API_OPENGLES2 && (override[api].fc_suffix ||
9901e04c3fSmrg                                          override[api].compat_suffix))) {
10001e04c3fSmrg               fprintf(stderr, "error: invalid value for %s: %s\n",
10101e04c3fSmrg                       env_var, version_str);
102af69d88dSmrg            }
103af69d88dSmrg         }
104af69d88dSmrg      }
105af69d88dSmrg   }
106af69d88dSmrg
10701e04c3fSmrgexit:
10801e04c3fSmrg   *version = override[api].version;
10901e04c3fSmrg   *fwd_context = override[api].fc_suffix;
11001e04c3fSmrg   *compat_context = override[api].compat_suffix;
111af69d88dSmrg}
112af69d88dSmrg
113af69d88dSmrg/**
11401e04c3fSmrg * Builds the Mesa version string.
115af69d88dSmrg */
116af69d88dSmrgstatic void
117af69d88dSmrgcreate_version_string(struct gl_context *ctx, const char *prefix)
118cdc920a0Smrg{
1193464ebd5Sriastradh   static const int max = 100;
1203464ebd5Sriastradh
121af69d88dSmrg   ctx->VersionString = malloc(max);
122af69d88dSmrg   if (ctx->VersionString) {
123af69d88dSmrg      _mesa_snprintf(ctx->VersionString, max,
12401e04c3fSmrg		     "%s%u.%u%s Mesa " PACKAGE_VERSION MESA_GIT_SHA1,
125af69d88dSmrg		     prefix,
126af69d88dSmrg		     ctx->Version / 10, ctx->Version % 10,
12701e04c3fSmrg		     (ctx->API == API_OPENGL_CORE) ? " (Core Profile)" :
12801e04c3fSmrg                     (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 32) ?
12901e04c3fSmrg                        " (Compatibility Profile)" : ""
130af69d88dSmrg		     );
131af69d88dSmrg   }
132af69d88dSmrg}
133af69d88dSmrg
134af69d88dSmrg/**
13501e04c3fSmrg * Override the context's version and/or API type if the environment variables
13601e04c3fSmrg * MESA_GL_VERSION_OVERRIDE or MESA_GLES_VERSION_OVERRIDE are set.
137af69d88dSmrg *
138af69d88dSmrg * Example uses of MESA_GL_VERSION_OVERRIDE:
139af69d88dSmrg *
14001e04c3fSmrg * 2.1: select a compatibility (non-Core) profile with GL version 2.1.
14101e04c3fSmrg * 3.0: select a compatibility (non-Core) profile with GL version 3.0.
14201e04c3fSmrg * 3.0FC: select a Core+Forward Compatible profile with GL version 3.0.
14301e04c3fSmrg * 3.1: select GL version 3.1 with GL_ARB_compatibility enabled per the driver default.
14401e04c3fSmrg * 3.1FC: select GL version 3.1 with forward compatibility and GL_ARB_compatibility disabled.
14501e04c3fSmrg * 3.1COMPAT: select GL version 3.1 with GL_ARB_compatibility enabled.
14601e04c3fSmrg * X.Y: override GL version to X.Y without changing the profile.
14701e04c3fSmrg * X.YFC: select a Core+Forward Compatible profile with GL version X.Y.
14801e04c3fSmrg * X.YCOMPAT: select a Compatibility profile with GL version X.Y.
14901e04c3fSmrg *
15001e04c3fSmrg * Example uses of MESA_GLES_VERSION_OVERRIDE:
15101e04c3fSmrg *
15201e04c3fSmrg * 2.0: select GLES version 2.0.
15301e04c3fSmrg * 3.0: select GLES version 3.0.
15401e04c3fSmrg * 3.1: select GLES version 3.1.
155af69d88dSmrg */
156af69d88dSmrgbool
157af69d88dSmrg_mesa_override_gl_version_contextless(struct gl_constants *consts,
158af69d88dSmrg                                      gl_api *apiOut, GLuint *versionOut)
159af69d88dSmrg{
160af69d88dSmrg   int version;
16101e04c3fSmrg   bool fwd_context, compat_context;
162af69d88dSmrg
16301e04c3fSmrg   get_gl_override(*apiOut, &version, &fwd_context, &compat_context);
164af69d88dSmrg
165af69d88dSmrg   if (version > 0) {
166af69d88dSmrg      *versionOut = version;
16701e04c3fSmrg
16801e04c3fSmrg      /* Modify the API and context flags as needed. */
16901e04c3fSmrg      if (*apiOut == API_OPENGL_CORE || *apiOut == API_OPENGL_COMPAT) {
17001e04c3fSmrg         if (version >= 30 && fwd_context) {
17101e04c3fSmrg            *apiOut = API_OPENGL_CORE;
17201e04c3fSmrg            consts->ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
17301e04c3fSmrg         } else if (compat_context) {
17401e04c3fSmrg            *apiOut = API_OPENGL_COMPAT;
17501e04c3fSmrg         }
176af69d88dSmrg      }
17701e04c3fSmrg
17801e04c3fSmrg      return true;
179af69d88dSmrg   }
18001e04c3fSmrg   return false;
181af69d88dSmrg}
182af69d88dSmrg
183af69d88dSmrgvoid
184af69d88dSmrg_mesa_override_gl_version(struct gl_context *ctx)
185af69d88dSmrg{
186af69d88dSmrg   if (_mesa_override_gl_version_contextless(&ctx->Const, &ctx->API,
187af69d88dSmrg                                             &ctx->Version)) {
18801e04c3fSmrg      /* We need to include API in version string for OpenGL ES, otherwise
18901e04c3fSmrg       * application can not detect GLES via glGetString(GL_VERSION) query.
19001e04c3fSmrg       *
19101e04c3fSmrg       * From OpenGL ES 3.2 spec, Page 436:
19201e04c3fSmrg       *
19301e04c3fSmrg       *     "The VERSION string is laid out as follows:
19401e04c3fSmrg       *
19501e04c3fSmrg       *     OpenGL ES N.M vendor-specific information"
19601e04c3fSmrg       *
19701e04c3fSmrg       * From OpenGL 4.5 spec, Page 538:
19801e04c3fSmrg       *
19901e04c3fSmrg       *     "The VERSION and SHADING_LANGUAGE_VERSION strings are laid out as
20001e04c3fSmrg       *     follows:
20101e04c3fSmrg       *
20201e04c3fSmrg       *     <version number><space><vendor-specific information>"
20301e04c3fSmrg       */
20401e04c3fSmrg      create_version_string(ctx, _mesa_is_gles(ctx) ? "OpenGL ES " : "");
20501e04c3fSmrg      ctx->Extensions.Version = ctx->Version;
206af69d88dSmrg   }
207af69d88dSmrg}
208af69d88dSmrg
209af69d88dSmrg/**
210af69d88dSmrg * Override the context's GLSL version if the environment variable
211af69d88dSmrg * MESA_GLSL_VERSION_OVERRIDE is set. Valid values for
212af69d88dSmrg * MESA_GLSL_VERSION_OVERRIDE are integers, such as "130".
213af69d88dSmrg */
214af69d88dSmrgvoid
215af69d88dSmrg_mesa_override_glsl_version(struct gl_constants *consts)
216af69d88dSmrg{
217af69d88dSmrg   const char *env_var = "MESA_GLSL_VERSION_OVERRIDE";
218af69d88dSmrg   const char *version;
219af69d88dSmrg   int n;
220af69d88dSmrg
221af69d88dSmrg   version = getenv(env_var);
222af69d88dSmrg   if (!version) {
223af69d88dSmrg      return;
224af69d88dSmrg   }
225af69d88dSmrg
226af69d88dSmrg   n = sscanf(version, "%u", &consts->GLSLVersion);
227af69d88dSmrg   if (n != 1) {
228af69d88dSmrg      fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version);
229af69d88dSmrg      return;
230af69d88dSmrg   }
231af69d88dSmrg}
232af69d88dSmrg
233af69d88dSmrg/**
234af69d88dSmrg * Examine enabled GL extensions to determine GL version.
235af69d88dSmrg */
236af69d88dSmrgstatic GLuint
237af69d88dSmrgcompute_version(const struct gl_extensions *extensions,
238af69d88dSmrg                const struct gl_constants *consts, gl_api api)
239af69d88dSmrg{
240af69d88dSmrg   GLuint major, minor, version;
241af69d88dSmrg
24201e04c3fSmrg   const bool ver_1_3 = (extensions->ARB_texture_border_clamp &&
24301e04c3fSmrg                         extensions->ARB_texture_cube_map &&
24401e04c3fSmrg                         extensions->ARB_texture_env_combine &&
24501e04c3fSmrg                         extensions->ARB_texture_env_dot3);
24601e04c3fSmrg   const bool ver_1_4 = (ver_1_3 &&
24701e04c3fSmrg                         extensions->ARB_depth_texture &&
24801e04c3fSmrg                         extensions->ARB_shadow &&
24901e04c3fSmrg                         extensions->ARB_texture_env_crossbar &&
25001e04c3fSmrg                         extensions->EXT_blend_color &&
25101e04c3fSmrg                         extensions->EXT_blend_func_separate &&
25201e04c3fSmrg                         extensions->EXT_blend_minmax &&
25301e04c3fSmrg                         extensions->EXT_point_parameters);
25401e04c3fSmrg   const bool ver_1_5 = (ver_1_4 &&
25501e04c3fSmrg                         extensions->ARB_occlusion_query);
25601e04c3fSmrg   const bool ver_2_0 = (ver_1_5 &&
25701e04c3fSmrg                         extensions->ARB_point_sprite &&
25801e04c3fSmrg                         extensions->ARB_vertex_shader &&
25901e04c3fSmrg                         extensions->ARB_fragment_shader &&
26001e04c3fSmrg                         extensions->ARB_texture_non_power_of_two &&
26101e04c3fSmrg                         extensions->EXT_blend_equation_separate &&
26201e04c3fSmrg                         extensions->EXT_stencil_two_side);
26301e04c3fSmrg   const bool ver_2_1 = (ver_2_0 &&
26401e04c3fSmrg                         extensions->EXT_pixel_buffer_object &&
26501e04c3fSmrg                         extensions->EXT_texture_sRGB);
26601e04c3fSmrg   const bool ver_3_0 = (ver_2_1 &&
26701e04c3fSmrg                         consts->GLSLVersion >= 130 &&
26801e04c3fSmrg                         (consts->MaxSamples >= 4 || consts->FakeSWMSAA) &&
26901e04c3fSmrg                         (api == API_OPENGL_CORE ||
27001e04c3fSmrg                          extensions->ARB_color_buffer_float) &&
27101e04c3fSmrg                         extensions->ARB_depth_buffer_float &&
27201e04c3fSmrg                         extensions->ARB_half_float_vertex &&
27301e04c3fSmrg                         extensions->ARB_map_buffer_range &&
27401e04c3fSmrg                         extensions->ARB_shader_texture_lod &&
27501e04c3fSmrg                         extensions->ARB_texture_float &&
27601e04c3fSmrg                         extensions->ARB_texture_rg &&
27701e04c3fSmrg                         extensions->ARB_texture_compression_rgtc &&
27801e04c3fSmrg                         extensions->EXT_draw_buffers2 &&
27901e04c3fSmrg                         extensions->ARB_framebuffer_object &&
28001e04c3fSmrg                         extensions->EXT_framebuffer_sRGB &&
28101e04c3fSmrg                         extensions->EXT_packed_float &&
28201e04c3fSmrg                         extensions->EXT_texture_array &&
28301e04c3fSmrg                         extensions->EXT_texture_shared_exponent &&
28401e04c3fSmrg                         extensions->EXT_transform_feedback &&
28501e04c3fSmrg                         extensions->NV_conditional_render);
28601e04c3fSmrg   const bool ver_3_1 = (ver_3_0 &&
28701e04c3fSmrg                         consts->GLSLVersion >= 140 &&
28801e04c3fSmrg                         extensions->ARB_draw_instanced &&
28901e04c3fSmrg                         extensions->ARB_texture_buffer_object &&
29001e04c3fSmrg                         extensions->ARB_uniform_buffer_object &&
29101e04c3fSmrg                         extensions->EXT_texture_snorm &&
29201e04c3fSmrg                         extensions->NV_primitive_restart &&
29301e04c3fSmrg                         extensions->NV_texture_rectangle &&
29401e04c3fSmrg                         consts->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits >= 16);
29501e04c3fSmrg   const bool ver_3_2 = (ver_3_1 &&
29601e04c3fSmrg                         consts->GLSLVersion >= 150 &&
29701e04c3fSmrg                         extensions->ARB_depth_clamp &&
29801e04c3fSmrg                         extensions->ARB_draw_elements_base_vertex &&
29901e04c3fSmrg                         extensions->ARB_fragment_coord_conventions &&
30001e04c3fSmrg                         extensions->EXT_provoking_vertex &&
30101e04c3fSmrg                         extensions->ARB_seamless_cube_map &&
30201e04c3fSmrg                         extensions->ARB_sync &&
30301e04c3fSmrg                         extensions->ARB_texture_multisample &&
30401e04c3fSmrg                         extensions->EXT_vertex_array_bgra);
30501e04c3fSmrg   const bool ver_3_3 = (ver_3_2 &&
30601e04c3fSmrg                         consts->GLSLVersion >= 330 &&
30701e04c3fSmrg                         extensions->ARB_blend_func_extended &&
30801e04c3fSmrg                         extensions->ARB_explicit_attrib_location &&
30901e04c3fSmrg                         extensions->ARB_instanced_arrays &&
31001e04c3fSmrg                         extensions->ARB_occlusion_query2 &&
31101e04c3fSmrg                         extensions->ARB_shader_bit_encoding &&
31201e04c3fSmrg                         extensions->ARB_texture_rgb10_a2ui &&
31301e04c3fSmrg                         extensions->ARB_timer_query &&
31401e04c3fSmrg                         extensions->ARB_vertex_type_2_10_10_10_rev &&
31501e04c3fSmrg                         extensions->EXT_texture_swizzle);
31601e04c3fSmrg   /* ARB_sampler_objects is always enabled in mesa */
31701e04c3fSmrg
31801e04c3fSmrg   const bool ver_4_0 = (ver_3_3 &&
31901e04c3fSmrg                         consts->GLSLVersion >= 400 &&
32001e04c3fSmrg                         extensions->ARB_draw_buffers_blend &&
32101e04c3fSmrg                         extensions->ARB_draw_indirect &&
32201e04c3fSmrg                         extensions->ARB_gpu_shader5 &&
32301e04c3fSmrg                         extensions->ARB_gpu_shader_fp64 &&
32401e04c3fSmrg                         extensions->ARB_sample_shading &&
32501e04c3fSmrg                         extensions->ARB_tessellation_shader &&
32601e04c3fSmrg                         extensions->ARB_texture_buffer_object_rgb32 &&
32701e04c3fSmrg                         extensions->ARB_texture_cube_map_array &&
32801e04c3fSmrg                         extensions->ARB_texture_query_lod &&
32901e04c3fSmrg                         extensions->ARB_transform_feedback2 &&
33001e04c3fSmrg                         extensions->ARB_transform_feedback3);
33101e04c3fSmrg   const bool ver_4_1 = (ver_4_0 &&
33201e04c3fSmrg                         consts->GLSLVersion >= 410 &&
33301e04c3fSmrg                         extensions->ARB_ES2_compatibility &&
33401e04c3fSmrg                         extensions->ARB_shader_precision &&
33501e04c3fSmrg                         extensions->ARB_vertex_attrib_64bit &&
33601e04c3fSmrg                         extensions->ARB_viewport_array);
33701e04c3fSmrg   const bool ver_4_2 = (ver_4_1 &&
33801e04c3fSmrg                         consts->GLSLVersion >= 420 &&
33901e04c3fSmrg                         extensions->ARB_base_instance &&
34001e04c3fSmrg                         extensions->ARB_conservative_depth &&
34101e04c3fSmrg                         extensions->ARB_internalformat_query &&
34201e04c3fSmrg                         extensions->ARB_shader_atomic_counters &&
34301e04c3fSmrg                         extensions->ARB_shader_image_load_store &&
34401e04c3fSmrg                         extensions->ARB_shading_language_420pack &&
34501e04c3fSmrg                         extensions->ARB_shading_language_packing &&
34601e04c3fSmrg                         extensions->ARB_texture_compression_bptc &&
34701e04c3fSmrg                         extensions->ARB_transform_feedback_instanced);
34801e04c3fSmrg   const bool ver_4_3 = (ver_4_2 &&
34901e04c3fSmrg                         consts->GLSLVersion >= 430 &&
35001e04c3fSmrg                         consts->Program[MESA_SHADER_VERTEX].MaxUniformBlocks >= 14 &&
35101e04c3fSmrg                         extensions->ARB_ES3_compatibility &&
35201e04c3fSmrg                         extensions->ARB_arrays_of_arrays &&
35301e04c3fSmrg                         extensions->ARB_compute_shader &&
35401e04c3fSmrg                         extensions->ARB_copy_image &&
35501e04c3fSmrg                         extensions->ARB_explicit_uniform_location &&
35601e04c3fSmrg                         extensions->ARB_fragment_layer_viewport &&
35701e04c3fSmrg                         extensions->ARB_framebuffer_no_attachments &&
35801e04c3fSmrg                         extensions->ARB_internalformat_query2 &&
35901e04c3fSmrg                         extensions->ARB_robust_buffer_access_behavior &&
36001e04c3fSmrg                         extensions->ARB_shader_image_size &&
36101e04c3fSmrg                         extensions->ARB_shader_storage_buffer_object &&
36201e04c3fSmrg                         extensions->ARB_stencil_texturing &&
36301e04c3fSmrg                         extensions->ARB_texture_buffer_range &&
36401e04c3fSmrg                         extensions->ARB_texture_query_levels &&
36501e04c3fSmrg                         extensions->ARB_texture_view);
36601e04c3fSmrg   const bool ver_4_4 = (ver_4_3 &&
36701e04c3fSmrg                         consts->GLSLVersion >= 440 &&
36801e04c3fSmrg                         consts->MaxVertexAttribStride >= 2048 &&
36901e04c3fSmrg                         extensions->ARB_buffer_storage &&
37001e04c3fSmrg                         extensions->ARB_clear_texture &&
37101e04c3fSmrg                         extensions->ARB_enhanced_layouts &&
37201e04c3fSmrg                         extensions->ARB_query_buffer_object &&
37301e04c3fSmrg                         extensions->ARB_texture_mirror_clamp_to_edge &&
37401e04c3fSmrg                         extensions->ARB_texture_stencil8 &&
37501e04c3fSmrg                         extensions->ARB_vertex_type_10f_11f_11f_rev);
37601e04c3fSmrg   const bool ver_4_5 = (ver_4_4 &&
37701e04c3fSmrg                         consts->GLSLVersion >= 450 &&
37801e04c3fSmrg                         extensions->ARB_ES3_1_compatibility &&
37901e04c3fSmrg                         extensions->ARB_clip_control &&
38001e04c3fSmrg                         extensions->ARB_conditional_render_inverted &&
38101e04c3fSmrg                         extensions->ARB_cull_distance &&
38201e04c3fSmrg                         extensions->ARB_derivative_control &&
38301e04c3fSmrg                         extensions->ARB_shader_texture_image_samples &&
38401e04c3fSmrg                         extensions->NV_texture_barrier);
38501e04c3fSmrg   const bool ver_4_6 = (ver_4_5 &&
38601e04c3fSmrg                         consts->GLSLVersion >= 460 &&
38701e04c3fSmrg                         /* extensions->ARB_gl_spirv */ 0 &&
38801e04c3fSmrg                         /* extensions->ARB_spirv_extensions */ 0 &&
38901e04c3fSmrg                         extensions->ARB_indirect_parameters &&
39001e04c3fSmrg                         extensions->ARB_pipeline_statistics_query &&
39101e04c3fSmrg                         extensions->ARB_polygon_offset_clamp &&
39201e04c3fSmrg                         extensions->ARB_shader_atomic_counter_ops &&
39301e04c3fSmrg                         extensions->ARB_shader_draw_parameters &&
39401e04c3fSmrg                         extensions->ARB_shader_group_vote &&
39501e04c3fSmrg                         extensions->ARB_texture_filter_anisotropic &&
39601e04c3fSmrg                         extensions->ARB_transform_feedback_overflow_query);
39701e04c3fSmrg
39801e04c3fSmrg   if (ver_4_6) {
39901e04c3fSmrg      major = 4;
40001e04c3fSmrg      minor = 6;
40101e04c3fSmrg   }
40201e04c3fSmrg   else if (ver_4_5) {
40301e04c3fSmrg      major = 4;
40401e04c3fSmrg      minor = 5;
40501e04c3fSmrg   }
40601e04c3fSmrg   else if (ver_4_4) {
40701e04c3fSmrg      major = 4;
40801e04c3fSmrg      minor = 4;
40901e04c3fSmrg   }
41001e04c3fSmrg   else if (ver_4_3) {
41101e04c3fSmrg      major = 4;
41201e04c3fSmrg      minor = 3;
41301e04c3fSmrg   }
41401e04c3fSmrg   else if (ver_4_2) {
41501e04c3fSmrg      major = 4;
41601e04c3fSmrg      minor = 2;
41701e04c3fSmrg   }
41801e04c3fSmrg   else if (ver_4_1) {
41901e04c3fSmrg      major = 4;
42001e04c3fSmrg      minor = 1;
42101e04c3fSmrg   }
42201e04c3fSmrg   else if (ver_4_0) {
42301e04c3fSmrg      major = 4;
42401e04c3fSmrg      minor = 0;
42501e04c3fSmrg   }
42601e04c3fSmrg   else if (ver_3_3) {
4273464ebd5Sriastradh      major = 3;
4283464ebd5Sriastradh      minor = 3;
4293464ebd5Sriastradh   }
4303464ebd5Sriastradh   else if (ver_3_2) {
4313464ebd5Sriastradh      major = 3;
4323464ebd5Sriastradh      minor = 2;
4333464ebd5Sriastradh   }
4343464ebd5Sriastradh   else if (ver_3_1) {
4353464ebd5Sriastradh      major = 3;
4363464ebd5Sriastradh      minor = 1;
4373464ebd5Sriastradh   }
4383464ebd5Sriastradh   else if (ver_3_0) {
4393464ebd5Sriastradh      major = 3;
4403464ebd5Sriastradh      minor = 0;
4413464ebd5Sriastradh   }
4423464ebd5Sriastradh   else if (ver_2_1) {
4433464ebd5Sriastradh      major = 2;
4443464ebd5Sriastradh      minor = 1;
445cdc920a0Smrg   }
446cdc920a0Smrg   else if (ver_2_0) {
4473464ebd5Sriastradh      major = 2;
4483464ebd5Sriastradh      minor = 0;
449cdc920a0Smrg   }
450cdc920a0Smrg   else if (ver_1_5) {
4513464ebd5Sriastradh      major = 1;
4523464ebd5Sriastradh      minor = 5;
453cdc920a0Smrg   }
454cdc920a0Smrg   else if (ver_1_4) {
4553464ebd5Sriastradh      major = 1;
4563464ebd5Sriastradh      minor = 4;
457cdc920a0Smrg   }
458cdc920a0Smrg   else if (ver_1_3) {
4593464ebd5Sriastradh      major = 1;
4603464ebd5Sriastradh      minor = 3;
461cdc920a0Smrg   }
462cdc920a0Smrg   else {
4633464ebd5Sriastradh      major = 1;
4643464ebd5Sriastradh      minor = 2;
4653464ebd5Sriastradh   }
4663464ebd5Sriastradh
467af69d88dSmrg   version = major * 10 + minor;
468af69d88dSmrg
469af69d88dSmrg   if (api == API_OPENGL_CORE && version < 31)
470af69d88dSmrg      return 0;
471af69d88dSmrg
472af69d88dSmrg   return version;
473cdc920a0Smrg}
474cdc920a0Smrg
475af69d88dSmrgstatic GLuint
476af69d88dSmrgcompute_version_es1(const struct gl_extensions *extensions)
4773464ebd5Sriastradh{
4783464ebd5Sriastradh   /* OpenGL ES 1.0 is derived from OpenGL 1.3 */
47901e04c3fSmrg   const bool ver_1_0 = (extensions->ARB_texture_env_combine &&
48001e04c3fSmrg                         extensions->ARB_texture_env_dot3);
4813464ebd5Sriastradh   /* OpenGL ES 1.1 is derived from OpenGL 1.5 */
48201e04c3fSmrg   const bool ver_1_1 = (ver_1_0 &&
48301e04c3fSmrg                         extensions->EXT_point_parameters);
4843464ebd5Sriastradh
4853464ebd5Sriastradh   if (ver_1_1) {
486af69d88dSmrg      return 11;
4873464ebd5Sriastradh   } else if (ver_1_0) {
488af69d88dSmrg      return 10;
4893464ebd5Sriastradh   } else {
490af69d88dSmrg      return 0;
4913464ebd5Sriastradh   }
4923464ebd5Sriastradh}
4933464ebd5Sriastradh
494af69d88dSmrgstatic GLuint
49501e04c3fSmrgcompute_version_es2(const struct gl_extensions *extensions,
49601e04c3fSmrg                    const struct gl_constants *consts)
4973464ebd5Sriastradh{
4983464ebd5Sriastradh   /* OpenGL ES 2.0 is derived from OpenGL 2.0 */
49901e04c3fSmrg   const bool ver_2_0 = (extensions->ARB_texture_cube_map &&
50001e04c3fSmrg                         extensions->EXT_blend_color &&
50101e04c3fSmrg                         extensions->EXT_blend_func_separate &&
50201e04c3fSmrg                         extensions->EXT_blend_minmax &&
50301e04c3fSmrg                         extensions->ARB_vertex_shader &&
50401e04c3fSmrg                         extensions->ARB_fragment_shader &&
50501e04c3fSmrg                         extensions->ARB_texture_non_power_of_two &&
50601e04c3fSmrg                         extensions->EXT_blend_equation_separate);
507af69d88dSmrg   /* FINISHME: This list isn't quite right. */
50801e04c3fSmrg   const bool ver_3_0 = (extensions->ARB_half_float_vertex &&
50901e04c3fSmrg                         extensions->ARB_internalformat_query &&
51001e04c3fSmrg                         extensions->ARB_map_buffer_range &&
51101e04c3fSmrg                         extensions->ARB_shader_texture_lod &&
51201e04c3fSmrg                         extensions->ARB_texture_float &&
51301e04c3fSmrg                         extensions->ARB_texture_rg &&
51401e04c3fSmrg                         extensions->ARB_depth_buffer_float &&
51501e04c3fSmrg                         /* extensions->ARB_framebuffer_object && */
51601e04c3fSmrg                         extensions->EXT_framebuffer_sRGB &&
51701e04c3fSmrg                         extensions->EXT_packed_float &&
51801e04c3fSmrg                         extensions->EXT_texture_array &&
51901e04c3fSmrg                         extensions->EXT_texture_shared_exponent &&
52001e04c3fSmrg                         extensions->EXT_transform_feedback &&
52101e04c3fSmrg                         extensions->ARB_draw_instanced &&
52201e04c3fSmrg                         extensions->ARB_uniform_buffer_object &&
52301e04c3fSmrg                         extensions->EXT_texture_snorm &&
52401e04c3fSmrg                         extensions->NV_primitive_restart &&
52501e04c3fSmrg                         extensions->OES_depth_texture_cube_map);
52601e04c3fSmrg   const bool es31_compute_shader =
52701e04c3fSmrg      consts->MaxComputeWorkGroupInvocations >= 128;
52801e04c3fSmrg   const bool ver_3_1 = (ver_3_0 &&
52901e04c3fSmrg                         consts->MaxVertexAttribStride >= 2048 &&
53001e04c3fSmrg                         extensions->ARB_arrays_of_arrays &&
53101e04c3fSmrg                         es31_compute_shader &&
53201e04c3fSmrg                         extensions->ARB_draw_indirect &&
53301e04c3fSmrg                         extensions->ARB_explicit_uniform_location &&
53401e04c3fSmrg                         extensions->ARB_framebuffer_no_attachments &&
53501e04c3fSmrg                         extensions->ARB_shader_atomic_counters &&
53601e04c3fSmrg                         extensions->ARB_shader_image_load_store &&
53701e04c3fSmrg                         extensions->ARB_shader_image_size &&
53801e04c3fSmrg                         extensions->ARB_shader_storage_buffer_object &&
53901e04c3fSmrg                         extensions->ARB_shading_language_packing &&
54001e04c3fSmrg                         extensions->ARB_stencil_texturing &&
54101e04c3fSmrg                         extensions->ARB_texture_multisample &&
54201e04c3fSmrg                         extensions->ARB_texture_gather &&
54301e04c3fSmrg                         extensions->MESA_shader_integer_functions &&
54401e04c3fSmrg                         extensions->EXT_shader_integer_mix);
54501e04c3fSmrg   const bool ver_3_2 = (ver_3_1 &&
54601e04c3fSmrg                         extensions->EXT_draw_buffers2 &&
54701e04c3fSmrg                         extensions->KHR_blend_equation_advanced &&
54801e04c3fSmrg                         extensions->KHR_robustness &&
54901e04c3fSmrg                         extensions->KHR_texture_compression_astc_ldr &&
55001e04c3fSmrg                         extensions->OES_copy_image &&
55101e04c3fSmrg                         extensions->ARB_draw_buffers_blend &&
55201e04c3fSmrg                         extensions->ARB_draw_elements_base_vertex &&
55301e04c3fSmrg                         extensions->OES_geometry_shader &&
55401e04c3fSmrg                         extensions->OES_primitive_bounding_box &&
55501e04c3fSmrg                         extensions->OES_sample_variables &&
55601e04c3fSmrg                         extensions->ARB_tessellation_shader &&
55701e04c3fSmrg                         extensions->ARB_texture_border_clamp &&
55801e04c3fSmrg                         extensions->OES_texture_buffer &&
55901e04c3fSmrg                         extensions->OES_texture_cube_map_array &&
56001e04c3fSmrg                         extensions->ARB_texture_stencil8);
56101e04c3fSmrg
56201e04c3fSmrg   if (ver_3_2) {
56301e04c3fSmrg      return 32;
56401e04c3fSmrg   } else if (ver_3_1) {
56501e04c3fSmrg      return 31;
56601e04c3fSmrg   } else if (ver_3_0) {
567af69d88dSmrg      return 30;
568af69d88dSmrg   } else if (ver_2_0) {
569af69d88dSmrg      return 20;
5703464ebd5Sriastradh   } else {
571af69d88dSmrg      return 0;
5723464ebd5Sriastradh   }
573af69d88dSmrg}
5743464ebd5Sriastradh
575af69d88dSmrgGLuint
576af69d88dSmrg_mesa_get_version(const struct gl_extensions *extensions,
577af69d88dSmrg                  struct gl_constants *consts, gl_api api)
578af69d88dSmrg{
579af69d88dSmrg   switch (api) {
580af69d88dSmrg   case API_OPENGL_COMPAT:
58101e04c3fSmrg      /* Disable higher GLSL versions for legacy contexts.
58201e04c3fSmrg       * This disallows creation of higher compatibility contexts. */
58301e04c3fSmrg      if (!consts->AllowHigherCompatVersion) {
58401e04c3fSmrg         consts->GLSLVersion = consts->GLSLVersionCompat;
585af69d88dSmrg      }
586af69d88dSmrg      /* fall through */
587af69d88dSmrg   case API_OPENGL_CORE:
588af69d88dSmrg      return compute_version(extensions, consts, api);
589af69d88dSmrg   case API_OPENGLES:
590af69d88dSmrg      return compute_version_es1(extensions);
591af69d88dSmrg   case API_OPENGLES2:
59201e04c3fSmrg      return compute_version_es2(extensions, consts);
5933464ebd5Sriastradh   }
594af69d88dSmrg   return 0;
5953464ebd5Sriastradh}
596cdc920a0Smrg
597cdc920a0Smrg/**
598af69d88dSmrg * Set the context's Version and VersionString fields.
5993464ebd5Sriastradh * This should only be called once as part of context initialization
6003464ebd5Sriastradh * or to perform version check for GLX_ARB_create_context_profile.
601cdc920a0Smrg */
602cdc920a0Smrgvoid
6033464ebd5Sriastradh_mesa_compute_version(struct gl_context *ctx)
604cdc920a0Smrg{
605af69d88dSmrg   if (ctx->Version)
60601e04c3fSmrg      goto done;
607cdc920a0Smrg
608af69d88dSmrg   ctx->Version = _mesa_get_version(&ctx->Extensions, &ctx->Const, ctx->API);
60901e04c3fSmrg   ctx->Extensions.Version = ctx->Version;
61001e04c3fSmrg
61101e04c3fSmrg   /* Make sure that the GLSL version lines up with the GL version. In some
61201e04c3fSmrg    * cases it can be too high, e.g. if an extension is missing.
61301e04c3fSmrg    */
61401e04c3fSmrg   if (_mesa_is_desktop_gl(ctx)) {
61501e04c3fSmrg      switch (ctx->Version) {
61601e04c3fSmrg      case 20:
61701e04c3fSmrg         /* fall-through, GLSL 1.20 is the minimum we support */
61801e04c3fSmrg      case 21:
61901e04c3fSmrg         ctx->Const.GLSLVersion = 120;
62001e04c3fSmrg         break;
62101e04c3fSmrg      case 30:
62201e04c3fSmrg         ctx->Const.GLSLVersion = 130;
62301e04c3fSmrg         break;
62401e04c3fSmrg      case 31:
62501e04c3fSmrg         ctx->Const.GLSLVersion = 140;
62601e04c3fSmrg         break;
62701e04c3fSmrg      case 32:
62801e04c3fSmrg         ctx->Const.GLSLVersion = 150;
62901e04c3fSmrg         break;
63001e04c3fSmrg      default:
63101e04c3fSmrg         if (ctx->Version >= 33)
63201e04c3fSmrg            ctx->Const.GLSLVersion = ctx->Version * 10;
63301e04c3fSmrg         break;
63401e04c3fSmrg      }
63501e04c3fSmrg   }
636af69d88dSmrg
6373464ebd5Sriastradh   switch (ctx->API) {
638af69d88dSmrg   case API_OPENGL_COMPAT:
639af69d88dSmrg   case API_OPENGL_CORE:
640af69d88dSmrg      create_version_string(ctx, "");
6413464ebd5Sriastradh      break;
642af69d88dSmrg
6433464ebd5Sriastradh   case API_OPENGLES:
644af69d88dSmrg      if (!ctx->Version) {
645af69d88dSmrg         _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support.");
646af69d88dSmrg         return;
647af69d88dSmrg      }
648af69d88dSmrg      create_version_string(ctx, "OpenGL ES-CM ");
6493464ebd5Sriastradh      break;
650af69d88dSmrg
6513464ebd5Sriastradh   case API_OPENGLES2:
652af69d88dSmrg      if (!ctx->Version) {
653af69d88dSmrg         _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support.");
654af69d88dSmrg         return;
655af69d88dSmrg      }
656af69d88dSmrg      create_version_string(ctx, "OpenGL ES ");
6573464ebd5Sriastradh      break;
658cdc920a0Smrg   }
65901e04c3fSmrg
66001e04c3fSmrgdone:
66101e04c3fSmrg   if (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 31)
66201e04c3fSmrg      ctx->Extensions.ARB_compatibility = GL_TRUE;
66301e04c3fSmrg}
66401e04c3fSmrg
66501e04c3fSmrg
66601e04c3fSmrgvoid
66701e04c3fSmrg_mesa_get_driver_uuid(struct gl_context *ctx, GLint *uuid)
66801e04c3fSmrg{
66901e04c3fSmrg   ctx->Driver.GetDriverUuid(ctx, (char*) uuid);
67001e04c3fSmrg}
67101e04c3fSmrg
67201e04c3fSmrgvoid
67301e04c3fSmrg_mesa_get_device_uuid(struct gl_context *ctx, GLint *uuid)
67401e04c3fSmrg{
67501e04c3fSmrg   ctx->Driver.GetDeviceUuid(ctx, (char*) uuid);
67601e04c3fSmrg}
67701e04c3fSmrg
67801e04c3fSmrg/**
67901e04c3fSmrg * Get the i-th GLSL version string.  If index=0, return the most recent
68001e04c3fSmrg * supported version.
68101e04c3fSmrg * \param ctx context to query
68201e04c3fSmrg * \param index  which version string to return, or -1 if none
68301e04c3fSmrg * \param versionOut returns the vesrion string
68401e04c3fSmrg * \return total number of shading language versions.
68501e04c3fSmrg */
68601e04c3fSmrgint
68701e04c3fSmrg_mesa_get_shading_language_version(const struct gl_context *ctx,
68801e04c3fSmrg                                   int index,
68901e04c3fSmrg                                   char **versionOut)
69001e04c3fSmrg{
69101e04c3fSmrg   int n = 0;
69201e04c3fSmrg
69301e04c3fSmrg#define GLSL_VERSION(S) \
69401e04c3fSmrg   if (n++ == index) \
69501e04c3fSmrg      *versionOut = S
69601e04c3fSmrg
69701e04c3fSmrg   /* GLSL core */
69801e04c3fSmrg   if (ctx->Const.GLSLVersion >= 460)
69901e04c3fSmrg      GLSL_VERSION("460");
70001e04c3fSmrg   if (ctx->Const.GLSLVersion >= 450)
70101e04c3fSmrg      GLSL_VERSION("450");
70201e04c3fSmrg   if (ctx->Const.GLSLVersion >= 440)
70301e04c3fSmrg      GLSL_VERSION("440");
70401e04c3fSmrg   if (ctx->Const.GLSLVersion >= 430)
70501e04c3fSmrg      GLSL_VERSION("430");
70601e04c3fSmrg   if (ctx->Const.GLSLVersion >= 420)
70701e04c3fSmrg      GLSL_VERSION("420");
70801e04c3fSmrg   if (ctx->Const.GLSLVersion >= 410)
70901e04c3fSmrg      GLSL_VERSION("410");
71001e04c3fSmrg   if (ctx->Const.GLSLVersion >= 400)
71101e04c3fSmrg      GLSL_VERSION("400");
71201e04c3fSmrg   if (ctx->Const.GLSLVersion >= 330)
71301e04c3fSmrg      GLSL_VERSION("330");
71401e04c3fSmrg   if (ctx->Const.GLSLVersion >= 150)
71501e04c3fSmrg      GLSL_VERSION("150");
71601e04c3fSmrg   if (ctx->Const.GLSLVersion >= 140)
71701e04c3fSmrg      GLSL_VERSION("140");
71801e04c3fSmrg   if (ctx->Const.GLSLVersion >= 130)
71901e04c3fSmrg      GLSL_VERSION("130");
72001e04c3fSmrg   if (ctx->Const.GLSLVersion >= 120)
72101e04c3fSmrg      GLSL_VERSION("120");
72201e04c3fSmrg   /* The GL spec says to return the empty string for GLSL 1.10 */
72301e04c3fSmrg   if (ctx->Const.GLSLVersion >= 110)
72401e04c3fSmrg      GLSL_VERSION("");
72501e04c3fSmrg
72601e04c3fSmrg   /* GLSL es */
72701e04c3fSmrg   if ((ctx->API == API_OPENGLES2 && ctx->Version >= 32) ||
72801e04c3fSmrg        ctx->Extensions.ARB_ES3_2_compatibility)
72901e04c3fSmrg      GLSL_VERSION("320 es");
73001e04c3fSmrg   if (_mesa_is_gles31(ctx) || ctx->Extensions.ARB_ES3_1_compatibility)
73101e04c3fSmrg      GLSL_VERSION("310 es");
73201e04c3fSmrg   if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility)
73301e04c3fSmrg      GLSL_VERSION("300 es");
73401e04c3fSmrg   if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility)
73501e04c3fSmrg      GLSL_VERSION("100");
73601e04c3fSmrg
73701e04c3fSmrg#undef GLSL_VERSION
73801e04c3fSmrg
73901e04c3fSmrg   return n;
740cdc920a0Smrg}
741