From 166da9355d95affe427a6cff3525df60e80a99df Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 21 Aug 2006 21:02:08 +0200 Subject: User / Kernel space fence objects (device-independent part). --- libdrm/xf86drm.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ libdrm/xf86drm.h | 20 ++++++++++ 2 files changed, 139 insertions(+) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index c9f1b2db..6302db3a 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2236,3 +2236,122 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, } return 0; } + +int drmFenceCreate(int fd, int shareable, unsigned type, int emit, + drmFence *fence) +{ + drm_fence_arg_t arg; + + arg.type = type; + arg.flags = (shareable) ? DRM_FENCE_FLAG_SHAREABLE : 0; + arg.flags |= (emit) ? DRM_FENCE_FLAG_EMIT : 0; + arg.op = drm_fence_create; + if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) + return -errno; + fence->handle = arg.handle; + fence->type = arg.type; + fence->signaled = 0; + return 0; +} + +int drmFenceDestroy(int fd, const drmFence *fence) +{ + drm_fence_arg_t 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; + + arg.handle = handle; + arg.op = drm_fence_reference; + if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) + return -errno; + fence->handle = arg.handle; + fence->type = arg.type; + fence->signaled = arg.signaled; + return 0; +} + +int drmFenceUnreference(int fd, const drmFence *fence) +{ + drm_fence_arg_t 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; + + arg.handle = fence->handle; + arg.type = flush_type; + arg.op = drm_fence_flush; + if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) + return -errno; + fence->type = arg.type; + fence->signaled = arg.signaled; + return 0; +} + +int drmFenceSignaled(int fd, drmFence *fence) +{ + drm_fence_arg_t arg; + + arg.handle = fence->handle; + arg.op = drm_fence_signaled; + if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) + return -errno; + fence->type = arg.type; + fence->signaled = arg.signaled; + return 0; +} + +int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type) +{ + drm_fence_arg_t arg; + + arg.handle = fence->handle; + arg.type = emit_type; + arg.op = drm_fence_emit; + if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) + return -errno; + fence->type = arg.type; + fence->signaled = arg.signaled; + return 0; +} + +int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, + int lazy, int ignore_signals) +{ + drm_fence_arg_t arg; + int ret; + + arg.handle = fence->handle; + arg.type = flush_type; + arg.flags = (lazy) ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + arg.flags |= (ignore_signals) ? DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS : 0; + arg.op = drm_fence_wait; + do { + ret = ioctl(fd, DRM_IOCTL_FENCE, &arg); + } while (ret != 0 && errno == EAGAIN); + + if (ret) + return -errno; + + fence->type = arg.type; + fence->signaled = arg.signaled; + return 0; +} + + diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 48a18f29..0e037daa 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -280,6 +280,11 @@ typedef struct _drmSetVersion { int drm_dd_minor; } drmSetVersion, *drmSetVersionPtr; +typedef struct _drmFence{ + unsigned handle; + unsigned type; + unsigned signaled; +} drmFence; #define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) @@ -596,6 +601,21 @@ extern int drmScatterGatherFree(int fd, drm_handle_t handle); extern int drmWaitVBlank(int fd, drmVBlankPtr vbl); +/* Fencing */ + +extern int drmFenceCreate(int fd, int shareable, unsigned type, int emit, + 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); +extern int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, + int lazy, int ignore_signals); +extern int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type); + + + /* Support routines */ extern int drmError(int err, const char *label); extern void *drmMalloc(int size); -- cgit v1.2.3 From a6535c8db4614376ce8ecb7d889b92db066a96cc Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 22 Aug 2006 10:44:09 +0200 Subject: Add a fence object class field for future use (For example VSYNC fence objects) --- libdrm/xf86drm.c | 10 +++++++++- libdrm/xf86drm.h | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 6302db3a..a2a2e28c 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2237,18 +2237,21 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, return 0; } -int drmFenceCreate(int fd, int shareable, unsigned type, int emit, +int drmFenceCreate(int fd, int shareable, int class,unsigned type, + int emit, drmFence *fence) { drm_fence_arg_t arg; arg.type = type; + arg.class = class; arg.flags = (shareable) ? DRM_FENCE_FLAG_SHAREABLE : 0; arg.flags |= (emit) ? DRM_FENCE_FLAG_EMIT : 0; 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->signaled = 0; return 0; @@ -2274,6 +2277,7 @@ int drmFenceReference(int fd, unsigned handle, drmFence *fence) if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) return -errno; fence->handle = arg.handle; + fence->class = arg.class; fence->type = arg.type; fence->signaled = arg.signaled; return 0; @@ -2299,6 +2303,7 @@ int drmFenceFlush(int fd, drmFence *fence, unsigned 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; @@ -2312,6 +2317,7 @@ int drmFenceSignaled(int fd, drmFence *fence) 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; @@ -2326,6 +2332,7 @@ int drmFenceEmit(int fd, drmFence *fence, unsigned 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; @@ -2349,6 +2356,7 @@ int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, if (ret) return -errno; + fence->class = arg.class; fence->type = arg.type; fence->signaled = arg.signaled; return 0; diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 0e037daa..78730785 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -282,6 +282,7 @@ typedef struct _drmSetVersion { typedef struct _drmFence{ unsigned handle; + int class; unsigned type; unsigned signaled; } drmFence; @@ -603,7 +604,8 @@ extern int drmWaitVBlank(int fd, drmVBlankPtr vbl); /* Fencing */ -extern int drmFenceCreate(int fd, int shareable, unsigned type, int emit, +extern int drmFenceCreate(int fd, int shareable, int class, + unsigned type, int emit, drmFence *fence); extern int drmFenceDestroy(int fd, const drmFence *fence); extern int drmFenceReference(int fd, unsigned handle, drmFence *fence); -- cgit v1.2.3 From b4b7b997605f88f3ffdcb0cc7cd1271e0cb24073 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sun, 27 Aug 2006 21:16:13 +0200 Subject: Remove the ioctl multiplexing, and instead allow for generic drm ioctls 0x80 - 0xFF. --- libdrm/xf86drm.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ libdrm/xf86drm.h | 7 +++++ 2 files changed, 103 insertions(+) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index a2a2e28c..e666df3c 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2362,4 +2362,100 @@ int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, return 0; } +static unsigned long combine64(unsigned lo, unsigned hi) +{ + unsigned long ret = lo; + if (sizeof(ret) == 8) { + int shift = 32; + ret |= (hi << shift); + } + return ret; +} + +static void split32(unsigned long val, unsigned *lo, unsigned *hi) +{ + *lo = val & 0xFFFFFFFFUL; + if (sizeof(val) == 8) { + int shift = 32; + *hi = val >> shift; + } else { + *hi = 0; + } +} + +int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) +{ + drm_ttm_arg_t argTTM; + drm_bo_arg_t arg; + + arg.num_requests = 1; + arg.op = drm_op_ttm; + split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi); + + argTTM.op = drm_ttm_create; + argTTM.flags = flags; + split32((unsigned long) &size, &argTTM.size_lo, &argTTM.size_hi); + + if (ioctl(fd, DRM_IOCTL_TTM, &arg)) + return -errno; + + ttm->handle = argTTM.handle; + ttm->user_token = (drm_handle_t) argTTM.user_token; + ttm->flags = argTTM.flags; + ttm->size = combine64(argTTM.size_lo, argTTM.size_hi); + return 0; +} + +int drmTTMDestroy(int fd, const drmTTM *ttm) +{ + drm_ttm_arg_t argTTM; + drm_bo_arg_t arg; + arg.num_requests = 1; + arg.op = drm_op_ttm; + split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi); + argTTM.op = drm_ttm_destroy; + argTTM.handle = ttm->handle; + if (ioctl(fd, DRM_IOCTL_TTM, &arg)) + return -errno; + return 0; +} + + +int drmTTMReference(int fd, unsigned handle, drmTTM *ttm) +{ + drm_ttm_arg_t argTTM; + drm_bo_arg_t arg; + + arg.num_requests = 1; + arg.op = drm_op_ttm; + split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi); + + argTTM.handle = handle; + argTTM.op = drm_ttm_reference; + if (ioctl(fd, DRM_IOCTL_TTM, &arg)) + return -errno; + ttm->handle = argTTM.handle; + ttm->user_token = (drm_handle_t) argTTM.user_token; + ttm->flags = argTTM.flags; + ttm->size = combine64(argTTM.size_lo, argTTM.size_hi); + return 0; +} + +int drmTTMUnreference(int fd, const drmTTM *ttm) +{ + drm_ttm_arg_t argTTM; + drm_bo_arg_t arg; + + argTTM.op = drm_ttm_destroy; + argTTM.handle = ttm->handle; + if (ioctl(fd, DRM_IOCTL_TTM, &arg)) + return -errno; + return 0; +} + +drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm) +{ + (void) fd; + return ttm->user_token; +} diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 78730785..92cef4c0 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -287,6 +287,13 @@ typedef struct _drmFence{ unsigned signaled; } drmFence; +typedef struct _drmTTM{ + unsigned handle; + drm_handle_t user_token; + unsigned flags; + unsigned long size; +} drmTTM; + #define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) #define DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ -- cgit v1.2.3 From 886d3b3061cdf53f5a353cbaac843f63104d2658 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sun, 27 Aug 2006 22:01:33 +0200 Subject: Bugfixes. --- libdrm/xf86drm.c | 57 +++++++++++++++++++++----------------------------------- libdrm/xf86drm.h | 7 +++++++ 2 files changed, 28 insertions(+), 36 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index e666df3c..88676083 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2385,37 +2385,28 @@ static void split32(unsigned long val, unsigned *lo, unsigned *hi) int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) { - drm_ttm_arg_t argTTM; - drm_bo_arg_t arg; + drm_ttm_arg_t arg; - arg.num_requests = 1; - arg.op = drm_op_ttm; - split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi); - - argTTM.op = drm_ttm_create; - argTTM.flags = flags; - split32((unsigned long) &size, &argTTM.size_lo, &argTTM.size_hi); + arg.op = drm_ttm_create; + arg.flags = flags; + split32((unsigned long) size, &arg.size_lo, &arg.size_hi); if (ioctl(fd, DRM_IOCTL_TTM, &arg)) return -errno; - ttm->handle = argTTM.handle; - ttm->user_token = (drm_handle_t) argTTM.user_token; - ttm->flags = argTTM.flags; - ttm->size = combine64(argTTM.size_lo, argTTM.size_hi); + ttm->handle = arg.handle; + ttm->user_token = (drm_handle_t) arg.user_token; + ttm->flags = arg.flags; + ttm->size = combine64(arg.size_lo, arg.size_hi); return 0; } int drmTTMDestroy(int fd, const drmTTM *ttm) { - drm_ttm_arg_t argTTM; - drm_bo_arg_t arg; + drm_ttm_arg_t arg; - arg.num_requests = 1; - arg.op = drm_op_ttm; - split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi); - argTTM.op = drm_ttm_destroy; - argTTM.handle = ttm->handle; + arg.op = drm_ttm_destroy; + arg.handle = ttm->handle; if (ioctl(fd, DRM_IOCTL_TTM, &arg)) return -errno; return 0; @@ -2424,31 +2415,25 @@ int drmTTMDestroy(int fd, const drmTTM *ttm) int drmTTMReference(int fd, unsigned handle, drmTTM *ttm) { - drm_ttm_arg_t argTTM; - drm_bo_arg_t arg; - - arg.num_requests = 1; - arg.op = drm_op_ttm; - split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi); + drm_ttm_arg_t arg; - argTTM.handle = handle; - argTTM.op = drm_ttm_reference; + arg.handle = handle; + arg.op = drm_ttm_reference; if (ioctl(fd, DRM_IOCTL_TTM, &arg)) return -errno; - ttm->handle = argTTM.handle; - ttm->user_token = (drm_handle_t) argTTM.user_token; - ttm->flags = argTTM.flags; - ttm->size = combine64(argTTM.size_lo, argTTM.size_hi); + ttm->handle = arg.handle; + ttm->user_token = (drm_handle_t) arg.user_token; + ttm->flags = arg.flags; + ttm->size = combine64(arg.size_lo, arg.size_hi); return 0; } int drmTTMUnreference(int fd, const drmTTM *ttm) { - drm_ttm_arg_t argTTM; - drm_bo_arg_t arg; + drm_ttm_arg_t arg; - argTTM.op = drm_ttm_destroy; - argTTM.handle = ttm->handle; + arg.op = drm_ttm_destroy; + arg.handle = ttm->handle; if (ioctl(fd, DRM_IOCTL_TTM, &arg)) return -errno; return 0; diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 92cef4c0..433191b4 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -623,6 +623,13 @@ extern int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, int lazy, int ignore_signals); extern int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type); +/* TTMS */ +extern int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, + unsigned flags); +extern int drmTTMDestroy(int fd, const drmTTM *ttm); +extern int drmTTMReference(int fd, unsigned handle, drmTTM *ttm); +extern int drmTTMUnreference(int fd, const drmTTM *ttm); +extern drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm); /* Support routines */ -- cgit v1.2.3 From e181f594a4a75790ce1d2a8e907f9fcc5e88b419 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 28 Aug 2006 09:49:09 +0200 Subject: Add a 64-bit drm unsigned type for 64-bit clean IOCTLS. Conversion functions in drmP.h and xf86drm.c. --- libdrm/xf86drm.c | 22 ++++++++++++---------- libdrm/xf86drm.h | 2 ++ 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 88676083..06c64303 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2362,25 +2362,27 @@ int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, return 0; } -static unsigned long combine64(unsigned lo, unsigned hi) +static unsigned long drmUL(drm_u64_t val) { - unsigned long ret = lo; + unsigned long ret = val.lo; if (sizeof(ret) == 8) { int shift = 32; - ret |= (hi << shift); + ret |= (val.hi << shift); } return ret; } -static void split32(unsigned long val, unsigned *lo, unsigned *hi) +static drm_u64_t drmU64(unsigned long val) { - *lo = val & 0xFFFFFFFFUL; + drm_u64_t ret; + ret.lo = val & 0xFFFFFFFFUL; if (sizeof(val) == 8) { int shift = 32; - *hi = val >> shift; + ret.hi = val >> shift; } else { - *hi = 0; + ret.hi = 0; } + return ret; } int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) @@ -2389,7 +2391,7 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) arg.op = drm_ttm_create; arg.flags = flags; - split32((unsigned long) size, &arg.size_lo, &arg.size_hi); + arg.size = drmU64(size); if (ioctl(fd, DRM_IOCTL_TTM, &arg)) return -errno; @@ -2397,7 +2399,7 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) ttm->handle = arg.handle; ttm->user_token = (drm_handle_t) arg.user_token; ttm->flags = arg.flags; - ttm->size = combine64(arg.size_lo, arg.size_hi); + ttm->size = drmUL(arg.size); return 0; } @@ -2424,7 +2426,7 @@ int drmTTMReference(int fd, unsigned handle, drmTTM *ttm) ttm->handle = arg.handle; ttm->user_token = (drm_handle_t) arg.user_token; ttm->flags = arg.flags; - ttm->size = combine64(arg.size_lo, arg.size_hi); + ttm->size = drmUL(arg.size); return 0; } diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 433191b4..58cbd16c 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -497,6 +497,8 @@ do { register unsigned int __old __asm("o0"); \ } \ } while(0) + + /* General user-level programmer's API: unprivileged */ extern int drmAvailable(void); extern int drmOpen(const char *name, const char *busid); -- cgit v1.2.3 From 279e8d26c6cf7347aa9cb6d50d025a41dff9a5be Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 29 Aug 2006 10:45:34 +0200 Subject: =?UTF-8?q?64-bit=20IOCTL=20integer=20(Michel=20D=E4nzer=20&=20Bri?= =?UTF-8?q?an=20Paul)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libdrm/xf86drm.c | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 06c64303..3731ee12 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2237,6 +2237,8 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, return 0; } +#ifdef __linux__ + int drmFenceCreate(int fd, int shareable, int class,unsigned type, int emit, drmFence *fence) @@ -2362,36 +2364,13 @@ int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, return 0; } -static unsigned long drmUL(drm_u64_t val) -{ - unsigned long ret = val.lo; - if (sizeof(ret) == 8) { - int shift = 32; - ret |= (val.hi << shift); - } - return ret; -} - -static drm_u64_t drmU64(unsigned long val) -{ - drm_u64_t ret; - ret.lo = val & 0xFFFFFFFFUL; - if (sizeof(val) == 8) { - int shift = 32; - ret.hi = val >> shift; - } else { - ret.hi = 0; - } - return ret; -} - int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) { drm_ttm_arg_t arg; arg.op = drm_ttm_create; arg.flags = flags; - arg.size = drmU64(size); + arg.size = size; if (ioctl(fd, DRM_IOCTL_TTM, &arg)) return -errno; @@ -2399,7 +2378,7 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) ttm->handle = arg.handle; ttm->user_token = (drm_handle_t) arg.user_token; ttm->flags = arg.flags; - ttm->size = drmUL(arg.size); + ttm->size = arg.size; return 0; } @@ -2426,7 +2405,7 @@ int drmTTMReference(int fd, unsigned handle, drmTTM *ttm) ttm->handle = arg.handle; ttm->user_token = (drm_handle_t) arg.user_token; ttm->flags = arg.flags; - ttm->size = drmUL(arg.size); + ttm->size = arg.size; return 0; } @@ -2446,3 +2425,4 @@ drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm) (void) fd; return ttm->user_token; } +#endif -- cgit v1.2.3 From 23f01c9fe8e6170459fe46ad5fc9757bbe967d96 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 29 Aug 2006 18:40:08 +0200 Subject: Checkpoint commit. Buffer object flags and IOCTL argument list. --- libdrm/xf86drm.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- libdrm/xf86mm.h | 105 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 libdrm/xf86mm.h (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 3731ee12..6de6c06f 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -65,6 +65,8 @@ # define _DRM_FREE free # include "drm.h" #endif +#include "xf86mm.h" + /* Not all systems have MAP_FAILED defined */ #ifndef MAP_FAILED @@ -2384,7 +2386,7 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) int drmTTMDestroy(int fd, const drmTTM *ttm) { - drm_ttm_arg_t arg; + drm_ttm_arg_t arg; arg.op = drm_ttm_destroy; arg.handle = ttm->handle; @@ -2425,4 +2427,135 @@ drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm) (void) fd; return ttm->user_token; } + +static int drmAdjustListNodes(DrmBufList *list) +{ + DrmBufNode *node; + DrmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (DrmBufNode *) 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(DrmBufNode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static void drmFreeList(DrmBufList *list) +{ + DrmBufNode *node; + DrmMMListHead *l; + int ret = 0; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(DrmBufNode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(DrmBufNode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +int drmResetList(DrmBufList *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--; + } + return drmAdjustListNodes(list); +} + +static int drmAddListItem(DrmBufList *list, DrmBuf *item, drm_bo_arg_t *arg) +{ + DrmBufNode *node; + DrmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (DrmBufNode *) malloc(sizeof(*node)); + if (!node) { + return -ENOMEM; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(DrmBufNode, l, head); + } + node->buf = item; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return 0; +} + +int drmCreateBufList(int numTarget, DrmBufList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +/* + * Prepare list for IOCTL submission. + */ + +static drm_bo_arg_t *drmPrepareList(DrmBufList *list) +{ + DrmMMListHead *cur, *next; + DrmBufNode *first, *curNode, *nextNode; + + cur = list->list.next; + if (cur == &list->list) + return NULL; + + first = DRMLISTENTRY(DrmBufNode, cur, head); + curNode = DRMLISTENTRY(DrmBufNode, cur, head); + + for (next = cur->next; next != &list->list; + cur = next, next = cur->next) { + nextNode = DRMLISTENTRY(DrmBufNode, next, head); + curNode->bo_arg.req.next = ((unsigned long) &nextNode->bo_arg.req); + curNode = nextNode; + } + curNode->bo_arg.req.next = 0; + return &first->bo_arg; +} + #endif diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h new file mode 100644 index 00000000..5fb78723 --- /dev/null +++ b/libdrm/xf86mm.h @@ -0,0 +1,105 @@ +/************************************************************************** + * + * 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 + + +/* + * 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 _DrmBuf{ + unsigned handle; +} DrmBuf; + + +typedef struct _DrmBufNode { + DrmMMListHead head; + DrmBuf *buf; + drm_bo_arg_t bo_arg; +} DrmBufNode; + +typedef struct _DrmMMBufList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + DrmMMListHead list; + DrmMMListHead free; +} DrmBufList; + + +#endif -- cgit v1.2.3 From de144ba23c1245cf021a63cc739c7c9903568272 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 29 Aug 2006 21:57:37 +0200 Subject: Part of buffer object libdrm interface. --- libdrm/xf86drm.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++------- libdrm/xf86drm.h | 2 + libdrm/xf86mm.h | 41 +++++++----- 3 files changed, 194 insertions(+), 38 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 6de6c06f..3fccdf69 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2381,6 +2381,8 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) ttm->user_token = (drm_handle_t) arg.user_token; ttm->flags = arg.flags; ttm->size = arg.size; + ttm->virtual = NULL; + ttm->mapCount = 0; return 0; } @@ -2428,14 +2430,14 @@ drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm) return ttm->user_token; } -static int drmAdjustListNodes(DrmBufList *list) +static int drmAdjustListNodes(drmBOList *list) { - DrmBufNode *node; - DrmMMListHead *l; + drmBONode *node; + drmMMListHead *l; int ret = 0; while(list->numCurrent < list->numTarget) { - node = (DrmBufNode *) malloc(sizeof(*node)); + node = (drmBONode *) malloc(sizeof(*node)); if (!node) { ret = -ENOMEM; break; @@ -2449,23 +2451,23 @@ static int drmAdjustListNodes(DrmBufList *list) if (l == &list->free) break; DRMLISTDEL(l); - node = DRMLISTENTRY(DrmBufNode, l, head); + node = DRMLISTENTRY(drmBONode, l, head); free(node); list->numCurrent--; } return ret; } -static void drmFreeList(DrmBufList *list) +static void drmFreeList(drmBOList *list) { - DrmBufNode *node; - DrmMMListHead *l; + drmBONode *node; + drmMMListHead *l; int ret = 0; l = list->list.next; while(l != &list->list) { DRMLISTDEL(l); - node = DRMLISTENTRY(DrmBufNode, l, head); + node = DRMLISTENTRY(drmBONode, l, head); free(node); l = list->free.next; list->numCurrent--; @@ -2475,16 +2477,16 @@ static void drmFreeList(DrmBufList *list) l = list->free.next; while(l != &list->free) { DRMLISTDEL(l); - node = DRMLISTENTRY(DrmBufNode, l, head); + node = DRMLISTENTRY(drmBONode, l, head); free(node); l = list->free.next; list->numCurrent--; } } -int drmResetList(DrmBufList *list) { +int drmResetList(drmBOList *list) { - DrmMMListHead *l; + drmMMListHead *l; int ret; ret = drmAdjustListNodes(list); @@ -2500,21 +2502,21 @@ int drmResetList(DrmBufList *list) { return drmAdjustListNodes(list); } -static int drmAddListItem(DrmBufList *list, DrmBuf *item, drm_bo_arg_t *arg) +static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg) { - DrmBufNode *node; - DrmMMListHead *l; + drmBONode *node; + drmMMListHead *l; l = list->free.next; if (l == &list->free) { - node = (DrmBufNode *) malloc(sizeof(*node)); + node = (drmBONode *) malloc(sizeof(*node)); if (!node) { return -ENOMEM; } list->numCurrent++; } else { DRMLISTDEL(l); - node = DRMLISTENTRY(DrmBufNode, l, head); + node = DRMLISTENTRY(drmBONode, l, head); } node->buf = item; DRMLISTADD(&node->head, &list->list); @@ -2522,7 +2524,7 @@ static int drmAddListItem(DrmBufList *list, DrmBuf *item, drm_bo_arg_t *arg) return 0; } -int drmCreateBufList(int numTarget, DrmBufList *list) +int drmCreateBufList(int numTarget, drmBOList *list) { DRMINITLISTHEAD(&list->list); DRMINITLISTHEAD(&list->free); @@ -2536,21 +2538,21 @@ int drmCreateBufList(int numTarget, DrmBufList *list) * Prepare list for IOCTL submission. */ -static drm_bo_arg_t *drmPrepareList(DrmBufList *list) +static drm_bo_arg_t *drmPrepareList(drmBOList *list) { - DrmMMListHead *cur, *next; - DrmBufNode *first, *curNode, *nextNode; + drmMMListHead *cur, *next; + drmBONode *first, *curNode, *nextNode; cur = list->list.next; if (cur == &list->list) return NULL; - first = DRMLISTENTRY(DrmBufNode, cur, head); - curNode = DRMLISTENTRY(DrmBufNode, cur, head); + first = DRMLISTENTRY(drmBONode, cur, head); + curNode = DRMLISTENTRY(drmBONode, cur, head); for (next = cur->next; next != &list->list; cur = next, next = cur->next) { - nextNode = DRMLISTENTRY(DrmBufNode, next, head); + nextNode = DRMLISTENTRY(drmBONode, next, head); curNode->bo_arg.req.next = ((unsigned long) &nextNode->bo_arg.req); curNode = nextNode; } @@ -2558,4 +2560,143 @@ static drm_bo_arg_t *drmPrepareList(DrmBufList *list) return &first->bo_arg; } +int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, + 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.req; + drm_bo_arg_reply_t *rep = &arg.rep; + + req->mask = mask; + req->hint = hint; + req->size = size; + req->type = type; + + buf->ttm = NULL; + + switch(type) { + case drm_bo_type_ttm: + req->arg_handle = ttm->handle; + req->buffer_start = start; + buf->ttm = ttm; + break; + case drm_bo_type_dc: + break; + case drm_bo_type_user: + req->buffer_start = (unsigned long) user_buffer; + buf->virtual = user_buffer; + break; + default: + return -EINVAL; + } + req->op = drm_bo_create; + req->next = 0; + + if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) + return -errno; + if (!rep->handled) { + return -EFAULT; + } + if (rep->ret) { + return rep->ret; + } + + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->map_handle = rep->arg_handle; + buf->map_flags = rep->map_flags; + buf->map_virtual = NULL; + buf->map_count = 0; + buf->virtual = NULL; + buf->mask = rep->mask; + buf->hint = rep->hint; + buf->start = rep->buffer_start; + + return 0; +} + +int drmBODestroy(int fd, drmBO *buf) +{ + drm_bo_arg_t arg; + drm_bo_arg_request_t *req = &arg.req; + drm_bo_arg_reply_t *rep = &arg.rep; + + req->handle = buf->handle; + req->op = drm_bo_destroy; + req->next = 0; + + if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) + return -errno; + if (!rep->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.req; + drm_bo_arg_reply_t *rep = &arg.rep; + + req->handle = handle; + req->op = drm_bo_reference; + req->next = 0; + + if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) + return -errno; + if (!rep->handled) { + return -EFAULT; + } + if (rep->ret) { + return rep->ret; + } + + buf->handle = rep->handle; + buf->type = drm_bo_type_dc; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->map_handle = rep->arg_handle; + buf->map_flags = rep->map_flags; + buf->map_virtual = NULL; + buf->map_count = 0; + buf->virtual = NULL; + buf->mask = rep->mask; + buf->hint = rep->hint; + return 0; +} + +int drmBOUnReference(int fd, drmBO *buf) +{ + drm_bo_arg_t arg; + drm_bo_arg_request_t *req = &arg.req; + drm_bo_arg_reply_t *rep = &arg.rep; + + req->handle = buf->handle; + req->op = drm_bo_unreference; + req->next = 0; + + if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) + return -errno; + if (!rep->handled) { + return -EFAULT; + } + if (rep->ret) { + return rep->ret; + } + + buf->handle = 0; + return 0; +} + #endif diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 58cbd16c..ca48bfbf 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -292,6 +292,8 @@ typedef struct _drmTTM{ drm_handle_t user_token; unsigned flags; unsigned long size; + void *virtual; + int mapCount; } drmTTM; #define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 5fb78723..08149d08 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -29,7 +29,7 @@ #ifndef _XF86MM_H_ #define _XF86MM_H_ #include - +#include "xf86drm.h" /* * List macros heavily inspired by the Linux kernel @@ -40,7 +40,7 @@ typedef struct _drmMMListHead { struct _drmMMListHead *prev; struct _drmMMListHead *next; -} DrmMMListHead; +} drmMMListHead; #define DRMINITLISTHEAD(__item) \ do{ \ @@ -82,24 +82,37 @@ typedef struct _drmMMListHead ((__type *)(((char *) (__item)) - offsetof(__type, __field))) -typedef struct _DrmBuf{ +typedef struct _drmBO{ + drm_bo_type_t type; unsigned handle; -} DrmBuf; - - -typedef struct _DrmBufNode { - DrmMMListHead head; - DrmBuf *buf; + drm_handle_t map_handle; + unsigned flags; + unsigned mask; + unsigned hint; + unsigned map_flags; + unsigned long size; + unsigned long offset; + unsigned long start; + void *virtual; + void *map_virtual; + int map_count; + drmTTM *ttm; +} drmBO; + + +typedef struct _drmBONode { + drmMMListHead head; + drmBO *buf; drm_bo_arg_t bo_arg; -} DrmBufNode; +} drmBONode; -typedef struct _DrmMMBufList { +typedef struct _drmBOList { unsigned numTarget; unsigned numCurrent; unsigned numOnList; - DrmMMListHead list; - DrmMMListHead free; -} DrmBufList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; #endif -- cgit v1.2.3 From e47a4fda2ef7aada45b7799ad20e8012102dc12e Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 30 Aug 2006 13:04:08 +0200 Subject: Memory manager init and takedown. --- libdrm/Makefile.am | 2 +- libdrm/xf86drm.c | 30 +++++++++++++++++++++++++++++- libdrm/xf86drm.h | 2 ++ libdrm/xf86mm.h | 9 ++++++++- 4 files changed, 40 insertions(+), 3 deletions(-) (limited to 'libdrm') diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am index b12e87fa..91a7e5dc 100644 --- a/libdrm/Makefile.am +++ b/libdrm/Makefile.am @@ -26,6 +26,6 @@ AM_CFLAGS = -I$(top_srcdir)/shared-core libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c libdrmincludedir = ${includedir} -libdrminclude_HEADERS = xf86drm.h +libdrminclude_HEADERS = xf86drm.h xf86mm.h EXTRA_DIST = ChangeLog TODO diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 3fccdf69..c9005c41 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -65,7 +65,6 @@ # define _DRM_FREE free # include "drm.h" #endif -#include "xf86mm.h" /* Not all systems have MAP_FAILED defined */ @@ -2582,6 +2581,7 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, buf->ttm = ttm; break; case drm_bo_type_dc: + req->buffer_start = start; break; case drm_bo_type_user: req->buffer_start = (unsigned long) user_buffer; @@ -2699,4 +2699,32 @@ int drmBOUnReference(int fd, drmBO *buf) return 0; } +int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, + unsigned long ttPOffset, unsigned long ttPSize) +{ + drm_mm_init_arg_t arg; + + arg.req.op = mm_init; + arg.req.vr_p_offset = vramPOffset; + arg.req.vr_p_size = vramPSize; + arg.req.tt_p_offset = vramPOffset; + arg.req.tt_p_size = vramPSize; + + if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg)) + return -errno; + + return 0; +} + +int drmMMTakedown(int fd) +{ + drm_mm_init_arg_t arg; + arg.req.op = mm_takedown; + + if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg)) + return -errno; + + return 0; +} + #endif diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index ca48bfbf..f257deda 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -670,4 +670,6 @@ extern int drmSLLookupNeighbors(void *l, unsigned long key, unsigned long *prev_key, void **prev_value, unsigned long *next_key, void **next_value); +#include "xf86mm.h" + #endif diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 08149d08..8711a144 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -29,7 +29,7 @@ #ifndef _XF86MM_H_ #define _XF86MM_H_ #include -#include "xf86drm.h" +#include "drm.h" /* * List macros heavily inspired by the Linux kernel @@ -114,5 +114,12 @@ typedef struct _drmBOList { drmMMListHead free; } drmBOList; +extern int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, + 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); + #endif -- cgit v1.2.3 From 14a835be616183e733a2d6a7dcc697b8a6f46caf Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 30 Aug 2006 15:08:40 +0200 Subject: Buffer object mapping and mapping synchronization for multiple clients. --- libdrm/xf86drm.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++----- libdrm/xf86mm.h | 8 ++--- 2 files changed, 99 insertions(+), 12 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index c9005c41..f592ff2a 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2606,10 +2606,10 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, buf->flags = rep->flags; buf->size = rep->size; buf->offset = rep->offset; - buf->map_handle = rep->arg_handle; - buf->map_flags = rep->map_flags; - buf->map_virtual = NULL; - buf->map_count = 0; + buf->mapHandle = rep->arg_handle; + buf->mapFlags = rep->map_flags; + buf->mapVirtual = NULL; + buf->mapCount = 0; buf->virtual = NULL; buf->mask = rep->mask; buf->hint = rep->hint; @@ -2666,13 +2666,14 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) buf->flags = rep->flags; buf->size = rep->size; buf->offset = rep->offset; - buf->map_handle = rep->arg_handle; - buf->map_flags = rep->map_flags; - buf->map_virtual = NULL; - buf->map_count = 0; + buf->mapHandle = rep->arg_handle; + buf->mapFlags = rep->map_flags; + buf->mapVirtual = NULL; + buf->mapCount = 0; buf->virtual = NULL; buf->mask = rep->mask; buf->hint = rep->hint; + buf->start = rep->buffer_start; return 0; } @@ -2699,6 +2700,92 @@ int drmBOUnReference(int fd, drmBO *buf) return 0; } +/* + * + */ + +int drmBOMap(int fd, drmBO *buf, unsigned map_flags, void **address) +{ + + drm_bo_arg_t arg; + drm_bo_arg_request_t *req = &arg.req; + drm_bo_arg_reply_t *rep = &arg.rep; + int ret = 0; + + /* + * Make sure we have a virtual address of the buffer. + */ + + if (!buf->mapVirtual) { + if (buf->mapCount == 0) { + drmAddress virtual; + ret = drmMap(fd, buf->mapHandle, buf->size + buf->start, &virtual); + if (ret) + return ret; + ++buf->mapCount; + buf->mapVirtual = virtual; + buf->virtual = ((char *) virtual) + buf->start; + fprintf(stderr,"Mapvirtual, virtual: 0x%08x 0x%08x\n", + buf->mapVirtual, buf->virtual); + } + } + + req->handle = buf->handle; + req->mask = map_flags; + req->op = drm_bo_map; + req->next = 0; + + /* + * 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 || !rep->handled || rep->ret) { + if (--buf->mapCount == 0) { + (void )drmUnmap(buf->mapVirtual, buf->start + buf->size); + } + } + if (ret) + return ret; + if (!rep->handled) + return -EFAULT; + if (rep->ret) + return rep->ret; + + *address = buf->virtual; + + return 0; +} + +int drmBOUnmap(int fd, drmBO *buf) +{ + drm_bo_arg_t arg; + drm_bo_arg_request_t *req = &arg.req; + + if (buf->mapCount == 0) { + return -EINVAL; + } + + if (--buf->mapCount == 0) { + (void) drmUnmap(buf->mapVirtual, buf->start + buf->size); + } + + req->handle = buf->handle; + req->op = drm_bo_unmap; + req->next = 0; + + if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) { + return -errno; + } + + return 0; +} + + int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, unsigned long ttPOffset, unsigned long ttPSize) { diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 8711a144..c811892f 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -85,17 +85,17 @@ typedef struct _drmMMListHead typedef struct _drmBO{ drm_bo_type_t type; unsigned handle; - drm_handle_t map_handle; + drm_handle_t mapHandle; unsigned flags; unsigned mask; unsigned hint; - unsigned map_flags; + unsigned mapFlags; unsigned long size; unsigned long offset; unsigned long start; void *virtual; - void *map_virtual; - int map_count; + void *mapVirtual; + int mapCount; drmTTM *ttm; } drmBO; -- cgit v1.2.3 From ff95ea5536d70f9bc8eac12f2c97dae71fb97066 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 30 Aug 2006 15:11:50 +0200 Subject: Add missing map flags. --- libdrm/xf86drm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index f592ff2a..6ffc4b39 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2704,7 +2704,7 @@ int drmBOUnReference(int fd, drmBO *buf) * */ -int drmBOMap(int fd, drmBO *buf, unsigned map_flags, void **address) +int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address) { drm_bo_arg_t arg; @@ -2731,7 +2731,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned map_flags, void **address) } req->handle = buf->handle; - req->mask = map_flags; + req->hint = mapFlags; req->op = drm_bo_map; req->next = 0; @@ -2756,6 +2756,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned map_flags, void **address) if (rep->ret) return rep->ret; + buf->mapFlags = mapFlags; *address = buf->virtual; return 0; -- cgit v1.2.3 From d39055174b5a487f0d848e1af4c3459fb4261bf1 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 30 Aug 2006 17:40:07 +0200 Subject: Remove the buffer object hint field and use it only as an argument. Validate stub. --- libdrm/xf86drm.c | 2 -- libdrm/xf86mm.h | 1 - 2 files changed, 3 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 6ffc4b39..1763b89a 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2612,7 +2612,6 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, buf->mapCount = 0; buf->virtual = NULL; buf->mask = rep->mask; - buf->hint = rep->hint; buf->start = rep->buffer_start; return 0; @@ -2672,7 +2671,6 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) buf->mapCount = 0; buf->virtual = NULL; buf->mask = rep->mask; - buf->hint = rep->hint; buf->start = rep->buffer_start; return 0; } diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index c811892f..21fed6cf 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -88,7 +88,6 @@ typedef struct _drmBO{ drm_handle_t mapHandle; unsigned flags; unsigned mask; - unsigned hint; unsigned mapFlags; unsigned long size; unsigned long offset; -- cgit v1.2.3 From ec8c79b79de6544cc09b5a2c85213a5f30e0d906 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 31 Aug 2006 14:10:13 +0200 Subject: More mapping synchronization. libdrm validate and fencing functions. --- libdrm/xf86drm.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++++------- libdrm/xf86mm.h | 2 + 2 files changed, 302 insertions(+), 40 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 1763b89a..a99c979d 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2501,7 +2501,9 @@ int drmResetList(drmBOList *list) { return drmAdjustListNodes(list); } -static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg) +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + unsigned long arg0, + unsigned long arg1) { drmBONode *node; drmMMListHead *l; @@ -2510,7 +2512,7 @@ static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg) if (l == &list->free) { node = (drmBONode *) malloc(sizeof(*node)); if (!node) { - return -ENOMEM; + return NULL; } list->numCurrent++; } else { @@ -2518,45 +2520,51 @@ static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg) node = DRMLISTENTRY(drmBONode, l, head); } node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; DRMLISTADD(&node->head, &list->list); list->numOnList++; - return 0; + return node; } -int drmCreateBufList(int numTarget, drmBOList *list) +void *drmBOListIterator(drmBOList *list) { - DRMINITLISTHEAD(&list->list); - DRMINITLISTHEAD(&list->free); - list->numTarget = numTarget; - list->numCurrent = 0; - list->numOnList = 0; - return drmAdjustListNodes(list); -} + void *ret = list->list.next; -/* - * Prepare list for IOCTL submission. - */ + if (ret == &list->list) + return NULL; + return ret; +} -static drm_bo_arg_t *drmPrepareList(drmBOList *list) +void *drmBOListNext(drmBOList *list, void *iterator) { - drmMMListHead *cur, *next; - drmBONode *first, *curNode, *nextNode; + void *ret; - cur = list->list.next; - if (cur == &list->list) + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) return NULL; + return ret; +} - first = DRMLISTENTRY(drmBONode, cur, head); - curNode = DRMLISTENTRY(drmBONode, cur, head); +void drmBOListBuf(void *iterator, drmBO **buf) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + + *buf = node->buf; +} - for (next = cur->next; next != &list->list; - cur = next, next = cur->next) { - nextNode = DRMLISTENTRY(drmBONode, next, head); - curNode->bo_arg.req.next = ((unsigned long) &nextNode->bo_arg.req); - curNode = nextNode; - } - curNode->bo_arg.req.next = 0; - return &first->bo_arg; + +int drmCreateBufList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); } int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, @@ -2567,6 +2575,7 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, drm_bo_arg_request_t *req = &arg.req; drm_bo_arg_reply_t *rep = &arg.rep; + arg.handled = 0; req->mask = mask; req->hint = hint; req->size = size; @@ -2595,7 +2604,8 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; - if (!rep->handled) { + if (!arg.handled) { + fprintf(stderr, "Not handled\n"); return -EFAULT; } if (rep->ret) { @@ -2607,7 +2617,6 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, buf->size = rep->size; buf->offset = rep->offset; buf->mapHandle = rep->arg_handle; - buf->mapFlags = rep->map_flags; buf->mapVirtual = NULL; buf->mapCount = 0; buf->virtual = NULL; @@ -2623,13 +2632,14 @@ int drmBODestroy(int fd, drmBO *buf) drm_bo_arg_request_t *req = &arg.req; drm_bo_arg_reply_t *rep = &arg.rep; + arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_destroy; req->next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; - if (!rep->handled) { + if (!arg.handled) { return -EFAULT; } if (rep->ret) { @@ -2647,13 +2657,14 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) drm_bo_arg_request_t *req = &arg.req; drm_bo_arg_reply_t *rep = &arg.rep; + arg.handled = 0; req->handle = handle; req->op = drm_bo_reference; req->next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; - if (!rep->handled) { + if (!arg.handled) { return -EFAULT; } if (rep->ret) { @@ -2666,7 +2677,6 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) buf->size = rep->size; buf->offset = rep->offset; buf->mapHandle = rep->arg_handle; - buf->mapFlags = rep->map_flags; buf->mapVirtual = NULL; buf->mapCount = 0; buf->virtual = NULL; @@ -2681,13 +2691,14 @@ int drmBOUnReference(int fd, drmBO *buf) drm_bo_arg_request_t *req = &arg.req; drm_bo_arg_reply_t *rep = &arg.rep; + arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_unreference; req->next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; - if (!rep->handled) { + if (!arg.handled) { return -EFAULT; } if (rep->ret) { @@ -2699,10 +2710,13 @@ int drmBOUnReference(int fd, drmBO *buf) } /* - * + * 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, void **address) +int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, + void **address) { drm_bo_arg_t arg; @@ -2714,6 +2728,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address) * Make sure we have a virtual address of the buffer. */ + fprintf(stderr, "Address is 0x%08x\n", address); if (!buf->mapVirtual) { if (buf->mapCount == 0) { drmAddress virtual; @@ -2728,8 +2743,11 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address) } } + fprintf(stderr, "Address is 0x%08x\n", address); + arg.handled = 0; req->handle = buf->handle; - req->hint = mapFlags; + req->mask = mapFlags; + req->hint = mapHint; req->op = drm_bo_map; req->next = 0; @@ -2738,23 +2756,26 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address) * This IOCTL synchronizes the buffer. */ + fprintf(stderr, "Address is 0x%08x\n", address); do { ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); } while (ret != 0 && errno == EAGAIN); - if (ret || !rep->handled || rep->ret) { + fprintf(stderr, "Address is 0x%08x\n", address); + if (ret || !arg.handled || rep->ret) { if (--buf->mapCount == 0) { (void )drmUnmap(buf->mapVirtual, buf->start + buf->size); } } if (ret) return ret; - if (!rep->handled) + if (!arg.handled) return -EFAULT; if (rep->ret) return rep->ret; buf->mapFlags = mapFlags; + fprintf(stderr, "Address is 0x%08x\n", address); *address = buf->virtual; return 0; @@ -2764,6 +2785,7 @@ int drmBOUnmap(int fd, drmBO *buf) { drm_bo_arg_t arg; drm_bo_arg_request_t *req = &arg.req; + drm_bo_arg_reply_t *rep = &arg.rep; if (buf->mapCount == 0) { return -EINVAL; @@ -2773,6 +2795,7 @@ int drmBOUnmap(int fd, drmBO *buf) (void) drmUnmap(buf->mapVirtual, buf->start + buf->size); } + arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_unmap; req->next = 0; @@ -2780,10 +2803,247 @@ int drmBOUnmap(int fd, drmBO *buf) 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.req; + drm_bo_arg_reply_t *rep = &arg.rep; + int ret = 0; + + arg.handled = 0; + 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; + req->next = 0; + + 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; + + buf->offset = rep->offset; + buf->flags = rep->flags; + buf->mask = rep->mask; + return 0; +} + + +int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle) +{ + drm_bo_arg_t arg; + drm_bo_arg_request_t *req = &arg.req; + drm_bo_arg_reply_t *rep = &arg.rep; + int ret = 0; + + arg.handled = 0; + req->handle = buf->handle; + req->mask = flags; + req->arg_handle = fenceHandle; + req->op = drm_bo_validate; + req->next = 0; + 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 drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, + unsigned mask, + int *newItem) +{ + drmBONode *node, *cur; + unsigned oldFlags, newFlags; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + mask &= ~DRM_BO_MASK_MEM; + + 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 memFlags = cur->arg0 & DRM_BO_MASK_MEM; + + if (!(memFlags & flags)) { + drmMsg("Incompatible memory location requests " + "on validate list.\n"); + return -EINVAL; + } + if ((cur->arg1 | mask) & (cur->arg0 ^ flags)) { + drmMsg("Incompatible buffer flag requests " + " on validate list.\n"); + return -EINVAL; + } + cur->arg1 |= mask; + cur->arg0 = (memFlags & flags) | ((cur->arg0 | flags) & cur->arg1); + } +} + + +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->req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long) arg; + + req->next = 0; + prevNext = &req->next; + arg->handled = 0; + 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, &arg); + } 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->rep; + + if (!arg->handled) + return -EFAULT; + if (rep->ret) + return rep->ret; + + buf = node->buf; + buf->offset = rep->offset; + buf->flags = rep->flags; + buf->mask = rep->mask; + } + + 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; + 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->req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long) arg; + + req->next = 0; + prevNext = &req->next; + arg->handled = 0; + 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, &arg); + + 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->rep; + + if (!arg->handled) + return -EFAULT; + if (rep->ret) + return rep->ret; + } + + return 0; +} int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, unsigned long ttPOffset, unsigned long ttPSize) diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 21fed6cf..aaee3c0b 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -103,6 +103,8 @@ typedef struct _drmBONode { drmMMListHead head; drmBO *buf; drm_bo_arg_t bo_arg; + unsigned long arg0; + unsigned long arg1; } drmBONode; typedef struct _drmBOList { -- cgit v1.2.3 From 4edb95d6e0a00a9a8885603cab2c99e3c6daa705 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 1 Sep 2006 11:23:21 +0200 Subject: Various bugfixes. --- libdrm/xf86drm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index a99c979d..41ad89cb 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -3053,8 +3053,8 @@ int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, arg.req.op = mm_init; arg.req.vr_p_offset = vramPOffset; arg.req.vr_p_size = vramPSize; - arg.req.tt_p_offset = vramPOffset; - arg.req.tt_p_size = vramPSize; + arg.req.tt_p_offset = ttPOffset; + arg.req.tt_p_size = ttPSize; if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg)) return -errno; -- cgit v1.2.3 From ef8e618cf30ab7dcbe8c7211e0c2508c5520a669 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 1 Sep 2006 16:38:06 +0200 Subject: Export buffer info on map and validate ioctls. Add an info ioctl operation. --- libdrm/xf86drm.c | 84 ++++++++++++++++++++++++++++++++++++++++++-------------- libdrm/xf86mm.h | 2 ++ 2 files changed, 65 insertions(+), 21 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 41ad89cb..aa1a5998 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2567,6 +2567,22 @@ int drmCreateBufList(int numTarget, drmBOList *list) 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; +} + + + int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, void *user_buffer, drm_bo_type_t type, unsigned mask, unsigned hint, drmBO *buf) @@ -2612,16 +2628,10 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, return rep->ret; } - buf->handle = rep->handle; - buf->flags = rep->flags; - buf->size = rep->size; - buf->offset = rep->offset; - buf->mapHandle = rep->arg_handle; + drmBOCopyReply(rep, buf); buf->mapVirtual = NULL; buf->mapCount = 0; buf->virtual = NULL; - buf->mask = rep->mask; - buf->start = rep->buffer_start; return 0; } @@ -2671,17 +2681,12 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) return rep->ret; } - buf->handle = rep->handle; + drmBOCopyReply(rep, buf); buf->type = drm_bo_type_dc; - buf->flags = rep->flags; - buf->size = rep->size; - buf->offset = rep->offset; - buf->mapHandle = rep->arg_handle; buf->mapVirtual = NULL; buf->mapCount = 0; buf->virtual = NULL; - buf->mask = rep->mask; - buf->start = rep->buffer_start; + return 0; } @@ -2777,6 +2782,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, buf->mapFlags = mapFlags; fprintf(stderr, "Address is 0x%08x\n", address); *address = buf->virtual; + drmBOCopyReply(rep, buf); return 0; } @@ -2838,9 +2844,7 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, if (rep->ret) return rep->ret; - buf->offset = rep->offset; - buf->flags = rep->flags; - buf->mask = rep->mask; + drmBOCopyReply(rep, buf); return 0; } @@ -2869,8 +2873,46 @@ int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle) return rep->ret; return 0; } - +int drmBOInfo(int fd, drmBO *buf) +{ + drm_bo_arg_t arg; + drm_bo_arg_request_t *req = &arg.req; + drm_bo_arg_reply_t *rep = &arg.rep; + int ret = 0; + + arg.handled = 0; + req->handle = buf->handle; + req->op = drm_bo_info; + req->next = 0; + + 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 drmBufBusy(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, @@ -2978,9 +3020,7 @@ int drmBOValidateList(int fd, drmBOList *list) return rep->ret; buf = node->buf; - buf->offset = rep->offset; - buf->flags = rep->flags; - buf->mask = rep->mask; + drmBOCopyReply(rep, buf); } return 0; @@ -2997,6 +3037,7 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) drm_bo_arg_reply_t *rep; drm_u64_t *prevNext = NULL; drmBO *buf; + unsigned fence_flags; int ret; first = NULL; @@ -3040,6 +3081,7 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) return -EFAULT; if (rep->ret) return rep->ret; + drmBOCopyReply(rep, buf); } return 0; diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index aaee3c0b..a8458b15 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -92,6 +92,8 @@ typedef struct _drmBO{ unsigned long size; unsigned long offset; unsigned long start; + unsigned replyFlags; + unsigned fenceFlags; void *virtual; void *mapVirtual; int mapCount; -- cgit v1.2.3 From 405b5d9ca8cc9f6c5c7bb764c684bf74ba7660c6 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 1 Sep 2006 18:11:05 +0200 Subject: Flag bit pattern bugfixes. Remove some error messages. --- libdrm/xf86drm.c | 74 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 32 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index aa1a5998..073fd0c4 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2598,6 +2598,7 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, req->type = type; buf->ttm = NULL; + buf->virtual = NULL; switch(type) { case drm_bo_type_ttm: @@ -2631,7 +2632,6 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, drmBOCopyReply(rep, buf); buf->mapVirtual = NULL; buf->mapCount = 0; - buf->virtual = NULL; return 0; } @@ -2642,6 +2642,12 @@ int drmBODestroy(int fd, drmBO *buf) drm_bo_arg_request_t *req = &arg.req; drm_bo_arg_reply_t *rep = &arg.rep; + if (buf->mapVirtual) { + (void) drmUnmap(buf->mapVirtual, buf->start + buf->size); + buf->mapVirtual = NULL; + buf->virtual = NULL; + } + arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_destroy; @@ -2729,26 +2735,32 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, drm_bo_arg_reply_t *rep = &arg.rep; int ret = 0; + /* + * At the moment, we don't allow recursive mapping of a buffer, since + * the first mapping may have to be unmapped before this one to succeed. + * This might result in a deadlock. We need a DRM mutex mechanism!! + */ + + if (buf->mapCount) { + drmMsg("Recursive mapping is currently not allowed.\n"); + return -EAGAIN; + } + /* * Make sure we have a virtual address of the buffer. */ - fprintf(stderr, "Address is 0x%08x\n", address); - if (!buf->mapVirtual) { - if (buf->mapCount == 0) { - drmAddress virtual; - ret = drmMap(fd, buf->mapHandle, buf->size + buf->start, &virtual); - if (ret) - return ret; - ++buf->mapCount; - buf->mapVirtual = virtual; - buf->virtual = ((char *) virtual) + buf->start; - fprintf(stderr,"Mapvirtual, virtual: 0x%08x 0x%08x\n", - buf->mapVirtual, buf->virtual); - } + if (!buf->virtual) { + drmAddress virtual; + ret = drmMap(fd, buf->mapHandle, buf->size + buf->start, &virtual); + if (ret) + return ret; + buf->mapVirtual = virtual; + buf->virtual = ((char *) virtual) + buf->start; + fprintf(stderr,"Mapvirtual, virtual: 0x%08x 0x%08x\n", + buf->mapVirtual, buf->virtual); } - fprintf(stderr, "Address is 0x%08x\n", address); arg.handled = 0; req->handle = buf->handle; req->mask = mapFlags; @@ -2761,28 +2773,21 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, * This IOCTL synchronizes the buffer. */ - fprintf(stderr, "Address is 0x%08x\n", address); do { ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); } while (ret != 0 && errno == EAGAIN); - fprintf(stderr, "Address is 0x%08x\n", address); - if (ret || !arg.handled || rep->ret) { - if (--buf->mapCount == 0) { - (void )drmUnmap(buf->mapVirtual, buf->start + buf->size); - } - } if (ret) return ret; if (!arg.handled) return -EFAULT; if (rep->ret) return rep->ret; - + + drmBOCopyReply(rep, buf); buf->mapFlags = mapFlags; - fprintf(stderr, "Address is 0x%08x\n", address); + ++buf->mapCount; *address = buf->virtual; - drmBOCopyReply(rep, buf); return 0; } @@ -2793,13 +2798,6 @@ int drmBOUnmap(int fd, drmBO *buf) drm_bo_arg_request_t *req = &arg.req; drm_bo_arg_reply_t *rep = &arg.rep; - if (buf->mapCount == 0) { - return -EINVAL; - } - - if (--buf->mapCount == 0) { - (void) drmUnmap(buf->mapVirtual, buf->start + buf->size); - } arg.handled = 0; req->handle = buf->handle; @@ -2814,6 +2812,8 @@ int drmBOUnmap(int fd, drmBO *buf) if (rep->ret) return rep->ret; + --buf->mapCount; + return 0; } @@ -2825,6 +2825,11 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, drm_bo_arg_reply_t *rep = &arg.rep; int ret = 0; + if (buf->mapCount) { + drmMsg("Cannot validate while buffer is mapped.\n"); + return -EAGAIN; + } + arg.handled = 0; req->handle = buf->handle; req->mask = flags; @@ -2988,6 +2993,11 @@ int drmBOValidateList(int fd, drmBOList *list) if (prevNext) *prevNext = (unsigned long) arg; + if (node->buf->mapCount) { + drmMsg("Cannot validate while buffer is mapped.\n"); + return -EAGAIN; + } + req->next = 0; prevNext = &req->next; arg->handled = 0; -- cgit v1.2.3 From f88c32fd4cb93fe8b9dfa543a26d74733d0cd8ef Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 4 Sep 2006 22:05:21 +0200 Subject: Libdrm function headers. Some renaming. --- libdrm/xf86drm.c | 10 +++++----- libdrm/xf86mm.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 073fd0c4..068d0fb9 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2457,7 +2457,7 @@ static int drmAdjustListNodes(drmBOList *list) return ret; } -static void drmFreeList(drmBOList *list) +void drmBOFreeList(drmBOList *list) { drmBONode *node; drmMMListHead *l; @@ -2483,7 +2483,7 @@ static void drmFreeList(drmBOList *list) } } -int drmResetList(drmBOList *list) { +int drmBOResetList(drmBOList *list) { drmMMListHead *l; int ret; @@ -2547,17 +2547,17 @@ void *drmBOListNext(drmBOList *list, void *iterator) return ret; } -void drmBOListBuf(void *iterator, drmBO **buf) +drmBO *drmBOListBuf(void *iterator) { drmBONode *node; drmMMListHead *l = (drmMMListHead *) iterator; node = DRMLISTENTRY(drmBONode, l, head); - *buf = node->buf; + return node->buf; } -int drmCreateBufList(int numTarget, drmBOList *list) +int drmBOCreateList(int numTarget, drmBOList *list) { DRMINITLISTHEAD(&list->list); DRMINITLISTHEAD(&list->free); diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index a8458b15..623f4d58 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -117,12 +117,63 @@ typedef struct _drmBOList { drmMMListHead free; } drmBOList; + +/* + * TTM functions. + */ + +extern int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, + unsigned flags); +extern int drmTTMDestroy(int fd, const drmTTM *ttm); +extern int drmTTMReference(int fd, unsigned handle, drmTTM *ttm); +extern int drmTTMUnreference(int fd, const drmTTM *ttm); +extern drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm); + +/* + * 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, drmTTM *ttm, unsigned long start, unsigned long size, 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 drmBufBusy(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); + + +/* + * Initialization functions. + */ + +extern int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, + unsigned long ttPOffset, unsigned long ttPSize); +extern int drmMMTakedown(int fd); #endif -- cgit v1.2.3 From 604215396847a7964fd7d68aa89d4f778b3bf22b Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 5 Sep 2006 18:00:25 +0200 Subject: Fence all unfenced buffers function. --- libdrm/xf86drm.c | 15 +++++++++++++++ libdrm/xf86drm.h | 1 + 2 files changed, 16 insertions(+) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 068d0fb9..6d087427 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2259,6 +2259,21 @@ int drmFenceCreate(int fd, int shareable, int class,unsigned type, fence->signaled = 0; return 0; } + +int drmFenceBuffers(int fd, int shareable, drmFence *fence) +{ + drm_fence_arg_t arg; + + arg.flags = (shareable) ? DRM_FENCE_FLAG_SHAREABLE : 0; + 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->signaled = 0; + return 0; +} int drmFenceDestroy(int fd, const drmFence *fence) { diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index f257deda..be1eeeff 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -626,6 +626,7 @@ extern int drmFenceSignaled(int fd, drmFence *fence); extern int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, int lazy, int ignore_signals); extern int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type); +extern int drmFenceBuffers(int fd, int shareable, drmFence *fence); /* TTMS */ extern int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, -- cgit v1.2.3 From e3f54ecdd9d266607afd7d8b62960b2154b63e9d Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 5 Sep 2006 19:36:45 +0200 Subject: Multithreaded application note. --- libdrm/xf86drm.c | 26 +++----------------------- libdrm/xf86mm.h | 13 +++++++++++++ 2 files changed, 16 insertions(+), 23 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 6d087427..dd97e26e 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2750,17 +2750,6 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, drm_bo_arg_reply_t *rep = &arg.rep; int ret = 0; - /* - * At the moment, we don't allow recursive mapping of a buffer, since - * the first mapping may have to be unmapped before this one to succeed. - * This might result in a deadlock. We need a DRM mutex mechanism!! - */ - - if (buf->mapCount) { - drmMsg("Recursive mapping is currently not allowed.\n"); - return -EAGAIN; - } - /* * Make sure we have a virtual address of the buffer. */ @@ -2827,8 +2816,6 @@ int drmBOUnmap(int fd, drmBO *buf) if (rep->ret) return rep->ret; - --buf->mapCount; - return 0; } @@ -2840,11 +2827,6 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, drm_bo_arg_reply_t *rep = &arg.rep; int ret = 0; - if (buf->mapCount) { - drmMsg("Cannot validate while buffer is mapped.\n"); - return -EAGAIN; - } - arg.handled = 0; req->handle = buf->handle; req->mask = flags; @@ -2853,10 +2835,12 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, req->op = drm_bo_validate; req->next = 0; + do{ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); } while (ret && errno == -EAGAIN); + if (ret) return ret; if (!arg.handled) @@ -3008,11 +2992,6 @@ int drmBOValidateList(int fd, drmBOList *list) if (prevNext) *prevNext = (unsigned long) arg; - if (node->buf->mapCount) { - drmMsg("Cannot validate while buffer is mapped.\n"); - return -EAGAIN; - } - req->next = 0; prevNext = &req->next; arg->handled = 0; @@ -3030,6 +3009,7 @@ int drmBOValidateList(int fd, drmBOList *list) ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); } while (ret && errno == -EAGAIN); + if (ret) return -errno; diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 623f4d58..43ea71b8 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -31,6 +31,18 @@ #include #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. @@ -82,6 +94,7 @@ typedef struct _drmMMListHead ((__type *)(((char *) (__item)) - offsetof(__type, __field))) + typedef struct _drmBO{ drm_bo_type_t type; unsigned handle; -- cgit v1.2.3 From 99acb7936660843090ea8a9f22d2d50d9433e0de Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 8 Sep 2006 17:24:38 +0200 Subject: Various bugfixes. --- libdrm/xf86drm.c | 79 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 28 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index dd97e26e..298b812a 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2512,6 +2512,7 @@ int drmBOResetList(drmBOList *list) { DRMLISTDEL(l); DRMLISTADD(l, &list->free); list->numOnList--; + l = list->list.next; } return drmAdjustListNodes(list); } @@ -2603,8 +2604,8 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, unsigned hint, drmBO *buf) { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + drm_bo_arg_request_t *req = &arg.d.req; + drm_bo_arg_reply_t *rep = &arg.d.rep; arg.handled = 0; req->mask = mask; @@ -2628,6 +2629,9 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, 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; } @@ -2654,10 +2658,10 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, int drmBODestroy(int fd, drmBO *buf) { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + drm_bo_arg_request_t *req = &arg.d.req; + drm_bo_arg_reply_t *rep = &arg.d.rep; - if (buf->mapVirtual) { + if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) { (void) drmUnmap(buf->mapVirtual, buf->start + buf->size); buf->mapVirtual = NULL; buf->virtual = NULL; @@ -2685,8 +2689,8 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + drm_bo_arg_request_t *req = &arg.d.req; + drm_bo_arg_reply_t *rep = &arg.d.rep; arg.handled = 0; req->handle = handle; @@ -2714,9 +2718,16 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) int drmBOUnReference(int fd, drmBO *buf) { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + 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; + } + arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_unreference; @@ -2746,23 +2757,25 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + 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) { + if (!buf->virtual && buf->type != drm_bo_type_fake) { drmAddress virtual; ret = drmMap(fd, buf->mapHandle, buf->size + buf->start, &virtual); if (ret) return ret; buf->mapVirtual = virtual; buf->virtual = ((char *) virtual) + buf->start; +#ifdef BODEBUG fprintf(stderr,"Mapvirtual, virtual: 0x%08x 0x%08x\n", buf->mapVirtual, buf->virtual); +#endif } arg.handled = 0; @@ -2799,8 +2812,8 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, int drmBOUnmap(int fd, drmBO *buf) { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + drm_bo_arg_request_t *req = &arg.d.req; + drm_bo_arg_reply_t *rep = &arg.d.rep; arg.handled = 0; @@ -2823,8 +2836,8 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, unsigned hint) { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + drm_bo_arg_request_t *req = &arg.d.req; + drm_bo_arg_reply_t *rep = &arg.d.rep; int ret = 0; arg.handled = 0; @@ -2856,8 +2869,8 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle) { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + drm_bo_arg_request_t *req = &arg.d.req; + drm_bo_arg_reply_t *rep = &arg.d.rep; int ret = 0; arg.handled = 0; @@ -2881,8 +2894,8 @@ int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle) int drmBOInfo(int fd, drmBO *buf) { drm_bo_arg_t arg; - drm_bo_arg_request_t *req = &arg.req; - drm_bo_arg_reply_t *rep = &arg.rep; + drm_bo_arg_request_t *req = &arg.d.req; + drm_bo_arg_reply_t *rep = &arg.d.rep; int ret = 0; arg.handled = 0; @@ -2963,6 +2976,7 @@ int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, cur->arg1 |= mask; cur->arg0 = (memFlags & flags) | ((cur->arg0 | flags) & cur->arg1); } + return 0; } @@ -2984,7 +2998,7 @@ int drmBOValidateList(int fd, drmBOList *list) node = DRMLISTENTRY(drmBONode, l, head); arg = &node->bo_arg; - req = &arg->req; + req = &arg->d.req; if (!first) first = arg; @@ -2999,14 +3013,20 @@ int drmBOValidateList(int fd, drmBOList *list) req->op = drm_bo_validate; req->mask = node->arg0; req->hint = 0; - req->arg_handle = node->arg1; + req->arg_handle = node->arg1 | DRM_BO_MASK_MEM; +#ifdef BODEBUG + fprintf(stderr, "Offset 0x%08x, Handle 0x%08x, " + "mask 0x%08x flags 0x%08x\n", + node->buf->offset, + req->handle, req->arg_handle, req->mask); +#endif } if (!first) return 0; do{ - ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); + ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first); } while (ret && errno == -EAGAIN); @@ -3015,9 +3035,8 @@ int drmBOValidateList(int fd, drmBOList *list) for (l = list->list.next; l != &list->list; l = l->next) { node = DRMLISTENTRY(drmBONode, l, head); - arg = &node->bo_arg; - rep = &arg->rep; + rep = &arg->d.rep; if (!arg->handled) return -EFAULT; @@ -3026,6 +3045,10 @@ int drmBOValidateList(int fd, drmBOList *list) buf = node->buf; drmBOCopyReply(rep, buf); +#ifdef BODEBUG + fprintf(stderr,"Offset 0x%08x, Flags 0x%08x\n", + buf->offset, buf->flags); +#endif } return 0; @@ -3051,7 +3074,7 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) node = DRMLISTENTRY(drmBONode, l, head); arg = &node->bo_arg; - req = &arg->req; + req = &arg->d.req; if (!first) first = arg; @@ -3071,7 +3094,7 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) if (!first) return 0; - ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); + ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first); if (ret) return -errno; @@ -3080,7 +3103,7 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) node = DRMLISTENTRY(drmBONode, l, head); arg = &node->bo_arg; - rep = &arg->rep; + rep = &arg->d.rep; if (!arg->handled) return -EFAULT; -- cgit v1.2.3 From 191e284709ee792a32124e96e43d5876406b93dc Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 12 Sep 2006 12:01:00 +0200 Subject: More bugfixes. Disable the i915 IRQ turnoff for now since it seems to be causing problems. --- libdrm/xf86drm.c | 70 +++++++++++++++++++++++++++++++++++++++++--------------- libdrm/xf86drm.h | 4 +++- libdrm/xf86mm.h | 3 ++- 3 files changed, 56 insertions(+), 21 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 298b812a..2ea6656f 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2256,6 +2256,7 @@ int drmFenceCreate(int fd, int shareable, int class,unsigned type, fence->handle = arg.handle; fence->class = arg.class; fence->type = arg.type; + fence->flags = arg.flags; fence->signaled = 0; return 0; } @@ -2271,6 +2272,7 @@ int drmFenceBuffers(int fd, int shareable, drmFence *fence) fence->handle = arg.handle; fence->class = arg.class; fence->type = arg.type; + fence->flags = arg.flags; fence->signaled = 0; return 0; } @@ -2297,6 +2299,7 @@ int drmFenceReference(int fd, unsigned handle, drmFence *fence) fence->handle = arg.handle; fence->class = arg.class; fence->type = arg.type; + fence->flags = 0; fence->signaled = arg.signaled; return 0; } @@ -2327,20 +2330,41 @@ int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type) return 0; } -int drmFenceSignaled(int fd, drmFence *fence) +int drmFenceUpdate(int fd, drmFence *fence) { - drm_fence_arg_t 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; + drm_fence_arg_t 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; } + + int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type) { drm_fence_arg_t arg; @@ -2362,6 +2386,12 @@ int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, drm_fence_arg_t arg; int ret; + if (!(fence->flags & DRM_FENCE_FLAG_SHAREABLE)) { + if (flush_type & fence->signaled == flush_type) { + return 0; + } + } + arg.handle = fence->handle; arg.type = flush_type; arg.flags = (lazy) ? DRM_FENCE_FLAG_WAIT_LAZY : 0; @@ -2942,8 +2972,6 @@ int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, *newItem = 0; cur = NULL; - mask &= ~DRM_BO_MASK_MEM; - for (l = list->list.next; l != &list->list; l = l->next) { node = DRMLISTENTRY(drmBONode, l, head); if (node->buf == buf) { @@ -2961,20 +2989,22 @@ int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, cur->arg0 = flags; cur->arg1 = mask; } else { - unsigned memFlags = cur->arg0 & DRM_BO_MASK_MEM; + unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM; + unsigned memFlags = cur->arg0 & flags & memMask; - if (!(memFlags & flags)) { + if (!memFlags) { drmMsg("Incompatible memory location requests " "on validate list.\n"); return -EINVAL; } - if ((cur->arg1 | mask) & (cur->arg0 ^ flags)) { + if ((cur->arg1 | mask) & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { drmMsg("Incompatible buffer flag requests " " on validate list.\n"); return -EINVAL; } cur->arg1 |= mask; - cur->arg0 = (memFlags & flags) | ((cur->arg0 | flags) & cur->arg1); + cur->arg0 = memFlags | ((cur->arg0 | flags) & + cur->arg1 & ~DRM_BO_MASK_MEM); } return 0; } @@ -3116,16 +3146,18 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) } int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, - unsigned long ttPOffset, unsigned long ttPSize) + unsigned long ttPOffset, unsigned long ttPSize, + unsigned long max_locked_size) { drm_mm_init_arg_t arg; - + arg.req.op = mm_init; arg.req.vr_p_offset = vramPOffset; arg.req.vr_p_size = vramPSize; arg.req.tt_p_offset = ttPOffset; arg.req.tt_p_size = ttPSize; - + arg.req.max_locked_pages = max_locked_size / getpagesize(); + if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg)) return -errno; diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index be1eeeff..1b136d31 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -284,6 +284,7 @@ typedef struct _drmFence{ unsigned handle; int class; unsigned type; + unsigned flags; unsigned signaled; } drmFence; @@ -622,7 +623,8 @@ 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); +extern int drmFenceSignaled(int fd, drmFence *fence, + unsigned fenceType, int *signaled); extern int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, int lazy, int ignore_signals); extern int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type); diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 43ea71b8..24e28245 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -185,7 +185,8 @@ extern int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle); */ extern int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, - unsigned long ttPOffset, unsigned long ttPSize); + unsigned long ttPOffset, unsigned long ttPSize, + unsigned long max_locked_size); extern int drmMMTakedown(int fd); -- cgit v1.2.3 From 861b26578cd5e497fb506ad5952fa62bd03ea201 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 12 Sep 2006 16:28:34 +0200 Subject: Use lazy fence wait when possible even for RW fences. Saves some CPU. Lindent. --- libdrm/xf86drm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 2ea6656f..3a23eae2 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2995,11 +2995,19 @@ int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, 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 ((cur->arg1 | mask) & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { drmMsg("Incompatible buffer flag requests " - " on validate list.\n"); + "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; -- cgit v1.2.3 From 49fbeb339c232804866cd548d6023fe559597353 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 15 Sep 2006 11:18:35 +0200 Subject: Some bugfixes. Change the fence object interface somewhat to allow some more flexibility. Make list IOCTLS really restartable. Try to avoid busy-waits in the kernel using immediate return to user-space with an -EAGAIN. --- libdrm/xf86drm.c | 92 ++++++++++++++++++++++++++++++++------------------------ libdrm/xf86drm.h | 42 -------------------------- libdrm/xf86mm.h | 34 ++++++++++++++++++++- 3 files changed, 85 insertions(+), 83 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 3a23eae2..2df74d14 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2240,16 +2240,20 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, #ifdef __linux__ -int drmFenceCreate(int fd, int shareable, int class,unsigned type, - int emit, +/* + * 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; arg.type = type; arg.class = class; - arg.flags = (shareable) ? DRM_FENCE_FLAG_SHAREABLE : 0; - arg.flags |= (emit) ? DRM_FENCE_FLAG_EMIT : 0; arg.op = drm_fence_create; if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) return -errno; @@ -2261,11 +2265,17 @@ int drmFenceCreate(int fd, int shareable, int class,unsigned type, return 0; } -int drmFenceBuffers(int fd, int shareable, drmFence *fence) +/* + * Valid flags are + * DRM_FENCE_FLAG_SHAREABLE + * DRM_FENCE_MASK_DRIVER + */ + +int drmFenceBuffers(int fd, unsigned flags, drmFence *fence) { drm_fence_arg_t arg; - arg.flags = (shareable) ? DRM_FENCE_FLAG_SHAREABLE : 0; + arg.flags = flags; arg.op = drm_fence_buffers; if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) return -errno; @@ -2299,7 +2309,7 @@ int drmFenceReference(int fd, unsigned handle, drmFence *fence) fence->handle = arg.handle; fence->class = arg.class; fence->type = arg.type; - fence->flags = 0; + fence->flags = arg.flags; fence->signaled = arg.signaled; return 0; } @@ -2363,12 +2373,18 @@ int drmFenceSignaled(int fd, drmFence *fence, unsigned fenceType, return 0; } +/* + * Valid flags are + * DRM_FENCE_FLAG_SHAREABLE + * DRM_FENCE_MASK_DRIVER + */ -int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type) +int drmFenceEmit(int fd, unsigned flags, drmFence *fence, unsigned emit_type) { drm_fence_arg_t arg; + arg.flags = flags; arg.handle = fence->handle; arg.type = emit_type; arg.op = drm_fence_emit; @@ -2379,23 +2395,27 @@ int drmFenceEmit(int fd, drmFence *fence, unsigned emit_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, drmFence *fence, unsigned flush_type, - int lazy, int ignore_signals) +int drmFenceWait(int fd, unsigned flags, drmFence *fence, unsigned flush_type) { drm_fence_arg_t arg; int ret; if (!(fence->flags & DRM_FENCE_FLAG_SHAREABLE)) { - if (flush_type & fence->signaled == flush_type) { + if ((flush_type & fence->signaled) == flush_type) { return 0; } } arg.handle = fence->handle; arg.type = flush_type; - arg.flags = (lazy) ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - arg.flags |= (ignore_signals) ? DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS : 0; + arg.flags = flags; arg.op = drm_fence_wait; do { ret = ioctl(fd, DRM_IOCTL_FENCE, &arg); @@ -2666,7 +2686,7 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, return -EINVAL; } req->op = drm_bo_create; - req->next = 0; + arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; @@ -2700,7 +2720,7 @@ int drmBODestroy(int fd, drmBO *buf) arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_destroy; - req->next = 0; + arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; @@ -2725,7 +2745,7 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) arg.handled = 0; req->handle = handle; req->op = drm_bo_reference; - req->next = 0; + arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; @@ -2761,7 +2781,7 @@ int drmBOUnReference(int fd, drmBO *buf) arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_unreference; - req->next = 0; + arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; @@ -2813,7 +2833,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, req->mask = mapFlags; req->hint = mapHint; req->op = drm_bo_map; - req->next = 0; + arg.next = 0; /* * May hang if the buffer object is busy. @@ -2849,7 +2869,7 @@ int drmBOUnmap(int fd, drmBO *buf) arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_unmap; - req->next = 0; + arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) { return -errno; @@ -2876,12 +2896,12 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, req->hint = hint; req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */ req->op = drm_bo_validate; - req->next = 0; + arg.next = 0; do{ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); - } while (ret && errno == -EAGAIN); + } while (ret && errno == EAGAIN); if (ret) @@ -2908,7 +2928,7 @@ int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle) req->mask = flags; req->arg_handle = fenceHandle; req->op = drm_bo_validate; - req->next = 0; + arg.next = 0; ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); @@ -2931,7 +2951,7 @@ int drmBOInfo(int fd, drmBO *buf) arg.handled = 0; req->handle = buf->handle; req->op = drm_bo_info; - req->next = 0; + arg.next = 0; ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); @@ -3044,20 +3064,14 @@ int drmBOValidateList(int fd, drmBOList *list) if (prevNext) *prevNext = (unsigned long) arg; - req->next = 0; - prevNext = &req->next; + arg->next = 0; + prevNext = &arg->next; arg->handled = 0; req->handle = node->buf->handle; req->op = drm_bo_validate; req->mask = node->arg0; req->hint = 0; - req->arg_handle = node->arg1 | DRM_BO_MASK_MEM; -#ifdef BODEBUG - fprintf(stderr, "Offset 0x%08x, Handle 0x%08x, " - "mask 0x%08x flags 0x%08x\n", - node->buf->offset, - req->handle, req->arg_handle, req->mask); -#endif + req->arg_handle = node->arg1; } if (!first) @@ -3065,7 +3079,7 @@ int drmBOValidateList(int fd, drmBOList *list) do{ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first); - } while (ret && errno == -EAGAIN); + } while (ret && errno == EAGAIN); if (ret) @@ -3076,17 +3090,15 @@ int drmBOValidateList(int fd, drmBOList *list) arg = &node->bo_arg; rep = &arg->d.rep; - if (!arg->handled) + if (!arg->handled) { + drmMsg("Unhandled request\n"); return -EFAULT; + } if (rep->ret) return rep->ret; buf = node->buf; drmBOCopyReply(rep, buf); -#ifdef BODEBUG - fprintf(stderr,"Offset 0x%08x, Flags 0x%08x\n", - buf->offset, buf->flags); -#endif } return 0; @@ -3120,8 +3132,8 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) if (prevNext) *prevNext = (unsigned long) arg; - req->next = 0; - prevNext = &req->next; + arg->next = 0; + prevNext = &arg->next; arg->handled = 0; req->handle = node->buf->handle; req->op = drm_bo_fence; diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 1b136d31..d97681c0 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -280,23 +280,6 @@ typedef struct _drmSetVersion { int drm_dd_minor; } drmSetVersion, *drmSetVersionPtr; -typedef struct _drmFence{ - unsigned handle; - int class; - unsigned type; - unsigned flags; - unsigned signaled; -} drmFence; - -typedef struct _drmTTM{ - unsigned handle; - drm_handle_t user_token; - unsigned flags; - unsigned long size; - void *virtual; - int mapCount; -} drmTTM; - #define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) #define DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ @@ -614,31 +597,6 @@ extern int drmScatterGatherFree(int fd, drm_handle_t handle); extern int drmWaitVBlank(int fd, drmVBlankPtr vbl); -/* Fencing */ - -extern int drmFenceCreate(int fd, int shareable, int class, - unsigned type, int emit, - 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, drmFence *fence, unsigned flush_type, - int lazy, int ignore_signals); -extern int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type); -extern int drmFenceBuffers(int fd, int shareable, drmFence *fence); - -/* TTMS */ -extern int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, - unsigned flags); -extern int drmTTMDestroy(int fd, const drmTTM *ttm); -extern int drmTTMReference(int fd, unsigned handle, drmTTM *ttm); -extern int drmTTMUnreference(int fd, const drmTTM *ttm); -extern drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm); - - /* Support routines */ extern int drmError(int err, const char *label); extern void *drmMalloc(int size); diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 24e28245..4cb37e23 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -93,7 +93,22 @@ typedef struct _drmMMListHead #define DRMLISTENTRY(__type, __item, __field) \ ((__type *)(((char *) (__item)) - offsetof(__type, __field))) - +typedef struct _drmFence{ + unsigned handle; + int class; + unsigned type; + unsigned flags; + unsigned signaled; +} drmFence; + +typedef struct _drmTTM{ + unsigned handle; + drm_handle_t user_token; + unsigned flags; + unsigned long size; + void *virtual; + int mapCount; +} drmTTM; typedef struct _drmBO{ drm_bo_type_t type; @@ -130,6 +145,23 @@ typedef struct _drmBOList { 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); + /* * TTM functions. -- cgit v1.2.3 From c4fad4c96168a3dfabaa8a7e97758fefd014c8a7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 18 Sep 2006 16:02:33 +0200 Subject: More verbose error reporting in some cases. Add a buffer object waitIdle user-space function. Fix some names and minor glitches. --- libdrm/xf86drm.c | 34 +++++++++++++++++++++++++++++++++- libdrm/xf86mm.h | 4 ++-- 2 files changed, 35 insertions(+), 3 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 2df74d14..606f098b 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2407,6 +2407,10 @@ 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; @@ -2964,8 +2968,36 @@ int drmBOInfo(int fd, drmBO *buf) 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)) { + arg.handled = 0; + req->handle = buf->handle; + req->op = drm_bo_wait_idle; + req->hint = hint; + arg.next = 0; + + 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 drmBufBusy(int fd, drmBO *buf, int *busy) +int drmBOBusy(int fd, drmBO *buf, int *busy) { if (!(buf->flags & DRM_BO_FLAG_SHAREABLE) && !(buf->replyFlags & DRM_BO_REP_BUSY)) { diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 4cb37e23..a62aef47 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -202,7 +202,7 @@ 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 drmBufBusy(int fd, drmBO *buf, int *busy); +extern int drmBOBusy(int fd, drmBO *buf, int *busy); extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, @@ -210,7 +210,7 @@ extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, 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. -- cgit v1.2.3 From ca1b15d645c74e20f638f5a09981bcf02f58caee Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 18 Sep 2006 20:43:31 +0200 Subject: Alternative implementation of page table zeroing using zap page_range. (Disabled for now) Fix bo_wait_idle bug. Remove stray debug message. --- libdrm/xf86drm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 606f098b..a7d4beb4 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2984,8 +2984,10 @@ int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint) req->hint = hint; arg.next = 0; - ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); - + do { + ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); + } while (ret && errno == EAGAIN); + if (ret) return ret; if (!arg.handled) -- cgit v1.2.3 From fa511a3ff5150d932fd963594d1ef67a94bb8b1f Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 20 Sep 2006 16:31:15 +0200 Subject: Allow for 64-bit map handles of ttms and buffer objects. --- libdrm/xf86mm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index a62aef47..c0e4f1b6 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -103,7 +103,7 @@ typedef struct _drmFence{ typedef struct _drmTTM{ unsigned handle; - drm_handle_t user_token; + drm_u64_t user_token; unsigned flags; unsigned long size; void *virtual; @@ -113,7 +113,7 @@ typedef struct _drmTTM{ typedef struct _drmBO{ drm_bo_type_t type; unsigned handle; - drm_handle_t mapHandle; + drm_u64_t mapHandle; unsigned flags; unsigned mask; unsigned mapFlags; -- cgit v1.2.3 From bd8ca12b7baff778d5bb7b4ad1d38d16b60a4d5a Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 26 Sep 2006 16:00:22 +0200 Subject: Silence valgrind. --- libdrm/xf86drm.c | 58 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index a7d4beb4..31d1c164 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2252,6 +2252,7 @@ int drmFenceCreate(int fd, unsigned flags, int class,unsigned type, { drm_fence_arg_t arg; + memset(&arg, 0, sizeof(arg)); arg.type = type; arg.class = class; arg.op = drm_fence_create; @@ -2275,6 +2276,7 @@ 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)) @@ -2291,6 +2293,7 @@ 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)) @@ -2302,6 +2305,7 @@ 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)) @@ -2318,6 +2322,7 @@ 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)) @@ -2329,6 +2334,7 @@ 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; @@ -2344,6 +2350,7 @@ 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)) @@ -2384,6 +2391,7 @@ 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; @@ -2417,6 +2425,7 @@ int drmFenceWait(int fd, unsigned flags, drmFence *fence, unsigned flush_type) } } + memset(&arg, 0, sizeof(arg)); arg.handle = fence->handle; arg.type = flush_type; arg.flags = flags; @@ -2438,6 +2447,7 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) { drm_ttm_arg_t arg; + memset(&arg, 0, sizeof(arg)); arg.op = drm_ttm_create; arg.flags = flags; arg.size = size; @@ -2458,6 +2468,7 @@ int drmTTMDestroy(int fd, const drmTTM *ttm) { drm_ttm_arg_t arg; + memset(&arg, 0, sizeof(arg)); arg.op = drm_ttm_destroy; arg.handle = ttm->handle; if (ioctl(fd, DRM_IOCTL_TTM, &arg)) @@ -2470,6 +2481,7 @@ int drmTTMReference(int fd, unsigned handle, drmTTM *ttm) { drm_ttm_arg_t arg; + memset(&arg, 0, sizeof(arg)); arg.handle = handle; arg.op = drm_ttm_reference; if (ioctl(fd, DRM_IOCTL_TTM, &arg)) @@ -2485,6 +2497,7 @@ int drmTTMUnreference(int fd, const drmTTM *ttm) { drm_ttm_arg_t arg; + memset(&arg, 0, sizeof(arg)); arg.op = drm_ttm_destroy; arg.handle = ttm->handle; if (ioctl(fd, DRM_IOCTL_TTM, &arg)) @@ -2660,8 +2673,9 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, drm_bo_arg_t arg; drm_bo_arg_request_t *req = &arg.d.req; drm_bo_arg_reply_t *rep = &arg.d.rep; - - arg.handled = 0; + + memset(buf, 0, sizeof(*buf)); + memset(&arg, 0, sizeof(arg)); req->mask = mask; req->hint = hint; req->size = size; @@ -2690,7 +2704,6 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, return -EINVAL; } req->op = drm_bo_create; - arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; @@ -2721,10 +2734,9 @@ int drmBODestroy(int fd, drmBO *buf) buf->virtual = NULL; } - arg.handled = 0; + memset(&arg, 0, sizeof(arg)); req->handle = buf->handle; req->op = drm_bo_destroy; - arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; @@ -2746,10 +2758,9 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf) drm_bo_arg_request_t *req = &arg.d.req; drm_bo_arg_reply_t *rep = &arg.d.rep; - arg.handled = 0; + memset(&arg, 0, sizeof(arg)); req->handle = handle; req->op = drm_bo_reference; - arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; @@ -2782,10 +2793,9 @@ int drmBOUnReference(int fd, drmBO *buf) buf->virtual = NULL; } - arg.handled = 0; + memset(&arg, 0, sizeof(arg)); req->handle = buf->handle; req->op = drm_bo_unreference; - arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; @@ -2832,12 +2842,11 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, #endif } - arg.handled = 0; + memset(&arg, 0, sizeof(arg)); req->handle = buf->handle; req->mask = mapFlags; req->hint = mapHint; req->op = drm_bo_map; - arg.next = 0; /* * May hang if the buffer object is busy. @@ -2870,10 +2879,9 @@ int drmBOUnmap(int fd, drmBO *buf) drm_bo_arg_reply_t *rep = &arg.d.rep; - arg.handled = 0; + memset(&arg, 0, sizeof(arg)); req->handle = buf->handle; req->op = drm_bo_unmap; - arg.next = 0; if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) { return -errno; @@ -2894,20 +2902,17 @@ int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, drm_bo_arg_reply_t *rep = &arg.d.rep; int ret = 0; - arg.handled = 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; - arg.next = 0; - do{ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); } while (ret && errno == EAGAIN); - if (ret) return ret; if (!arg.handled) @@ -2927,12 +2932,11 @@ int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle) drm_bo_arg_reply_t *rep = &arg.d.rep; int ret = 0; - arg.handled = 0; + memset(&arg, 0, sizeof(arg)); req->handle = buf->handle; req->mask = flags; req->arg_handle = fenceHandle; req->op = drm_bo_validate; - arg.next = 0; ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); @@ -2952,10 +2956,9 @@ int drmBOInfo(int fd, drmBO *buf) drm_bo_arg_reply_t *rep = &arg.d.rep; int ret = 0; - arg.handled = 0; + memset(&arg, 0, sizeof(arg)); req->handle = buf->handle; req->op = drm_bo_info; - arg.next = 0; ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); @@ -2978,11 +2981,10 @@ int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint) if ((buf->flags & DRM_BO_FLAG_SHAREABLE) || (buf->replyFlags & DRM_BO_REP_BUSY)) { - arg.handled = 0; + memset(&arg, 0, sizeof(arg)); req->handle = buf->handle; req->op = drm_bo_wait_idle; req->hint = hint; - arg.next = 0; do { ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); @@ -3098,9 +3100,8 @@ int drmBOValidateList(int fd, drmBOList *list) if (prevNext) *prevNext = (unsigned long) arg; - arg->next = 0; + memset(arg, 0, sizeof(*arg)); prevNext = &arg->next; - arg->handled = 0; req->handle = node->buf->handle; req->op = drm_bo_validate; req->mask = node->arg0; @@ -3166,9 +3167,8 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) if (prevNext) *prevNext = (unsigned long) arg; - arg->next = 0; + memset(arg, 0, sizeof(*arg)); prevNext = &arg->next; - arg->handled = 0; req->handle = node->buf->handle; req->op = drm_bo_fence; req->mask = node->arg0; @@ -3205,6 +3205,7 @@ int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, { drm_mm_init_arg_t arg; + memset(&arg, 0, sizeof(arg)); arg.req.op = mm_init; arg.req.vr_p_offset = vramPOffset; arg.req.vr_p_size = vramPSize; @@ -3221,6 +3222,9 @@ int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, int drmMMTakedown(int fd) { drm_mm_init_arg_t arg; + + + memset(&arg, 0, sizeof(arg)); arg.req.op = mm_takedown; if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg)) -- cgit v1.2.3 From 9810ec2737de6aa81e764225f580e4ea39de437a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 22 Aug 2006 16:40:07 +0200 Subject: Add support for tracking drawable information to core Actually make the existing ioctls for adding and removing drawables do something useful, and add another ioctl for the X server to update drawable information. The only kind of drawable information tracked so far is cliprects. (cherry picked from 29598e5253ff5c085ccf63580fd24b84db848424 commit) --- libdrm/xf86drm.c | 16 ++++++++++++++++ libdrm/xf86drm.h | 3 +++ 2 files changed, 19 insertions(+) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 31d1c164..ab884eb5 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -1398,6 +1398,22 @@ int drmDestroyDrawable(int fd, drm_drawable_t handle) return 0; } +int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, + drm_drawable_info_type_t type, unsigned int num, + void *data) +{ + drm_update_draw_t update; + + update.handle = handle; + update.type = type; + update.num = num; + update.data = (unsigned long long)(unsigned long)data; + + if (ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update)) return -errno; + + return 0; +} + /** * Acquire the AGP device. * diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index d97681c0..d39974de 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -545,6 +545,9 @@ extern int drmSwitchToContext(int fd, drm_context_t context); extern int drmDestroyContext(int fd, drm_context_t handle); extern int drmCreateDrawable(int fd, drm_drawable_t * handle); extern int drmDestroyDrawable(int fd, drm_drawable_t handle); +extern int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, + drm_drawable_info_type_t type, + unsigned int num, void *data); extern int drmCtlInstHandler(int fd, int irq); extern int drmCtlUninstHandler(int fd); -- cgit v1.2.3 From 316e73676861c0e019d52ec7bf7b7b1451eaed97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 31 Aug 2006 18:32:08 +0200 Subject: Add definition of DRM_VBLANK_SECONDARY. (cherry picked from 84b38b63f05e04ade8b1ddfb770047fd86de0d64 commit) --- libdrm/xf86drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'libdrm') diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index d39974de..07178ec3 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -252,6 +252,7 @@ typedef struct _drmTextureRegion { typedef enum { DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ } drmVBlankSeqType; -- cgit v1.2.3 From ed82172378666d35ca60e6094fdecb59511a135f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 1 Sep 2006 11:27:14 +0200 Subject: Core vsync: Add flag DRM_VBLANK_NEXTONMISS. When this flag is set and the target sequence is missed, wait for the next vertical blank instead of returning immediately. (cherry picked from 89e323e4900af84cc33219ad24eb0b435a039d23 commit) --- libdrm/xf86drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'libdrm') diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 07178ec3..ae89fd6f 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -252,6 +252,7 @@ typedef struct _drmTextureRegion { typedef enum { DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ } drmVBlankSeqType; -- cgit v1.2.3 From eacedf41a65f135722e7bee6f1a66a803619237f Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 2 Oct 2006 15:06:35 +0200 Subject: Make the user_token 44-bit for TTMs, and have them occupy a unique file space starting at 0x00100000000. This will hopefully allow us to use unmap_mapping_range(). Note that user-space will need 64-bit file offset support. --- libdrm/xf86drm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index ab884eb5..bce913d3 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -46,6 +46,9 @@ # include # endif #else +# ifdef HAVE_CONFIG_H +# include +# endif # include # include # include @@ -2804,7 +2807,7 @@ int drmBOUnReference(int fd, drmBO *buf) if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) { - (void) drmUnmap(buf->mapVirtual, buf->start + buf->size); + (void) munmap(buf->mapVirtual, buf->start + buf->size); buf->mapVirtual = NULL; buf->virtual = NULL; } @@ -2847,8 +2850,12 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, if (!buf->virtual && buf->type != drm_bo_type_fake) { drmAddress virtual; - ret = drmMap(fd, buf->mapHandle, buf->size + buf->start, &virtual); - if (ret) + 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; -- cgit v1.2.3 From f2db76e2f206d2017f710eaddc4b33add4498898 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 11 Oct 2006 13:40:35 +0200 Subject: Big update: Adapt for new functions in the 2.6.19 kernel. Remove the ability to have multiple regions in one TTM. This simplifies a lot of code. Remove the ability to access TTMs from user space. We don't need it anymore without ttm regions. Don't change caching policy for evicted buffers. Instead change it only when the buffer is accessed by the CPU (on the first page fault). This tremendously speeds up eviction rates. Current code is safe for kernels <= 2.6.14. Should also be OK with 2.6.19 and above. --- libdrm/xf86drm.c | 82 ++++---------------------------------------------------- libdrm/xf86mm.h | 23 +--------------- 2 files changed, 6 insertions(+), 99 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index bce913d3..a083ca23 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2462,74 +2462,6 @@ int drmFenceWait(int fd, unsigned flags, drmFence *fence, unsigned flush_type) return 0; } -int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) -{ - drm_ttm_arg_t arg; - - memset(&arg, 0, sizeof(arg)); - arg.op = drm_ttm_create; - arg.flags = flags; - arg.size = size; - - if (ioctl(fd, DRM_IOCTL_TTM, &arg)) - return -errno; - - ttm->handle = arg.handle; - ttm->user_token = (drm_handle_t) arg.user_token; - ttm->flags = arg.flags; - ttm->size = arg.size; - ttm->virtual = NULL; - ttm->mapCount = 0; - return 0; -} - -int drmTTMDestroy(int fd, const drmTTM *ttm) -{ - drm_ttm_arg_t arg; - - memset(&arg, 0, sizeof(arg)); - arg.op = drm_ttm_destroy; - arg.handle = ttm->handle; - if (ioctl(fd, DRM_IOCTL_TTM, &arg)) - return -errno; - return 0; -} - - -int drmTTMReference(int fd, unsigned handle, drmTTM *ttm) -{ - drm_ttm_arg_t arg; - - memset(&arg, 0, sizeof(arg)); - arg.handle = handle; - arg.op = drm_ttm_reference; - if (ioctl(fd, DRM_IOCTL_TTM, &arg)) - return -errno; - ttm->handle = arg.handle; - ttm->user_token = (drm_handle_t) arg.user_token; - ttm->flags = arg.flags; - ttm->size = arg.size; - return 0; -} - -int drmTTMUnreference(int fd, const drmTTM *ttm) -{ - drm_ttm_arg_t arg; - - memset(&arg, 0, sizeof(arg)); - arg.op = drm_ttm_destroy; - arg.handle = ttm->handle; - if (ioctl(fd, DRM_IOCTL_TTM, &arg)) - return -errno; - return 0; -} - -drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm) -{ - (void) fd; - return ttm->user_token; -} - static int drmAdjustListNodes(drmBOList *list) { drmBONode *node; @@ -2685,7 +2617,7 @@ static void drmBOCopyReply(const drm_bo_arg_reply_t *rep, -int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, +int drmBOCreate(int fd, void *ttm, unsigned long start, unsigned long size, void *user_buffer, drm_bo_type_t type, unsigned mask, unsigned hint, drmBO *buf) { @@ -2700,15 +2632,9 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, req->size = size; req->type = type; - buf->ttm = NULL; buf->virtual = NULL; switch(type) { - case drm_bo_type_ttm: - req->arg_handle = ttm->handle; - req->buffer_start = start; - buf->ttm = ttm; - break; case drm_bo_type_dc: req->buffer_start = start; break; @@ -2727,10 +2653,10 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) return -errno; if (!arg.handled) { - fprintf(stderr, "Not handled\n"); return -EFAULT; } if (rep->ret) { + fprintf(stderr, "Error %d\n", rep->ret); return rep->ret; } @@ -2853,8 +2779,10 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, virtual = mmap(0, buf->size + buf->start, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf->mapHandle); - if (virtual == MAP_FAILED) + if (virtual == MAP_FAILED) { ret = -errno; + fprintf(stderr, "Map error 0x%016llx\n", buf->mapHandle); + } if (ret) return ret; buf->mapVirtual = virtual; diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index c0e4f1b6..78df37c3 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -101,15 +101,6 @@ typedef struct _drmFence{ unsigned signaled; } drmFence; -typedef struct _drmTTM{ - unsigned handle; - drm_u64_t user_token; - unsigned flags; - unsigned long size; - void *virtual; - int mapCount; -} drmTTM; - typedef struct _drmBO{ drm_bo_type_t type; unsigned handle; @@ -125,7 +116,6 @@ typedef struct _drmBO{ void *virtual; void *mapVirtual; int mapCount; - drmTTM *ttm; } drmBO; @@ -163,17 +153,6 @@ extern int drmFenceEmit(int fd, unsigned flags, drmFence *fence, extern int drmFenceBuffers(int fd, unsigned flags, drmFence *fence); -/* - * TTM functions. - */ - -extern int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, - unsigned flags); -extern int drmTTMDestroy(int fd, const drmTTM *ttm); -extern int drmTTMReference(int fd, unsigned handle, drmTTM *ttm); -extern int drmTTMUnreference(int fd, const drmTTM *ttm); -extern drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm); - /* * Buffer object list functions. */ @@ -189,7 +168,7 @@ extern int drmBOCreateList(int numTarget, drmBOList *list); * Buffer object functions. */ -extern int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size, +extern int drmBOCreate(int fd, void *ttm, unsigned long start, unsigned long size, void *user_buffer, drm_bo_type_t type, unsigned mask, unsigned hint, drmBO *buf); extern int drmBODestroy(int fd, drmBO *buf); -- cgit v1.2.3 From 30703893674b3da5b862dee2acd6efca13424398 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 11 Oct 2006 22:21:01 +0200 Subject: Compatibility code for 2.6.15-2.6.18. It is ugly but a little comfort is that it will go away in the mainstream kernel. Some bugfixes, mainly in error paths. --- libdrm/xf86drm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index a083ca23..c7683182 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2624,7 +2624,8 @@ int drmBOCreate(int fd, void *ttm, unsigned long start, unsigned long size, 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; @@ -2650,7 +2651,11 @@ int drmBOCreate(int fd, void *ttm, unsigned long start, unsigned long size, } req->op = drm_bo_create; - if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) + do { + ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); + } while (ret != 0 && errno == EAGAIN); + + if (ret) return -errno; if (!arg.handled) { return -EFAULT; -- cgit v1.2.3 From 5881ce1b91034fbdf81dda37a23215cfc1310cdf Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Oct 2006 11:05:37 +0200 Subject: Extend generality for more memory types. Fix up init and destruction code. --- libdrm/xf86drm.c | 31 ++++++++++++++++++++++--------- libdrm/xf86mm.h | 9 +++++---- 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index c7683182..039c9b32 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -3155,19 +3155,16 @@ int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle) return 0; } -int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, - unsigned long ttPOffset, unsigned long ttPSize, - unsigned long max_locked_size) +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.vr_p_offset = vramPOffset; - arg.req.vr_p_size = vramPSize; - arg.req.tt_p_offset = ttPOffset; - arg.req.tt_p_size = ttPSize; - arg.req.max_locked_pages = max_locked_size / getpagesize(); + 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; @@ -3175,13 +3172,29 @@ int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, return 0; } -int drmMMTakedown(int fd) +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 drmMMMaxLockedSize(int fd, unsigned long maxLockedSize) +{ + drm_mm_init_arg_t arg; + + + memset(&arg, 0, sizeof(arg)); + arg.req.op = mm_set_max_pages; + arg.req.p_size = maxLockedSize / getpagesize(); if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg)) return -errno; diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 78df37c3..b2ba24d5 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -195,10 +195,11 @@ extern int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint); * Initialization functions. */ -extern int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize, - unsigned long ttPOffset, unsigned long ttPSize, - unsigned long max_locked_size); -extern int drmMMTakedown(int fd); +extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize, + unsigned memType); +extern int drmMMTakedown(int fd, unsigned memType); +extern int drmMMMaxLockedSize(int fd, unsigned long maxLockedSize); + #endif -- cgit v1.2.3 From 5443dbe35f182b9286a96d24d29037d5cb625e3d Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Oct 2006 16:00:25 +0200 Subject: Implement mm_lock and mm_unlock functions. The mm_lock function is used when leaving vt. It evicts _all_ buffers. Buffers with the DRM_BO_NO_MOVE attribute set will be guaranteed to get the same offset when / if they are rebound. --- libdrm/xf86drm.c | 33 +++++++++++++++++++++++++++++++++ libdrm/xf86mm.h | 3 ++- 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 039c9b32..253ba690 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -3202,4 +3202,37 @@ int drmMMMaxLockedSize(int fd, unsigned long maxLockedSize) 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; +} + + #endif diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index b2ba24d5..c3112c90 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -199,7 +199,8 @@ extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize, unsigned memType); extern int drmMMTakedown(int fd, unsigned memType); extern int drmMMMaxLockedSize(int fd, unsigned long maxLockedSize); - +extern int drmMMLock(int fd, unsigned memType); +extern int drmMMUnlock(int fd, unsigned memType); #endif -- cgit v1.2.3 From c34faf224b959bf61e4c3eb29c66a12edbd31841 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Oct 2006 20:03:26 +0200 Subject: Remove max number of locked pages check and call, since that is now handled by the memory accounting. --- libdrm/xf86drm.c | 15 --------------- libdrm/xf86mm.h | 1 - 2 files changed, 16 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 253ba690..5c799b6d 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -3187,21 +3187,6 @@ int drmMMTakedown(int fd, unsigned memType) return 0; } -int drmMMMaxLockedSize(int fd, unsigned long maxLockedSize) -{ - drm_mm_init_arg_t arg; - - - memset(&arg, 0, sizeof(arg)); - arg.req.op = mm_set_max_pages; - arg.req.p_size = maxLockedSize / getpagesize(); - - if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg)) - return -errno; - - return 0; -} - int drmMMLock(int fd, unsigned memType) { drm_mm_init_arg_t arg; diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index c3112c90..da868fe5 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -198,7 +198,6 @@ extern int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint); extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize, unsigned memType); extern int drmMMTakedown(int fd, unsigned memType); -extern int drmMMMaxLockedSize(int fd, unsigned long maxLockedSize); extern int drmMMLock(int fd, unsigned memType); extern int drmMMUnlock(int fd, unsigned memType); -- cgit v1.2.3 From 25fe4a80490bba709099f0401535d2f96ac7729c Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Oct 2006 20:04:41 +0200 Subject: Remove some debugging messages. --- libdrm/xf86drm.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 5c799b6d..9047c8db 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2786,16 +2786,11 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, fd, buf->mapHandle); if (virtual == MAP_FAILED) { ret = -errno; - fprintf(stderr, "Map error 0x%016llx\n", buf->mapHandle); } if (ret) return ret; buf->mapVirtual = virtual; buf->virtual = ((char *) virtual) + buf->start; -#ifdef BODEBUG - fprintf(stderr,"Mapvirtual, virtual: 0x%08x 0x%08x\n", - buf->mapVirtual, buf->virtual); -#endif } memset(&arg, 0, sizeof(arg)); -- cgit v1.2.3