summaryrefslogtreecommitdiff
path: root/src/glx/mini/miniglx.c
diff options
context:
space:
mode:
authorJon Smirl <jonsmirl@gmail.com>2004-06-26 17:16:42 +0000
committerJon Smirl <jonsmirl@gmail.com>2004-06-26 17:16:42 +0000
commitc2bffec91a5b6ba72514c875b70dbc96ac97431d (patch)
tree3c5f963b8cec93217b18cdec35c50f0c45b3339e /src/glx/mini/miniglx.c
parente16f6e3f234391027b300ec2ca8b56fc13aac825 (diff)
Mesa-solo builds with these changes. There are still more fixups needed to
get individual drivers working again. This converts miniglx to the new dri interface. Thanks to Erdi Chen for the new interface code.
Diffstat (limited to 'src/glx/mini/miniglx.c')
-rw-r--r--src/glx/mini/miniglx.c435
1 files changed, 395 insertions, 40 deletions
diff --git a/src/glx/mini/miniglx.c b/src/glx/mini/miniglx.c
index 7e78a020dd..31bd9cc034 100644
--- a/src/glx/mini/miniglx.c
+++ b/src/glx/mini/miniglx.c
@@ -108,10 +108,45 @@
#include <linux/vt.h>
#include "miniglxP.h"
-#include "dri.h"
+#include "dri_util.h"
+#include "imports.h"
+#include "glcontextmodes.h"
#include "glapi.h"
-#include "xf86drm.h"
+
+
+extern GLboolean __glXCreateContextWithConfig(__DRInativeDisplay *dpy,
+ int screen, int fbconfigID, void *contextID,
+ drm_context_t *hHWContext);
+
+extern GLboolean __glXGetDrawableInfo(__DRInativeDisplay *dpy, int scrn,
+ __DRIid draw, unsigned int * index, unsigned int * stamp,
+ int * x, int * y, int * width, int * height,
+ int * numClipRects, drm_clip_rect_t ** pClipRects,
+ int * backX, int * backY,
+ int * numBackClipRects, drm_clip_rect_t ** pBackClipRects);
+
+
+/** Wrapper around either malloc() */
+void *
+_mesa_malloc(size_t bytes)
+{
+ return malloc(bytes);
+}
+
+/** Wrapper around either calloc() */
+void *
+_mesa_calloc(size_t bytes)
+{
+ return calloc(1, bytes);
+}
+
+/** Wrapper around either free() */
+void
+_mesa_free(void *ptr)
+{
+ free(ptr);
+}
/**
@@ -664,10 +699,10 @@ CloseFBDev( Display *dpy )
* Returns the MiniGLXDisplayRec::driScreen attribute.
*/
__DRIscreen *
-__glXFindDRIScreen(Display *dpy, int scrn)
+__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn)
{
(void) scrn;
- return dpy->driScreen;
+ return &((Display*)dpy)->driScreen;
}
/**
@@ -681,9 +716,10 @@ __glXFindDRIScreen(Display *dpy, int scrn)
* the MiniGLXDisplayRec::TheWindow attribute.
*/
Bool
-__glXWindowExists(Display *dpy, GLXDrawable draw)
+__glXWindowExists(__DRInativeDisplay *dpy, GLXDrawable draw)
{
- if (dpy->TheWindow == draw)
+ Display* display = (Display*)dpy;
+ if (display->TheWindow == draw)
return True;
else
return False;
@@ -875,6 +911,24 @@ static int __read_config_file( Display *dpy )
static int InitDriver( Display *dpy )
{
+ char * str;
+ char * srvLibname = NULL;
+
+ srvLibname = strdup(dpy->clientDriverName);
+ if (!srvLibname) {
+ goto failed;
+ }
+
+ /*
+ * Construct server library name. Assume clientDriverName ends
+ * with dri.so. Replace dri.so with srv.so.
+ */
+ str = strstr(srvLibname, "dri.so");
+ if (!str) {
+ goto failed;
+ }
+ strcpy(str, "srv.so");
+
/*
* Begin DRI setup.
* We're kind of combining the per-display and per-screen information
@@ -884,32 +938,51 @@ static int InitDriver( Display *dpy )
if (!dpy->dlHandle) {
fprintf(stderr, "Unable to open %s: %s\n", dpy->clientDriverName,
dlerror());
- return GL_FALSE;
+ goto failed;
+ }
+
+ dpy->dlHandleSrv = dlopen(srvLibname, RTLD_NOW | RTLD_GLOBAL);
+ if (!dpy->dlHandleSrv) {
+ fprintf(stderr, "Unable to open %s: %s\n", dpy->clientDriverName,
+ dlerror());
+ goto failed;
}
/* Pull in Mini GLX specific hooks:
*/
- dpy->driver = (struct DRIDriverRec *) dlsym(dpy->dlHandle,
+ dpy->driver = (struct DRIDriverRec *) dlsym(dpy->dlHandleSrv,
"__driDriver");
if (!dpy->driver) {
fprintf(stderr, "Couldn't find __driDriver in %s\n",
dpy->clientDriverName);
- dlclose(dpy->dlHandle);
- return GL_FALSE;
+ goto failed;
}
/* Pull in standard DRI client-side driver hooks:
*/
- dpy->createScreen = (driCreateScreenFunc*) dlsym(dpy->dlHandle,
- "__driCreateScreen");
- if (!dpy->createScreen) {
+ dpy->createNewScreen = (PFNCREATENEWSCREENFUNC)
+ dlsym(dpy->dlHandle, "__driCreateNewScreen");
+ if (!dpy->createNewScreen) {
fprintf(stderr, "Couldn't find __driCreateScreen in %s\n",
dpy->clientDriverName);
- dlclose(dpy->dlHandle);
- return GL_FALSE;
+ goto failed;
}
return GL_TRUE;
+
+failed:
+ if (srvLibname) {
+ free(srvLibname);
+ }
+ if (dpy->dlHandleSrv) {
+ dlclose(dpy->dlHandleSrv);
+ dpy->dlHandleSrv = 0;
+ }
+ if (dpy->dlHandle) {
+ dlclose(dpy->dlHandle);
+ dpy->dlHandle = 0;
+ }
+ return GL_FALSE;
}
@@ -1014,6 +1087,199 @@ __miniglx_StartServer( const char *display_name )
}
+static void *
+CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc)
+{
+ int directCapable;
+ void *psp = NULL;
+ drm_handle_t hSAREA;
+ drmAddress pSAREA;
+ const char *BusID;
+ __GLcontextModes *modes;
+ __GLcontextModes *temp;
+ int i;
+ __DRIversion ddx_version;
+ __DRIversion dri_version;
+ __DRIversion drm_version;
+ __DRIframebuffer framebuffer;
+ int fd = -1;
+ int status;
+ const char * err_msg;
+ const char * err_extra;
+ drmVersionPtr version;
+ drm_handle_t hFB;
+ int junk;
+
+
+ /* Create the linked list of context modes, and populate it with the
+ * GLX visual information passed in by libGL.
+ */
+
+ modes = _gl_context_modes_create( dpy->numModes, sizeof(__GLcontextModes) );
+ if ( modes == NULL ) {
+ return NULL;
+ }
+
+ temp = modes;
+ for ( i = 0 ; i < dpy->numModes ; i++ ) {
+ __GLcontextModes * next;
+ assert( temp != NULL );
+ next = temp->next;
+ *temp = dpy->modes[i];
+ temp->next = next;
+ temp->screen = scrn;
+
+ temp = temp->next;
+ }
+
+ err_msg = "XF86DRIOpenConnection";
+ err_extra = NULL;
+
+ hSAREA = dpy->driverContext.shared.hSAREA;
+ BusID = dpy->driverContext.pciBusID;
+
+ fd = drmOpen(NULL, BusID);
+
+ err_msg = "open DRM";
+ err_extra = strerror( -fd );
+
+ if (fd < 0) goto done;
+
+ drm_magic_t magic;
+
+ err_msg = "drmGetMagic";
+ err_extra = NULL;
+
+ if (drmGetMagic(fd, &magic)) goto done;
+
+ version = drmGetVersion(fd);
+ if (version) {
+ drm_version.major = version->version_major;
+ drm_version.minor = version->version_minor;
+ drm_version.patch = version->version_patchlevel;
+ drmFreeVersion(version);
+ }
+ else {
+ drm_version.major = -1;
+ drm_version.minor = -1;
+ drm_version.patch = -1;
+ }
+
+ /*
+ * Get device name (like "tdfx") and the ddx version numbers.
+ * We'll check the version in each DRI driver's "createScreen"
+ * function.
+ */
+ err_msg = "XF86DRIGetClientDriverName";
+ ddx_version.major = 4;
+ ddx_version.minor = 0;
+ ddx_version.patch = 0;
+
+ /*
+ * Get the DRI X extension version.
+ */
+ err_msg = "XF86DRIQueryVersion";
+ dri_version.major = 4;
+ dri_version.minor = 0;
+ dri_version.patch = 0;
+
+ /*
+ * Get device-specific info. pDevPriv will point to a struct
+ * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
+ * that has information about the screen size, depth, pitch,
+ * ancilliary buffers, DRM mmap handles, etc.
+ */
+ err_msg = "XF86DRIGetDeviceInfo";
+ hFB = dpy->driverContext.shared.hFrameBuffer;
+ framebuffer.size = dpy->driverContext.shared.fbSize;
+ framebuffer.stride = dpy->driverContext.shared.fbStride;
+ framebuffer.dev_priv_size = dpy->driverContext.driverClientMsgSize;
+ framebuffer.dev_priv = dpy->driverContext.driverClientMsg;
+ framebuffer.width = dpy->driverContext.shared.virtualWidth;
+ framebuffer.height = dpy->driverContext.shared.virtualHeight;
+
+ /*
+ * Map the framebuffer region.
+ */
+ status = drmMap(fd, hFB, framebuffer.size,
+ (drmAddressPtr)&framebuffer.base);
+
+ err_msg = "drmMap of framebuffer";
+ err_extra = strerror( -status );
+
+ if ( status != 0 ) goto done;
+
+ /*
+ * Map the SAREA region. Further mmap regions may be setup in
+ * each DRI driver's "createScreen" function.
+ */
+ status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
+
+ err_msg = "drmMap of sarea";
+ err_extra = strerror( -status );
+
+ if ( status == 0 ) {
+ PFNGLXGETINTERNALVERSIONPROC get_ver;
+
+ get_ver = (PFNGLXGETINTERNALVERSIONPROC)
+ glXGetProcAddress( (const GLubyte *) "__glXGetInternalVersion" );
+
+ err_msg = "InitDriver";
+ err_extra = NULL;
+ psp = dpy->createNewScreen(dpy, scrn, psc, modes,
+ & ddx_version,
+ & dri_version,
+ & drm_version,
+ & framebuffer,
+ pSAREA,
+ fd,
+ (get_ver != NULL) ? (*get_ver)() : 20040602,
+ (__GLcontextModes **) &dpy->driver_modes);
+ if (dpy->driver_modes == NULL) {
+ dpy->driver_modes = modes;
+ }
+ else {
+ _gl_context_modes_destroy(modes);
+ modes = NULL;
+ }
+ }
+
+done:
+ if ( psp == NULL ) {
+ if ( pSAREA != MAP_FAILED ) {
+ (void)drmUnmap(pSAREA, SAREA_MAX);
+ }
+
+ if ( framebuffer.base != MAP_FAILED ) {
+ (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
+ }
+
+ if ( framebuffer.dev_priv != NULL ) {
+ free(framebuffer.dev_priv);
+ }
+
+ if ( fd >= 0 ) {
+ (void)drmClose(fd);
+ }
+
+ if ( modes != NULL ) {
+ _gl_context_modes_destroy( modes );
+ }
+
+ if ( err_extra != NULL ) {
+ fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
+ err_extra);
+ }
+ else {
+ fprintf(stderr, "libGL error: %s failed\n", err_msg );
+ }
+
+ fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
+ }
+
+ return psp;
+}
+
/**
* \brief Initialize the graphics system.
*
@@ -1083,9 +1349,8 @@ XOpenDisplay( const char *display_name )
*
* Need to shut down DRM and free DRI data in XDestroyWindow(), too.
*/
- dpy->driScreen = (*dpy->createScreen)(dpy->driver,
- &dpy->driverContext);
- if (!dpy->driScreen) {
+ dpy->driScreen.private = CallCreateNewScreen(dpy, 0, &dpy->driScreen);
+ if (!dpy->driScreen.private) {
fprintf(stderr, "%s: __driCreateScreen failed\n", __FUNCTION__);
dlclose(dpy->dlHandle);
free(dpy);
@@ -1124,7 +1389,7 @@ XCloseDisplay( Display *dpy )
/* As this is done in XOpenDisplay, need to undo it here:
*/
- (*dpy->driScreen->destroyScreen)(dpy->driScreen);
+ dpy->driScreen.destroyScreen(dpy, 0, dpy->driScreen.private);
__miniglx_close_connections( dpy );
@@ -1187,6 +1452,8 @@ XCreateWindow( Display *dpy, Window parent, int x, int y,
Visual *visual, unsigned long valuemask,
XSetWindowAttributes *attributes )
{
+ const int empty_attribute_list[1] = { None };
+
Window win;
/* ignored */
@@ -1252,11 +1519,10 @@ XCreateWindow( Display *dpy, Window parent, int x, int y,
win->curBottom = win->frontBottom;
}
- win->driDrawable = dpy->driScreen->createDrawable(dpy->driScreen,
- width, height,
- dpy->clientID, visual->mode);
+ dpy->driScreen.createNewDrawable(dpy, dpy->driver_modes, (int) win,
+ &win->driDrawable, GLX_WINDOW_BIT, empty_attribute_list);
- if (!win->driDrawable) {
+ if (!win->driDrawable.private) {
fprintf(stderr, "%s: dri.createDrawable failed\n", __FUNCTION__);
free(win);
return NULL;
@@ -1293,7 +1559,7 @@ XDestroyWindow( Display *display, Window win )
XUnmapWindow( display, win );
/* Destroy the drawable. */
- (*win->driDrawable->destroyDrawable)(win->driDrawable);
+ win->driDrawable.destroyDrawable(display, win->driDrawable.private);
free(win);
/* unlink window from display */
@@ -1748,14 +2014,14 @@ glXCreateContext( Display *dpy, XVisualInfo *vis,
ctx->vid = vis->visualid;
if (shareList)
- sharePriv = shareList->driContext;
+ sharePriv = shareList->driContext.private;
else
sharePriv = NULL;
-
- ctx->driContext = (*dpy->driScreen->createContext)(dpy->driScreen,
- vis->visual->mode,
- sharePriv);
- if (!ctx->driContext) {
+
+ ctx->driContext.private = dpy->driScreen.createNewContext(dpy, vis->visual->mode,
+ GLX_WINDOW_BIT, sharePriv, &ctx->driContext);
+
+ if (!ctx->driContext.private) {
free(ctx);
return NULL;
}
@@ -1782,10 +2048,10 @@ glXDestroyContext( Display *dpy, GLXContext ctx )
if (ctx) {
if (glxctx == ctx) {
/* destroying current context */
- (*ctx->driContext->bindContext)(dpy->driScreen, 0, 0);
+ ctx->driContext.bindContext3(dpy, 0, 0, 0, 0);
CurrentContext = 0;
}
- (*ctx->driContext->destroyContext)(ctx->driContext);
+ ctx->driContext.destroyContext(dpy, 0, ctx->driContext.private);
free(ctx);
}
}
@@ -1825,17 +2091,20 @@ glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx)
GLXDrawable oldDrawable = glXGetCurrentDrawable();
/* unbind old */
if (oldContext) {
- (*oldContext->driContext->unbindContext)(oldDrawable->driDrawable, oldContext->driContext);
+ oldContext->driContext.unbindContext3(dpy, 0,
+ (__DRIid) oldDrawable, (__DRIid) oldDrawable,
+ &oldContext->driContext);
}
/* bind new */
CurrentContext = ctx;
- (*ctx->driContext->bindContext)(dpy->driScreen, drawable->driDrawable, ctx->driContext);
+ ctx->driContext.bindContext3(dpy, 0, (__DRIid) drawable,
+ (__DRIid) drawable, &ctx->driContext);
ctx->drawBuffer = drawable;
ctx->curBuffer = drawable;
}
else if (ctx && dpy) {
/* unbind */
- (*ctx->driContext->bindContext)(dpy->driScreen, 0, 0);
+ ctx->driContext.bindContext3(dpy, 0, 0, 0, 0);
}
else if (dpy) {
CurrentContext = 0; /* kw: this seems to be intended??? */
@@ -1865,7 +2134,7 @@ glXSwapBuffers( Display *dpy, GLXDrawable drawable )
if (!dpy || !drawable)
return;
- (*drawable->driDrawable->swapBuffers)(drawable->driDrawable);
+ drawable->driDrawable.swapBuffers(dpy, drawable->driDrawable.private);
}
@@ -1906,6 +2175,90 @@ glXGetCurrentDrawable( void )
}
+GLboolean
+__glXCreateContextWithConfig(__DRInativeDisplay *dpy, int screen,
+ int fbconfigID, void *contextID, drm_context_t *hHWContext)
+{
+ __DRIscreen *pDRIScreen;
+ __DRIscreenPrivate *psp;
+
+ pDRIScreen = __glXFindDRIScreen(dpy, screen);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ return GL_FALSE;
+ }
+
+ psp = (__DRIscreenPrivate *) pDRIScreen->private;
+
+ if (psp->fd) {
+ if (drmCreateContext(psp->fd, hHWContext)) {
+ fprintf(stderr, ">>> drmCreateContext failed\n");
+ return GL_FALSE;
+ }
+ *(void**)contextID = (void*) *hHWContext;
+ }
+
+ return GL_TRUE;
+}
+
+
+GLboolean
+__glXGetDrawableInfo(__DRInativeDisplay *dpy, int scrn,
+ __DRIid draw, unsigned int * index, unsigned int * stamp,
+ int * x, int * y, int * width, int * height,
+ int * numClipRects, drm_clip_rect_t ** pClipRects,
+ int * backX, int * backY,
+ int * numBackClipRects, drm_clip_rect_t ** pBackClipRects)
+{
+ GLXDrawable drawable = (GLXDrawable) draw;
+ drm_clip_rect_t * cliprect;
+
+ if (drawable == 0) {
+ return GL_FALSE;
+ }
+
+ cliprect = (drm_clip_rect_t*) _mesa_malloc(sizeof(drm_clip_rect_t));
+ cliprect->x1 = drawable->x;
+ cliprect->y1 = drawable->y;
+ cliprect->x2 = drawable->x + drawable->w;
+ cliprect->y2 = drawable->y + drawable->h;
+
+ *x = drawable->x;
+ *y = drawable->y;
+ *width = drawable->w;
+ *height = drawable->h;
+ *numClipRects = 1;
+ *pClipRects = cliprect;
+ *backX = 0;
+ *backY = 0;
+ *numBackClipRects = 0;
+ *pBackClipRects = 0;
+
+ return GL_TRUE;
+}
+
+
+GLboolean
+XF86DRIDestroyContext(__DRInativeDisplay *dpy, int screen, __DRIid context_id )
+{
+ return GL_TRUE;
+}
+
+
+GLboolean
+XF86DRICreateDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable,
+ drm_drawable_t *hHWDrawable )
+{
+ return GL_TRUE;
+}
+
+
+GLboolean
+XF86DRIDestroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
+{
+ return GL_TRUE;
+}
+
+
/**
* \brief Query function address.
*
@@ -1926,8 +2279,7 @@ glXGetCurrentDrawable( void )
* Returns the function address by looking up its name in a static (name,
* address) pair list.
*/
-const void *
-glXGetProcAddress( const GLubyte *procName )
+void (*glXGetProcAddress(const GLubyte *procname))( void )
{
struct name_address {
const char *name;
@@ -1955,15 +2307,18 @@ glXGetProcAddress( const GLubyte *procName )
{ "glXDestroyPbuffer", (void *) glXDestroyPbuffer },
{ "glXChooseFBConfig", (void *) glXChooseFBConfig },
{ "glXGetVisualFromFBConfig", (void *) glXGetVisualFromFBConfig },
+ { "__glXCreateContextWithConfig", (void *) __glXCreateContextWithConfig },
+ { "__glXGetDrawableInfo", (void *) __glXGetDrawableInfo },
+ { "__glXWindowExists", (void *) __glXWindowExists },
{ NULL, NULL }
};
const struct name_address *entry;
for (entry = functions; entry->name; entry++) {
- if (strcmp(entry->name, (const char *) procName) == 0) {
+ if (strcmp(entry->name, (const char *) procname) == 0) {
return entry->func;
}
}
- return _glapi_get_proc_address((const char *) procName);
+ return _glapi_get_proc_address((const char *) procname);
}