diff options
Diffstat (limited to 'video/filter/vf_gpu_vulkan.c')
-rw-r--r-- | video/filter/vf_gpu_vulkan.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/video/filter/vf_gpu_vulkan.c b/video/filter/vf_gpu_vulkan.c new file mode 100644 index 0000000000..d477fd153a --- /dev/null +++ b/video/filter/vf_gpu_vulkan.c @@ -0,0 +1,115 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "options/m_config.h" +#include "video/filter/vf_gpu.h" +#include "video/out/placebo/ra_pl.h" +#include "video/out/placebo/utils.h" +#include "video/out/vulkan/context.h" +#include "video/out/vulkan/utils.h" + +struct vk_offscreen_ctx { + struct ra_ctx *ractx; + struct mpvk_ctx *vk; +}; + +extern const struct m_sub_options vulkan_conf; + +static void vk_ctx_destroy(void *p) +{ + struct offscreen_ctx *ctx = p; + struct vk_offscreen_ctx *vkctx = ctx->priv; + struct ra_ctx *ractx = vkctx->ractx; + struct mpvk_ctx *vk = vkctx->vk; + + if (ractx->ra) { + pl_gpu_finish(vk->gpu); + ractx->ra->fns->destroy(ctx->ra); + ractx->ra = NULL; + ctx->ra = NULL; + } + + vk->gpu = NULL; + pl_vulkan_destroy(&vk->vulkan); + mpvk_uninit(vk); + talloc_free(vk); + talloc_free(ractx); +} + +static struct offscreen_ctx *vk_offscreen_ctx_create(struct mpv_global *global, + struct mp_log *log) +{ + struct offscreen_ctx *ctx = talloc(NULL, struct offscreen_ctx); + talloc_set_destructor(ctx, vk_ctx_destroy); + *ctx = (struct offscreen_ctx){ + .log = log, + }; + + struct ra_ctx *ractx = talloc_zero(ctx, struct ra_ctx); + struct mpvk_ctx *vk = talloc_zero(ctx, struct mpvk_ctx); + ractx->log = ctx->log; + ractx->global = global; + + vk->pllog = mppl_log_create(ctx, log); + if (!vk->pllog) + goto error; + + struct pl_vk_inst_params pl_vk_params = {0}; + struct ra_ctx_opts *ctx_opts = mp_get_config_group(NULL, global, &ra_ctx_conf); + pl_vk_params.debug = ctx_opts->debug; + talloc_free(ctx_opts); + mppl_log_set_probing(vk->pllog, true); + vk->vkinst = pl_vk_inst_create(vk->pllog, &pl_vk_params); + mppl_log_set_probing(vk->pllog, false); + if (!vk->vkinst) + goto error; + + struct vulkan_opts *vk_opts = mp_get_config_group(NULL, global, &vulkan_conf); + vk->vulkan = mppl_create_vulkan(vk_opts, vk->vkinst, vk->pllog, VK_NULL_HANDLE); + talloc_free(vk_opts); + if (!vk->vulkan) + goto error; + + vk->gpu = vk->vulkan->gpu; + ractx->ra = ra_create_pl(vk->gpu, ractx->log); + if (!ractx->ra) + goto error; + + struct vk_offscreen_ctx *vkctx = talloc(ctx, struct vk_offscreen_ctx); + *vkctx = (struct vk_offscreen_ctx){ + .ractx = ractx, + .vk = vk + }; + + ctx->ra = ractx->ra; + ctx->priv = vkctx; + + return ctx; + +error: + pl_vulkan_destroy(&vk->vulkan); + mpvk_uninit(vk); + talloc_free(vk); + talloc_free(ractx); + talloc_free(ctx); + return NULL; +} + +const struct offscreen_context offscreen_vk = { + .api = "vulkan", + .offscreen_ctx_create = vk_offscreen_ctx_create +}; |