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