* Copyright © 2008 Jérôme Glisse
* All Rights Reserved.
*
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
+ * 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
+ * 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
* Dave Airlie
* Jérôme Glisse <glisse@freedesktop.org>
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
+#include <errno.h>
#include "xf86drm.h"
#include "drm.h"
#include "radeon_drm.h"
struct radeon_bo base;
uint32_t name;
int map_count;
+ void *priv_ptr;
};
struct bo_manager_gem {
struct radeon_bo_manager base;
};
+static int bo_wait(struct radeon_bo *bo);
+
static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
uint32_t handle,
uint32_t size,
open_arg.name = handle;
r = ioctl(bom->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
if (r != 0) {
- fprintf(stderr, "GEM open failed: %d (%s)\n",r,strerror(r));
free(bo);
return NULL;
}
args.size = size;
args.alignment = alignment;
args.initial_domain = bo->base.domains;
- args.no_backing_store = 0;
+ args.flags = 0;
+ args.handle = 0;
r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE,
&args, sizeof(args));
bo->base.handle = args.handle;
if (r) {
+ fprintf(stderr, "Failed to allocate :\n");
+ fprintf(stderr, " size : %d bytes\n", size);
+ fprintf(stderr, " alignment : %d bytes\n", alignment);
+ fprintf(stderr, " domains : %d\n", bo->base.domains);
free(bo);
return NULL;
}
}
+ radeon_bo_ref((struct radeon_bo*)bo);
return (struct radeon_bo*)bo;
}
{
}
-static void bo_unref(struct radeon_bo *bo)
+static struct radeon_bo *bo_unref(struct radeon_bo *bo)
{
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
struct drm_gem_close args;
if (bo == NULL) {
- return;
+ return NULL;
}
if (bo->cref) {
- /* FIXME: what to do ? */
- return;
+ return bo;
}
- if (bo_gem->map_count) {
- munmap(bo->ptr, bo->size);
+ if (bo_gem->priv_ptr) {
+ munmap(bo_gem->priv_ptr, bo->size);
}
/* close object */
args.handle = bo->handle;
ioctl(bo->bom->fd, DRM_IOCTL_GEM_CLOSE, &args);
+ memset(bo_gem, 0, sizeof(struct radeon_bo_gem));
free(bo_gem);
+ return NULL;
}
static int bo_map(struct radeon_bo *bo, int write)
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
struct drm_radeon_gem_mmap args;
int r;
- uint8_t *tt;
+ void *ptr;
if (bo_gem->map_count++ != 0) {
return 0;
}
+ if (bo_gem->priv_ptr) {
+ goto wait;
+ }
+
bo->ptr = NULL;
args.handle = bo->handle;
args.offset = 0;
DRM_RADEON_GEM_MMAP,
&args,
sizeof(args));
- if (!r) {
- bo->ptr = (void *)(unsigned long)args.addr_ptr;
+ if (r) {
+ fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n",
+ bo, bo->handle, r);
+ return r;
}
- tt = bo->ptr;
- return r;
+ ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, bo->bom->fd, args.addr_ptr);
+ if (ptr == MAP_FAILED)
+ return -errno;
+ bo_gem->priv_ptr = ptr;
+wait:
+ bo->ptr = bo_gem->priv_ptr;
+ r = bo_wait(bo);
+ if (r)
+ return r;
+ return 0;
}
static int bo_unmap(struct radeon_bo *bo)
if (--bo_gem->map_count > 0) {
return 0;
}
- munmap(bo->ptr, bo->size);
+ //munmap(bo->ptr, bo->size);
bo->ptr = NULL;
return 0;
}
+static int bo_wait(struct radeon_bo *bo)
+{
+ struct drm_radeon_gem_wait_idle args;
+ int ret;
+
+ args.handle = bo->handle;
+ do {
+ ret = drmCommandWriteRead(bo->bom->fd, DRM_RADEON_GEM_WAIT_IDLE,
+ &args, sizeof(args));
+ } while (ret == -EBUSY);
+ return ret;
+}
+
+static int bo_is_busy(struct radeon_bo *bo, uint32_t *domain)
+{
+ struct drm_radeon_gem_busy args;
+ int ret;
+
+ args.handle = bo->handle;
+ args.domain = 0;
+
+ ret = drmCommandWriteRead(bo->bom->fd, DRM_RADEON_GEM_BUSY,
+ &args, sizeof(args));
+
+ *domain = args.domain;
+ return ret;
+}
+
+static int bo_set_tiling(struct radeon_bo *bo, uint32_t tiling_flags,
+ uint32_t pitch)
+{
+ struct drm_radeon_gem_set_tiling args;
+ int r;
+
+ args.handle = bo->handle;
+ args.tiling_flags = tiling_flags;
+ args.pitch = pitch;
+
+ r = drmCommandWriteRead(bo->bom->fd,
+ DRM_RADEON_GEM_SET_TILING,
+ &args,
+ sizeof(args));
+ return r;
+}
+
+static int bo_get_tiling(struct radeon_bo *bo, uint32_t *tiling_flags,
+ uint32_t *pitch)
+{
+ struct drm_radeon_gem_set_tiling args;
+ int r;
+
+ args.handle = bo->handle;
+
+ r = drmCommandWriteRead(bo->bom->fd,
+ DRM_RADEON_GEM_GET_TILING,
+ &args,
+ sizeof(args));
+
+ if (r)
+ return r;
+
+ *tiling_flags = args.tiling_flags;
+ *pitch = args.pitch;
+ return r;
+}
+
static struct radeon_bo_funcs bo_gem_funcs = {
bo_open,
bo_ref,
bo_unref,
bo_map,
- bo_unmap
+ bo_unmap,
+ bo_wait,
+ NULL,
+ bo_set_tiling,
+ bo_get_tiling,
+ bo_is_busy,
};
-struct radeon_bo_manager *radeon_bo_manager_gem(int fd)
+struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
{
struct bo_manager_gem *bomg;
return (struct radeon_bo_manager*)bomg;
}
-void radeon_bo_manager_gem_shutdown(struct radeon_bo_manager *bom)
+void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
{
struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
}
free(bomg);
}
+
+uint32_t radeon_gem_name_bo(struct radeon_bo *bo)
+{
+ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
+ return bo_gem->name;
+}
+
+int radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
+{
+ struct drm_gem_flink flink;
+ int r;
+
+ flink.handle = bo->handle;
+ r = ioctl(bo->bom->fd, DRM_IOCTL_GEM_FLINK, &flink);
+ if (r) {
+ return r;
+ }
+ *name = flink.name;
+ return 0;
+}
+
+int radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
+{
+ struct drm_radeon_gem_set_domain args;
+ int r;
+
+ args.handle = bo->handle;
+ args.read_domains = read_domains;
+ args.write_domain = write_domain;
+
+ r = drmCommandWriteRead(bo->bom->fd,
+ DRM_RADEON_GEM_SET_DOMAIN,
+ &args,
+ sizeof(args));
+ return r;
+}