From 96c3418e063d0a2e2ac1b83dc11a5a25cbef9555 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 12 Dec 2018 09:49:35 -0800 Subject: [PATCH] virgl/vtest: receive and handle shared memory fd The only tricky part is with protocol 0 we can either have a display target or resource backing store. With protocol 2 we can have both. Make the map/unmap functions only deal with the resource backing store. v2: Handle MSAA texture case. v3: spelling v4: Fix dangling else (@prak) v5: mmap --> os_mmap (@prak) + added comments (@gerddie) Signed-off-by: Gurchetan Singh Reviewed-By: Gert Wollny Reviewed-By: Piotr Rak --- .../winsys/virgl/vtest/virgl_vtest_socket.c | 11 +++- .../winsys/virgl/vtest/virgl_vtest_winsys.c | 51 ++++++++++++++++--- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c index 71c10d9c523..58005df5595 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c @@ -300,7 +300,16 @@ static int virgl_vtest_send_resource_create2(struct virgl_vtest_winsys *vws, virgl_block_write(vws->sock_fd, &vtest_hdr, sizeof(vtest_hdr)); virgl_block_write(vws->sock_fd, &res_create_buf, sizeof(res_create_buf)); - *out_fd = -1; + + /* Multi-sampled textures have no backing store attached. */ + if (size == 0) + return 0; + + *out_fd = virgl_vtest_receive_fd(vws->sock_fd); + if (*out_fd < 0) { + fprintf(stderr, "failed to get fd\n"); + return -1; + } return 0; } diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c index 2952189dfb7..42c608e1b83 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c @@ -26,6 +26,7 @@ #include "util/u_inlines.h" #include "util/os_time.h" #include "state_tracker/sw_winsys.h" +#include "os/os_mman.h" #include "virgl_vtest_winsys.h" #include "virgl_vtest_public.h" @@ -134,7 +135,13 @@ static void virgl_hw_res_destroy(struct virgl_vtest_winsys *vtws, virgl_vtest_send_resource_unref(vtws, res->res_handle); if (res->dt) vtws->sws->displaytarget_destroy(vtws->sws, res->dt); - free(res->ptr); + if (vtws->protocol_version >= 2) { + if (res->ptr) + os_munmap(res->ptr, res->size); + } else { + free(res->ptr); + } + FREE(res); } @@ -242,7 +249,7 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws, width, height, 64, NULL, &res->stride); - } else { + } else if (vtws->protocol_version < 2) { res->ptr = align_malloc(size, 64); if (!res->ptr) { FREE(res); @@ -259,6 +266,32 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws, width, height, depth, array_size, last_level, nr_samples, size, &fd); + if (vtws->protocol_version >= 2) { + if (res->size == 0) { + res->ptr = NULL; + goto out; + } + + if (fd < 0) { + FREE(res); + fprintf(stderr, "Unable to get a valid fd\n"); + return NULL; + } + + res->ptr = os_mmap(NULL, res->size, PROT_WRITE | PROT_READ, MAP_SHARED, + fd, 0); + + if (res->ptr == MAP_FAILED) { + fprintf(stderr, "Client failed to map shared memory region\n"); + close(fd); + FREE(res); + return NULL; + } + + close(fd); + } + +out: res->res_handle = handle++; pipe_reference_init(&res->reference, 1); p_atomic_set(&res->num_cs_references, 0); @@ -277,11 +310,17 @@ static void *virgl_vtest_resource_map(struct virgl_winsys *vws, { struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws); - if (res->dt) { - return vtws->sws->displaytarget_map(vtws->sws, res->dt, 0); - } else { + /* + * With protocol v0 we can either have a display target or a resource backing + * store. With protocol v2 we can have both, so only return the memory mapped + * backing store in this function. We can copy to the display target when + * appropriate. + */ + if (vtws->protocol_version >= 2 || !res->dt) { res->mapped = res->ptr; return res->mapped; + } else { + return vtws->sws->displaytarget_map(vtws->sws, res->dt, 0); } } @@ -292,7 +331,7 @@ static void virgl_vtest_resource_unmap(struct virgl_winsys *vws, if (res->mapped) res->mapped = NULL; - if (res->dt) + if (res->dt && vtws->protocol_version < 2) vtws->sws->displaytarget_unmap(vtws->sws, res->dt); } -- 2.30.2