diff --git a/vtest/util.c b/vtest/util.c index 0d3c78f..2c74ba8 100644 --- a/vtest/util.c +++ b/vtest/util.c @@ -21,12 +21,14 @@ * OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ + #include "util.h" #include #include #include #include + int vtest_wait_for_fd_read(int fd) { fd_set read_fds; @@ -36,11 +38,13 @@ int vtest_wait_for_fd_read(int fd) FD_SET(fd, &read_fds); ret = select(fd + 1, &read_fds, NULL, NULL, NULL); - if (ret < 0) + if (ret < 0) { return ret; + } if (FD_ISSET(fd, &read_fds)) { return 0; } + return -1; } diff --git a/vtest/util.h b/vtest/util.h index 4684b49..2c60bc5 100644 --- a/vtest/util.h +++ b/vtest/util.h @@ -21,6 +21,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ + #ifndef VTEST_UTIL_H #define VTEST_UTIL_H diff --git a/vtest/vtest.h b/vtest/vtest.h index d400316..463c2a0 100644 --- a/vtest/vtest.h +++ b/vtest/vtest.h @@ -21,10 +21,12 @@ * OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ + #ifndef VTEST_H #define VTEST_H #include + int vtest_create_renderer(int in_fd, int out_fd, uint32_t length); int vtest_send_caps(uint32_t length_dw); @@ -49,5 +51,6 @@ int vtest_ping_protocol_version(uint32_t length_dw); int vtest_protocol_version(uint32_t length_dw); void vtest_destroy_renderer(void); + #endif diff --git a/vtest/vtest_protocol.h b/vtest/vtest_protocol.h index 3a05931..a2ea241 100644 --- a/vtest/vtest_protocol.h +++ b/vtest/vtest_protocol.h @@ -21,6 +21,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ + #ifndef VTEST_PROTOCOL #define VTEST_PROTOCOL diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c index 25fdf79..a061f95 100644 --- a/vtest/vtest_renderer.c +++ b/vtest/vtest_renderer.c @@ -21,6 +21,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ + #include #include #include @@ -39,53 +40,54 @@ #include "util/u_memory.h" #include "util/u_hash_table.h" + static int ctx_id = 1; static int fence_id = 1; static int last_fence; static void vtest_write_fence(UNUSED void *cookie, uint32_t fence_id_in) { - last_fence = fence_id_in; + last_fence = fence_id_in; } struct virgl_renderer_callbacks vtest_cbs = { - .version = 1, - .write_fence = vtest_write_fence, + .version = 1, + .write_fence = vtest_write_fence, }; struct vtest_renderer { - int in_fd; - int out_fd; - unsigned protocol_version; - struct util_hash_table *iovec_hash; + int in_fd; + int out_fd; + unsigned protocol_version; + struct util_hash_table *iovec_hash; }; struct vtest_renderer renderer; struct virgl_box { - uint32_t x, y, z; - uint32_t w, h, d; + uint32_t x, y, z; + uint32_t w, h, d; }; static int __failed_call(const char* func, const char *called, int ret) { - fprintf(stderr, "%s called %s which failed (%d)\n", func, called, ret); - return ret; + fprintf(stderr, "%s called %s which failed (%d)\n", func, called, ret); + return ret; } #define report_failed_call(called, ret) \ - __failed_call(__FUNCTION__, called, ret) + __failed_call(__FUNCTION__, called, ret) static int __failure(const char* func, const char *reason, int ret) { - fprintf(stderr, "%s %s (%d)\n", func, reason, ret); - return ret; + fprintf(stderr, "%s %s (%d)\n", func, reason, ret); + return ret; } #define report_failure(reason, ret) \ - __failure(__FUNCTION__, reason, ret) + __failure(__FUNCTION__, reason, ret) static unsigned hash_func(void *key) @@ -97,12 +99,13 @@ hash_func(void *key) static int compare_iovecs(void *key1, void *key2) { - if (key1 < key2) + if (key1 < key2) { return -1; - if (key1 > key2) + } else if (key1 > key2) { return 1; - else + } else { return 0; + } } static void free_iovec(void *value) @@ -119,13 +122,17 @@ static int vtest_block_write(int fd, void *buf, int size) int left; int ret; left = size; + do { ret = write(fd, ptr, left); - if (ret < 0) + if (ret < 0) { return -errno; + } + left -= ret; ptr += ret; } while (left); + return size; } @@ -135,12 +142,16 @@ static int vtest_block_write_zero(int fd, int size) int left; int ret; left = size; + do { ret = write(fd, zero, MIN2(left, 256)); - if (ret < 0) + if (ret < 0) { return -errno; + } + left -= ret; } while (left); + return size; } @@ -154,11 +165,14 @@ int vtest_block_read(int fd, void *buf, int size) left = size; do { ret = read(fd, ptr, left); - if (ret <= 0) - return ret == -1 ? -errno : 0; + if (ret <= 0) { + return ret == -1 ? -errno : 0; + } + left -= ret; ptr += ret; } while (left); + if (getenv("VTEST_SAVE")) { if (savefd == -1) { savefd = open(getenv("VTEST_SAVE"), @@ -173,568 +187,611 @@ int vtest_block_read(int fd, void *buf, int size) exit(1); } } + return size; } int vtest_create_renderer(int in_fd, int out_fd, uint32_t length) { - char *vtestname; - 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; - - /* By default we support version 0 unless VCMD_PROTOCOL_VERSION is sent */ - renderer.protocol_version = 0; - - if (getenv("VTEST_USE_GLX")) - ctx = VIRGL_RENDERER_USE_GLX; - - if (getenv("VTEST_USE_EGL_SURFACELESS")) { - if (ctx & VIRGL_RENDERER_USE_GLX) { - fprintf(stderr, "Cannot use surfaceless with GLX.\n"); - return -1; - } - ctx |= VIRGL_RENDERER_USE_SURFACELESS; - } - - if (getenv("VTEST_USE_GLES")) { - if (ctx & VIRGL_RENDERER_USE_GLX) { - fprintf(stderr, "Cannot use GLES with GLX.\n"); - return -1; - } - ctx |= VIRGL_RENDERER_USE_GLES; - } - - ret = virgl_renderer_init(&renderer, - ctx | VIRGL_RENDERER_THREAD_SYNC, &vtest_cbs); - if (ret) { + char *vtestname; + 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; + + /* By default we support version 0 unless VCMD_PROTOCOL_VERSION is sent */ + renderer.protocol_version = 0; + + if (getenv("VTEST_USE_GLX")) { + ctx = VIRGL_RENDERER_USE_GLX; + } + + if (getenv("VTEST_USE_EGL_SURFACELESS")) { + if (ctx & VIRGL_RENDERER_USE_GLX) { + fprintf(stderr, "Cannot use surfaceless with GLX.\n"); + return -1; + } + ctx |= VIRGL_RENDERER_USE_SURFACELESS; + } + + if (getenv("VTEST_USE_GLES")) { + if (ctx & VIRGL_RENDERER_USE_GLX) { + fprintf(stderr, "Cannot use GLES with GLX.\n"); + return -1; + } + ctx |= VIRGL_RENDERER_USE_GLES; + } + + ret = virgl_renderer_init(&renderer, + ctx | VIRGL_RENDERER_THREAD_SYNC, &vtest_cbs); + if (ret) { fprintf(stderr, "failed to initialise renderer.\n"); return -1; - } + } - vtestname = calloc(1, length + 1); - if (!vtestname) + vtestname = calloc(1, length + 1); + if (!vtestname) { return -1; + } - ret = vtest_block_read(renderer.in_fd, vtestname, length); - if (ret != (int)length) { - ret = -1; - goto end; - } + ret = vtest_block_read(renderer.in_fd, vtestname, length); + if (ret != (int)length) { + ret = -1; + goto end; + } - ret = virgl_renderer_context_create(ctx_id, strlen(vtestname), vtestname); + ret = virgl_renderer_context_create(ctx_id, strlen(vtestname), vtestname); end: - free(vtestname); - return ret; + free(vtestname); + return ret; } int vtest_ping_protocol_version(UNUSED uint32_t length_dw) { - uint32_t hdr_buf[VTEST_HDR_SIZE]; - int ret; - - hdr_buf[VTEST_CMD_LEN] = VCMD_PING_PROTOCOL_VERSION_SIZE; - hdr_buf[VTEST_CMD_ID] = VCMD_PING_PROTOCOL_VERSION; - ret = vtest_block_write(renderer.out_fd, hdr_buf, sizeof(hdr_buf)); - if (ret < 0) - return ret; - return 0; + uint32_t hdr_buf[VTEST_HDR_SIZE]; + int ret; + + hdr_buf[VTEST_CMD_LEN] = VCMD_PING_PROTOCOL_VERSION_SIZE; + hdr_buf[VTEST_CMD_ID] = VCMD_PING_PROTOCOL_VERSION; + ret = vtest_block_write(renderer.out_fd, hdr_buf, sizeof(hdr_buf)); + if (ret < 0) { + return ret; + } + + return 0; } int vtest_protocol_version(UNUSED uint32_t length_dw) { - uint32_t hdr_buf[VTEST_HDR_SIZE]; - uint32_t version_buf[VCMD_PROTOCOL_VERSION_SIZE]; - int ret; + uint32_t hdr_buf[VTEST_HDR_SIZE]; + uint32_t version_buf[VCMD_PROTOCOL_VERSION_SIZE]; + int ret; - ret = vtest_block_read(renderer.in_fd, &version_buf, sizeof(version_buf)); - if (ret != sizeof(version_buf)) - return -1; + ret = vtest_block_read(renderer.in_fd, &version_buf, sizeof(version_buf)); + if (ret != sizeof(version_buf)) + return -1; - renderer.protocol_version = MIN2(version_buf[VCMD_PROTOCOL_VERSION_VERSION], - VTEST_PROTOCOL_VERSION); + renderer.protocol_version = MIN2(version_buf[VCMD_PROTOCOL_VERSION_VERSION], + VTEST_PROTOCOL_VERSION); - hdr_buf[VTEST_CMD_LEN] = VCMD_PROTOCOL_VERSION_SIZE; - hdr_buf[VTEST_CMD_ID] = VCMD_PROTOCOL_VERSION; + hdr_buf[VTEST_CMD_LEN] = VCMD_PROTOCOL_VERSION_SIZE; + hdr_buf[VTEST_CMD_ID] = VCMD_PROTOCOL_VERSION; - version_buf[VCMD_PROTOCOL_VERSION_VERSION] = renderer.protocol_version; + version_buf[VCMD_PROTOCOL_VERSION_VERSION] = renderer.protocol_version; - ret = vtest_block_write(renderer.out_fd, hdr_buf, sizeof(hdr_buf)); - if (ret < 0) + ret = vtest_block_write(renderer.out_fd, hdr_buf, sizeof(hdr_buf)); + if (ret < 0) { return ret; + } - ret = vtest_block_write(renderer.out_fd, version_buf, sizeof(version_buf)); - if (ret < 0) + ret = vtest_block_write(renderer.out_fd, version_buf, sizeof(version_buf)); + if (ret < 0) { return ret; + } - return 0; + return 0; } void vtest_destroy_renderer(void) { - virgl_renderer_context_destroy(ctx_id); - virgl_renderer_cleanup(&renderer); - renderer.in_fd = -1; - renderer.out_fd = -1; + virgl_renderer_context_destroy(ctx_id); + virgl_renderer_cleanup(&renderer); + renderer.in_fd = -1; + renderer.out_fd = -1; } int vtest_send_caps2(UNUSED uint32_t length_dw) { - uint32_t hdr_buf[2]; - void *caps_buf; - int ret; - uint32_t max_ver, max_size; - - virgl_renderer_get_cap_set(2, &max_ver, &max_size); - - if (max_size == 0) - return -1; - caps_buf = malloc(max_size); - if (!caps_buf) - return -1; - - virgl_renderer_fill_caps(2, 1, caps_buf); - - hdr_buf[0] = max_size + 1; - hdr_buf[1] = 2; - ret = vtest_block_write(renderer.out_fd, hdr_buf, 8); - if (ret < 0) - goto end; - vtest_block_write(renderer.out_fd, caps_buf, max_size); - if (ret < 0) - goto end; + uint32_t hdr_buf[2]; + void *caps_buf; + int ret; + uint32_t max_ver, max_size; + + virgl_renderer_get_cap_set(2, &max_ver, &max_size); + + if (max_size == 0) { + return -1; + } + + caps_buf = malloc(max_size); + if (!caps_buf) { + return -1; + } + + virgl_renderer_fill_caps(2, 1, caps_buf); + + hdr_buf[0] = max_size + 1; + hdr_buf[1] = 2; + ret = vtest_block_write(renderer.out_fd, hdr_buf, 8); + if (ret < 0) { + goto end; + } + + vtest_block_write(renderer.out_fd, caps_buf, max_size); + if (ret < 0) { + goto end; + } end: - free(caps_buf); - return 0; + free(caps_buf); + return 0; } int vtest_send_caps(UNUSED uint32_t length_dw) { - uint32_t max_ver, max_size; - void *caps_buf; - uint32_t hdr_buf[2]; - int ret; - - virgl_renderer_get_cap_set(1, &max_ver, &max_size); - - caps_buf = malloc(max_size); - if (!caps_buf) - return -1; - - virgl_renderer_fill_caps(1, 1, caps_buf); - - hdr_buf[0] = max_size + 1; - hdr_buf[1] = 1; - ret = vtest_block_write(renderer.out_fd, hdr_buf, 8); - if (ret < 0) - goto end; - vtest_block_write(renderer.out_fd, caps_buf, max_size); - if (ret < 0) - goto end; + uint32_t max_ver, max_size; + void *caps_buf; + uint32_t hdr_buf[2]; + int ret; + + virgl_renderer_get_cap_set(1, &max_ver, &max_size); + + caps_buf = malloc(max_size); + if (!caps_buf) { + return -1; + } + + virgl_renderer_fill_caps(1, 1, caps_buf); + + hdr_buf[0] = max_size + 1; + hdr_buf[1] = 1; + ret = vtest_block_write(renderer.out_fd, hdr_buf, 8); + if (ret < 0) { + goto end; + } + + vtest_block_write(renderer.out_fd, caps_buf, max_size); + if (ret < 0) { + goto end; + } end: - free(caps_buf); - return 0; + free(caps_buf); + return 0; } int vtest_create_resource(UNUSED uint32_t length_dw) { - uint32_t res_create_buf[VCMD_RES_CREATE_SIZE]; - struct virgl_renderer_resource_create_args args; - 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_CREATE_RES_HANDLE]; - args.target = res_create_buf[VCMD_RES_CREATE_TARGET]; - args.format = res_create_buf[VCMD_RES_CREATE_FORMAT]; - args.bind = res_create_buf[VCMD_RES_CREATE_BIND]; - - args.width = res_create_buf[VCMD_RES_CREATE_WIDTH]; - args.height = res_create_buf[VCMD_RES_CREATE_HEIGHT]; - args.depth = res_create_buf[VCMD_RES_CREATE_DEPTH]; - args.array_size = res_create_buf[VCMD_RES_CREATE_ARRAY_SIZE]; - args.last_level = res_create_buf[VCMD_RES_CREATE_LAST_LEVEL]; - args.nr_samples = res_create_buf[VCMD_RES_CREATE_NR_SAMPLES]; - args.flags = 0; - - ret = virgl_renderer_resource_create(&args, NULL, 0); - - virgl_renderer_ctx_attach_resource(ctx_id, args.handle); - return ret; + uint32_t res_create_buf[VCMD_RES_CREATE_SIZE]; + struct virgl_renderer_resource_create_args args; + 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_CREATE_RES_HANDLE]; + args.target = res_create_buf[VCMD_RES_CREATE_TARGET]; + args.format = res_create_buf[VCMD_RES_CREATE_FORMAT]; + args.bind = res_create_buf[VCMD_RES_CREATE_BIND]; + + args.width = res_create_buf[VCMD_RES_CREATE_WIDTH]; + args.height = res_create_buf[VCMD_RES_CREATE_HEIGHT]; + args.depth = res_create_buf[VCMD_RES_CREATE_DEPTH]; + args.array_size = res_create_buf[VCMD_RES_CREATE_ARRAY_SIZE]; + args.last_level = res_create_buf[VCMD_RES_CREATE_LAST_LEVEL]; + args.nr_samples = res_create_buf[VCMD_RES_CREATE_NR_SAMPLES]; + args.flags = 0; + + ret = virgl_renderer_resource_create(&args, NULL, 0); + + virgl_renderer_ctx_attach_resource(ctx_id, args.handle); + return ret; } int vtest_create_resource2(UNUSED uint32_t length_dw) { - 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; - - // Check that the handle doesn't already exist. - if (util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(args.handle))) + 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; + + // Check that the handle doesn't already exist. + if (util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(args.handle))) { return -EEXIST; + } - ret = virgl_renderer_resource_create(&args, NULL, 0); - if (ret) + ret = virgl_renderer_resource_create(&args, NULL, 0); + if (ret) { return ret; + } - virgl_renderer_ctx_attach_resource(ctx_id, args.handle); + virgl_renderer_ctx_attach_resource(ctx_id, args.handle); - iovec = CALLOC_STRUCT(iovec); - if (!iovec) + 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) + 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); - util_hash_table_set(renderer.iovec_hash, intptr_to_pointer(args.handle), iovec); + virgl_renderer_resource_attach_iov(args.handle, iovec, 1); + util_hash_table_set(renderer.iovec_hash, intptr_to_pointer(args.handle), iovec); - return ret; + return ret; } int vtest_resource_unref(UNUSED uint32_t length_dw) { - uint32_t res_unref_buf[VCMD_RES_UNREF_SIZE]; - int ret; - uint32_t handle; + uint32_t res_unref_buf[VCMD_RES_UNREF_SIZE]; + int ret; + uint32_t handle; - ret = vtest_block_read(renderer.in_fd, &res_unref_buf, sizeof(res_unref_buf)); - if (ret != sizeof(res_unref_buf)) + ret = vtest_block_read(renderer.in_fd, &res_unref_buf, sizeof(res_unref_buf)); + if (ret != sizeof(res_unref_buf)) { return -1; + } - handle = res_unref_buf[VCMD_RES_UNREF_RES_HANDLE]; - virgl_renderer_ctx_attach_resource(ctx_id, handle); + 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_detach_iov(handle, NULL, NULL); + util_hash_table_remove(renderer.iovec_hash, intptr_to_pointer(handle)); - virgl_renderer_resource_unref(handle); - return 0; + virgl_renderer_resource_unref(handle); + return 0; } int vtest_submit_cmd(uint32_t length_dw) { - uint32_t *cbuf; - int ret; + uint32_t *cbuf; + int ret; - if (length_dw > UINT_MAX / 4) - return -1; + if (length_dw > UINT_MAX / 4) { + return -1; + } - cbuf = malloc(length_dw * 4); - if (!cbuf) - return -1; + cbuf = malloc(length_dw * 4); + if (!cbuf) { + return -1; + } - ret = vtest_block_read(renderer.in_fd, cbuf, length_dw * 4); - if (ret != (int)length_dw * 4) { - free(cbuf); - return -1; - } + ret = vtest_block_read(renderer.in_fd, cbuf, length_dw * 4); + if (ret != (int)length_dw * 4) { + free(cbuf); + return -1; + } - virgl_renderer_submit_cmd(cbuf, ctx_id, length_dw); + virgl_renderer_submit_cmd(cbuf, ctx_id, length_dw); - free(cbuf); - return 0; + 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) + 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(UNUSED 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.in_fd, thdr_buf, VCMD_TRANSFER_HDR_SIZE * 4); - if (ret != VCMD_TRANSFER_HDR_SIZE * 4) + 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.in_fd, thdr_buf, VCMD_TRANSFER_HDR_SIZE * 4); + if (ret != VCMD_TRANSFER_HDR_SIZE * 4) { return ret; + } - DECODE_TRANSFER; + DECODE_TRANSFER; - ptr = malloc(data_size); - if (!ptr) + ptr = malloc(data_size); + if (!ptr) { return -ENOMEM; + } - iovec.iov_len = data_size; - iovec.iov_base = ptr; - ret = virgl_renderer_transfer_read_iov(handle, - ctx_id, - level, - stride, - layer_stride, - &box, - 0, - &iovec, 1); - if (ret) + iovec.iov_len = data_size; + iovec.iov_base = ptr; + ret = virgl_renderer_transfer_read_iov(handle, + ctx_id, + level, + stride, + layer_stride, + &box, + 0, + &iovec, 1); + if (ret) { fprintf(stderr," transfer read failed %d\n", ret); - ret = vtest_block_write(renderer.out_fd, ptr, data_size); + } + + ret = vtest_block_write(renderer.out_fd, ptr, data_size); - free(ptr); - return ret < 0 ? ret : 0; + free(ptr); + return ret < 0 ? ret : 0; } int vtest_transfer_put(UNUSED 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.in_fd, thdr_buf, VCMD_TRANSFER_HDR_SIZE * 4); - if (ret != VCMD_TRANSFER_HDR_SIZE * 4) + 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.in_fd, thdr_buf, VCMD_TRANSFER_HDR_SIZE * 4); + if (ret != VCMD_TRANSFER_HDR_SIZE * 4) { return ret; + } - DECODE_TRANSFER; + DECODE_TRANSFER; - ptr = malloc(data_size); - if (!ptr) + ptr = malloc(data_size); + if (!ptr) { return -ENOMEM; + } - ret = vtest_block_read(renderer.in_fd, ptr, data_size); - if (ret < 0) + ret = vtest_block_read(renderer.in_fd, ptr, data_size); + if (ret < 0) { return ret; + } - iovec.iov_len = data_size; - iovec.iov_base = ptr; - ret = virgl_renderer_transfer_write_iov(handle, - ctx_id, - level, - stride, - layer_stride, - &box, - 0, - &iovec, 1); - if (ret) + iovec.iov_len = data_size; + iovec.iov_base = ptr; + ret = virgl_renderer_transfer_write_iov(handle, + ctx_id, + level, + stride, + layer_stride, + &box, + 0, + &iovec, 1); + if (ret) { fprintf(stderr," transfer write failed %d\n", ret); - free(ptr); - return 0; + } + + free(ptr); + 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) + 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(UNUSED uint32_t length_dw) { - 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; - uint32_t extra_data = 0; - struct iovec *iovec; - - ret = vtest_block_read(renderer.in_fd, thdr_buf, sizeof(thdr_buf)); - if (ret != sizeof(thdr_buf)) { + 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; + uint32_t extra_data = 0; + struct iovec *iovec; + + ret = vtest_block_read(renderer.in_fd, thdr_buf, sizeof(thdr_buf)); + if (ret != sizeof(thdr_buf)) { return ret; - } + } - DECODE_TRANSFER2; + DECODE_TRANSFER2; - iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle)); - if (!iovec) { + iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle)); + if (!iovec) { return report_failed_call("util_hash_table_get", -ESRCH); - } + } - if (offset >= iovec->iov_len) { + if (offset >= iovec->iov_len) { return report_failure("offset larger then length of backing store", -EFAULT); - } - - ret = virgl_renderer_transfer_read_iov(handle, - ctx_id, - level, - 0, - 0, - &box, - offset, - NULL, 0); - if (ret) { + } + + ret = virgl_renderer_transfer_read_iov(handle, + ctx_id, + level, + 0, + 0, + &box, + offset, + NULL, 0); + if (ret) { return report_failed_call("virgl_renderer_transfer_read_iov", ret); - } + } - /* Make sure we don't read out of bounds. */ - if (data_size > (iovec->iov_len - offset)) { + /* Make sure we don't read out of bounds. */ + if (data_size > (iovec->iov_len - offset)) { extra_data = data_size - (iovec->iov_len - offset); data_size -= extra_data; - } + } - ret = vtest_block_write(renderer.out_fd, - iovec->iov_base + offset, - data_size); - if (ret < 0) { + ret = vtest_block_write(renderer.out_fd, + iovec->iov_base + offset, + data_size); + if (ret < 0) { return report_failed_call("vtest_block_write", ret); - } + } - if (extra_data) { + if (extra_data) { ret = vtest_block_write_zero(renderer.out_fd, extra_data); if (ret < 0) { - return report_failed_call("vtest_block_write_zero", ret); + return report_failed_call("vtest_block_write_zero", ret); } - } + } - return ret < 0 ? ret : 0; + return ret < 0 ? ret : 0; } int vtest_transfer_put2(UNUSED uint32_t length_dw) { - 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)) + 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; + DECODE_TRANSFER2; - iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle)); - if (!iovec) { + iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle)); + if (!iovec) { return report_failed_call("util_hash_table_get", -ESRCH); - } + } - ret = vtest_block_read(renderer.in_fd, iovec->iov_base + offset, data_size); - if (ret < 0) { + ret = vtest_block_read(renderer.in_fd, iovec->iov_base + offset, data_size); + if (ret < 0) { return report_failed_call("vtest_block_read", ret); - } - - ret = virgl_renderer_transfer_write_iov(handle, - ctx_id, - level, - 0, - 0, - &box, - offset, - NULL, 0); - if (ret) { + } + + ret = virgl_renderer_transfer_write_iov(handle, + ctx_id, + level, + 0, + 0, + &box, + offset, + NULL, 0); + if (ret) { return report_failed_call("virgl_renderer_transfer_write_iov", ret); - } + } - return 0; + return 0; } int vtest_resource_busy_wait(UNUSED uint32_t length_dw) { - uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE]; - int ret, fd; - int flags; - uint32_t hdr_buf[VTEST_HDR_SIZE]; - uint32_t reply_buf[1]; - bool busy = false; - - vtest_renderer_create_fence(); - ret = vtest_block_read(renderer.in_fd, &bw_buf, sizeof(bw_buf)); - if (ret != sizeof(bw_buf)) - return -1; - - /* handle = bw_buf[VCMD_BUSY_WAIT_HANDLE]; unused as of now */ - flags = bw_buf[VCMD_BUSY_WAIT_FLAGS]; - - if (flags == VCMD_BUSY_WAIT_FLAG_WAIT) { - do { - if (last_fence == (fence_id - 1)) - break; - - fd = virgl_renderer_get_poll_fd(); - if (fd != -1) - vtest_wait_for_fd_read(fd); - virgl_renderer_poll(); - } 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; - - ret = vtest_block_write(renderer.out_fd, hdr_buf, sizeof(hdr_buf)); - if (ret < 0) - return ret; - - ret = vtest_block_write(renderer.out_fd, reply_buf, sizeof(reply_buf)); - if (ret < 0) - return ret; - - return 0; + uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE]; + int ret, fd; + int flags; + uint32_t hdr_buf[VTEST_HDR_SIZE]; + uint32_t reply_buf[1]; + bool busy = false; + + vtest_renderer_create_fence(); + ret = vtest_block_read(renderer.in_fd, &bw_buf, sizeof(bw_buf)); + if (ret != sizeof(bw_buf)) { + return -1; + } + + /* handle = bw_buf[VCMD_BUSY_WAIT_HANDLE]; unused as of now */ + flags = bw_buf[VCMD_BUSY_WAIT_FLAGS]; + + if (flags == VCMD_BUSY_WAIT_FLAG_WAIT) { + do { + if (last_fence == (fence_id - 1)) { + break; + } + + fd = virgl_renderer_get_poll_fd(); + if (fd != -1) { + vtest_wait_for_fd_read(fd); + } + + virgl_renderer_poll(); + } 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; + + ret = vtest_block_write(renderer.out_fd, hdr_buf, sizeof(hdr_buf)); + if (ret < 0) { + return ret; + } + + ret = vtest_block_write(renderer.out_fd, reply_buf, sizeof(reply_buf)); + if (ret < 0) { + return ret; + } + + return 0; } int vtest_renderer_create_fence(void) { - virgl_renderer_create_fence(fence_id++, ctx_id); - return 0; + virgl_renderer_create_fence(fence_id++, ctx_id); + return 0; } int vtest_poll(void) { - virgl_renderer_poll(); - return 0; + virgl_renderer_poll(); + return 0; } diff --git a/vtest/vtest_server.c b/vtest/vtest_server.c index d7f7c9b..578c474 100644 --- a/vtest/vtest_server.c +++ b/vtest/vtest_server.c @@ -21,6 +21,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ + #include #include #include @@ -37,54 +38,56 @@ #include "vtest.h" #include "vtest_protocol.h" + static int vtest_open_socket(const char *path) { - struct sockaddr_un un; - int sock; - - sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - return -1; - } - - memset(&un, 0, sizeof(un)); - un.sun_family = AF_UNIX; - - snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); - - unlink(un.sun_path); - - if (bind(sock, (struct sockaddr *)&un, sizeof(un)) < 0) { - goto err; - } - - if (listen(sock, 1) < 0){ - goto err; - } - - return sock; - err: - close(sock); - return -1; + struct sockaddr_un un; + int sock; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + return -1; + } + + memset(&un, 0, sizeof(un)); + un.sun_family = AF_UNIX; + + snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); + + unlink(un.sun_path); + + if (bind(sock, (struct sockaddr *)&un, sizeof(un)) < 0) { + goto err; + } + + if (listen(sock, 1) < 0){ + goto err; + } + + return sock; +err: + close(sock); + return -1; } static int wait_for_socket_accept(int sock) { - fd_set read_fds; - int new_fd; - int ret; - FD_ZERO(&read_fds); - FD_SET(sock, &read_fds); - - ret = select(sock + 1, &read_fds, NULL, NULL, NULL); - if (ret < 0) - return ret; - - if (FD_ISSET(sock, &read_fds)) { - new_fd = accept(sock, NULL, NULL); - return new_fd; - } - return -1; + fd_set read_fds; + int new_fd; + int ret; + FD_ZERO(&read_fds); + FD_SET(sock, &read_fds); + + ret = select(sock + 1, &read_fds, NULL, NULL, NULL); + if (ret < 0) { + return ret; + } + + if (FD_ISSET(sock, &read_fds)) { + new_fd = accept(sock, NULL, NULL); + return new_fd; + } + return -1; } typedef int (*vtest_cmd_fptr_t)(uint32_t); @@ -168,11 +171,11 @@ static int run_renderer(int in_fd, int out_fd) int main(int argc, char **argv) { - int ret, sock = -1, in_fd, out_fd; - pid_t pid; - bool do_fork = true, loop = true; - struct sigaction sa; - char *socket_name = VTEST_DEFAULT_SOCKET_NAME; + int ret, sock = -1, in_fd, out_fd; + pid_t pid; + bool do_fork = true, loop = true; + struct sigaction sa; + char *socket_name = VTEST_DEFAULT_SOCKET_NAME; #ifdef __AFL_LOOP while (__AFL_LOOP(1000)) { @@ -180,10 +183,10 @@ while (__AFL_LOOP(1000)) { if (argc > 1) { if (!strcmp(argv[1], "--no-loop-or-fork")) { - do_fork = false; - loop = false; + do_fork = false; + loop = false; } else if (!strcmp(argv[1], "--no-fork")) { - do_fork = false; + do_fork = false; } else { ret = open(argv[1], O_RDONLY); if (ret == -1) { @@ -201,48 +204,52 @@ while (__AFL_LOOP(1000)) { do_fork = false; goto start; } - } + } - if (do_fork) { + if (do_fork) { sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGCHLD, &sa, 0) == -1) { - perror(0); - exit(1); + perror(0); + exit(1); } - } + } - sock = vtest_open_socket(socket_name); + sock = vtest_open_socket(socket_name); restart: - in_fd = wait_for_socket_accept(sock); - out_fd = in_fd; + in_fd = wait_for_socket_accept(sock); + out_fd = in_fd; start: - if (do_fork) { + if (do_fork) { /* fork a renderer process */ switch ((pid = fork())) { case 0: - run_renderer(in_fd, out_fd); - exit(0); - break; + run_renderer(in_fd, out_fd); + exit(0); + break; case -1: default: - close(in_fd); - if (loop) - goto restart; + close(in_fd); + if (loop) { + goto restart; + } } - } else { + } else { run_renderer(in_fd, out_fd); vtest_destroy_renderer(); - if (loop) + if (loop) { goto restart; - } + } + } - if (sock != -1) - close(sock); - if (in_fd != out_fd) - close(out_fd); + if (sock != -1) { + close(sock); + } + if (in_fd != out_fd) { + close(out_fd); + } #ifdef __AFL_LOOP }