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