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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user