diff --git a/vtest/vtest.h b/vtest/vtest.h index 9f9300f..ae2e196 100644 --- a/vtest/vtest.h +++ b/vtest/vtest.h @@ -1,6 +1,7 @@ #ifndef VTEST_H #define VTEST_H +#include int vtest_create_renderer(int fd); int vtest_send_caps(void); @@ -8,5 +9,14 @@ int vtest_send_caps(void); int vtest_create_resource(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_put(uint32_t length_dw); + +int vtest_block_read(int fd, void *buf, int size); + +int vtest_resource_busy_wait(void); +int vtest_renderer_create_fence(void); +int vtest_poll(void); #endif diff --git a/vtest/vtest_protocol.h b/vtest/vtest_protocol.h index f06896f..c465339 100644 --- a/vtest/vtest_protocol.h +++ b/vtest/vtest_protocol.h @@ -22,15 +22,12 @@ #define VCMD_SUBMIT_CMD 6 +#define VCMD_RESOURCE_BUSY_WAIT 7 + /* get caps */ /* 0 length cmd */ /* resp VCMD_GET_CAPS + caps */ -/* context create */ -#define VCMD_CONTEXT_CREATE_CTX_ID 0 -/* context destroy */ -#define VCMD_CONTEXT_DESTROY_CTX_ID 0 - #define VCMD_RES_CREATE_SIZE 10 #define VCMD_RES_CREATE_RES_HANDLE 0 #define VCMD_RES_CREATE_TARGET 1 @@ -46,6 +43,7 @@ #define VCMD_RES_UNREF_SIZE 1 #define VCMD_RES_UNREF_RES_HANDLE 0 +#define VCMD_TRANSFER_HDR_SIZE 11 #define VCMD_TRANSFER_RES_HANDLE 0 #define VCMD_TRANSFER_LEVEL 1 #define VCMD_TRANSFER_STRIDE 2 @@ -56,7 +54,12 @@ #define VCMD_TRANSFER_WIDTH 7 #define VCMD_TRANSFER_HEIGHT 8 #define VCMD_TRANSFER_DEPTH 9 -#define VCMD_TRANSFER_OFFSET 10 -#define VCMD_TRANSFER_DATA 11 +#define VCMD_TRANSFER_DATA_SIZE 10 + +#define VCMD_BUSY_WAIT_FLAG_WAIT 1 + +#define VCMD_BUSY_WAIT_SIZE 2 +#define VCMD_BUSY_WAIT_HANDLE 0 +#define VCMD_BUSY_WAIT_FLAGS 1 #endif diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c index eb5aea3..6fc9d3f 100644 --- a/vtest/vtest_renderer.c +++ b/vtest/vtest_renderer.c @@ -1,14 +1,26 @@ #include +#include #include #include #include "virglrenderer.h" +#include +#include "vtest.h" #include "vtest_protocol.h" static int ctx_id = 1; +static int fence_id = 1; + +static int last_fence; +static void vtest_write_fence(void *cookie, uint32_t fence_id) +{ + fprintf(stderr, "fence %d expired\n", fence_id); + last_fence = fence_id; +} + struct virgl_renderer_callbacks vtest_cbs = { .version = 1, - // .write_fence = vtest_write_fence, + .write_fence = vtest_write_fence, }; struct vtest_renderer { @@ -17,6 +29,43 @@ struct vtest_renderer { struct vtest_renderer renderer; +struct virgl_box { + uint32_t x, y, z; + uint32_t w, h, d; +}; + +static int vtest_block_write(int fd, void *buf, int size) +{ + void *ptr = buf; + int left; + int ret; + left = size; + do { + ret = write(fd, ptr, left); + if (ret < 0) + return -errno; + left -= ret; + ptr += ret; + } while (left); + return size; +} + +int vtest_block_read(int fd, void *buf, int size) +{ + void *ptr = buf; + int left; + int ret; + left = size; + do { + ret = read(fd, ptr, left); + if (ret < 0) + return -errno; + left -= ret; + ptr += ret; + } while (left); + return size; +} + int vtest_create_renderer(int fd) { const char *vtestname = "vtestname"; @@ -44,8 +93,8 @@ int vtest_send_caps(void) hdr_buf[0] = max_size + 1; hdr_buf[1] = 1; - write(renderer.remote_fd, hdr_buf, 8); - write(renderer.remote_fd, caps_buf, max_size); + vtest_block_write(renderer.remote_fd, hdr_buf, 8); + vtest_block_write(renderer.remote_fd, caps_buf, max_size); return 0; } @@ -55,7 +104,7 @@ int vtest_create_resource(void) struct virgl_renderer_resource_create_args args; int ret; - ret = read(renderer.remote_fd, &res_create_buf, sizeof(res_create_buf)); + ret = vtest_block_read(renderer.remote_fd, &res_create_buf, sizeof(res_create_buf)); if (ret != sizeof(res_create_buf)) return -1; @@ -84,7 +133,7 @@ int vtest_resource_unref(void) int ret; uint32_t handle; - ret = read(renderer.remote_fd, &res_unref_buf, sizeof(res_unref_buf)); + ret = vtest_block_read(renderer.remote_fd, &res_unref_buf, sizeof(res_unref_buf)); if (ret != sizeof(res_unref_buf)) return -1; @@ -103,7 +152,7 @@ int vtest_submit_cmd(uint32_t length_dw) if (!cbuf) return -1; - ret = read(renderer.remote_fd, cbuf, length_dw * 4); + ret = vtest_block_read(renderer.remote_fd, cbuf, length_dw * 4); if (ret != length_dw * 4) return -1; @@ -112,3 +161,141 @@ int vtest_submit_cmd(uint32_t length_dw) free(cbuf); return 0; } + +#define DECODE_TRANSFER \ + do { \ + handle = thdr_buf[VCMD_TRANSFER_RES_HANDLE]; \ + level = thdr_buf[VCMD_TRANSFER_LEVEL]; \ + stride = thdr_buf[VCMD_TRANSFER_STRIDE]; \ + layer_stride = thdr_buf[VCMD_TRANSFER_LAYER_STRIDE]; \ + box.x = thdr_buf[VCMD_TRANSFER_X]; \ + box.y = thdr_buf[VCMD_TRANSFER_Y]; \ + box.z = thdr_buf[VCMD_TRANSFER_Z]; \ + box.w = thdr_buf[VCMD_TRANSFER_WIDTH]; \ + box.h = thdr_buf[VCMD_TRANSFER_HEIGHT]; \ + box.d = thdr_buf[VCMD_TRANSFER_DEPTH]; \ + data_size = thdr_buf[VCMD_TRANSFER_DATA_SIZE]; \ + } while(0) + + +int vtest_transfer_get(uint32_t length_dw) +{ + uint32_t thdr_buf[VCMD_TRANSFER_HDR_SIZE]; + int ret; + int level; + uint32_t stride, layer_stride, handle; + struct virgl_box box; + uint32_t data_size; + void *ptr; + struct iovec iovec; + + ret = vtest_block_read(renderer.remote_fd, thdr_buf, VCMD_TRANSFER_HDR_SIZE * 4); + if (ret != VCMD_TRANSFER_HDR_SIZE * 4) + return ret; + + DECODE_TRANSFER; + + ptr = malloc(data_size); + if (!ptr) + return -ENOMEM; + + iovec.iov_len = data_size; + iovec.iov_base = ptr; + virgl_renderer_transfer_read_iov(handle, + ctx_id, + level, + stride, + layer_stride, + &box, + 0, + &iovec, 1); + + vtest_block_write(renderer.remote_fd, ptr, data_size); + free(ptr); + return 0; +} + +int vtest_transfer_put(uint32_t length_dw) +{ + uint32_t thdr_buf[VCMD_TRANSFER_HDR_SIZE]; + int ret; + int level; + uint32_t stride, layer_stride, handle; + struct virgl_box box; + uint32_t data_size; + void *ptr; + struct iovec iovec; + ret = vtest_block_read(renderer.remote_fd, thdr_buf, VCMD_TRANSFER_HDR_SIZE * 4); + if (ret != VCMD_TRANSFER_HDR_SIZE * 4) + return ret; + + DECODE_TRANSFER; + + ptr = malloc(data_size); + if (!ptr) + return -ENOMEM; + + vtest_block_read(renderer.remote_fd, ptr, data_size); + + iovec.iov_len = data_size; + iovec.iov_base = ptr; + virgl_renderer_transfer_write_iov(handle, + ctx_id, + level, + stride, + layer_stride, + &box, + 0, + &iovec, 1); + free(ptr); + return 0; +} + +int vtest_resource_busy_wait(void) +{ + uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE]; + int ret; + int handle; + int flags; + uint32_t hdr_buf[VTEST_HDR_SIZE]; + uint32_t reply_buf[1]; + bool busy = false; + ret = vtest_block_read(renderer.remote_fd, &bw_buf, sizeof(bw_buf)); + if (ret != sizeof(bw_buf)) + return -1; + + handle = bw_buf[VCMD_BUSY_WAIT_HANDLE]; + flags = bw_buf[VCMD_BUSY_WAIT_FLAGS]; + + if (flags == VCMD_BUSY_WAIT_FLAG_WAIT) { + do { + if (last_fence != (fence_id - 1)) + virgl_renderer_poll(); + else + break; + } while (1); + busy = false; + } else { + busy = last_fence != (fence_id - 1); + } + + hdr_buf[VTEST_CMD_LEN] = 1; + hdr_buf[VTEST_CMD_ID] = VCMD_RESOURCE_BUSY_WAIT; + reply_buf[0] = busy ? 1 : 0; + fprintf(stderr, "busy check %d, %d\n", handle, flags); + + vtest_block_write(renderer.remote_fd, hdr_buf, sizeof(hdr_buf)); + vtest_block_write(renderer.remote_fd, reply_buf, sizeof(reply_buf)); + return 0; +} + +int vtest_renderer_create_fence(void) +{ + virgl_renderer_create_fence(fence_id++, ctx_id); + return 0; +} + +int vtest_poll(void) +{ + virgl_renderer_poll(); +} diff --git a/vtest/vtest_server.c b/vtest/vtest_server.c index f8cbf1d..0486305 100644 --- a/vtest/vtest_server.c +++ b/vtest/vtest_server.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -80,6 +81,8 @@ int main(void) { int sock, new_fd, ret; uint32_t header[VTEST_HDR_SIZE]; + static int fence_id = 1; + bool do_fence; sock = vtest_open_socket("/tmp/.virgl_test"); new_fd = wait_for_socket_accept(sock); @@ -90,11 +93,12 @@ again: if (ret < 0) goto err; - ret = read(new_fd, &header, sizeof(header)); + ret = vtest_block_read(new_fd, &header, sizeof(header)); if (ret == 8) { fprintf(stderr, "got length: %d cmd: %d\n", header[0], header[1]); - + vtest_poll(); + do_fence = false; switch (header[1]) { case VCMD_GET_CAPS: vtest_send_caps(); @@ -107,10 +111,22 @@ again: break; case VCMD_SUBMIT_CMD: vtest_submit_cmd(header[0]); + do_fence = true; + break; + case VCMD_TRANSFER_GET: + vtest_transfer_get(header[0]); + break; + case VCMD_TRANSFER_PUT: + vtest_transfer_put(header[0]); + do_fence = true; break; + case VCMD_RESOURCE_BUSY_WAIT: + vtest_resource_busy_wait(); default: break; } + if (do_fence) + vtest_renderer_create_fence(); goto again; } err: