Coverage Report

Created: 2025-06-24 08:20

/src/skia/src/gpu/ganesh/vk/GrVkResourceProvider.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Copyright 2016 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 "src/gpu/ganesh/vk/GrVkResourceProvider.h"
9
10
#include "include/core/SkData.h"
11
#include "include/core/SkString.h"
12
#include "include/gpu/ganesh/GrDirectContext.h"
13
#include "include/gpu/ganesh/GrTypes.h"
14
#include "include/private/base/SkDebug.h"
15
#include "include/private/gpu/ganesh/GrTypesPriv.h"
16
#include "src/core/SkTaskGroup.h"
17
#include "src/core/SkTraceEvent.h"
18
#include "src/gpu/Blend.h"
19
#include "src/gpu/RefCntedCallback.h"
20
#include "src/gpu/ganesh/GrDirectContextPriv.h"
21
#include "src/gpu/ganesh/GrGeometryProcessor.h"
22
#include "src/gpu/ganesh/GrSamplerState.h"
23
#include "src/gpu/ganesh/GrStencilSettings.h"
24
#include "src/gpu/ganesh/vk/GrVkCommandBuffer.h"
25
#include "src/gpu/ganesh/vk/GrVkCommandPool.h"
26
#include "src/gpu/ganesh/vk/GrVkDescriptorPool.h"
27
#include "src/gpu/ganesh/vk/GrVkGpu.h"
28
#include "src/gpu/ganesh/vk/GrVkPipeline.h"
29
#include "src/gpu/ganesh/vk/GrVkRenderTarget.h"
30
#include "src/gpu/ganesh/vk/GrVkUtil.h"
31
32
#include <algorithm>
33
#include <cstring>
34
35
class GrProgramInfo;
36
class GrRenderTarget;
37
class GrVkDescriptorSet;
38
39
GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
40
0
    : fGpu(gpu)
