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
