summaryrefslogtreecommitdiff
path: root/vtest
diff options
context:
space:
mode:
authorDave Airlie <airlied@gmail.com>2015-03-16 12:30:15 +1000
committerDave Airlie <airlied@gmail.com>2015-03-16 12:30:15 +1000
commit1e9560f092cee1dccd641954a11a6082f882c79a (patch)
tree13481c3ceb2abb48ed23cf805e2d0c65691b07b2 /vtest
parent020b8307e12c0512c76596606a7cdbc3a740b607 (diff)
vtest: finish transfer, start adding fences
Diffstat (limited to 'vtest')
-rw-r--r--vtest/vtest.h10
-rw-r--r--vtest/vtest_protocol.h17
-rw-r--r--vtest/vtest_renderer.c199
-rw-r--r--vtest/vtest_server.c20
4 files changed, 231 insertions, 15 deletions
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 <errno.h>
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 <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "virglrenderer.h"
+#include <sys/uio.h>
+#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 <stdio.h>
+#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -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: