vtest: assign vtest_resource unique server-generated id

This paves the way for a protcol change where the server will
generate resource ids.  This also improves our error handling by
switching from FREE to vtest_unref_resource.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Ryan Neph <ryanneph@google.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
Chia-I Wu 4 years ago
parent 76be631ae5
commit 50e05e95e6
  1. 88
      vtest/vtest_renderer.c

@ -48,6 +48,9 @@
#include "util/u_hash_table.h" #include "util/u_hash_table.h"
struct vtest_resource { struct vtest_resource {
struct list_head head;
uint32_t server_res_id;
uint32_t res_id; uint32_t res_id;
struct iovec iov; struct iovec iov;
@ -82,6 +85,9 @@ struct vtest_renderer {
struct list_head free_contexts; struct list_head free_contexts;
int next_context_id; int next_context_id;
struct list_head free_resources;
int next_resource_id;
struct vtest_context *current_context; struct vtest_context *current_context;
}; };
@ -115,8 +121,45 @@ static struct vtest_renderer renderer = {
.max_length = UINT_MAX, .max_length = UINT_MAX,
.fence_id = 1, .fence_id = 1,
.next_context_id = 1, .next_context_id = 1,
.next_resource_id = 1,
}; };
static struct vtest_resource *vtest_new_resource(uint32_t client_res_id)
{
struct vtest_resource *res;
if (LIST_IS_EMPTY(&renderer.free_resources)) {
res = malloc(sizeof(*res));
if (!res) {
return NULL;
}
res->server_res_id = renderer.next_resource_id++;
} else {
res = LIST_ENTRY(struct vtest_resource, renderer.free_resources.next, head);
list_del(&res->head);
}
res->res_id = client_res_id ? client_res_id : res->server_res_id;
res->iov.iov_base = NULL;
res->iov.iov_len = 0;
return res;
}
static void vtest_unref_resource(struct vtest_resource *res)
{
/* virgl_renderer_ctx_detach_resource and virgl_renderer_resource_detach_iov
* are implied
*/
virgl_renderer_resource_unref(res->res_id);
if (res->iov.iov_base)
munmap(res->iov.iov_base, res->iov.iov_len);
list_add(&res->head, &renderer.free_resources);
}
static unsigned static unsigned
resource_hash_func(void *key) resource_hash_func(void *key)
{ {
@ -140,15 +183,7 @@ static void
resource_destroy_func(void *value) resource_destroy_func(void *value)
{ {
struct vtest_resource *res = value; struct vtest_resource *res = value;
vtest_unref_resource(res);
/* virgl_renderer_ctx_detach_resource and virgl_renderer_resource_detach_iov
* are implied
*/
virgl_renderer_resource_unref(res->res_id);
if (res->iov.iov_base)
munmap(res->iov.iov_base, res->iov.iov_len);
free(res);
} }
static int vtest_block_write(int fd, void *buf, int size) static int vtest_block_write(int fd, void *buf, int size)
@ -263,6 +298,7 @@ int vtest_init_renderer(int ctx_flags, const char *render_device)
renderer.rendernode_name = render_device; renderer.rendernode_name = render_device;
list_inithead(&renderer.active_contexts); list_inithead(&renderer.active_contexts);
list_inithead(&renderer.free_contexts); list_inithead(&renderer.free_contexts);
list_inithead(&renderer.free_resources);
ret = virgl_renderer_init(&renderer, ret = virgl_renderer_init(&renderer,
ctx_flags | VIRGL_RENDERER_THREAD_SYNC, &renderer_cbs); ctx_flags | VIRGL_RENDERER_THREAD_SYNC, &renderer_cbs);
@ -294,6 +330,17 @@ void vtest_cleanup_renderer(void)
renderer.current_context = NULL; renderer.current_context = NULL;
} }
if (renderer.next_resource_id > 1) {
struct vtest_resource *res, *tmp;
LIST_FOR_EACH_ENTRY_SAFE(res, tmp, &renderer.free_resources, head) {
free(res);
}
list_inithead(&renderer.free_resources);
renderer.next_resource_id = 1;
}
virgl_renderer_cleanup(&renderer); virgl_renderer_cleanup(&renderer);
} }
@ -767,16 +814,18 @@ static int vtest_create_resource_internal(struct vtest_context *ctx,
if (util_hash_table_get(ctx->resource_table, intptr_to_pointer(args->handle))) if (util_hash_table_get(ctx->resource_table, intptr_to_pointer(args->handle)))
return -EEXIST; return -EEXIST;
res = vtest_new_resource(args->handle);
if (!res)
return -ENOMEM;
args->handle = res->res_id;
ret = virgl_renderer_resource_create(args, NULL, 0); ret = virgl_renderer_resource_create(args, NULL, 0);
if (ret) if (ret) {
vtest_unref_resource(res);
return report_failed_call("virgl_renderer_resource_create", ret); return report_failed_call("virgl_renderer_resource_create", ret);
}
virgl_renderer_ctx_attach_resource(ctx->ctx_id, args->handle); virgl_renderer_ctx_attach_resource(ctx->ctx_id, res->res_id);
res = CALLOC_STRUCT(vtest_resource);
if (!res)
return -ENOMEM;
res->res_id = args->handle;
/* no shm for v1 resources or v2 multi-sample resources */ /* no shm for v1 resources or v2 multi-sample resources */
if (shm_size) { if (shm_size) {
@ -784,22 +833,21 @@ static int vtest_create_resource_internal(struct vtest_context *ctx,
fd = vtest_create_resource_setup_shm(res, shm_size); fd = vtest_create_resource_setup_shm(res, shm_size);
if (fd < 0) { if (fd < 0) {
FREE(res); vtest_unref_resource(res);
return -ENOMEM; return -ENOMEM;
} }
ret = vtest_send_fd(ctx->out_fd, fd); ret = vtest_send_fd(ctx->out_fd, fd);
if (ret < 0) { if (ret < 0) {
munmap(res->iov.iov_base, res->iov.iov_len);
close(fd); close(fd);
FREE(res); vtest_unref_resource(res);
return report_failed_call("vtest_send_fd", ret); return report_failed_call("vtest_send_fd", ret);
} }
/* Closing the file descriptor does not unmap the region. */ /* Closing the file descriptor does not unmap the region. */
close(fd); close(fd);
virgl_renderer_resource_attach_iov(args->handle, &res->iov, 1); virgl_renderer_resource_attach_iov(res->res_id, &res->iov, 1);
} }
util_hash_table_set(ctx->resource_table, intptr_to_pointer(res->res_id), res); util_hash_table_set(ctx->resource_table, intptr_to_pointer(res->res_id), res);

Loading…
Cancel
Save