41
0
    , fPipelineCache(VK_NULL_HANDLE) {
42
0
    fPipelineStateCache = sk_make_sp<PipelineStateCache>(gpu);
43
0
}
44
45
0
GrVkResourceProvider::~GrVkResourceProvider() {
46
0
    SkASSERT(fRenderPassArray.empty());
47
0
    SkASSERT(fExternalRenderPasses.empty());
48
0
    SkASSERT(fMSAALoadPipelines.empty());
49
0
    SkASSERT(VK_NULL_HANDLE == fPipelineCache);
50
0
}
Unexecuted instantiation: GrVkResourceProvider::~GrVkResourceProvider()
Unexecuted instantiation: GrVkResourceProvider::~GrVkResourceProvider()
51
52
0
VkPipelineCache GrVkResourceProvider::pipelineCache() {
53
0
    if (fPipelineCache == VK_NULL_HANDLE) {
54
0
        TRACE_EVENT0("skia.shaders", "CreatePipelineCache-GrVkResourceProvider");
55
0
        VkPipelineCacheCreateInfo createInfo;
56
0
        memset(&createInfo, 0, sizeof(VkPipelineCacheCreateInfo));
57
0
        createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
58
0
        createInfo.pNext = nullptr;
59
0
        createInfo.flags = 0;
60
61
0
        auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
62
0
        sk_sp<SkData> cached;
63
0
        if (persistentCache) {
64
0
            uint32_t key = GrVkGpu::kPipelineCache_PersistentCacheKeyType;
65
0
            sk_sp<SkData> keyData = SkData::MakeWithoutCopy(&key, sizeof(uint32_t));
66
0
            cached = persistentCache->load(*keyData);
67
0
        }
68
0
        bool usedCached = false;
69
0
        if (cached) {
70
0
            const uint32_t* cacheHeader = (const uint32_t*)cached->data();
71
0
            if (cacheHeader[1] == VK_PIPELINE_CACHE_HEADER_VERSION_ONE) {
72
                // For version one of the header, the total header size is 16 bytes plus
73
                // VK_UUID_SIZE bytes. See Section 9.6 (Pipeline Cache) in the vulkan spec to see
74
                // the breakdown of these bytes.
75
0
                SkASSERT(cacheHeader[0] == 16 + VK_UUID_SIZE);
76
0
                const VkPhysicalDeviceProperties& devProps = fGpu->physicalDeviceProperties();
77
0
                const uint8_t* supportedPipelineCacheUUID = devProps.pipelineCacheUUID;
78
0
                if (cacheHeader[2] == devProps.vendorID && cacheHeader[3] == devProps.deviceID &&
79
0
                    !memcmp(&cacheHeader[4], supportedPipelineCacheUUID, VK_UUID_SIZE)) {
80
0
                    createInfo.initialDataSize = cached->size();
81
0
                    createInfo.pInitialData = cached->data();
82
0
                    usedCached = true;
83
0
                }
84
0
            }
85
0
        }
86
0
        if (!usedCached) {
87
0
            createInfo.initialDataSize = 0;
88
0
            createInfo.pInitialData = nullptr;
89
0
        }
90
91
0
        VkResult result;
92
0
        GR_VK_CALL_RESULT(fGpu, result, CreatePipelineCache(fGpu->device(), &createInfo, nullptr,
93
0
                                                            &fPipelineCache));
94
0
        if (VK_SUCCESS != result) {
95
0
            fPipelineCache = VK_NULL_HANDLE;
96
0
        }
97
0
    }
98
0
    return fPipelineCache;
99
0
}
Unexecuted instantiation: GrVkResourceProvider::pipelineCache()
Unexecuted instantiation: GrVkResourceProvider::pipelineCache()
100
101
0
void GrVkResourceProvider::init() {
102
    // Init uniform descriptor objects
103
0
    GrVkDescriptorSetManager* dsm = GrVkDescriptorSetManager::CreateUniformManager(fGpu);
104
0
    fDescriptorSetManagers.emplace_back(dsm);
105
0
    SkASSERT(1 == fDescriptorSetManagers.size());
106
0
    fUniformDSHandle = GrVkDescriptorSetManager::Handle(0);
107
0
    dsm = GrVkDescriptorSetManager::CreateInputManager(fGpu);
108
0
    fDescriptorSetManagers.emplace_back(dsm);
109
0
    SkASSERT(2 == fDescriptorSetManagers.size());
110
0
    fInputDSHandle = GrVkDescriptorSetManager::Handle(1);
111
0
}
Unexecuted instantiation: GrVkResourceProvider::init()
Unexecuted instantiation: GrVkResourceProvider::init()
112
113
sk_sp<const GrVkPipeline> GrVkResourceProvider::makePipeline(
114
        const GrProgramInfo& programInfo,
115
        VkPipelineShaderStageCreateInfo* shaderStageInfo,
116
        int shaderStageCount,
117
        VkRenderPass compatibleRenderPass,
118
        VkPipelineLayout layout,
119
0
        uint32_t subpass) {
120
0
    return GrVkPipeline::Make(fGpu, programInfo, shaderStageInfo, shaderStageCount,
121
0
                              compatibleRenderPass, layout, this->pipelineCache(), subpass);
122
0
}
123
124
// To create framebuffers, we first need to create a simple RenderPass that is
125
// only used for framebuffer creation. When we actually render we will create
126
// RenderPasses as needed that are compatible with the framebuffer.
127
const GrVkRenderPass*
128
GrVkResourceProvider::findCompatibleRenderPass(GrVkRenderTarget* target,
129
                                               CompatibleRPHandle* compatibleHandle,
130
                                               bool withResolve,
131
                                               bool withStencil,
132
                                               SelfDependencyFlags selfDepFlags,
133
0
                                               LoadFromResolve loadFromResolve) {
134
    // Get attachment information from render target. This includes which attachments the render
135
    // target has (color, stencil) and the attachments format and sample count.
136
0
    GrVkRenderPass::AttachmentFlags attachmentFlags;
137
0
    GrVkRenderPass::AttachmentsDescriptor attachmentsDesc;
138
0
    if (!target->getAttachmentsDescriptor(&attachmentsDesc, &attachmentFlags,
139
0
                                          withResolve, withStencil)) {
140
0
        return nullptr;
141
0
    }
142
143
0
    return this->findCompatibleRenderPass(&attachmentsDesc, attachmentFlags, selfDepFlags,
144
0
                                          loadFromResolve, compatibleHandle);
145
0
}
146
147
const GrVkRenderPass*
148
GrVkResourceProvider::findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor* desc,
149
                                               GrVkRenderPass::AttachmentFlags attachmentFlags,
150
                                               SelfDependencyFlags selfDepFlags,
151
                                               LoadFromResolve loadFromResolve,
