/* * 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 . */ #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, NULL); 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 };