From 0b3e195268c788cd8456dcdefeb7b7271a6f1c0c Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 1 Jul 2020 16:42:24 -0700 Subject: [PATCH] vtest: add VCMD_GET_CAPSET Comparing to VCMD_GET_{CAPS,CAPS2}, it allows any capset id/version to be queried. This is similar to linux's DRM_IOCTL_VIRTGPU_GET_CAPS. Signed-off-by: Chia-I Wu Reviewed-by: Isaac Bosompem --- vtest/vtest.h | 1 + vtest/vtest_protocol.h | 6 ++++++ vtest/vtest_renderer.c | 49 ++++++++++++++++++++++++++++++++++++++++++ vtest/vtest_server.c | 1 + 4 files changed, 57 insertions(+) diff --git a/vtest/vtest.h b/vtest/vtest.h index 15db9be..d05e292 100644 --- a/vtest/vtest.h +++ b/vtest/vtest.h @@ -80,6 +80,7 @@ int vtest_protocol_version(uint32_t length_dw); /* since protocol version 3 */ int vtest_get_param(uint32_t length_dw); +int vtest_get_capset(uint32_t length_dw); void vtest_set_max_length(uint32_t length); diff --git a/vtest/vtest_protocol.h b/vtest/vtest_protocol.h index a83339e..07df4be 100644 --- a/vtest/vtest_protocol.h +++ b/vtest/vtest_protocol.h @@ -67,6 +67,7 @@ #ifdef VIRGL_RENDERER_UNSTABLE_APIS /* since protocol version 3 */ #define VCMD_GET_PARAM 15 +#define VCMD_GET_CAPSET 16 #endif /* VIRGL_RENDERER_UNSTABLE_APIS */ #define VCMD_RES_CREATE_SIZE 10 @@ -139,6 +140,11 @@ #define VCMD_GET_PARAM_PARAM 0 /* resp param validity and value */ +#define VCMD_GET_CAPSET_SIZE 2 +#define VCMD_GET_CAPSET_ID 0 +#define VCMD_GET_CAPSET_VERSION 1 +/* resp capset validity and contents */ + #endif /* VIRGL_RENDERER_UNSTABLE_APIS */ #endif /* VTEST_PROTOCOL */ diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c index ff6d6a5..16c053a 100644 --- a/vtest/vtest_renderer.c +++ b/vtest/vtest_renderer.c @@ -521,6 +521,55 @@ int vtest_get_param(UNUSED uint32_t length_dw) return 0; } +int vtest_get_capset(UNUSED uint32_t length_dw) +{ + struct vtest_context *ctx = vtest_get_current_context(); + uint32_t get_capset_buf[VCMD_GET_CAPSET_SIZE]; + uint32_t resp_buf[VTEST_HDR_SIZE + 1]; + uint32_t id; + uint32_t version; + uint32_t max_version; + uint32_t max_size; + void *caps; + int ret; + + ret = ctx->input->read(ctx->input, get_capset_buf, sizeof(get_capset_buf)); + if (ret != sizeof(get_capset_buf)) + return -1; + + id = get_capset_buf[VCMD_GET_CAPSET_ID]; + version = get_capset_buf[VCMD_GET_CAPSET_VERSION]; + + virgl_renderer_get_cap_set(id, &max_version, &max_size); + + /* unsupported id or version */ + if ((!max_version && !max_size) || version > max_version) { + resp_buf[VTEST_CMD_LEN] = 1; + resp_buf[VTEST_CMD_ID] = VCMD_GET_CAPSET; + resp_buf[VTEST_CMD_DATA_START] = false; + return vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf)); + } + + if (max_size % 4) + return -EINVAL; + + caps = malloc(max_size); + if (!caps) + return -ENOMEM; + + virgl_renderer_fill_caps(id, version, caps); + + resp_buf[VTEST_CMD_LEN] = 1 + max_size / 4; + resp_buf[VTEST_CMD_ID] = VCMD_GET_CAPSET; + resp_buf[VTEST_CMD_DATA_START] = true; + ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf)); + if (ret >= 0) + ret = vtest_block_write(ctx->out_fd, caps, max_size); + + free(caps); + return ret >= 0 ? 0 : ret; +} + int vtest_send_caps2(UNUSED uint32_t length_dw) { struct vtest_context *ctx = vtest_get_current_context(); diff --git a/vtest/vtest_server.c b/vtest/vtest_server.c index 866224c..2e5689f 100644 --- a/vtest/vtest_server.c +++ b/vtest/vtest_server.c @@ -606,6 +606,7 @@ static const struct vtest_command { /* since protocol version 3 */ [VCMD_GET_PARAM] = { vtest_get_param, false }, + [VCMD_GET_CAPSET] = { vtest_get_capset, false }, }; static int vtest_client_dispatch_commands(struct vtest_client *client)