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