Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver into input-hotplug

This commit is contained in:
Daniel Stone 2006-11-02 03:15:25 +02:00 committed by Daniel Stone
commit be291a6d97
10 changed files with 1241 additions and 30 deletions

View File

@ -60,6 +60,7 @@ nodist_libmain_la_SOURCES = accum.c \
light.c \ light.c \
lines.c \ lines.c \
matrix.c \ matrix.c \
mipmap.c \
mm.c \ mm.c \
occlude.c \ occlude.c \
pixel.c \ pixel.c \

View File

@ -49,7 +49,8 @@ dnl xwin-config.h covers the XWin DDX.
AC_CONFIG_HEADERS(include/xwin-config.h) AC_CONFIG_HEADERS(include/xwin-config.h)
dnl kdrive-config.h covers the kdrive DDX dnl kdrive-config.h covers the kdrive DDX
AC_CONFIG_HEADERS(include/kdrive-config.h) AC_CONFIG_HEADERS(include/kdrive-config.h)
dnl libdrm now needs 64-bit file offsets
AC_CONFIG_HEADERS(include/libdrm-config.h)
AC_PROG_CC AC_PROG_CC
AM_PROG_AS AM_PROG_AS
@ -62,6 +63,7 @@ AC_PROG_MAKE_SET
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG
AC_PROG_LEX AC_PROG_LEX
AC_PROG_YACC AC_PROG_YACC
AC_SYS_LARGEFILE
XORG_PROG_RAWCPP XORG_PROG_RAWCPP
AC_HEADER_DIRENT AC_HEADER_DIRENT
@ -889,7 +891,7 @@ PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS])
PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS]) PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}" XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm" XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
AC_SUBST([SYS_LIBS]) AC_SUBST([SYS_LIBS])
# The Xorg binary needs to export symbols so that they can be used from modules # The Xorg binary needs to export symbols so that they can be used from modules
@ -923,9 +925,9 @@ AC_MSG_CHECKING([for a useful monotonic clock ...])
if ! test "x$have_clock_gettime" = xno; then if ! test "x$have_clock_gettime" = xno; then
if ! test "x$have_clock_gettime" = xyes; then if ! test "x$have_clock_gettime" = xyes; then
LIBS="$have_clock_gettime" CLOCK_LIBS="$have_clock_gettime"
else else
LIBS="" CLOCK_LIBS=""
fi fi
AC_RUN_IFELSE([ AC_RUN_IFELSE([
@ -950,7 +952,8 @@ AC_MSG_RESULT([$MONOTONIC_CLOCK])
if test "x$MONOTONIC_CLOCK" = xyes; then if test "x$MONOTONIC_CLOCK" = xyes; then
AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()]) AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()])
XSERVER_LIBS="$XSERVER_LIBS $LIBS" XSERVER_LIBS="$XSERVER_LIBS $CLOCK_LIBS"
LIBS="$LIBS $CLOCK_LIBS"
fi fi
dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so
@ -1028,7 +1031,7 @@ AC_MSG_RESULT([$XVFB])
AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes]) AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes])
if test "x$XVFB" = xyes; then if test "x$XVFB" = xyes; then
XVFB_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB" XVFB_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XVFB_LIBS]) AC_SUBST([XVFB_LIBS])
fi fi
@ -1044,7 +1047,7 @@ AC_MSG_RESULT([$XNEST])
AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes]) AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
if test "x$XNEST" = xyes; then if test "x$XNEST" = xyes; then
XNEST_LIBS="$XSERVER_LIBS $FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB" XNEST_LIBS="$XSERVER_LIBS $FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XNEST_LIBS]) AC_SUBST([XNEST_LIBS])
fi fi
@ -1394,7 +1397,7 @@ AC_MSG_RESULT([$XPRINT])
if test "x$XPRINT" = xyes; then if test "x$XPRINT" = xyes; then
PKG_CHECK_MODULES([XPRINT], [printproto x11 xfont $XDMCP_MODULES xau]) PKG_CHECK_MODULES([XPRINT], [printproto x11 xfont $XDMCP_MODULES xau])
XPRINT_EXTENSIONS="$XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $RENDER_LIB $COMPOSITE_LIB $RANDR_LIB $XI_LIB $FIXES_LIB $DAMAGE_LIB $XI_LIB $GLX_LIBS" XPRINT_EXTENSIONS="$XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $RENDER_LIB $COMPOSITE_LIB $RANDR_LIB $XI_LIB $FIXES_LIB $DAMAGE_LIB $XI_LIB $GLX_LIBS"
XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $CONFIG_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB" XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $CONFIG_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XPRINT_CFLAGS]) AC_SUBST([XPRINT_CFLAGS])
AC_SUBST([XPRINT_LIBS]) AC_SUBST([XPRINT_LIBS])

