summaryrefslogtreecommitdiff
path: root/libdrm
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-08-30 15:08:40 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-08-30 15:08:40 +0200
commit14a835be616183e733a2d6a7dcc697b8a6f46caf (patch)
treeadaa844d3d5955681442df5032c4ef8b76683f1d /libdrm
parente47a4fda2ef7aada45b7799ad20e8012102dc12e (diff)
Buffer object mapping and mapping synchronization for multiple clients.
Diffstat (limited to 'libdrm')
-rw-r--r--libdrm/xf86drm.c103
-rw-r--r--libdrm/xf86mm.h8
2 files changed, 99 insertions, 12 deletions
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;