152
0
                                               CompatibleRPHandle* compatibleHandle) {
153
0
    for (int i = 0; i < fRenderPassArray.size(); ++i) {
154
0
        if (fRenderPassArray[i].isCompatible(*desc, attachmentFlags, selfDepFlags,
155
0
                                             loadFromResolve)) {
156
0
            const GrVkRenderPass* renderPass = fRenderPassArray[i].getCompatibleRenderPass();
157
0
            renderPass->ref();
158
0
            if (compatibleHandle) {
159
0
                *compatibleHandle = CompatibleRPHandle(i);
160
0
            }
161
0
            return renderPass;
162
0
        }
163
0
    }
164
165
0
    GrVkRenderPass* renderPass = GrVkRenderPass::CreateSimple(fGpu, desc, attachmentFlags,
166
0
                                                              selfDepFlags, loadFromResolve);
167
0
    if (!renderPass) {
168
0
        return nullptr;
169
0
    }
170
0
    fRenderPassArray.emplace_back(renderPass);
171
172
0
    if (compatibleHandle) {
173
0
        *compatibleHandle = CompatibleRPHandle(fRenderPassArray.size() - 1);
174
0
    }
175
0
    return renderPass;
176
0
}
177
178
const GrVkRenderPass* GrVkResourceProvider::findCompatibleExternalRenderPass(
179
0
        VkRenderPass renderPass, uint32_t colorAttachmentIndex) {
180
0
    for (int i = 0; i < fExternalRenderPasses.size(); ++i) {
181
0
        if (fExternalRenderPasses[i]->isCompatibleExternalRP(renderPass)) {
182
0
            fExternalRenderPasses[i]->ref();
183
#ifdef SK_DEBUG
184
            uint32_t cachedColorIndex;
185
0
            SkASSERT(fExternalRenderPasses[i]->colorAttachmentIndex(&cachedColorIndex));
186
0
            SkASSERT(cachedColorIndex == colorAttachmentIndex);
187
#endif
188
0
            return fExternalRenderPasses[i];
189
0
        }
190
0
    }
191
192
0
    const GrVkRenderPass* newRenderPass = new GrVkRenderPass(fGpu, renderPass,
193
0
                                                             colorAttachmentIndex);
194
0
    fExternalRenderPasses.push_back(newRenderPass);
195
0
    newRenderPass->ref();
196
0
    return newRenderPass;
197
0
}
Unexecuted instantiation: GrVkResourceProvider::findCompatibleExternalRenderPass(VkRenderPass_T*, unsigned int)
Unexecuted instantiation: GrVkResourceProvider::findCompatibleExternalRenderPass(VkRenderPass_T*, unsigned int)
198
199
const GrVkRenderPass* GrVkResourceProvider::findRenderPass(
200
        GrVkRenderTarget* target,
201
        const GrVkRenderPass::LoadStoreOps& colorOps,
202
        const GrVkRenderPass::LoadStoreOps& resolveOps,
203
        const GrVkRenderPass::LoadStoreOps& stencilOps,
204
        CompatibleRPHandle* compatibleHandle,
205
        bool withResolve,
206
        bool withStencil,
207
        SelfDependencyFlags selfDepFlags,
208
0
        LoadFromResolve loadFromResolve) {
209
0
    GrVkResourceProvider::CompatibleRPHandle tempRPHandle;
210
0
    GrVkResourceProvider::CompatibleRPHandle* pRPHandle = compatibleHandle ? compatibleHandle
211
0
                                                                           : &tempRPHandle;
212
0
    *pRPHandle = target->compatibleRenderPassHandle(withResolve, withStencil, selfDepFlags,
213
0
                                                    loadFromResolve);
214
0
    if (!pRPHandle->isValid()) {
215
0
        return nullptr;
216
0
    }
217
218
0
    return this->findRenderPass(*pRPHandle, colorOps, resolveOps, stencilOps);
219
0
}
220
221
const GrVkRenderPass*
222
GrVkResourceProvider::findRenderPass(const CompatibleRPHandle& compatibleHandle,
223
                                     const GrVkRenderPass::LoadStoreOps& colorOps,
224
                                     const GrVkRenderPass::LoadStoreOps& resolveOps,
225
0
                                     const GrVkRenderPass::LoadStoreOps& stencilOps) {
226
0
    SkASSERT(compatibleHandle.isValid() && compatibleHandle.toIndex() < fRenderPassArray.size());
227
0
    CompatibleRenderPassSet& compatibleSet = fRenderPassArray[compatibleHandle.toIndex()];
228
0
    const GrVkRenderPass* renderPass = compatibleSet.getRenderPass(fGpu,
229
0
                                                                   colorOps,
230
0
                                                                   resolveOps,
231
0
                                                                   stencilOps);
232
0
    if (!renderPass) {
233
0
        return nullptr;
234
0
    }
235
0
    renderPass->ref();
236
0
    return renderPass;
237
0
}
Unexecuted instantiation: GrVkResourceProvider::findRenderPass(GrResourceHandle<GrVkResourceProvider::CompatibleRPHandleKind> const&, GrVkRenderPass::LoadStoreOps const&, GrVkRenderPass::LoadStoreOps const&, GrVkRenderPass::LoadStoreOps const&)
Unexecuted instantiation: GrVkResourceProvider::findRenderPass(GrResourceHandle<GrVkResourceProvider::CompatibleRPHandleKind> const&, GrVkRenderPass::LoadStoreOps const&, GrVkRenderPass::LoadStoreOps const&, GrVkRenderPass::LoadStoreOps const&)
238
239
GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
240
0
                                                            VkDescriptorType type, uint32_t count) {
241
0
    return GrVkDescriptorPool::Create(fGpu, type, count);
242
0
}
243
244
GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(
245
0
        GrSamplerState params, const skgpu::VulkanYcbcrConversionInfo& ycbcrInfo) {
246
0
    GrVkSampler* sampler = fSamplers.find(GrVkSampler::GenerateKey(params, ycbcrInfo));
247
0
    if (!sampler) {
248
0
        sampler = GrVkSampler::Create(fGpu, params, ycbcrInfo);
249
0
        if (!sampler) {
250
0
            return nullptr;
251
0
        }
252
0
        fSamplers.add(sampler);
253
0
    }
254
0
    SkASSERT(sampler);
255
0
    sampler->ref();
256
0
    return sampler;
257
0
}
Unexecuted instantiation: GrVkResourceProvider::findOrCreateCompatibleSampler(GrSamplerState, skgpu::VulkanYcbcrConversionInfo const&)
Unexecuted instantiation: GrVkResourceProvider::findOrCreateCompatibleSampler(GrSamplerState, skgpu::VulkanYcbcrConversionInfo const&)
258
259
GrVkSamplerYcbcrConversion* GrVkResourceProvider::findOrCreateCompatibleSamplerYcbcrConversion(
260
0
        const skgpu::VulkanYcbcrConversionInfo& ycbcrInfo) {
261
0
    GrVkSamplerYcbcrConversion* ycbcrConversion =
262
0
            fYcbcrConversions.find(GrVkSamplerYcbcrConversion::GenerateKey(ycbcrInfo));
263
0
    if (!ycbcrConversion) {
264
0
        ycbcrConversion = GrVkSamplerYcbcrConversion::Create(fGpu, ycbcrInfo);
265
0
        if (!ycbcrConversion) {
266
0
            return nullptr;
267
0
        }
268
0
        fYcbcrConversions.add(ycbcrConversion);
269
0
    }
270
0
    SkASSERT(ycbcrConversion);
271
0
    ycbcrConversion->ref();
272
0
    return ycbcrConversion;
273
0
}
Unexecuted instantiation: GrVkResourceProvider::findOrCreateCompatibleSamplerYcbcrConversion(skgpu::VulkanYcbcrConversionInfo const&)
Unexecuted instantiation: GrVkResourceProvider::findOrCreateCompatibleSamplerYcbcrConversion(skgpu::VulkanYcbcrConversionInfo const&)
274
275
GrVkPipelineState* GrVkResourceProvider::findOrCreateCompatiblePipelineState(
276
        GrRenderTarget* renderTarget,
277
        const GrProgramInfo& programInfo,
278
        VkRenderPass compatibleRenderPass,
279
0
        bool overrideSubpassForResolveLoad) {
280
0
    return fPipelineStateCache->findOrCreatePipelineState(renderTarget, programInfo,
281
0
                                                          compatibleRenderPass,
282
0
                                                          overrideSubpassForResolveLoad);
283
0
}
284
285
GrVkPipelineState* GrVkResourceProvider::findOrCreateCompatiblePipelineState(
286
        const GrProgramDesc& desc,
287
        const GrProgramInfo& programInfo,
288
        VkRenderPass compatibleRenderPass,
289
0
        GrThreadSafePipelineBuilder::Stats::ProgramCacheResult* stat) {
290
291
0
    auto tmp =  fPipelineStateCache->findOrCreatePipelineState(desc, programInfo,
292
0
                                                               compatibleRenderPass, stat);
293
0
    if (!tmp) {
294
0
        fPipelineStateCache->stats()->incNumPreCompilationFailures();
295
0
    } else {
296
0
        fPipelineStateCache->stats()->incNumPreProgramCacheResult(*stat);
297
0
    }
298
299
0
    return tmp;
300
0
}
301
302
sk_sp<const GrVkPipeline> GrVkResourceProvider::findOrCreateMSAALoadPipeline(
303
        const GrVkRenderPass& renderPass,
304
        int numSamples,
305
        VkPipelineShaderStageCreateInfo* shaderStageInfo,
306
0
        VkPipelineLayout pipelineLayout) {
307
    // Find or Create a compatible pipeline
308
0
    sk_sp<const GrVkPipeline> pipeline;
309
0
    for (int i = 0; i < fMSAALoadPipelines.size() && !pipeline; ++i) {
310
0
        if (fMSAALoadPipelines[i].fRenderPass->isCompatible(renderPass)) {
311
0
            pipeline = fMSAALoadPipelines[i].fPipeline;
312
0
        }
313
0
    }
314
0
    if (!pipeline) {
315
0
        pipeline = GrVkPipeline::Make(
316
0
                fGpu,
317
0
                /*vertexAttribs=*/GrGeometryProcessor::AttributeSet(),
318
0
                /*instanceAttribs=*/GrGeometryProcessor::AttributeSet(),
319
0
                GrPrimitiveType::kTriangleStrip,
320
0
                kTopLeft_GrSurfaceOrigin,
321
0
                GrStencilSettings(),
322
0
                numSamples,
323
0
                /*isHWantialiasState=*/false,
324
0
                skgpu::BlendInfo(),
325
0
                /*isWireframe=*/false,
326
0
                /*useConservativeRaster=*/false,
327
0
                /*subpass=*/0,
328
0
                shaderStageInfo,
329
0
                /*shaderStageCount=*/2,
330
0
                renderPass.vkRenderPass(),
331
0
                pipelineLayout,
332
0
                /*ownsLayout=*/false,
333
0
                this->pipelineCache());
334
0
        if (!pipeline) {
335
0
            return nullptr;
336
0
        }
337
0
        fMSAALoadPipelines.push_back({pipeline, &renderPass});
338
0
    }
339
0
    SkASSERT(pipeline);
340
0
    return pipeline;
341
0
}
Unexecuted instantiation: GrVkResourceProvider::findOrCreateMSAALoadPipeline(GrVkRenderPass const&, int, VkPipelineShaderStageCreateInfo*, VkPipelineLayout_T*)
Unexecuted instantiation: GrVkResourceProvider::findOrCreateMSAALoadPipeline(GrVkRenderPass const&, int, VkPipelineShaderStageCreateInfo*, VkPipelineLayout_T*)
342
343
void GrVkResourceProvider::getZeroSamplerDescriptorSetHandle(
344
0
        GrVkDescriptorSetManager::Handle* handle) {
345
0
    SkASSERT(handle);
346
0
    for (int i = 0; i < fDescriptorSetManagers.size(); ++i) {
347
0
        if (fDescriptorSetManagers[i]->isZeroSampler()) {
348
0
            *handle = GrVkDescriptorSetManager::Handle(i);
349
0
            return;
350
0
        }
351
0
    }
352
353
0
    GrVkDescriptorSetManager* dsm =
354
0
            GrVkDescriptorSetManager::CreateZeroSamplerManager(fGpu);
355
0
    fDescriptorSetManagers.emplace_back(dsm);
356
0
    *handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.size() - 1);
