/src/skia/tools/gpu/vk/VkTestHelper.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #if defined(SK_VULKAN) |
11 | | |
12 | | #include "include/core/SkSurface.h" |
13 | | #include "include/gpu/ganesh/GrTypes.h" |
14 | | #include "include/gpu/vk/VulkanBackendContext.h" |
15 | | #include "include/gpu/vk/VulkanMemoryAllocator.h" |
16 | | #include "tests/TestType.h" |
17 | | #include "tools/gpu/ProtectedUtils.h" |
18 | | #include "tools/gpu/vk/VkTestUtils.h" |
19 | | |
20 | | #if defined(SK_GANESH) |
21 | | #include "include/gpu/ganesh/GrDirectContext.h" |
22 | | #include "include/gpu/ganesh/vk/GrVkDirectContext.h" |
23 | | #endif |
24 | | |
25 | | #if defined(SK_GRAPHITE) |
26 | | #include "include/gpu/graphite/Context.h" |
27 | | #include "include/gpu/graphite/vk/VulkanGraphiteUtils.h" |
28 | | #include "src/gpu/graphite/ContextOptionsPriv.h" |
29 | | #endif |
30 | | |
31 | | #define ACQUIRE_INST_VK_PROC(name) \ |
32 | 0 | fVk##name = reinterpret_cast<PFN_vk##name>(instProc(fBackendContext.fInstance, "vk" #name)); \ |
33 | 0 | if (fVk##name == nullptr) { \ |
34 | 0 | SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \ |
35 | 0 | return false; \ |
36 | 0 | } |
37 | | |
38 | | #define ACQUIRE_DEVICE_VK_PROC(name) \ |
39 | 0 | fVk##name = reinterpret_cast<PFN_vk##name>(fVkGetDeviceProcAddr(fDevice, "vk" #name)); \ |
40 | 0 | if (fVk##name == nullptr) { \ |
41 | 0 | SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \ |
42 | 0 | return false; \ |
43 | 0 | } |
44 | | |
45 | | #if defined(SK_GANESH) |
46 | | |
47 | | class GaneshVkTestHelper : public VkTestHelper { |
48 | | public: |
49 | 0 | GaneshVkTestHelper(bool isProtected) : VkTestHelper(isProtected) {} |
50 | | |
51 | 0 | ~GaneshVkTestHelper() override { |
52 | | // Make sure any work, release procs, etc left on the context are finished with before we |
53 | | // start tearing everything down. |
54 | 0 | if (fDirectContext) { |
55 | 0 | fDirectContext->flushAndSubmit(GrSyncCpu::kYes); |
56 | 0 | } |
57 | |
|
58 | 0 | fDirectContext.reset(); |
59 | 0 | } |
60 | | |
61 | 0 | bool isValid() const override { return fDirectContext != nullptr; } |
62 | | |
63 | 0 | sk_sp<SkSurface> createSurface(SkISize size, bool textureable, bool isProtected) override { |
64 | | // Make Ganesh use DMSAA to better match Graphite's behavior |
65 | 0 | SkSurfaceProps props(SkSurfaceProps::kDynamicMSAA_Flag, kUnknown_SkPixelGeometry); |
66 | |
|
67 | 0 | return ProtectedUtils::CreateProtectedSkSurface(fDirectContext.get(), size, |
68 | 0 | textureable, isProtected, |
69 | 0 | &props); |
70 | 0 | } |
71 | | |
72 | 0 | void submitAndWaitForCompletion(bool* completionMarker) override { |
73 | 0 | fDirectContext->submit(); |
74 | 0 | while (!*completionMarker) { |
75 | 0 | fDirectContext->checkAsyncWorkCompletion(); |
76 | 0 | } |
77 | 0 | } |
78 | | |
79 | 0 | GrDirectContext* directContext() override { return fDirectContext.get(); } |
80 | | |
81 | | protected: |
82 | 0 | bool init() override { |
83 | 0 | if (!this->setupBackendContext()) { |
84 | 0 | return false; |
85 | 0 | } |
86 | | |
87 | 0 | SkASSERT(fBackendContext.fMemoryAllocator); |
88 | 0 | fDirectContext = GrDirectContexts::MakeVulkan(fBackendContext); |
89 | 0 | if (!fDirectContext) { |
90 | 0 | return false; |
91 | 0 | } |
92 | | |
93 | 0 | SkASSERT(fDirectContext->supportsProtectedContent() == fIsProtected); |
94 | 0 | return true; |
95 | 0 | } Unexecuted instantiation: GaneshVkTestHelper::init() Unexecuted instantiation: GaneshVkTestHelper::init() |
96 | | |
97 | | private: |
98 | | sk_sp<GrDirectContext> fDirectContext; |
99 | | }; |
100 | | |
101 | | #endif // SK_GANESH |
102 | | |
103 | | #if defined(SK_GRAPHITE) |
104 | | |
105 | | class GraphiteVkTestHelper : public VkTestHelper { |
106 | | public: |
107 | 0 | GraphiteVkTestHelper(bool isProtected) : VkTestHelper(isProtected) {} |
108 | | |
109 | 0 | ~GraphiteVkTestHelper() override { |
110 | | // Make sure any work, release procs, etc left on the context are finished with before we |
111 | | // start tearing everything down. |
112 | |
|
113 | 0 | std::unique_ptr<skgpu::graphite::Recording> recording; |
114 | 0 | if (fRecorder) { |
115 | 0 | recording = fRecorder->snap(); |
116 | 0 | } |
117 | |
|
118 | 0 | if (fContext) { |
119 | 0 | fContext->insertRecording({ recording.get() }); |
120 | 0 | fContext->submit(skgpu::graphite::SyncToCpu::kYes); |
121 | 0 | } |
122 | |
|
123 | 0 | recording.reset(); |
124 | 0 | fRecorder.reset(); |
125 | 0 | fContext.reset(); |
126 | 0 | } |
127 | | |
128 | 0 | bool isValid() const override { return fContext != nullptr && fRecorder != nullptr; } |
129 | | |
130 | | sk_sp<SkSurface> createSurface(SkISize size, |
131 | | bool /* textureable */, |
132 | 0 | bool isProtected) override { |
133 | 0 | return ProtectedUtils::CreateProtectedSkSurface(fRecorder.get(), size, |
134 | 0 | skgpu::Protected(isProtected)); |
135 | 0 | } |
136 | | |
137 | 0 | void submitAndWaitForCompletion(bool* completionMarker) override { |
138 | 0 | fContext->submit(); |
139 | 0 | while (!*completionMarker) { |
140 | 0 | fContext->checkAsyncWorkCompletion(); |
141 | 0 | } |
142 | 0 | } |
143 | | |
144 | 0 | skgpu::graphite::Recorder* recorder() override { return fRecorder.get(); } |
145 | 0 | skgpu::graphite::Context* context() override { return fContext.get(); } |
146 | | |
147 | | protected: |
148 | 0 | bool init() override { |
149 | 0 | if (!this->setupBackendContext()) { |
150 | 0 | return false; |
151 | 0 | } |
152 | | |
153 | 0 | skgpu::graphite::ContextOptions contextOptions; |
154 | 0 | skgpu::graphite::ContextOptionsPriv contextOptionsPriv; |
155 | | // Needed to make ManagedGraphiteTexture::ReleaseProc (w/in CreateProtectedSkSurface) work |
156 | 0 | contextOptionsPriv.fStoreContextRefInRecorder = true; |
157 | 0 | contextOptions.fOptionsPriv = &contextOptionsPriv; |
158 | |
|
159 | 0 | fContext = skgpu::graphite::ContextFactory::MakeVulkan(fBackendContext, contextOptions); |
160 | 0 | if (!fContext) { |
161 | 0 | return false; |
162 | 0 | } |
163 | | |
164 | 0 | SkASSERT(fContext->supportsProtectedContent() == fIsProtected); |
165 | |
|
166 | 0 | fRecorder = fContext->makeRecorder(); |
167 | 0 | if (!fRecorder) { |
168 | 0 | return false; |
169 | 0 | } |
170 | | |
171 | 0 | return true; |
172 | 0 | } Unexecuted instantiation: GraphiteVkTestHelper::init() Unexecuted instantiation: GraphiteVkTestHelper::init() |
173 | | |
174 | | private: |
175 | | std::unique_ptr<skgpu::graphite::Context> fContext; |
176 | | std::unique_ptr<skgpu::graphite::Recorder> fRecorder; |
177 | | }; |
178 | | |
179 | | #endif // SK_GRAPHITE |
180 | | |
181 | | std::unique_ptr<VkTestHelper> VkTestHelper::Make(skiatest::TestType testType, |
182 | 0 | bool isProtected) { |
183 | 0 | std::unique_ptr<VkTestHelper> helper; |
184 | |
|
185 | 0 | switch (testType) { |
186 | 0 | #if defined(SK_GANESH) |
187 | 0 | case skiatest::TestType::kGanesh: |
188 | 0 | helper = std::make_unique<GaneshVkTestHelper>(isProtected); |
189 | 0 | break; |
190 | 0 | #endif |
191 | 0 | #if defined(SK_GRAPHITE) |
192 | 0 | case skiatest::TestType::kGraphite: |
193 | 0 | helper = std::make_unique<GraphiteVkTestHelper>(isProtected); |
194 | 0 | break; |
195 | 0 | #endif |
196 | 0 | default: |
197 | 0 | return nullptr; |
198 | 0 | } |
199 | 0 | if (!helper->init()) { |
200 | 0 | return nullptr; |
201 | 0 | } |
202 | | |
203 | 0 | return helper; |
204 | 0 | } |
205 | | |
206 | 0 | bool VkTestHelper::setupBackendContext() { |
207 | 0 | PFN_vkGetInstanceProcAddr instProc; |
208 | 0 | if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) { |
209 | 0 | return false; |
210 | 0 | } |
211 | | |
212 | 0 | fFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; |
213 | 0 | fFeatures.pNext = nullptr; |
214 | |
|
215 | 0 | fBackendContext.fInstance = VK_NULL_HANDLE; |
216 | 0 | fBackendContext.fDevice = VK_NULL_HANDLE; |
217 | |
|
218 | 0 | if (!sk_gpu_test::CreateVkBackendContext(instProc, &fBackendContext, &fExtensions, |
219 | 0 | &fFeatures, &fDebugCallback, nullptr, |
220 | 0 | sk_gpu_test::CanPresentFn(), fIsProtected)) { |
221 | 0 | return false; |
222 | 0 | } |
223 | 0 | fDevice = fBackendContext.fDevice; |
224 | |
|
225 | 0 | if (fDebugCallback != VK_NULL_HANDLE) { |
226 | 0 | fDestroyDebugCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>( |
227 | 0 | instProc(fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT")); |
228 | 0 | } |
229 | 0 | ACQUIRE_INST_VK_PROC(DestroyInstance) |
230 | 0 | ACQUIRE_INST_VK_PROC(DeviceWaitIdle) |
231 | 0 | ACQUIRE_INST_VK_PROC(DestroyDevice) |
232 | | |
233 | 0 | ACQUIRE_INST_VK_PROC(GetPhysicalDeviceFormatProperties) |
234 | 0 | ACQUIRE_INST_VK_PROC(GetPhysicalDeviceMemoryProperties) |
235 | | |
236 | 0 | ACQUIRE_INST_VK_PROC(GetDeviceProcAddr) |
237 | | |
238 | 0 | ACQUIRE_DEVICE_VK_PROC(CreateImage) |
239 | 0 | ACQUIRE_DEVICE_VK_PROC(DestroyImage) |
240 | 0 | ACQUIRE_DEVICE_VK_PROC(GetImageMemoryRequirements) |
241 | 0 | ACQUIRE_DEVICE_VK_PROC(AllocateMemory) |
242 | 0 | ACQUIRE_DEVICE_VK_PROC(FreeMemory) |
243 | 0 | ACQUIRE_DEVICE_VK_PROC(BindImageMemory) |
244 | 0 | ACQUIRE_DEVICE_VK_PROC(MapMemory) |
245 | 0 | ACQUIRE_DEVICE_VK_PROC(UnmapMemory) |
246 | 0 | ACQUIRE_DEVICE_VK_PROC(FlushMappedMemoryRanges) |
247 | 0 | ACQUIRE_DEVICE_VK_PROC(GetImageSubresourceLayout) |
248 | 0 | return true; |
249 | 0 | } |
250 | | |
251 | 0 | VkTestHelper::~VkTestHelper() { |
252 | 0 | fBackendContext.fMemoryAllocator.reset(); |
253 | 0 | if (fDevice != VK_NULL_HANDLE) { |
254 | 0 | fVkDeviceWaitIdle(fDevice); |
255 | 0 | fVkDestroyDevice(fDevice, nullptr); |
256 | 0 | fDevice = VK_NULL_HANDLE; |
257 | 0 | } |
258 | 0 | if (fDebugCallback != VK_NULL_HANDLE) { |
259 | 0 | fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr); |
260 | 0 | } |
261 | |
|
262 | 0 | if (fBackendContext.fInstance != VK_NULL_HANDLE) { |
263 | 0 | fVkDestroyInstance(fBackendContext.fInstance, nullptr); |
264 | 0 | fBackendContext.fInstance = VK_NULL_HANDLE; |
265 | 0 | } |
266 | |
|
267 | 0 | sk_gpu_test::FreeVulkanFeaturesStructs(&fFeatures); |
268 | 0 | } |
269 | | |
270 | | #endif // SK_VULKAN |