vtest: add VCMD_RESOURCE_CREATE_BLOB

It gives clients access to virgl_renderer_resource_create_blob and
virgl_renderer_resource_export_blob.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Ryan Neph <ryanneph@google.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
Chia-I Wu 4 years ago
parent 4e2c25f752
commit 6543354118
  1. 1
      vtest/vtest.h
  2. 25
      vtest/vtest_protocol.h
  3. 106
      vtest/vtest_renderer.c
  4. 1
      vtest/vtest_server.c

@ -84,6 +84,7 @@ int vtest_protocol_version(uint32_t length_dw);
int vtest_get_param(uint32_t length_dw);
int vtest_get_capset(uint32_t length_dw);
int vtest_context_init(uint32_t length_dw);
int vtest_resource_create_blob(uint32_t length_dw);
void vtest_set_max_length(uint32_t length);

@ -70,6 +70,7 @@
#define VCMD_GET_PARAM 15
#define VCMD_GET_CAPSET 16
#define VCMD_CONTEXT_INIT 17
#define VCMD_RESOURCE_CREATE_BLOB 18
#endif /* VIRGL_RENDERER_UNSTABLE_APIS */
#define VCMD_RES_CREATE_SIZE 10
@ -140,6 +141,9 @@
#ifdef VIRGL_RENDERER_UNSTABLE_APIS
enum vcmd_param {
VCMD_PARAM_HOST_COHERENT_DMABUF_BLOB = 1,
};
#define VCMD_GET_PARAM_SIZE 1
#define VCMD_GET_PARAM_PARAM 0
/* resp param validity and value */
@ -152,6 +156,27 @@
#define VCMD_CONTEXT_INIT_SIZE 1
#define VCMD_CONTEXT_INIT_CAPSET_ID 0
enum vcmd_blob_type {
VCMD_BLOB_TYPE_GUEST = 1,
VCMD_BLOB_TYPE_HOST3D = 2,
VCMD_BLOB_TYPE_HOST3D_GUEST = 3,
};
enum vcmd_blob_flag {
VCMD_BLOB_FLAG_MAPPABLE = 1 << 0,
VCMD_BLOB_FLAG_SHAREABLE = 1 << 1,
VCMD_BLOB_FLAG_CROSS_DEVICE = 1 << 2,
};
#define VCMD_RES_CREATE_BLOB_SIZE 6
#define VCMD_RES_CREATE_BLOB_TYPE 0
#define VCMD_RES_CREATE_BLOB_FLAGS 1
#define VCMD_RES_CREATE_BLOB_SIZE_LO 2
#define VCMD_RES_CREATE_BLOB_SIZE_HI 3
#define VCMD_RES_CREATE_BLOB_ID_LO 4
#define VCMD_RES_CREATE_BLOB_ID_HI 5
/* resp res_id and mmap'able fd */
#endif /* VIRGL_RENDERER_UNSTABLE_APIS */
#endif /* VTEST_PROTOCOL */