357
0
}
Unexecuted instantiation: GrVkResourceProvider::getZeroSamplerDescriptorSetHandle(GrResourceHandle<GrVkDescriptorSetManager::HandleKind>*)
Unexecuted instantiation: GrVkResourceProvider::getZeroSamplerDescriptorSetHandle(GrResourceHandle<GrVkDescriptorSetManager::HandleKind>*)
358
359
void GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType type,
360
                                                         const GrVkUniformHandler& uniformHandler,
361
0
                                                         GrVkDescriptorSetManager::Handle* handle) {
362
0
    SkASSERT(handle);
363
0
    SkASSERT(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type ||
364
0
             VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type);
365
0
    for (int i = 0; i < fDescriptorSetManagers.size(); ++i) {
366
0
        if (fDescriptorSetManagers[i]->isCompatible(type, &uniformHandler)) {
367
0
           *handle = GrVkDescriptorSetManager::Handle(i);
368
0
           return;
369
0
        }
370
0
    }
371
372
0
    GrVkDescriptorSetManager* dsm = GrVkDescriptorSetManager::CreateSamplerManager(fGpu, type,
373
0
                                                                                   uniformHandler);
374
0
    fDescriptorSetManagers.emplace_back(dsm);
375
0
    *handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.size() - 1);
