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" 287ec681f3Smrg#include "draw_validate.h" 297ec681f3Smrg 307ec681f3Smrg#include "util/os_misc.h" 317ec681f3Smrg#include "util/simple_mtx.h" 327ec681f3Smrg 333464ebd5Sriastradh#include "mtypes.h" 34cdc920a0Smrg#include "version.h" 353464ebd5Sriastradh#include "git_sha1.h" 36cdc920a0Smrg 377ec681f3Smrgstatic simple_mtx_t override_lock = _SIMPLE_MTX_INITIALIZER_NP; 387ec681f3Smrg 39af69d88dSmrg/** 40af69d88dSmrg * Scans 'string' to see if it ends with 'ending'. 41af69d88dSmrg */ 4201e04c3fSmrgstatic bool 43af69d88dSmrgcheck_for_ending(const char *string, const char *ending) 44af69d88dSmrg{ 4501e04c3fSmrg const size_t len1 = strlen(string); 4601e04c3fSmrg const size_t len2 = strlen(ending); 47cdc920a0Smrg 4801e04c3fSmrg if (len2 > len1) 4901e04c3fSmrg return false; 50af69d88dSmrg 5101e04c3fSmrg return strcmp(string + (len1 - len2), ending) == 0; 52af69d88dSmrg} 53cdc920a0Smrg 54cdc920a0Smrg/** 55af69d88dSmrg * Returns the gl override data 56af69d88dSmrg * 57af69d88dSmrg * version > 0 indicates there is an override requested 58af69d88dSmrg * fwd_context is only valid if version > 0 59cdc920a0Smrg */ 60cdc920a0Smrgstatic void 6101e04c3fSmrgget_gl_override(gl_api api, int *version, bool *fwd_context, 6201e04c3fSmrg bool *compat_context) 63af69d88dSmrg{ 6401e04c3fSmrg const char *env_var = (api == API_OPENGL_CORE || api == API_OPENGL_COMPAT) 6501e04c3fSmrg ? "MESA_GL_VERSION_OVERRIDE" : "MESA_GLES_VERSION_OVERRIDE"; 66af69d88dSmrg const char *version_str; 67af69d88dSmrg int major, minor, n; 6801e04c3fSmrg static struct override_info { 6901e04c3fSmrg int version; 7001e04c3fSmrg bool fc_suffix; 7101e04c3fSmrg bool compat_suffix; 7201e04c3fSmrg } override[] = { 7301e04c3fSmrg [API_OPENGL_COMPAT] = { -1, false, false}, 7401e04c3fSmrg [API_OPENGLES] = { -1, false, false}, 7501e04c3fSmrg [API_OPENGLES2] = { -1, false, false}, 7601e04c3fSmrg [API_OPENGL_CORE] = { -1, false, false}, 7701e04c3fSmrg }; 78af69d88dSmrg 7901e04c3fSmrg STATIC_ASSERT(ARRAY_SIZE(override) == API_OPENGL_LAST + 1); 8001e04c3fSmrg 817ec681f3Smrg simple_mtx_lock(&override_lock); 827ec681f3Smrg 8301e04c3fSmrg if (api == API_OPENGLES) 8401e04c3fSmrg goto exit; 8501e04c3fSmrg 8601e04c3fSmrg if (override[api].version < 0) { 8701e04c3fSmrg override[api].version = 0; 88af69d88dSmrg 897ec681f3Smrg version_str = os_get_option(env_var); 90af69d88dSmrg if (version_str) { 9101e04c3fSmrg override[api].fc_suffix = check_for_ending(version_str, "FC"); 9201e04c3fSmrg override[api].compat_suffix = check_for_ending(version_str, "COMPAT"); 93af69d88dSmrg 94af69d88dSmrg n = sscanf(version_str, "%u.%u", &major, &minor); 95af69d88dSmrg if (n != 2) { 9601e04c3fSmrg fprintf(stderr, "error: invalid value for %s: %s\n", 9701e04c3fSmrg env_var, version_str); 9801e04c3fSmrg override[api].version = 0; 99af69d88dSmrg } else { 10001e04c3fSmrg override[api].version = major * 10 + minor; 10101e04c3fSmrg 10201e04c3fSmrg /* There is no such thing as compatibility or forward-compatible for 10301e04c3fSmrg * OpenGL ES 2.0 or 3.x APIs. 10401e04c3fSmrg */ 10501e04c3fSmrg if ((override[api].version < 30 && override[api].fc_suffix) || 10601e04c3fSmrg (api == API_OPENGLES2 && (override[api].fc_suffix || 10701e04c3fSmrg override[api].compat_suffix))) { 10801e04c3fSmrg fprintf(stderr, "error: invalid value for %s: %s\n", 10901e04c3fSmrg env_var, version_str); 110af69d88dSmrg } 111af69d88dSmrg } 112af69d88dSmrg } 113af69d88dSmrg } 114af69d88dSmrg 11501e04c3fSmrgexit: 11601e04c3fSmrg *version = override[api].version; 11701e04c3fSmrg *fwd_context = override[api].fc_suffix; 11801e04c3fSmrg *compat_context = override[api].compat_suffix; 1197ec681f3Smrg 1207ec681f3Smrg simple_mtx_unlock(&override_lock); 121af69d88dSmrg} 122af69d88dSmrg 123af69d88dSmrg/** 12401e04c3fSmrg * Builds the Mesa version string. 125af69d88dSmrg */ 126af69d88dSmrgstatic void 127af69d88dSmrgcreate_version_string(struct gl_context *ctx, const char *prefix) 128cdc920a0Smrg{ 1293464ebd5Sriastradh static const int max = 100; 1303464ebd5Sriastradh 131af69d88dSmrg ctx->VersionString = malloc(max); 132af69d88dSmrg if (ctx->VersionString) { 1337ec681f3Smrg snprintf(ctx->VersionString, max, 13401e04c3fSmrg "%s%u.%u%s Mesa " PACKAGE_VERSION MESA_GIT_SHA1, 135af69d88dSmrg prefix, 136af69d88dSmrg ctx->Version / 10, ctx->Version % 10, 13701e04c3fSmrg (ctx->API == API_OPENGL_CORE) ? " (Core Profile)" : 13801e04c3fSmrg (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 32) ? 13901e04c3fSmrg " (Compatibility Profile)" : "" 140af69d88dSmrg ); 141af69d88dSmrg } 142af69d88dSmrg} 143af69d88dSmrg 144af69d88dSmrg/** 14501e04c3fSmrg * Override the context's version and/or API type if the environment variables 14601e04c3fSmrg * MESA_GL_VERSION_OVERRIDE or MESA_GLES_VERSION_OVERRIDE are set. 147af69d88dSmrg * 148af69d88dSmrg * Example uses of MESA_GL_VERSION_OVERRIDE: 149af69d88dSmrg * 15001e04c3fSmrg * 2.1: select a compatibility (non-Core) profile with GL version 2.1. 15101e04c3fSmrg * 3.0: select a compatibility (non-Core) profile with GL version 3.0. 15201e04c3fSmrg * 3.0FC: select a Core+Forward Compatible profile with GL version 3.0. 15301e04c3fSmrg * 3.1: select GL version 3.1 with GL_ARB_compatibility enabled per the driver default. 15401e04c3fSmrg * 3.1FC: select GL version 3.1 with forward compatibility and GL_ARB_compatibility disabled. 15501e04c3fSmrg * 3.1COMPAT: select GL version 3.1 with GL_ARB_compatibility enabled. 15601e04c3fSmrg * X.Y: override GL version to X.Y without changing the profile. 15701e04c3fSmrg * X.YFC: select a Core+Forward Compatible profile with GL version X.Y. 15801e04c3fSmrg * X.YCOMPAT: select a Compatibility profile with GL version X.Y. 15901e04c3fSmrg * 16001e04c3fSmrg * Example uses of MESA_GLES_VERSION_OVERRIDE: 16101e04c3fSmrg * 16201e04c3fSmrg * 2.0: select GLES version 2.0. 16301e04c3fSmrg * 3.0: select GLES version 3.0. 16401e04c3fSmrg * 3.1: select GLES version 3.1. 165af69d88dSmrg */ 166af69d88dSmrgbool 167af69d88dSmrg_mesa_override_gl_version_contextless(struct gl_constants *consts, 168af69d88dSmrg gl_api *apiOut, GLuint *versionOut) 169af69d88dSmrg{ 170af69d88dSmrg int version; 17101e04c3fSmrg bool fwd_context, compat_context; 172af69d88dSmrg 17301e04c3fSmrg get_gl_override(*apiOut, &version, &fwd_context, &compat_context); 174af69d88dSmrg 175af69d88dSmrg if (version > 0) { 176af69d88dSmrg *versionOut = version; 17701e04c3fSmrg 17801e04c3fSmrg /* Modify the API and context flags as needed. */ 17901e04c3fSmrg if (*apiOut == API_OPENGL_CORE || *apiOut == API_OPENGL_COMPAT) { 18001e04c3fSmrg if (version >= 30 && fwd_context) { 18101e04c3fSmrg *apiOut = API_OPENGL_CORE; 18201e04c3fSmrg consts->ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; 18301e04c3fSmrg } else if (compat_context) { 18401e04c3fSmrg *apiOut = API_OPENGL_COMPAT; 18501e04c3fSmrg } 186af69d88dSmrg } 18701e04c3fSmrg 18801e04c3fSmrg return true; 189af69d88dSmrg } 19001e04c3fSmrg return false; 191af69d88dSmrg} 192af69d88dSmrg 193af69d88dSmrgvoid 194af69d88dSmrg_mesa_override_gl_version(struct gl_context *ctx) 195af69d88dSmrg{ 196af69d88dSmrg if (_mesa_override_gl_version_contextless(&ctx->Const, &ctx->API, 197af69d88dSmrg &ctx->Version)) { 19801e04c3fSmrg /* We need to include API in version string for OpenGL ES, otherwise 19901e04c3fSmrg * application can not detect GLES via glGetString(GL_VERSION) query. 20001e04c3fSmrg * 20101e04c3fSmrg * From OpenGL ES 3.2 spec, Page 436: 20201e04c3fSmrg * 20301e04c3fSmrg * "The VERSION string is laid out as follows: 20401e04c3fSmrg * 20501e04c3fSmrg * OpenGL ES N.M vendor-specific information" 20601e04c3fSmrg * 20701e04c3fSmrg * From OpenGL 4.5 spec, Page 538: 20801e04c3fSmrg * 20901e04c3fSmrg * "The VERSION and SHADING_LANGUAGE_VERSION strings are laid out as 21001e04c3fSmrg * follows: 21101e04c3fSmrg * 21201e04c3fSmrg * <version number><space><vendor-specific information>" 21301e04c3fSmrg */ 21401e04c3fSmrg create_version_string(ctx, _mesa_is_gles(ctx) ? "OpenGL ES " : ""); 21501e04c3fSmrg ctx->Extensions.Version = ctx->Version; 216af69d88dSmrg } 217af69d88dSmrg} 218af69d88dSmrg 219af69d88dSmrg/** 220af69d88dSmrg * Override the context's GLSL version if the environment variable 221af69d88dSmrg * MESA_GLSL_VERSION_OVERRIDE is set. Valid values for 222af69d88dSmrg * MESA_GLSL_VERSION_OVERRIDE are integers, such as "130". 223af69d88dSmrg */ 224af69d88dSmrgvoid 225af69d88dSmrg_mesa_override_glsl_version(struct gl_constants *consts) 226af69d88dSmrg{ 227af69d88dSmrg const char *env_var = "MESA_GLSL_VERSION_OVERRIDE"; 228af69d88dSmrg const char *version; 229af69d88dSmrg int n; 230af69d88dSmrg 231af69d88dSmrg version = getenv(env_var); 232af69d88dSmrg if (!version) { 233af69d88dSmrg return; 234af69d88dSmrg } 235af69d88dSmrg 236af69d88dSmrg n = sscanf(version, "%u", &consts->GLSLVersion); 237af69d88dSmrg if (n != 1) { 238af69d88dSmrg fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version); 239af69d88dSmrg return; 240af69d88dSmrg } 241af69d88dSmrg} 242af69d88dSmrg 243af69d88dSmrg/** 244af69d88dSmrg * Examine enabled GL extensions to determine GL version. 245af69d88dSmrg */ 246af69d88dSmrgstatic GLuint 247af69d88dSmrgcompute_version(const struct gl_extensions *extensions, 248af69d88dSmrg const struct gl_constants *consts, gl_api api) 249af69d88dSmrg{ 250af69d88dSmrg GLuint major, minor, version; 251af69d88dSmrg 25201e04c3fSmrg const bool ver_1_3 = (extensions->ARB_texture_border_clamp && 25301e04c3fSmrg extensions->ARB_texture_cube_map && 25401e04c3fSmrg extensions->ARB_texture_env_combine && 25501e04c3fSmrg extensions->ARB_texture_env_dot3); 25601e04c3fSmrg const bool ver_1_4 = (ver_1_3 && 25701e04c3fSmrg extensions->ARB_depth_texture && 25801e04c3fSmrg extensions->ARB_shadow && 25901e04c3fSmrg extensions->ARB_texture_env_crossbar && 26001e04c3fSmrg extensions->EXT_blend_color && 26101e04c3fSmrg extensions->EXT_blend_func_separate && 26201e04c3fSmrg extensions->EXT_blend_minmax && 26301e04c3fSmrg extensions->EXT_point_parameters); 26401e04c3fSmrg const bool ver_1_5 = (ver_1_4 && 26501e04c3fSmrg extensions->ARB_occlusion_query); 26601e04c3fSmrg const bool ver_2_0 = (ver_1_5 && 26701e04c3fSmrg extensions->ARB_point_sprite && 26801e04c3fSmrg extensions->ARB_vertex_shader && 26901e04c3fSmrg extensions->ARB_fragment_shader && 27001e04c3fSmrg extensions->ARB_texture_non_power_of_two && 27101e04c3fSmrg extensions->EXT_blend_equation_separate && 27201e04c3fSmrg extensions->EXT_stencil_two_side); 27301e04c3fSmrg const bool ver_2_1 = (ver_2_0 && 27401e04c3fSmrg extensions->EXT_pixel_buffer_object && 27501e04c3fSmrg extensions->EXT_texture_sRGB); 2767ec681f3Smrg /* We lie about the minimum number of color attachments. Strictly, OpenGL 2777ec681f3Smrg * 3.0 requires 8, whereas OpenGL ES requires 4. OpenGL ES 3.0 class 2787ec681f3Smrg * hardware may only support 4 render targets. Advertise non-conformant 2797ec681f3Smrg * OpenGL 3.0 anyway. Affects freedreno on a3xx 2807ec681f3Smrg */ 28101e04c3fSmrg const bool ver_3_0 = (ver_2_1 && 28201e04c3fSmrg consts->GLSLVersion >= 130 && 2837ec681f3Smrg consts->MaxColorAttachments >= 4 && 28401e04c3fSmrg (consts->MaxSamples >= 4 || consts->FakeSWMSAA) && 28501e04c3fSmrg (api == API_OPENGL_CORE || 28601e04c3fSmrg extensions->ARB_color_buffer_float) && 28701e04c3fSmrg extensions->ARB_depth_buffer_float && 28801e04c3fSmrg extensions->ARB_half_float_vertex && 28901e04c3fSmrg extensions->ARB_map_buffer_range && 29001e04c3fSmrg extensions->ARB_shader_texture_lod && 29101e04c3fSmrg extensions->ARB_texture_float && 29201e04c3fSmrg extensions->ARB_texture_rg && 29301e04c3fSmrg extensions->ARB_texture_compression_rgtc && 29401e04c3fSmrg extensions->EXT_draw_buffers2 && 29501e04c3fSmrg extensions->ARB_framebuffer_object && 29601e04c3fSmrg extensions->EXT_framebuffer_sRGB && 29701e04c3fSmrg extensions->EXT_packed_float && 29801e04c3fSmrg extensions->EXT_texture_array && 29901e04c3fSmrg extensions->EXT_texture_shared_exponent && 30001e04c3fSmrg extensions->EXT_transform_feedback && 30101e04c3fSmrg extensions->NV_conditional_render); 30201e04c3fSmrg const bool ver_3_1 = (ver_3_0 && 30301e04c3fSmrg consts->GLSLVersion >= 140 && 30401e04c3fSmrg extensions->ARB_draw_instanced && 30501e04c3fSmrg extensions->ARB_texture_buffer_object && 30601e04c3fSmrg extensions->ARB_uniform_buffer_object && 30701e04c3fSmrg extensions->EXT_texture_snorm && 30801e04c3fSmrg extensions->NV_primitive_restart && 30901e04c3fSmrg extensions->NV_texture_rectangle && 31001e04c3fSmrg consts->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits >= 16); 31101e04c3fSmrg const bool ver_3_2 = (ver_3_1 && 31201e04c3fSmrg consts->GLSLVersion >= 150 && 31301e04c3fSmrg extensions->ARB_depth_clamp && 31401e04c3fSmrg extensions->ARB_draw_elements_base_vertex && 31501e04c3fSmrg extensions->ARB_fragment_coord_conventions && 31601e04c3fSmrg extensions->EXT_provoking_vertex && 31701e04c3fSmrg extensions->ARB_seamless_cube_map && 31801e04c3fSmrg extensions->ARB_sync && 31901e04c3fSmrg extensions->ARB_texture_multisample && 32001e04c3fSmrg extensions->EXT_vertex_array_bgra); 32101e04c3fSmrg const bool ver_3_3 = (ver_3_2 && 32201e04c3fSmrg consts->GLSLVersion >= 330 && 32301e04c3fSmrg extensions->ARB_blend_func_extended && 32401e04c3fSmrg extensions->ARB_explicit_attrib_location && 32501e04c3fSmrg extensions->ARB_instanced_arrays && 32601e04c3fSmrg extensions->ARB_occlusion_query2 && 32701e04c3fSmrg extensions->ARB_shader_bit_encoding && 32801e04c3fSmrg extensions->ARB_texture_rgb10_a2ui && 32901e04c3fSmrg extensions->ARB_timer_query && 33001e04c3fSmrg extensions->ARB_vertex_type_2_10_10_10_rev && 33101e04c3fSmrg extensions->EXT_texture_swizzle); 33201e04c3fSmrg /* ARB_sampler_objects is always enabled in mesa */ 33301e04c3fSmrg 33401e04c3fSmrg const bool ver_4_0 = (ver_3_3 && 33501e04c3fSmrg consts->GLSLVersion >= 400 && 33601e04c3fSmrg extensions->ARB_draw_buffers_blend && 33701e04c3fSmrg extensions->ARB_draw_indirect && 33801e04c3fSmrg extensions->ARB_gpu_shader5 && 33901e04c3fSmrg extensions->ARB_gpu_shader_fp64 && 34001e04c3fSmrg extensions->ARB_sample_shading && 34101e04c3fSmrg extensions->ARB_tessellation_shader && 34201e04c3fSmrg extensions->ARB_texture_buffer_object_rgb32 && 34301e04c3fSmrg extensions->ARB_texture_cube_map_array && 34401e04c3fSmrg extensions->ARB_texture_query_lod && 34501e04c3fSmrg extensions->ARB_transform_feedback2 && 34601e04c3fSmrg extensions->ARB_transform_feedback3); 34701e04c3fSmrg const bool ver_4_1 = (ver_4_0 && 34801e04c3fSmrg consts->GLSLVersion >= 410 && 3497ec681f3Smrg consts->MaxTextureSize >= 16384 && 3507ec681f3Smrg consts->MaxRenderbufferSize >= 16384 && 35101e04c3fSmrg extensions->ARB_ES2_compatibility && 35201e04c3fSmrg extensions->ARB_shader_precision && 35301e04c3fSmrg extensions->ARB_vertex_attrib_64bit && 35401e04c3fSmrg extensions->ARB_viewport_array); 35501e04c3fSmrg const bool ver_4_2 = (ver_4_1 && 35601e04c3fSmrg consts->GLSLVersion >= 420 && 35701e04c3fSmrg extensions->ARB_base_instance && 35801e04c3fSmrg extensions->ARB_conservative_depth && 35901e04c3fSmrg extensions->ARB_internalformat_query && 36001e04c3fSmrg extensions->ARB_shader_atomic_counters && 36101e04c3fSmrg extensions->ARB_shader_image_load_store && 36201e04c3fSmrg extensions->ARB_shading_language_420pack && 36301e04c3fSmrg extensions->ARB_shading_language_packing && 36401e04c3fSmrg extensions->ARB_texture_compression_bptc && 36501e04c3fSmrg extensions->ARB_transform_feedback_instanced); 36601e04c3fSmrg const bool ver_4_3 = (ver_4_2 && 36701e04c3fSmrg consts->GLSLVersion >= 430 && 36801e04c3fSmrg consts->Program[MESA_SHADER_VERTEX].MaxUniformBlocks >= 14 && 36901e04c3fSmrg extensions->ARB_ES3_compatibility && 37001e04c3fSmrg extensions->ARB_arrays_of_arrays && 37101e04c3fSmrg extensions->ARB_compute_shader && 37201e04c3fSmrg extensions->ARB_copy_image && 37301e04c3fSmrg extensions->ARB_explicit_uniform_location && 37401e04c3fSmrg extensions->ARB_fragment_layer_viewport && 37501e04c3fSmrg extensions->ARB_framebuffer_no_attachments && 37601e04c3fSmrg extensions->ARB_internalformat_query2 && 37701e04c3fSmrg extensions->ARB_robust_buffer_access_behavior && 37801e04c3fSmrg extensions->ARB_shader_image_size && 37901e04c3fSmrg extensions->ARB_shader_storage_buffer_object && 38001e04c3fSmrg extensions->ARB_stencil_texturing && 38101e04c3fSmrg extensions->ARB_texture_buffer_range && 38201e04c3fSmrg extensions->ARB_texture_query_levels && 38301e04c3fSmrg extensions->ARB_texture_view); 38401e04c3fSmrg const bool ver_4_4 = (ver_4_3 && 38501e04c3fSmrg consts->GLSLVersion >= 440 && 38601e04c3fSmrg consts->MaxVertexAttribStride >= 2048 && 38701e04c3fSmrg extensions->ARB_buffer_storage && 38801e04c3fSmrg extensions->ARB_clear_texture && 38901e04c3fSmrg extensions->ARB_enhanced_layouts && 39001e04c3fSmrg extensions->ARB_query_buffer_object && 39101e04c3fSmrg extensions->ARB_texture_mirror_clamp_to_edge && 39201e04c3fSmrg extensions->ARB_texture_stencil8 && 39301e04c3fSmrg extensions->ARB_vertex_type_10f_11f_11f_rev); 39401e04c3fSmrg const bool ver_4_5 = (ver_4_4 && 39501e04c3fSmrg consts->GLSLVersion >= 450 && 39601e04c3fSmrg extensions->ARB_ES3_1_compatibility && 39701e04c3fSmrg extensions->ARB_clip_control && 39801e04c3fSmrg extensions->ARB_conditional_render_inverted && 39901e04c3fSmrg extensions->ARB_cull_distance && 40001e04c3fSmrg extensions->ARB_derivative_control && 40101e04c3fSmrg extensions->ARB_shader_texture_image_samples && 40201e04c3fSmrg extensions->NV_texture_barrier); 40301e04c3fSmrg const bool ver_4_6 = (ver_4_5 && 40401e04c3fSmrg consts->GLSLVersion >= 460 && 4057ec681f3Smrg extensions->ARB_gl_spirv && 4067ec681f3Smrg extensions->ARB_spirv_extensions && 40701e04c3fSmrg extensions->ARB_indirect_parameters && 40801e04c3fSmrg extensions->ARB_pipeline_statistics_query && 40901e04c3fSmrg extensions->ARB_polygon_offset_clamp && 41001e04c3fSmrg extensions->ARB_shader_atomic_counter_ops && 41101e04c3fSmrg extensions->ARB_shader_draw_parameters && 41201e04c3fSmrg extensions->ARB_shader_group_vote && 41301e04c3fSmrg extensions->ARB_texture_filter_anisotropic && 41401e04c3fSmrg extensions->ARB_transform_feedback_overflow_query); 41501e04c3fSmrg 41601e04c3fSmrg if (ver_4_6) { 41701e04c3fSmrg major = 4; 41801e04c3fSmrg minor = 6; 41901e04c3fSmrg } 42001e04c3fSmrg else if (ver_4_5) { 42101e04c3fSmrg major = 4; 42201e04c3fSmrg minor = 5; 42301e04c3fSmrg } 42401e04c3fSmrg else if (ver_4_4) { 42501e04c3fSmrg major = 4; 42601e04c3fSmrg minor = 4; 42701e04c3fSmrg } 42801e04c3fSmrg else if (ver_4_3) { 42901e04c3fSmrg major = 4; 43001e04c3fSmrg minor = 3; 43101e04c3fSmrg } 43201e04c3fSmrg else if (ver_4_2) { 43301e04c3fSmrg major = 4; 43401e04c3fSmrg minor = 2; 43501e04c3fSmrg } 43601e04c3fSmrg else if (ver_4_1) { 43701e04c3fSmrg major = 4; 43801e04c3fSmrg minor = 1; 43901e04c3fSmrg } 44001e04c3fSmrg else if (ver_4_0) { 44101e04c3fSmrg major = 4; 44201e04c3fSmrg minor = 0; 44301e04c3fSmrg } 44401e04c3fSmrg else if (ver_3_3) { 4453464ebd5Sriastradh major = 3; 4463464ebd5Sriastradh minor = 3; 4473464ebd5Sriastradh } 4483464ebd5Sriastradh else if (ver_3_2) { 4493464ebd5Sriastradh major = 3; 4503464ebd5Sriastradh minor = 2; 4513464ebd5Sriastradh } 4523464ebd5Sriastradh else if (ver_3_1) { 4533464ebd5Sriastradh major = 3; 4543464ebd5Sriastradh minor = 1; 4553464ebd5Sriastradh } 4563464ebd5Sriastradh else if (ver_3_0) { 4573464ebd5Sriastradh major = 3; 4583464ebd5Sriastradh minor = 0; 4593464ebd5Sriastradh } 4603464ebd5Sriastradh else if (ver_2_1) { 4613464ebd5Sriastradh major = 2; 4623464ebd5Sriastradh minor = 1; 463cdc920a0Smrg } 464cdc920a0Smrg else if (ver_2_0) { 4653464ebd5Sriastradh major = 2; 4663464ebd5Sriastradh minor = 0; 467cdc920a0Smrg } 468cdc920a0Smrg else if (ver_1_5) { 4693464ebd5Sriastradh major = 1; 4703464ebd5Sriastradh minor = 5; 471cdc920a0Smrg } 472cdc920a0Smrg else if (ver_1_4) { 4733464ebd5Sriastradh major = 1; 4743464ebd5Sriastradh minor = 4; 475cdc920a0Smrg } 476cdc920a0Smrg else if (ver_1_3) { 4773464ebd5Sriastradh major = 1; 4783464ebd5Sriastradh minor = 3; 479cdc920a0Smrg } 480cdc920a0Smrg else { 4813464ebd5Sriastradh major = 1; 4823464ebd5Sriastradh minor = 2; 4833464ebd5Sriastradh } 4843464ebd5Sriastradh 485af69d88dSmrg version = major * 10 + minor; 486af69d88dSmrg 487af69d88dSmrg if (api == API_OPENGL_CORE && version < 31) 488af69d88dSmrg return 0; 489af69d88dSmrg 490af69d88dSmrg return version; 491cdc920a0Smrg} 492cdc920a0Smrg 493af69d88dSmrgstatic GLuint 494af69d88dSmrgcompute_version_es1(const struct gl_extensions *extensions) 4953464ebd5Sriastradh{ 4963464ebd5Sriastradh /* OpenGL ES 1.0 is derived from OpenGL 1.3 */ 49701e04c3fSmrg const bool ver_1_0 = (extensions->ARB_texture_env_combine && 49801e04c3fSmrg extensions->ARB_texture_env_dot3); 4993464ebd5Sriastradh /* OpenGL ES 1.1 is derived from OpenGL 1.5 */ 50001e04c3fSmrg const bool ver_1_1 = (ver_1_0 && 50101e04c3fSmrg extensions->EXT_point_parameters); 5023464ebd5Sriastradh 5033464ebd5Sriastradh if (ver_1_1) { 504af69d88dSmrg return 11; 5053464ebd5Sriastradh } else if (ver_1_0) { 506af69d88dSmrg return 10; 5073464ebd5Sriastradh } else { 508af69d88dSmrg return 0; 5093464ebd5Sriastradh } 5103464ebd5Sriastradh} 5113464ebd5Sriastradh 512af69d88dSmrgstatic GLuint 51301e04c3fSmrgcompute_version_es2(const struct gl_extensions *extensions, 51401e04c3fSmrg const struct gl_constants *consts) 5153464ebd5Sriastradh{ 5163464ebd5Sriastradh /* OpenGL ES 2.0 is derived from OpenGL 2.0 */ 51701e04c3fSmrg const bool ver_2_0 = (extensions->ARB_texture_cube_map && 51801e04c3fSmrg extensions->EXT_blend_color && 51901e04c3fSmrg extensions->EXT_blend_func_separate && 52001e04c3fSmrg extensions->EXT_blend_minmax && 52101e04c3fSmrg extensions->ARB_vertex_shader && 52201e04c3fSmrg extensions->ARB_fragment_shader && 52301e04c3fSmrg extensions->ARB_texture_non_power_of_two && 52401e04c3fSmrg extensions->EXT_blend_equation_separate); 525af69d88dSmrg /* FINISHME: This list isn't quite right. */ 52601e04c3fSmrg const bool ver_3_0 = (extensions->ARB_half_float_vertex && 52701e04c3fSmrg extensions->ARB_internalformat_query && 52801e04c3fSmrg extensions->ARB_map_buffer_range && 52901e04c3fSmrg extensions->ARB_shader_texture_lod && 530b9abf16eSmaya extensions->OES_texture_float && 531b9abf16eSmaya extensions->OES_texture_half_float && 532b9abf16eSmaya extensions->OES_texture_half_float_linear && 53301e04c3fSmrg extensions->ARB_texture_rg && 53401e04c3fSmrg extensions->ARB_depth_buffer_float && 535b9abf16eSmaya extensions->ARB_framebuffer_object && 536b9abf16eSmaya extensions->EXT_sRGB && 53701e04c3fSmrg extensions->EXT_packed_float && 53801e04c3fSmrg extensions->EXT_texture_array && 53901e04c3fSmrg extensions->EXT_texture_shared_exponent && 540b9abf16eSmaya extensions->EXT_texture_sRGB && 54101e04c3fSmrg extensions->EXT_transform_feedback && 54201e04c3fSmrg extensions->ARB_draw_instanced && 54301e04c3fSmrg extensions->ARB_uniform_buffer_object && 54401e04c3fSmrg extensions->EXT_texture_snorm && 5457ec681f3Smrg (extensions->NV_primitive_restart || 5467ec681f3Smrg consts->PrimitiveRestartFixedIndex) && 547b9abf16eSmaya extensions->OES_depth_texture_cube_map && 5487ec681f3Smrg extensions->EXT_texture_type_2_10_10_10_REV && 5497ec681f3Smrg consts->MaxColorAttachments >= 4); 55001e04c3fSmrg const bool es31_compute_shader = 5517ec681f3Smrg consts->MaxComputeWorkGroupInvocations >= 128 && 5527ec681f3Smrg consts->Program[MESA_SHADER_COMPUTE].MaxShaderStorageBlocks && 5537ec681f3Smrg consts->Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers && 5547ec681f3Smrg consts->Program[MESA_SHADER_COMPUTE].MaxImageUniforms; 55501e04c3fSmrg const bool ver_3_1 = (ver_3_0 && 55601e04c3fSmrg consts->MaxVertexAttribStride >= 2048 && 55701e04c3fSmrg extensions->ARB_arrays_of_arrays && 55801e04c3fSmrg es31_compute_shader && 55901e04c3fSmrg extensions->ARB_draw_indirect && 56001e04c3fSmrg extensions->ARB_explicit_uniform_location && 56101e04c3fSmrg extensions->ARB_framebuffer_no_attachments && 56201e04c3fSmrg extensions->ARB_shading_language_packing && 56301e04c3fSmrg extensions->ARB_stencil_texturing && 56401e04c3fSmrg extensions->ARB_texture_multisample && 56501e04c3fSmrg extensions->ARB_texture_gather && 56601e04c3fSmrg extensions->MESA_shader_integer_functions && 56701e04c3fSmrg extensions->EXT_shader_integer_mix); 56801e04c3fSmrg const bool ver_3_2 = (ver_3_1 && 5697ec681f3Smrg /* ES 3.2 requires that images/buffers be accessible 5707ec681f3Smrg * from fragment shaders as well 5717ec681f3Smrg */ 5727ec681f3Smrg extensions->ARB_shader_atomic_counters && 5737ec681f3Smrg extensions->ARB_shader_image_load_store && 5747ec681f3Smrg extensions->ARB_shader_image_size && 5757ec681f3Smrg extensions->ARB_shader_storage_buffer_object && 5767ec681f3Smrg 57701e04c3fSmrg extensions->EXT_draw_buffers2 && 57801e04c3fSmrg extensions->KHR_blend_equation_advanced && 57901e04c3fSmrg extensions->KHR_robustness && 58001e04c3fSmrg extensions->KHR_texture_compression_astc_ldr && 58101e04c3fSmrg extensions->OES_copy_image && 58201e04c3fSmrg extensions->ARB_draw_buffers_blend && 58301e04c3fSmrg extensions->ARB_draw_elements_base_vertex && 58401e04c3fSmrg extensions->OES_geometry_shader && 58501e04c3fSmrg extensions->OES_primitive_bounding_box && 58601e04c3fSmrg extensions->OES_sample_variables && 58701e04c3fSmrg extensions->ARB_tessellation_shader && 58801e04c3fSmrg extensions->ARB_texture_border_clamp && 58901e04c3fSmrg extensions->OES_texture_buffer && 59001e04c3fSmrg extensions->OES_texture_cube_map_array && 59101e04c3fSmrg extensions->ARB_texture_stencil8); 59201e04c3fSmrg 59301e04c3fSmrg if (ver_3_2) { 59401e04c3fSmrg return 32; 59501e04c3fSmrg } else if (ver_3_1) { 59601e04c3fSmrg return 31; 59701e04c3fSmrg } else if (ver_3_0) { 598af69d88dSmrg return 30; 599af69d88dSmrg } else if (ver_2_0) { 600af69d88dSmrg return 20; 6013464ebd5Sriastradh } else { 602af69d88dSmrg return 0; 6033464ebd5Sriastradh } 604af69d88dSmrg} 6053464ebd5Sriastradh 606af69d88dSmrgGLuint 607af69d88dSmrg_mesa_get_version(const struct gl_extensions *extensions, 608af69d88dSmrg struct gl_constants *consts, gl_api api) 609af69d88dSmrg{ 610af69d88dSmrg switch (api) { 611af69d88dSmrg case API_OPENGL_COMPAT: 61201e04c3fSmrg /* Disable higher GLSL versions for legacy contexts. 61301e04c3fSmrg * This disallows creation of higher compatibility contexts. */ 61401e04c3fSmrg if (!consts->AllowHigherCompatVersion) { 61501e04c3fSmrg consts->GLSLVersion = consts->GLSLVersionCompat; 616af69d88dSmrg } 6177ec681f3Smrg FALLTHROUGH; 618af69d88dSmrg case API_OPENGL_CORE: 619af69d88dSmrg return compute_version(extensions, consts, api); 620af69d88dSmrg case API_OPENGLES: 621af69d88dSmrg return compute_version_es1(extensions); 622af69d88dSmrg case API_OPENGLES2: 62301e04c3fSmrg return compute_version_es2(extensions, consts); 6243464ebd5Sriastradh } 625af69d88dSmrg return 0; 6263464ebd5Sriastradh} 627cdc920a0Smrg 628cdc920a0Smrg/** 629af69d88dSmrg * Set the context's Version and VersionString fields. 6303464ebd5Sriastradh * This should only be called once as part of context initialization 6313464ebd5Sriastradh * or to perform version check for GLX_ARB_create_context_profile. 632cdc920a0Smrg */ 633cdc920a0Smrgvoid 6343464ebd5Sriastradh_mesa_compute_version(struct gl_context *ctx) 635cdc920a0Smrg{ 636af69d88dSmrg if (ctx->Version) 63701e04c3fSmrg goto done; 638cdc920a0Smrg 639af69d88dSmrg ctx->Version = _mesa_get_version(&ctx->Extensions, &ctx->Const, ctx->API); 64001e04c3fSmrg ctx->Extensions.Version = ctx->Version; 64101e04c3fSmrg 64201e04c3fSmrg /* Make sure that the GLSL version lines up with the GL version. In some 64301e04c3fSmrg * cases it can be too high, e.g. if an extension is missing. 64401e04c3fSmrg */ 64501e04c3fSmrg if (_mesa_is_desktop_gl(ctx)) { 64601e04c3fSmrg switch (ctx->Version) { 64701e04c3fSmrg case 20: 6487ec681f3Smrg FALLTHROUGH; /* GLSL 1.20 is the minimum we support */ 64901e04c3fSmrg case 21: 65001e04c3fSmrg ctx->Const.GLSLVersion = 120; 65101e04c3fSmrg break; 65201e04c3fSmrg case 30: 65301e04c3fSmrg ctx->Const.GLSLVersion = 130; 65401e04c3fSmrg break; 65501e04c3fSmrg case 31: 65601e04c3fSmrg ctx->Const.GLSLVersion = 140; 65701e04c3fSmrg break; 65801e04c3fSmrg case 32: 65901e04c3fSmrg ctx->Const.GLSLVersion = 150; 66001e04c3fSmrg break; 66101e04c3fSmrg default: 66201e04c3fSmrg if (ctx->Version >= 33) 66301e04c3fSmrg ctx->Const.GLSLVersion = ctx->Version * 10; 66401e04c3fSmrg break; 66501e04c3fSmrg } 66601e04c3fSmrg } 667af69d88dSmrg 6683464ebd5Sriastradh switch (ctx->API) { 669af69d88dSmrg case API_OPENGL_COMPAT: 670af69d88dSmrg case API_OPENGL_CORE: 671af69d88dSmrg create_version_string(ctx, ""); 6723464ebd5Sriastradh break; 673af69d88dSmrg 6743464ebd5Sriastradh case API_OPENGLES: 675af69d88dSmrg if (!ctx->Version) { 676af69d88dSmrg _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support."); 677af69d88dSmrg return; 678af69d88dSmrg } 679af69d88dSmrg create_version_string(ctx, "OpenGL ES-CM "); 6803464ebd5Sriastradh break; 681af69d88dSmrg 6823464ebd5Sriastradh case API_OPENGLES2: 683af69d88dSmrg if (!ctx->Version) { 684af69d88dSmrg _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support."); 685af69d88dSmrg return; 686af69d88dSmrg } 687af69d88dSmrg create_version_string(ctx, "OpenGL ES "); 6883464ebd5Sriastradh break; 689cdc920a0Smrg } 69001e04c3fSmrg 69101e04c3fSmrgdone: 69201e04c3fSmrg if (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 31) 69301e04c3fSmrg ctx->Extensions.ARB_compatibility = GL_TRUE; 6947ec681f3Smrg 6957ec681f3Smrg /* Precompute valid primitive types for faster draw time validation. */ 6967ec681f3Smrg /* All primitive type enums are less than 32, so we can use the shift. */ 6977ec681f3Smrg ctx->SupportedPrimMask = (1 << GL_POINTS) | 6987ec681f3Smrg (1 << GL_LINES) | 6997ec681f3Smrg (1 << GL_LINE_LOOP) | 7007ec681f3Smrg (1 << GL_LINE_STRIP) | 7017ec681f3Smrg (1 << GL_TRIANGLES) | 7027ec681f3Smrg (1 << GL_TRIANGLE_STRIP) | 7037ec681f3Smrg (1 << GL_TRIANGLE_FAN); 7047ec681f3Smrg 7057ec681f3Smrg if (ctx->API == API_OPENGL_COMPAT) { 7067ec681f3Smrg ctx->SupportedPrimMask |= (1 << GL_QUADS) | 7077ec681f3Smrg (1 << GL_QUAD_STRIP) | 7087ec681f3Smrg (1 << GL_POLYGON); 7097ec681f3Smrg } 7107ec681f3Smrg 7117ec681f3Smrg if (_mesa_has_geometry_shaders(ctx)) { 7127ec681f3Smrg ctx->SupportedPrimMask |= (1 << GL_LINES_ADJACENCY) | 7137ec681f3Smrg (1 << GL_LINE_STRIP_ADJACENCY) | 7147ec681f3Smrg (1 << GL_TRIANGLES_ADJACENCY) | 7157ec681f3Smrg (1 << GL_TRIANGLE_STRIP_ADJACENCY); 7167ec681f3Smrg } 7177ec681f3Smrg 7187ec681f3Smrg if (_mesa_has_tessellation(ctx)) 7197ec681f3Smrg ctx->SupportedPrimMask |= 1 << GL_PATCHES; 7207ec681f3Smrg 7217ec681f3Smrg /* First time initialization. */ 7227ec681f3Smrg _mesa_update_valid_to_render_state(ctx); 72301e04c3fSmrg} 72401e04c3fSmrg 72501e04c3fSmrg 72601e04c3fSmrgvoid 72701e04c3fSmrg_mesa_get_driver_uuid(struct gl_context *ctx, GLint *uuid) 72801e04c3fSmrg{ 72901e04c3fSmrg ctx->Driver.GetDriverUuid(ctx, (char*) uuid); 73001e04c3fSmrg} 73101e04c3fSmrg 73201e04c3fSmrgvoid 73301e04c3fSmrg_mesa_get_device_uuid(struct gl_context *ctx, GLint *uuid) 73401e04c3fSmrg{ 73501e04c3fSmrg ctx->Driver.GetDeviceUuid(ctx, (char*) uuid); 73601e04c3fSmrg} 73701e04c3fSmrg 73801e04c3fSmrg/** 73901e04c3fSmrg * Get the i-th GLSL version string. If index=0, return the most recent 74001e04c3fSmrg * supported version. 74101e04c3fSmrg * \param ctx context to query 74201e04c3fSmrg * \param index which version string to return, or -1 if none 74301e04c3fSmrg * \param versionOut returns the vesrion string 74401e04c3fSmrg * \return total number of shading language versions. 74501e04c3fSmrg */ 74601e04c3fSmrgint 74701e04c3fSmrg_mesa_get_shading_language_version(const struct gl_context *ctx, 74801e04c3fSmrg int index, 74901e04c3fSmrg char **versionOut) 75001e04c3fSmrg{ 75101e04c3fSmrg int n = 0; 75201e04c3fSmrg 75301e04c3fSmrg#define GLSL_VERSION(S) \ 75401e04c3fSmrg if (n++ == index) \ 75501e04c3fSmrg *versionOut = S 75601e04c3fSmrg 75701e04c3fSmrg /* GLSL core */ 75801e04c3fSmrg if (ctx->Const.GLSLVersion >= 460) 75901e04c3fSmrg GLSL_VERSION("460"); 76001e04c3fSmrg if (ctx->Const.GLSLVersion >= 450) 76101e04c3fSmrg GLSL_VERSION("450"); 76201e04c3fSmrg if (ctx->Const.GLSLVersion >= 440) 76301e04c3fSmrg GLSL_VERSION("440"); 76401e04c3fSmrg if (ctx->Const.GLSLVersion >= 430) 76501e04c3fSmrg GLSL_VERSION("430"); 76601e04c3fSmrg if (ctx->Const.GLSLVersion >= 420) 76701e04c3fSmrg GLSL_VERSION("420"); 76801e04c3fSmrg if (ctx->Const.GLSLVersion >= 410) 76901e04c3fSmrg GLSL_VERSION("410"); 77001e04c3fSmrg if (ctx->Const.GLSLVersion >= 400) 77101e04c3fSmrg GLSL_VERSION("400"); 77201e04c3fSmrg if (ctx->Const.GLSLVersion >= 330) 77301e04c3fSmrg GLSL_VERSION("330"); 77401e04c3fSmrg if (ctx->Const.GLSLVersion >= 150) 77501e04c3fSmrg GLSL_VERSION("150"); 77601e04c3fSmrg if (ctx->Const.GLSLVersion >= 140) 77701e04c3fSmrg GLSL_VERSION("140"); 77801e04c3fSmrg if (ctx->Const.GLSLVersion >= 130) 77901e04c3fSmrg GLSL_VERSION("130"); 78001e04c3fSmrg if (ctx->Const.GLSLVersion >= 120) 78101e04c3fSmrg GLSL_VERSION("120"); 78201e04c3fSmrg /* The GL spec says to return the empty string for GLSL 1.10 */ 78301e04c3fSmrg if (ctx->Const.GLSLVersion >= 110) 78401e04c3fSmrg GLSL_VERSION(""); 78501e04c3fSmrg 78601e04c3fSmrg /* GLSL es */ 78701e04c3fSmrg if ((ctx->API == API_OPENGLES2 && ctx->Version >= 32) || 78801e04c3fSmrg ctx->Extensions.ARB_ES3_2_compatibility) 78901e04c3fSmrg GLSL_VERSION("320 es"); 79001e04c3fSmrg if (_mesa_is_gles31(ctx) || ctx->Extensions.ARB_ES3_1_compatibility) 79101e04c3fSmrg GLSL_VERSION("310 es"); 79201e04c3fSmrg if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) 79301e04c3fSmrg GLSL_VERSION("300 es"); 79401e04c3fSmrg if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) 79501e04c3fSmrg GLSL_VERSION("100"); 79601e04c3fSmrg 79701e04c3fSmrg#undef GLSL_VERSION 79801e04c3fSmrg 79901e04c3fSmrg return n; 800cdc920a0Smrg} 801