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