From 7b59e9b6e180c887b44356891abdf958643de047 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 30 Jul 2009 00:40:37 +0100 Subject: First part of GEM memory mapping implementation --- glamo/glamo_bo.h | 8 ++--- glamo/glamo_bo_gem.c | 77 +++++++++++++++++++++++++++++++++---------------- include/drm/glamo_drm.h | 13 ++++----- 3 files changed, 61 insertions(+), 37 deletions(-) diff --git a/glamo/glamo_bo.h b/glamo/glamo_bo.h index dcbe00a6..8ef2a18b 100644 --- a/glamo/glamo_bo.h +++ b/glamo/glamo_bo.h @@ -52,11 +52,11 @@ struct glamo_bo { uint32_t flags; unsigned cref; #ifdef GLAMO_BO_TRACK - struct glamo_track *track; + struct glamo_track *track; #endif - void *ptr; - struct glamo_bo_manager *bom; - uint32_t space_accounted; + struct glamo_bo_manager *bom; + void *virtual; + uint32_t space_accounted; }; /* bo functions */ diff --git a/glamo/glamo_bo_gem.c b/glamo/glamo_bo_gem.c index 6dc5a148..d53720e7 100644 --- a/glamo/glamo_bo_gem.c +++ b/glamo/glamo_bo_gem.c @@ -49,6 +49,7 @@ struct glamo_bo_gem { struct glamo_bo base; uint32_t name; int map_count; + void *virtual; }; struct bo_manager_gem { @@ -78,8 +79,8 @@ static struct glamo_bo *bo_open(struct glamo_bo_manager *bom, bo->base.alignment = alignment; bo->base.domains = domains; bo->base.flags = flags; - bo->base.ptr = NULL; bo->map_count = 0; + bo->virtual = NULL; if (handle) { struct drm_gem_open open_arg; @@ -133,7 +134,7 @@ static struct glamo_bo *bo_unref(struct glamo_bo *bo) return bo; } if (bo_gem->map_count) { - munmap(bo->ptr, bo->size); + munmap(bo->virtual, bo->size); } /* close object */ @@ -146,28 +147,54 @@ static struct glamo_bo *bo_unref(struct glamo_bo *bo) static int bo_map(struct glamo_bo *bo, int write) { - struct glamo_bo_gem *bo_gem = (struct glamo_bo_gem*)bo; - struct drm_glamo_gem_mmap args; - int r; + struct glamo_bo_gem *bo_gem; + struct glamo_bo_manager *bufmgr; + int ret; - if (bo_gem->map_count++ != 0) { - return 0; - } - bo->ptr = NULL; - args.handle = bo->handle; - args.offset = 0; - args.size = (uint64_t)bo->size; - r = drmCommandWriteRead(bo->bom->fd, - DRM_GLAMO_GEM_MMAP, - &args, - sizeof(args)); - if (!r) { - bo->ptr = (void *)(unsigned long)args.addr_ptr; - } else { - fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n", - bo, bo->handle, r); - } - return r; + bo_gem = (struct glamo_bo_gem *)bo; + bufmgr = (struct glamo_bo_manager*)bo->bom; + + /* Get a mapping of the buffer if we haven't before. */ + if (bo_gem->virtual == NULL) { + + struct drm_glamo_gem_mmap mmap_arg; + + memset(&mmap_arg, 0, sizeof(mmap_arg)); + mmap_arg.handle = bo->handle; + + /* Get the fake offset back... */ + ret = ioctl(bufmgr->fd, DRM_IOCTL_GLAMO_GEM_MMAP, &mmap_arg); + if (ret != 0) { + fprintf(stderr, + "%s:%d: Error preparing BO map %d (%d): %s .\n", + __FILE__, __LINE__, + bo->handle, bo_gem->name, + strerror(errno)); + return ret; + } + fprintf(stderr, "offset=%8llx\n", + (long long int)mmap_arg.offset); + + /* and mmap it */ + bo_gem->virtual = mmap(0, bo->size, PROT_READ | PROT_WRITE, + MAP_SHARED, bufmgr->fd, + mmap_arg.offset); + if (bo_gem->virtual == MAP_FAILED) { + fprintf(stderr, + "%s:%d: Error mapping buffer %d (%d): %s .\n", + __FILE__, __LINE__, + bo->handle, bo_gem->name, + strerror(errno)); + return errno; + } + } + + bo->virtual = bo_gem->virtual; + + printf("bo_map: %d (%d) -> %p\n", bo->handle, bo_gem->name, + bo_gem->virtual); + + return 0; } static int bo_unmap(struct glamo_bo *bo) @@ -177,8 +204,8 @@ static int bo_unmap(struct glamo_bo *bo) if (--bo_gem->map_count > 0) { return 0; } - munmap(bo->ptr, bo->size); - bo->ptr = NULL; + munmap(bo->virtual, bo->size); + bo->virtual = NULL; return 0; } diff --git a/include/drm/glamo_drm.h b/include/drm/glamo_drm.h index 1b585e4f..c0bc0e5a 100644 --- a/include/drm/glamo_drm.h +++ b/include/drm/glamo_drm.h @@ -65,11 +65,11 @@ #define DRM_IOCTL_GLAMO_GEM_WAIT_RENDERING DRM_IOW(DRM_COMMAND_BASE + DRM_GLAMO_GEM_WAIT_RENDERING, struct drm_glamo_gem_wait_rendering) typedef struct drm_glamo_cmd_buffer { - int bufsz; /* Size of buffer, in bytes */ + unsigned int bufsz; /* Size of buffer, in bytes */ char __user *buf; /* Buffer of stuff to go onto the ring buffer */ - int *obj_pos; /* Offsets (in bytes) at which to put objs */ + unsigned int *obj_pos; /* Offsets (in bytes) at which to put objs */ uint32_t *objs; /* List of buffer object (handles) to use */ - int nobjs; /* Number of objects referenced */ + unsigned int nobjs; /* Number of objects referenced */ int nbox; struct drm_clip_rect __user *boxes; } drm_glamo_cmd_buffer_t; @@ -88,11 +88,8 @@ struct drm_glamo_gem_create { }; struct drm_glamo_gem_mmap { - uint32_t handle; - uint32_t pad; - uint64_t offset; - uint64_t size; - uint64_t addr_ptr; + uint32_t handle; /* Handle goes in... */ + uint64_t offset; /* ...offset comes out */ }; struct drm_glamo_gem_wait_rendering { -- cgit v1.2.3