376
0
}
Unexecuted instantiation: GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType, GrVkUniformHandler const&, GrResourceHandle<GrVkDescriptorSetManager::HandleKind>*)
Unexecuted instantiation: GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType, GrVkUniformHandler const&, GrResourceHandle<GrVkDescriptorSetManager::HandleKind>*)
377
378
0
VkDescriptorSetLayout GrVkResourceProvider::getUniformDSLayout() const {
379
0
    SkASSERT(fUniformDSHandle.isValid());
380
0
    return fDescriptorSetManagers[fUniformDSHandle.toIndex()]->layout();
381
0
}
Unexecuted instantiation: GrVkResourceProvider::getUniformDSLayout() const
Unexecuted instantiation: GrVkResourceProvider::getUniformDSLayout() const
382
383
0
VkDescriptorSetLayout GrVkResourceProvider::getInputDSLayout() const {
384
0
    SkASSERT(fInputDSHandle.isValid());
385
0
    return fDescriptorSetManagers[fInputDSHandle.toIndex()]->layout();
386
0
}
Unexecuted instantiation: GrVkResourceProvider::getInputDSLayout() const
Unexecuted instantiation: GrVkResourceProvider::getInputDSLayout() const
387
388
VkDescriptorSetLayout GrVkResourceProvider::getSamplerDSLayout(
389
0
        const GrVkDescriptorSetManager::Handle& handle) const {
390
0
    SkASSERT(handle.isValid());
391
0
    return fDescriptorSetManagers[handle.toIndex()]->layout();
392
0
}
Unexecuted instantiation: GrVkResourceProvider::getSamplerDSLayout(GrResourceHandle<GrVkDescriptorSetManager::HandleKind> const&) const
Unexecuted instantiation: GrVkResourceProvider::getSamplerDSLayout(GrResourceHandle<GrVkDescriptorSetManager::HandleKind> const&) const
393
394
0
const GrVkDescriptorSet* GrVkResourceProvider::getUniformDescriptorSet() {
395
0
    SkASSERT(fUniformDSHandle.isValid());
396
0
    return fDescriptorSetManagers[fUniformDSHandle.toIndex()]->getDescriptorSet(fGpu,
397
0
                                                                                fUniformDSHandle);
398
0
}
Unexecuted instantiation: GrVkResourceProvider::getUniformDescriptorSet()
Unexecuted instantiation: GrVkResourceProvider::getUniformDescriptorSet()
399
400
0
const GrVkDescriptorSet* GrVkResourceProvider::getInputDescriptorSet() {
401
0
    SkASSERT(fInputDSHandle.isValid());
402
0
    return fDescriptorSetManagers[fInputDSHandle.toIndex()]->getDescriptorSet(fGpu, fInputDSHandle);
403
0
}
Unexecuted instantiation: GrVkResourceProvider::getInputDescriptorSet()
Unexecuted instantiation: GrVkResourceProvider::getInputDescriptorSet()
404
405
const GrVkDescriptorSet* GrVkResourceProvider::getSamplerDescriptorSet(
406
0
        const GrVkDescriptorSetManager::Handle& handle) {
407
0
    SkASSERT(handle.isValid());
408
0
    return fDescriptorSetManagers[handle.toIndex()]->getDescriptorSet(fGpu, handle);
409
0
}
Unexecuted instantiation: GrVkResourceProvider::getSamplerDescriptorSet(GrResourceHandle<GrVkDescriptorSetManager::HandleKind> const&)
Unexecuted instantiation: GrVkResourceProvider::getSamplerDescriptorSet(GrResourceHandle<GrVkDescriptorSetManager::HandleKind> const&)
410
411
void GrVkResourceProvider::recycleDescriptorSet(const GrVkDescriptorSet* descSet,
412
0
                                                const GrVkDescriptorSetManager::Handle& handle) {
413
0
    SkASSERT(descSet);
414
0
    SkASSERT(handle.isValid());
415
0
    int managerIdx = handle.toIndex();
416
0
    SkASSERT(managerIdx < fDescriptorSetManagers.size());
417
0
    fDescriptorSetManagers[managerIdx]->recycleDescriptorSet(descSet);
418
0
}
Unexecuted instantiation: GrVkResourceProvider::recycleDescriptorSet(GrVkDescriptorSet const*, GrResourceHandle<GrVkDescriptorSetManager::HandleKind> const&)
Unexecuted instantiation: GrVkResourceProvider::recycleDescriptorSet(GrVkDescriptorSet const*, GrResourceHandle<GrVkDescriptorSetManager::HandleKind> const&)
419
420
0
GrVkCommandPool* GrVkResourceProvider::findOrCreateCommandPool() {
421
0
    GrVkCommandPool* result;
422
0
    if (!fAvailableCommandPools.empty()) {
423
0
        result = fAvailableCommandPools.back();
424
0
        fAvailableCommandPools.pop_back();
425
0
    } else {
426
0
        result = GrVkCommandPool::Create(fGpu);
427
0
        if (!result) {
428
0
            return nullptr;
429
0
        }
430
0
    }
431
0
    SkASSERT(result->unique());
432
0
    SkDEBUGCODE(
433
0
        for (const GrVkCommandPool* pool : fActiveCommandPools) {
434
0
            SkASSERT(pool != result);
435
0
        }
436
0
        for (const GrVkCommandPool* pool : fAvailableCommandPools) {
437
0
            SkASSERT(pool != result);
438
0
        }
439
0
    )
440
0
    fActiveCommandPools.push_back(result);
441
0
    result->ref();
442
0
    return result;
443
0
}
Unexecuted instantiation: GrVkResourceProvider::findOrCreateCommandPool()
Unexecuted instantiation: GrVkResourceProvider::findOrCreateCommandPool()
444
445
0
void GrVkResourceProvider::checkCommandBuffers() {
446
    // When resetting a command buffer it can trigger client provided procs (e.g. release or
447
    // finished) to be called. During these calls the client could trigger us to abandon the vk
448
    // context, e.g. if we are in a DEVICE_LOST state. When we abandon the vk context we will
449
    // unref all the fActiveCommandPools and reset the array. Since this can happen in the middle
450
    // of the loop here, we need to additionally check that fActiveCommandPools still has pools on
451
    // each iteration.
452
    //
453
    // TODO: We really need to have a more robust way to protect us from client proc calls that
454
    // happen in the middle of us doing work. This may be just one of many potential pitfalls that
455
    // could happen from the client triggering GrDirectContext changes during a proc call.
456
0
    for (int i = fActiveCommandPools.size() - 1; !fActiveCommandPools.empty() && i >= 0; --i) {
457
0
        GrVkCommandPool* pool = fActiveCommandPools[i];
458
0
        if (!pool->isOpen()) {
459
0
            GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
460
0
            if (buffer->finished(fGpu)) {
461
0
                fActiveCommandPools.removeShuffle(i);
462
0
                SkASSERT(pool->unique());
463
0
                pool->reset(fGpu);
464
                // After resetting the pool (specifically releasing the pool's resources) we may
465
                // have called a client callback proc which may have disconnected the GrVkGpu. In
466
                // that case we do not want to push the pool back onto the cache, but instead just
467
                // drop the pool.
468
0
                if (fGpu->disconnected()) {
469
0
                    pool->unref();
470
0
                    return;
471
0
                }
472
0
                fAvailableCommandPools.push_back(pool);
473
0
            }
474
0
        }
475
0
    }
476
0
}
Unexecuted instantiation: GrVkResourceProvider::checkCommandBuffers()
Unexecuted instantiation: GrVkResourceProvider::checkCommandBuffers()
477
478
0
void GrVkResourceProvider::forceSyncAllCommandBuffers() {
479
0
    for (int i = fActiveCommandPools.size() - 1; !fActiveCommandPools.empty() && i >= 0; --i) {
480
0
        GrVkCommandPool* pool = fActiveCommandPools[i];
481
0
        if (!pool->isOpen()) {
482
0
            GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
483
0
            buffer->forceSync(fGpu);
484
0
        }
485
0
    }
486
0
}
487
488
void GrVkResourceProvider::addFinishedProcToActiveCommandBuffers(
489
0
        sk_sp<skgpu::RefCntedCallback> finishedCallback) {
490
0
    for (int i = 0; i < fActiveCommandPools.size(); ++i) {
491
0
        GrVkCommandPool* pool = fActiveCommandPools[i];
492
0
        GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
493
0
        buffer->addFinishedProc(finishedCallback);
494
0
    }
495
0
}
496
497
0
void GrVkResourceProvider::destroyResources() {
498
0
    SkTaskGroup* taskGroup = fGpu->getContext()->priv().getTaskGroup();
499
0
    if (taskGroup) {
500
0
        taskGroup->wait();
501
0
    }
502
503
    // Release all msaa load pipelines
504
0
    fMSAALoadPipelines.clear();
505
506
    // loop over all render pass sets to make sure we destroy all the internal VkRenderPasses
507
0
    for (int i = 0; i < fRenderPassArray.size(); ++i) {
508
0
        fRenderPassArray[i].releaseResources();
509
0
    }
510
0
    fRenderPassArray.clear();
511
512
0
    for (int i = 0; i < fExternalRenderPasses.size(); ++i) {
513
0
        fExternalRenderPasses[i]->unref();
514
0
    }
515
0
    fExternalRenderPasses.clear();
516
517
    // Iterate through all store GrVkSamplers and unref them before resetting the hash table.
518
0
    fSamplers.foreach([&](auto* elt) { elt->unref(); });
519
0
    fSamplers.reset();
520
521
0
    fYcbcrConversions.foreach([&](auto* elt) { elt->unref(); });
522
0
    fYcbcrConversions.reset();
523
524
0
    fPipelineStateCache->release();
525
526
0
    GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineCache(fGpu->device(), fPipelineCache, nullptr));
