Coverage Report

Created: 2024-05-20 07:14

/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