1 /*
2  * Copyright 2020 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "tools/gpu/vk/VkTestHelper.h"
9 
10 #ifdef SK_VULKAN
11 
12 #include "include/core/SkSurface.h"
13 #include "include/gpu/GrDirectContext.h"
14 #include "tools/gpu/vk/VkTestUtils.h"
15 
16 #define ACQUIRE_INST_VK_PROC(name)                                                           \
17     fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, fBackendContext.fInstance,\
18                                                        VK_NULL_HANDLE));                     \
19     if (fVk##name == nullptr) {                                                              \
20         SkDebugf("Function ptr for vk%s could not be acquired\n", #name);                    \
21         return false;                                                                        \
22     }
23 
24 #define ACQUIRE_DEVICE_VK_PROC(name)                                                          \
25     fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, VK_NULL_HANDLE, fDevice)); \
26     if (fVk##name == nullptr) {                                                               \
27         SkDebugf("Function ptr for vk%s could not be acquired\n", #name);                     \
28         return false;                                                                         \
29     }
30 
init()31 bool VkTestHelper::init() {
32     PFN_vkGetInstanceProcAddr instProc;
33     PFN_vkGetDeviceProcAddr devProc;
34     if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
35         return false;
36     }
37     auto getProc = [&instProc, &devProc](const char* proc_name,
38                                          VkInstance instance, VkDevice device) {
39         if (device != VK_NULL_HANDLE) {
40             return devProc(device, proc_name);
41         }
42         return instProc(instance, proc_name);
43     };
44 
45     fFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
46     fFeatures.pNext = nullptr;
47 
48     fBackendContext.fInstance = VK_NULL_HANDLE;
49     fBackendContext.fDevice = VK_NULL_HANDLE;
50 
51     if (!sk_gpu_test::CreateVkBackendContext(getProc, &fBackendContext, &fExtensions,
52                                              &fFeatures, &fDebugCallback, nullptr,
53                                              sk_gpu_test::CanPresentFn(), fIsProtected)) {
54         return false;
55     }
56     fDevice = fBackendContext.fDevice;
57 
58     if (fDebugCallback != VK_NULL_HANDLE) {
59         fDestroyDebugCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
60                 instProc(fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT"));
61     }
62     ACQUIRE_INST_VK_PROC(DestroyInstance)
63     ACQUIRE_INST_VK_PROC(DeviceWaitIdle)
64     ACQUIRE_INST_VK_PROC(DestroyDevice)
65 
66     ACQUIRE_INST_VK_PROC(GetPhysicalDeviceFormatProperties)
67     ACQUIRE_INST_VK_PROC(GetPhysicalDeviceMemoryProperties)
68 
69     ACQUIRE_DEVICE_VK_PROC(CreateImage)
70     ACQUIRE_DEVICE_VK_PROC(DestroyImage)
71     ACQUIRE_DEVICE_VK_PROC(GetImageMemoryRequirements)
72     ACQUIRE_DEVICE_VK_PROC(AllocateMemory)
73     ACQUIRE_DEVICE_VK_PROC(FreeMemory)
74     ACQUIRE_DEVICE_VK_PROC(BindImageMemory)
75     ACQUIRE_DEVICE_VK_PROC(MapMemory)
76     ACQUIRE_DEVICE_VK_PROC(UnmapMemory)
77     ACQUIRE_DEVICE_VK_PROC(FlushMappedMemoryRanges)
78     ACQUIRE_DEVICE_VK_PROC(GetImageSubresourceLayout)
79 
80     fDirectContext = GrDirectContext::MakeVulkan(fBackendContext);
81     if (!fDirectContext) {
82         return false;
83     }
84 
85     return true;
86 }
87 
cleanup()88 void VkTestHelper::cleanup() {
89     // Make sure any work, release procs, etc left on the context are finished with before we start
90     // tearing everything down.
91     if (fDirectContext) {
92         fDirectContext->flushAndSubmit(true);
93     }
94 
95     fDirectContext.reset();
96 
97     fBackendContext.fMemoryAllocator.reset();
98     if (fDevice != VK_NULL_HANDLE) {
99         fVkDeviceWaitIdle(fDevice);
100         fVkDestroyDevice(fDevice, nullptr);
101         fDevice = VK_NULL_HANDLE;
102     }
103     if (fDebugCallback != VK_NULL_HANDLE) {
104         fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr);
105     }
106 
107     if (fBackendContext.fInstance != VK_NULL_HANDLE) {
108         fVkDestroyInstance(fBackendContext.fInstance, nullptr);
109         fBackendContext.fInstance = VK_NULL_HANDLE;
110     }
111 
112     sk_gpu_test::FreeVulkanFeaturesStructs(&fFeatures);
113 }
114 
115 #endif // SK_VULKAN
116