diff options
author | Yiwei Zhang <zzyiwei@chromium.org> | 2022-11-10 15:08:50 -0800 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-01-09 23:11:14 +0000 |
commit | 4b959eab3f1a3cb29a200431778711cc531c2630 (patch) | |
tree | c06ac989593f59dfe00321180524e130e93f9049 /server | |
parent | aa00f95e2bd47e2aacfb45922fd6b56e061f8de6 (diff) |
server: relocate renderer interface into render_state
Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/993>
Diffstat (limited to 'server')
-rw-r--r-- | server/render_context.c | 276 | ||||
-rw-r--r-- | server/render_protocol.h | 4 | ||||
-rw-r--r-- | server/render_state.c | 173 | ||||
-rw-r--r-- | server/render_state.h | 53 |
4 files changed, 295 insertions, 211 deletions
diff --git a/server/render_context.c b/server/render_context.c index 327d829..cdb1639 100644 --- a/server/render_context.c +++ b/server/render_context.c @@ -9,59 +9,9 @@ #include "util/u_thread.h" #include "virgl_util.h" -#include "virglrenderer.h" -#include "vrend_iov.h" #include "render_state.h" -static bool -render_context_import_resource(struct render_context *ctx, - const struct render_context_op_import_resource_request *req, - int res_fd) -{ - const uint32_t res_id = req->res_id; - const enum virgl_resource_fd_type fd_type = req->fd_type; - const uint64_t size = req->size; - - if (fd_type == VIRGL_RESOURCE_FD_INVALID || !size) { - render_log("failed to attach invalid resource %d", res_id); - return false; - } - - uint32_t import_fd_type; - switch (fd_type) { - case VIRGL_RESOURCE_FD_DMABUF: - import_fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF; - break; - case VIRGL_RESOURCE_FD_OPAQUE: - import_fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE; - break; - case VIRGL_RESOURCE_FD_SHM: - import_fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_SHM; - break; - default: - import_fd_type = 0; - break; - } - const struct virgl_renderer_resource_import_blob_args import_args = { - .res_handle = res_id, - .blob_mem = VIRGL_RENDERER_BLOB_MEM_HOST3D, - .fd_type = import_fd_type, - .fd = res_fd, - .size = size, - }; - - int ret = virgl_renderer_resource_import_blob(&import_args); - if (ret) { - render_log("failed to import blob resource %d (%d)", res_id, ret); - return false; - } - - virgl_renderer_ctx_attach_resource(ctx->ctx_id, res_id); - - return true; -} - void render_context_update_timeline(struct render_context *ctx, uint32_t ring_idx, @@ -74,149 +24,50 @@ render_context_update_timeline(struct render_context *ctx, } static bool -render_context_init_virgl_context(struct render_context *ctx, - const struct render_context_op_init_request *req, - int shmem_fd, - int fence_eventfd) -{ - const int timeline_count = req->shmem_size / sizeof(*ctx->shmem_timelines); - - void *shmem_ptr = mmap(NULL, req->shmem_size, PROT_WRITE, MAP_SHARED, shmem_fd, 0); - if (shmem_ptr == MAP_FAILED) - return false; - - int ret = virgl_renderer_context_create_with_flags(ctx->ctx_id, req->flags, - ctx->name_len, ctx->name); - if (ret) { - munmap(shmem_ptr, req->shmem_size); - return false; - } - - ctx->shmem_fd = shmem_fd; - ctx->shmem_size = req->shmem_size; - ctx->shmem_ptr = shmem_ptr; - ctx->shmem_timelines = shmem_ptr; - - for (int i = 0; i < timeline_count; i++) - atomic_store(&ctx->shmem_timelines[i], 0); - - ctx->timeline_count = timeline_count; - - ctx->fence_eventfd = fence_eventfd; - - return true; -} - -static bool -render_context_create_resource(struct render_context *ctx, - const struct render_context_op_create_resource_request *req, - enum virgl_resource_fd_type *out_fd_type, - uint32_t *out_map_info, - int *out_res_fd) -{ - const uint32_t res_id = req->res_id; - const struct virgl_renderer_resource_create_blob_args blob_args = { - .res_handle = res_id, - .ctx_id = ctx->ctx_id, - .blob_mem = VIRGL_RENDERER_BLOB_MEM_HOST3D, - .blob_flags = req->blob_flags, - .blob_id = req->blob_id, - .size = req->blob_size, - }; - int ret = virgl_renderer_resource_create_blob(&blob_args); - if (ret) { - render_log("failed to create blob resource"); - return false; - } - - uint32_t map_info; - ret = virgl_renderer_resource_get_map_info(res_id, &map_info); - if (ret) { - /* properly set map_info when the resource has no map cache info */ - map_info = VIRGL_RENDERER_MAP_CACHE_NONE; - } - - uint32_t fd_type; - int res_fd; - ret = virgl_renderer_resource_export_blob(res_id, &fd_type, &res_fd); - if (ret) { - virgl_renderer_resource_unref(res_id); - return false; - } - - /* RENDER_CONTEXT_OP_CREATE_RESOURCE implies attach and proxy will not send - * RENDER_CONTEXT_OP_IMPORT_RESOURCE to attach the resource again. - */ - virgl_renderer_ctx_attach_resource(ctx->ctx_id, res_id); - - switch (fd_type) { - case VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF: - *out_fd_type = VIRGL_RESOURCE_FD_DMABUF; - break; - case VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE: - *out_fd_type = VIRGL_RESOURCE_FD_OPAQUE; - break; - case VIRGL_RENDERER_BLOB_FD_TYPE_SHM: - *out_fd_type = VIRGL_RESOURCE_FD_SHM; - break; - default: - *out_fd_type = 0; - } - - *out_map_info = map_info; - *out_res_fd = res_fd; - - return true; -} - -static bool render_context_dispatch_submit_fence(struct render_context *ctx, - const union render_context_op_request *req, + const union render_context_op_request *request, UNUSED const int *fds, UNUSED int fd_count) { - /* always merge fences */ - assert(!(req->submit_fence.flags & ~VIRGL_RENDERER_FENCE_FLAG_MERGEABLE)); - const uint32_t flags = VIRGL_RENDERER_FENCE_FLAG_MERGEABLE; - const uint32_t ring_idx = req->submit_fence.ring_index; - const uint32_t seqno = req->submit_fence.seqno; + const struct render_context_op_submit_fence_request *req = &request->submit_fence; - assert(ring_idx < (uint32_t)ctx->timeline_count); - int ret = virgl_renderer_context_create_fence(ctx->ctx_id, flags, ring_idx, seqno); - - return !ret; + /* always merge fences */ + assert(!(req->flags & ~VIRGL_RENDERER_FENCE_FLAG_MERGEABLE)); + assert(req->ring_index < (uint32_t)ctx->timeline_count); + return render_state_submit_fence(ctx->ctx_id, VIRGL_RENDERER_FENCE_FLAG_MERGEABLE, + req->ring_index, req->seqno); } static bool render_context_dispatch_submit_cmd(struct render_context *ctx, - const union render_context_op_request *req, + const union render_context_op_request *request, UNUSED const int *fds, UNUSED int fd_count) { - const int ndw = req->submit_cmd.size / sizeof(uint32_t); - void *cmd = (void *)req->submit_cmd.cmd; - if (req->submit_cmd.size > sizeof(req->submit_cmd.cmd)) { - cmd = malloc(req->submit_cmd.size); + const struct render_context_op_submit_cmd_request *req = &request->submit_cmd; + void *cmd = (void *)req->cmd; + if (req->size > sizeof(req->cmd)) { + cmd = malloc(req->size); if (!cmd) return true; - const size_t inlined = sizeof(req->submit_cmd.cmd); - const size_t remain = req->submit_cmd.size - inlined; + const size_t inlined = sizeof(req->cmd); + const size_t remain = req->size - inlined; - memcpy(cmd, req->submit_cmd.cmd, inlined); + memcpy(cmd, req->cmd, inlined); if (!render_socket_receive_data(&ctx->socket, (char *)cmd + inlined, remain)) { free(cmd); return false; } } - int ret = virgl_renderer_submit_cmd(cmd, ctx->ctx_id, ndw); + bool ok = render_state_submit_cmd(ctx->ctx_id, cmd, req->size); - if (cmd != req->submit_cmd.cmd) + if (cmd != req->cmd) free(cmd); const struct render_context_op_submit_cmd_reply reply = { - .ok = !ret, + .ok = ok, }; if (!render_socket_send_reply(&ctx->socket, &reply, sizeof(reply))) return false; @@ -225,40 +76,18 @@ render_context_dispatch_submit_cmd(struct render_context *ctx, } static bool -render_context_dispatch_create_resource(struct render_context *ctx, - const union render_context_op_request *req, - UNUSED const int *fds, - UNUSED int fd_count) -{ - struct render_context_op_create_resource_reply reply = { - .fd_type = VIRGL_RESOURCE_FD_INVALID, - }; - int res_fd; - bool ok = render_context_create_resource(ctx, &req->create_resource, &reply.fd_type, - &reply.map_info, &res_fd); - if (!ok) - return render_socket_send_reply(&ctx->socket, &reply, sizeof(reply)); - - ok = - render_socket_send_reply_with_fds(&ctx->socket, &reply, sizeof(reply), &res_fd, 1); - close(res_fd); - - return ok; -} - -static bool -render_context_dispatch_destroy_resource(UNUSED struct render_context *ctx, +render_context_dispatch_destroy_resource(struct render_context *ctx, const union render_context_op_request *req, UNUSED const int *fds, UNUSED int fd_count) { - virgl_renderer_resource_unref(req->destroy_resource.res_id); + render_state_destroy_resource(ctx->ctx_id, req->destroy_resource.res_id); return true; } static bool render_context_dispatch_import_resource(struct render_context *ctx, - const union render_context_op_request *req, + const union render_context_op_request *request, const int *fds, int fd_count) { @@ -268,21 +97,73 @@ render_context_dispatch_import_resource(struct render_context *ctx, } /* classic 3d resource with valid size reuses the blob import path here */ - return render_context_import_resource(ctx, &req->import_resource, fds[0]); + const struct render_context_op_import_resource_request *req = + &request->import_resource; + return render_state_import_resource(ctx->ctx_id, req->res_id, req->fd_type, fds[0], + req->size); +} + +static bool +render_context_dispatch_create_resource(struct render_context *ctx, + const union render_context_op_request *request, + UNUSED const int *fds, + UNUSED int fd_count) +{ + const struct render_context_op_create_resource_request *req = + &request->create_resource; + struct render_context_op_create_resource_reply reply = { + .fd_type = VIRGL_RESOURCE_FD_INVALID, + }; + int res_fd; + bool ok = render_state_create_resource(ctx->ctx_id, req->res_id, req->blob_flags, + req->blob_id, req->blob_size, &reply.fd_type, + &res_fd, &reply.map_info); + if (!ok) + return render_socket_send_reply(&ctx->socket, &reply, sizeof(reply)); + + ok = + render_socket_send_reply_with_fds(&ctx->socket, &reply, sizeof(reply), &res_fd, 1); + close(res_fd); + + return ok; } static bool render_context_dispatch_init(struct render_context *ctx, - const union render_context_op_request *req, + const union render_context_op_request *request, const int *fds, int fd_count) { if (fd_count != 1 && fd_count != 2) return false; + const struct render_context_op_init_request *req = &request->init; + const int timeline_count = req->shmem_size / sizeof(*ctx->shmem_timelines); const int shmem_fd = fds[0]; const int fence_eventfd = fd_count == 2 ? fds[1] : -1; - return render_context_init_virgl_context(ctx, &req->init, shmem_fd, fence_eventfd); + + void *shmem_ptr = mmap(NULL, req->shmem_size, PROT_WRITE, MAP_SHARED, shmem_fd, 0); + if (shmem_ptr == MAP_FAILED) + return false; + + if (!render_state_create_context(ctx->ctx_id, req->flags, ctx->name_len, ctx->name)) { + munmap(shmem_ptr, req->shmem_size); + return false; + } + + ctx->shmem_fd = shmem_fd; + ctx->shmem_size = req->shmem_size; + ctx->shmem_ptr = shmem_ptr; + ctx->shmem_timelines = shmem_ptr; + + for (int i = 0; i < timeline_count; i++) + atomic_store(&ctx->shmem_timelines[i], 0); + + ctx->timeline_count = timeline_count; + + ctx->fence_eventfd = fence_eventfd; + + return true; } static bool @@ -377,11 +258,8 @@ render_context_run(struct render_context *ctx) static void render_context_fini(struct render_context *ctx) { - render_state_lock_dispatch(); /* destroy the context first to join its sync threads and ring threads */ - virgl_renderer_context_destroy(ctx->ctx_id); - render_state_unlock_dispatch(); - + render_state_destroy_context(ctx->ctx_id); render_state_remove_context(ctx); if (ctx->shmem_ptr) diff --git a/server/render_protocol.h b/server/render_protocol.h index 778adcf..573f33a 100644 --- a/server/render_protocol.h +++ b/server/render_protocol.h @@ -9,8 +9,6 @@ #include <stdint.h> #include "virgl_resource.h" -#include "virglrenderer.h" -#include "virglrenderer_hw.h" /* this covers the command line options and the socket type */ #define RENDER_SERVER_VERSION 0 @@ -186,7 +184,7 @@ struct render_context_op_destroy_resource_request { */ struct render_context_op_submit_cmd_request { struct render_context_op_header header; - size_t size; + uint32_t size; char cmd[256]; /* if size > sizeof(cmd), followed by (size - sizeof(cmd)) bytes in another * message; size still must be small diff --git a/server/render_state.c b/server/render_state.c index f6ae07b..2ecf8cb 100644 --- a/server/render_state.c +++ b/server/render_state.c @@ -5,6 +5,8 @@ #include "render_state.h" +#include <inttypes.h> + #include "virglrenderer.h" #include "render_context.h" @@ -160,3 +162,174 @@ fail: render_state_unlock_struct(); return false; } + +bool +render_state_create_context(uint32_t ctx_id, + uint32_t flags, + uint32_t name_len, + const char *name) +{ + int ret = virgl_renderer_context_create_with_flags(ctx_id, flags, name_len, name); + if (ret) { + render_log("failed to create context %u with flags %u (%d)", ctx_id, flags, ret); + return false; + } + + return true; +} + +void +render_state_destroy_context(uint32_t ctx_id) +{ + render_state_lock_dispatch(); + /* destroy the context first to join its sync threads and ring threads */ + virgl_renderer_context_destroy(ctx_id); + render_state_unlock_dispatch(); +} + +bool +render_state_submit_cmd(uint32_t ctx_id, void *cmd, uint32_t size) +{ + int ret = virgl_renderer_submit_cmd(cmd, ctx_id, size / sizeof(uint32_t)); + if (ret) { + render_log("failed to submit cmd: ctx_id %u size %u ret(%d)", ctx_id, size, ret); + return false; + } + + return true; +} + +bool +render_state_submit_fence(uint32_t ctx_id, + uint32_t flags, + uint64_t queue_id, + uint64_t fence_id) +{ + + int ret = virgl_renderer_context_create_fence(ctx_id, flags, queue_id, fence_id); + if (ret) { + render_log( + "failed to create context fence: ctx_id %u with flags %u queue_id %" PRIu64 + " fence_id %" PRIu64 " ret(%d)", + ctx_id, flags, queue_id, fence_id, ret); + return false; + } + + return true; +} + +bool +render_state_create_resource(uint32_t ctx_id, + uint32_t res_id, + uint32_t blob_flags, + uint64_t blob_id, + uint64_t blob_size, + enum virgl_resource_fd_type *out_fd_type, + int *out_res_fd, + uint32_t *out_map_info) +{ + const struct virgl_renderer_resource_create_blob_args blob_args = { + .res_handle = res_id, + .ctx_id = ctx_id, + .blob_mem = VIRGL_RENDERER_BLOB_MEM_HOST3D, + .blob_flags = blob_flags, + .blob_id = blob_id, + .size = blob_size, + }; + int ret = virgl_renderer_resource_create_blob(&blob_args); + if (ret) { + render_log("failed to create blob resource"); + return false; + } + + uint32_t map_info; + ret = virgl_renderer_resource_get_map_info(res_id, &map_info); + if (ret) { + /* properly set map_info when the resource has no map cache info */ + map_info = VIRGL_RENDERER_MAP_CACHE_NONE; + } + + uint32_t fd_type; + int res_fd; + ret = virgl_renderer_resource_export_blob(res_id, &fd_type, &res_fd); + if (ret) { + virgl_renderer_resource_unref(res_id); + return false; + } + + /* RENDER_CONTEXT_OP_CREATE_RESOURCE implies attach and proxy will not send + * RENDER_CONTEXT_OP_IMPORT_RESOURCE to attach the resource again. + */ + virgl_renderer_ctx_attach_resource(ctx_id, res_id); + + switch (fd_type) { + case VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF: + *out_fd_type = VIRGL_RESOURCE_FD_DMABUF; + break; + case VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE: + *out_fd_type = VIRGL_RESOURCE_FD_OPAQUE; + break; + case VIRGL_RENDERER_BLOB_FD_TYPE_SHM: + *out_fd_type = VIRGL_RESOURCE_FD_SHM; + break; + default: + *out_fd_type = 0; + } + + *out_map_info = map_info; + *out_res_fd = res_fd; + + return true; +} + +bool +render_state_import_resource(uint32_t ctx_id, + uint32_t res_id, + enum virgl_resource_fd_type fd_type, + int fd, + uint64_t size) +{ + if (fd_type == VIRGL_RESOURCE_FD_INVALID || !size) { + render_log("failed to attach invalid resource %d", res_id); + return false; + } + + uint32_t blob_fd_type; + switch (fd_type) { + case VIRGL_RESOURCE_FD_DMABUF: + blob_fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF; + break; + case VIRGL_RESOURCE_FD_OPAQUE: + blob_fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE; + break; + case VIRGL_RESOURCE_FD_SHM: + blob_fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_SHM; + break; + default: + render_log("unknown fd_type %d", fd_type); + return false; + } + + const struct virgl_renderer_resource_import_blob_args import_args = { + .res_handle = res_id, + .blob_mem = VIRGL_RENDERER_BLOB_MEM_HOST3D, + .fd_type = blob_fd_type, + .fd = fd, + .size = size, + }; + int ret = virgl_renderer_resource_import_blob(&import_args); + if (ret) { + render_log("failed to import blob resource %u (%d)", res_id, ret); + return false; + } + + virgl_renderer_ctx_attach_resource(ctx_id, res_id); + + return true; +} + +void +render_state_destroy_resource(UNUSED uint32_t ctx_id, uint32_t res_id) +{ + virgl_renderer_resource_unref(res_id); +} diff --git a/server/render_state.h b/server/render_state.h index 5cfd277..c664498 100644 --- a/server/render_state.h +++ b/server/render_state.h @@ -13,27 +13,24 @@ #endif /* Workers call into virglrenderer. When they are processes, not much care is - * required. We just want to be careful that the server process might have - * initialized viglrenderer before workers are forked. - * - * But when workers are threads, we need to grab a lock to protect + * required. But when workers are threads, we need to grab a lock to protect * virglrenderer. * - * TODO skip virglrenderer.h and go straight to vkr_renderer.h. That allows - * us to remove this file. + * TODO skip virglrenderer.h and go straight to vkr_renderer.h. */ struct render_state { #ifdef ENABLE_RENDER_SERVER_WORKER_THREAD - /* this protects the struct */ + /* protect the struct */ mtx_t struct_mutex; - /* this protects virglrenderer */ + /* protect virglrenderer interface */ mtx_t dispatch_mutex; #endif - /* for nested initialization */ + /* track and init/fini just once */ int init_count; uint32_t init_flags; + /* track the render_context */ struct list_head contexts; }; @@ -67,4 +64,42 @@ render_state_unlock_dispatch(void) #endif } +bool +render_state_create_context(uint32_t ctx_id, + uint32_t flags, + uint32_t name_len, + const char *name); + +void +render_state_destroy_context(uint32_t ctx_id); + +bool +render_state_submit_cmd(uint32_t ctx_id, void *cmd, uint32_t size); + +bool +render_state_submit_fence(uint32_t ctx_id, + uint32_t flags, + uint64_t queue_id, + uint64_t fence_id); + +bool +render_state_create_resource(uint32_t ctx_id, + uint32_t res_id, + uint32_t blob_flags, + uint64_t blob_id, + uint64_t blob_size, + enum virgl_resource_fd_type *out_fd_type, + int *out_res_fd, + uint32_t *out_map_info); + +bool +render_state_import_resource(uint32_t ctx_id, + uint32_t res_id, + enum virgl_resource_fd_type fd_type, + int fd, + uint64_t size); + +void +render_state_destroy_resource(uint32_t ctx_id, uint32_t res_id); + #endif /* RENDER_STATE_H */ |