[Mesa-dev] [PATCH] winsys/radeon: add user pointer support
Marek Olšák
maraeo at gmail.com
Wed Feb 11 01:59:00 PST 2015
On Wed, Feb 11, 2015 at 9:48 AM, Christian König
<deathsimple at vodafone.de> wrote:
> 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.
Yes. As an alternative plan, I guess I can try calling the ioctl with
a NULL pointer during winsys initialization. Is there a special return
value that will tell me the ioctl doesn't exist? It's a crude way of
checking for ioctl support indeed, but it might be sufficient.
Marek
>
> 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
>> <deathsimple at vodafone.de> wrote:
>>>
>>> Am 10.02.2015 um 03:41 schrieb Alex Deucher:
>>>>
>>>> On Mon, Feb 9, 2015 at 7:29 PM, Marek Olšák <maraeo at gmail.com> 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
>>>>> <deathsimple at vodafone.de>
>>>>> wrote:
>>>>>>
>>>>>> From: Christian König <christian.koenig at amd.com>
>>>>>>
>>>>>> Signed-off-by: Christian König <christian.koenig at amd.com>
>>>>>> ---
>>>>>> 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
>>>>>> mesa-dev at lists.freedesktop.org
>>>>>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>>>>
>>>>> _______________________________________________
>>>>> mesa-dev mailing list
>>>>> mesa-dev at lists.freedesktop.org
>>>>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>>
>>>
>
More information about the mesa-dev
mailing list