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