1cb93a386Sopenharmony_ci
2cb93a386Sopenharmony_ci/*
3cb93a386Sopenharmony_ci * Copyright 2016 Google Inc.
4cb93a386Sopenharmony_ci *
5cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
6cb93a386Sopenharmony_ci * found in the LICENSE file.
7cb93a386Sopenharmony_ci */
8cb93a386Sopenharmony_ci
9cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkVulkan.h"
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "tools/sk_app/win/WindowContextFactory_win.h"
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_ci#include "tools/sk_app/VulkanWindowContext.h"
14cb93a386Sopenharmony_ci#include "tools/sk_app/win/Window_win.h"
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkInterface.h"
17cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h"
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci#include "tools/gpu/vk/VkTestUtils.h"
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ci#include <Windows.h>
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_cinamespace sk_app {
24cb93a386Sopenharmony_cinamespace window_context_factory {
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_cistd::unique_ptr<WindowContext> MakeVulkanForWin(HWND hwnd, const DisplayParams& params) {
27cb93a386Sopenharmony_ci    PFN_vkGetInstanceProcAddr instProc;
28cb93a386Sopenharmony_ci    PFN_vkGetDeviceProcAddr devProc;
29cb93a386Sopenharmony_ci    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
30cb93a386Sopenharmony_ci        return nullptr;
31cb93a386Sopenharmony_ci    }
32cb93a386Sopenharmony_ci
33cb93a386Sopenharmony_ci    auto createVkSurface = [hwnd, instProc] (VkInstance instance) -> VkSurfaceKHR {
34cb93a386Sopenharmony_ci        static PFN_vkCreateWin32SurfaceKHR createWin32SurfaceKHR = nullptr;
35cb93a386Sopenharmony_ci        if (!createWin32SurfaceKHR) {
36cb93a386Sopenharmony_ci            createWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
37cb93a386Sopenharmony_ci                instProc(instance, "vkCreateWin32SurfaceKHR");
38cb93a386Sopenharmony_ci        }
39cb93a386Sopenharmony_ci        HINSTANCE hinstance = GetModuleHandle(0);
40cb93a386Sopenharmony_ci        VkSurfaceKHR surface;
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_ci        VkWin32SurfaceCreateInfoKHR surfaceCreateInfo;
43cb93a386Sopenharmony_ci        memset(&surfaceCreateInfo, 0, sizeof(VkWin32SurfaceCreateInfoKHR));
44cb93a386Sopenharmony_ci        surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
45cb93a386Sopenharmony_ci        surfaceCreateInfo.pNext = nullptr;
46cb93a386Sopenharmony_ci        surfaceCreateInfo.flags = 0;
47cb93a386Sopenharmony_ci        surfaceCreateInfo.hinstance = hinstance;
48cb93a386Sopenharmony_ci        surfaceCreateInfo.hwnd = hwnd;
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci        VkResult res = createWin32SurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
51cb93a386Sopenharmony_ci        if (VK_SUCCESS != res) {
52cb93a386Sopenharmony_ci            return VK_NULL_HANDLE;
53cb93a386Sopenharmony_ci        }
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_ci        return surface;
56cb93a386Sopenharmony_ci    };
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ci    auto canPresent = [instProc] (VkInstance instance, VkPhysicalDevice physDev,
59cb93a386Sopenharmony_ci                                  uint32_t queueFamilyIndex) {
60cb93a386Sopenharmony_ci        static PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
61cb93a386Sopenharmony_ci                                            getPhysicalDeviceWin32PresentationSupportKHR = nullptr;
62cb93a386Sopenharmony_ci        if (!getPhysicalDeviceWin32PresentationSupportKHR) {
63cb93a386Sopenharmony_ci            getPhysicalDeviceWin32PresentationSupportKHR =
64cb93a386Sopenharmony_ci                (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
65cb93a386Sopenharmony_ci                    instProc(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
66cb93a386Sopenharmony_ci        }
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci        VkBool32 check = getPhysicalDeviceWin32PresentationSupportKHR(physDev, queueFamilyIndex);
69cb93a386Sopenharmony_ci        return (VK_FALSE != check);
70cb93a386Sopenharmony_ci    };
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci    std::unique_ptr<WindowContext> ctx(
73cb93a386Sopenharmony_ci            new VulkanWindowContext(params, createVkSurface, canPresent, instProc, devProc));
74cb93a386Sopenharmony_ci    if (!ctx->isValid()) {
75cb93a386Sopenharmony_ci        return nullptr;
76cb93a386Sopenharmony_ci    }
77cb93a386Sopenharmony_ci    return ctx;
78cb93a386Sopenharmony_ci}
79cb93a386Sopenharmony_ci
80cb93a386Sopenharmony_ci}  // namespace window_context_factory
81cb93a386Sopenharmony_ci}  // namespace sk_app
82