summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorYiwei Zhang <zzyiwei@chromium.org>2022-11-10 15:08:50 -0800
committerMarge Bot <emma+marge@anholt.net>2023-01-09 23:11:14 +0000
commit4b959eab3f1a3cb29a200431778711cc531c2630 (patch)
treec06ac989593f59dfe00321180524e130e93f9049 /server
parentaa00f95e2bd47e2aacfb45922fd6b56e061f8de6 (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.c276
-rw-r--r--server/render_protocol.h4
-rw-r--r--server/render_state.c173
-rw-r--r--server/render_state.h53
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 */