diff --git a/vtest/vtest.h b/vtest/vtest.h index ea25d9a..d63ce34 100644 --- a/vtest/vtest.h +++ b/vtest/vtest.h @@ -30,11 +30,14 @@ int vtest_create_renderer(int in_fd, int out_fd, uint32_t length); int vtest_send_caps(void); int vtest_send_caps2(void); int vtest_create_resource(void); +int vtest_create_resource2(void); int vtest_resource_unref(void); int vtest_submit_cmd(uint32_t length_dw); int vtest_transfer_get(uint32_t length_dw); +int vtest_transfer_get2(void); int vtest_transfer_put(uint32_t length_dw); +int vtest_transfer_put2(void); int vtest_block_read(int fd, void *buf, int size); diff --git a/vtest/vtest_protocol.h b/vtest/vtest_protocol.h index dca3074..3a05931 100644 --- a/vtest/vtest_protocol.h +++ b/vtest/vtest_protocol.h @@ -59,6 +59,10 @@ #define VCMD_PROTOCOL_VERSION 11 +#define VCMD_RESOURCE_CREATE2 12 +#define VCMD_TRANSFER_GET2 13 +#define VCMD_TRANSFER_PUT2 14 + #define VCMD_RES_CREATE_SIZE 10 #define VCMD_RES_CREATE_RES_HANDLE 0 #define VCMD_RES_CREATE_TARGET 1 @@ -71,6 +75,19 @@ #define VCMD_RES_CREATE_LAST_LEVEL 8 #define VCMD_RES_CREATE_NR_SAMPLES 9 +#define VCMD_RES_CREATE2_SIZE 11 +#define VCMD_RES_CREATE2_RES_HANDLE 0 +#define VCMD_RES_CREATE2_TARGET 1 +#define VCMD_RES_CREATE2_FORMAT 2 +#define VCMD_RES_CREATE2_BIND 3 +#define VCMD_RES_CREATE2_WIDTH 4 +#define VCMD_RES_CREATE2_HEIGHT 5 +#define VCMD_RES_CREATE2_DEPTH 6 +#define VCMD_RES_CREATE2_ARRAY_SIZE 7 +#define VCMD_RES_CREATE2_LAST_LEVEL 8 +#define VCMD_RES_CREATE2_NR_SAMPLES 9 +#define VCMD_RES_CREATE2_DATA_SIZE 10 + #define VCMD_RES_UNREF_SIZE 1 #define VCMD_RES_UNREF_RES_HANDLE 0 @@ -87,6 +104,18 @@ #define VCMD_TRANSFER_DEPTH 9 #define VCMD_TRANSFER_DATA_SIZE 10 +#define VCMD_TRANSFER2_HDR_SIZE 10 +#define VCMD_TRANSFER2_RES_HANDLE 0 +#define VCMD_TRANSFER2_LEVEL 1 +#define VCMD_TRANSFER2_X 2 +#define VCMD_TRANSFER2_Y 3 +#define VCMD_TRANSFER2_Z 4 +#define VCMD_TRANSFER2_WIDTH 5 +#define VCMD_TRANSFER2_HEIGHT 6 +#define VCMD_TRANSFER2_DEPTH 7 +#define VCMD_TRANSFER2_DATA_SIZE 8 +#define VCMD_TRANSFER2_OFFSET 9 + #define VCMD_BUSY_WAIT_FLAG_WAIT 1 #define VCMD_BUSY_WAIT_SIZE 2 diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c index 3d27385..384c3c1 100644 --- a/vtest/vtest_renderer.c +++ b/vtest/vtest_renderer.c @@ -36,6 +36,8 @@ #include "util.h" #include "util/u_debug.h" #include "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_hash_table.h" static int ctx_id = 1; static int fence_id = 1; @@ -55,6 +57,7 @@ struct vtest_renderer { int in_fd; int out_fd; unsigned protocol_version; + struct util_hash_table *iovec_hash; }; struct vtest_renderer renderer; @@ -64,6 +67,32 @@ struct virgl_box { uint32_t w, h, d; }; +static unsigned +hash_func(void *key) +{ + intptr_t ip = pointer_to_intptr(key); + return (unsigned)(ip & 0xffffffff); +} + +static int +compare_iovecs(void *key1, void *key2) +{ + if (key1 < key2) + return -1; + if (key1 > key2) + return 1; + else + return 0; +} + +static void free_iovec(void *value) +{ + struct iovec *iovec = value; + + free(iovec->iov_base); + free(iovec); +} + static int vtest_block_write(int fd, void *buf, int size) { void *ptr = buf; @@ -118,6 +147,7 @@ int vtest_create_renderer(int in_fd, int out_fd, uint32_t length) int ret; int ctx = VIRGL_RENDERER_USE_EGL; + renderer.iovec_hash = util_hash_table_create(hash_func, compare_iovecs, free_iovec); renderer.in_fd = in_fd; renderer.out_fd = out_fd; @@ -306,6 +336,52 @@ int vtest_create_resource(void) return ret; } +int vtest_create_resource2(void) +{ + uint32_t res_create_buf[VCMD_RES_CREATE2_SIZE]; + struct virgl_renderer_resource_create_args args; + struct iovec *iovec; + int ret; + + ret = vtest_block_read(renderer.in_fd, &res_create_buf, sizeof(res_create_buf)); + if (ret != sizeof(res_create_buf)) + return -1; + + args.handle = res_create_buf[VCMD_RES_CREATE2_RES_HANDLE]; + args.target = res_create_buf[VCMD_RES_CREATE2_TARGET]; + args.format = res_create_buf[VCMD_RES_CREATE2_FORMAT]; + args.bind = res_create_buf[VCMD_RES_CREATE2_BIND]; + + args.width = res_create_buf[VCMD_RES_CREATE2_WIDTH]; + args.height = res_create_buf[VCMD_RES_CREATE2_HEIGHT]; + args.depth = res_create_buf[VCMD_RES_CREATE2_DEPTH]; + args.array_size = res_create_buf[VCMD_RES_CREATE2_ARRAY_SIZE]; + args.last_level = res_create_buf[VCMD_RES_CREATE2_LAST_LEVEL]; + args.nr_samples = res_create_buf[VCMD_RES_CREATE2_NR_SAMPLES]; + args.flags = 0; + + ret = virgl_renderer_resource_create(&args, NULL, 0); + if (ret) + return ret; + + virgl_renderer_ctx_attach_resource(ctx_id, args.handle); + + iovec = CALLOC_STRUCT(iovec); + if (!iovec) + return -ENOMEM; + + iovec->iov_len = res_create_buf[VCMD_RES_CREATE2_DATA_SIZE]; + iovec->iov_base = calloc(1, iovec->iov_len); + if (!iovec->iov_base) + return -ENOMEM; + + virgl_renderer_resource_attach_iov(args.handle, iovec, 1); + assert(!util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(args.handle))); + util_hash_table_set(renderer.iovec_hash, intptr_to_pointer(args.handle), iovec); + + return ret; +} + int vtest_resource_unref(void) { uint32_t res_unref_buf[VCMD_RES_UNREF_SIZE]; @@ -318,6 +394,10 @@ int vtest_resource_unref(void) handle = res_unref_buf[VCMD_RES_UNREF_RES_HANDLE]; virgl_renderer_ctx_attach_resource(ctx_id, handle); + + virgl_renderer_resource_detach_iov(handle, NULL, NULL); + util_hash_table_remove(renderer.iovec_hash, intptr_to_pointer(handle)); + virgl_renderer_resource_unref(handle); return 0; } @@ -442,6 +522,93 @@ int vtest_transfer_put(UNUSED uint32_t length_dw) return 0; } +#define DECODE_TRANSFER2 \ + do { \ + handle = thdr_buf[VCMD_TRANSFER2_RES_HANDLE]; \ + level = thdr_buf[VCMD_TRANSFER2_LEVEL]; \ + box.x = thdr_buf[VCMD_TRANSFER2_X]; \ + box.y = thdr_buf[VCMD_TRANSFER2_Y]; \ + box.z = thdr_buf[VCMD_TRANSFER2_Z]; \ + box.w = thdr_buf[VCMD_TRANSFER2_WIDTH]; \ + box.h = thdr_buf[VCMD_TRANSFER2_HEIGHT]; \ + box.d = thdr_buf[VCMD_TRANSFER2_DEPTH]; \ + data_size = thdr_buf[VCMD_TRANSFER2_DATA_SIZE]; \ + offset = thdr_buf[VCMD_TRANSFER2_OFFSET]; \ + } while(0) + + +int vtest_transfer_get2(void) +{ + uint32_t thdr_buf[VCMD_TRANSFER2_HDR_SIZE]; + int ret; + int level; + uint32_t handle; + struct virgl_box box; + uint32_t data_size; + uint32_t offset; + struct iovec *iovec; + + ret = vtest_block_read(renderer.in_fd, thdr_buf, sizeof(thdr_buf)); + if (ret != sizeof(thdr_buf)) + return ret; + + DECODE_TRANSFER2; + + ret = virgl_renderer_transfer_read_iov(handle, + ctx_id, + level, + 0, + 0, + &box, + offset, + NULL, 0); + if (ret) + fprintf(stderr," transfer read failed %d\n", ret); + + iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle)); + assert(iovec); + ret = vtest_block_write(renderer.out_fd, + iovec->iov_base + offset, + data_size); + return ret < 0 ? ret : 0; +} + +int vtest_transfer_put2(void) +{ + uint32_t thdr_buf[VCMD_TRANSFER2_HDR_SIZE]; + int ret; + int level; + uint32_t handle; + struct virgl_box box; + uint32_t data_size; + uint32_t offset; + struct iovec *iovec; + + ret = vtest_block_read(renderer.in_fd, thdr_buf, sizeof(thdr_buf)); + if (ret != sizeof(thdr_buf)) + return ret; + + DECODE_TRANSFER2; + + iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle)); + assert(iovec); + ret = vtest_block_read(renderer.in_fd, iovec->iov_base + offset, data_size); + if (ret < 0) + return ret; + + ret = virgl_renderer_transfer_write_iov(handle, + ctx_id, + level, + 0, + 0, + &box, + offset, + NULL, 0); + if (ret) + fprintf(stderr," transfer write failed %d\n", ret); + return 0; +} + int vtest_resource_busy_wait(void) { uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE]; diff --git a/vtest/vtest_server.c b/vtest/vtest_server.c index d728cad..bc6c95f 100644 --- a/vtest/vtest_server.c +++ b/vtest/vtest_server.c @@ -113,6 +113,9 @@ again: case VCMD_RESOURCE_CREATE: ret = vtest_create_resource(); break; + case VCMD_RESOURCE_CREATE2: + ret = vtest_create_resource2(); + break; case VCMD_RESOURCE_UNREF: ret = vtest_resource_unref(); break; @@ -125,6 +128,12 @@ again: case VCMD_TRANSFER_PUT: ret = vtest_transfer_put(header[0]); break; + case VCMD_TRANSFER_GET2: + ret = vtest_transfer_get2(); + break; + case VCMD_TRANSFER_PUT2: + ret = vtest_transfer_put2(); + break; case VCMD_RESOURCE_BUSY_WAIT: vtest_renderer_create_fence(); ret = vtest_resource_busy_wait();