crocus: hook up memory object creation from handle
Port cdb5a72764
from iris
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11352>
This commit is contained in:
@@ -1289,6 +1289,59 @@ err:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct crocus_bo *
|
||||||
|
crocus_bo_import_dmabuf_no_mods(struct crocus_bufmgr *bufmgr,
|
||||||
|
int prime_fd)
|
||||||
|
{
|
||||||
|
uint32_t handle;
|
||||||
|
struct crocus_bo *bo;
|
||||||
|
|
||||||
|
mtx_lock(&bufmgr->lock);
|
||||||
|
int ret = drmPrimeFDToHandle(bufmgr->fd, prime_fd, &handle);
|
||||||
|
if (ret) {
|
||||||
|
DBG("import_dmabuf: failed to obtain handle from fd: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
mtx_unlock(&bufmgr->lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if the kernel has already returned this buffer to us. Just as
|
||||||
|
* for named buffers, we must not create two bo's pointing at the same
|
||||||
|
* kernel object
|
||||||
|
*/
|
||||||
|
bo = find_and_ref_external_bo(bufmgr->handle_table, handle);
|
||||||
|
if (bo)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
bo = bo_calloc();
|
||||||
|
if (!bo)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
p_atomic_set(&bo->refcount, 1);
|
||||||
|
|
||||||
|
/* Determine size of bo. The fd-to-handle ioctl really should
|
||||||
|
* return the size, but it doesn't. If we have kernel 3.12 or
|
||||||
|
* later, we can lseek on the prime fd to get the size. Older
|
||||||
|
* kernels will just fail, in which case we fall back to the
|
||||||
|
* provided (estimated or guess size). */
|
||||||
|
ret = lseek(prime_fd, 0, SEEK_END);
|
||||||
|
if (ret != -1)
|
||||||
|
bo->size = ret;
|
||||||
|
|
||||||
|
bo->bufmgr = bufmgr;
|
||||||
|
bo->name = "prime";
|
||||||
|
bo->reusable = false;
|
||||||
|
bo->external = true;
|
||||||
|
bo->kflags = 0;
|
||||||
|
bo->gem_handle = handle;
|
||||||
|
_mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo);
|
||||||
|
|
||||||
|
out:
|
||||||
|
mtx_unlock(&bufmgr->lock);
|
||||||
|
return bo;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
crocus_bo_make_external_locked(struct crocus_bo *bo)
|
crocus_bo_make_external_locked(struct crocus_bo *bo)
|
||||||
{
|
{
|
||||||
|
@@ -307,6 +307,8 @@ void crocus_destroy_hw_context(struct crocus_bufmgr *bufmgr, uint32_t ctx_id);
|
|||||||
int crocus_bo_export_dmabuf(struct crocus_bo *bo, int *prime_fd);
|
int crocus_bo_export_dmabuf(struct crocus_bo *bo, int *prime_fd);
|
||||||
struct crocus_bo *crocus_bo_import_dmabuf(struct crocus_bufmgr *bufmgr,
|
struct crocus_bo *crocus_bo_import_dmabuf(struct crocus_bufmgr *bufmgr,
|
||||||
int prime_fd, uint64_t modifier);
|
int prime_fd, uint64_t modifier);
|
||||||
|
struct crocus_bo *crocus_bo_import_dmabuf_no_mods(struct crocus_bufmgr *bufmgr,
|
||||||
|
int prime_fd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports a bo as a GEM handle into a given DRM file descriptor
|
* Exports a bo as a GEM handle into a given DRM file descriptor
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
#include "util/u_transfer_helper.h"
|
#include "util/u_transfer_helper.h"
|
||||||
#include "util/u_upload_mgr.h"
|
#include "util/u_upload_mgr.h"
|
||||||
#include "util/ralloc.h"
|
#include "util/ralloc.h"
|
||||||
|
#include "util/u_memory.h"
|
||||||
#include "crocus_batch.h"
|
#include "crocus_batch.h"
|
||||||
#include "crocus_context.h"
|
#include "crocus_context.h"
|
||||||
#include "crocus_resource.h"
|
#include "crocus_resource.h"
|
||||||
@@ -1889,6 +1890,66 @@ crocus_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier
|
|||||||
return util_format_get_num_planes(format);
|
return util_format_get_num_planes(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct pipe_memory_object *
|
||||||
|
crocus_memobj_create_from_handle(struct pipe_screen *pscreen,
|
||||||
|
struct winsys_handle *whandle,
|
||||||
|
bool dedicated)
|
||||||
|
{
|
||||||
|
struct crocus_screen *screen = (struct crocus_screen *)pscreen;
|
||||||
|
struct crocus_memory_object *memobj = CALLOC_STRUCT(crocus_memory_object);
|
||||||
|
struct crocus_bo *bo;
|
||||||
|
const struct isl_drm_modifier_info *mod_inf;
|
||||||
|
|
||||||
|
if (!memobj)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
switch (whandle->type) {
|
||||||
|
case WINSYS_HANDLE_TYPE_SHARED:
|
||||||
|
bo = crocus_bo_gem_create_from_name(screen->bufmgr, "winsys image",
|
||||||
|
whandle->handle);
|
||||||
|
break;
|
||||||
|
case WINSYS_HANDLE_TYPE_FD:
|
||||||
|
mod_inf = isl_drm_modifier_get_info(whandle->modifier);
|
||||||
|
if (mod_inf) {
|
||||||
|
bo = crocus_bo_import_dmabuf(screen->bufmgr, whandle->handle,
|
||||||
|
whandle->modifier);
|
||||||
|
} else {
|
||||||
|
/* If we can't get information about the tiling from the
|
||||||
|
* kernel we ignore it. We are going to set it when we
|
||||||
|
* create the resource.
|
||||||
|
*/
|
||||||
|
bo = crocus_bo_import_dmabuf_no_mods(screen->bufmgr,
|
||||||
|
whandle->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unreachable("invalid winsys handle type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bo) {
|
||||||
|
free(memobj);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memobj->b.dedicated = dedicated;
|
||||||
|
memobj->bo = bo;
|
||||||
|
|
||||||
|
crocus_bo_reference(memobj->bo);
|
||||||
|
|
||||||
|
return &memobj->b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
crocus_memobj_destroy(struct pipe_screen *pscreen,
|
||||||
|
struct pipe_memory_object *pmemobj)
|
||||||
|
{
|
||||||
|
struct crocus_memory_object *memobj = (struct crocus_memory_object *)pmemobj;
|
||||||
|
|
||||||
|
crocus_bo_unreference(memobj->bo);
|
||||||
|
free(memobj);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
crocus_init_screen_resource_functions(struct pipe_screen *pscreen)
|
crocus_init_screen_resource_functions(struct pipe_screen *pscreen)
|
||||||
{
|
{
|
||||||
@@ -1904,6 +1965,8 @@ crocus_init_screen_resource_functions(struct pipe_screen *pscreen)
|
|||||||
pscreen->resource_get_handle = crocus_resource_get_handle;
|
pscreen->resource_get_handle = crocus_resource_get_handle;
|
||||||
pscreen->resource_get_param = crocus_resource_get_param;
|
pscreen->resource_get_param = crocus_resource_get_param;
|
||||||
pscreen->resource_destroy = u_transfer_helper_resource_destroy;
|
pscreen->resource_destroy = u_transfer_helper_resource_destroy;
|
||||||
|
pscreen->memobj_create_from_handle = crocus_memobj_create_from_handle;
|
||||||
|
pscreen->memobj_destroy = crocus_memobj_destroy;
|
||||||
pscreen->transfer_helper =
|
pscreen->transfer_helper =
|
||||||
u_transfer_helper_create(&transfer_vtbl, screen->devinfo.ver >= 6,
|
u_transfer_helper_create(&transfer_vtbl, screen->devinfo.ver >= 6,
|
||||||
screen->devinfo.ver >= 6, false, true);
|
screen->devinfo.ver >= 6, false, true);
|
||||||
|
@@ -282,6 +282,14 @@ struct crocus_transfer {
|
|||||||
void (*unmap)(struct crocus_transfer *);
|
void (*unmap)(struct crocus_transfer *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory Object
|
||||||
|
*/
|
||||||
|
struct crocus_memory_object {
|
||||||
|
struct pipe_memory_object b;
|
||||||
|
struct crocus_bo *bo;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unwrap a pipe_resource to get the underlying crocus_bo (for convenience).
|
* Unwrap a pipe_resource to get the underlying crocus_bo (for convenience).
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user