Add GLX provider for DRI2.
This commit is contained in:
		
							parent
							
								
									b71dc54352
								
							
						
					
					
						commit
						879515b139
					
				| 
						 | 
					@ -25,6 +25,7 @@ INCLUDES = \
 | 
				
			||||||
	-I$(top_srcdir)/hw/xfree86/os-support/bus \
 | 
						-I$(top_srcdir)/hw/xfree86/os-support/bus \
 | 
				
			||||||
	-I$(top_srcdir)/hw/xfree86/common \
 | 
						-I$(top_srcdir)/hw/xfree86/common \
 | 
				
			||||||
	-I$(top_srcdir)/hw/xfree86/dri \
 | 
						-I$(top_srcdir)/hw/xfree86/dri \
 | 
				
			||||||
 | 
						-I$(top_srcdir)/hw/xfree86/dri2 \
 | 
				
			||||||
	-I$(top_srcdir)/mi
 | 
						-I$(top_srcdir)/mi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +37,7 @@ nodist_libglx_la_SOURCES = indirect_size.h \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libglxdri_la_SOURCES = \
 | 
					libglxdri_la_SOURCES = \
 | 
				
			||||||
        glxdri.c \
 | 
					        glxdri.c \
 | 
				
			||||||
 | 
					        glxdri2.c \
 | 
				
			||||||
        extension_string.c \
 | 
					        extension_string.c \
 | 
				
			||||||
        extension_string.h
 | 
					        extension_string.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,573 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright © 2007 Red Hat, Inc
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, distribute, and sell this software
 | 
				
			||||||
 | 
					 * and its documentation for any purpose is hereby granted without
 | 
				
			||||||
 | 
					 * fee, provided that the above copyright notice appear in all copies
 | 
				
			||||||
 | 
					 * and that both that copyright notice and this permission notice
 | 
				
			||||||
 | 
					 * appear in supporting documentation, and that the name of Red Hat,
 | 
				
			||||||
 | 
					 * Inc not be used in advertising or publicity pertaining to
 | 
				
			||||||
 | 
					 * distribution of the software without specific, written prior
 | 
				
			||||||
 | 
					 * permission.  Red Hat, Inc makes no representations about the
 | 
				
			||||||
 | 
					 * suitability of this software for any purpose.  It is provided "as
 | 
				
			||||||
 | 
					 * is" without express or implied warranty.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 | 
				
			||||||
 | 
					 * NO EVENT SHALL RED HAT, INC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 | 
				
			||||||
 | 
					 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
				
			||||||
 | 
					 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_DIX_CONFIG_H
 | 
				
			||||||
 | 
					#include <dix-config.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					#include <dlfcn.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <drm.h>
 | 
				
			||||||
 | 
					#include <GL/gl.h>
 | 
				
			||||||
 | 
					#include <GL/internal/dri_interface.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <windowstr.h>
 | 
				
			||||||
 | 
					#include <os.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _XF86DRI_SERVER_
 | 
				
			||||||
 | 
					#include <xf86drm.h>
 | 
				
			||||||
 | 
					#include <xf86dristr.h>
 | 
				
			||||||
 | 
					#include <xf86str.h>
 | 
				
			||||||
 | 
					#include <xf86.h>
 | 
				
			||||||
 | 
					#include <dri2.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "glxserver.h"
 | 
				
			||||||
 | 
					#include "glxutil.h"
 | 
				
			||||||
 | 
					#include "glcontextmodes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "g_disptab.h"
 | 
				
			||||||
 | 
					#include "glapitable.h"
 | 
				
			||||||
 | 
					#include "glapi.h"
 | 
				
			||||||
 | 
					#include "glthread.h"
 | 
				
			||||||
 | 
					#include "dispatch.h"
 | 
				
			||||||
 | 
					#include "extension_string.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define containerOf(ptr, type, member)			\
 | 
				
			||||||
 | 
					    (type *)( (char *)ptr - offsetof(type,member) )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct __GLXDRIscreen   __GLXDRIscreen;
 | 
				
			||||||
 | 
					typedef struct __GLXDRIcontext  __GLXDRIcontext;
 | 
				
			||||||
 | 
					typedef struct __GLXDRIdrawable __GLXDRIdrawable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct __GLXDRIscreen {
 | 
				
			||||||
 | 
					    __GLXscreen		 base;
 | 
				
			||||||
 | 
					    __DRIscreen		 driScreen;
 | 
				
			||||||
 | 
					    void		*driver;
 | 
				
			||||||
 | 
					    int			 fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xf86EnterVTProc	*enterVT;
 | 
				
			||||||
 | 
					    xf86LeaveVTProc	*leaveVT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __DRIcopySubBufferExtension *copySubBuffer;
 | 
				
			||||||
 | 
					    __DRIswapControlExtension *swapControl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct __GLXDRIcontext {
 | 
				
			||||||
 | 
					    __GLXcontext base;
 | 
				
			||||||
 | 
					    __DRIcontext driContext;
 | 
				
			||||||
 | 
					    drm_context_t hwContext;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct __GLXDRIdrawable {
 | 
				
			||||||
 | 
					    __GLXdrawable base;
 | 
				
			||||||
 | 
					    __DRIdrawable driDrawable;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char CREATE_NEW_SCREEN_FUNC[] = __DRI2_CREATE_NEW_SCREEN_STRING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					__glXDRIdrawableDestroy(__GLXdrawable *drawable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (*private->driDrawable.destroyDrawable)(&private->driDrawable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* If the X window was destroyed, the dri DestroyWindow hook will
 | 
				
			||||||
 | 
					     * aready have taken care of this, so only call if pDraw isn't NULL. */
 | 
				
			||||||
 | 
					    if (drawable->pDraw != NULL)
 | 
				
			||||||
 | 
						DRI2DestroyDrawable(drawable->pDraw->pScreen, drawable->pDraw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xfree(private);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GLboolean
 | 
				
			||||||
 | 
					__glXDRIdrawableResize(__GLXdrawable *glxPriv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Nothing to do here, the DRI driver asks the server for drawable
 | 
				
			||||||
 | 
					     * geometry when it sess the SAREA timestamps change.*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return GL_TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GLboolean
 | 
				
			||||||
 | 
					__glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (*private->driDrawable.swapBuffers)(&private->driDrawable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
 | 
				
			||||||
 | 
					    __GLXDRIscreen *screen = (__GLXDRIscreen *)
 | 
				
			||||||
 | 
						glxGetScreen(baseDrawable->pDraw->pScreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (screen->swapControl)
 | 
				
			||||||
 | 
						screen->swapControl->setSwapInterval(&draw->driDrawable, interval);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
 | 
				
			||||||
 | 
								       int x, int y, int w, int h)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
 | 
				
			||||||
 | 
					    __GLXDRIscreen *screen = (__GLXDRIscreen *)
 | 
				
			||||||
 | 
						glxGetScreen(basePrivate->pDraw->pScreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (screen->copySubBuffer)
 | 
				
			||||||
 | 
						screen->copySubBuffer->copySubBuffer(&private->driDrawable,
 | 
				
			||||||
 | 
										     x, y, w, h);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					__glXDRIcontextDestroy(__GLXcontext *baseContext)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
 | 
				
			||||||
 | 
					    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseContext->pGlxScreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context->driContext.destroyContext(&context->driContext);
 | 
				
			||||||
 | 
					    drmDestroyContext(screen->fd, context->hwContext);
 | 
				
			||||||
 | 
					    __glXContextDestroy(&context->base);
 | 
				
			||||||
 | 
					    xfree(context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (*context->driContext.bindContext)(&context->driContext,
 | 
				
			||||||
 | 
										      &draw->driDrawable,
 | 
				
			||||||
 | 
										      &read->driDrawable);
 | 
				
			||||||
 | 
					}					      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (*context->driContext.unbindContext)(&context->driContext);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
 | 
				
			||||||
 | 
							    unsigned long mask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
 | 
				
			||||||
 | 
					    __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* FIXME: We will need to add DRIcontext::copyContext for this. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (void) dst;
 | 
				
			||||||
 | 
					    (void) src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					__glXDRIcontextForceCurrent(__GLXcontext *baseContext)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (*context->driContext.bindContext)(&context->driContext,
 | 
				
			||||||
 | 
										      &draw->driDrawable,
 | 
				
			||||||
 | 
										      &read->driDrawable);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					__glXDRIbindTexImage(__GLXcontext *baseContext,
 | 
				
			||||||
 | 
							     int buffer,
 | 
				
			||||||
 | 
							     __GLXdrawable *glxPixmap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					__glXDRIreleaseTexImage(__GLXcontext *baseContext,
 | 
				
			||||||
 | 
								int buffer,
 | 
				
			||||||
 | 
								__GLXdrawable *pixmap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
 | 
				
			||||||
 | 
					    __glXDRIbindTexImage,
 | 
				
			||||||
 | 
					    __glXDRIreleaseTexImage
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					__glXDRIscreenDestroy(__GLXscreen *baseScreen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    screen->driScreen.destroyScreen(&screen->driScreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dlclose(screen->driver);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __glXScreenDestroy(baseScreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xfree(screen);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __GLXcontext *
 | 
				
			||||||
 | 
					__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
 | 
				
			||||||
 | 
								    __GLcontextModes *modes,
 | 
				
			||||||
 | 
								    __GLXcontext *baseShareContext)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
 | 
				
			||||||
 | 
					    __GLXDRIcontext *context, *shareContext;
 | 
				
			||||||
 | 
					    __DRIcontext *driShare;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    shareContext = (__GLXDRIcontext *) baseShareContext;
 | 
				
			||||||
 | 
					    if (shareContext)
 | 
				
			||||||
 | 
						driShare = &shareContext->driContext;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
						driShare = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context = xalloc(sizeof *context);
 | 
				
			||||||
 | 
					    if (context == NULL)
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(context, 0, sizeof *context);
 | 
				
			||||||
 | 
					    context->base.destroy           = __glXDRIcontextDestroy;
 | 
				
			||||||
 | 
					    context->base.makeCurrent       = __glXDRIcontextMakeCurrent;
 | 
				
			||||||
 | 
					    context->base.loseCurrent       = __glXDRIcontextLoseCurrent;
 | 
				
			||||||
 | 
					    context->base.copy              = __glXDRIcontextCopy;
 | 
				
			||||||
 | 
					    context->base.forceCurrent      = __glXDRIcontextForceCurrent;
 | 
				
			||||||
 | 
					    context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (drmCreateContext(screen->fd, &context->hwContext))
 | 
				
			||||||
 | 
						    return GL_FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context->driContext.private =
 | 
				
			||||||
 | 
						screen->driScreen.createNewContext(&screen->driScreen,
 | 
				
			||||||
 | 
										   modes,
 | 
				
			||||||
 | 
										   0, /* render type */
 | 
				
			||||||
 | 
										   driShare,
 | 
				
			||||||
 | 
										   context->hwContext,
 | 
				
			||||||
 | 
										   &context->driContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return &context->base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __GLXdrawable *
 | 
				
			||||||
 | 
					__glXDRIscreenCreateDrawable(__GLXscreen *screen,
 | 
				
			||||||
 | 
								     DrawablePtr pDraw,
 | 
				
			||||||
 | 
								     int type,
 | 
				
			||||||
 | 
								     XID drawId,
 | 
				
			||||||
 | 
								     __GLcontextModes *modes)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *private;
 | 
				
			||||||
 | 
					    GLboolean retval;
 | 
				
			||||||
 | 
					    drm_drawable_t hwDrawable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private = xalloc(sizeof *private);
 | 
				
			||||||
 | 
					    if (private == NULL)
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(private, 0, sizeof *private);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!__glXDrawableInit(&private->base, screen,
 | 
				
			||||||
 | 
								   pDraw, type, drawId, modes)) {
 | 
				
			||||||
 | 
					        xfree(private);
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private->base.destroy       = __glXDRIdrawableDestroy;
 | 
				
			||||||
 | 
					    private->base.resize        = __glXDRIdrawableResize;
 | 
				
			||||||
 | 
					    private->base.swapBuffers   = __glXDRIdrawableSwapBuffers;
 | 
				
			||||||
 | 
					    private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    retval = DRI2CreateDrawable(screen->pScreen, pDraw, &hwDrawable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private->driDrawable.private =
 | 
				
			||||||
 | 
						(driScreen->driScreen.createNewDrawable)(&driScreen->driScreen,
 | 
				
			||||||
 | 
											 modes,
 | 
				
			||||||
 | 
											 &private->driDrawable,
 | 
				
			||||||
 | 
											 hwDrawable, 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return &private->base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					getUST(int64_t *ust)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct timeval  tv;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (ust == NULL)
 | 
				
			||||||
 | 
						return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (gettimeofday(&tv, NULL) == 0) {
 | 
				
			||||||
 | 
						ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
						return -errno;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __glXReportDamage(__DRIdrawable *driDraw,
 | 
				
			||||||
 | 
								      int x, int y,
 | 
				
			||||||
 | 
								      drm_clip_rect_t *rects, int num_rects,
 | 
				
			||||||
 | 
								      GLboolean front_buffer)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIdrawable *drawable =
 | 
				
			||||||
 | 
						    containerOf(driDraw, __GLXDRIdrawable, driDrawable);
 | 
				
			||||||
 | 
					    DrawablePtr pDraw = drawable->base.pDraw;
 | 
				
			||||||
 | 
					    RegionRec region;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    REGION_INIT(pDraw->pScreen, ®ion, (BoxPtr) rects, num_rects);
 | 
				
			||||||
 | 
					    REGION_TRANSLATE(pScreen, ®ion, pDraw->x, pDraw->y);
 | 
				
			||||||
 | 
					    DamageDamageRegion(pDraw, ®ion);
 | 
				
			||||||
 | 
					    REGION_UNINIT(pDraw->pScreen, ®ion);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table of functions that we export to the driver. */
 | 
				
			||||||
 | 
					static const __DRIinterfaceMethods interface_methods = {
 | 
				
			||||||
 | 
					    _gl_context_modes_create,
 | 
				
			||||||
 | 
					    _gl_context_modes_destroy,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NULL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getUST,
 | 
				
			||||||
 | 
					    NULL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __glXReportDamage,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char dri_driver_path[] = DRI_DRIVER_PATH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Bool
 | 
				
			||||||
 | 
					glxDRIEnterVT (int index, int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIscreen *screen = (__GLXDRIscreen *) 
 | 
				
			||||||
 | 
						glxGetScreen(screenInfo.screens[index]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(*screen->enterVT) (index, flags))
 | 
				
			||||||
 | 
						return FALSE;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    glxResumeClients();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					glxDRILeaveVT (int index, int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLXDRIscreen *screen = (__GLXDRIscreen *)
 | 
				
			||||||
 | 
						glxGetScreen(screenInfo.screens[index]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    glxSuspendClients();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (*screen->leaveVT) (index, flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					initializeExtensions(__GLXDRIscreen *screen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const __DRIextension **extensions;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    extensions = screen->driScreen.getExtensions(&screen->driScreen);
 | 
				
			||||||
 | 
					    for (i = 0; extensions[i]; i++) {
 | 
				
			||||||
 | 
					#ifdef __DRI_COPY_SUB_BUFFER
 | 
				
			||||||
 | 
						if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
 | 
				
			||||||
 | 
						    screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
 | 
				
			||||||
 | 
						    __glXEnableExtension(screen->glx_enable_bits,
 | 
				
			||||||
 | 
									 "GLX_MESA_copy_sub_buffer");
 | 
				
			||||||
 | 
						    
 | 
				
			||||||
 | 
						    LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __DRI_SWAP_CONTROL
 | 
				
			||||||
 | 
						if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
 | 
				
			||||||
 | 
						    screen->swapControl = (__DRIswapControlExtension *) extensions[i];
 | 
				
			||||||
 | 
						    __glXEnableExtension(screen->glx_enable_bits,
 | 
				
			||||||
 | 
									 "GLX_SGI_swap_control");
 | 
				
			||||||
 | 
						    __glXEnableExtension(screen->glx_enable_bits,
 | 
				
			||||||
 | 
									 "GLX_MESA_swap_control");
 | 
				
			||||||
 | 
						    
 | 
				
			||||||
 | 
						    LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						/* Ignore unknown extensions */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					static __GLXscreen *
 | 
				
			||||||
 | 
					__glXDRIscreenProbe(ScreenPtr pScreen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __DRI2_CREATE_NEW_SCREEN_FUNC *createNewScreen;
 | 
				
			||||||
 | 
					    __DRIversion   ddx_version;
 | 
				
			||||||
 | 
					    __DRIversion   dri_version;
 | 
				
			||||||
 | 
					    __DRIversion   drm_version;
 | 
				
			||||||
 | 
					    drmVersionPtr version;
 | 
				
			||||||
 | 
					    const char *driverName;
 | 
				
			||||||
 | 
					    __GLXDRIscreen *screen;
 | 
				
			||||||
 | 
					    char filename[128];
 | 
				
			||||||
 | 
					    size_t buffer_size;
 | 
				
			||||||
 | 
					    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 | 
				
			||||||
 | 
					    unsigned int sareaHandle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    screen = xalloc(sizeof *screen);
 | 
				
			||||||
 | 
					    if (screen == NULL)
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					    memset(screen, 0, sizeof *screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!xf86LoaderCheckSymbol("DRI2Connect") ||
 | 
				
			||||||
 | 
						!DRI2Connect(pScreen,
 | 
				
			||||||
 | 
							     &screen->fd,
 | 
				
			||||||
 | 
							     &driverName,
 | 
				
			||||||
 | 
							     &ddx_version.major,
 | 
				
			||||||
 | 
							     &ddx_version.minor,
 | 
				
			||||||
 | 
							     &ddx_version.patch,
 | 
				
			||||||
 | 
							     &sareaHandle)) {
 | 
				
			||||||
 | 
						LogMessage(X_INFO,
 | 
				
			||||||
 | 
							   "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum);
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    screen->base.destroy        = __glXDRIscreenDestroy;
 | 
				
			||||||
 | 
					    screen->base.createContext  = __glXDRIscreenCreateContext;
 | 
				
			||||||
 | 
					    screen->base.createDrawable = __glXDRIscreenCreateDrawable;
 | 
				
			||||||
 | 
					    screen->base.swapInterval   = __glXDRIdrawableSwapInterval;
 | 
				
			||||||
 | 
					    screen->base.pScreen       = pScreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __glXInitExtensionEnableBits(screen->glx_enable_bits);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* DRI protocol version. */
 | 
				
			||||||
 | 
					    dri_version.major = XF86DRI_MAJOR_VERSION;
 | 
				
			||||||
 | 
					    dri_version.minor = XF86DRI_MINOR_VERSION;
 | 
				
			||||||
 | 
					    dri_version.patch = XF86DRI_PATCH_VERSION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    version = drmGetVersion(screen->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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    snprintf(filename, sizeof filename, "%s/%s_dri.so",
 | 
				
			||||||
 | 
					             dri_driver_path, driverName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
 | 
				
			||||||
 | 
					    if (screen->driver == NULL) {
 | 
				
			||||||
 | 
						LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
 | 
				
			||||||
 | 
							   filename, dlerror());
 | 
				
			||||||
 | 
					        goto handle_error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    createNewScreen = dlsym(screen->driver, CREATE_NEW_SCREEN_FUNC);
 | 
				
			||||||
 | 
					    if (createNewScreen == NULL) {
 | 
				
			||||||
 | 
						LogMessage(X_ERROR, "AIGLX error: dlsym for %s failed (%s)\n",
 | 
				
			||||||
 | 
							   CREATE_NEW_SCREEN_FUNC, dlerror());
 | 
				
			||||||
 | 
					      goto handle_error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    screen->driScreen.private =
 | 
				
			||||||
 | 
						(*createNewScreen)(pScreen->myNum,
 | 
				
			||||||
 | 
								   &screen->driScreen,
 | 
				
			||||||
 | 
								   &ddx_version,
 | 
				
			||||||
 | 
								   &dri_version,
 | 
				
			||||||
 | 
								   &drm_version,
 | 
				
			||||||
 | 
								   screen->fd,
 | 
				
			||||||
 | 
								   sareaHandle,
 | 
				
			||||||
 | 
								   &interface_methods,
 | 
				
			||||||
 | 
								   &screen->base.fbconfigs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (screen->driScreen.private == NULL) {
 | 
				
			||||||
 | 
						LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed");
 | 
				
			||||||
 | 
						goto handle_error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    initializeExtensions(screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __glXScreenInit(&screen->base, pScreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
 | 
				
			||||||
 | 
					    if (buffer_size > 0) {
 | 
				
			||||||
 | 
						if (screen->base.GLXextensions != NULL) {
 | 
				
			||||||
 | 
						    xfree(screen->base.GLXextensions);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen->base.GLXextensions = xnfalloc(buffer_size);
 | 
				
			||||||
 | 
						(void) __glXGetExtensionString(screen->glx_enable_bits, 
 | 
				
			||||||
 | 
									       screen->base.GLXextensions);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    screen->enterVT = pScrn->EnterVT;
 | 
				
			||||||
 | 
					    pScrn->EnterVT = glxDRIEnterVT; 
 | 
				
			||||||
 | 
					    screen->leaveVT = pScrn->LeaveVT;
 | 
				
			||||||
 | 
					    pScrn->LeaveVT = glxDRILeaveVT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogMessage(X_INFO,
 | 
				
			||||||
 | 
						       "AIGLX: Loaded and initialized %s\n", filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return &screen->base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 handle_error:
 | 
				
			||||||
 | 
					    if (screen->driver)
 | 
				
			||||||
 | 
					        dlclose(screen->driver);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xfree(screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__GLXprovider __glXDRI2Provider = {
 | 
				
			||||||
 | 
					    __glXDRIscreenProbe,
 | 
				
			||||||
 | 
					    "DRI2",
 | 
				
			||||||
 | 
					    NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -280,6 +280,30 @@ void GlxSetVisualConfigs(int nconfigs,
 | 
				
			||||||
     * call it. */
 | 
					     * call it. */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					filterOutNativeConfigs(__GLXscreen *pGlxScreen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    __GLcontextModes *m, *next, *native_modes, **last;
 | 
				
			||||||
 | 
					    ScreenPtr pScreen = pGlxScreen->pScreen;
 | 
				
			||||||
 | 
					    int i, depth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    last = &pGlxScreen->fbconfigs;
 | 
				
			||||||
 | 
					    for (m = pGlxScreen->fbconfigs; m != NULL; m = next) {
 | 
				
			||||||
 | 
						next = m->next;
 | 
				
			||||||
 | 
						depth = m->redBits + m->blueBits + m->greenBits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < pScreen->numVisuals; i++) {
 | 
				
			||||||
 | 
						    if (pScreen->visuals[i].nplanes == depth) {
 | 
				
			||||||
 | 
							*last = m;
 | 
				
			||||||
 | 
							last = &m->next;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *last = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static XID
 | 
					static XID
 | 
				
			||||||
findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m)
 | 
					findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -513,6 +537,8 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
 | 
				
			||||||
    pGlxScreen->CloseScreen = pScreen->CloseScreen;
 | 
					    pGlxScreen->CloseScreen = pScreen->CloseScreen;
 | 
				
			||||||
    pScreen->CloseScreen = glxCloseScreen;
 | 
					    pScreen->CloseScreen = glxCloseScreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    filterOutNativeConfigs(pGlxScreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    i = 0;
 | 
					    i = 0;
 | 
				
			||||||
    for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
 | 
					    for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
 | 
				
			||||||
	m->fbconfigID = FakeClientID(0);
 | 
						m->fbconfigID = FakeClientID(0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,6 +125,9 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
 | 
				
			||||||
      provider = LoaderSymbol("__glXDRIProvider");
 | 
					      provider = LoaderSymbol("__glXDRIProvider");
 | 
				
			||||||
      if (provider)
 | 
					      if (provider)
 | 
				
			||||||
	GlxPushProvider(provider);
 | 
						GlxPushProvider(provider);
 | 
				
			||||||
 | 
					      provider = LoaderSymbol("__glXDRI2Provider");
 | 
				
			||||||
 | 
					      if (provider)
 | 
				
			||||||
 | 
						GlxPushProvider(provider);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (xf86Info.glxVisuals) {
 | 
					    switch (xf86Info.glxVisuals) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue