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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24 25 #include "imports.h" 26 #include "mtypes.h" 27 #include "version.h" 28 #include "git_sha1.h" 29 30 /** 31 * Override the context's GL version if the environment variable 32 * MESA_GL_VERSION_OVERRIDE is set. Valid values of MESA_GL_VERSION_OVERRIDE 33 * are point-separated version numbers, such as "3.0". 34 */ 35 static void 36 override_version(struct gl_context *ctx) 37 { 38 const char *env_var = "MESA_GL_VERSION_OVERRIDE"; 39 const char *version; 40 int n; 41 int major, minor; 42 43 version = getenv(env_var); 44 if (!version) { 45 return; 46 } 47 48 n = sscanf(version, "%u.%u", &major, &minor); 49 if (n != 2) { 50 fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version); 51 return; 52 } 53 54 ctx->Version = major * 10 + minor; 55 } 56 57 /** 58 * Override the context's GLSL version if the environment variable 59 * MESA_GLSL_VERSION_OVERRIDE is set. Valid values for 60 * MESA_GLSL_VERSION_OVERRIDE are integers, such as "130". 61 */ 62 void 63 _mesa_override_glsl_version(struct gl_context *ctx) 64 { 65 const char *env_var = "MESA_GLSL_VERSION_OVERRIDE"; 66 const char *version; 67 int n; 68 69 version = getenv(env_var); 70 if (!version) { 71 return; 72 } 73 74 n = sscanf(version, "%u", &ctx->Const.GLSLVersion); 75 if (n != 1) { 76 fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version); 77 return; 78 } 79 } 80 81 /** 82 * Examine enabled GL extensions to determine GL version. 83 */ 84 static void 85 compute_version(struct gl_context *ctx) 86 { 87 GLuint major, minor; 88 static const int max = 100; 89 90 const GLboolean ver_1_3 = (ctx->Extensions.ARB_texture_border_clamp && 91 ctx->Extensions.ARB_texture_cube_map && 92 ctx->Extensions.ARB_texture_env_combine && 93 ctx->Extensions.ARB_texture_env_dot3); 94 const GLboolean ver_1_4 = (ver_1_3 && 95 ctx->Extensions.ARB_depth_texture && 96 ctx->Extensions.ARB_shadow && 97 ctx->Extensions.ARB_texture_env_crossbar && 98 ctx->Extensions.ARB_window_pos && 99 ctx->Extensions.EXT_blend_color && 100 ctx->Extensions.EXT_blend_func_separate && 101 ctx->Extensions.EXT_blend_minmax && 102 ctx->Extensions.EXT_fog_coord && 103 ctx->Extensions.EXT_point_parameters && 104 ctx->Extensions.EXT_secondary_color); 105 const GLboolean ver_1_5 = (ver_1_4 && 106 ctx->Extensions.ARB_occlusion_query && 107 ctx->Extensions.EXT_shadow_funcs); 108 const GLboolean ver_2_0 = (ver_1_5 && 109 ctx->Extensions.ARB_point_sprite && 110 ctx->Extensions.ARB_shader_objects && 111 ctx->Extensions.ARB_vertex_shader && 112 ctx->Extensions.ARB_fragment_shader && 113 ctx->Extensions.ARB_texture_non_power_of_two && 114 ctx->Extensions.EXT_blend_equation_separate && 115 116 /* Technically, 2.0 requires the functionality 117 * of the EXT version. Enable 2.0 if either 118 * extension is available, and assume that a 119 * driver that only exposes the ATI extension 120 * will fallback to software when necessary. 121 */ 122 (ctx->Extensions.EXT_stencil_two_side 123 || ctx->Extensions.ATI_separate_stencil)); 124 const GLboolean ver_2_1 = (ver_2_0 && 125 ctx->Const.GLSLVersion >= 120 && 126 ctx->Extensions.EXT_pixel_buffer_object && 127 ctx->Extensions.EXT_texture_sRGB); 128 const GLboolean ver_3_0 = (ver_2_1 && 129 ctx->Const.GLSLVersion >= 130 && 130 ctx->Const.MaxSamples >= 4 && 131 ctx->Extensions.ARB_color_buffer_float && 132 ctx->Extensions.ARB_depth_buffer_float && 133 ctx->Extensions.ARB_half_float_pixel && 134 ctx->Extensions.ARB_half_float_vertex && 135 ctx->Extensions.ARB_map_buffer_range && 136 ctx->Extensions.ARB_shader_texture_lod && 137 ctx->Extensions.ARB_texture_float && 138 ctx->Extensions.ARB_texture_rg && 139 ctx->Extensions.ARB_texture_compression_rgtc && 140 ctx->Extensions.EXT_draw_buffers2 && 141 ctx->Extensions.ARB_framebuffer_object && 142 ctx->Extensions.EXT_framebuffer_sRGB && 143 ctx->Extensions.EXT_packed_float && 144 ctx->Extensions.EXT_texture_array && 145 ctx->Extensions.EXT_texture_shared_exponent && 146 ctx->Extensions.EXT_transform_feedback && 147 ctx->Extensions.NV_conditional_render); 148 const GLboolean ver_3_1 = (ver_3_0 && 149 ctx->Const.GLSLVersion >= 140 && 150 ctx->Extensions.ARB_copy_buffer && 151 ctx->Extensions.ARB_draw_instanced && 152 ctx->Extensions.ARB_texture_buffer_object && 153 ctx->Extensions.ARB_uniform_buffer_object && 154 ctx->Extensions.EXT_texture_snorm && 155 ctx->Extensions.NV_primitive_restart && 156 ctx->Extensions.NV_texture_rectangle && 157 ctx->Const.MaxVertexTextureImageUnits >= 16); 158 const GLboolean ver_3_2 = (ver_3_1 && 159 ctx->Const.GLSLVersion >= 150 && 160 ctx->Extensions.ARB_depth_clamp && 161 ctx->Extensions.ARB_draw_elements_base_vertex && 162 ctx->Extensions.ARB_fragment_coord_conventions && 163 ctx->Extensions.ARB_geometry_shader4 && 164 ctx->Extensions.EXT_provoking_vertex && 165 ctx->Extensions.ARB_seamless_cube_map && 166 ctx->Extensions.ARB_sync && 167 ctx->Extensions.ARB_texture_multisample && 168 ctx->Extensions.EXT_vertex_array_bgra); 169 const GLboolean ver_3_3 = (ver_3_2 && 170 ctx->Const.GLSLVersion >= 330 && 171 ctx->Extensions.ARB_blend_func_extended && 172 ctx->Extensions.ARB_explicit_attrib_location && 173 ctx->Extensions.ARB_instanced_arrays && 174 ctx->Extensions.ARB_occlusion_query2 && 175 ctx->Extensions.ARB_shader_bit_encoding && 176 ctx->Extensions.ARB_texture_rgb10_a2ui && 177 ctx->Extensions.ARB_timer_query && 178 ctx->Extensions.ARB_vertex_type_2_10_10_10_rev && 179 ctx->Extensions.EXT_texture_swizzle); 180 /* ARB_sampler_objects is always enabled in mesa */ 181 182 if (ver_3_3) { 183 major = 3; 184 minor = 3; 185 } 186 else if (ver_3_2) { 187 major = 3; 188 minor = 2; 189 } 190 else if (ver_3_1) { 191 major = 3; 192 minor = 1; 193 } 194 else if (ver_3_0) { 195 major = 3; 196 minor = 0; 197 } 198 else if (ver_2_1) { 199 major = 2; 200 minor = 1; 201 } 202 else if (ver_2_0) { 203 major = 2; 204 minor = 0; 205 } 206 else if (ver_1_5) { 207 major = 1; 208 minor = 5; 209 } 210 else if (ver_1_4) { 211 major = 1; 212 minor = 4; 213 } 214 else if (ver_1_3) { 215 major = 1; 216 minor = 3; 217 } 218 else { 219 major = 1; 220 minor = 2; 221 } 222 223 ctx->Version = major * 10 + minor; 224 225 override_version(ctx); 226 227 ctx->VersionString = (char *) malloc(max); 228 if (ctx->VersionString) { 229 _mesa_snprintf(ctx->VersionString, max, 230 "%u.%u Mesa " MESA_VERSION_STRING 231 #ifdef MESA_GIT_SHA1 232 " (" MESA_GIT_SHA1 ")" 233 #endif 234 , 235 ctx->Version / 10, ctx->Version % 10); 236 } 237 } 238 239 static void 240 compute_version_es1(struct gl_context *ctx) 241 { 242 static const int max = 100; 243 244 /* OpenGL ES 1.0 is derived from OpenGL 1.3 */ 245 const GLboolean ver_1_0 = (ctx->Extensions.ARB_texture_env_combine && 246 ctx->Extensions.ARB_texture_env_dot3); 247 /* OpenGL ES 1.1 is derived from OpenGL 1.5 */ 248 const GLboolean ver_1_1 = (ver_1_0 && 249 ctx->Extensions.EXT_point_parameters); 250 251 if (ver_1_1) { 252 ctx->Version = 11; 253 } else if (ver_1_0) { 254 ctx->Version = 10; 255 } else { 256 _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support."); 257 } 258 259 ctx->VersionString = (char *) malloc(max); 260 if (ctx->VersionString) { 261 _mesa_snprintf(ctx->VersionString, max, 262 "OpenGL ES-CM 1.%d Mesa " MESA_VERSION_STRING 263 #ifdef MESA_GIT_SHA1 264 " (" MESA_GIT_SHA1 ")" 265 #endif 266 , 267 ctx->Version % 10); 268 } 269 } 270 271 static void 272 compute_version_es2(struct gl_context *ctx) 273 { 274 static const int max = 100; 275 276 /* OpenGL ES 2.0 is derived from OpenGL 2.0 */ 277 const GLboolean ver_2_0 = (ctx->Extensions.ARB_texture_cube_map && 278 ctx->Extensions.EXT_blend_color && 279 ctx->Extensions.EXT_blend_func_separate && 280 ctx->Extensions.EXT_blend_minmax && 281 ctx->Extensions.ARB_shader_objects && 282 ctx->Extensions.ARB_vertex_shader && 283 ctx->Extensions.ARB_fragment_shader && 284 ctx->Extensions.ARB_texture_non_power_of_two && 285 ctx->Extensions.EXT_blend_equation_separate); 286 if (ver_2_0) { 287 ctx->Version = 20; 288 } else { 289 _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support."); 290 } 291 292 ctx->VersionString = (char *) malloc(max); 293 if (ctx->VersionString) { 294 _mesa_snprintf(ctx->VersionString, max, 295 "OpenGL ES 2.0 Mesa " MESA_VERSION_STRING 296 #ifdef MESA_GIT_SHA1 297 " (" MESA_GIT_SHA1 ")" 298 #endif 299 ); 300 } 301 } 302 303 /** 304 * Set the context's Version and VersionString fields. 305 * This should only be called once as part of context initialization 306 * or to perform version check for GLX_ARB_create_context_profile. 307 */ 308 void 309 _mesa_compute_version(struct gl_context *ctx) 310 { 311 if (ctx->Version) 312 return; 313 314 switch (ctx->API) { 315 case API_OPENGL: 316 case API_OPENGL_CORE: 317 compute_version(ctx); 318 break; 319 case API_OPENGLES: 320 compute_version_es1(ctx); 321 break; 322 case API_OPENGLES2: 323 compute_version_es2(ctx); 324 break; 325 } 326 327 } 328