View File

@ -930,9 +930,8 @@ fbComposite (CARD8 op,
case PictOpOver: case PictOpOver:
if (pMask) if (pMask)
{ {
if (srcRepeat && if (fbCanGetSolid(pSrc) &&
pSrc->pDrawable->width == 1 && !maskRepeat)
pSrc->pDrawable->height == 1)
{ {
srcRepeat = FALSE; srcRepeat = FALSE;
if (PICT_FORMAT_COLOR(pSrc->format)) { if (PICT_FORMAT_COLOR(pSrc->format)) {
@ -1044,7 +1043,7 @@ fbComposite (CARD8 op,
{ {
if (pSrc->pDrawable == pMask->pDrawable && if (pSrc->pDrawable == pMask->pDrawable &&
xSrc == xMask && ySrc == yMask && xSrc == xMask && ySrc == yMask &&
!pMask->componentAlpha) !pMask->componentAlpha && !maskRepeat)
{ {
/* source == mask: non-premultiplied data */ /* source == mask: non-premultiplied data */
switch (pSrc->format) { switch (pSrc->format) {
@ -1108,9 +1107,7 @@ fbComposite (CARD8 op,
else else
{ {
/* non-repeating source, repeating mask => translucent window */ /* non-repeating source, repeating mask => translucent window */
if (maskRepeat && if (fbCanGetSolid(pMask))
pMask->pDrawable->width == 1 &&
pMask->pDrawable->height == 1)
{ {
if (pSrc->format == PICT_x8r8g8b8 && if (pSrc->format == PICT_x8r8g8b8 &&
pDst->format == PICT_x8r8g8b8 && pDst->format == PICT_x8r8g8b8 &&
@ -1127,9 +1124,7 @@ fbComposite (CARD8 op,
} }
else /* no mask */ else /* no mask */
{ {
if (srcRepeat && if (fbCanGetSolid(pSrc))
pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1)
{ {
/* no mask and repeating source */ /* no mask and repeating source */
switch (pSrc->format) { switch (pSrc->format) {

View File

@ -30,6 +30,13 @@
#include "renderedge.h" #include "renderedge.h"
#if defined(__GNUC__)
#define INLINE __inline__
#else
#define INLINE
#endif
#define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) ) #define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
#define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b)) #define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b))
@ -67,6 +74,40 @@
#define Green(x) (((x) >> 8) & 0xff) #define Green(x) (((x) >> 8) & 0xff)
#define Blue(x) ((x) & 0xff) #define Blue(x) ((x) & 0xff)
/**
* Returns TRUE if the fbComposeGetSolid can be used to get a single solid
* color representing every source sampling location of the picture.
*/
static INLINE Bool
fbCanGetSolid(PicturePtr pict)
{
if (pict->pDrawable == NULL ||
pict->pDrawable->width != 1 ||
pict->pDrawable->height != 1)
{
return FALSE;
}
if (pict->repeat != RepeatNormal)
return FALSE;
switch (pict->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
case PICT_r8g8b8:
case PICT_b8g8r8:
case PICT_r5g6b5:
case PICT_b5g6r5:
return TRUE;
default:
return FALSE;
}
}
#define fbCanGetSolid(pict) \
(pict->pDrawable != NULL && pict->pDrawable->width == 1 && pict->pDrawable->height == 1)
#define fbComposeGetSolid(pict, bits, fmt) { \ #define fbComposeGetSolid(pict, bits, fmt) { \
FbBits *__bits__; \ FbBits *__bits__; \
FbStride __stride__; \ FbStride __stride__; \
@ -322,12 +363,6 @@
#define FASTCALL #define FASTCALL
#endif #endif
#if defined(__GNUC__)
#define INLINE __inline__
#else
#define INLINE
#endif
typedef struct _FbComposeData { typedef struct _FbComposeData {
CARD8 op; CARD8 op;
PicturePtr src; PicturePtr src;

View File

@ -58,12 +58,15 @@ Xorg_LDADD = $(XORG_LIBS) \
Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
BUILT_SOURCES = xorg.conf.example
CLEAN = xorg.conf.example xorg.conf.example.pre
EXTRA_DIST = xorgconf.cpp
if SOLARIS_ASM_INLINE if SOLARIS_ASM_INLINE
# Needs to be built before any files are compiled when using Sun compilers # Needs to be built before any files are compiled when using Sun compilers
# so in*/out* inline definitions are properly processed. # so in*/out* inline definitions are properly processed.
BUILT_SOURCES = os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il BUILT_SOURCES += os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il
os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il: os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il:
cd os-support/solaris ; make solaris-$(SOLARIS_INOUT_ARCH).il cd os-support/solaris ; make solaris-$(SOLARIS_INOUT_ARCH).il
@ -84,10 +87,6 @@ endif
optionsdir = $(libdir)/X11 optionsdir = $(libdir)/X11
dist_options_DATA = Options dist_options_DATA = Options
BUILT_SOURCES = xorg.conf.example
CLEAN = xorg.conf.example xorg.conf.example.pre
EXTRA_DIST = xorgconf.cpp
CPP_FILES_FLAGS = \ CPP_FILES_FLAGS = \
-DRGBPATH=\"$(RGB_DB)\" \ -DRGBPATH=\"$(RGB_DB)\" \
-DLOCALFONTPATH="\"$(BASE_FONT_PATH)/local\"" \ -DLOCALFONTPATH="\"$(BASE_FONT_PATH)/local\"" \
@ -103,4 +102,4 @@ relink:
rm -f Xorg && $(MAKE) Xorg rm -f Xorg && $(MAKE) Xorg
xorg.conf.example.pre: xorgconf.cpp xorg.conf.example.pre: xorgconf.cpp
cp $< $@ cp $(srcdir)/xorgconf.cpp $@

View File

@ -33,6 +33,7 @@
#ifdef HAVE_XORG_CONFIG_H #ifdef HAVE_XORG_CONFIG_H
#include <libdrm-config.h>
#include <xorg-config.h> #include <xorg-config.h>
#endif #endif
@ -2305,3 +2306,957 @@ int drmRemoveSIGIOHandler(int fd)
return xf86RemoveSIGIOHandler(fd); return xf86RemoveSIGIOHandler(fd);
} }
/*
* Valid flags are
* DRM_FENCE_FLAG_EMIT
* DRM_FENCE_FLAG_SHAREABLE
* DRM_FENCE_MASK_DRIVER
*/
int drmFenceCreate(int fd, unsigned flags, int class,unsigned type,
drmFence *fence)
{
drm_fence_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.type = type;
arg.class = class;
arg.op = drm_fence_create;
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
return -errno;
fence->handle = arg.handle;
fence->class = arg.class;
fence->type = arg.type;
fence->flags = arg.flags;
fence->signaled = 0;
return 0;
}
/*
* Valid flags are
* DRM_FENCE_FLAG_SHAREABLE
* DRM_FENCE_MASK_DRIVER
*/
int drmFenceBuffers(int fd, unsigned flags, drmFence *fence)
{
drm_fence_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.flags = flags;
arg.op = drm_fence_buffers;
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
return -errno;
fence->handle = arg.handle;
fence->class = arg.class;
fence->type = arg.type;
fence->flags = arg.flags;
fence->signaled = 0;
return 0;
}
int drmFenceDestroy(int fd, const drmFence *fence)
{
drm_fence_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
arg.op = drm_fence_destroy;
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
return -errno;
return 0;
}
int drmFenceReference(int fd, unsigned handle, drmFence *fence)
{
drm_fence_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.handle = handle;
arg.op = drm_fence_reference;
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
return -errno;
fence->handle = arg.handle;
fence->class = arg.class;
fence->type = arg.type;
fence->flags = arg.flags;
fence->signaled = arg.signaled;
return 0;
}
int drmFenceUnreference(int fd, const drmFence *fence)
{
drm_fence_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
arg.op = drm_fence_unreference;
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
return -errno;
return 0;
}
int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type)
{
drm_fence_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
arg.type = flush_type;
arg.op = drm_fence_flush;
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
return -errno;
fence->class = arg.class;
fence->type = arg.type;
fence->signaled = arg.signaled;
return 0;
}
int drmFenceUpdate(int fd, drmFence *fence)
{
drm_fence_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
arg.op = drm_fence_signaled;
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
return -errno;
fence->class = arg.class;
fence->type = arg.type;
fence->signaled = arg.signaled;
return 0;
}
int drmFenceSignaled(int fd, drmFence *fence, unsigned fenceType,
int *signaled)
{
int
ret;
if ((fence->flags & DRM_FENCE_FLAG_SHAREABLE) ||
((fenceType & fence->signaled) != fenceType)) {
ret = drmFenceFlush(fd, fence, fenceType);
if (ret)
return ret;
}
*signaled = ((fenceType & fence->signaled) == fenceType);
return 0;
}
/*
* Valid flags are
* DRM_FENCE_FLAG_SHAREABLE
* DRM_FENCE_MASK_DRIVER
*/
int drmFenceEmit(int fd, unsigned flags, drmFence *fence, unsigned emit_type)
{
drm_fence_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.flags = flags;
arg.handle = fence->handle;
arg.type = emit_type;
arg.op = drm_fence_emit;
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
return -errno;
fence->class = arg.class;
fence->type = arg.type;
fence->signaled = arg.signaled;
return 0;
}
/*
* Valid flags are
* DRM_FENCE_FLAG_WAIT_LAZY
* DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS
*/
int drmFenceWait(int fd, unsigned flags, drmFence *fence, unsigned flush_type)
{
drm_fence_arg_t arg;
int ret;
if (flush_type == 0) {
flush_type = fence->type;
}
if (!(fence->flags & DRM_FENCE_FLAG_SHAREABLE)) {
if ((flush_type & fence->signaled) == flush_type) {
return 0;
}
}
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
arg.type = flush_type;
arg.flags = flags;
arg.op = drm_fence_wait;
do {
ret = ioctl(fd, DRM_IOCTL_FENCE, &arg);
} while (ret != 0 && errno == EAGAIN);
if (ret)
return -errno;
fence->class = arg.class;
fence->type = arg.type;
fence->signaled = arg.signaled;
return 0;
}
static int drmAdjustListNodes(drmBOList *list)
{
drmBONode *node;
drmMMListHead *l;
int ret = 0;
while(list->numCurrent < list->numTarget) {
node = (drmBONode *) malloc(sizeof(*node));
if (!node) {
ret = -ENOMEM;
break;
}
list->numCurrent++;
DRMLISTADD(&node->head, &list->free);
}
while(list->numCurrent > list->numTarget) {
l = list->free.next;
if (l == &list->free)
break;
DRMLISTDEL(l);
node = DRMLISTENTRY(drmBONode, l, head);
free(node);
list->numCurrent--;
}
return ret;
}
void drmBOFreeList(drmBOList *list)
{
drmBONode *node;
drmMMListHead *l;
l = list->list.next;
while(l != &list->list) {
DRMLISTDEL(l);
node = DRMLISTENTRY(drmBONode, l, head);
free(node);
l = list->free.next;
list->numCurrent--;
list->numOnList--;
}
l = list->free.next;
while(l != &list->free) {
DRMLISTDEL(l);
node = DRMLISTENTRY(drmBONode, l, head);
free(node);
l = list->free.next;
list->numCurrent--;
}
}
int drmBOResetList(drmBOList *list) {
drmMMListHead *l;
int ret;
ret = drmAdjustListNodes(list);
if (ret)
return ret;
l = list->list.next;
while(l != &list->list) {
DRMLISTDEL(l);
DRMLISTADD(l, &list->free);
list->numOnList--;
l = list->list.next;
}
return drmAdjustListNodes(list);
}
static drmBONode *drmAddListItem(drmBOList *list, drmBO *item,
unsigned long arg0,
unsigned long arg1)
{
drmBONode *node;
drmMMListHead *l;
l = list->free.next;
if (l == &list->free) {
node = (drmBONode *) malloc(sizeof(*node));
if (!node) {
return NULL;
}
list->numCurrent++;
} else {
DRMLISTDEL(l);
node = DRMLISTENTRY(drmBONode, l, head);
}
node->buf = item;
node->arg0 = arg0;
node->arg1 = arg1;
DRMLISTADD(&node->head, &list->list);
list->numOnList++;
return node;
}
void *drmBOListIterator(drmBOList *list)
{
void *ret = list->list.next;
if (ret == &list->list)
return NULL;
return ret;
}
void *drmBOListNext(drmBOList *list, void *iterator)
{
void *ret;
drmMMListHead *l = (drmMMListHead *) iterator;
ret = l->next;
if (ret == &list->list)
return NULL;
return ret;
}
drmBO *drmBOListBuf(void *iterator)
{
drmBONode *node;
drmMMListHead *l = (drmMMListHead *) iterator;
node = DRMLISTENTRY(drmBONode, l, head);
return node->buf;
}
int drmBOCreateList(int numTarget, drmBOList *list)
{
DRMINITLISTHEAD(&list->list);
DRMINITLISTHEAD(&list->free);
list->numTarget = numTarget;
list->numCurrent = 0;
list->numOnList = 0;
return drmAdjustListNodes(list);
}
static void drmBOCopyReply(const drm_bo_arg_reply_t *rep,
drmBO *buf)
{
buf->handle = rep->handle;
buf->flags = rep->flags;
buf->size = rep->size;
buf->offset = rep->offset;
buf->mapHandle = rep->arg_handle;
buf->mask = rep->mask;
buf->start = rep->buffer_start;
buf->fenceFlags = rep->fence_flags;
buf->replyFlags = rep->rep_flags;
buf->pageAlignment = rep->page_alignment;
}
int drmBOCreate(int fd, unsigned long start, unsigned long size,
unsigned pageAlignment, void *user_buffer, drm_bo_type_t type,
unsigned mask,
unsigned hint, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
int ret;
memset(buf, 0, sizeof(*buf));
memset(&arg, 0, sizeof(arg));
req->mask = mask;
req->hint = hint;
req->size = size;
req->type = type;
req->page_alignment = pageAlignment;
buf->virtual = NULL;
switch(type) {
case drm_bo_type_dc:
req->buffer_start = start;
break;
case drm_bo_type_user:
req->buffer_start = (unsigned long) user_buffer;
buf->virtual = user_buffer;
break;
case drm_bo_type_fake:
req->buffer_start = start;
break;
default:
return -EINVAL;
}
req->op = drm_bo_create;
do {
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
} while (ret != 0 && errno == EAGAIN);
if (ret)
return -errno;
if (!arg.handled) {
return -EFAULT;
}
if (rep->ret) {
fprintf(stderr, "Error %d\n", rep->ret);
return rep->ret;
}
drmBOCopyReply(rep, buf);
buf->mapVirtual = NULL;
buf->mapCount = 0;
return 0;
}
int drmBODestroy(int fd, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
(void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
buf->mapVirtual = NULL;
buf->virtual = NULL;
}
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
req->op = drm_bo_destroy;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
if (!arg.handled) {
return -EFAULT;
}
if (rep->ret) {
return rep->ret;
}
buf->handle = 0;
return 0;
}
int drmBOReference(int fd, unsigned handle, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
memset(&arg, 0, sizeof(arg));
req->handle = handle;
req->op = drm_bo_reference;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
if (!arg.handled) {
return -EFAULT;
}
if (rep->ret) {
return rep->ret;
}
drmBOCopyReply(rep, buf);
buf->type = drm_bo_type_dc;
buf->mapVirtual = NULL;
buf->mapCount = 0;
buf->virtual = NULL;
return 0;
}
int drmBOUnReference(int fd, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
(void) munmap(buf->mapVirtual, buf->start + buf->size);
buf->mapVirtual = NULL;
buf->virtual = NULL;
}
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
req->op = drm_bo_unreference;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
if (!arg.handled) {
return -EFAULT;
}
if (rep->ret) {
return rep->ret;
}
buf->handle = 0;
return 0;
}
/*
* Flags can be DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE or'ed together
* Hint currently be DRM_BO_HINT_DONT_BLOCK, which makes the
* call return an -EBUSY if it can' immediately honor the mapping request.
*/
int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
void **address)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
int ret = 0;
/*
* Make sure we have a virtual address of the buffer.
*/
if (!buf->virtual && buf->type != drm_bo_type_fake) {
drmAddress virtual;
virtual = mmap(0, buf->size + buf->start,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf->mapHandle);
if (virtual == MAP_FAILED) {
ret = -errno;
}
if (ret)
return ret;
buf->mapVirtual = virtual;
buf->virtual = ((char *) virtual) + buf->start;
}
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
req->mask = mapFlags;
req->hint = mapHint;
req->op = drm_bo_map;
/*
* May hang if the buffer object is busy.
* This IOCTL synchronizes the buffer.
*/
do {
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
} while (ret != 0 && errno == EAGAIN);
if (ret)
return ret;
if (!arg.handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
drmBOCopyReply(rep, buf);
buf->mapFlags = mapFlags;
++buf->mapCount;
*address = buf->virtual;
return 0;
}
int drmBOUnmap(int fd, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
req->op = drm_bo_unmap;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) {
return -errno;
}
if (!arg.handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
return 0;
}
int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
unsigned hint)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
int ret = 0;
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
req->mask = flags;
req->hint = hint;
req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */
req->op = drm_bo_validate;
do{
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
} while (ret && errno == EAGAIN);
if (ret)
return ret;
if (!arg.handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
drmBOCopyReply(rep, buf);
return 0;
}
int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
int ret = 0;
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
req->mask = flags;
req->arg_handle = fenceHandle;
req->op = drm_bo_validate;
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
if (ret)
return ret;
if (!arg.handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
return 0;
}
int drmBOInfo(int fd, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
int ret = 0;
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
req->op = drm_bo_info;
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
if (ret)
return ret;
if (!arg.handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
drmBOCopyReply(rep, buf);
return 0;
}
int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.d.req;
drm_bo_arg_reply_t *rep = &arg.d.rep;
int ret = 0;
if ((buf->flags & DRM_BO_FLAG_SHAREABLE) ||
(buf->replyFlags & DRM_BO_REP_BUSY)) {
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
req->op = drm_bo_wait_idle;
req->hint = hint;
do {
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
} while (ret && errno == EAGAIN);
if (ret)
return ret;
if (!arg.handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
drmBOCopyReply(rep, buf);
}
return 0;
}
int drmBOBusy(int fd, drmBO *buf, int *busy)
{
if (!(buf->flags & DRM_BO_FLAG_SHAREABLE) &&
!(buf->replyFlags & DRM_BO_REP_BUSY)) {
*busy = 0;
return 0;
} else {
int ret = drmBOInfo(fd, buf);
if (ret)
return ret;
*busy = (buf->replyFlags & DRM_BO_REP_BUSY);
return 0;
}
}
int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
unsigned mask,
int *newItem)
{
drmBONode *node, *cur;
drmMMListHead *l;
*newItem = 0;
cur = NULL;
for (l = list->list.next; l != &list->list; l = l->next) {
node = DRMLISTENTRY(drmBONode, l, head);
if (node->buf == buf) {
cur = node;
break;
}
}
if (!cur) {
cur = drmAddListItem(list, buf, flags, mask);
if (!cur) {
drmMsg("Out of memory creating validate list node.\n");
return -ENOMEM;
}
*newItem = 1;
cur->arg0 = flags;
cur->arg1 = mask;
} else {
unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM;
unsigned memFlags = cur->arg0 & flags & memMask;
if (!memFlags) {
drmMsg("Incompatible memory location requests "
"on validate list.\n");
drmMsg("Previous flag: 0x%08lx, mask: 0x%08lx\n",
cur->arg0, cur->arg1);
drmMsg("Current flag: 0x%08lx, mask: 0x%08lx\n",
flags, mask);
return -EINVAL;
}
if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
drmMsg("Incompatible buffer flag requests "
"on validate list.\n");
drmMsg("Previous flag: 0x%08lx, mask: 0x%08lx\n",
cur->arg0, cur->arg1);
drmMsg("Current flag: 0x%08lx, mask: 0x%08lx\n",
flags, mask);
return -EINVAL;
}
cur->arg1 |= mask;
cur->arg0 = memFlags | ((cur->arg0 | flags) &
cur->arg1 & ~DRM_BO_MASK_MEM);
}
return 0;
}
int drmBOValidateList(int fd, drmBOList *list)
{
drmBONode *node;
drmMMListHead *l;
drm_bo_arg_t *arg, *first;
drm_bo_arg_request_t *req;
drm_bo_arg_reply_t *rep;
drm_u64_t *prevNext = NULL;
drmBO *buf;
int ret;
first = NULL;
for (l = list->list.next; l != &list->list; l = l->next) {
node = DRMLISTENTRY(drmBONode, l, head);
arg = &node->bo_arg;
req = &arg->d.req;
if (!first)
first = arg;
if (prevNext)
*prevNext = (unsigned long) arg;
memset(arg, 0, sizeof(*arg));
prevNext = &arg->next;
req->handle = node->buf->handle;
req->op = drm_bo_validate;
req->mask = node->arg0;
req->hint = 0;
req->arg_handle = node->arg1;
}
if (!first)
return 0;
do{
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
} while (ret && errno == EAGAIN);
if (ret)
return -errno;
for (l = list->list.next; l != &list->list; l = l->next) {
node = DRMLISTENTRY(drmBONode, l, head);
arg = &node->bo_arg;
rep = &arg->d.rep;
if (!arg->handled) {
drmMsg("Unhandled request\n");
return -EFAULT;
}
if (rep->ret)
return rep->ret;
buf = node->buf;
drmBOCopyReply(rep, buf);
}
return 0;
}
int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
{
drmBONode *node;
drmMMListHead *l;
drm_bo_arg_t *arg, *first;
drm_bo_arg_request_t *req;
drm_bo_arg_reply_t *rep;
drm_u64_t *prevNext = NULL;
int ret;
first = NULL;
for (l = list->list.next; l != &list->list; l = l->next) {
node = DRMLISTENTRY(drmBONode, l, head);
arg = &node->bo_arg;
req = &arg->d.req;
if (!first)
first = arg;
if (prevNext)
*prevNext = (unsigned long) arg;
memset(arg, 0, sizeof(*arg));
prevNext = &arg->next;
req->handle = node->buf->handle;
req->op = drm_bo_fence;
req->mask = node->arg0;
req->arg_handle = fenceHandle;
}
if (!first)
return 0;
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
if (ret)
return -errno;
for (l = list->list.next; l != &list->list; l = l->next) {
node = DRMLISTENTRY(drmBONode, l, head);
arg = &node->bo_arg;
rep = &arg->d.rep;
if (!arg->handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
drmBOCopyReply(rep, node->buf);
}
return 0;
}
int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
unsigned memType)
{
drm_mm_init_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.req.op = mm_init;
arg.req.p_offset = pOffset;
arg.req.p_size = pSize;
arg.req.mem_type = memType;
if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
return -errno;
return 0;
}
int drmMMTakedown(int fd, unsigned memType)
{
drm_mm_init_arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.req.op = mm_takedown;
arg.req.mem_type = memType;
if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
return -errno;
return 0;
}
int drmMMLock(int fd, unsigned memType)
{
drm_mm_init_arg_t arg;
int ret;
memset(&arg, 0, sizeof(arg));
arg.req.op = mm_lock;
arg.req.mem_type = memType;
do{
ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
} while (ret && errno == EAGAIN);
return ret;
}
int drmMMUnlock(int fd, unsigned memType)
{
drm_mm_init_arg_t arg;
int ret;
memset(&arg, 0, sizeof(arg));
arg.req.op = mm_unlock;
arg.req.mem_type = memType;
do{
ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
} while (ret && errno == EAGAIN);
return ret;
}

View File

@ -36,6 +36,7 @@
#define _XF86DRM_H_ #define _XF86DRM_H_
#include <drm.h> #include <drm.h>
#include <xf86mm.h>
/* Defaults, if nothing set in xf86config */ /* Defaults, if nothing set in xf86config */
#define DRM_DEV_UID 0 #define DRM_DEV_UID 0

View File

@ -0,0 +1,210 @@
/**************************************************************************
*
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
* 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 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
* THE COPYRIGHT HOLDERS, AUTHORS 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.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
*
**************************************************************************/
#ifndef _XF86MM_H_
#define _XF86MM_H_
#include <stddef.h>
#include "drm.h"
/*
* Note on multithreaded applications using this interface.
* Libdrm is not threadsafe, so common buffer, TTM, and fence objects need to
* be protected using an external mutex.
*
* Note: Don't protect the following functions, as it may lead to deadlocks:
* drmBOUnmap(), drmFenceBuffers().
* The kernel is synchronizing and refcounting buffer maps.
* User space only needs to refcount object usage within the same application.
*/
/*
* List macros heavily inspired by the Linux kernel
* list handling. No list looping yet.
*/
typedef struct _drmMMListHead
{
struct _drmMMListHead *prev;
struct _drmMMListHead *next;
} drmMMListHead;
#define DRMINITLISTHEAD(__item) \
do{ \
(__item)->prev = (__item); \
(__item)->next = (__item); \
} while (0)
#define DRMLISTADD(__item, __list) \
do { \
(__item)->prev = (__list); \
(__item)->next = (__list)->next; \
(__list)->next->prev = (__item); \
(__list)->next = (__item); \
} while (0)
#define DRMLISTADDTAIL(__item, __list) \
do { \
(__item)->next = (__list); \
(__item)->prev = (__list)->prev; \
(__list)->prev->next = (__item); \
(__list)->prev = (__item); \
} while(0)
#define DRMLISTDEL(__item) \
do { \
(__item)->prev->next = (__item)->next; \
(__item)->next->prev = (__item)->prev; \
} while(0)
#define DRMLISTDELINIT(__item) \
do { \
(__item)->prev->next = (__item)->next; \
(__item)->next->prev = (__item)->prev; \
(__item)->next = (__item); \
(__item)->prev = (__item); \
} while(0)
#define DRMLISTENTRY(__type, __item, __field) \
((__type *)(((char *) (__item)) - offsetof(__type, __field)))
typedef struct _drmFence{
unsigned handle;
int class;
unsigned type;
unsigned flags;
unsigned signaled;
unsigned pad[4]; /* for future expansion */
} drmFence;
typedef struct _drmBO{
drm_bo_type_t type;
unsigned handle;
drm_u64_t mapHandle;
unsigned flags;
unsigned mask;
unsigned mapFlags;
unsigned long size;
unsigned long offset;
unsigned long start;
unsigned replyFlags;
unsigned fenceFlags;
unsigned pageAlignment;
void *virtual;
void *mapVirtual;
int mapCount;
unsigned pad[8]; /* for future expansion */
} drmBO;
typedef struct _drmBONode {
drmMMListHead head;
drmBO *buf;
drm_bo_arg_t bo_arg;
unsigned long arg0;
unsigned long arg1;
} drmBONode;
typedef struct _drmBOList {
unsigned numTarget;
unsigned numCurrent;
unsigned numOnList;
drmMMListHead list;
drmMMListHead free;
} drmBOList;
/* Fencing */
extern int drmFenceCreate(int fd, unsigned flags, int class,
unsigned type,
drmFence *fence);
extern int drmFenceDestroy(int fd, const drmFence *fence);
extern int drmFenceReference(int fd, unsigned handle, drmFence *fence);
extern int drmFenceUnreference(int fd, const drmFence *fence);
extern int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type);
extern int drmFenceSignaled(int fd, drmFence *fence,
unsigned fenceType, int *signaled);
extern int drmFenceWait(int fd, unsigned flags, drmFence *fence,
unsigned flush_type);
extern int drmFenceEmit(int fd, unsigned flags, drmFence *fence,
unsigned emit_type);
extern int drmFenceBuffers(int fd, unsigned flags, drmFence *fence);
extern int drmFenceUpdate(int fd, drmFence *fence);
/*
* Buffer object list functions.
*/
extern void drmBOFreeList(drmBOList *list);
extern int drmBOResetList(drmBOList *list);
extern void *drmBOListIterator(drmBOList *list);
extern void *drmBOListNext(drmBOList *list, void *iterator);
extern drmBO *drmBOListBuf(void *iterator);
extern int drmBOCreateList(int numTarget, drmBOList *list);
/*
* Buffer object functions.
*/
extern int drmBOCreate(int fd, unsigned long start, unsigned long size,
unsigned pageAlignment,void *user_buffer,
drm_bo_type_t type, unsigned mask,
unsigned hint, drmBO *buf);
extern int drmBODestroy(int fd, drmBO *buf);
extern int drmBOReference(int fd, unsigned handle, drmBO *buf);
extern int drmBOUnReference(int fd, drmBO *buf);
extern int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
void **address);
extern int drmBOUnmap(int fd, drmBO *buf);
extern int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
unsigned hint);
extern int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle);
extern int drmBOInfo(int fd, drmBO *buf);
extern int drmBOBusy(int fd, drmBO *buf, int *busy);
extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
unsigned mask,
int *newItem);
extern int drmBOValidateList(int fd, drmBOList *list);
extern int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle);
extern int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint);
/*
* Initialization functions.
*/
extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
unsigned memType);
extern int drmMMTakedown(int fd, unsigned memType);
extern int drmMMLock(int fd, unsigned memType);
extern int drmMMUnlock(int fd, unsigned memType);
#endif

View File

@ -0,0 +1,10 @@
/*
* libdrm-config.h.in: not at all generated.
*/
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES

View File

@ -58,6 +58,8 @@ OR PERFORMANCE OF THIS SOFTWARE.
#ifdef _POSIX_C_SOURCE #ifdef _POSIX_C_SOURCE
#define _SAVED_POSIX_C_SOURCE _POSIX_C_SOURCE #define _SAVED_POSIX_C_SOURCE _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE #undef _POSIX_C_SOURCE
#else if defined(sun) /* Needed to tell Solaris headers not to restrict to */
#define __EXTENSIONS__ /* only the functions defined in POSIX 199309. */
#endif #endif
#define _POSIX_C_SOURCE 199309L #define _POSIX_C_SOURCE 199309L
#include <time.h> #include <time.h>