[virglrenderer-devel] [RFC PATCH] vtest: Add backing store to each resource
Tomeu Vizoso
tomeu.vizoso at collabora.com
Mon Jul 30 14:27:34 UTC 2018
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.
---
Standing issues:
- Doesn't address compatibility with the mesa side. Can we assume the
user of vtest knows which Mesa version to use?
- The backing store isn't released. Should we add a callback from
vrend_renderer_resource_destroy?
- There's the problem with the offset passed to the transfer API
pointing to the first pixel that Mesa is interested in, but the size arg
refers to whole lines/layers.
Any opinions welcome.
Thanks,
Tomeu
---
src/virglrenderer.h | 2 ++
src/vrend_renderer.c | 2 ++
src/vrend_renderer.h | 2 ++
vtest/vtest_protocol.h | 6 +++--
vtest/vtest_renderer.c | 59 ++++++++++++++++++++++++++----------------
5 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/src/virglrenderer.h b/src/virglrenderer.h
index bc7cedfeaa53..7591a69a2005 100644
--- a/src/virglrenderer.h
+++ b/src/virglrenderer.h
@@ -167,6 +167,8 @@ struct virgl_renderer_resource_info {
uint32_t flags;
uint32_t tex_id;
uint32_t stride;
+ struct iovec *iov;
+ uint32_t num_iovs;
int drm_fourcc;
};
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 70622209eba6..04b4db7612e7 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -7994,6 +7994,8 @@ int vrend_renderer_resource_get_info(int res_handle,
info->format = res->base.format;
info->flags = res->y_0_top ? VIRGL_RESOURCE_Y_0_TOP : 0;
info->stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, 0)) * elsize;
+ info->iov = res->iov;
+ info->num_iovs = res->num_iovs;
return 0;
}
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index 8f1192ecc507..c99e3e16f801 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -348,6 +348,8 @@ struct vrend_renderer_resource_info {
uint32_t flags;
uint32_t tex_id;
uint32_t stride;
+ struct iovec *iov;
+ uint32_t num_iovs;
};
int vrend_renderer_resource_get_info(int res_handle,
diff --git a/vtest/vtest_protocol.h b/vtest/vtest_protocol.h
index f6176437e6e9..1d3e426998d1 100644
--- a/vtest/vtest_protocol.h
+++ b/vtest/vtest_protocol.h
@@ -54,7 +54,7 @@
/* 0 length cmd */
/* resp VCMD_GET_CAPS + caps */
-#define VCMD_RES_CREATE_SIZE 10
+#define VCMD_RES_CREATE_SIZE 11
#define VCMD_RES_CREATE_RES_HANDLE 0
#define VCMD_RES_CREATE_TARGET 1
#define VCMD_RES_CREATE_FORMAT 2
@@ -65,11 +65,12 @@
#define VCMD_RES_CREATE_ARRAY_SIZE 7
#define VCMD_RES_CREATE_LAST_LEVEL 8
#define VCMD_RES_CREATE_NR_SAMPLES 9
+#define VCMD_RES_CREATE_DATA_SIZE 10
#define VCMD_RES_UNREF_SIZE 1
#define VCMD_RES_UNREF_RES_HANDLE 0
-#define VCMD_TRANSFER_HDR_SIZE 11
+#define VCMD_TRANSFER_HDR_SIZE 12
#define VCMD_TRANSFER_RES_HANDLE 0
#define VCMD_TRANSFER_LEVEL 1
#define VCMD_TRANSFER_STRIDE 2
@@ -81,6 +82,7 @@
#define VCMD_TRANSFER_HEIGHT 8
#define VCMD_TRANSFER_DEPTH 9
#define VCMD_TRANSFER_DATA_SIZE 10
+#define VCMD_TRANSFER_OFFSET 11
#define VCMD_BUSY_WAIT_FLAG_WAIT 1
diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c
index 8f0262a83b20..a5cbc63807fa 100644
--- a/vtest/vtest_renderer.c
+++ b/vtest/vtest_renderer.c
@@ -35,6 +35,7 @@
#include "vtest_protocol.h"
#include "util.h"
#include "util/u_debug.h"
+#include "util/u_memory.h"
static int ctx_id = 1;
static int fence_id = 1;
@@ -234,6 +235,7 @@ int vtest_create_resource(void)
{
uint32_t res_create_buf[VCMD_RES_CREATE_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));
@@ -254,8 +256,22 @@ int vtest_create_resource(void)
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_CREATE_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);
+
return ret;
}
@@ -312,6 +328,7 @@ int vtest_submit_cmd(uint32_t length_dw)
box.h = thdr_buf[VCMD_TRANSFER_HEIGHT]; \
box.d = thdr_buf[VCMD_TRANSFER_DEPTH]; \
data_size = thdr_buf[VCMD_TRANSFER_DATA_SIZE]; \
+ offset = thdr_buf[VCMD_TRANSFER_OFFSET]; \
} while(0)
@@ -322,9 +339,9 @@ int vtest_transfer_get(UNUSED uint32_t length_dw)
int level;
uint32_t stride, layer_stride, handle;
struct virgl_box box;
+ struct virgl_renderer_resource_info info;
uint32_t data_size;
- void *ptr;
- struct iovec iovec;
+ uint32_t offset;
ret = vtest_block_read(renderer.in_fd, thdr_buf, VCMD_TRANSFER_HDR_SIZE * 4);
if (ret != VCMD_TRANSFER_HDR_SIZE * 4)
@@ -332,25 +349,19 @@ int vtest_transfer_get(UNUSED uint32_t length_dw)
DECODE_TRANSFER;
- 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);
+ offset,
+ NULL, 0);
if (ret)
fprintf(stderr," transfer read failed %d\n", ret);
- ret = vtest_block_write(renderer.out_fd, ptr, data_size);
- free(ptr);
+ virgl_renderer_resource_get_info(handle, &info);
+ ret = vtest_block_write(renderer.out_fd, info.iov[0].iov_base + offset, data_size);
return ret < 0 ? ret : 0;
}
@@ -361,9 +372,9 @@ int vtest_transfer_put(UNUSED uint32_t length_dw)
int level;
uint32_t stride, layer_stride, handle;
struct virgl_box box;
+ struct virgl_renderer_resource_info info;
uint32_t data_size;
- void *ptr;
- struct iovec iovec;
+ uint32_t offset;
ret = vtest_block_read(renderer.in_fd, thdr_buf, VCMD_TRANSFER_HDR_SIZE * 4);
if (ret != VCMD_TRANSFER_HDR_SIZE * 4)
@@ -371,27 +382,29 @@ int vtest_transfer_put(UNUSED uint32_t length_dw)
DECODE_TRANSFER;
- ptr = malloc(data_size);
- if (!ptr)
- return -ENOMEM;
+ virgl_renderer_resource_get_info(handle, &info);
+
+ /* HACK: We can get passed an offset to the middle of a row or layer, and
+ because of data_size being in whole rows or layers, offset + data_size
+ could be past the limits of the resource.
+ */
+ if (offset + data_size > info.iov[0].iov_len)
+ offset = info.iov[0].iov_len - data_size;
- ret = vtest_block_read(renderer.in_fd, ptr, data_size);
+ ret = vtest_block_read(renderer.in_fd, info.iov[0].iov_base + offset, 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);
+ offset,
+ NULL, 0);
if (ret)
fprintf(stderr," transfer write failed %d\n", ret);
- free(ptr);
return 0;
}
--
2.17.1
More information about the virglrenderer-devel
mailing list