527
0
    fPipelineCache = VK_NULL_HANDLE;
528
529
0
    for (GrVkCommandPool* pool : fActiveCommandPools) {
530
0
        SkASSERT(pool->unique());
531
0
        pool->unref();
532
0
    }
533
0
    fActiveCommandPools.clear();
534
535
0
    for (GrVkCommandPool* pool : fAvailableCommandPools) {
536
0
        SkASSERT(pool->unique());
537
0
        pool->unref();
538
0
    }
539
0
    fAvailableCommandPools.clear();
540
541
    // We must release/destroy all command buffers and pipeline states before releasing the
542
    // GrVkDescriptorSetManagers. Additionally, we must release all uniform buffers since they hold
543
    // refs to GrVkDescriptorSets.
544
0
    for (int i = 0; i < fDescriptorSetManagers.size(); ++i) {
545
0
        fDescriptorSetManagers[i]->release(fGpu);
546
0
    }
547
0
    fDescriptorSetManagers.clear();
548
549
0
}
Unexecuted instantiation: GrVkResourceProvider::destroyResources()
Unexecuted instantiation: GrVkResourceProvider::destroyResources()
550
551
0
void GrVkResourceProvider::releaseUnlockedBackendObjects() {
552
0
    for (GrVkCommandPool* pool : fAvailableCommandPools) {
553
0
        SkASSERT(pool->unique());
554
0
        pool->unref();
555
0
    }
556
0
    fAvailableCommandPools.clear();
557
0
}
Unexecuted instantiation: GrVkResourceProvider::releaseUnlockedBackendObjects()
Unexecuted instantiation: GrVkResourceProvider::releaseUnlockedBackendObjects()
558
559
0
void GrVkResourceProvider::storePipelineCacheData(size_t maxSize) {
560
0
    if (this->pipelineCache() == VK_NULL_HANDLE) {
561
0
        return;
562
0
    }
563
0
    size_t dataSize = 0;
564
0
    VkResult result;
565
0
    GR_VK_CALL_RESULT(fGpu, result, GetPipelineCacheData(fGpu->device(), this->pipelineCache(),
566
0
                                                         &dataSize, nullptr));
567
0
    if (result != VK_SUCCESS) {
568
0
        return;
569
0
    }
570
571
0
    dataSize = std::min(dataSize, maxSize);
572
573
0
    std::unique_ptr<uint8_t[]> data(new uint8_t[dataSize]);
574
575
0
    GR_VK_CALL_RESULT_NOCHECK(
576
0
            fGpu,
577
0
            result,
578
0
            GetPipelineCacheData(
579
0
                    fGpu->device(), this->pipelineCache(), &dataSize, (void*)data.get()));
580
0
    fGpu->checkVkResult(result);
581
0
    if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) {
582
0
        SkDebugf("%s: vkGetPipelineCacheData: failed vulkan call (%d)", __func__, result);
583
0
        return;
584
0
    }
