blob: c6f7e11c58fa7eb005169c6b11f30484ec9079e8 [file] [log] [blame]
/*
* Copyright 2020 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef VKR_CONTEXT_H
#define VKR_CONTEXT_H
#include "vkr_common.h"
#include "venus-protocol/vn_protocol_renderer_defines.h"
#include "virgl_context.h"
#include "vrend_iov.h"
#include "vkr_cs.h"
struct virgl_resource;
/*
* When a virgl_resource is attached in vkr_context_attach_resource, a
* vkr_resource_attachment is created. A vkr_resource_attachment is valid
* until the resource it tracks is detached.
*/
struct vkr_resource_attachment {
struct virgl_resource *resource;
/* if VIRGL_RESOURCE_FD_SHM, this is the mapping of the shm and iov below
* points to this
*/
struct iovec shm_iov;
const struct iovec *iov;
int iov_count;
};
enum vkr_context_validate_level {
/* no validation */
VKR_CONTEXT_VALIDATE_NONE,
/* force enabling a subset of the validation layer */
VKR_CONTEXT_VALIDATE_ON,
/* force enabling the validation layer */
VKR_CONTEXT_VALIDATE_FULL,
};
struct vkr_cpu_sync {
uint32_t flags;
uint32_t ring_idx;
uint64_t fence_id;
struct list_head head;
};
struct vkr_context {
struct virgl_context base;
char *debug_name;
enum vkr_context_validate_level validate_level;
bool validate_fatal;
mtx_t mutex;
struct list_head rings;
struct hash_table *object_table;
struct hash_table *resource_table;
struct vkr_cs_encoder encoder;
struct vkr_cs_decoder decoder;
struct vn_dispatch_context dispatch;
int fence_eventfd;
struct list_head busy_queues;
struct list_head signaled_syncs;
struct list_head signaled_cpu_syncs;
struct vkr_queue *sync_queues[64];
struct vkr_instance *instance;
char *instance_name;
};
void
vkr_context_free_resource(struct hash_entry *entry);
static inline void
vkr_context_add_resource(struct vkr_context *ctx, struct vkr_resource_attachment *att)
{
assert(!_mesa_hash_table_search(ctx->resource_table, &att->resource->res_id));
_mesa_hash_table_insert(ctx->resource_table, &att->resource->res_id, att);
}
static inline void
vkr_context_remove_resource(struct vkr_context *ctx, uint32_t res_id)
{
struct hash_entry *entry = _mesa_hash_table_search(ctx->resource_table, &res_id);
if (likely(entry)) {
vkr_context_free_resource(entry);
_mesa_hash_table_remove(ctx->resource_table, entry);
}
}
static inline struct vkr_resource_attachment *
vkr_context_get_resource(struct vkr_context *ctx, uint32_t res_id)
{
const struct hash_entry *entry = _mesa_hash_table_search(ctx->resource_table, &res_id);
return likely(entry) ? entry->data : NULL;
}
static inline bool
vkr_context_validate_object_id(struct vkr_context *ctx, vkr_object_id id)
{
if (unlikely(!id || _mesa_hash_table_search(ctx->object_table, &id))) {
vkr_log("invalid object id %" PRIu64, id);
vkr_cs_decoder_set_fatal(&ctx->decoder);
return false;
}
return true;
}
static inline void *
vkr_context_alloc_object(UNUSED struct vkr_context *ctx,
size_t size,
VkObjectType type,
const void *id_handle)
{
const vkr_object_id id = vkr_cs_handle_load_id((const void **)id_handle, type);
if (!vkr_context_validate_object_id(ctx, id))
return NULL;
return vkr_object_alloc(size, type, id);
}
void
vkr_context_free_object(struct hash_entry *entry);
static inline void
vkr_context_add_object(struct vkr_context *ctx, struct vkr_object *obj)
{
assert(vkr_is_recognized_object_type(obj->type));
assert(obj->id);
assert(!_mesa_hash_table_search(ctx->object_table, &obj->id));
_mesa_hash_table_insert(ctx->object_table, &obj->id, obj);
}
static inline void
vkr_context_remove_object(struct vkr_context *ctx, struct vkr_object *obj)
{
assert(_mesa_hash_table_search(ctx->object_table, &obj->id));
struct hash_entry *entry = _mesa_hash_table_search(ctx->object_table, &obj->id);
if (likely(entry)) {
vkr_context_free_object(entry);
_mesa_hash_table_remove(ctx->object_table, entry);
}
}
static inline void
vkr_context_remove_objects(struct vkr_context *ctx, struct list_head *objects)
{
struct vkr_object *obj, *tmp;
LIST_FOR_EACH_ENTRY_SAFE (obj, tmp, objects, track_head)
vkr_context_remove_object(ctx, obj);
/* objects should be reinitialized if to be reused */
}
static inline void *
vkr_context_get_object(struct vkr_context *ctx, vkr_object_id obj_id)
{
const struct hash_entry *entry = _mesa_hash_table_search(ctx->object_table, &obj_id);
return likely(entry) ? entry->data : NULL;
}
static inline const char *
vkr_context_get_name(const struct vkr_context *ctx)
{
/* ctx->instance_name is the application name while ctx->debug_name is
* usually the guest process name or the hypervisor name. This never
* returns NULL because ctx->debug_name is never NULL.
*/
return ctx->instance_name ? ctx->instance_name : ctx->debug_name;
}
void
vkr_context_add_instance(struct vkr_context *ctx,
struct vkr_instance *instance,
const char *name);
void
vkr_context_remove_instance(struct vkr_context *ctx, struct vkr_instance *instance);
#endif /* VKR_CONTEXT_H */