@ -76,6 +76,7 @@ struct vtest_context {
struct vtest_renderer {
const char *rendernode_name;
bool multi_clients;
uint32_t ctx_flags;
uint32_t max_length;
@ -303,14 +304,16 @@ int vtest_init_renderer(bool multi_clients,
list_inithead(&renderer.free_contexts);
list_inithead(&renderer.free_resources);
ret = virgl_renderer_init(&renderer,
ctx_flags | VIRGL_RENDERER_THREAD_SYNC, &renderer_cbs);
ctx_flags |= VIRGL_RENDERER_THREAD_SYNC |
VIRGL_RENDERER_USE_EXTERNAL_BLOB;
ret = virgl_renderer_init(&renderer, ctx_flags, &renderer_cbs);
if (ret) {
fprintf(stderr, "failed to initialise renderer.\n");
return -1;
}
renderer.multi_clients = multi_clients;
renderer.ctx_flags = ctx_flags;
return 0;
}
@ -915,6 +918,105 @@ int vtest_create_resource2(UNUSED uint32_t length_dw)
return vtest_create_resource_internal(ctx, VCMD_RESOURCE_CREATE2, &args, shm_size);
}
int vtest_resource_create_blob(UNUSED uint32_t length_dw)
{
struct vtest_context *ctx = vtest_get_current_context();
uint32_t res_create_blob_buf[VCMD_RES_CREATE_BLOB_SIZE];
uint32_t resp_buf[VTEST_HDR_SIZE + 1];
struct virgl_renderer_resource_create_blob_args args;
struct vtest_resource *res;
int fd;
int ret;
ret = ctx->input->read(ctx->input, res_create_blob_buf,
sizeof(res_create_blob_buf));
if (ret != sizeof(res_create_blob_buf))
return -1;
memset(&args, 0, sizeof(args));
args.blob_mem = res_create_blob_buf[VCMD_RES_CREATE_BLOB_TYPE];
args.blob_flags = res_create_blob_buf[VCMD_RES_CREATE_BLOB_FLAGS];
args.size = res_create_blob_buf[VCMD_RES_CREATE_BLOB_SIZE_LO];
args.size |= (uint64_t)res_create_blob_buf[VCMD_RES_CREATE_BLOB_SIZE_HI] << 32;
args.blob_id = res_create_blob_buf[VCMD_RES_CREATE_BLOB_ID_LO];
args.blob_id |= (uint64_t)res_create_blob_buf[VCMD_RES_CREATE_BLOB_ID_HI] << 32;
res = vtest_new_resource(0);
if (!res)
return -ENOMEM;
args.res_handle = res->res_id;
args.ctx_id = ctx->ctx_id;
switch (args.blob_mem) {
case VIRGL_RENDERER_BLOB_MEM_GUEST:
case VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST:
fd = vtest_create_resource_setup_shm(res, args.size);
if (fd < 0) {
vtest_unref_resource(res);
return -ENOMEM;
}
args.iovecs = &res->iov;
args.num_iovs = 1;
break;
case VIRGL_RENDERER_BLOB_MEM_HOST3D:
fd = -1;
break;
default:
return -EINVAL;
}
ret = virgl_renderer_resource_create_blob(&args);
if (ret) {
if (fd >= 0)
close(fd);
vtest_unref_resource(res);
return report_failed_call("virgl_renderer_resource_create_blob", ret);
}
/* need dmabuf */
if (args.blob_mem == VIRGL_RENDERER_BLOB_MEM_HOST3D) {
uint32_t fd_type;
ret = virgl_renderer_resource_export_blob(res->res_id, &fd_type, &fd);
if (ret) {
vtest_unref_resource(res);
return report_failed_call("virgl_renderer_resource_export_blob", ret);
}
if (fd_type != VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF) {
close(fd);
vtest_unref_resource(res);
return report_failed_call("virgl_renderer_resource_export_blob", -EINVAL);
}
}
virgl_renderer_ctx_attach_resource(ctx->ctx_id, res->res_id);
resp_buf[VTEST_CMD_LEN] = 1;
resp_buf[VTEST_CMD_ID] = VCMD_RESOURCE_CREATE_BLOB;
resp_buf[VTEST_CMD_DATA_START] = res->res_id;
ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
if (ret < 0) {
close(fd);
vtest_unref_resource(res);
return ret;
}
ret = vtest_send_fd(ctx->out_fd, fd);
if (ret < 0) {
close(fd);
vtest_unref_resource(res);
return report_failed_call("vtest_send_fd", ret);
}
/* Closing the file descriptor does not unmap the region. */
close(fd);
util_hash_table_set(ctx->resource_table, intptr_to_pointer(res->res_id), res);
return 0;
}
int vtest_resource_unref(UNUSED uint32_t length_dw)
{
struct vtest_context *ctx = vtest_get_current_context();

@ -610,6 +610,7 @@ static const struct vtest_command {
[VCMD_GET_PARAM] = { vtest_get_param, false },
[VCMD_GET_CAPSET] = { vtest_get_capset, false },
[VCMD_CONTEXT_INIT] = { vtest_context_init, false },
[VCMD_RESOURCE_CREATE_BLOB] = { vtest_resource_create_blob, true },
};
static int vtest_client_dispatch_commands(struct vtest_client *client)

Loading…
Cancel
Save