diff --git a/src/Makefile.am b/src/Makefile.am index b15d708..f716498 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,8 @@ libvrend_la_SOURCES = \ virgl_context.h \ virgl_hw.h \ virgl_protocol.h \ + virgl_resource.c \ + virgl_resource.h \ virgl_util.c \ virgl_util.h \ vrend_iov.h \ diff --git a/src/meson.build b/src/meson.build index 742954a..5afcd86 100644 --- a/src/meson.build +++ b/src/meson.build @@ -29,6 +29,8 @@ virgl_sources = [ 'virgl_context.h', 'virgl_hw.h', 'virgl_protocol.h', + 'virgl_resource.c', + 'virgl_resource.h', 'virgl_util.c', 'virgl_util.h', 'vrend_blitter.c', diff --git a/src/virgl_context.h b/src/virgl_context.h index 879618d..f09dc67 100644 --- a/src/virgl_context.h +++ b/src/virgl_context.h @@ -28,6 +28,10 @@ #include #include +/** + * Base class for renderer contexts. For example, vrend_decode_ctx is a + * subclass of virgl_context. + */ struct virgl_context { uint32_t ctx_id; diff --git a/src/virgl_resource.c b/src/virgl_resource.c new file mode 100644 index 0000000..73c1e27 --- /dev/null +++ b/src/virgl_resource.c @@ -0,0 +1,110 @@ +/************************************************************************** + * + * Copyright (C) 2020 Chromium + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "virgl_resource.h" + +#include +#include + +#include "util/u_hash_table.h" +#include "util/u_pointer.h" +#include "virgl_util.h" + +static struct util_hash_table *virgl_resource_table; +static struct virgl_resource_pipe_callbacks pipe_callbacks; + +static void +virgl_resource_destroy_func(void *val) +{ + struct virgl_resource *res = (struct virgl_resource *)val; + + if (res->pipe_resource) + pipe_callbacks.unref(res->pipe_resource, pipe_callbacks.data); + + free(res); +} + +int +virgl_resource_table_init(const struct virgl_resource_pipe_callbacks *callbacks) +{ + virgl_resource_table = util_hash_table_create(hash_func_u32, + compare_func, + virgl_resource_destroy_func); + if (!virgl_resource_table) + return ENOMEM; + + pipe_callbacks = *callbacks; + + return 0; +} + +void +virgl_resource_table_cleanup(void) +{ + util_hash_table_destroy(virgl_resource_table); + memset(&pipe_callbacks, 0, sizeof(pipe_callbacks)); +} + +void +virgl_resource_table_reset(void) +{ + util_hash_table_clear(virgl_resource_table); +} + +int +virgl_resource_create_from_pipe(uint32_t res_id, struct pipe_resource *pres) +{ + struct virgl_resource *res; + enum pipe_error err; + + res = calloc(1, sizeof(*res)); + if (!res) + return ENOMEM; + + err = util_hash_table_set(virgl_resource_table, + uintptr_to_pointer(res_id), + res); + if (err != PIPE_OK) { + free(res); + return ENOMEM; + } + + res->res_id = res_id; + /* take ownership */ + res->pipe_resource = pres; + + return 0; +} + +void +virgl_resource_remove(uint32_t res_id) +{ + util_hash_table_remove(virgl_resource_table, uintptr_to_pointer(res_id)); +} + +struct virgl_resource *virgl_resource_lookup(uint32_t res_id) +{ + return util_hash_table_get(virgl_resource_table, + uintptr_to_pointer(res_id)); +} diff --git a/src/virgl_resource.h b/src/virgl_resource.h new file mode 100644 index 0000000..46046c4 --- /dev/null +++ b/src/virgl_resource.h @@ -0,0 +1,70 @@ +/************************************************************************** + * + * Copyright (C) 2020 Chromium + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef VIRGL_RESOURCE_H +#define VIRGL_RESOURCE_H + +#include + +struct pipe_resource; + +/** + * A global cross-context resource. A virgl_resource is not directly usable + * by renderer contexts, but must be attached and imported into renderer + * contexts to create context objects first. For example, it can be attached + * and imported into a vrend_decode_ctx to create a vrend_resource. + * + * It is also possible to create a virgl_resource from a context object. + */ +struct virgl_resource { + uint32_t res_id; + + struct pipe_resource *pipe_resource; +}; + +struct virgl_resource_pipe_callbacks { + void *data; + + void (*unref)(struct pipe_resource *pres, void *data); +}; + +int +virgl_resource_table_init(const struct virgl_resource_pipe_callbacks *callbacks); + +void +virgl_resource_table_cleanup(void); + +void +virgl_resource_table_reset(void); + +int +virgl_resource_create_from_pipe(uint32_t res_id, struct pipe_resource *pres); + +void +virgl_resource_remove(uint32_t res_id); + +struct virgl_resource * +virgl_resource_lookup(uint32_t res_id); + +#endif /* VIRGL_RESOURCE_H */