From 36d050210ea854f2632c8c2a960dca94dabbf526 Mon Sep 17 00:00:00 2001 From: Isaac Bosompem Date: Wed, 7 Sep 2022 18:32:51 -0400 Subject: [PATCH] virgl: Set use_staging in resource_from_handle This flag controls virgl's behavior when buffers are accessed on the guest through Mesa's GBM interface. As such, this flag needs to be consistent in both the resource creation and fd import case. Previously, the fd import resource's flag value would be inconsistent with the original resource's value. This patch fixes this by inferring the value of this flag based on the resource's size. Signed-Off By: Isaac Bosompem Part-of: --- src/gallium/drivers/virgl/virgl_resource.c | 15 +++++++++++++++ src/gallium/drivers/virgl/virgl_winsys.h | 3 +++ src/gallium/winsys/virgl/drm/virgl_drm_winsys.c | 8 ++++++++ 3 files changed, 26 insertions(+) diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c index f8edcc182bc..48205174490 100644 --- a/src/gallium/drivers/virgl/virgl_resource.c +++ b/src/gallium/drivers/virgl/virgl_resource.c @@ -708,6 +708,8 @@ static struct pipe_resource *virgl_resource_from_handle(struct pipe_screen *scre { uint32_t winsys_stride, plane_offset, plane; uint64_t modifier; + uint32_t storage_size; + struct virgl_screen *vs = virgl_screen(screen); if (templ->target == PIPE_BUFFER) return NULL; @@ -739,6 +741,19 @@ static struct pipe_resource *virgl_resource_from_handle(struct pipe_screen *scre return NULL; } + /* + * If the overall resource is larger than a single page in size, we can + * compare it with the amount of memory allocated on the guest to determine + * if we should be using the staging path. + * + * If not, the decision is not as clear. However, since the resource can + * fit within a single page, the import will function correctly. + */ + storage_size = vs->vws->resource_get_storage_size(vs->vws, res->hw_res); + + if (res->metadata.total_size > storage_size) + res->use_staging = 1; + /* 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)) { diff --git a/src/gallium/drivers/virgl/virgl_winsys.h b/src/gallium/drivers/virgl/virgl_winsys.h index 45c3819ed8e..13e82b033b4 100644 --- a/src/gallium/drivers/virgl/virgl_winsys.h +++ b/src/gallium/drivers/virgl/virgl_winsys.h @@ -103,6 +103,9 @@ struct virgl_winsys { uint32_t stride, struct winsys_handle *whandle); + uint32_t (*resource_get_storage_size)(struct virgl_winsys* vws, + struct virgl_hw_res* res); + struct virgl_cmd_buf *(*cmd_buf_create)(struct virgl_winsys *ws, uint32_t size); void (*cmd_buf_destroy)(struct virgl_cmd_buf *buf); diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c index 20dc3450f91..9c1137ada49 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c @@ -459,6 +459,13 @@ alloc: return res; } +static uint32_t +virgl_drm_winsys_resource_get_storage_size(struct virgl_winsys *qws, + struct virgl_hw_res *res) +{ + return res->size; +} + static struct virgl_hw_res * virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws, struct winsys_handle *whandle, @@ -1250,6 +1257,7 @@ virgl_drm_winsys_create(int drmFD) 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_get_storage_size = virgl_drm_winsys_resource_get_storage_size; qdws->base.resource_map = virgl_drm_resource_map; qdws->base.resource_wait = virgl_drm_resource_wait; qdws->base.resource_is_busy = virgl_drm_resource_is_busy;