vtest: finish transfer, start adding fences

macos/master
Dave Airlie 10 years ago
parent 020b8307e1
commit 1e9560f092
  1. 10
      vtest/vtest.h
  2. 17
      vtest/vtest_protocol.h
  3. 199
      vtest/vtest_renderer.c
  4. 20
      vtest/vtest_server.c

@ -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

@ -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

@ -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();
}

@ -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:

Loading…
Cancel
Save