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. 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
