From 41c673888207821e252a03480fe0457bc4bfd9ec Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 16 Oct 2024 13:02:13 +0200 Subject: [PATCH] virgl/vtest: Add support for creating blob resources Buffers that are created using MAP_PERSISTENT or MAP_COHERENT will created as blob resources. Signed-off-by: Gert Wollny Part-of: --- .../winsys/virgl/vtest/virgl_vtest_socket.c | 45 ++++++++++- .../winsys/virgl/vtest/virgl_vtest_winsys.c | 75 ++++++++++++++++--- .../winsys/virgl/vtest/virgl_vtest_winsys.h | 5 ++ 3 files changed, 112 insertions(+), 13 deletions(-) diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c index 0dbc7554c69..4a0dfd20aea 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c @@ -31,6 +31,8 @@ #include #include +#define VIRGL_RENDERER_UNSTABLE_APIS + #include "virgl_vtest_winsys.h" #include "virgl_vtest_public.h" @@ -317,10 +319,6 @@ static int virgl_vtest_send_resource_create2(struct virgl_vtest_winsys *vws, virgl_block_write(vws->sock_fd, &vtest_hdr, sizeof(vtest_hdr)); virgl_block_write(vws->sock_fd, &res_create_buf, sizeof(res_create_buf)); - /* Multi-sampled textures have no backing store attached. */ - if (size == 0) - return 0; - if (vws->protocol_version >= 3) { virgl_block_read(vws->sock_fd, vtest_hdr, sizeof(vtest_hdr)); assert(vtest_hdr[VTEST_CMD_LEN] == 1); @@ -328,6 +326,10 @@ static int virgl_vtest_send_resource_create2(struct virgl_vtest_winsys *vws, virgl_block_read(vws->sock_fd, &handle, sizeof(handle)); } + /* Multi-sampled textures have no backing store attached. */ + if (size == 0) + return handle; + *out_fd = virgl_vtest_receive_fd(vws->sock_fd); if (*out_fd < 0) { fprintf(stderr, "failed to get fd\n"); @@ -558,3 +560,38 @@ int virgl_vtest_busy_wait(struct virgl_vtest_winsys *vws, int handle, assert(ret); return result[0]; } + +int +virgl_vtest_send_create_blob(struct virgl_vtest_winsys *vws, + uint32_t size, uint32_t blob_id, + int *out_fd) +{ + uint32_t vtest_hdr[VTEST_HDR_SIZE]; + vtest_hdr[VTEST_CMD_LEN] = VCMD_RES_CREATE_BLOB_SIZE; + vtest_hdr[VTEST_CMD_ID] = VCMD_RESOURCE_CREATE_BLOB; + + uint32_t vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_SIZE]; + + vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_TYPE] = VCMD_BLOB_TYPE_HOST3D; + vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_FLAGS] = VCMD_BLOB_FLAG_MAPPABLE; + vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_SIZE_LO] = (uint32_t)size; + vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_SIZE_HI] = 0; + vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_ID_LO] = (uint32_t)blob_id; + vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_ID_HI] = 0; + + virgl_block_write(vws->sock_fd, vtest_hdr, sizeof(vtest_hdr)); + virgl_block_write(vws->sock_fd, vcmd_res_create_blob, sizeof(vcmd_res_create_blob)); + + vtest_hdr[0] = 0; + virgl_block_read(vws->sock_fd, vtest_hdr, sizeof(vtest_hdr)); + assert(vtest_hdr[VTEST_CMD_LEN] == 1); + assert(vtest_hdr[VTEST_CMD_ID] == VCMD_RESOURCE_CREATE_BLOB); + + uint32_t res_id; + virgl_block_read(vws->sock_fd, &res_id, sizeof(res_id)); + + *out_fd = virgl_vtest_receive_fd(vws->sock_fd); + + return res_id; +} + diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c index 2ab9edb1d5b..2b096083bd8 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c @@ -32,6 +32,7 @@ #include "virgl_vtest_winsys.h" #include "virgl_vtest_public.h" +#include "virtio-gpu/virgl_protocol.h" /* Gets a pointer to the virgl_hw_res containing the pointed to cache entry. */ #define cache_entry_container_res(ptr) \ @@ -222,6 +223,43 @@ static void virgl_vtest_resource_reference(struct virgl_winsys *vws, *dres = sres; } +static int +virgl_vtest_winsys_resource_create_blob(struct virgl_winsys *vws, + enum pipe_texture_target target, + uint32_t format, + uint32_t bind, + uint32_t width, + uint32_t height, + uint32_t depth, + uint32_t array_size, + uint32_t last_level, + uint32_t nr_samples, + uint32_t flags, + uint32_t size, + int *fd) +{ + uint32_t cmd[VIRGL_PIPE_RES_CREATE_SIZE + 1] = { 0 }; + struct virgl_vtest_winsys *vvws = virgl_vtest_winsys(vws); + + int32_t blob_id = p_atomic_inc_return(&vvws->blob_id); + cmd[0] = VIRGL_CMD0(VIRGL_CCMD_PIPE_RESOURCE_CREATE, 0, VIRGL_PIPE_RES_CREATE_SIZE); + cmd[VIRGL_PIPE_RES_CREATE_FORMAT] = format; + cmd[VIRGL_PIPE_RES_CREATE_BIND] = bind; + cmd[VIRGL_PIPE_RES_CREATE_TARGET] = target; + cmd[VIRGL_PIPE_RES_CREATE_WIDTH] = width; + cmd[VIRGL_PIPE_RES_CREATE_HEIGHT] = height; + cmd[VIRGL_PIPE_RES_CREATE_DEPTH] = depth; + cmd[VIRGL_PIPE_RES_CREATE_ARRAY_SIZE] = array_size; + cmd[VIRGL_PIPE_RES_CREATE_LAST_LEVEL] = last_level; + cmd[VIRGL_PIPE_RES_CREATE_NR_SAMPLES] = nr_samples; + cmd[VIRGL_PIPE_RES_CREATE_FLAGS] = flags; + cmd[VIRGL_PIPE_RES_CREATE_BLOB_ID] = blob_id; + + virgl_vtest_submit_cmd(vvws, cmd, VIRGL_PIPE_RES_CREATE_SIZE + 1); + return virgl_vtest_send_create_blob(vvws, size, blob_id, fd); +} + + static struct virgl_hw_res * virgl_vtest_winsys_resource_create(struct virgl_winsys *vws, enum pipe_texture_target target, @@ -234,6 +272,7 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws, uint32_t array_size, uint32_t last_level, uint32_t nr_samples, + uint32_t flags, uint32_t size) { struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws); @@ -269,14 +308,31 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws, } } + if ((flags & (VIRGL_RESOURCE_FLAG_MAP_PERSISTENT | + VIRGL_RESOURCE_FLAG_MAP_COHERENT))) { + width = ALIGN(width, getpagesize()); + size = ALIGN(size, getpagesize()); + handle = virgl_vtest_winsys_resource_create_blob(vws, target, format, bind, + width, height, depth, + array_size, last_level, nr_samples, + flags, size, &fd); + + if (handle) { + pipe_reference_init(&res->reference, 1); + p_atomic_set(&res->num_cs_references, 0); + } + } else { + + handle = virgl_vtest_send_resource_create(vtws, handle, target, pipe_to_virgl_format(format), bind, + width, height, depth, array_size, + last_level, nr_samples, size, &fd); + } + res->bind = bind; res->format = format; res->height = height; res->width = width; res->size = size; - handle = virgl_vtest_send_resource_create(vtws, handle, target, pipe_to_virgl_format(format), bind, - width, height, depth, array_size, - last_level, nr_samples, size, &fd); if (vtws->protocol_version >= 2) { if (res->size == 0) { @@ -408,11 +464,11 @@ virgl_vtest_winsys_resource_cache_create(struct virgl_winsys *vws, mtx_unlock(&vtws->mutex); alloc: - res = virgl_vtest_winsys_resource_create(vws, target, map_front_private, - format, bind, width, height, depth, - array_size, last_level, nr_samples, - size); - return res; + + return virgl_vtest_winsys_resource_create(vws, target, map_front_private, + format, bind, width, height, depth, + array_size, last_level, nr_samples, flags, + size); } static bool virgl_vtest_res_is_added(struct virgl_vtest_cmd_buf *cbuf, @@ -517,7 +573,7 @@ virgl_vtest_fence_create(struct virgl_winsys *vws) NULL, PIPE_FORMAT_R8_UNORM, VIRGL_BIND_CUSTOM, - 8, 1, 1, 0, 0, 0, 8); + 8, 1, 1, 0, 0, 0, 0, 8); return (struct pipe_fence_handle *)res; } @@ -723,6 +779,7 @@ virgl_vtest_winsys_wrap(struct sw_winsys *sws) vtws->base.fence_reference = virgl_fence_reference; vtws->base.supports_fences = 0; vtws->base.supports_encoded_transfers = (vtws->protocol_version >= 2); + vtws->base.supports_coherent = 1; vtws->base.flush_frontbuffer = virgl_vtest_flush_frontbuffer; diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.h b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.h index ae3473a5d73..8b3c37dcf29 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.h +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.h @@ -49,6 +49,7 @@ struct virgl_vtest_winsys { struct virgl_resource_cache cache; mtx_t mutex; + int32_t blob_id; unsigned protocol_version; }; @@ -152,4 +153,8 @@ int virgl_vtest_recv_transfer_get_data(struct virgl_vtest_winsys *vws, int virgl_vtest_busy_wait(struct virgl_vtest_winsys *vws, int handle, int flags); + +int +virgl_vtest_send_create_blob(struct virgl_vtest_winsys *vws, + uint32_t size, uint32_t blob_id, int *fd); #endif