From 0c25ac52425e6d6eb037b99ab90f41b47e3f4491 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Tue, 22 Jul 2008 22:26:26 -0400 Subject: [PATCH] g3dvl: Add Nouveau winsys, libdriclient. Nouveau winsys is based on Mesa's Nouveau winsys and soft-links to most of it. The 'nouveau_context' and 'nouveau_screen' code contains most of the changes, 'nouveau_winsys_pipe', 'nouveau_swapbuffers' and 'nouveau_lock' contain some minor changes. The driclient library contains the DRI userland stuff, most of which was based on Mesa's DRI code. --- src/driclient/include/driclient.h | 98 +++ src/driclient/include/xf86dri.h | 119 ++++ src/driclient/src/Makefile | 22 + src/driclient/src/XF86dri.c | 619 ++++++++++++++++++ src/driclient/src/driclient.c | 292 +++++++++ src/driclient/src/test | Bin 0 -> 68389 bytes src/driclient/src/test.c | 41 ++ src/driclient/src/xf86dri.h | 119 ++++ src/driclient/src/xf86dristr.h | 342 ++++++++++ src/gallium/state_trackers/g3dvl/Makefile | 2 +- src/gallium/state_trackers/g3dvl/vl_context.c | 68 +- .../state_trackers/g3dvl/vl_shader_build.c | 12 + .../state_trackers/g3dvl/vl_shader_build.h | 1 + src/gallium/state_trackers/g3dvl/vl_surface.c | 4 +- src/gallium/winsys/g3dvl/nouveau/Makefile | 46 ++ src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c | 1 + .../winsys/g3dvl/nouveau/nouveau_channel.c | 1 + .../winsys/g3dvl/nouveau/nouveau_context.c | 371 +++++++++++ .../winsys/g3dvl/nouveau/nouveau_context.h | 105 +++ .../winsys/g3dvl/nouveau/nouveau_device.c | 1 + .../winsys/g3dvl/nouveau/nouveau_dma.c | 1 + .../winsys/g3dvl/nouveau/nouveau_dma.h | 1 + .../winsys/g3dvl/nouveau/nouveau_dri.h | 1 + .../winsys/g3dvl/nouveau/nouveau_drmif.h | 1 + .../winsys/g3dvl/nouveau/nouveau_fence.c | 1 + .../winsys/g3dvl/nouveau/nouveau_grobj.c | 1 + .../winsys/g3dvl/nouveau/nouveau_local.h | 1 + .../winsys/g3dvl/nouveau/nouveau_lock.c | 92 +++ .../winsys/g3dvl/nouveau/nouveau_notifier.c | 1 + .../winsys/g3dvl/nouveau/nouveau_pushbuf.c | 1 + .../winsys/g3dvl/nouveau/nouveau_resource.c | 1 + .../winsys/g3dvl/nouveau/nouveau_screen.c | 88 +++ .../winsys/g3dvl/nouveau/nouveau_screen.h | 24 + .../g3dvl/nouveau/nouveau_swapbuffers.c | 64 ++ .../g3dvl/nouveau/nouveau_swapbuffers.h | 10 + .../winsys/g3dvl/nouveau/nouveau_winsys.c | 1 + .../g3dvl/nouveau/nouveau_winsys_pipe.c | 261 ++++++++ .../g3dvl/nouveau/nouveau_winsys_pipe.h | 1 + .../g3dvl/nouveau/nouveau_winsys_softpipe.c | 1 + .../winsys/g3dvl/nouveau/nv04_surface.c | 1 + .../winsys/g3dvl/nouveau/nv50_surface.c | 1 + src/gallium/winsys/g3dvl/vl_winsys.h | 14 + src/gallium/winsys/g3dvl/xsp_winsys.c | 72 +- src/gallium/winsys/g3dvl/xsp_winsys.h | 12 - src/libXvMC/Makefile | 19 +- src/libXvMC/context.c | 4 +- 46 files changed, 2896 insertions(+), 43 deletions(-) create mode 100644 src/driclient/include/driclient.h create mode 100644 src/driclient/include/xf86dri.h create mode 100644 src/driclient/src/Makefile create mode 100644 src/driclient/src/XF86dri.c create mode 100644 src/driclient/src/driclient.c create mode 100755 src/driclient/src/test create mode 100644 src/driclient/src/test.c create mode 100644 src/driclient/src/xf86dri.h create mode 100644 src/driclient/src/xf86dristr.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/Makefile create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_device.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_local.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nv04_surface.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nv50_surface.c create mode 100644 src/gallium/winsys/g3dvl/vl_winsys.h delete mode 100644 src/gallium/winsys/g3dvl/xsp_winsys.h diff --git a/src/driclient/include/driclient.h b/src/driclient/include/driclient.h new file mode 100644 index 00000000000..36438a9f790 --- /dev/null +++ b/src/driclient/include/driclient.h @@ -0,0 +1,98 @@ +#ifndef driclient_h +#define driclient_h + +#include +#include +#include +#include "xf86dri.h" + +/* TODO: Bring in DRI XML options */ + +typedef struct dri_version +{ + int major; + int minor; + int patch; +} dri_version_t; + +typedef struct dri_screen +{ + Display *display; + unsigned int num; + dri_version_t ddx, dri, drm; + int draw_lock_id; + int fd; + drm_sarea_t *sarea; + void *drawable_hash; + void *private; +} dri_screen_t; + +struct dri_context; + +typedef struct dri_drawable +{ + drm_drawable_t drm_drawable; + Drawable x_drawable; + unsigned int sarea_index; + unsigned int *sarea_stamp; + unsigned int last_sarea_stamp; + int x, y, w, h; + int back_x, back_y; + int num_cliprects, num_back_cliprects; + drm_clip_rect_t *cliprects, *back_cliprects; + dri_screen_t *dri_screen; + unsigned int refcount; + void *private; +} dri_drawable_t; + +typedef struct dri_context +{ + XID id; + drm_context_t drm_context; + dri_screen_t *dri_screen; + void *private; +} dri_context_t; + +typedef struct dri_framebuffer +{ + drm_handle_t drm_handle; + int base, size, stride; + int private_size; + void *private; +} dri_framebuffer_t; + +int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf); +int driDestroyScreen(dri_screen_t *dri_screen); +int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable); +int driUpdateDrawableInfo(dri_drawable_t *dri_drawable); +int driDestroyDrawable(dri_drawable_t *dri_drawable); +int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context); +int driDestroyContext(dri_context_t *dri_context); +int driCompareVersions(const dri_version_t *v1, const dri_version_t *v2); + +#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable) \ +do \ +{ \ + if (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp) \ + driUpdateDrawableInfo(dri_drawable); \ +} while (0) + +#define DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable) \ +do \ +{ \ + while (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp) \ + { \ + register unsigned int hwContext = dri_screen->sarea->lock.lock & \ + ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \ + DRM_UNLOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext); \ + \ + DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id); \ + DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable); \ + DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id); \ + \ + DRM_LIGHT_LOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext); \ + } \ +} while (0) + +#endif + diff --git a/src/driclient/include/xf86dri.h b/src/driclient/include/xf86dri.h new file mode 100644 index 00000000000..baf80a7a9dd --- /dev/null +++ b/src/driclient/include/xf86dri.h @@ -0,0 +1,119 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/** + * \file xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin + * \author Jens Owen + * \author Rickard E. (Rik) Faith + */ + +#ifndef _XF86DRI_H_ +#define _XF86DRI_H_ + +#include +#include + +#define X_XF86DRIQueryVersion 0 +#define X_XF86DRIQueryDirectRenderingCapable 1 +#define X_XF86DRIOpenConnection 2 +#define X_XF86DRICloseConnection 3 +#define X_XF86DRIGetClientDriverName 4 +#define X_XF86DRICreateContext 5 +#define X_XF86DRIDestroyContext 6 +#define X_XF86DRICreateDrawable 7 +#define X_XF86DRIDestroyDrawable 8 +#define X_XF86DRIGetDrawableInfo 9 +#define X_XF86DRIGetDeviceInfo 10 +#define X_XF86DRIAuthConnection 11 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ + +#define XF86DRINumberEvents 0 + +#define XF86DRIClientNotLocal 0 +#define XF86DRIOperationNotSupported 1 +#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) + +#ifndef _XF86DRI_SERVER_ + +_XFUNCPROTOBEGIN + +Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); + +Bool XF86DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion, + int *patchVersion ); + +Bool XF86DRIQueryDirectRenderingCapable( Display *dpy, int screen, + Bool *isCapable ); + +Bool XF86DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA, + char **busIDString ); + +Bool XF86DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic ); + +Bool XF86DRICloseConnection( Display *dpy, int screen ); + +Bool XF86DRIGetClientDriverName( Display *dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName ); + +Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool XF86DRIDestroyContext( Display *dpy, int screen, + XID context_id ); + +Bool XF86DRICreateDrawable( Display *dpy, int screen, + Drawable drawable, drm_drawable_t *hHWDrawable ); + +Bool XF86DRIDestroyDrawable( Display *dpy, int screen, + Drawable drawable); + +Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t **pBackClipRects ); + +Bool XF86DRIGetDeviceInfo( Display *dpy, int screen, + drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate ); + +_XFUNCPROTOEND + +#endif /* _XF86DRI_SERVER_ */ + +#endif /* _XF86DRI_H_ */ + diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile new file mode 100644 index 00000000000..0fac552de5b --- /dev/null +++ b/src/driclient/src/Makefile @@ -0,0 +1,22 @@ +TARGET = libdriclient.a +OBJECTS = driclient.o XF86dri.o +DRMDIR ?= /usr + +CFLAGS += -g -Wall -fPIC -Werror -I../include -I${DRMDIR}/include -I${DRMDIR}/include/drm + +############################################# + +.PHONY = all clean + +all: ${TARGET} test + +${TARGET}: ${OBJECTS} + ar rcs $@ $^ + cp ${TARGET} ../lib + +test: test.o + $(CC) -L../lib -L${DRMDIR}/lib ${LDFLAGS} -o $@ $^ -ldriclient -lX11 -lXext -ldrm + +clean: + rm -rf ${OBJECTS} ${TARGET} test test.o + diff --git a/src/driclient/src/XF86dri.c b/src/driclient/src/XF86dri.c new file mode 100644 index 00000000000..9e359a92384 --- /dev/null +++ b/src/driclient/src/XF86dri.c @@ -0,0 +1,619 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Faith + * + */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#define NEED_REPLIES +#include +#include +#include +#include "xf86dristr.h" + +static XExtensionInfo _xf86dri_info_data; +static XExtensionInfo *xf86dri_info = &_xf86dri_info_data; +static char xf86dri_extension_name[] = XF86DRINAME; + +#define XF86DRICheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xf86dri_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int close_display(Display *dpy, XExtCodes *extCodes); +static /* const */ XExtensionHooks xf86dri_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info, + xf86dri_extension_name, + &xf86dri_extension_hooks, + 0, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info) + + +/***************************************************************************** + * * + * public XFree86-DRI Extension routines * + * * + *****************************************************************************/ + +#if 0 +#include +#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg); +#else +#define TRACE(msg) +#endif + +#define PUBLIC + +PUBLIC Bool XF86DRIQueryExtension (dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display (dpy); + + TRACE("QueryExtension..."); + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + TRACE("QueryExtension... return True"); + return True; + } else { + TRACE("QueryExtension... return False"); + return False; + } +} + +PUBLIC Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) + Display* dpy; + int* majorVersion; + int* minorVersion; + int* patchVersion; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIQueryVersionReply rep; + xXF86DRIQueryVersionReq *req; + + TRACE("QueryVersion..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return False"); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + *patchVersion = rep.patchVersion; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return True"); + return True; +} + +PUBLIC Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable) + Display* dpy; + int screen; + Bool* isCapable; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIQueryDirectRenderingCapableReply rep; + xXF86DRIQueryDirectRenderingCapableReq *req; + + TRACE("QueryDirectRenderingCapable..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryDirectRenderingCapable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryDirectRenderingCapable; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return False"); + return False; + } + *isCapable = rep.isCapable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return True"); + return True; +} + +PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString) + Display* dpy; + int screen; + drm_handle_t * hSAREA; + char **busIdString; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIOpenConnectionReply rep; + xXF86DRIOpenConnectionReq *req; + + TRACE("OpenConnection..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIOpenConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIOpenConnection; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + + *hSAREA = rep.hSAREALow; + if (sizeof(drm_handle_t) == 8) { + int shift = 32; /* var to prevent warning on next line */ + *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift; + } + + if (rep.length) { + if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { + _XEatData(dpy, ((rep.busIdStringLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + _XReadPad(dpy, *busIdString, rep.busIdStringLength); + } else { + *busIdString = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return True"); + return True; +} + +PUBLIC Bool XF86DRIAuthConnection(dpy, screen, magic) + Display* dpy; + int screen; + drm_magic_t magic; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIAuthConnectionReq *req; + xXF86DRIAuthConnectionReply rep; + + TRACE("AuthConnection..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIAuthConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIAuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return False"); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return True"); + return True; +} + +PUBLIC Bool XF86DRICloseConnection(dpy, screen) + Display* dpy; + int screen; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRICloseConnectionReq *req; + + TRACE("CloseConnection..."); + + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICloseConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICloseConnection; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CloseConnection... return True"); + return True; +} + +PUBLIC Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, + ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName) + Display* dpy; + int screen; + int* ddxDriverMajorVersion; + int* ddxDriverMinorVersion; + int* ddxDriverPatchVersion; + char** clientDriverName; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIGetClientDriverNameReply rep; + xXF86DRIGetClientDriverNameReq *req; + + TRACE("GetClientDriverName..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetClientDriverName, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetClientDriverName; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + + *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; + *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; + *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; + + if (rep.length) { + if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { + _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); + } else { + *clientDriverName = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return True"); + return True; +} + +PUBLIC Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context, + hHWContext) + Display* dpy; + int screen; + int configID; + XID* context; + drm_context_t * hHWContext; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRICreateContextReply rep; + xXF86DRICreateContextReq *req; + + TRACE("CreateContext..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateContext; + req->visual = configID; + req->screen = screen; + *context = XAllocID(dpy); + req->context = *context; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return False"); + return False; + } + *hHWContext = rep.hHWContext; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return True"); + return True; +} + +PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) + Display* dpy; + int screen; + Visual* visual; + XID* context; + drm_context_t * hHWContext; +{ + return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid, + context, hHWContext ); +} + +PUBLIC Bool XF86DRIDestroyContext( Display * ndpy, int screen, + XID context ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIDestroyContextReq *req; + + TRACE("DestroyContext..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyContext; + req->screen = screen; + req->context = context; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyContext... return True"); + return True; +} + +PUBLIC Bool XF86DRICreateDrawable( Display * ndpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xXF86DRICreateDrawableReply rep; + xXF86DRICreateDrawableReq *req; + + TRACE("CreateDrawable..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateDrawable; + req->screen = screen; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return False"); + return False; + } + *hHWDrawable = rep.hHWDrawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return True"); + return True; +} + +PUBLIC Bool XF86DRIDestroyDrawable( Display * ndpy, int screen, + Drawable drawable ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIDestroyDrawableReq *req; + + TRACE("DestroyDrawable..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyDrawable; + req->screen = screen; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyDrawable... return True"); + return True; +} + +PUBLIC Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable, + unsigned int* index, unsigned int* stamp, + int* X, int* Y, int* W, int* H, + int* numClipRects, drm_clip_rect_t ** pClipRects, + int* backX, int* backY, + int* numBackClipRects, drm_clip_rect_t ** pBackClipRects ) +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIGetDrawableInfoReply rep; + xXF86DRIGetDrawableInfoReq *req; + int total_rects; + + TRACE("GetDrawableInfo..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDrawableInfo; + req->screen = screen; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) + { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } + *index = rep.drawableTableIndex; + *stamp = rep.drawableTableStamp; + *X = (int)rep.drawableX; + *Y = (int)rep.drawableY; + *W = (int)rep.drawableWidth; + *H = (int)rep.drawableHeight; + *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + +#if 0 + /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks + * backwards compatibility (Because of the >> 2 shift) but the fix + * enables multi-threaded apps to work. + */ + if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) { + _XEatData(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } +#endif + + if (*numClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numClipRects); + + *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); + if (*pClipRects) + _XRead(dpy, (char*)*pClipRects, len); + } else { + *pClipRects = NULL; + } + + if (*numBackClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); + + *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); + if (*pBackClipRects) + _XRead(dpy, (char*)*pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return True"); + return True; +} + +PUBLIC Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer, + fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) + Display* dpy; + int screen; + drm_handle_t * hFrameBuffer; + int* fbOrigin; + int* fbSize; + int* fbStride; + int* devPrivateSize; + void** pDevPrivate; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIGetDeviceInfoReply rep; + xXF86DRIGetDeviceInfoReq *req; + + TRACE("GetDeviceInfo..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDeviceInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDeviceInfo; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + + *hFrameBuffer = rep.hFrameBufferLow; + if (sizeof(drm_handle_t) == 8) { + int shift = 32; /* var to prevent warning on next line */ + *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift; + } + + *fbOrigin = rep.framebufferOrigin; + *fbSize = rep.framebufferSize; + *fbStride = rep.framebufferStride; + *devPrivateSize = rep.devPrivateSize; + + if (rep.length) { + if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { + _XEatData(dpy, ((rep.devPrivateSize+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize); + } else { + *pDevPrivate = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return True"); + return True; +} + +PUBLIC Bool XF86DRIOpenFullScreen(dpy, screen, drawable) + Display* dpy; + int screen; + Drawable drawable; +{ + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return False; +} + +PUBLIC Bool XF86DRICloseFullScreen(dpy, screen, drawable) + Display* dpy; + int screen; + Drawable drawable; +{ + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return True; +} + diff --git a/src/driclient/src/driclient.c b/src/driclient/src/driclient.c new file mode 100644 index 00000000000..7a7ca95702a --- /dev/null +++ b/src/driclient/src/driclient.c @@ -0,0 +1,292 @@ +#include "driclient.h" +#include +#include + +int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf) +{ + int evbase, errbase; + char *driver_name; + int newly_opened; + drm_magic_t magic; + drmVersionPtr drm_version; + drm_handle_t sarea_handle; + char *bus_id; + dri_screen_t *dri_scrn; + + assert(display); + assert(dri_screen); + + if (!XF86DRIQueryExtension(display, &evbase, &errbase)) + return 1; + + dri_scrn = calloc(1, sizeof(dri_screen_t)); + + if (!dri_scrn) + return 1; + + if (!XF86DRIQueryVersion(display, &dri_scrn->dri.major, &dri_scrn->dri.minor, &dri_scrn->dri.patch)) + goto free_screen; + + dri_scrn->display = display; + dri_scrn->num = screen; + dri_scrn->draw_lock_id = 1; + + if (!XF86DRIOpenConnection(display, screen, &sarea_handle, &bus_id)) + goto free_screen; + + dri_scrn->fd = -1; + dri_scrn->fd = drmOpenOnce(NULL, bus_id, &newly_opened); + XFree(bus_id); + + if (dri_scrn->fd < 0) + goto close_connection; + + if (drmGetMagic(dri_scrn->fd, &magic)) + goto close_drm; + + drm_version = drmGetVersion(dri_scrn->fd); + + if (!drm_version) + goto close_drm; + + dri_scrn->drm.major = drm_version->version_major; + dri_scrn->drm.minor = drm_version->version_minor; + dri_scrn->drm.patch = drm_version->version_patchlevel; + drmFreeVersion(drm_version); + + if (!XF86DRIAuthConnection(display, screen, magic)) + goto close_drm; + + if (!XF86DRIGetClientDriverName + ( + display, + screen, + &dri_scrn->ddx.major, + &dri_scrn->ddx.minor, + &dri_scrn->ddx.patch, + &driver_name + )) + goto close_drm; + + if (drmMap(dri_scrn->fd, sarea_handle, SAREA_MAX, (drmAddress)&dri_scrn->sarea)) + goto close_drm; + + dri_scrn->drawable_hash = drmHashCreate(); + + if (!dri_scrn->drawable_hash) + goto unmap_sarea; + + if (dri_framebuf) + { + if (!XF86DRIGetDeviceInfo + ( + display, + screen, &dri_framebuf->drm_handle, + &dri_framebuf->base, + &dri_framebuf->size, + &dri_framebuf->stride, + &dri_framebuf->private_size, + &dri_framebuf->private + )) + goto destroy_hash; + } + + *dri_screen = dri_scrn; + + return 0; + +destroy_hash: + drmHashDestroy(dri_scrn->drawable_hash); +unmap_sarea: + drmUnmap(dri_scrn->sarea, SAREA_MAX); +close_drm: + drmCloseOnce(dri_scrn->fd); +close_connection: + XF86DRICloseConnection(display, screen); +free_screen: + free(dri_scrn); + + return 1; +} + +int driDestroyScreen(dri_screen_t *dri_screen) +{ + assert(dri_screen); + + drmHashDestroy(dri_screen->drawable_hash); + drmUnmap(dri_screen->sarea, SAREA_MAX); + drmCloseOnce(dri_screen->fd); + XF86DRICloseConnection(dri_screen->display, dri_screen->num); + free(dri_screen); + + return 0; +} + +int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable) +{ + int evbase, errbase; + dri_drawable_t *dri_draw; + + assert(dri_screen); + assert(dri_drawable); + + if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase)) + return 1; + + if (!drmHashLookup(dri_screen->drawable_hash, drawable, (void**)dri_drawable)) + { + /* Found */ + (*dri_drawable)->refcount++; + return 0; + } + + dri_draw = calloc(1, sizeof(dri_drawable_t)); + + if (!dri_draw) + return 1; + + if (!XF86DRICreateDrawable(dri_screen->display, 0, drawable, &dri_draw->drm_drawable)) + { + free(dri_draw); + return 1; + } + + dri_draw->x_drawable = drawable; + dri_draw->sarea_index = 0; + dri_draw->sarea_stamp = NULL; + dri_draw->last_sarea_stamp = 0; + dri_draw->dri_screen = dri_screen; + dri_draw->refcount = 1; + + if (drmHashInsert(dri_screen->drawable_hash, drawable, dri_draw)) + { + XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable); + free(dri_draw); + return 1; + } + + /* + * XXX: Need this to initialize sarea pointer and other stuff in dri_drawable_t + * to be able to use the DRI_VALIDATE_DRAWABLE_INFO macro, but is it safe to + * call without any sync? + */ + if (driUpdateDrawableInfo(dri_draw)) + { + XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable); + free(dri_draw); + return 1; + } + + *dri_drawable = dri_draw; + + return 0; +} + +int driUpdateDrawableInfo(dri_drawable_t *dri_drawable) +{ + assert(dri_drawable); + + if (dri_drawable->cliprects) + XFree(dri_drawable->cliprects); + if (dri_drawable->back_cliprects) + XFree(dri_drawable->back_cliprects); + + DRM_SPINUNLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id); + + if (!XF86DRIGetDrawableInfo + ( + dri_drawable->dri_screen->display, + dri_drawable->dri_screen->num, + dri_drawable->x_drawable, + &dri_drawable->sarea_index, + &dri_drawable->last_sarea_stamp, + &dri_drawable->x, + &dri_drawable->y, + &dri_drawable->w, + &dri_drawable->h, + &dri_drawable->num_cliprects, + &dri_drawable->cliprects, + &dri_drawable->back_x, + &dri_drawable->back_y, + &dri_drawable->num_back_cliprects, + &dri_drawable->back_cliprects + )) + { + dri_drawable->sarea_stamp = &dri_drawable->last_sarea_stamp; + dri_drawable->num_cliprects = 0; + dri_drawable->cliprects = NULL; + dri_drawable->num_back_cliprects = 0; + dri_drawable->back_cliprects = 0; + + return 1; + } + else + dri_drawable->sarea_stamp = &dri_drawable->dri_screen->sarea->drawableTable[dri_drawable->sarea_index].stamp; + + DRM_SPINLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id); + + return 0; +} + +int driDestroyDrawable(dri_drawable_t *dri_drawable) +{ + assert(dri_drawable); + + if (--dri_drawable->refcount == 0) + { + if (dri_drawable->cliprects) + XFree(dri_drawable->cliprects); + if (dri_drawable->back_cliprects) + XFree(dri_drawable->back_cliprects); + drmHashDelete(dri_drawable->dri_screen->drawable_hash, dri_drawable->x_drawable); + XF86DRIDestroyDrawable(dri_drawable->dri_screen->display, dri_drawable->dri_screen->num, dri_drawable->x_drawable); + free(dri_drawable); + } + + return 0; +} + +int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context) +{ + int evbase, errbase; + dri_context_t *dri_ctx; + + assert(dri_screen); + assert(visual); + assert(dri_context); + + if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase)) + return 1; + + dri_ctx = calloc(1, sizeof(dri_context_t)); + + if (!dri_ctx) + return 1; + + if (!XF86DRICreateContext(dri_screen->display, dri_screen->num, visual, &dri_ctx->id, &dri_ctx->drm_context)) + { + free(dri_ctx); + return 1; + } + + dri_ctx->dri_screen = dri_screen; + *dri_context = dri_ctx; + + return 0; +} + +int driDestroyContext(dri_context_t *dri_context) +{ + assert(dri_context); + + XF86DRIDestroyContext(dri_context->dri_screen->display, dri_context->dri_screen->num, dri_context->id); + free(dri_context); + + return 0; +} + +int driCompareVersions(const dri_version_t *v1, const dri_version_t *v2) +{ + return (v1->major == v2->major) && (v1->minor == v2->minor) && (v1->patch == v2->patch); +} + diff --git a/src/driclient/src/test b/src/driclient/src/test new file mode 100755 index 0000000000000000000000000000000000000000..57cddf8e00ab4cc372d83a3eb4dad5a73b1f6597 GIT binary patch literal 68389 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 +#include +#include "driclient.h" + +int main(int argc, char **argv) +{ + Display *dpy; + Window root, window; + + dri_screen_t *screen; + dri_drawable_t *dri_drawable; + dri_context_t *context; + + dpy = XOpenDisplay(NULL); + root = XDefaultRootWindow(dpy); + window = XCreateSimpleWindow(dpy, root, 0, 0, 100, 100, 0, 0, 0); + + XSelectInput(dpy, window, 0); + XMapWindow(dpy, window); + XSync(dpy, 0); + + assert(driCreateScreen(dpy, 0, &screen, NULL) == 0); + assert(driCreateDrawable(screen, window, &dri_drawable) == 0); + assert(driCreateContext(screen, XDefaultVisual(dpy, 0), &context) == 0); + assert(driUpdateDrawableInfo(dri_drawable) == 0); + + DRI_VALIDATE_DRAWABLE_INFO(screen, dri_drawable); + + assert(drmGetLock(screen->fd, context->drm_context, 0) == 0); + assert(drmUnlock(screen->fd, context->drm_context) == 0); + + assert(driDestroyContext(context) == 0); + assert(driDestroyDrawable(dri_drawable) == 0); + assert(driDestroyScreen(screen) == 0); + + XDestroyWindow(dpy, window); + XCloseDisplay(dpy); + + return 0; +} + diff --git a/src/driclient/src/xf86dri.h b/src/driclient/src/xf86dri.h new file mode 100644 index 00000000000..baf80a7a9dd --- /dev/null +++ b/src/driclient/src/xf86dri.h @@ -0,0 +1,119 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/** + * \file xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin + * \author Jens Owen + * \author Rickard E. (Rik) Faith + */ + +#ifndef _XF86DRI_H_ +#define _XF86DRI_H_ + +#include +#include + +#define X_XF86DRIQueryVersion 0 +#define X_XF86DRIQueryDirectRenderingCapable 1 +#define X_XF86DRIOpenConnection 2 +#define X_XF86DRICloseConnection 3 +#define X_XF86DRIGetClientDriverName 4 +#define X_XF86DRICreateContext 5 +#define X_XF86DRIDestroyContext 6 +#define X_XF86DRICreateDrawable 7 +#define X_XF86DRIDestroyDrawable 8 +#define X_XF86DRIGetDrawableInfo 9 +#define X_XF86DRIGetDeviceInfo 10 +#define X_XF86DRIAuthConnection 11 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ + +#define XF86DRINumberEvents 0 + +#define XF86DRIClientNotLocal 0 +#define XF86DRIOperationNotSupported 1 +#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) + +#ifndef _XF86DRI_SERVER_ + +_XFUNCPROTOBEGIN + +Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); + +Bool XF86DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion, + int *patchVersion ); + +Bool XF86DRIQueryDirectRenderingCapable( Display *dpy, int screen, + Bool *isCapable ); + +Bool XF86DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA, + char **busIDString ); + +Bool XF86DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic ); + +Bool XF86DRICloseConnection( Display *dpy, int screen ); + +Bool XF86DRIGetClientDriverName( Display *dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName ); + +Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool XF86DRIDestroyContext( Display *dpy, int screen, + XID context_id ); + +Bool XF86DRICreateDrawable( Display *dpy, int screen, + Drawable drawable, drm_drawable_t *hHWDrawable ); + +Bool XF86DRIDestroyDrawable( Display *dpy, int screen, + Drawable drawable); + +Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t **pBackClipRects ); + +Bool XF86DRIGetDeviceInfo( Display *dpy, int screen, + drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate ); + +_XFUNCPROTOEND + +#endif /* _XF86DRI_SERVER_ */ + +#endif /* _XF86DRI_H_ */ + diff --git a/src/driclient/src/xf86dristr.h b/src/driclient/src/xf86dristr.h new file mode 100644 index 00000000000..b834bd1a1a0 --- /dev/null +++ b/src/driclient/src/xf86dristr.h @@ -0,0 +1,342 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Fiath + * + */ + +#ifndef _XF86DRISTR_H_ +#define _XF86DRISTR_H_ + +#include "xf86dri.h" + +#define XF86DRINAME "XFree86-DRI" + +/* The DRI version number. This was originally set to be the same of the + * XFree86 version number. However, this version is really indepedent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define XF86DRI_MAJOR_VERSION 4 +#define XF86DRI_MINOR_VERSION 1 +#define XF86DRI_PATCH_VERSION 0 + +typedef struct _XF86DRIQueryVersion { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIQueryVersion */ + CARD16 length B16; +} xXF86DRIQueryVersionReq; +#define sz_xXF86DRIQueryVersionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DRI protocol */ + CARD16 minorVersion B16; /* minor version of DRI protocol */ + CARD32 patchVersion B32; /* patch version of DRI protocol */ + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIQueryVersionReply; +#define sz_xXF86DRIQueryVersionReply 32 + +typedef struct _XF86DRIQueryDirectRenderingCapable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIQueryDirectRenderingCapableReq; +#define sz_xXF86DRIQueryDirectRenderingCapableReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL isCapable; + BOOL pad2; + BOOL pad3; + BOOL pad4; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; + CARD32 pad9 B32; +} xXF86DRIQueryDirectRenderingCapableReply; +#define sz_xXF86DRIQueryDirectRenderingCapableReply 32 + +typedef struct _XF86DRIOpenConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIOpenConnectionReq; +#define sz_xXF86DRIOpenConnectionReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hSAREALow B32; + CARD32 hSAREAHigh B32; + CARD32 busIdStringLength B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xXF86DRIOpenConnectionReply; +#define sz_xXF86DRIOpenConnectionReply 32 + +typedef struct _XF86DRIAuthConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; + CARD32 magic B32; +} xXF86DRIAuthConnectionReq; +#define sz_xXF86DRIAuthConnectionReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIAuthConnectionReply; +#define zx_xXF86DRIAuthConnectionReply 32 + +typedef struct _XF86DRICloseConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRICloseConnectionReq; +#define sz_xXF86DRICloseConnectionReq 8 + +typedef struct _XF86DRIGetClientDriverName { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetClientDriverName */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetClientDriverNameReq; +#define sz_xXF86DRIGetClientDriverNameReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ddxDriverMajorVersion B32; + CARD32 ddxDriverMinorVersion B32; + CARD32 ddxDriverPatchVersion B32; + CARD32 clientDriverNameLength B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIGetClientDriverNameReply; +#define sz_xXF86DRIGetClientDriverNameReply 32 + +typedef struct _XF86DRICreateContext { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 visual B32; + CARD32 context B32; +} xXF86DRICreateContextReq; +#define sz_xXF86DRICreateContextReq 16 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWContext B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateContextReply; +#define sz_xXF86DRICreateContextReply 32 + +typedef struct _XF86DRIDestroyContext { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 context B32; +} xXF86DRIDestroyContextReq; +#define sz_xXF86DRIDestroyContextReq 12 + +typedef struct _XF86DRICreateDrawable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICreateDrawableReq; +#define sz_xXF86DRICreateDrawableReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWDrawable B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateDrawableReply; +#define sz_xXF86DRICreateDrawableReply 32 + +typedef struct _XF86DRIDestroyDrawable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIDestroyDrawableReq; +#define sz_xXF86DRIDestroyDrawableReq 12 + +typedef struct _XF86DRIGetDrawableInfo { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDrawableInfo */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIGetDrawableInfoReq; +#define sz_xXF86DRIGetDrawableInfoReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 drawableTableIndex B32; + CARD32 drawableTableStamp B32; + INT16 drawableX B16; + INT16 drawableY B16; + INT16 drawableWidth B16; + INT16 drawableHeight B16; + CARD32 numClipRects B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; +} xXF86DRIGetDrawableInfoReply; + +#define sz_xXF86DRIGetDrawableInfoReply 36 + + +typedef struct _XF86DRIGetDeviceInfo { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDeviceInfo */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetDeviceInfoReq; +#define sz_xXF86DRIGetDeviceInfoReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hFrameBufferLow B32; + CARD32 hFrameBufferHigh B32; + CARD32 framebufferOrigin B32; + CARD32 framebufferSize B32; + CARD32 framebufferStride B32; + CARD32 devPrivateSize B32; +} xXF86DRIGetDeviceInfoReply; +#define sz_xXF86DRIGetDeviceInfoReply 32 + +typedef struct _XF86DRIOpenFullScreen { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIOpenFullScreenReq; +#define sz_xXF86DRIOpenFullScreenReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isFullScreen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIOpenFullScreenReply; +#define sz_xXF86DRIOpenFullScreenReply 32 + +typedef struct _XF86DRICloseFullScreen { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICloseFullScreenReq; +#define sz_xXF86DRICloseFullScreenReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xXF86DRICloseFullScreenReply; +#define sz_xXF86DRICloseFullScreenReply 32 + + +#endif /* _XF86DRISTR_H_ */ diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile index 50e3c843b55..c6a22cad4e2 100644 --- a/src/gallium/state_trackers/g3dvl/Makefile +++ b/src/gallium/state_trackers/g3dvl/Makefile @@ -2,7 +2,7 @@ TARGET = libg3dvl.a OBJECTS = vl_context.o vl_data.o vl_surface.o vl_shader_build.o vl_util.o GALLIUMDIR = ../.. -CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary +CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary -I${GALLIUMDIR}/winsys/g3dvl ############################################# diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 3d4ca7cf4e2..850a769376e 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -330,6 +330,10 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -354,7 +358,7 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.i_vs = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -432,7 +436,7 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.i_fs = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -499,6 +503,10 @@ static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -527,7 +535,7 @@ static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.p_vs[0] = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -603,6 +611,10 @@ static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -643,7 +655,7 @@ static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.p_vs[1] = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -700,6 +712,10 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -761,7 +777,7 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.p_fs[0] = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -821,6 +837,10 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0-t4 */ + decl = vl_decl_temps(0, 4); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -928,7 +948,7 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.p_fs[1] = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -998,6 +1018,10 @@ static int vlCreateVertexShaderFrameBMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -1030,7 +1054,7 @@ static int vlCreateVertexShaderFrameBMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.b_vs[0] = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -1104,6 +1128,10 @@ static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -1148,7 +1176,7 @@ static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.b_vs[1] = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -1207,6 +1235,10 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0-t2 */ + decl = vl_decl_temps(0, 2); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -1283,7 +1315,7 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.b_fs[0] = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -1346,6 +1378,10 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0-t5 */ + decl = vl_decl_temps(0, 5); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -1479,7 +1515,7 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.b_fs[1] = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -1771,6 +1807,10 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mov o0, i0 ; Move pos in to pos out */ inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -1789,7 +1829,7 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.csc.vertex_shader = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -1839,6 +1879,10 @@ static int vlCreateFragmentShaderCSC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl s0 ; Sampler for tex containing picture to display */ decl = vl_decl_samplers(0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1870,7 +1914,7 @@ static int vlCreateFragmentShaderCSC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.csc.fragment_shader = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.c b/src/gallium/state_trackers/g3dvl/vl_shader_build.c index 365ad697257..1dc5be6fdbb 100644 --- a/src/gallium/state_trackers/g3dvl/vl_shader_build.c +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.c @@ -74,6 +74,18 @@ struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int inde return decl; } +struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + return decl; +} + struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last) { struct tgsi_full_declaration decl = tgsi_default_full_declaration(); diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.h b/src/gallium/state_trackers/g3dvl/vl_shader_build.h index 9e64bbeeae0..878d7e2c457 100644 --- a/src/gallium/state_trackers/g3dvl/vl_shader_build.h +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.h @@ -14,6 +14,7 @@ struct tgsi_full_declaration vl_decl_interpolated_input ); struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last); struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int index, unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last); struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last); struct tgsi_full_instruction vl_inst2 ( diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 145ea32892a..9b91ab4e223 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "vl_context.h" #include "vl_defs.h" #include "vl_util.h" @@ -711,12 +712,13 @@ int vlPutSurface pipe->set_sampler_textures(pipe, 1, &surface->texture); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + bind_pipe_drawable(pipe, drawable); /* TODO: Need to take destx, desty into consideration */ pipe->winsys->flush_frontbuffer ( pipe->winsys, surface->context->states.csc.framebuffer.cbufs[0], - &drawable + pipe->priv ); vlBeginRender(surface->context); diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile new file mode 100644 index 00000000000..644ac083e65 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -0,0 +1,46 @@ +TARGET = libnouveau_dri.so +GALLIUMDIR = ../../.. +DRMDIR ?= /usr +DRIDIR = ../../../../driclient + +OBJECTS = nouveau_bo.o nouveau_fence.o nouveau_swapbuffers.o nouveau_channel.o \ + nouveau_grobj.o nouveau_context.o nouveau_winsys.o nouveau_lock.o \ + nouveau_winsys_pipe.o nouveau_device.o nouveau_notifier.o nouveau_dma.o \ + nouveau_pushbuf.o nouveau_resource.o nouveau_screen.o nv04_surface.o \ + nv50_surface.o #nouveau_winsys_softpipe.o + +CFLAGS += -g -Wall -Werror -fPIC \ + -I${GALLIUMDIR}/include \ + -I${GALLIUMDIR}/winsys/g3dvl \ + -I${DRMDIR}/include \ + -I${DRMDIR}/include/drm \ + -I${GALLIUMDIR}/drivers \ + -I${GALLIUMDIR}/auxiliary \ + -I${DRIDIR}/include + +LDFLAGS += -L${DRMDIR}/lib \ + -L${DRIDIR}/lib \ + -L${GALLIUMDIR}/auxiliary/draw \ + -L${GALLIUMDIR}/auxiliary/tgsi \ + -L${GALLIUMDIR}/auxiliary/translate \ + -L${GALLIUMDIR}/auxiliary/rtasm \ + -L${GALLIUMDIR}/auxiliary/cso_cache \ + -L${GALLIUMDIR}/drivers/nv10 \ + -L${GALLIUMDIR}/drivers/nv30 \ + -L${GALLIUMDIR}/drivers/nv40 \ + -L${GALLIUMDIR}/drivers/nv50 + +LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm + +############################################# + +.PHONY = all clean + +all: ${TARGET} + +${TARGET}: ${OBJECTS} + $(CC) ${LDFLAGS} -shared -o $@ $^ ${LIBS} + +clean: + rm -rf ${OBJECTS} ${TARGET} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c new file mode 120000 index 00000000000..73ac4a4171a --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_bo.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c new file mode 120000 index 00000000000..6c9b2c48d84 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_channel.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c new file mode 100644 index 00000000000..5e173c76728 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c @@ -0,0 +1,371 @@ +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nouveau_context.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +/* +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + { "bo", DEBUG_BO }, + { NULL, 0 } +}; +int __nouveau_debug = 0; +#endif +*/ + +/* + * TODO: Re-examine dri_screen, dri_context, nouveau_screen, nouveau_context + * relationships, seems like there is a lot of room for simplification there. + */ + +static void +nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) +{ + nouveau_grobj_free(&nvc->NvCtxSurf2D); + nouveau_grobj_free(&nvc->NvImageBlit); + nouveau_grobj_free(&nvc->NvGdiRect); + nouveau_grobj_free(&nvc->NvM2MF); + nouveau_grobj_free(&nvc->Nv2D); + nouveau_grobj_free(&nvc->NvSwzSurf); + nouveau_grobj_free(&nvc->NvSIFM); + + nouveau_notifier_free(&nvc->sync_notifier); + + nouveau_channel_free(&nvc->channel); + + FREE(nvc); +} + +static struct nouveau_channel_context * +nouveau_channel_context_create(struct nouveau_device *dev) +{ + struct nouveau_channel_context *nvc; + int ret; + + nvc = CALLOC_STRUCT(nouveau_channel_context); + if (!nvc) + return NULL; + + if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, + &nvc->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + nvc->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, + &nvc->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + ret = nouveau_surface_channel_create_nv50(nvc); + break; + default: + ret = nouveau_surface_channel_create_nv04(nvc); + break; + } + + if (ret) { + NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + return nvc; +} + +int +nouveau_context_create(dri_context_t *dri_context) +{ + dri_screen_t *dri_screen = dri_context->dri_screen; + struct nouveau_screen *nv_screen = dri_screen->private; + struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context); + struct pipe_context *pipe = NULL; + struct nouveau_channel_context *nvc = NULL; + struct nouveau_device *dev = nv_screen->device; + int i; + + switch (dev->chipset & 0xf0) { + case 0x10: + case 0x20: + /* NV10 */ + case 0x30: + /* NV30 */ + case 0x40: + case 0x60: + /* NV40 */ + case 0x50: + case 0x80: + case 0x90: + /* G80 */ + break; + default: + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); + return 1; + } + + dri_context->private = (void*)nv; + nv->dri_context = dri_context; + nv->nv_screen = nv_screen; + + { + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nvdev->ctx = dri_context->drm_context; + nvdev->lock = (drmLock*)&dri_screen->sarea->lock; + } + + /* + driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, + nv->dri_screen->myNum, "nouveau"); +#ifdef DEBUG + __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), + debug_control); +#endif + */ + + /*XXX: Hack up a fake region and buffer object for front buffer. + * This will go away with TTM, replaced with a simple reference + * of the front buffer handle passed to us by the DDX. + */ + { + struct pipe_surface *fb_surf; + struct nouveau_pipe_buffer *fb_buf; + struct nouveau_bo_priv *fb_bo; + + fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); + fb_bo->drm.offset = nv_screen->front_offset; + fb_bo->drm.flags = NOUVEAU_MEM_FB; + fb_bo->drm.size = nv_screen->front_pitch * + nv_screen->front_height; + fb_bo->refcount = 1; + fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; + fb_bo->base.offset = fb_bo->drm.offset; + fb_bo->base.handle = (unsigned long)fb_bo; + fb_bo->base.size = fb_bo->drm.size; + fb_bo->base.device = nv_screen->device; + + fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); + fb_buf->bo = &fb_bo->base; + + fb_surf = calloc(1, sizeof(struct pipe_surface)); + if (nv_screen->front_cpp == 2) + fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; + else + fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; + pf_get_block(fb_surf->format, &fb_surf->block); + fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; + fb_surf->height = nv_screen->front_height; + fb_surf->stride = fb_surf->width * fb_surf->block.size; + fb_surf->refcount = 1; + fb_surf->buffer = &fb_buf->base; + + nv->frontbuffer = fb_surf; + } + + nvc = nv_screen->nvc; + + if (!nvc) { + nvc = nouveau_channel_context_create(dev); + if (!nvc) { + NOUVEAU_ERR("Failed initialising GPU context\n"); + return 1; + } + nv_screen->nvc = nvc; + } + + nvc->refcount++; + nv->nvc = nvc; + + /* Find a free slot for a pipe context, allocate a new one if needed */ + nv->pctx_id = -1; + for (i = 0; i < nvc->nr_pctx; i++) { + if (nvc->pctx[i] == NULL) { + nv->pctx_id = i; + break; + } + } + + if (nv->pctx_id < 0) { + nv->pctx_id = nvc->nr_pctx++; + nvc->pctx = + realloc(nvc->pctx, + sizeof(struct pipe_context *) * nvc->nr_pctx); + } + + /* Create pipe */ + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + if (nouveau_surface_init_nv50(nv)) + return 1; + break; + default: + if (nouveau_surface_init_nv04(nv)) + return 1; + break; + } + + if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { + struct pipe_screen *pscreen; + + pipe = nouveau_pipe_create(nv); + if (!pipe) + NOUVEAU_ERR("Couldn't create hw pipe\n"); + pscreen = nvc->pscreen; + + nv->cap.hw_vertex_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); + nv->cap.hw_index_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); + } + + /* XXX: nouveau_winsys_softpipe needs a mesa header removed before we can compile it. */ + /* + if (!pipe) { + NOUVEAU_MSG("Using softpipe\n"); + pipe = nouveau_create_softpipe(nv); + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return 1; + } + } + */ + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return 1; + } + + pipe->priv = nv; + + return 0; +} + +void +nouveau_context_destroy(dri_context_t *dri_context) +{ + struct nouveau_context *nv = dri_context->private; + struct nouveau_channel_context *nvc = nv->nvc; + + assert(nv); + + if (nv->pctx_id >= 0) { + nvc->pctx[nv->pctx_id] = NULL; + if (--nvc->refcount <= 0) { + nouveau_channel_context_destroy(nvc); + nv->nv_screen->nvc = NULL; + } + } + + free(nv); +} + +int +nouveau_context_bind(struct nouveau_context *nv, dri_drawable_t *dri_drawable) +{ + assert(nv); + assert(dri_drawable); + + if (nv->dri_drawable != dri_drawable) + { + nv->dri_drawable = dri_drawable; + dri_drawable->private = nv; + } + + return 0; +} + +int +nouveau_context_unbind(struct nouveau_context *nv) +{ + assert(nv); + + nv->dri_drawable = NULL; + + return 0; +} + +/* Show starts here */ + +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) +{ + struct nouveau_context *nv; + dri_drawable_t *dri_drawable; + + nv = pipe->priv; + + driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable); + + nouveau_context_bind(nv, dri_drawable); + + return 0; +} + +int unbind_pipe_drawable(struct pipe_context *pipe) +{ + nouveau_context_unbind(pipe->priv); + + return 0; +} + +struct pipe_context* create_pipe_context(Display *display, int screen) +{ + dri_screen_t *dri_screen; + dri_framebuffer_t dri_framebuf; + dri_context_t *dri_context; + struct nouveau_context *nv; + + driCreateScreen(display, screen, &dri_screen, &dri_framebuf); + driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context); + + nouveau_screen_create(dri_screen, &dri_framebuf); + nouveau_context_create(dri_context); + + nv = dri_context->private; + + return nv->nvc->pctx[nv->pctx_id]; +} + +int destroy_pipe_context(struct pipe_context *pipe) +{ + struct pipe_screen *screen; + struct pipe_winsys *winsys; + struct nouveau_context *nv; + dri_screen_t *dri_screen; + dri_context_t *dri_context; + + assert(pipe); + + screen = pipe->screen; + winsys = pipe->winsys; + nv = pipe->priv; + dri_context = nv->dri_context; + dri_screen = dri_context->dri_screen; + + pipe->destroy(pipe); + screen->destroy(screen); + free(winsys); + + nouveau_context_destroy(dri_context); + nouveau_screen_destroy(dri_screen); + driDestroyContext(dri_context); + driDestroyScreen(dri_screen); + + return 0; +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h new file mode 100644 index 00000000000..395a3ab7903 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h @@ -0,0 +1,105 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +/*#include "xmlconfig.h"*/ + +#include +#include "nouveau/nouveau_winsys.h" +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +struct nouveau_channel_context { + struct pipe_screen *pscreen; + int refcount; + + unsigned cur_pctx; + unsigned nr_pctx; + struct pipe_context **pctx; + + struct nouveau_channel *channel; + + struct nouveau_notifier *sync_notifier; + + /* Common */ + struct nouveau_grobj *NvM2MF; + /* NV04-NV40 */ + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvSwzSurf; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvSIFM; + /* G80 */ + struct nouveau_grobj *Nv2D; + + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; +}; + +struct nouveau_context { + /* DRI stuff */ + dri_context_t *dri_context; + dri_drawable_t *dri_drawable; + unsigned int last_stamp; + /*driOptionCache dri_option_cache;*/ + drm_context_t drm_context; + drmLock drm_lock; + int locked; + struct nouveau_screen *nv_screen; + struct pipe_surface *frontbuffer; + + struct { + int hw_vertex_buffer; + int hw_index_buffer; + } cap; + + /* Hardware context */ + struct nouveau_channel_context *nvc; + int pctx_id; + + /* pipe_surface accel */ + struct pipe_surface *surf_src, *surf_dst; + unsigned surf_src_offset, surf_dst_offset; + + int (*surface_copy_prep)(struct nouveau_context *, + struct pipe_surface *dst, + struct pipe_surface *src); + void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h); + void (*surface_copy_done)(struct nouveau_context *); + int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, + unsigned, unsigned, unsigned, unsigned, unsigned); +}; + +extern int nouveau_context_create(dri_context_t *); +extern void nouveau_context_destroy(dri_context_t *); +extern int nouveau_context_bind(struct nouveau_context *, dri_drawable_t *); +extern int nouveau_context_unbind(struct nouveau_context *); + +#ifdef DEBUG +extern int __nouveau_debug; + +#define DEBUG_BO (1 << 0) + +#define DBG(flag, ...) do { \ + if (__nouveau_debug & (DEBUG_##flag)) \ + NOUVEAU_ERR(__VA_ARGS__); \ +} while(0) +#else +#define DBG(flag, ...) +#endif + +extern void LOCK_HARDWARE(struct nouveau_context *); +extern void UNLOCK_HARDWARE(struct nouveau_context *); + +extern int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); +extern int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); +extern int nouveau_surface_init_nv04(struct nouveau_context *); +extern int nouveau_surface_init_nv50(struct nouveau_context *); + +extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); +extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); + +#endif diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c new file mode 120000 index 00000000000..47d52dafa89 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_device.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c new file mode 120000 index 00000000000..45078c964f4 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dma.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h new file mode 120000 index 00000000000..6b9ec777417 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dma.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h new file mode 120000 index 00000000000..0e6c9fce355 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dri.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h new file mode 120000 index 00000000000..473b7d4812d --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_drmif.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c new file mode 120000 index 00000000000..ef1f0c6afe1 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_fence.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c new file mode 120000 index 00000000000..428186544c6 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_grobj.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h new file mode 120000 index 00000000000..6b878aad224 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_local.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c new file mode 100644 index 00000000000..375634bd059 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c @@ -0,0 +1,92 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include +#include "nouveau_context.h" +#include "nouveau_screen.h" + +static pthread_mutex_t lockMutex = PTHREAD_MUTEX_INITIALIZER; + +static void +nouveau_contended_lock(struct nouveau_context *nv, unsigned int flags) +{ + dri_drawable_t *dri_drawable = nv->dri_drawable; + dri_screen_t *dri_screen = nv->dri_context->dri_screen; + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + drmGetLock(nvdev->fd, nvdev->ctx, flags); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + if (dri_drawable) + DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable); +} + +/* Lock the hardware and validate our state. + */ +void +LOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + char __ret=0; + + pthread_mutex_lock(&lockMutex); + assert(!nv->locked); + + DRM_CAS(nvdev->lock, nvdev->ctx, + (DRM_LOCK_HELD | nvdev->ctx), __ret); + + if (__ret) + nouveau_contended_lock(nv, 0); + nv->locked = 1; +} + + +/* Unlock the hardware using the global current context + */ +void +UNLOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + assert(nv->locked); + nv->locked = 0; + + DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); + + pthread_mutex_unlock(&lockMutex); +} diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c new file mode 120000 index 00000000000..3024a612a7a --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_notifier.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c new file mode 120000 index 00000000000..dae31d97998 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_pushbuf.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c new file mode 120000 index 00000000000..e0d71e9d2bf --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_resource.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c new file mode 100644 index 00000000000..0087ce0056b --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c @@ -0,0 +1,88 @@ +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "nouveau_context.h" +#include "nouveau_drm.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#error nouveau_drm.h version does not match expected version +#endif + +/* +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN +DRI_CONF_END; +static const GLuint __driNConfigOptions = 0; +*/ + +int +nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) +{ + /* XXX: Someone forgot to bump this? */ + static const dri_version_t ddx_expected = {0, 0, 10 /*NOUVEAU_DRM_HEADER_PATCHLEVEL*/}; + static const dri_version_t dri_expected = {4, 1, 0}; + static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; + + struct nouveau_dri *nv_dri = dri_framebuf->private; + struct nouveau_screen *nv_screen; + int ret; + + if (!driCompareVersions(&ddx_expected, &dri_screen->ddx)) + { + NOUVEAU_ERR("Unexpected DDX version.\n"); + return 1; + } + + if (!driCompareVersions(&drm_expected, &dri_screen->drm)) + { + NOUVEAU_ERR("Unexpected DRM version.\n"); + return 1; + } + + if (!driCompareVersions(&dri_expected, &dri_screen->dri)) + { + NOUVEAU_ERR("Unexpected DRI version.\n"); + return 1; + } + + if (dri_framebuf->private_size != sizeof(struct nouveau_dri)) { + NOUVEAU_ERR("DRI struct mismatch between DDX/DRI.\n"); + return 1; + } + + nv_screen = CALLOC_STRUCT(nouveau_screen); + if (!nv_screen) + return 1; + nv_screen->dri_screen = dri_screen; + dri_screen->private = (void*)nv_screen; + + /* + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + */ + + if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, + dri_screen->fd, 0))) { + NOUVEAU_ERR("Failed opening nouveau device: %d.\n", ret); + return 1; + } + + nv_screen->front_offset = nv_dri->front_offset; + nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); + nv_screen->front_cpp = nv_dri->bpp / 8; + nv_screen->front_height = nv_dri->height; + + return 0; +} + +void +nouveau_screen_destroy(dri_screen_t *dri_screen) +{ + struct nouveau_screen *nv_screen = dri_screen->private; + + FREE(nv_screen); +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h new file mode 100644 index 00000000000..8a58bb75564 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h @@ -0,0 +1,24 @@ +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +/* TODO: Investigate using DRI options for interesting things */ +/*#include "xmlconfig.h"*/ + +struct nouveau_screen { + dri_screen_t *dri_screen; + struct nouveau_device *device; + struct nouveau_channel_context *nvc; + + uint32_t front_offset; + uint32_t front_pitch; + uint32_t front_cpp; + uint32_t front_height; + + /*driOptionCache option_cache;*/ +}; + +int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf); +void nouveau_screen_destroy(dri_screen_t *dri_screen); + +#endif + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c new file mode 100644 index 00000000000..7916c806151 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c @@ -0,0 +1,64 @@ +#include "pipe/p_context.h" +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +void +nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct nouveau_context *nv = dri_drawable->private; + drm_clip_rect_t *pbox; + int nbox, i; + + LOCK_HARDWARE(nv); + if (!dri_drawable->num_cliprects) { + UNLOCK_HARDWARE(nv); + return; + } + pbox = dri_drawable->cliprects; + nbox = dri_drawable->num_cliprects; + + nv->surface_copy_prep(nv, nv->frontbuffer, surf); + for (i = 0; i < nbox; i++, pbox++) { + int sx, sy, dx, dy, w, h; + + sx = pbox->x1 - dri_drawable->x; + sy = pbox->y1 - dri_drawable->y; + dx = pbox->x1; + dy = pbox->y1; + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + } + + FIRE_RING(nv->nvc->channel); + UNLOCK_HARDWARE(nv); + + //if (nv->last_stamp != dri_drawable->last_sarea_stamp) + //nv->last_stamp = dri_drawable->last_sarea_stamp; +} + +void +nouveau_copy_sub_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, int x, int y, int w, int h) +{ + if (surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = x + w; + rect.y2 = y + h; + + nouveau_copy_buffer(dri_drawable, surf, &rect); + } +} + +void +nouveau_swap_buffers(dri_drawable_t *dri_drawable, struct pipe_surface *surf) +{ + if (surf) + nouveau_copy_buffer(dri_drawable, surf, NULL); +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h new file mode 100644 index 00000000000..35e934adba8 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h @@ -0,0 +1,10 @@ +#ifndef __NOUVEAU_SWAPBUFFERS_H__ +#define __NOUVEAU_SWAPBUFFERS_H__ + +extern void nouveau_copy_buffer(dri_drawable_t *, struct pipe_surface *, + const drm_clip_rect_t *); +extern void nouveau_copy_sub_buffer(dri_drawable_t *, struct pipe_surface *, + int x, int y, int w, int h); +extern void nouveau_swap_buffers(dri_drawable_t *, struct pipe_surface *); + +#endif diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c new file mode 120000 index 00000000000..43de49b98bb --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c new file mode 100644 index 00000000000..b835bd57606 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -0,0 +1,261 @@ +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" +#include "nouveau_winsys_pipe.h" + +static void +nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, + void *context_private) +{ + struct nouveau_context *nv = context_private; + dri_drawable_t *dri_drawable = nv->dri_drawable; + + nouveau_copy_buffer(dri_drawable, surf, NULL); +} + +static const char * +nouveau_get_name(struct pipe_winsys *pws) +{ + return "Nouveau/DRI"; +} + +static struct pipe_surface * +nouveau_surface_alloc(struct pipe_winsys *ws) +{ + struct pipe_surface *surf; + + surf = CALLOC_STRUCT(pipe_surface); + if (!surf) + return NULL; + + surf->refcount = 1; + surf->winsys = ws; + return surf; +} + +/* Borrowed from Mesa's xm_winsys */ +static unsigned int +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +nouveau_surface_alloc_storage +( + struct pipe_winsys *pws, + struct pipe_surface *surface, + unsigned width, + unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage +) +{ + const unsigned int ALIGNMENT = 256; + + assert(pws); + assert(surface); + + surface->width = width; + surface->height = height; + surface->format = format; + pf_get_block(format, &surface->block); + surface->nblocksx = pf_get_nblocksx(&surface->block, width); + surface->nblocksy = pf_get_nblocksy(&surface->block, height); + surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); + surface->usage = flags; + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); + + return 0; +} + +static void +nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + + *s = NULL; + if (--surf->refcount <= 0) { + if (surf->buffer) + pipe_buffer_reference(ws, &surf->buffer, NULL); + free(surf); + } +} + +static struct pipe_buffer * +nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, + unsigned usage, unsigned size) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + uint32_t flags; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.alignment = alignment; + nvbuf->base.usage = usage; + nvbuf->base.size = size; + + flags = NOUVEAU_BO_LOCAL; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) + flags |= NOUVEAU_BO_GART; + flags |= NOUVEAU_BO_VRAM; + } + + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + if (nv->cap.hw_vertex_buffer) + flags |= NOUVEAU_BO_GART; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + if (nv->cap.hw_index_buffer) + flags |= NOUVEAU_BO_GART; + } + + if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) { + free(nvbuf); + return NULL; + } + + return &nvbuf->base; +} + +static struct pipe_buffer * +nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.size = bytes; + + if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) { + free(nvbuf); + return NULL; + } + + return &nvbuf->base; +} + +static void +nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + + nouveau_bo_del(&nvbuf->bo); + free(nvbuf); +} + +static void * +nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + uint32_t map_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + map_flags |= NOUVEAU_BO_RD; + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + map_flags |= NOUVEAU_BO_WR; + + if (nouveau_bo_map(nvbuf->bo, map_flags)) + return NULL; + return nvbuf->bo->map; +} + +static void +nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + + nouveau_bo_unmap(nvbuf->bo); +} + +static INLINE struct nouveau_fence * +nouveau_pipe_fence(struct pipe_fence_handle *pfence) +{ + return (struct nouveau_fence *)pfence; +} + +static void +nouveau_pipe_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ + nouveau_fence_ref((void *)pfence, (void *)ptr); +} + +static int +nouveau_pipe_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + + if (nouveau_fence(fence)->signalled == 0) + nouveau_fence_flush(nvpws->nv->nvc->channel); + + return !nouveau_fence(fence)->signalled; +} + +static int +nouveau_pipe_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(fence, &ref); + return nouveau_fence_wait(&ref); +} + +struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv) +{ + struct nouveau_pipe_winsys *nvpws; + struct pipe_winsys *pws; + + nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); + if (!nvpws) + return NULL; + nvpws->nv = nv; + pws = &nvpws->pws; + + pws->flush_frontbuffer = nouveau_flush_frontbuffer; + + pws->surface_alloc = nouveau_surface_alloc; + pws->surface_alloc_storage = nouveau_surface_alloc_storage; + pws->surface_release = nouveau_surface_release; + + pws->buffer_create = nouveau_pipe_bo_create; + pws->buffer_destroy = nouveau_pipe_bo_del; + pws->user_buffer_create = nouveau_pipe_bo_user_create; + pws->buffer_map = nouveau_pipe_bo_map; + pws->buffer_unmap = nouveau_pipe_bo_unmap; + + pws->fence_reference = nouveau_pipe_fence_reference; + pws->fence_signalled = nouveau_pipe_fence_signalled; + pws->fence_finish = nouveau_pipe_fence_finish; + + pws->get_name = nouveau_get_name; + + return &nvpws->pws; +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h new file mode 120000 index 00000000000..264716fef04 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys_pipe.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c new file mode 120000 index 00000000000..83faccde969 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys_softpipe.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c new file mode 120000 index 00000000000..e05f0671d63 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c @@ -0,0 +1 @@ +../../dri/nouveau/nv04_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c new file mode 120000 index 00000000000..3850748229d --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c @@ -0,0 +1 @@ +../../dri/nouveau/nv50_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h new file mode 100644 index 00000000000..c83db28dd98 --- /dev/null +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -0,0 +1,14 @@ +#ifndef vl_winsys_h +#define vl_winsys_h + +#include + +struct pipe_context; + +struct pipe_context* create_pipe_context(Display *display, int screen); +int destroy_pipe_context(struct pipe_context *pipe); +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable); +int unbind_pipe_drawable(struct pipe_context *pipe); + +#endif + diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index c660c6e0186..0100fe37bdb 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -1,4 +1,4 @@ -#include "xsp_winsys.h" +#include "vl_winsys.h" #include #include #include @@ -11,10 +11,17 @@ struct xsp_pipe_winsys { struct pipe_winsys base; - Display *display; XImage fbimage; }; +struct xsp_context +{ + Display *display; + int screen; + Drawable drawable; + int drawable_bound; +}; + struct xsp_buffer { struct pipe_buffer base; @@ -183,13 +190,18 @@ static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *f static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) { - struct xsp_pipe_winsys *xsp_winsys; + struct xsp_pipe_winsys *xsp_winsys; + struct xsp_context *xsp_context; assert(pws); assert(surface); assert(context_private); xsp_winsys = (struct xsp_pipe_winsys*)pws; + xsp_context = (struct xsp_context*)context_private; + + if (!xsp_context->drawable_bound) + return; xsp_winsys->fbimage.width = surface->width; xsp_winsys->fbimage.height = surface->height; @@ -198,9 +210,9 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface * XPutImage ( - xsp_winsys->display, - *(Drawable*)context_private, - XDefaultGC(xsp_winsys->display, XDefaultScreen(xsp_winsys->display)), + xsp_context->display, + xsp_context->drawable, + XDefaultGC(xsp_context->display, xsp_context->screen), &xsp_winsys->fbimage, 0, 0, @@ -209,7 +221,7 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface * surface->width, surface->height ); - XFlush(xsp_winsys->display); + XFlush(xsp_context->display); pipe_surface_unmap(surface); } @@ -221,11 +233,37 @@ static const char* xsp_get_name(struct pipe_winsys *pws) /* Show starts here */ -struct pipe_context* create_pipe_context(Display *display) +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) +{ + struct xsp_context *xsp_context; + + assert(pipe); + + xsp_context = pipe->priv; + xsp_context->drawable = drawable; + xsp_context->drawable_bound = 1; + + return 0; +} + +int unbind_pipe_drawable(struct pipe_context *pipe) +{ + struct xsp_context *xsp_context; + + assert(pipe); + + xsp_context = pipe->priv; + xsp_context->drawable_bound = 0; + + return 0; +} + +struct pipe_context* create_pipe_context(Display *display, int screen) { struct xsp_pipe_winsys *xsp_winsys; - struct pipe_screen *screen; - struct pipe_context *pipe; + struct xsp_context *xsp_context; + struct pipe_screen *sp_screen; + struct pipe_context *sp_pipe; assert(display); @@ -243,7 +281,6 @@ struct pipe_context* create_pipe_context(Display *display) xsp_winsys->base.fence_finish = xsp_fence_finish; xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; xsp_winsys->base.get_name = xsp_get_name; - xsp_winsys->display = display; { /* XXX: Can't use the returned XImage* directly, @@ -269,10 +306,16 @@ struct pipe_context* create_pipe_context(Display *display) XDestroyImage(template); } - screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); - pipe = softpipe_create(screen, (struct pipe_winsys*)xsp_winsys, NULL); + sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); + sp_pipe = softpipe_create(sp_screen, (struct pipe_winsys*)xsp_winsys, NULL); + + xsp_context = calloc(1, sizeof(struct xsp_context)); + xsp_context->display = display; + xsp_context->screen = screen; + + sp_pipe->priv = xsp_context; - return pipe; + return sp_pipe; } int destroy_pipe_context(struct pipe_context *pipe) @@ -284,6 +327,7 @@ int destroy_pipe_context(struct pipe_context *pipe) screen = pipe->screen; winsys = pipe->winsys; + free(pipe->priv); pipe->destroy(pipe); screen->destroy(screen); free(winsys); diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.h b/src/gallium/winsys/g3dvl/xsp_winsys.h deleted file mode 100644 index cb163dc24d2..00000000000 --- a/src/gallium/winsys/g3dvl/xsp_winsys.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef xsp_winsys_h -#define xsp_winsys_h - -#include - -struct pipe_context; - -struct pipe_context* create_pipe_context(Display *display); -int destroy_pipe_context(struct pipe_context *pipe); - -#endif - diff --git a/src/libXvMC/Makefile b/src/libXvMC/Makefile index 4985ecd3e9d..83fcfc523c1 100644 --- a/src/libXvMC/Makefile +++ b/src/libXvMC/Makefile @@ -1,7 +1,12 @@ TARGET = libXvMCg3dvl.so SONAME = libXvMCg3dvl.so.1 GALLIUMDIR = ../gallium -OBJECTS = block.o surface.o context.o subpicture.o attributes.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o + +OBJECTS = block.o surface.o context.o subpicture.o attributes.o + +ifeq (${DRIVER}, softpipe) +OBJECTS += ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o +endif CFLAGS += -g -fPIC -Wall -Werror \ -I${GALLIUMDIR}/state_trackers/g3dvl \ @@ -9,6 +14,8 @@ CFLAGS += -g -fPIC -Wall -Werror \ -I${GALLIUMDIR}/include \ -I${GALLIUMDIR}/auxiliary \ -I${GALLIUMDIR}/drivers + +ifeq (${DRIVER}, softpipe) LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ -L${GALLIUMDIR}/drivers/softpipe \ -L${GALLIUMDIR}/auxiliary/tgsi \ @@ -17,7 +24,17 @@ LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ -L${GALLIUMDIR}/auxiliary/cso_cache \ -L${GALLIUMDIR}/auxiliary/util \ -L${GALLIUMDIR}/auxiliary/rtasm +else +LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ + -L${GALLIUMDIR}/winsys/g3dvl/nouveau \ + -L${GALLIUMDIR}/auxiliary/util +endif + +ifeq (${DRIVER}, softpipe) LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil -lm +else +LIBS += -lg3dvl -lnouveau_dri -lutil +endif ############################################# diff --git a/src/libXvMC/context.c b/src/libXvMC/context.c index 22eadc1889b..59e1cb2b256 100644 --- a/src/libXvMC/context.c +++ b/src/libXvMC/context.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include static Status Validate(Display *display, XvPortID port, int surface_type_id, unsigned int width, unsigned int height, int flags, int *chroma_format) { @@ -117,7 +117,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i if (ret != Success) return ret; - pipe = create_pipe_context(display); + pipe = create_pipe_context(display, XDefaultScreen(display)); assert(pipe); -- 2.30.2