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 <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31624>
This commit is contained in:
Gert Wollny
2024-10-16 13:02:13 +02:00
committed by Marge Bot
parent 8b33eece30
commit 41c6738882
3 changed files with 112 additions and 13 deletions
@@ -31,6 +31,8 @@
#include <util/format/u_format.h>
#include <util/u_process.h>
#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;
}
@@ -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;
@@ -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