585
586
0
    uint32_t key = GrVkGpu::kPipelineCache_PersistentCacheKeyType;
587
0
    sk_sp<SkData> keyData = SkData::MakeWithoutCopy(&key, sizeof(uint32_t));
588
589
0
    fGpu->getContext()->priv().getPersistentCache()->store(
590
0
            *keyData, *SkData::MakeWithoutCopy(data.get(), dataSize), SkString("VkPipelineCache"));
591
0
}
Unexecuted instantiation: GrVkResourceProvider::storePipelineCacheData(unsigned long)
Unexecuted instantiation: GrVkResourceProvider::storePipelineCacheData(unsigned long)
592
593
////////////////////////////////////////////////////////////////////////////////
594
595
GrVkResourceProvider::CompatibleRenderPassSet::CompatibleRenderPassSet(GrVkRenderPass* renderPass)
596
0
        : fLastReturnedIndex(0) {
597
0
    renderPass->ref();
598
0
    fRenderPasses.push_back(renderPass);
599
0
}
600
601
bool GrVkResourceProvider::CompatibleRenderPassSet::isCompatible(
602
        const GrVkRenderPass::AttachmentsDescriptor& attachmentsDescriptor,
603
        GrVkRenderPass::AttachmentFlags attachmentFlags,
604
        SelfDependencyFlags selfDepFlags,
605
0
        LoadFromResolve loadFromResolve) const {
606
    // The first GrVkRenderpass should always exists since we create the basic load store
607
    // render pass on create
608
0
    SkASSERT(fRenderPasses[0]);
609
0
    return fRenderPasses[0]->isCompatible(attachmentsDescriptor, attachmentFlags, selfDepFlags,
610
0
                                          loadFromResolve);
611
0
}
Unexecuted instantiation: GrVkResourceProvider::CompatibleRenderPassSet::isCompatible(GrVkRenderPass::AttachmentsDescriptor const&, GrVkRenderPass::AttachmentFlags, GrVkRenderPass::SelfDependencyFlags, GrVkRenderPass::LoadFromResolve) const
Unexecuted instantiation: GrVkResourceProvider::CompatibleRenderPassSet::isCompatible(GrVkRenderPass::AttachmentsDescriptor const&, GrVkRenderPass::AttachmentFlags, GrVkRenderPass::SelfDependencyFlags, GrVkRenderPass::LoadFromResolve) const
612
613
GrVkRenderPass* GrVkResourceProvider::CompatibleRenderPassSet::getRenderPass(
614
        GrVkGpu* gpu,
615
        const GrVkRenderPass::LoadStoreOps& colorOps,
616
        const GrVkRenderPass::LoadStoreOps& resolveOps,
617
0
        const GrVkRenderPass::LoadStoreOps& stencilOps) {
618
0
    for (int i = 0; i < fRenderPasses.size(); ++i) {
619
0
        int idx = (i + fLastReturnedIndex) % fRenderPasses.size();
620
0
        if (fRenderPasses[idx]->equalLoadStoreOps(colorOps, resolveOps, stencilOps)) {
621
0
            fLastReturnedIndex = idx;
622
0
            return fRenderPasses[idx];
623
0
        }
624
0
    }
625
0
    GrVkRenderPass* renderPass = GrVkRenderPass::Create(gpu, *this->getCompatibleRenderPass(),
626
0
                                                        colorOps, resolveOps, stencilOps);
627
0
    if (!renderPass) {
628
0
        return nullptr;
629
0
    }
630
0
    fRenderPasses.push_back(renderPass);
631
0
    fLastReturnedIndex = fRenderPasses.size() - 1;
632
0
    return renderPass;
633
0
}
634
635
0
void GrVkResourceProvider::CompatibleRenderPassSet::releaseResources() {
636
0
    for (int i = 0; i < fRenderPasses.size(); ++i) {
637
0
        if (fRenderPasses[i]) {
638
0
            fRenderPasses[i]->unref();
639
0
            fRenderPasses[i] = nullptr;
640
0
        }
641
0
    }
642
0
}
643