1706f2543Smrg/* 2706f2543Smrg * Copyright © 2008 George Sapountzis <gsap7@yahoo.gr> 3706f2543Smrg * Copyright © 2008 Red Hat, Inc 4706f2543Smrg * 5706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software 6706f2543Smrg * and its documentation for any purpose is hereby granted without 7706f2543Smrg * fee, provided that the above copyright notice appear in all copies 8706f2543Smrg * and that both that copyright notice and this permission notice 9706f2543Smrg * appear in supporting documentation, and that the name of the 10706f2543Smrg * copyright holders not be used in advertising or publicity 11706f2543Smrg * pertaining to distribution of the software without specific, 12706f2543Smrg * written prior permission. The copyright holders make no 13706f2543Smrg * representations about the suitability of this software for any 14706f2543Smrg * purpose. It is provided "as is" without express or implied 15706f2543Smrg * warranty. 16706f2543Smrg * 17706f2543Smrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 18706f2543Smrg * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 19706f2543Smrg * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 20706f2543Smrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21706f2543Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 22706f2543Smrg * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 23706f2543Smrg * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 24706f2543Smrg * SOFTWARE. 25706f2543Smrg */ 26706f2543Smrg 27706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 28706f2543Smrg#include <dix-config.h> 29706f2543Smrg#endif 30706f2543Smrg 31706f2543Smrg#include <stdint.h> 32706f2543Smrg#include <stdio.h> 33706f2543Smrg#include <string.h> 34706f2543Smrg#include <errno.h> 35706f2543Smrg#include <sys/time.h> 36706f2543Smrg#include <dlfcn.h> 37706f2543Smrg 38706f2543Smrg#include <GL/gl.h> 39706f2543Smrg#include <GL/internal/dri_interface.h> 40706f2543Smrg#include <GL/glxtokens.h> 41706f2543Smrg 42706f2543Smrg#include "scrnintstr.h" 43706f2543Smrg#include "pixmapstr.h" 44706f2543Smrg#include "gcstruct.h" 45706f2543Smrg#include "os.h" 46706f2543Smrg 47706f2543Smrg#include "glxserver.h" 48706f2543Smrg#include "glxutil.h" 49706f2543Smrg#include "glxdricommon.h" 50706f2543Smrg 51706f2543Smrg#include "glapitable.h" 52706f2543Smrg#include "glapi.h" 53706f2543Smrg#include "glthread.h" 54706f2543Smrg#include "dispatch.h" 55706f2543Smrg#include "extension_string.h" 56706f2543Smrg 57706f2543Smrg/* RTLD_LOCAL is not defined on Cygwin */ 58706f2543Smrg#ifdef __CYGWIN__ 59706f2543Smrg#ifndef RTLD_LOCAL 60706f2543Smrg#define RTLD_LOCAL 0 61706f2543Smrg#endif 62706f2543Smrg#endif 63706f2543Smrg 64706f2543Smrgtypedef struct __GLXDRIscreen __GLXDRIscreen; 65706f2543Smrgtypedef struct __GLXDRIcontext __GLXDRIcontext; 66706f2543Smrgtypedef struct __GLXDRIdrawable __GLXDRIdrawable; 67706f2543Smrg 68706f2543Smrgstruct __GLXDRIscreen { 69706f2543Smrg __GLXscreen base; 70706f2543Smrg __DRIscreen *driScreen; 71706f2543Smrg void *driver; 72706f2543Smrg 73706f2543Smrg const __DRIcoreExtension *core; 74706f2543Smrg const __DRIswrastExtension *swrast; 75706f2543Smrg const __DRIcopySubBufferExtension *copySubBuffer; 76706f2543Smrg const __DRItexBufferExtension *texBuffer; 77706f2543Smrg}; 78706f2543Smrg 79706f2543Smrgstruct __GLXDRIcontext { 80706f2543Smrg __GLXcontext base; 81706f2543Smrg __DRIcontext *driContext; 82706f2543Smrg}; 83706f2543Smrg 84706f2543Smrgstruct __GLXDRIdrawable { 85706f2543Smrg __GLXdrawable base; 86706f2543Smrg __DRIdrawable *driDrawable; 87706f2543Smrg __GLXDRIscreen *screen; 88706f2543Smrg 89706f2543Smrg GCPtr gc; /* scratch GC for span drawing */ 90706f2543Smrg GCPtr swapgc; /* GC for swapping the color buffers */ 91706f2543Smrg}; 92706f2543Smrg 93706f2543Smrgstatic void 94706f2543Smrg__glXDRIdrawableDestroy(__GLXdrawable *drawable) 95706f2543Smrg{ 96706f2543Smrg __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; 97706f2543Smrg const __DRIcoreExtension *core = private->screen->core; 98706f2543Smrg 99706f2543Smrg (*core->destroyDrawable)(private->driDrawable); 100706f2543Smrg 101706f2543Smrg FreeGC(private->gc, (GContext)0); 102706f2543Smrg FreeGC(private->swapgc, (GContext)0); 103706f2543Smrg 104706f2543Smrg __glXDrawableRelease(drawable); 105706f2543Smrg 106706f2543Smrg free(private); 107706f2543Smrg} 108706f2543Smrg 109706f2543Smrgstatic GLboolean 110706f2543Smrg__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable) 111706f2543Smrg{ 112706f2543Smrg __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; 113706f2543Smrg const __DRIcoreExtension *core = private->screen->core; 114706f2543Smrg 115706f2543Smrg (*core->swapBuffers)(private->driDrawable); 116706f2543Smrg 117706f2543Smrg return TRUE; 118706f2543Smrg} 119706f2543Smrg 120706f2543Smrgstatic void 121706f2543Smrg__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, 122706f2543Smrg int x, int y, int w, int h) 123706f2543Smrg{ 124706f2543Smrg __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; 125706f2543Smrg const __DRIcopySubBufferExtension *copySubBuffer = 126706f2543Smrg private->screen->copySubBuffer; 127706f2543Smrg 128706f2543Smrg if (copySubBuffer) 129706f2543Smrg (*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h); 130706f2543Smrg} 131706f2543Smrg 132706f2543Smrgstatic void 133706f2543Smrg__glXDRIcontextDestroy(__GLXcontext *baseContext) 134706f2543Smrg{ 135706f2543Smrg __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; 136706f2543Smrg __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; 137706f2543Smrg 138706f2543Smrg (*screen->core->destroyContext)(context->driContext); 139706f2543Smrg __glXContextDestroy(&context->base); 140706f2543Smrg free(context); 141706f2543Smrg} 142706f2543Smrg 143706f2543Smrgstatic int 144706f2543Smrg__glXDRIcontextMakeCurrent(__GLXcontext *baseContext) 145706f2543Smrg{ 146706f2543Smrg __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; 147706f2543Smrg __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; 148706f2543Smrg __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; 149706f2543Smrg __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; 150706f2543Smrg 151706f2543Smrg return (*screen->core->bindContext)(context->driContext, 152706f2543Smrg draw->driDrawable, 153706f2543Smrg read->driDrawable); 154706f2543Smrg} 155706f2543Smrg 156706f2543Smrgstatic int 157706f2543Smrg__glXDRIcontextLoseCurrent(__GLXcontext *baseContext) 158706f2543Smrg{ 159706f2543Smrg __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; 160706f2543Smrg __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; 161706f2543Smrg 162706f2543Smrg return (*screen->core->unbindContext)(context->driContext); 163706f2543Smrg} 164706f2543Smrg 165706f2543Smrgstatic int 166706f2543Smrg__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, 167706f2543Smrg unsigned long mask) 168706f2543Smrg{ 169706f2543Smrg __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; 170706f2543Smrg __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; 171706f2543Smrg __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; 172706f2543Smrg 173706f2543Smrg return (*screen->core->copyContext)(dst->driContext, 174706f2543Smrg src->driContext, mask); 175706f2543Smrg} 176706f2543Smrg 177706f2543Smrgstatic int 178706f2543Smrg__glXDRIcontextForceCurrent(__GLXcontext *baseContext) 179706f2543Smrg{ 180706f2543Smrg __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; 181706f2543Smrg __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; 182706f2543Smrg __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; 183706f2543Smrg __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; 184706f2543Smrg 185706f2543Smrg return (*screen->core->bindContext)(context->driContext, 186706f2543Smrg draw->driDrawable, 187706f2543Smrg read->driDrawable); 188706f2543Smrg} 189706f2543Smrg 190706f2543Smrg#ifdef __DRI_TEX_BUFFER 191706f2543Smrg 192706f2543Smrgstatic int 193706f2543Smrg__glXDRIbindTexImage(__GLXcontext *baseContext, 194706f2543Smrg int buffer, 195706f2543Smrg __GLXdrawable *glxPixmap) 196706f2543Smrg{ 197706f2543Smrg __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap; 198706f2543Smrg const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer; 199706f2543Smrg __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; 200706f2543Smrg 201706f2543Smrg if (texBuffer == NULL) 202706f2543Smrg return Success; 203706f2543Smrg 204706f2543Smrg#if __DRI_TEX_BUFFER_VERSION >= 2 205706f2543Smrg if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) { 206706f2543Smrg (*texBuffer->setTexBuffer2)(context->driContext, 207706f2543Smrg glxPixmap->target, 208706f2543Smrg glxPixmap->format, 209706f2543Smrg drawable->driDrawable); 210706f2543Smrg } else 211706f2543Smrg#endif 212706f2543Smrg texBuffer->setTexBuffer(context->driContext, 213706f2543Smrg glxPixmap->target, 214706f2543Smrg drawable->driDrawable); 215706f2543Smrg 216706f2543Smrg return Success; 217706f2543Smrg} 218706f2543Smrg 219706f2543Smrgstatic int 220706f2543Smrg__glXDRIreleaseTexImage(__GLXcontext *baseContext, 221706f2543Smrg int buffer, 222706f2543Smrg __GLXdrawable *pixmap) 223706f2543Smrg{ 224706f2543Smrg /* FIXME: Just unbind the texture? */ 225706f2543Smrg return Success; 226706f2543Smrg} 227706f2543Smrg 228706f2543Smrg#else 229706f2543Smrg 230706f2543Smrgstatic int 231706f2543Smrg__glXDRIbindTexImage(__GLXcontext *baseContext, 232706f2543Smrg int buffer, 233706f2543Smrg __GLXdrawable *glxPixmap) 234706f2543Smrg{ 235706f2543Smrg return Success; 236706f2543Smrg} 237706f2543Smrg 238706f2543Smrgstatic int 239706f2543Smrg__glXDRIreleaseTexImage(__GLXcontext *baseContext, 240706f2543Smrg int buffer, 241706f2543Smrg __GLXdrawable *pixmap) 242706f2543Smrg{ 243706f2543Smrg return Success; 244706f2543Smrg} 245706f2543Smrg 246706f2543Smrg#endif 247706f2543Smrg 248706f2543Smrgstatic __GLXtextureFromPixmap __glXDRItextureFromPixmap = { 249706f2543Smrg __glXDRIbindTexImage, 250706f2543Smrg __glXDRIreleaseTexImage 251706f2543Smrg}; 252706f2543Smrg 253706f2543Smrgstatic void 254706f2543Smrg__glXDRIscreenDestroy(__GLXscreen *baseScreen) 255706f2543Smrg{ 256706f2543Smrg __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; 257706f2543Smrg 258706f2543Smrg (*screen->core->destroyScreen)(screen->driScreen); 259706f2543Smrg 260706f2543Smrg dlclose(screen->driver); 261706f2543Smrg 262706f2543Smrg __glXScreenDestroy(baseScreen); 263706f2543Smrg 264706f2543Smrg free(screen); 265706f2543Smrg} 266706f2543Smrg 267706f2543Smrgstatic __GLXcontext * 268706f2543Smrg__glXDRIscreenCreateContext(__GLXscreen *baseScreen, 269706f2543Smrg __GLXconfig *glxConfig, 270706f2543Smrg __GLXcontext *baseShareContext) 271706f2543Smrg{ 272706f2543Smrg __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; 273706f2543Smrg __GLXDRIcontext *context, *shareContext; 274706f2543Smrg __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; 275706f2543Smrg const __DRIcoreExtension *core = screen->core; 276706f2543Smrg __DRIcontext *driShare; 277706f2543Smrg 278706f2543Smrg shareContext = (__GLXDRIcontext *) baseShareContext; 279706f2543Smrg if (shareContext) 280706f2543Smrg driShare = shareContext->driContext; 281706f2543Smrg else 282706f2543Smrg driShare = NULL; 283706f2543Smrg 284706f2543Smrg context = calloc(1, sizeof *context); 285706f2543Smrg if (context == NULL) 286706f2543Smrg return NULL; 287706f2543Smrg 288706f2543Smrg context->base.destroy = __glXDRIcontextDestroy; 289706f2543Smrg context->base.makeCurrent = __glXDRIcontextMakeCurrent; 290706f2543Smrg context->base.loseCurrent = __glXDRIcontextLoseCurrent; 291706f2543Smrg context->base.copy = __glXDRIcontextCopy; 292706f2543Smrg context->base.forceCurrent = __glXDRIcontextForceCurrent; 293706f2543Smrg context->base.textureFromPixmap = &__glXDRItextureFromPixmap; 294706f2543Smrg 295706f2543Smrg context->driContext = 296706f2543Smrg (*core->createNewContext)(screen->driScreen, 297706f2543Smrg config->driConfig, driShare, context); 298706f2543Smrg 299706f2543Smrg return &context->base; 300706f2543Smrg} 301706f2543Smrg 302706f2543Smrgstatic __GLXdrawable * 303706f2543Smrg__glXDRIscreenCreateDrawable(ClientPtr client, 304706f2543Smrg __GLXscreen *screen, 305706f2543Smrg DrawablePtr pDraw, 306706f2543Smrg XID drawId, 307706f2543Smrg int type, 308706f2543Smrg XID glxDrawId, 309706f2543Smrg __GLXconfig *glxConfig) 310706f2543Smrg{ 311706f2543Smrg XID gcvals[2]; 312706f2543Smrg int status; 313706f2543Smrg __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; 314706f2543Smrg __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; 315706f2543Smrg __GLXDRIdrawable *private; 316706f2543Smrg 317706f2543Smrg private = calloc(1, sizeof *private); 318706f2543Smrg if (private == NULL) 319706f2543Smrg return NULL; 320706f2543Smrg 321706f2543Smrg private->screen = driScreen; 322706f2543Smrg if (!__glXDrawableInit(&private->base, screen, 323706f2543Smrg pDraw, type, glxDrawId, glxConfig)) { 324706f2543Smrg free(private); 325706f2543Smrg return NULL; 326706f2543Smrg } 327706f2543Smrg 328706f2543Smrg private->base.destroy = __glXDRIdrawableDestroy; 329706f2543Smrg private->base.swapBuffers = __glXDRIdrawableSwapBuffers; 330706f2543Smrg private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; 331706f2543Smrg 332706f2543Smrg gcvals[0] = GXcopy; 333706f2543Smrg private->gc = CreateGC(pDraw, GCFunction, gcvals, &status, (XID)0, serverClient); 334706f2543Smrg gcvals[1] = FALSE; 335706f2543Smrg private->swapgc = CreateGC(pDraw, GCFunction | GCGraphicsExposures, gcvals, &status, (XID)0, serverClient); 336706f2543Smrg 337706f2543Smrg private->driDrawable = 338706f2543Smrg (*driScreen->swrast->createNewDrawable)(driScreen->driScreen, 339706f2543Smrg config->driConfig, 340706f2543Smrg private); 341706f2543Smrg 342706f2543Smrg return &private->base; 343706f2543Smrg} 344706f2543Smrg 345706f2543Smrgstatic void 346706f2543SmrgswrastGetDrawableInfo(__DRIdrawable *draw, 347706f2543Smrg int *x, int *y, int *w, int *h, 348706f2543Smrg void *loaderPrivate) 349706f2543Smrg{ 350706f2543Smrg __GLXDRIdrawable *drawable = loaderPrivate; 351706f2543Smrg DrawablePtr pDraw = drawable->base.pDraw; 352706f2543Smrg 353706f2543Smrg *x = pDraw->x; 354706f2543Smrg *y = pDraw->x; 355706f2543Smrg *w = pDraw->width; 356706f2543Smrg *h = pDraw->height; 357706f2543Smrg} 358706f2543Smrg 359706f2543Smrgstatic void 360706f2543SmrgswrastPutImage(__DRIdrawable *draw, int op, 361706f2543Smrg int x, int y, int w, int h, char *data, 362706f2543Smrg void *loaderPrivate) 363706f2543Smrg{ 364706f2543Smrg __GLXDRIdrawable *drawable = loaderPrivate; 365706f2543Smrg DrawablePtr pDraw = drawable->base.pDraw; 366706f2543Smrg GCPtr gc; 367706f2543Smrg 368706f2543Smrg switch (op) { 369706f2543Smrg case __DRI_SWRAST_IMAGE_OP_DRAW: 370706f2543Smrg gc = drawable->gc; 371706f2543Smrg break; 372706f2543Smrg case __DRI_SWRAST_IMAGE_OP_SWAP: 373706f2543Smrg gc = drawable->swapgc; 374706f2543Smrg break; 375706f2543Smrg default: 376706f2543Smrg return; 377706f2543Smrg } 378706f2543Smrg 379706f2543Smrg ValidateGC(pDraw, gc); 380706f2543Smrg 381706f2543Smrg gc->ops->PutImage(pDraw, gc, pDraw->depth, 382706f2543Smrg x, y, w, h, 0, ZPixmap, data); 383706f2543Smrg} 384706f2543Smrg 385706f2543Smrgstatic void 386706f2543SmrgswrastGetImage(__DRIdrawable *draw, 387706f2543Smrg int x, int y, int w, int h, char *data, 388706f2543Smrg void *loaderPrivate) 389706f2543Smrg{ 390706f2543Smrg __GLXDRIdrawable *drawable = loaderPrivate; 391706f2543Smrg DrawablePtr pDraw = drawable->base.pDraw; 392706f2543Smrg ScreenPtr pScreen = pDraw->pScreen; 393706f2543Smrg 394706f2543Smrg pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data); 395706f2543Smrg} 396706f2543Smrg 397706f2543Smrgstatic const __DRIswrastLoaderExtension swrastLoaderExtension = { 398706f2543Smrg { __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION }, 399706f2543Smrg swrastGetDrawableInfo, 400706f2543Smrg swrastPutImage, 401706f2543Smrg swrastGetImage 402706f2543Smrg}; 403706f2543Smrg 404706f2543Smrgstatic const __DRIextension *loader_extensions[] = { 405706f2543Smrg &systemTimeExtension.base, 406706f2543Smrg &swrastLoaderExtension.base, 407706f2543Smrg NULL 408706f2543Smrg}; 409706f2543Smrg 410706f2543Smrgstatic void 411706f2543SmrginitializeExtensions(__GLXDRIscreen *screen) 412706f2543Smrg{ 413706f2543Smrg const __DRIextension **extensions; 414706f2543Smrg int i; 415706f2543Smrg 416706f2543Smrg extensions = screen->core->getExtensions(screen->driScreen); 417706f2543Smrg 418706f2543Smrg for (i = 0; extensions[i]; i++) { 419706f2543Smrg#ifdef __DRI_COPY_SUB_BUFFER 420706f2543Smrg if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { 421706f2543Smrg screen->copySubBuffer = 422706f2543Smrg (const __DRIcopySubBufferExtension *) extensions[i]; 423706f2543Smrg /* GLX_MESA_copy_sub_buffer is always enabled. */ 424706f2543Smrg } 425706f2543Smrg#endif 426706f2543Smrg 427706f2543Smrg#ifdef __DRI_TEX_BUFFER 428706f2543Smrg if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { 429706f2543Smrg screen->texBuffer = 430706f2543Smrg (const __DRItexBufferExtension *) extensions[i]; 431706f2543Smrg /* GLX_EXT_texture_from_pixmap is always enabled. */ 432706f2543Smrg } 433706f2543Smrg#endif 434706f2543Smrg /* Ignore unknown extensions */ 435706f2543Smrg } 436706f2543Smrg} 437706f2543Smrg 438706f2543Smrgstatic const char dri_driver_path[] = DRI_DRIVER_PATH; 439706f2543Smrg 440706f2543Smrgstatic __GLXscreen * 441706f2543Smrg__glXDRIscreenProbe(ScreenPtr pScreen) 442706f2543Smrg{ 443706f2543Smrg const char *driverName = "swrast"; 444706f2543Smrg __GLXDRIscreen *screen; 445706f2543Smrg char filename[128]; 446706f2543Smrg const __DRIextension **extensions; 447706f2543Smrg const __DRIconfig **driConfigs; 448706f2543Smrg int i; 449706f2543Smrg 450706f2543Smrg screen = calloc(1, sizeof *screen); 451706f2543Smrg if (screen == NULL) 452706f2543Smrg return NULL; 453706f2543Smrg 454706f2543Smrg screen->base.destroy = __glXDRIscreenDestroy; 455706f2543Smrg screen->base.createContext = __glXDRIscreenCreateContext; 456706f2543Smrg screen->base.createDrawable = __glXDRIscreenCreateDrawable; 457706f2543Smrg screen->base.swapInterval = NULL; 458706f2543Smrg screen->base.pScreen = pScreen; 459706f2543Smrg 460706f2543Smrg snprintf(filename, sizeof filename, 461706f2543Smrg "%s/%s_dri.so", dri_driver_path, driverName); 462706f2543Smrg 463706f2543Smrg screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); 464706f2543Smrg if (screen->driver == NULL) { 465706f2543Smrg LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", 466706f2543Smrg filename, dlerror()); 467706f2543Smrg goto handle_error; 468706f2543Smrg } 469706f2543Smrg 470706f2543Smrg extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); 471706f2543Smrg if (extensions == NULL) { 472706f2543Smrg LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", 473706f2543Smrg driverName, dlerror()); 474706f2543Smrg goto handle_error; 475706f2543Smrg } 476706f2543Smrg 477706f2543Smrg for (i = 0; extensions[i]; i++) { 478706f2543Smrg if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && 479706f2543Smrg extensions[i]->version >= __DRI_CORE_VERSION) { 480706f2543Smrg screen->core = (const __DRIcoreExtension *) extensions[i]; 481706f2543Smrg } 482706f2543Smrg if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0 && 483706f2543Smrg extensions[i]->version >= __DRI_SWRAST_VERSION) { 484706f2543Smrg screen->swrast = (const __DRIswrastExtension *) extensions[i]; 485706f2543Smrg } 486706f2543Smrg } 487706f2543Smrg 488706f2543Smrg if (screen->core == NULL || screen->swrast == NULL) { 489706f2543Smrg LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n", 490706f2543Smrg driverName); 491706f2543Smrg goto handle_error; 492706f2543Smrg } 493706f2543Smrg 494706f2543Smrg screen->driScreen = 495706f2543Smrg (*screen->swrast->createNewScreen)(pScreen->myNum, 496706f2543Smrg loader_extensions, 497706f2543Smrg &driConfigs, 498706f2543Smrg screen); 499706f2543Smrg 500706f2543Smrg if (screen->driScreen == NULL) { 501706f2543Smrg LogMessage(X_ERROR, 502706f2543Smrg "AIGLX error: Calling driver entry point failed\n"); 503706f2543Smrg goto handle_error; 504706f2543Smrg } 505706f2543Smrg 506706f2543Smrg initializeExtensions(screen); 507706f2543Smrg 508706f2543Smrg screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs, 509706f2543Smrg GLX_WINDOW_BIT | 510706f2543Smrg GLX_PIXMAP_BIT | 511706f2543Smrg GLX_PBUFFER_BIT); 512706f2543Smrg 513706f2543Smrg __glXScreenInit(&screen->base, pScreen); 514706f2543Smrg 515706f2543Smrg screen->base.GLXmajor = 1; 516706f2543Smrg screen->base.GLXminor = 4; 517706f2543Smrg 518706f2543Smrg LogMessage(X_INFO, 519706f2543Smrg "AIGLX: Loaded and initialized %s\n", filename); 520706f2543Smrg 521706f2543Smrg return &screen->base; 522706f2543Smrg 523706f2543Smrg handle_error: 524706f2543Smrg if (screen->driver) 525706f2543Smrg dlclose(screen->driver); 526706f2543Smrg 527706f2543Smrg free(screen); 528706f2543Smrg 529706f2543Smrg LogMessage(X_ERROR, "GLX: could not load software renderer\n"); 530706f2543Smrg 531706f2543Smrg return NULL; 532706f2543Smrg} 533706f2543Smrg 534706f2543Smrg_X_EXPORT __GLXprovider __glXDRISWRastProvider = { 535706f2543Smrg __glXDRIscreenProbe, 536706f2543Smrg "DRISWRAST", 537706f2543Smrg NULL 538706f2543Smrg}; 539