xref: /aosp_15_r20/external/skia/tools/graphite/vk/GraphiteVulkanTestContext.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2022 Google LLC
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/graphite/vk/GraphiteVulkanTestContext.h"
9 
10 #include "include/gpu/graphite/Context.h"
11 #include "include/gpu/graphite/ContextOptions.h"
12 #include "include/gpu/graphite/vk/VulkanGraphiteUtils.h"
13 #include "include/gpu/vk/VulkanExtensions.h"
14 #include "include/gpu/vk/VulkanMemoryAllocator.h"
15 #include "src/gpu/graphite/ContextOptionsPriv.h"
16 #include "tools/gpu/ContextType.h"
17 #include "tools/gpu/vk/VkTestUtils.h"
18 #include "tools/graphite/TestOptions.h"
19 
20 extern bool gCreateProtectedContext;
21 
22 namespace skiatest::graphite {
23 
Make()24 std::unique_ptr<GraphiteTestContext> VulkanTestContext::Make() {
25     skgpu::VulkanBackendContext backendContext;
26     skgpu::VulkanExtensions* extensions;
27     VkPhysicalDeviceFeatures2* features;
28     VkDebugReportCallbackEXT debugCallback = VK_NULL_HANDLE;
29     PFN_vkDestroyDebugReportCallbackEXT destroyCallback = nullptr;
30 
31     PFN_vkGetInstanceProcAddr instProc;
32     if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
33         return nullptr;
34     }
35 
36     extensions = new skgpu::VulkanExtensions();
37     features = new VkPhysicalDeviceFeatures2;
38     memset(features, 0, sizeof(VkPhysicalDeviceFeatures2));
39     if (!sk_gpu_test::CreateVkBackendContext(instProc, &backendContext, extensions,
40                                              features, &debugCallback,
41                                              nullptr, sk_gpu_test::CanPresentFn(),
42                                              gCreateProtectedContext)) {
43         sk_gpu_test::FreeVulkanFeaturesStructs(features);
44         delete features;
45         delete extensions;
46         return nullptr;
47     }
48     if (debugCallback != VK_NULL_HANDLE) {
49         destroyCallback = (PFN_vkDestroyDebugReportCallbackEXT) instProc(
50                 backendContext.fInstance, "vkDestroyDebugReportCallbackEXT");
51     }
52 
53     return std::unique_ptr<GraphiteTestContext>(new VulkanTestContext(backendContext,
54                                                                       extensions,
55                                                                       features,
56                                                                       debugCallback,
57                                                                       destroyCallback));
58 }
59 
60 #define ACQUIRE_VK_PROC_LOCAL(name, inst)                                                \
61     PFN_vk##name localVk##name =                                                         \
62             reinterpret_cast<PFN_vk##name>(fVulkan.fGetProc("vk" #name, inst, nullptr)); \
63     do {                                                                                 \
64         if (localVk##name == nullptr) {                                                  \
65             SkDebugf("Function ptr for vk%s could not be acquired\n", #name);            \
66             return;                                                                      \
67         }                                                                                \
68     } while (0)
69 
~VulkanTestContext()70 VulkanTestContext::~VulkanTestContext() {
71     fVulkan.fMemoryAllocator.reset();
72     ACQUIRE_VK_PROC_LOCAL(DeviceWaitIdle, fVulkan.fInstance);
73     ACQUIRE_VK_PROC_LOCAL(DestroyDevice, fVulkan.fInstance);
74     ACQUIRE_VK_PROC_LOCAL(DestroyInstance, fVulkan.fInstance);
75     localVkDeviceWaitIdle(fVulkan.fDevice);
76     localVkDestroyDevice(fVulkan.fDevice, nullptr);
77 #ifdef SK_ENABLE_VK_LAYERS
78     if (fDebugCallback != VK_NULL_HANDLE) {
79         fDestroyDebugReportCallbackEXT(fVulkan.fInstance, fDebugCallback, nullptr);
80     }
81 #else
82     // Surpress unused private member variable warning
83     (void)fDebugCallback;
84     (void)fDestroyDebugReportCallbackEXT;
85 #endif
86     localVkDestroyInstance(fVulkan.fInstance, nullptr);
87     delete fExtensions;
88 
89     sk_gpu_test::FreeVulkanFeaturesStructs(fFeatures);
90     delete fFeatures;
91 }
92 
contextType()93 skgpu::ContextType VulkanTestContext::contextType() {
94     return skgpu::ContextType::kVulkan;
95 }
96 
makeContext(const TestOptions & options)97 std::unique_ptr<skgpu::graphite::Context> VulkanTestContext::makeContext(
98         const TestOptions& options) {
99     SkASSERT(!options.hasDawnOptions());
100     skgpu::graphite::ContextOptions revisedContextOptions(options.fContextOptions);
101     skgpu::graphite::ContextOptionsPriv contextOptionsPriv;
102     if (!options.fContextOptions.fOptionsPriv) {
103         revisedContextOptions.fOptionsPriv = &contextOptionsPriv;
104     }
105     // Needed to make synchronous readPixels work
106     revisedContextOptions.fOptionsPriv->fStoreContextRefInRecorder = true;
107     SkASSERT(fVulkan.fMemoryAllocator);
108     return skgpu::graphite::ContextFactory::MakeVulkan(fVulkan, revisedContextOptions);
109 }
110 
111 }  // namespace skiatest::graphite
112