1/* 2 * Copyright © 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include <string.h> 25#include <ctype.h> 26 27#include "glxclient.h" 28#include <xcb/glx.h> 29#include <X11/Xlib-xcb.h> 30 31_X_HIDDEN void 32__glX_send_client_info(struct glx_display *glx_dpy) 33{ 34 const unsigned ext_length = strlen("GLX_ARB_create_context"); 35 const unsigned prof_length = strlen("_profile"); 36 char *gl_extension_string; 37 int gl_extension_length; 38 xcb_connection_t *c; 39 Bool any_screen_has_ARB_create_context = False; 40 Bool any_screen_has_ARB_create_context_profile = False; 41 unsigned i; 42 /* You need GLX_ARB_create_context_profile to get beyond 3.1 anyway */ 43 static const uint32_t gl_versions[] = { 44 2, 1, 45 3, 0, 46 3, 1, 47 }; 48 /* 49 * This is weird, but it matches what NVIDIA does/expects. For big-GL 50 * below 3.2 there is no such thing as a "profile", so we name them all 51 * with no profile bits. Except we don't name anything lower than 2.1, 52 * since GLX_ARB_create_context_profile says: 53 * 54 * "Only the highest supported version below 3.0 should be sent, since 55 * OpenGL 2.1 is backwards compatible with all earlier versions." 56 * 57 * In order to also support GLES below 3.2, we name every possible GLES 58 * version with the ES2 bit set, which happens to just mean GLES generally 59 * and not a particular major version. 3.2 happens to be a legal version 60 * number for both big-GL and GLES, so it gets all three bits set. 61 * Everything 3.3 and above is big-GL only so gets the core and compat 62 * bits set. 63 */ 64 static const uint32_t gl_versions_profiles[] = { 65 1, 0, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 66 1, 1, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 67 2, 0, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 68 2, 1, 0x0, 69 3, 0, 0x0, 70 3, 0, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 71 3, 1, 0x0, 72 3, 1, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 73 3, 2, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 74 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB | 75 GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 76 3, 3, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 77 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 78 4, 0, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 79 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 80 4, 1, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 81 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 82 4, 2, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 83 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 84 4, 3, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 85 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 86 4, 4, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 87 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 88 4, 5, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 89 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 90 4, 6, GLX_CONTEXT_CORE_PROFILE_BIT_ARB | 91 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 92 }; 93 static const char glx_extensions[] = 94 "GLX_ARB_create_context GLX_ARB_create_context_profile"; 95 96 /* There are three possible flavors of the client info structure that the 97 * client could send to the server. The version sent depends on the 98 * combination of GLX versions and extensions supported by the client and 99 * the server. This client only supports GLX major version 1. 100 * 101 * Server supports Client sends 102 * ---------------------------------------------------------------------- 103 * GLX version = 1.0 Nothing. 104 * 105 * GLX version >= 1.1 struct GLXClientInfo 106 * 107 * GLX version >= 1.4 and 108 * GLX_ARB_create_context struct glXSetClientInfoARB 109 * 110 * GLX version >= 1.4 and 111 * GLX_ARB_create_context_profile struct glXSetClientInfo2ARB 112 * 113 * GLX_ARB_create_context and GLX_ARB_create_context_profile use FBConfigs, 114 * and these only exist in GLX 1.4 or with GLX_SGIX_fbconfig. I can't 115 * imagine an implementation that supports GLX_SGIX_fbconfig and 116 * GLX_ARB_create_context but not GLX 1.4. Making GLX 1.4 a hard 117 * requirement in this case does not seem like a limitation. 118 */ 119 120 if (glx_dpy->minorVersion == 0) 121 return; 122 123 /* Determine whether any screen on the server supports either of the 124 * create-context extensions. 125 */ 126 for (i = 0; i < ScreenCount(glx_dpy->dpy); i++) { 127 struct glx_screen *src = glx_dpy->screens[i]; 128 129 const char *haystack = src->serverGLXexts; 130 while (haystack != NULL) { 131 char *match = strstr(haystack, "GLX_ARB_create_context"); 132 133 if (match == NULL) 134 break; 135 136 match += ext_length; 137 138 switch (match[0]) { 139 case '\0': 140 case ' ': 141 any_screen_has_ARB_create_context = True; 142 break; 143 144 case '_': 145 if (strncmp(match, "_profile", prof_length) == 0 146 && (match[prof_length] == '\0' 147 || match[prof_length] == ' ')) { 148 any_screen_has_ARB_create_context_profile = True; 149 match += prof_length; 150 } 151 break; 152 } 153 154 haystack = match; 155 } 156 } 157 158 gl_extension_string = __glXGetClientGLExtensionString(); 159 if (gl_extension_string == NULL) { 160 return; 161 } 162 163 gl_extension_length = strlen(gl_extension_string) + 1; 164 165 c = XGetXCBConnection(glx_dpy->dpy); 166 167 /* Depending on the GLX verion and the available extensions on the server, 168 * send the correct "flavor" of protocol to the server. 169 * 170 * THE ORDER IS IMPORTANT. We want to send the most recent version of the 171 * protocol that the server can support. 172 */ 173 if (glx_dpy->minorVersion == 4 174 && any_screen_has_ARB_create_context_profile) { 175 xcb_glx_set_client_info_2arb(c, 176 GLX_MAJOR_VERSION, GLX_MINOR_VERSION, 177 sizeof(gl_versions_profiles) 178 / (3 * sizeof(gl_versions_profiles[0])), 179 gl_extension_length, 180 strlen(glx_extensions) + 1, 181 gl_versions_profiles, 182 gl_extension_string, 183 glx_extensions); 184 } else if (glx_dpy->minorVersion == 4 185 && any_screen_has_ARB_create_context) { 186 xcb_glx_set_client_info_arb(c, 187 GLX_MAJOR_VERSION, GLX_MINOR_VERSION, 188 sizeof(gl_versions) 189 / (2 * sizeof(gl_versions[0])), 190 gl_extension_length, 191 strlen(glx_extensions) + 1, 192 gl_versions, 193 gl_extension_string, 194 glx_extensions); 195 } else { 196 xcb_glx_client_info(c, 197 GLX_MAJOR_VERSION, GLX_MINOR_VERSION, 198 gl_extension_length, 199 gl_extension_string); 200 } 201 202 free(gl_extension_string); 203} 204