mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 02:30:12 +01:00
virgl: add support for VIRGL_CAP_V2_UNTYPED_RESOURCE
An untyped resource is a blob resource that contains only raw bytes without type information (e.g., width, height, format, etc.). virgl supports only typed resources, and when it encounters untyped resources, it fails silently in the host. This cap enables virgl to assign type information to untyped resources. Signed-off-by: Chia-I Wu <olvaffe@gmail.com> Reviewed-By: Isaac Bosompem <mrisaacb@google.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8584>
This commit is contained in:
parent
41366ba494
commit
d37124b065
4 changed files with 116 additions and 0 deletions
|
|
@ -582,6 +582,49 @@ static struct pipe_resource *virgl_resource_from_handle(struct pipe_screen *scre
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* assign blob resource a type in case it was created untyped */
|
||||
if (res->blob_mem && plane == 0 &&
|
||||
(vs->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_UNTYPED_RESOURCE)) {
|
||||
uint32_t plane_strides[VIRGL_MAX_PLANE_COUNT];
|
||||
uint32_t plane_offsets[VIRGL_MAX_PLANE_COUNT];
|
||||
uint32_t plane_count = 0;
|
||||
struct pipe_resource *iter = &res->u.b;
|
||||
|
||||
do {
|
||||
struct virgl_resource *plane = virgl_resource(iter);
|
||||
|
||||
/* must be a plain 2D texture sharing the same hw_res */
|
||||
if (plane->u.b.target != PIPE_TEXTURE_2D ||
|
||||
plane->u.b.depth0 != 1 ||
|
||||
plane->u.b.array_size != 1 ||
|
||||
plane->u.b.last_level != 0 ||
|
||||
plane->u.b.nr_samples > 1 ||
|
||||
plane->hw_res != res->hw_res ||
|
||||
plane_count >= VIRGL_MAX_PLANE_COUNT) {
|
||||
vs->vws->resource_reference(vs->vws, &res->hw_res, NULL);
|
||||
FREE(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plane_strides[plane_count] = plane->metadata.stride[0];
|
||||
plane_offsets[plane_count] = plane->metadata.plane_offset;
|
||||
plane_count++;
|
||||
iter = iter->next;
|
||||
} while (iter);
|
||||
|
||||
vs->vws->resource_set_type(vs->vws,
|
||||
res->hw_res,
|
||||
pipe_to_virgl_format(res->u.b.format),
|
||||
pipe_to_virgl_bind(vs, res->u.b.bind),
|
||||
res->u.b.width0,
|
||||
res->u.b.height0,
|
||||
usage,
|
||||
res->metadata.modifier,
|
||||
plane_count,
|
||||
plane_strides,
|
||||
plane_offsets);
|
||||
}
|
||||
|
||||
virgl_texture_init(res);
|
||||
|
||||
return &res->u.b;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct virgl_hw_res;
|
|||
|
||||
#define VIRGL_MAX_TBUF_DWORDS 1024
|
||||
#define VIRGL_MAX_CMDBUF_DWORDS ((64 * 1024) + VIRGL_MAX_TBUF_DWORDS)
|
||||
#define VIRGL_MAX_PLANE_COUNT 3
|
||||
|
||||
struct virgl_drm_caps {
|
||||
union virgl_caps caps;
|
||||
|
|
@ -87,6 +88,15 @@ struct virgl_winsys {
|
|||
uint32_t *plane_offset,
|
||||
uint64_t *modifier,
|
||||
uint32_t *blob_mem);
|
||||
void (*resource_set_type)(struct virgl_winsys *vws,
|
||||
struct virgl_hw_res *res,
|
||||
uint32_t format, uint32_t bind,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t usage, uint64_t modifier,
|
||||
uint32_t plane_count,
|
||||
const uint32_t *plane_strides,
|
||||
const uint32_t *plane_offsets);
|
||||
|
||||
boolean (*resource_get_handle)(struct virgl_winsys *vws,
|
||||
struct virgl_hw_res *res,
|
||||
uint32_t stride,
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@ virgl_drm_winsys_resource_create_blob(struct virgl_winsys *qws,
|
|||
res->bo_handle = drm_rc_blob.bo_handle;
|
||||
res->size = size;
|
||||
res->flags = flags;
|
||||
res->maybe_untyped = false;
|
||||
pipe_reference_init(&res->reference, 1);
|
||||
p_atomic_set(&res->external, false);
|
||||
p_atomic_set(&res->num_cs_references, 0);
|
||||
|
|
@ -267,6 +268,7 @@ virgl_drm_winsys_resource_create(struct virgl_winsys *qws,
|
|||
res->bo_handle = createcmd.bo_handle;
|
||||
res->size = size;
|
||||
res->target = target;
|
||||
res->maybe_untyped = false;
|
||||
pipe_reference_init(&res->reference, 1);
|
||||
p_atomic_set(&res->external, false);
|
||||
p_atomic_set(&res->num_cs_references, 0);
|
||||
|
|
@ -425,6 +427,10 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
|
|||
struct virgl_hw_res *res = NULL;
|
||||
uint32_t handle = whandle->handle;
|
||||
|
||||
if (whandle->plane >= VIRGL_MAX_PLANE_COUNT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (whandle->offset != 0 && whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
|
||||
_debug_printf("attempt to import unsupported winsys offset %u\n",
|
||||
whandle->offset);
|
||||
|
|
@ -496,6 +502,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
|
|||
*blob_mem = info_arg.blob_mem;
|
||||
|
||||
res->size = info_arg.size;
|
||||
res->maybe_untyped = info_arg.blob_mem ? true : false;
|
||||
pipe_reference_init(&res->reference, 1);
|
||||
p_atomic_set(&res->external, true);
|
||||
res->num_cs_references = 0;
|
||||
|
|
@ -509,6 +516,58 @@ done:
|
|||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
virgl_drm_winsys_resource_set_type(struct virgl_winsys *qws,
|
||||
struct virgl_hw_res *res,
|
||||
uint32_t format, uint32_t bind,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t usage, uint64_t modifier,
|
||||
uint32_t plane_count,
|
||||
const uint32_t *plane_strides,
|
||||
const uint32_t *plane_offsets)
|
||||
{
|
||||
struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
|
||||
uint32_t cmd[VIRGL_PIPE_RES_SET_TYPE_SIZE(VIRGL_MAX_PLANE_COUNT)];
|
||||
struct drm_virtgpu_execbuffer eb;
|
||||
int ret;
|
||||
|
||||
mtx_lock(&qdws->bo_handles_mutex);
|
||||
|
||||
if (!res->maybe_untyped) {
|
||||
mtx_unlock(&qdws->bo_handles_mutex);
|
||||
return;
|
||||
}
|
||||
res->maybe_untyped = false;
|
||||
|
||||
assert(plane_count && plane_count <= VIRGL_MAX_PLANE_COUNT);
|
||||
|
||||
cmd[0] = VIRGL_CMD0(VIRGL_CCMD_PIPE_RESOURCE_SET_TYPE, 0, VIRGL_PIPE_RES_SET_TYPE_SIZE(plane_count));
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_RES_HANDLE] = res->res_handle,
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_FORMAT] = format;
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_BIND] = bind;
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_WIDTH] = width;
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_HEIGHT] = height;
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_USAGE] = usage;
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_MODIFIER_LO] = (uint32_t)modifier;
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_MODIFIER_HI] = (uint32_t)(modifier >> 32);
|
||||
for (uint32_t i = 0; i < plane_count; i++) {
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_PLANE_STRIDE(i)] = plane_strides[i];
|
||||
cmd[VIRGL_PIPE_RES_SET_TYPE_PLANE_OFFSET(i)] = plane_offsets[i];
|
||||
}
|
||||
|
||||
memset(&eb, 0, sizeof(eb));
|
||||
eb.command = (uintptr_t)cmd;
|
||||
eb.size = (1 + VIRGL_PIPE_RES_SET_TYPE_SIZE(plane_count)) * 4;
|
||||
eb.num_bo_handles = 1;
|
||||
eb.bo_handles = (uintptr_t)&res->bo_handle;
|
||||
|
||||
ret = drmIoctl(qdws->fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &eb);
|
||||
if (ret == -1)
|
||||
_debug_printf("failed to set resource type: %s", errno);
|
||||
|
||||
mtx_unlock(&qdws->bo_handles_mutex);
|
||||
}
|
||||
|
||||
static boolean virgl_drm_winsys_resource_get_handle(struct virgl_winsys *qws,
|
||||
struct virgl_hw_res *res,
|
||||
uint32_t stride,
|
||||
|
|
@ -1091,6 +1150,7 @@ virgl_drm_winsys_create(int drmFD)
|
|||
qdws->base.resource_create = virgl_drm_winsys_resource_cache_create;
|
||||
qdws->base.resource_reference = virgl_drm_resource_reference;
|
||||
qdws->base.resource_create_from_handle = virgl_drm_winsys_resource_create_handle;
|
||||
qdws->base.resource_set_type = virgl_drm_winsys_resource_set_type;
|
||||
qdws->base.resource_get_handle = virgl_drm_winsys_resource_get_handle;
|
||||
qdws->base.resource_map = virgl_drm_resource_map;
|
||||
qdws->base.resource_wait = virgl_drm_resource_wait;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ struct virgl_hw_res {
|
|||
uint32_t flags;
|
||||
uint32_t flink_name;
|
||||
|
||||
/* false when the resource is known to be typed */
|
||||
bool maybe_untyped;
|
||||
|
||||
/* true when the resource is imported or exported */
|
||||
int external;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue