1 /*
2  * This file is part of mpv.
3  *
4  * mpv is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * mpv is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "video/out/gpu/context.h"
19 #include "video/out/w32_common.h"
20 
21 #include "common.h"
22 #include "context.h"
23 #include "utils.h"
24 
25 EXTERN_C IMAGE_DOS_HEADER __ImageBase;
26 #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
27 
28 struct priv {
29     struct mpvk_ctx vk;
30 };
31 
win_uninit(struct ra_ctx * ctx)32 static void win_uninit(struct ra_ctx *ctx)
33 {
34     struct priv *p = ctx->priv;
35 
36     ra_vk_ctx_uninit(ctx);
37     mpvk_uninit(&p->vk);
38     vo_w32_uninit(ctx->vo);
39 }
40 
win_init(struct ra_ctx * ctx)41 static bool win_init(struct ra_ctx *ctx)
42 {
43     struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
44     struct mpvk_ctx *vk = &p->vk;
45     int msgl = ctx->opts.probing ? MSGL_V : MSGL_ERR;
46 
47     if (!mpvk_init(vk, ctx, VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
48         goto error;
49 
50     if (!vo_w32_init(ctx->vo))
51         goto error;
52 
53     VkWin32SurfaceCreateInfoKHR wininfo = {
54          .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
55          .hinstance = HINST_THISCOMPONENT,
56          .hwnd = vo_w32_hwnd(ctx->vo),
57     };
58 
59     struct ra_vk_ctx_params params = {0};
60 
61     VkInstance inst = vk->vkinst->instance;
62     VkResult res = vkCreateWin32SurfaceKHR(inst, &wininfo, NULL, &vk->surface);
63     if (res != VK_SUCCESS) {
64         MP_MSG(ctx, msgl, "Failed creating Windows surface\n");
65         goto error;
66     }
67 
68     if (!ra_vk_ctx_init(ctx, vk, params, VK_PRESENT_MODE_FIFO_KHR))
69         goto error;
70 
71     return true;
72 
73 error:
74     win_uninit(ctx);
75     return false;
76 }
77 
resize(struct ra_ctx * ctx)78 static bool resize(struct ra_ctx *ctx)
79 {
80     return ra_vk_ctx_resize(ctx, ctx->vo->dwidth, ctx->vo->dheight);
81 }
82 
win_reconfig(struct ra_ctx * ctx)83 static bool win_reconfig(struct ra_ctx *ctx)
84 {
85     vo_w32_config(ctx->vo);
86     return resize(ctx);
87 }
88 
win_control(struct ra_ctx * ctx,int * events,int request,void * arg)89 static int win_control(struct ra_ctx *ctx, int *events, int request, void *arg)
90 {
91     int ret = vo_w32_control(ctx->vo, events, request, arg);
92     if (*events & VO_EVENT_RESIZE) {
93         if (!resize(ctx))
94             return VO_ERROR;
95     }
96     return ret;
97 }
98 
99 const struct ra_ctx_fns ra_ctx_vulkan_win = {
100     .type           = "vulkan",
101     .name           = "winvk",
102     .reconfig       = win_reconfig,
103     .control        = win_control,
104     .init           = win_init,
105     .uninit         = win_uninit,
106 };
107