summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/virgl/drm
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2020-12-24 15:37:15 -0800
committerMarge Bot <eric+marge@anholt.net>2021-01-22 21:25:49 +0000
commitd37124b065c2b6c99c042fb402c6a23ce16b034e (patch)
treeb6d6033c0bb895421feb934d724c85a930698d7a /src/gallium/winsys/virgl/drm
parent41366ba49424592086cba0c32aa26e72482411e6 (diff)
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>
Diffstat (limited to 'src/gallium/winsys/virgl/drm')
-rw-r--r--src/gallium/winsys/virgl/drm/virgl_drm_winsys.c60
-rw-r--r--src/gallium/winsys/virgl/drm/virgl_drm_winsys.h3
2 files changed, 63 insertions, 0 deletions
diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
index 2be575fb21d..bf79ba7ddf7 100644
--- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
+++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
@@ -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;
diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h
index 1d7f03de264..28fb9715aaf 100644
--- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h
+++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h
@@ -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;