### Build libglvnd with Meson Source: https://context7.com/glvnd/libglvnd/llms.txt Instructions for building libglvnd using the Meson build system, including dependency installation, configuration, building, testing, and installation. Recommended for faster builds. ```bash # Build using Meson (recommended, faster) # Install dependencies (Debian/Ubuntu) sudo apt-get install libxext-dev libx11-dev x11proto-gl-dev meson ninja-build # Configure and build meson builddir ninja -C builddir # Run tests ninja -C builddir test # Install sudo ninja -C builddir install # Build using Autotools ./autogen.sh ./configure --prefix=/usr make make check sudo make install # Configuration options (meson) meson builddir \ -Dglx=enabled \ -Degl=true \ -Dgles1=true \ -Dgles2=true \ -Dx11=enabled \ -Dtls=true # View all options Meson configure builddir ``` -------------------------------- ### Install build dependencies on Debian Source: https://github.com/glvnd/libglvnd/blob/master/README.md Required packages for building libglvnd on Debian-based systems. ```bash sudo apt-get install libxext-dev libx11-dev x11proto-gl-dev ``` -------------------------------- ### Mesa EGL ICD Configuration Source: https://github.com/glvnd/libglvnd/blob/master/src/EGL/icd_enumeration.md Example JSON file for configuring the Mesa EGL ICD. This file is typically installed in a system directory and specifies the library path for the Mesa EGL driver. ```json { "file_format_version" : "1.0.0", "ICD" : { "library_path" : "libEGL_mesa.so.0" } } ``` -------------------------------- ### Third-Party EGL ICD Configuration Source: https://github.com/glvnd/libglvnd/blob/master/src/EGL/icd_enumeration.md Example JSON file for a third-party EGL ICD installed in a custom location. This specifies an absolute path to the ICD library, ensuring it can be found by the loader. ```json { "file_format_version" : "1.0.0", "ICD" : { "library_path" : "/opt/myvendor/lib64/libEGL_myvendor.so" } } ``` -------------------------------- ### Configure EGL ICD Discovery Source: https://context7.com/glvnd/libglvnd/llms.txt EGL vendor libraries are discovered via JSON configuration files. These files specify the library path and can be installed system-wide or configured via environment variables. ```json { "file_format_version": "1.0.0", "ICD": { "library_path": "libEGL_vendor.so.0" } } ``` ```bash # Install vendor ICD configuration file # System-wide installation (requires root) sudo mkdir -p /usr/share/glvnd/egl_vendor.d sudo cp 50_myvendor.json /usr/share/glvnd/egl_vendor.d/ # Alternative: Use environment variable for testing export __EGL_VENDOR_LIBRARY_FILENAMES=/path/to/myvendor.json # Or specify search directories export __EGL_VENDOR_LIBRARY_DIRS=/opt/myvendor/share/glvnd/egl_vendor.d # Example JSON for vendor at non-standard location cat > /etc/glvnd/egl_vendor.d/10_myvendor.json << 'EOF' { "file_format_version": "1.0.0", "ICD": { "library_path": "/opt/myvendor/lib64/libEGL_myvendor.so" } } EOF ``` -------------------------------- ### Standard OpenGL Application with libglvnd Source: https://context7.com/glvnd/libglvnd/llms.txt Demonstrates initializing a GLX context and performing rendering using libglvnd's transparent dispatch mechanism. ```c // Standard OpenGL application - works with libglvnd transparently #include #include int main(int argc, char *argv[]) { Display *dpy = XOpenDisplay(NULL); // Choose framebuffer config int attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_DOUBLEBUFFER, True, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, None }; int numConfigs; GLXFBConfig *configs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &numConfigs); // Create context - libglvnd dispatches to correct vendor GLXContext ctx = glXCreateNewContext(dpy, configs[0], GLX_RGBA_TYPE, NULL, True); // Create window and make current XVisualInfo *vi = glXGetVisualFromFBConfig(dpy, configs[0]); Window win = createWindow(dpy, vi); glXMakeCurrent(dpy, win, ctx); // OpenGL calls are dispatched to the vendor that owns the context glClearColor(0.0f, 0.0f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glXSwapBuffers(dpy, win); // Clean up glXMakeCurrent(dpy, None, NULL); glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return 0; } ``` -------------------------------- ### GLX Vendor Library Entry Point (`__glx_Main`) Source: https://context7.com/glvnd/libglvnd/llms.txt The `__glx_Main` function is the mandatory entry point for GLX vendor libraries. It handles the ABI handshake with libGLX, receives necessary exports, and provides implementations for required callbacks. ```APIDOC ## GLX Vendor Library Entry Point (`__glx_Main`) ### Description This function serves as the primary interface for GLX vendor libraries to register with libGLX. It performs an ABI version check, stores essential export tables, and populates the import table with vendor-provided callback function pointers. ### Method C Function ### Endpoint N/A (Library Entry Point) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include Bool __glx_Main(uint32_t version, const __GLXapiExports *exports, __GLXvendorInfo *vendor, __GLXapiImports *imports) { // Check ABI version compatibility if (GLX_VENDOR_ABI_GET_MAJOR_VERSION(version) != GLX_VENDOR_ABI_GET_MAJOR_VERSION(GLX_VENDOR_ABI_VERSION)) { return False; // Incompatible major version } // Store the exports table for later use g_glxExports = exports; g_vendorInfo = vendor; // Fill in the required callbacks imports->isScreenSupported = myIsScreenSupported; imports->getProcAddress = myGetProcAddress; imports->getDispatchAddress = myGetDispatchAddress; imports->setDispatchIndex = mySetDispatchIndex; // Optional callbacks imports->notifyError = myNotifyError; imports->isPatchSupported = myIsPatchSupported; imports->initiatePatch = myInitiatePatch; imports->releasePatch = myReleasePatch; imports->patchThreadAttach = myPatchThreadAttach; return True; // Success } ``` ### Response #### Success Response (True) Indicates successful initialization and registration of the vendor library. #### Error Response (False) Indicates failure, typically due to incompatible ABI versions. #### Response Example `True` or `False` (Boolean) ``` -------------------------------- ### Implement GLX Vendor Library Entry Point Source: https://context7.com/glvnd/libglvnd/llms.txt The __glx_Main function is the mandatory entry point for GLX vendor libraries. It handles ABI version verification and registers required callbacks for screen support, function lookups, and dispatch management. ```c #include // Vendor library implementation of the main entry point Bool __glx_Main(uint32_t version, const __GLXapiExports *exports, __GLXvendorInfo *vendor, __GLXapiImports *imports) { // Check ABI version compatibility if (GLX_VENDOR_ABI_GET_MAJOR_VERSION(version) != GLX_VENDOR_ABI_GET_MAJOR_VERSION(GLX_VENDOR_ABI_VERSION)) { return False; // Incompatible major version } // Store the exports table for later use g_glxExports = exports; g_vendorInfo = vendor; // Fill in the required callbacks imports->isScreenSupported = myIsScreenSupported; imports->getProcAddress = myGetProcAddress; imports->getDispatchAddress = myGetDispatchAddress; imports->setDispatchIndex = mySetDispatchIndex; // Optional callbacks imports->notifyError = myNotifyError; imports->isPatchSupported = myIsPatchSupported; imports->initiatePatch = myInitiatePatch; imports->releasePatch = myReleasePatch; imports->patchThreadAttach = myPatchThreadAttach; return True; // Success } // Required callback: Check if vendor supports a screen static Bool myIsScreenSupported(Display *dpy, int screen) { // Check if this vendor can handle the given display/screen // Return False to fall back to indirect rendering return True; } // Required callback: Return function pointer for GL/GLX function static void *myGetProcAddress(const GLubyte *procName) { // Return pointer to vendor's implementation of the function if (strcmp((const char *)procName, "glClear") == 0) { return (void *)vendor_glClear; } return NULL; } // Required callback: Return dispatch stub for GLX extension static void *myGetDispatchAddress(const GLubyte *procName) { // Return vendor-neutral dispatch function for GLX extensions if (strcmp((const char *)procName, "glXExampleExtensionFunction") == 0) { return (void *)dispatch_glXExampleExtensionFunction; } return NULL; } ``` -------------------------------- ### Build libglvnd using Meson Source: https://github.com/glvnd/libglvnd/blob/master/README.md Alternative build process using Meson and Ninja for faster compilation. ```bash sudo apt-get install ninja-build meson meson builddir ninja -C builddir ``` -------------------------------- ### Build libglvnd using Autotools Source: https://github.com/glvnd/libglvnd/blob/master/README.md Standard build process using autogen and make. ```bash ./autogen.sh ./configure make ``` -------------------------------- ### Implement GLX Vendor Dispatch Functions Source: https://context7.com/glvnd/libglvnd/llms.txt Demonstrates how vendor libraries implement GLX extension dispatching and manage context/drawable mappings using libGLX exports. ```c #include // Example GLX extension dispatch function void dispatch_glXExampleExtensionFunction(Display *dpy, int screen, int *retval) { // Get the vendor info for this display/screen __GLXvendorInfo *vendor = g_glxExports->getDynDispatch(dpy, screen); if (vendor == NULL) { return; } // Get the actual function from the dispatch table PFNGLXEXAMPLEEXTENSIONFUNCTION func = (PFNGLXEXAMPLEEXTENSIONFUNCTION)g_glxExports->fetchDispatchEntry( vendor, DISPATCH_INDEX_glXExampleExtensionFunction); if (func != NULL) { func(dpy, screen, retval); } } // Creating and tracking GLX contexts GLXContext createContext(Display *dpy, GLXFBConfig config, GLXContext shareList, Bool direct) { // Create the actual context GLXContext ctx = actualCreateContext(dpy, config, shareList, direct); if (ctx != NULL) { // Register the context with libGLX int result = g_glxExports->addVendorContextMapping(dpy, ctx, g_vendorInfo); if (result != 0) { actualDestroyContext(dpy, ctx); return NULL; } } return ctx; } // Destroying contexts void destroyContext(Display *dpy, GLXContext ctx) { // Remove from libGLX tracking first g_glxExports->removeVendorContextMapping(dpy, ctx); // Then destroy the actual context actualDestroyContext(dpy, ctx); } // Dispatch function for drawable-based operations void dispatch_glXSwapBuffers(Display *dpy, GLXDrawable drawable) { __GLXvendorInfo *vendor = g_glxExports->vendorFromDrawable(dpy, drawable); if (vendor == NULL) { return; } PFNGLXSWAPBUFFERSPROC func = (PFNGLXSWAPBUFFERSPROC)g_glxExports->fetchDispatchEntry( vendor, DISPATCH_INDEX_glXSwapBuffers); if (func != NULL) { func(dpy, drawable); } } ``` -------------------------------- ### Entrypoint Patching Support Functions Source: https://context7.com/glvnd/libglvnd/llms.txt These C functions demonstrate how vendor libraries can implement entrypoint patching for performance. They require GLdispatchABI.h and include checks for patch support, initiation, release, and thread attachment. ```c #include // Check if patching is supported for the given stub type GLboolean myIsPatchSupported(int type, int stubSize) { // Check if we support this architecture switch (type) { case __GLDISPATCH_STUB_X86_64: return (stubSize >= 16); // Need at least 16 bytes case __GLDISPATCH_STUB_X86: return (stubSize >= 8); case __GLDISPATCH_STUB_AARCH64: return (stubSize >= 16); default: return GL_FALSE; } } // Patch the entrypoints GLboolean myInitiatePatch(int type, int stubSize, DispatchPatchLookupStubOffset lookupStubOffset) { // Iterate over functions to patch const char *functions[] = {"glClear", "glDrawArrays", "glDrawElements", NULL}; for (int i = 0; functions[i] != NULL; i++) { void *writePtr; const void *execPtr; if (lookupStubOffset(functions[i], &writePtr, &execPtr)) { // Write patch code to writePtr // Use execPtr for PC-relative offset calculations patchFunction(type, writePtr, execPtr, stubSize, getVendorFunctionAddress(functions[i])); } } return GL_TRUE; } // Called when patching is no longer needed void myReleasePatch(void) { // Clean up any vendor-side state related to patching // Note: libglvnd restores the original stubs automatically } // Called when a thread starts using GL void myPatchThreadAttach(void) { // Initialize any per-thread state needed by the vendor initializeThreadState(); } ``` -------------------------------- ### Implement EGL Vendor Entry Point Source: https://context7.com/glvnd/libglvnd/llms.txt The __egl_Main function is the mandatory entry point for EGL vendor libraries to exchange function tables with libEGL. ```c #include // Global pointer to libEGL's exported functions static const __EGLapiExports *g_eglExports = NULL; EGLBoolean __egl_Main(uint32_t version, const __EGLapiExports *exports, __EGLvendorInfo *vendor, __EGLapiImports *imports) { // Verify ABI compatibility if (EGL_VENDOR_ABI_GET_MAJOR_VERSION(version) != EGL_VENDOR_ABI_GET_MAJOR_VERSION(EGL_VENDOR_ABI_VERSION)) { return EGL_FALSE; } // Store the exports for later use g_eglExports = exports; // Fill in required callbacks imports->getPlatformDisplay = myGetPlatformDisplay; imports->getSupportsAPI = myGetSupportsAPI; imports->getProcAddress = myGetProcAddress; imports->getDispatchAddress = myGetDispatchAddress; imports->setDispatchIndex = mySetDispatchIndex; // Optional callbacks imports->getVendorString = myGetVendorString; imports->isPatchSupported = myIsPatchSupported; imports->initiatePatch = myInitiatePatch; imports->releasePatch = myReleasePatch; imports->patchThreadAttach = myPatchThreadAttach; imports->findNativeDisplayPlatform = myFindNativeDisplayPlatform; return EGL_TRUE; } // Required callback: Create an EGLDisplay static EGLDisplay myGetPlatformDisplay(EGLenum platform, void *nativeDisplay, const EGLAttrib *attrib_list) { // Handle EGL_DEFAULT_DISPLAY if (platform == EGL_NONE && nativeDisplay == EGL_DEFAULT_DISPLAY) { return createDefaultDisplay(); } // Handle specific platforms if (platform == EGL_PLATFORM_GBM_KHR) { return createGbmDisplay(nativeDisplay, attrib_list); } return EGL_NO_DISPLAY; } // Required callback: Check if vendor supports the given API static EGLBoolean myGetSupportsAPI(EGLenum api) { switch (api) { case EGL_OPENGL_API: case EGL_OPENGL_ES_API: return EGL_TRUE; default: return EGL_FALSE; } } ``` -------------------------------- ### Compiling Applications with libglvnd Source: https://context7.com/glvnd/libglvnd/llms.txt Commands for linking applications against libglvnd libraries using direct flags or pkg-config. ```bash # Compile application - link against libglvnd libraries gcc -o myapp myapp.c -lGL -lX11 # For EGL applications gcc -o myeglapp myeglapp.c -lEGL -lGLESv2 # pkg-config support gcc -o myapp myapp.c $(pkg-config --cflags --libs gl x11) gcc -o myeglapp myeglapp.c $(pkg-config --cflags --libs egl glesv2) ``` -------------------------------- ### Initialize and Manage GLdispatch Contexts Source: https://context7.com/glvnd/libglvnd/llms.txt Provides the core lifecycle management for GLdispatch, including initialization, dispatch table creation, and context switching. ```c #include "GLdispatch.h" // Initialize GLdispatch (call once at library load) void initializeGLdispatch(void) { // Check ABI version int abiVersion = __glDispatchGetABIVersion(); if (abiVersion != GLDISPATCH_ABI_VERSION) { fprintf(stderr, "GLdispatch ABI mismatch\n"); return; } // Initialize the dispatch system __glDispatchInit(); } // Create a dispatch table for a new context __GLdispatchTable *createDispatchTable(void) { // Callback to provide function addresses return __glDispatchCreateTable(myGetProcAddressCallback, NULL); } static void *myGetProcAddressCallback(const char *procName, void *param) { // Return vendor's implementation of the function return dlsym(vendorLibHandle, procName); } // Make a context current GLboolean makeContextCurrent(__GLdispatchThreadState *threadState, __GLdispatchTable *dispatch, int vendorID) { // Optional: provide patch callbacks for entrypoint optimization __GLdispatchPatchCallbacks patchCb = { .isPatchSupported = myIsPatchSupported, .initiatePatch = myInitiatePatch, .releasePatch = myReleasePatch, .threadAttach = myThreadAttach }; return __glDispatchMakeCurrent(threadState, dispatch, vendorID, &patchCb); } // Release the current context void releaseContext(void) { __glDispatchLoseCurrent(); } // Get function pointer for application use __GLdispatchProc getProcAddress(const char *name) { return __glDispatchGetProcAddress(name); } // Clean up on library unload void cleanupGLdispatch(void) { __glDispatchFini(); } ``` -------------------------------- ### EGL Vendor Library Entry Point Source: https://context7.com/glvnd/libglvnd/llms.txt The __egl_Main function is the mandatory entry point for EGL vendor libraries, used to exchange function tables between libEGL and the vendor library. ```APIDOC ## __egl_Main ### Description Initializes the vendor library and exchanges function pointers with libEGL. This function verifies ABI compatibility and populates the imports structure with vendor-specific callbacks. ### Parameters - **version** (uint32_t) - Required - The ABI version requested by libEGL. - **exports** (const __EGLapiExports *) - Required - Pointer to libEGL's exported functions. - **vendor** (__EGLvendorInfo *) - Required - Pointer to vendor information structure. - **imports** (__EGLapiImports *) - Required - Structure to be populated with vendor callbacks. ### Response - **Return** (EGLBoolean) - Returns EGL_TRUE if initialization succeeds, EGL_FALSE otherwise. ``` -------------------------------- ### EGL Vendor Dispatch Functions Source: https://context7.com/glvnd/libglvnd/llms.txt These functions demonstrate how EGL vendor libraries dispatch calls to the correct implementation using libEGL's exports. They require libeglabi.h and handle error checking and vendor identification. ```c #include // Dispatch function for display-based operations void *dispatch_eglTestDispatchDisplay(EGLDisplay dpy, EGLint command, EGLAttrib param) { // Notify libEGL about this call (required for error handling) __EGLvendorInfo *vendor = g_eglExports->getVendorFromDisplay(dpy); if (vendor == NULL) { g_eglExports->setEGLError(EGL_BAD_DISPLAY); return NULL; } // Set the vendor for error tracking if (!g_eglExports->setLastVendor(vendor)) { return NULL; } // Get and call the actual function pfn_eglTestDispatchDisplay func = (pfn_eglTestDispatchDisplay)g_eglExports->fetchDispatchEntry( vendor, DISPATCH_INDEX_eglTestDispatchDisplay); if (func != NULL) { return func(dpy, command, param); } g_eglExports->setEGLError(EGL_BAD_PARAMETER); return NULL; } // Dispatch based on current context void *dispatch_eglTestDispatchCurrent(EGLint command, EGLAttrib param) { __EGLvendorInfo *vendor = g_eglExports->getCurrentVendor(); if (vendor == NULL) { g_eglExports->setEGLError(EGL_BAD_CONTEXT); return NULL; } g_eglExports->setLastVendor(vendor); pfn_eglTestDispatchCurrent func = (pfn_eglTestDispatchCurrent)g_eglExports->fetchDispatchEntry( vendor, DISPATCH_INDEX_eglTestDispatchCurrent); return func ? func(command, param) : NULL; } // Dispatch based on EGLDeviceEXT void *dispatch_eglTestDispatchDevice(EGLDeviceEXT dev, EGLint command, EGLAttrib param) { __EGLvendorInfo *vendor = g_eglExports->getVendorFromDevice(dev); if (vendor == NULL) { g_eglExports->setEGLError(EGL_BAD_DEVICE_EXT); return NULL; } g_eglExports->setLastVendor(vendor); pfn_eglTestDispatchDevice func = (pfn_eglTestDispatchDevice)g_eglExports->fetchDispatchEntry( vendor, DISPATCH_INDEX_eglTestDispatchDevice); return func ? func(dev, command, param) : NULL; } ``` -------------------------------- ### GLX Vendor Callbacks Source: https://context7.com/glvnd/libglvnd/llms.txt Vendor libraries must implement several callback functions that libGLX will invoke to query capabilities, retrieve function pointers, and manage dispatching. ```APIDOC ## GLX Vendor Callbacks ### Description These are the callback functions that a GLX vendor library must provide to libGLX. They are registered via the `__glx_Main` function's `imports` table. ### Callbacks #### `isScreenSupported` - **Description**: Checks if the vendor library supports rendering on the specified display and screen. - **Signature**: `Bool isScreenSupported(Display *dpy, int screen)` - **Return**: `True` if the screen is supported, `False` otherwise. #### `getProcAddress` - **Description**: Returns a function pointer to the vendor's implementation of a given OpenGL or GLX function name. - **Signature**: `void *getProcAddress(const GLubyte *procName)` - **Return**: A pointer to the function implementation, or `NULL` if not found. #### `getDispatchAddress` - **Description**: Returns a function pointer to the vendor-neutral dispatch stub for a GLX extension function. - **Signature**: `void *getDispatchAddress(const GLubyte *procName)` - **Return**: A pointer to the dispatch stub function, or `NULL` if not found. #### `setDispatchIndex` - **Description**: Sets the dispatch index for a given function, used internally by libglvnd for efficient dispatching. - **Signature**: `void setDispatchIndex(void *function, uint32_t index)` #### Optional Callbacks - `notifyError`: Called when an error occurs. - `isPatchSupported`: Checks if a specific patch is supported. - `initiatePatch`: Initiates a patch. - `releasePatch`: Releases a patch. - `patchThreadAttach`: Handles thread attachment for patching. ### Request Example (Illustrative Implementations) #### `myIsScreenSupported` ```c static Bool myIsScreenSupported(Display *dpy, int screen) { // Check if this vendor can handle the given display/screen // Return False to fall back to indirect rendering return True; } ``` #### `myGetProcAddress` ```c static void *myGetProcAddress(const GLubyte *procName) { // Return pointer to vendor's implementation of the function if (strcmp((const char *)procName, "glClear") == 0) { return (void *)vendor_glClear; } return NULL; } ``` #### `myGetDispatchAddress` ```c static void *myGetDispatchAddress(const GLubyte *procName) { // Return vendor-neutral dispatch function for GLX extensions if (strcmp((const char *)procName, "glXExampleExtensionFunction") == 0) { return (void *)dispatch_glXExampleExtensionFunction; } return NULL; } ``` ``` -------------------------------- ### EGL ICD Configuration Source: https://context7.com/glvnd/libglvnd/llms.txt EGL vendor libraries are discovered via JSON configuration files. These files specify the library path for the vendor implementation. ```APIDOC ## EGL ICD Configuration File ### Description A JSON file used by libglvnd to locate and load the EGL vendor library. ### Request Body - **file_format_version** (string) - Required - The version of the ICD file format (e.g., "1.0.0"). - **ICD** (object) - Required - Contains the vendor library configuration. - **library_path** (string) - Required - The absolute or relative path to the vendor's EGL implementation library (e.g., "libEGL_vendor.so.0"). ### Request Example { "file_format_version": "1.0.0", "ICD": { "library_path": "libEGL_vendor.so.0" } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.