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