Since you always need to have a fallback anyway in case you got memory the GPU can't handle (mapped file etc...) you can just call the IOCTL, check the return value and if it didn't worked go the fallback path.

Or do you need to know if it's available or not to make the extension available or not? Mhm, didn't really considered that case while writing it.

Yeah, we should probably have bumped the version number,
Christian.

Am 11.02.2015 um 02:03 schrieb Marek Olšák:
One more thing. How can userspace check if this is supported by the
kernel driver? The DRM version should have been bumped probably.

Marek

On Tue, Feb 10, 2015 at 9:35 AM, Christian König
<[email protected]> wrote:
Am 10.02.2015 um 03:41 schrieb Alex Deucher:
On Mon, Feb 9, 2015 at 7:29 PM, Marek Olšák <[email protected]> wrote:
Hi Christian,

What hardware is this supported on? SI and later? Or even r600? r300?
Theoretically r300 and newer hardware, however, the kernel currently
only allows it on r600 and newer since we never tested it on r300
class hardware.

It also won't work if the AGP GART is used, but using AGP hardware with the
PCIE GART should work fine.

Getting it to work on R300 is just a matter of removing the single line
check in the kernel and really testing it a bit.

Regards,
Christian.


Alex

Thanks,

Marek

On Thu, Feb 5, 2015 at 6:34 PM, Christian König <[email protected]>
wrote:
From: Christian König <[email protected]>

Signed-off-by: Christian König <[email protected]>
---
   src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 102
++++++++++++++++++++++++++
   src/gallium/winsys/radeon/drm/radeon_winsys.h |  11 +++
   2 files changed, 113 insertions(+)

diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 1ebec10..2605ca6 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -42,6 +42,24 @@
   #include <fcntl.h>
   #include <stdio.h>

+#ifndef DRM_RADEON_GEM_USERPTR
+
+#define DRM_RADEON_GEM_USERPTR         0x2d
+
+#define RADEON_GEM_USERPTR_READONLY    (1 << 0)
+#define RADEON_GEM_USERPTR_ANONONLY    (1 << 1)
+#define RADEON_GEM_USERPTR_VALIDATE    (1 << 2)
+#define RADEON_GEM_USERPTR_REGISTER    (1 << 3)
+
+struct drm_radeon_gem_userptr {
+       uint64_t                addr;
+       uint64_t                size;
+       uint32_t                flags;
+       uint32_t                handle;
+};
+
+#endif
+
   extern const struct pb_vtbl radeon_bo_vtbl;

   static INLINE struct radeon_bo *radeon_bo(struct pb_buffer *bo)
@@ -846,6 +864,89 @@ radeon_winsys_bo_create(struct radeon_winsys *rws,
       return (struct pb_buffer*)buffer;
   }

+static struct pb_buffer *radeon_winsys_bo_from_ptr(struct radeon_winsys
*rws,
+                                                   void *pointer,
unsigned size)
+{
+    struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
+    struct radeon_bomgr *mgr = radeon_bomgr(ws->kman);
+    struct drm_radeon_gem_userptr args;
+    struct radeon_bo *bo;
+    int r;
+
+    bo = CALLOC_STRUCT(radeon_bo);
+    if (!bo)
+        return NULL;
+
+    memset(&args, 0, sizeof(args));
+    args.addr = (uintptr_t)pointer;
+    args.size = size;
+    args.flags = RADEON_GEM_USERPTR_ANONONLY |
+        RADEON_GEM_USERPTR_VALIDATE |
+        RADEON_GEM_USERPTR_REGISTER;
+    if (drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_USERPTR,
+                            &args, sizeof(args))) {
+        FREE(bo);
+        return NULL;
+    }
+
+    pipe_mutex_lock(mgr->bo_handles_mutex);
+
+    /* Initialize it. */
+    pipe_reference_init(&bo->base.reference, 1);
+    bo->handle = args.handle;
+    bo->base.alignment = 0;
+    bo->base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
+    bo->base.size = size;
+    bo->base.vtbl = &radeon_bo_vtbl;
+    bo->mgr = mgr;
+    bo->rws = mgr->rws;
+    bo->va = 0;
+    bo->initial_domain = RADEON_DOMAIN_GTT;
+    pipe_mutex_init(bo->map_mutex);
+
+    util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)bo->handle,
bo);
+
+    pipe_mutex_unlock(mgr->bo_handles_mutex);
+
+    if (mgr->va) {
+        struct drm_radeon_gem_va va;
+
+        bo->va = radeon_bomgr_find_va(mgr, bo->base.size, 1 << 20);
+
+        va.handle = bo->handle;
+        va.operation = RADEON_VA_MAP;
+        va.vm_id = 0;
+        va.offset = bo->va;
+        va.flags = RADEON_VM_PAGE_READABLE |
+                   RADEON_VM_PAGE_WRITEABLE |
+                   RADEON_VM_PAGE_SNOOPED;
+        va.offset = bo->va;
+        r = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_VA, &va,
sizeof(va));
+        if (r && va.operation == RADEON_VA_RESULT_ERROR) {
+            fprintf(stderr, "radeon: Failed to assign virtual address
space\n");
+            radeon_bo_destroy(&bo->base);
+            return NULL;
+        }
+        pipe_mutex_lock(mgr->bo_handles_mutex);
+        if (va.operation == RADEON_VA_RESULT_VA_EXIST) {
+            struct pb_buffer *b = &bo->base;
+            struct radeon_bo *old_bo =
+                util_hash_table_get(mgr->bo_vas,
(void*)(uintptr_t)va.offset);
+
+            pipe_mutex_unlock(mgr->bo_handles_mutex);
+            pb_reference(&b, &old_bo->base);
+            return b;
+        }
+
+        util_hash_table_set(mgr->bo_vas, (void*)(uintptr_t)bo->va, bo);
+        pipe_mutex_unlock(mgr->bo_handles_mutex);
+    }
+
+    ws->allocated_gtt += align(bo->base.size, 4096);
+
+    return (struct pb_buffer*)bo;
+}
+
   static struct pb_buffer *radeon_winsys_bo_from_handle(struct
radeon_winsys *rws,
                                                         struct
winsys_handle *whandle,
                                                         unsigned
*stride)
@@ -1040,6 +1141,7 @@ void radeon_bomgr_init_functions(struct
radeon_drm_winsys *ws)
       ws->base.buffer_is_busy = radeon_bo_is_busy;
       ws->base.buffer_create = radeon_winsys_bo_create;
       ws->base.buffer_from_handle = radeon_winsys_bo_from_handle;
+    ws->base.buffer_from_ptr = radeon_winsys_bo_from_ptr;
       ws->base.buffer_get_handle = radeon_winsys_bo_get_handle;
       ws->base.buffer_get_virtual_address = radeon_winsys_bo_va;
       ws->base.buffer_get_initial_domain = radeon_bo_get_initial_domain;
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h
b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index 5dc9313..d9fa1ab 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -394,6 +394,17 @@ struct radeon_winsys {
                                               unsigned *stride);

       /**
+     * Get a winsys buffer from a user pointer. The resulting buffer
can't be
+     * mapped or exported. Both pointer and size must be page aligned.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param pointer   User pointer to turn into a buffer object.
+     * \param Size      Size in bytes for the new buffer.
+     */
+    struct pb_buffer *(*buffer_from_ptr)(struct radeon_winsys *ws,
+                                         void *pointer, unsigned size);
+
+    /**
        * Get a winsys handle from a winsys buffer. The internal
structure
        * of the handle is platform-specific and only a winsys should
access it.
        *
--
1.9.1

_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to