Home | History | Annotate | Download | only in main
      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