vtest: Add backing store to each resource

With the main aim of making vtest's usage of virglrenderer more similar
to that of QEMU, this patch sets a backing store to each resource and
reads from or writes to at each transfer operation.

v2: - Instead of adding a callback on resource destruction, free the
      iovec when we unref a resource as we know that we won't be doing
      anything else with it. (Dave Airlie)

v3: - Store pointers to iovecs in the global to also release them

v4: - Add new commands for resource creation and transfers, to be used
      when protocol version >= 1.

v5: - Replaced the global array of iovecs with a hash table because some
      es31 tests create thousands of resources and reach any sane limit.

Tested-by: Jakob Bornecrantz <jakob@collabora.com>
Reviewed-by: Jakob Bornecrantz <jakob@collabora.com>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Jakob Bornecrantz <jakob@collabora.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
macos/master
Tomeu Vizoso 6 years ago committed by Dave Airlie
parent 33da7361ae
commit 6373d5a35f
  1. 3
      vtest/vtest.h
  2. 29
      vtest/vtest_protocol.h
  3. 167
      vtest/vtest_renderer.c
  4. 9
      vtest/vtest_server.c

@ -30,11 +30,14 @@ int vtest_create_renderer(int in_fd, int out_fd, uint32_t length);
int vtest_send_caps(void);
int vtest_send_caps2(void);
int vtest_create_resource(void);
int vtest_create_resource2(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_get2(void);
int vtest_transfer_put(uint32_t length_dw);
int vtest_transfer_put2(void);
int vtest_block_read(int fd, void *buf, int size);

@ -59,6 +59,10 @@
#define VCMD_PROTOCOL_VERSION 11
#define VCMD_RESOURCE_CREATE2 12
#define VCMD_TRANSFER_GET2 13
#define VCMD_TRANSFER_PUT2 14
#define VCMD_RES_CREATE_SIZE 10
#define VCMD_RES_CREATE_RES_HANDLE 0
#define VCMD_RES_CREATE_TARGET 1
@ -71,6 +75,19 @@
#define VCMD_RES_CREATE_LAST_LEVEL 8
#define VCMD_RES_CREATE_NR_SAMPLES 9
#define VCMD_RES_CREATE2_SIZE 11
#define VCMD_RES_CREATE2_RES_HANDLE 0
#define VCMD_RES_CREATE2_TARGET 1
#define VCMD_RES_CREATE2_FORMAT 2
#define VCMD_RES_CREATE2_BIND 3
#define VCMD_RES_CREATE2_WIDTH 4
#define VCMD_RES_CREATE2_HEIGHT 5
#define VCMD_RES_CREATE2_DEPTH 6
#define VCMD_RES_CREATE2_ARRAY_SIZE 7
#define VCMD_RES_CREATE2_LAST_LEVEL 8
#define VCMD_RES_CREATE2_NR_SAMPLES 9
#define VCMD_RES_CREATE2_DATA_SIZE 10
#define VCMD_RES_UNREF_SIZE 1
#define VCMD_RES_UNREF_RES_HANDLE 0
@ -87,6 +104,18 @@
#define VCMD_TRANSFER_DEPTH 9
#define VCMD_TRANSFER_DATA_SIZE 10
#define VCMD_TRANSFER2_HDR_SIZE 10
#define VCMD_TRANSFER2_RES_HANDLE 0
#define VCMD_TRANSFER2_LEVEL 1
#define VCMD_TRANSFER2_X 2
#define VCMD_TRANSFER2_Y 3
#define VCMD_TRANSFER2_Z 4
#define VCMD_TRANSFER2_WIDTH 5
#define VCMD_TRANSFER2_HEIGHT 6
#define VCMD_TRANSFER2_DEPTH 7
#define VCMD_TRANSFER2_DATA_SIZE 8
#define VCMD_TRANSFER2_OFFSET 9
#define VCMD_BUSY_WAIT_FLAG_WAIT 1
#define VCMD_BUSY_WAIT_SIZE 2

@ -36,6 +36,8 @@
#include "util.h"
#include "util/u_debug.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_hash_table.h"
static int ctx_id = 1;
static int fence_id = 1;
@ -55,6 +57,7 @@ struct vtest_renderer {
int in_fd;
int out_fd;
unsigned protocol_version;
struct util_hash_table *iovec_hash;
};
struct vtest_renderer renderer;
@ -64,6 +67,32 @@ struct virgl_box {
uint32_t w, h, d;
};
static unsigned
hash_func(void *key)
{
intptr_t ip = pointer_to_intptr(key);
return (unsigned)(ip & 0xffffffff);
}
static int
compare_iovecs(void *key1, void *key2)
{
if (key1 < key2)
return -1;
if (key1 > key2)
return 1;
else
return 0;
}
static void free_iovec(void *value)
{
struct iovec *iovec = value;
free(iovec->iov_base);
free(iovec);
}
static int vtest_block_write(int fd, void *buf, int size)
{
void *ptr = buf;
@ -118,6 +147,7 @@ int vtest_create_renderer(int in_fd, int out_fd, uint32_t length)
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;
@ -306,6 +336,52 @@ int vtest_create_resource(void)
return ret;
}
int vtest_create_resource2(void)
{
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;
ret = virgl_renderer_resource_create(&args, NULL, 0);
if (ret)
return ret;
virgl_renderer_ctx_attach_resource(ctx_id, args.handle);
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)
return -ENOMEM;
virgl_renderer_resource_attach_iov(args.handle, iovec, 1);
assert(!util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(args.handle)));
util_hash_table_set(renderer.iovec_hash, intptr_to_pointer(args.handle), iovec);
return ret;
}
int vtest_resource_unref(void)
{
uint32_t res_unref_buf[VCMD_RES_UNREF_SIZE];
@ -318,6 +394,10 @@ int vtest_resource_unref(void)
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_unref(handle);
return 0;
}
@ -442,6 +522,93 @@ int vtest_transfer_put(UNUSED uint32_t length_dw)
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)
int vtest_transfer_get2(void)
{
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;
ret = virgl_renderer_transfer_read_iov(handle,
ctx_id,
level,
0,
0,
&box,
offset,
NULL, 0);
if (ret)
fprintf(stderr," transfer read failed %d\n", ret);
iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle));
assert(iovec);
ret = vtest_block_write(renderer.out_fd,
iovec->iov_base + offset,
data_size);
return ret < 0 ? ret : 0;
}
int vtest_transfer_put2(void)
{
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;
iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle));
assert(iovec);
ret = vtest_block_read(renderer.in_fd, iovec->iov_base + offset, data_size);
if (ret < 0)
return ret;
ret = virgl_renderer_transfer_write_iov(handle,
ctx_id,
level,
0,
0,
&box,
offset,
NULL, 0);
if (ret)
fprintf(stderr," transfer write failed %d\n", ret);
return 0;
}
int vtest_resource_busy_wait(void)
{
uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE];

@ -113,6 +113,9 @@ again:
case VCMD_RESOURCE_CREATE:
ret = vtest_create_resource();
break;
case VCMD_RESOURCE_CREATE2:
ret = vtest_create_resource2();
break;
case VCMD_RESOURCE_UNREF:
ret = vtest_resource_unref();
break;
@ -125,6 +128,12 @@ again:
case VCMD_TRANSFER_PUT:
ret = vtest_transfer_put(header[0]);
break;
case VCMD_TRANSFER_GET2:
ret = vtest_transfer_get2();
break;
case VCMD_TRANSFER_PUT2:
ret = vtest_transfer_put2();
break;
case VCMD_RESOURCE_BUSY_WAIT:
vtest_renderer_create_fence();
ret = vtest_resource_busy_wait();

Loading…
Cancel
Save