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