dri_glx.c revision 6ddf66e9230ee862ac341c4767cf6b3b2dd2552b
127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/************************************************************************** 227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiAll Rights Reserved. 527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiPermission is hereby granted, free of charge, to any person obtaining a 727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshicopy of this software and associated documentation files (the 827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi"Software"), to deal in the Software without restriction, including 927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiwithout limitation the rights to use, copy, modify, merge, publish, 1027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshidistribute, sub license, and/or sell copies of the Software, and to 1127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshipermit persons to whom the Software is furnished to do so, subject to 1227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshithe following conditions: 1327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 1427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiThe above copyright notice and this permission notice (including the 1527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshinext paragraph) shall be included in all copies or substantial portions 1627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiof the Software. 172272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi 1827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 2227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 2627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi**************************************************************************/ 2727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 2827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/* 2927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Authors: 3027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Kevin E. Martin <kevin@precisioninsight.com> 318d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang * Brian Paul <brian@precisioninsight.com> 328d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang * 338d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang */ 3427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 3527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 368f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang 378f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang#include <X11/Xlib.h> 388f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang#include <X11/extensions/Xfixes.h> 398f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang#include <X11/extensions/Xdamage.h> 4027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "glxclient.h" 4127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "xf86dri.h" 4227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "dri2.h" 4327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "sarea.h" 442272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi#include <dlfcn.h> 4527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <sys/types.h> 4627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <sys/mman.h> 4727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "xf86drm.h" 488d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang#include "dri_common.h" 498d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang 5027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistruct dri_display 5127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{ 5227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __GLXDRIdisplay base; 5327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 5427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi /* 5527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi ** XFree86-DRI version information 5627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi */ 5727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int driMajor; 5827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int driMinor; 5927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int driPatch; 6027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}; 6127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 6227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistruct dri_screen 638d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang{ 648d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang __GLXscreenConfigs base; 658d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang 668d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang __DRIscreen *driScreen; 678d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang __GLXDRIscreen vtable; 6827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi const __DRIlegacyExtension *legacy; 698d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang const __DRIcoreExtension *core; 7027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi const __DRIswapControlExtension *swapControl; 7127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi const __DRImediaStreamCounterExtension *msc; 72e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi const __DRIconfig **driver_configs; 73e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi const __DRIcopySubBufferExtension *driCopySubBuffer; 7427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 7527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi void *driver; 76e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi int fd; 77e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}; 7827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 7927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistruct dri_context 8027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{ 81b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang __GLXcontext base; 82b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang __GLXDRIcontext dri_vtable; 8327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __DRIcontext *driContext; 8427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi XID hwContextID; 85c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi}; 86c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi 8727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistruct dri_drawable 8827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{ 89b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang __GLXDRIdrawable base; 90b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang 9127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __DRIdrawable *driDrawable; 9227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}; 9327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 9427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic const struct glx_context_vtable dri_context_vtable; 9527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 9627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/* 9727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Given a display pointer and screen number, determine the name of 9827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * the DRI driver for the screen. (I.e. "r128", "tdfx", etc). 9927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Return True for success, False for failure. 10027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi */ 10127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic Bool 102b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria WangdriGetDriverName(Display * dpy, int scrNum, char **driverName) 103b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang{ 10427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int directCapable; 10527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi Bool b; 10627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int event, error; 10727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int driverMajor, driverMinor, driverPatch; 1083473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi 1093473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi *driverName = NULL; 1103473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi 1113473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */ 1123473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) { 1133473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n"); 1143473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi return False; 1153473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi } 116b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang if (!directCapable) { 117b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n"); 11827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return False; 11927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 12027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 12127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor, 12227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi &driverPatch, driverName); 12327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (!b) { 12427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi ErrorMessageF("Cannot determine driver name for screen %d\n", 125b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang scrNum); 126b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang return False; 12727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 12827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 12927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", 13027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi driverMajor, driverMinor, driverPatch, *driverName, 13127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi scrNum); 13227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 13327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return True; 134b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang } 135b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */ 13627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi char *dev; 13727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev); 13827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 13927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (ret) 14027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi Xfree(dev); 14127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 14227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return ret; 1432272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi } 14427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 1458d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang return False; 146b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang} 14727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 14827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/* 149b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * Exported function for querying the DRI driver for a given screen. 150b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * 15127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * The returned char pointer points to a static array that will be 15227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * overwritten by subsequent calls. 15327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi */ 15427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiPUBLIC const char * 15527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiglXGetScreenDriver(Display * dpy, int scrNum) 15627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{ 15727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi static char ret[32]; 15827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi char *driverName; 15927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (driGetDriverName(dpy, scrNum, &driverName)) { 16027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int len; 16127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (!driverName) 162b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang return NULL; 163b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang len = strlen(driverName); 16427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (len >= 31) 16527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return NULL; 16627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi memcpy(ret, driverName, len + 1); 16727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi Xfree(driverName); 16827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return ret; 16927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 17027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return NULL; 17127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi} 172b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang 173b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang/* 17427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Exported function for obtaining a driver's option list (UTF-8 encoded XML). 17527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * 17627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * The returned char pointer points directly into the driver. Therefore 17727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * it should be treated as a constant. 1782272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi * 179b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * If the driver was not found or does not support configuration NULL is 180b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * returned. 1812272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi * 182b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * Note: The driver remains opened after this function returns. 183b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang */ 184b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria WangPUBLIC const char * 18527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiglXGetDriverConfig(const char *driverName) 1862272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi{ 18727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi void *handle = driOpenDriver(driverName); 18827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (handle) 1892272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi return dlsym(handle, "__driConfigOptions"); 190b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang else 191b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang return NULL; 1922272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi} 193b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang 1942272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi#ifdef XDAMAGE_1_1_INTERFACE 195b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang 19627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic GLboolean 1972272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimihas_damage_post(Display * dpy) 19827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{ 19927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi static GLboolean inited = GL_FALSE; 20027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi static GLboolean has_damage; 201b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang 202b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang if (!inited) { 20327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int major, minor; 20427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 205b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang if (XDamageQueryVersion(dpy, &major, &minor) && 206b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang major == 1 && minor >= 1) { 20727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi has_damage = GL_TRUE; 20827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 20927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi else { 21027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi has_damage = GL_FALSE; 2112272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi } 2122272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi inited = GL_TRUE; 21327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 2142272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi 21527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return has_damage; 2162272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi} 21727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 21827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic void 2192272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi__glXReportDamage(__DRIdrawable * driDraw, 2202272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi int x, int y, 22127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi drm_clip_rect_t * rects, int num_rects, 22227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi GLboolean front_buffer, void *loaderPrivate) 223b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang{ 224b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang XRectangle *xrects; 22527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi XserverRegion region; 22627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int i; 22727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int x_off, y_off; 22827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __GLXDRIdrawable *glxDraw = loaderPrivate; 22927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __GLXscreenConfigs *psc = glxDraw->psc; 23027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi Display *dpy = psc->dpy; 23127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi Drawable drawable; 23227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 23327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (!has_damage_post(dpy)) 23427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return; 23527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 236b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang if (front_buffer) { 237b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang x_off = x; 23827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi y_off = y; 23927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi drawable = RootWindow(dpy, psc->scr); 24027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 24127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi else { 242b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang x_off = 0; 243b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang y_off = 0; 24427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi drawable = glxDraw->xDrawable; 24527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 24627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 24727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi xrects = malloc(sizeof(XRectangle) * num_rects); 24827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (xrects == NULL) 24927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return; 25027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 251b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang for (i = 0; i < num_rects; i++) { 252b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang xrects[i].x = rects[i].x1 + x_off; 25327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi xrects[i].y = rects[i].y1 + y_off; 25427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi xrects[i].width = rects[i].x2 - rects[i].x1; 25527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi xrects[i].height = rects[i].y2 - rects[i].y1; 25627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 257b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang region = XFixesCreateRegion(dpy, xrects, num_rects); 258a2cd44cb5067b4fe98794860690394254d3ac73cGloria Wang free(xrects); 25927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi XDamageAdd(dpy, drawable, region); 26027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi XFixesDestroyRegion(dpy, region); 26127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi} 262b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang 263b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wangstatic const __DRIdamageExtension damageExtension = { 264e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi {__DRI_DAMAGE, __DRI_DAMAGE_VERSION}, 265e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi __glXReportDamage, 266e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}; 267e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi 268e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi#endif 269e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi 270e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatic GLboolean 271b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang__glXDRIGetDrawableInfo(__DRIdrawable * drawable, 272b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang unsigned int *index, unsigned int *stamp, 2732272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi int *X, int *Y, int *W, int *H, 274b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang int *numClipRects, drm_clip_rect_t ** pClipRects, 275b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang int *backX, int *backY, 276b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang int *numBackClipRects, 27727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi drm_clip_rect_t ** pBackClipRects, 2782272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi void *loaderPrivate) 27927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{ 28027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __GLXDRIdrawable *glxDraw = loaderPrivate; 281b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang __GLXscreenConfigs *psc = glxDraw->psc; 282b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang Display *dpy = psc->dpy; 283b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang 2842272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable, 285b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang index, stamp, X, Y, W, H, 2862272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi numClipRects, pClipRects, 287b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang backX, backY, 28827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi numBackClipRects, pBackClipRects); 2892272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi} 29027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 29127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { 292b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang {__DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION}, 293b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang __glXDRIGetDrawableInfo 294b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang}; 295b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang 29627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic const __DRIextension *loader_extensions[] = { 297b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang &systemTimeExtension.base, 29827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi &getDrawableInfoExtension.base, 29927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#ifdef XDAMAGE_1_1_INTERFACE 300b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang &damageExtension.base, 301b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang#endif 30227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi NULL 30327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}; 30427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 30527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/** 3062272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi * Perform the required libGL-side initialization and call the client-side 307b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * driver's \c __driCreateNewScreen function. 3082272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi * 309b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * \param dpy Display pointer. 310b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * \param scrn Screen number on the display. 311b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * \param psc DRI screen information. 31227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * \param driDpy DRI display information. 3132272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi * \param createNewScreen Pointer to the client-side driver's 31427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * \c __driCreateNewScreen function. 31527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * \returns A pointer to the \c __DRIscreen structure returned by 316b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang * the client-side driver on success, or \c NULL on failure. 317a2cd44cb5067b4fe98794860690394254d3ac73cGloria Wang */ 31827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic void * 319b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria WangCallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, 320b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang struct dri_display * driDpy) 321b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang{ 32227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi void *psp = NULL; 32327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi drm_handle_t hSAREA; 32427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi drmAddress pSAREA = MAP_FAILED; 32527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi char *BusID; 32627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __DRIversion ddx_version; 32727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __DRIversion dri_version; 32827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __DRIversion drm_version; 32927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi __DRIframebuffer framebuffer; 33027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int fd = -1; 33127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi int status; 33227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 33327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi drm_magic_t magic; 33427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi drmVersionPtr version; 3358d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang int newlyopened; 3368d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang char *driverName; 3378d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang drm_handle_t hFB; 3388d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang int junk; 3398d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang const __DRIconfig **driver_configs; 3408d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang struct glx_config *visual; 3418d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang 3428d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang /* DRI protocol version. */ 3438d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang dri_version.major = driDpy->driMajor; 3448d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang dri_version.minor = driDpy->driMinor; 3458d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang dri_version.patch = driDpy->driPatch; 3468d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang 3478d2577b9ac2f95f218db59a78447efd3c6a742ddGloria Wang framebuffer.base = MAP_FAILED; 348 framebuffer.dev_priv = NULL; 349 framebuffer.size = 0; 350 351 if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { 352 ErrorMessageF("XF86DRIOpenConnection failed\n"); 353 goto handle_error; 354 } 355 356 fd = drmOpenOnce(NULL, BusID, &newlyopened); 357 358 Xfree(BusID); /* No longer needed */ 359 360 if (fd < 0) { 361 ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd)); 362 goto handle_error; 363 } 364 365 if (drmGetMagic(fd, &magic)) { 366 ErrorMessageF("drmGetMagic failed\n"); 367 goto handle_error; 368 } 369 370 version = drmGetVersion(fd); 371 if (version) { 372 drm_version.major = version->version_major; 373 drm_version.minor = version->version_minor; 374 drm_version.patch = version->version_patchlevel; 375 drmFreeVersion(version); 376 } 377 else { 378 drm_version.major = -1; 379 drm_version.minor = -1; 380 drm_version.patch = -1; 381 } 382 383 if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) { 384 ErrorMessageF("XF86DRIAuthConnection failed\n"); 385 goto handle_error; 386 } 387 388 /* Get device name (like "tdfx") and the ddx version numbers. 389 * We'll check the version in each DRI driver's "createNewScreen" 390 * function. */ 391 if (!XF86DRIGetClientDriverName(dpy, scrn, 392 &ddx_version.major, 393 &ddx_version.minor, 394 &ddx_version.patch, &driverName)) { 395 ErrorMessageF("XF86DRIGetClientDriverName failed\n"); 396 goto handle_error; 397 } 398 399 Xfree(driverName); /* No longer needed. */ 400 401 /* 402 * Get device-specific info. pDevPriv will point to a struct 403 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that 404 * has information about the screen size, depth, pitch, ancilliary 405 * buffers, DRM mmap handles, etc. 406 */ 407 if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk, 408 &framebuffer.size, &framebuffer.stride, 409 &framebuffer.dev_priv_size, 410 &framebuffer.dev_priv)) { 411 ErrorMessageF("XF86DRIGetDeviceInfo failed"); 412 goto handle_error; 413 } 414 415 framebuffer.width = DisplayWidth(dpy, scrn); 416 framebuffer.height = DisplayHeight(dpy, scrn); 417 418 /* Map the framebuffer region. */ 419 status = drmMap(fd, hFB, framebuffer.size, 420 (drmAddressPtr) & framebuffer.base); 421 if (status != 0) { 422 ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status)); 423 goto handle_error; 424 } 425 426 /* Map the SAREA region. Further mmap regions may be setup in 427 * each DRI driver's "createNewScreen" function. 428 */ 429 status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA); 430 if (status != 0) { 431 ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status)); 432 goto handle_error; 433 } 434 435 psp = (*psc->legacy->createNewScreen) (scrn, 436 &ddx_version, 437 &dri_version, 438 &drm_version, 439 &framebuffer, 440 pSAREA, 441 fd, 442 loader_extensions, 443 &driver_configs, psc); 444 445 if (psp == NULL) { 446 ErrorMessageF("Calling driver entry point failed"); 447 goto handle_error; 448 } 449 450 psc->base.configs = 451 driConvertConfigs(psc->core, psc->base.configs, driver_configs); 452 psc->base.visuals = 453 driConvertConfigs(psc->core, psc->base.visuals, driver_configs); 454 455 psc->driver_configs = driver_configs; 456 457 /* Visuals with depth != screen depth are subject to automatic compositing 458 * in the X server, so DRI1 can't render to them properly. Mark them as 459 * non-conformant to prevent apps from picking them up accidentally. 460 */ 461 for (visual = psc->base.visuals; visual; visual = visual->next) { 462 XVisualInfo template; 463 XVisualInfo *visuals; 464 int num_visuals; 465 long mask; 466 467 template.visualid = visual->visualID; 468 mask = VisualIDMask; 469 visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals); 470 471 if (visuals) { 472 if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn)) 473 visual->visualRating = GLX_NON_CONFORMANT_CONFIG; 474 475 XFree(visuals); 476 } 477 } 478 479 return psp; 480 481 handle_error: 482 if (pSAREA != MAP_FAILED) 483 drmUnmap(pSAREA, SAREA_MAX); 484 485 if (framebuffer.base != MAP_FAILED) 486 drmUnmap((drmAddress) framebuffer.base, framebuffer.size); 487 488 if (framebuffer.dev_priv != NULL) 489 Xfree(framebuffer.dev_priv); 490 491 if (fd >= 0) 492 drmCloseOnce(fd); 493 494 XF86DRICloseConnection(dpy, scrn); 495 496 ErrorMessageF("reverting to software direct rendering\n"); 497 498 return NULL; 499} 500 501static void 502dri_destroy_context(__GLXcontext * context) 503{ 504 struct dri_context *pcp = (struct dri_context *) context; 505 struct dri_screen *psc = (struct dri_screen *) context->psc; 506 507 if (context->xid) 508 glx_send_destroy_context(psc->base.dpy, context->xid); 509 510 if (context->extensions) 511 XFree((char *) context->extensions); 512 513 GarbageCollectDRIDrawables(context->psc); 514 515 (*psc->core->destroyContext) (pcp->driContext); 516 517 XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID); 518 Xfree(pcp); 519} 520 521static Bool 522driBindContext(__GLXcontext *context, 523 __GLXDRIdrawable *draw, __GLXDRIdrawable *read) 524{ 525 struct dri_context *pcp = (struct dri_context *) context; 526 struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; 527 struct dri_drawable *pdr = (struct dri_drawable *) draw; 528 struct dri_drawable *prd = (struct dri_drawable *) read; 529 530 return (*psc->core->bindContext) (pcp->driContext, 531 pdr->driDrawable, prd->driDrawable); 532} 533 534static void 535driUnbindContext(__GLXcontext * context) 536{ 537 struct dri_context *pcp = (struct dri_context *) context; 538 struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; 539 540 (*psc->core->unbindContext) (pcp->driContext); 541} 542 543static const struct glx_context_vtable dri_context_vtable = { 544 dri_destroy_context, 545 NULL, 546 NULL, 547 DRI_glXUseXFont, 548 NULL, 549 NULL, 550}; 551 552static __GLXcontext * 553dri_create_context(__GLXscreenConfigs *base, 554 struct glx_config *config_base, 555 GLXContext shareList, int renderType) 556{ 557 struct dri_context *pcp, *pcp_shared; 558 struct dri_screen *psc = (struct dri_screen *) base; 559 drm_context_t hwContext; 560 __DRIcontext *shared = NULL; 561 __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; 562 563 if (!psc->base.driScreen) 564 return NULL; 565 566 if (shareList) { 567 pcp_shared = (struct dri_context *) shareList->driContext; 568 shared = pcp_shared->driContext; 569 } 570 571 pcp = Xmalloc(sizeof *pcp); 572 if (pcp == NULL) 573 return NULL; 574 575 memset(pcp, 0, sizeof *pcp); 576 if (!glx_context_init(&pcp->base, &psc->base, &config->base)) { 577 Xfree(pcp); 578 return NULL; 579 } 580 581 if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr, 582 config->base.visualID, 583 &pcp->hwContextID, &hwContext)) { 584 Xfree(pcp); 585 return NULL; 586 } 587 588 pcp->driContext = 589 (*psc->legacy->createNewContext) (psc->driScreen, 590 config->driConfig, 591 renderType, shared, hwContext, pcp); 592 if (pcp->driContext == NULL) { 593 XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID); 594 Xfree(pcp); 595 return NULL; 596 } 597 598 pcp->base.vtable = &dri_context_vtable; 599 pcp->base.driContext = &pcp->dri_vtable; 600 pcp->dri_vtable.bindContext = driBindContext; 601 pcp->dri_vtable.unbindContext = driUnbindContext; 602 603 return &pcp->base; 604} 605 606static void 607driDestroyDrawable(__GLXDRIdrawable * pdraw) 608{ 609 struct dri_screen *psc = (struct dri_screen *) pdraw->psc; 610 struct dri_drawable *pdp = (struct dri_drawable *) pdraw; 611 612 (*psc->core->destroyDrawable) (pdp->driDrawable); 613 XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, pdraw->drawable); 614 Xfree(pdraw); 615} 616 617static __GLXDRIdrawable * 618driCreateDrawable(__GLXscreenConfigs *base, 619 XID xDrawable, 620 GLXDrawable drawable, struct glx_config *config_base) 621{ 622 drm_drawable_t hwDrawable; 623 void *empty_attribute_list = NULL; 624 __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; 625 struct dri_screen *psc = (struct dri_screen *) base; 626 struct dri_drawable *pdp; 627 628 /* Old dri can't handle GLX 1.3+ drawable constructors. */ 629 if (xDrawable != drawable) 630 return NULL; 631 632 pdp = Xmalloc(sizeof *pdp); 633 if (!pdp) 634 return NULL; 635 636 memset(pdp, 0, sizeof *pdp); 637 pdp->base.drawable = drawable; 638 pdp->base.psc = &psc->base; 639 640 if (!XF86DRICreateDrawable(psc->base.dpy, psc->base.scr, 641 drawable, &hwDrawable)) { 642 Xfree(pdp); 643 return NULL; 644 } 645 646 /* Create a new drawable */ 647 pdp->driDrawable = 648 (*psc->legacy->createNewDrawable) (psc->driScreen, 649 config->driConfig, 650 hwDrawable, 651 GLX_WINDOW_BIT, 652 empty_attribute_list, pdp); 653 654 if (!pdp->driDrawable) { 655 XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, drawable); 656 Xfree(pdp); 657 return NULL; 658 } 659 660 pdp->base.destroyDrawable = driDestroyDrawable; 661 662 return &pdp->base; 663} 664 665static int64_t 666driSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2, 667 int64_t unused3) 668{ 669 struct dri_screen *psc = (struct dri_screen *) pdraw->psc; 670 struct dri_drawable *pdp = (struct dri_drawable *) pdraw; 671 672 (*psc->core->swapBuffers) (pdp->driDrawable); 673 return 0; 674} 675 676static void 677driCopySubBuffer(__GLXDRIdrawable * pdraw, 678 int x, int y, int width, int height) 679{ 680 struct dri_drawable *pdp = (struct dri_drawable *) pdraw; 681 struct dri_screen *psc = (struct dri_screen *) pdp->base.psc; 682 683 (*psc->driCopySubBuffer->copySubBuffer) (pdp->driDrawable, 684 x, y, width, height); 685} 686 687static void 688driDestroyScreen(__GLXscreenConfigs *base) 689{ 690 struct dri_screen *psc = (struct dri_screen *) base; 691 692 /* Free the direct rendering per screen data */ 693 if (psc->driScreen) 694 (*psc->core->destroyScreen) (psc->driScreen); 695 driDestroyConfigs(psc->driver_configs); 696 psc->driScreen = NULL; 697 if (psc->driver) 698 dlclose(psc->driver); 699} 700 701#ifdef __DRI_SWAP_BUFFER_COUNTER 702 703static int 704driDrawableGetMSC(__GLXscreenConfigs *base, __GLXDRIdrawable *pdraw, 705 int64_t *ust, int64_t *msc, int64_t *sbc) 706{ 707 struct dri_screen *psc = (struct dri_screen *) base; 708 struct dri_drawable *pdp = (struct dri_drawable *) pdraw; 709 710 if (pdp && psc->sbc && psc->msc) 711 return ( (*psc->msc->getMSC)(psc->driScreen, msc) == 0 && 712 (*psc->sbc->getSBC)(pdp->driDrawable, sbc) == 0 && 713 __glXGetUST(ust) == 0 ); 714} 715 716static int 717driWaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, 718 int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) 719{ 720 struct dri_screen *psc = (struct dri_screen *) pdraw->psc; 721 struct dri_drawable *pdp = (struct dri_drawable *) pdraw; 722 723 if (pdp != NULL && psc->msc != NULL) { 724 ret = (*psc->msc->waitForMSC) (pdp->driDrawable, target_msc, 725 divisor, remainder, msc, sbc); 726 727 /* __glXGetUST returns zero on success and non-zero on failure. 728 * This function returns True on success and False on failure. 729 */ 730 return ret == 0 && __glXGetUST(ust) == 0; 731 } 732} 733 734static int 735driWaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, 736 int64_t *msc, int64_t *sbc) 737{ 738 struct dri_drawable *pdp = (struct dri_drawable *) pdraw; 739 740 if (pdp != NULL && psc->sbc != NULL) { 741 ret = 742 (*psc->sbc->waitForSBC) (pdp->driDrawable, target_sbc, msc, sbc); 743 744 /* __glXGetUST returns zero on success and non-zero on failure. 745 * This function returns True on success and False on failure. 746 */ 747 return ((ret == 0) && (__glXGetUST(ust) == 0)); 748 } 749 750 return DRI2WaitSBC(pdp->base.psc->dpy, 751 pdp->base.xDrawable, target_sbc, ust, msc, sbc); 752} 753 754#endif 755 756static int 757driSetSwapInterval(__GLXDRIdrawable *pdraw, int interval) 758{ 759 GLXContext gc = __glXGetCurrentContext(); 760 struct dri_drawable *pdp = (struct dri_drawable *) pdraw; 761 struct dri_screen *psc; 762 763 if (gc->driContext) { 764 psc = (struct dri_screen *) pdraw->psc; 765 766 if (psc->swapControl != NULL && pdraw != NULL) { 767 psc->swapControl->setSwapInterval(pdp->driDrawable, interval); 768 return 0; 769 } 770 } 771 772 return GLX_BAD_CONTEXT; 773} 774 775static int 776driGetSwapInterval(__GLXDRIdrawable *pdraw) 777{ 778 GLXContext gc = __glXGetCurrentContext(); 779 struct dri_drawable *pdp = (struct dri_drawable *) pdraw; 780 struct dri_screen *psc; 781 782 if (gc != NULL && gc->driContext) { 783 psc = (struct dri_screen *) pdraw->psc; 784 785 if (psc->swapControl != NULL && pdraw != NULL) { 786 return psc->swapControl->getSwapInterval(pdp->driDrawable); 787 } 788 } 789 790 return 0; 791} 792 793/* Bind DRI1 specific extensions */ 794static void 795driBindExtensions(struct dri_screen *psc, const __DRIextension **extensions) 796{ 797 int i; 798 799 for (i = 0; extensions[i]; i++) { 800 /* No DRI2 support for swap_control at the moment, since SwapBuffers 801 * is done by the X server */ 802 if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { 803 psc->swapControl = (__DRIswapControlExtension *) extensions[i]; 804 __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control"); 805 __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control"); 806 } 807 808 if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) { 809 psc->msc = (__DRImediaStreamCounterExtension *) extensions[i]; 810 __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync"); 811 } 812 813 if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { 814 psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; 815 __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer"); 816 } 817 818 if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { 819 __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read"); 820 } 821 /* Ignore unknown extensions */ 822 } 823} 824 825static const struct glx_screen_vtable dri_screen_vtable = { 826 dri_create_context 827}; 828 829static __GLXscreenConfigs * 830driCreateScreen(int screen, __GLXdisplayPrivate *priv) 831{ 832 struct dri_display *pdp; 833 __GLXDRIscreen *psp; 834 const __DRIextension **extensions; 835 struct dri_screen *psc; 836 char *driverName; 837 int i; 838 839 psc = Xcalloc(1, sizeof *psc); 840 if (psc == NULL) 841 return NULL; 842 843 memset(psc, 0, sizeof *psc); 844 if (!glx_screen_init(&psc->base, screen, priv)) 845 return NULL; 846 847 if (!driGetDriverName(priv->dpy, screen, &driverName)) { 848 Xfree(psc); 849 return NULL; 850 } 851 852 psc->driver = driOpenDriver(driverName); 853 Xfree(driverName); 854 if (psc->driver == NULL) { 855 Xfree(psc); 856 return NULL; 857 } 858 859 extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); 860 if (extensions == NULL) { 861 ErrorMessageF("driver exports no extensions (%s)\n", dlerror()); 862 Xfree(psc); 863 return NULL; 864 } 865 866 for (i = 0; extensions[i]; i++) { 867 if (strcmp(extensions[i]->name, __DRI_CORE) == 0) 868 psc->core = (__DRIcoreExtension *) extensions[i]; 869 if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0) 870 psc->legacy = (__DRIlegacyExtension *) extensions[i]; 871 } 872 873 if (psc->core == NULL || psc->legacy == NULL) { 874 Xfree(psc); 875 return NULL; 876 } 877 878 pdp = (struct dri_display *) priv->driDisplay; 879 psc->driScreen = 880 CallCreateNewScreen(psc->base.dpy, screen, psc, pdp); 881 if (psc->driScreen == NULL) { 882 dlclose(psc->driver); 883 Xfree(psc); 884 return NULL; 885 } 886 887 extensions = psc->core->getExtensions(psc->driScreen); 888 driBindExtensions(psc, extensions); 889 890 psc->base.vtable = &dri_screen_vtable; 891 psp = &psc->vtable; 892 psc->base.driScreen = psp; 893 if (psc->driCopySubBuffer) 894 psp->copySubBuffer = driCopySubBuffer; 895 896 psp->destroyScreen = driDestroyScreen; 897 psp->createDrawable = driCreateDrawable; 898 psp->swapBuffers = driSwapBuffers; 899 900#ifdef __DRI_SWAP_BUFFER_COUNTER 901 psp->getDrawableMSC = driDrawableGetMSC; 902 psp->waitForMSC = driWaitForMSC; 903 psp->waitForSBC = driWaitForSBC; 904#endif 905 906 psp->setSwapInterval = driSetSwapInterval; 907 psp->getSwapInterval = driGetSwapInterval; 908 909 return &psc->base; 910} 911 912/* Called from __glXFreeDisplayPrivate. 913 */ 914static void 915driDestroyDisplay(__GLXDRIdisplay * dpy) 916{ 917 Xfree(dpy); 918} 919 920/* 921 * Allocate, initialize and return a __DRIdisplayPrivate object. 922 * This is called from __glXInitialize() when we are given a new 923 * display pointer. 924 */ 925_X_HIDDEN __GLXDRIdisplay * 926driCreateDisplay(Display * dpy) 927{ 928 struct dri_display *pdpyp; 929 int eventBase, errorBase; 930 int major, minor, patch; 931 932 if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) { 933 return NULL; 934 } 935 936 if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) { 937 return NULL; 938 } 939 940 pdpyp = Xmalloc(sizeof *pdpyp); 941 if (!pdpyp) { 942 return NULL; 943 } 944 945 pdpyp->driMajor = major; 946 pdpyp->driMinor = minor; 947 pdpyp->driPatch = patch; 948 949 pdpyp->base.destroyDisplay = driDestroyDisplay; 950 pdpyp->base.createScreen = driCreateScreen; 951 952 return &pdpyp->base; 953} 954 955#endif /* GLX_DIRECT_RENDERING */ 956