1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci* Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci*
4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci* found in the LICENSE file.
6cb93a386Sopenharmony_ci*/
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkDescriptorSetManager.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkDescriptorPool.h"
11cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkDescriptorSet.h"
12cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h"
13cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUniformHandler.h"
14cb93a386Sopenharmony_ci
15cb93a386Sopenharmony_ci#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
16cb93a386Sopenharmony_ci#include <sanitizer/lsan_interface.h>
17cb93a386Sopenharmony_ci#endif
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ciGrVkDescriptorSetManager* GrVkDescriptorSetManager::CreateUniformManager(GrVkGpu* gpu) {
20cb93a386Sopenharmony_ci    SkSTArray<1, uint32_t> visibilities;
21cb93a386Sopenharmony_ci    uint32_t stages = kVertex_GrShaderFlag | kFragment_GrShaderFlag;
22cb93a386Sopenharmony_ci    visibilities.push_back(stages);
23cb93a386Sopenharmony_ci    SkTArray<const GrVkSampler*> samplers;
24cb93a386Sopenharmony_ci    return Create(gpu, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, visibilities, samplers);
25cb93a386Sopenharmony_ci}
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_ciGrVkDescriptorSetManager* GrVkDescriptorSetManager::CreateSamplerManager(
28cb93a386Sopenharmony_ci        GrVkGpu* gpu, VkDescriptorType type, const GrVkUniformHandler& uniformHandler) {
29cb93a386Sopenharmony_ci    SkSTArray<4, uint32_t> visibilities;
30cb93a386Sopenharmony_ci    SkSTArray<4, const GrVkSampler*> immutableSamplers;
31cb93a386Sopenharmony_ci    SkASSERT(type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
32cb93a386Sopenharmony_ci    for (int i = 0 ; i < uniformHandler.numSamplers(); ++i) {
33cb93a386Sopenharmony_ci        visibilities.push_back(uniformHandler.samplerVisibility(i));
34cb93a386Sopenharmony_ci        immutableSamplers.push_back(uniformHandler.immutableSampler(i));
35cb93a386Sopenharmony_ci    }
36cb93a386Sopenharmony_ci    return Create(gpu, type, visibilities, immutableSamplers);
37cb93a386Sopenharmony_ci}
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ciGrVkDescriptorSetManager* GrVkDescriptorSetManager::CreateZeroSamplerManager(GrVkGpu* gpu) {
40cb93a386Sopenharmony_ci    SkTArray<uint32_t> visibilities;
41cb93a386Sopenharmony_ci    SkTArray<const GrVkSampler*> immutableSamplers;
42cb93a386Sopenharmony_ci    return Create(gpu, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, visibilities, immutableSamplers);
43cb93a386Sopenharmony_ci}
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ciGrVkDescriptorSetManager* GrVkDescriptorSetManager::CreateInputManager(GrVkGpu* gpu) {
46cb93a386Sopenharmony_ci    SkSTArray<1, uint32_t> visibilities;
47cb93a386Sopenharmony_ci    visibilities.push_back(kFragment_GrShaderFlag);
48cb93a386Sopenharmony_ci    SkTArray<const GrVkSampler*> samplers;
49cb93a386Sopenharmony_ci    return Create(gpu, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, visibilities, samplers);
50cb93a386Sopenharmony_ci}
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ciVkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) {
53cb93a386Sopenharmony_ci    VkShaderStageFlags flags = 0;
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_ci    if (visibility & kVertex_GrShaderFlag) {
56cb93a386Sopenharmony_ci        flags |= VK_SHADER_STAGE_VERTEX_BIT;
57cb93a386Sopenharmony_ci    }
58cb93a386Sopenharmony_ci    if (visibility & kFragment_GrShaderFlag) {
59cb93a386Sopenharmony_ci        flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
60cb93a386Sopenharmony_ci    }
61cb93a386Sopenharmony_ci    return flags;
62cb93a386Sopenharmony_ci}
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_cistatic bool get_layout_and_desc_count(GrVkGpu* gpu,
65cb93a386Sopenharmony_ci                                      VkDescriptorType type,
66cb93a386Sopenharmony_ci                                      const SkTArray<uint32_t>& visibilities,
67cb93a386Sopenharmony_ci                                      const SkTArray<const GrVkSampler*>& immutableSamplers,
68cb93a386Sopenharmony_ci                                      VkDescriptorSetLayout* descSetLayout,
69cb93a386Sopenharmony_ci                                      uint32_t* descCountPerSet) {
70cb93a386Sopenharmony_ci    if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type ||
71cb93a386Sopenharmony_ci        VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type) {
72cb93a386Sopenharmony_ci        uint32_t numBindings = visibilities.count();
73cb93a386Sopenharmony_ci        std::unique_ptr<VkDescriptorSetLayoutBinding[]> dsSamplerBindings(
74cb93a386Sopenharmony_ci                new VkDescriptorSetLayoutBinding[numBindings]);
75cb93a386Sopenharmony_ci        *descCountPerSet = 0;
76cb93a386Sopenharmony_ci        for (uint32_t i = 0; i < numBindings; ++i) {
77cb93a386Sopenharmony_ci            uint32_t visibility = visibilities[i];
78cb93a386Sopenharmony_ci            dsSamplerBindings[i].binding = i;
79cb93a386Sopenharmony_ci            dsSamplerBindings[i].descriptorType = type;
80cb93a386Sopenharmony_ci            dsSamplerBindings[i].descriptorCount = 1;
81cb93a386Sopenharmony_ci            dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(visibility);
82cb93a386Sopenharmony_ci            if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type) {
83cb93a386Sopenharmony_ci                if (immutableSamplers[i]) {
84cb93a386Sopenharmony_ci                    (*descCountPerSet) += gpu->vkCaps().ycbcrCombinedImageSamplerDescriptorCount();
85cb93a386Sopenharmony_ci                    dsSamplerBindings[i].pImmutableSamplers = immutableSamplers[i]->samplerPtr();
86cb93a386Sopenharmony_ci                } else {
87cb93a386Sopenharmony_ci                    (*descCountPerSet)++;
88cb93a386Sopenharmony_ci                    dsSamplerBindings[i].pImmutableSamplers = nullptr;
89cb93a386Sopenharmony_ci                }
90cb93a386Sopenharmony_ci            }
91cb93a386Sopenharmony_ci        }
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ci        VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo;
94cb93a386Sopenharmony_ci        memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
95cb93a386Sopenharmony_ci        dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
96cb93a386Sopenharmony_ci        dsSamplerLayoutCreateInfo.pNext = nullptr;
97cb93a386Sopenharmony_ci        dsSamplerLayoutCreateInfo.flags = 0;
98cb93a386Sopenharmony_ci        dsSamplerLayoutCreateInfo.bindingCount = numBindings;
99cb93a386Sopenharmony_ci        // Setting to nullptr fixes an error in the param checker validation layer. Even though
100cb93a386Sopenharmony_ci        // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is
101cb93a386Sopenharmony_ci        // null.
102cb93a386Sopenharmony_ci        dsSamplerLayoutCreateInfo.pBindings = numBindings ? dsSamplerBindings.get() : nullptr;
103cb93a386Sopenharmony_ci
104cb93a386Sopenharmony_ci#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
105cb93a386Sopenharmony_ci        // skia:8713
106cb93a386Sopenharmony_ci        __lsan::ScopedDisabler lsanDisabler;
107cb93a386Sopenharmony_ci#endif
108cb93a386Sopenharmony_ci        VkResult result;
109cb93a386Sopenharmony_ci        GR_VK_CALL_RESULT(gpu, result,
110cb93a386Sopenharmony_ci                          CreateDescriptorSetLayout(gpu->device(),
111cb93a386Sopenharmony_ci                                                    &dsSamplerLayoutCreateInfo,
112cb93a386Sopenharmony_ci                                                    nullptr,
113cb93a386Sopenharmony_ci                                                    descSetLayout));
114cb93a386Sopenharmony_ci        if (result != VK_SUCCESS) {
115cb93a386Sopenharmony_ci            return false;
116cb93a386Sopenharmony_ci        }
117cb93a386Sopenharmony_ci    } else if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
118cb93a386Sopenharmony_ci        static constexpr int kUniformDescPerSet = 1;
119cb93a386Sopenharmony_ci        SkASSERT(kUniformDescPerSet == visibilities.count());
120cb93a386Sopenharmony_ci        // Create Uniform Buffer Descriptor
121cb93a386Sopenharmony_ci        VkDescriptorSetLayoutBinding dsUniBinding;
122cb93a386Sopenharmony_ci        dsUniBinding.binding = GrVkUniformHandler::kUniformBinding;
123cb93a386Sopenharmony_ci        dsUniBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
124cb93a386Sopenharmony_ci        dsUniBinding.descriptorCount = 1;
125cb93a386Sopenharmony_ci        dsUniBinding.stageFlags = visibility_to_vk_stage_flags(visibilities[0]);
126cb93a386Sopenharmony_ci        dsUniBinding.pImmutableSamplers = nullptr;
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ci        VkDescriptorSetLayoutCreateInfo uniformLayoutCreateInfo;
129cb93a386Sopenharmony_ci        uniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
130cb93a386Sopenharmony_ci        uniformLayoutCreateInfo.pNext = nullptr;
131cb93a386Sopenharmony_ci        uniformLayoutCreateInfo.flags = 0;
132cb93a386Sopenharmony_ci        uniformLayoutCreateInfo.bindingCount = 1;
133cb93a386Sopenharmony_ci        uniformLayoutCreateInfo.pBindings = &dsUniBinding;
134cb93a386Sopenharmony_ci
135cb93a386Sopenharmony_ci#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
136cb93a386Sopenharmony_ci        // skia:8713
137cb93a386Sopenharmony_ci        __lsan::ScopedDisabler lsanDisabler;
138cb93a386Sopenharmony_ci#endif
139cb93a386Sopenharmony_ci        VkResult result;
140cb93a386Sopenharmony_ci        GR_VK_CALL_RESULT(gpu, result, CreateDescriptorSetLayout(gpu->device(),
141cb93a386Sopenharmony_ci                                                                 &uniformLayoutCreateInfo,
142cb93a386Sopenharmony_ci                                                                 nullptr,
143cb93a386Sopenharmony_ci                                                                 descSetLayout));
144cb93a386Sopenharmony_ci        if (result != VK_SUCCESS) {
145cb93a386Sopenharmony_ci            return false;
146cb93a386Sopenharmony_ci        }
147cb93a386Sopenharmony_ci
148cb93a386Sopenharmony_ci        *descCountPerSet = kUniformDescPerSet;
149cb93a386Sopenharmony_ci    } else {
150cb93a386Sopenharmony_ci        SkASSERT(type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
151cb93a386Sopenharmony_ci        static constexpr int kInputDescPerSet = 1;
152cb93a386Sopenharmony_ci        SkASSERT(kInputDescPerSet == visibilities.count());
153cb93a386Sopenharmony_ci
154cb93a386Sopenharmony_ci        // Create Input Buffer Descriptor
155cb93a386Sopenharmony_ci        VkDescriptorSetLayoutBinding dsInpuBinding;
156cb93a386Sopenharmony_ci        dsInpuBinding.binding = 0;
157cb93a386Sopenharmony_ci        dsInpuBinding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
158cb93a386Sopenharmony_ci        dsInpuBinding.descriptorCount = 1;
159cb93a386Sopenharmony_ci        SkASSERT(visibilities[0] == kFragment_GrShaderFlag);
160cb93a386Sopenharmony_ci        dsInpuBinding.stageFlags = visibility_to_vk_stage_flags(visibilities[0]);
161cb93a386Sopenharmony_ci        dsInpuBinding.pImmutableSamplers = nullptr;
162cb93a386Sopenharmony_ci
163cb93a386Sopenharmony_ci        VkDescriptorSetLayoutCreateInfo inputLayoutCreateInfo;
164cb93a386Sopenharmony_ci        inputLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
165cb93a386Sopenharmony_ci        inputLayoutCreateInfo.pNext = nullptr;
166cb93a386Sopenharmony_ci        inputLayoutCreateInfo.flags = 0;
167cb93a386Sopenharmony_ci        inputLayoutCreateInfo.bindingCount = 1;
168cb93a386Sopenharmony_ci        inputLayoutCreateInfo.pBindings = &dsInpuBinding;
169cb93a386Sopenharmony_ci
170cb93a386Sopenharmony_ci#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
171cb93a386Sopenharmony_ci        // skia:8713
172cb93a386Sopenharmony_ci        __lsan::ScopedDisabler lsanDisabler;
173cb93a386Sopenharmony_ci#endif
174cb93a386Sopenharmony_ci        VkResult result;
175cb93a386Sopenharmony_ci        GR_VK_CALL_RESULT(gpu, result, CreateDescriptorSetLayout(gpu->device(),
176cb93a386Sopenharmony_ci                                                                 &inputLayoutCreateInfo,
177cb93a386Sopenharmony_ci                                                                 nullptr, descSetLayout));
178cb93a386Sopenharmony_ci        if (result != VK_SUCCESS) {
179cb93a386Sopenharmony_ci            return false;
180cb93a386Sopenharmony_ci        }
181cb93a386Sopenharmony_ci
182cb93a386Sopenharmony_ci        *descCountPerSet = kInputDescPerSet;
183cb93a386Sopenharmony_ci    }
184cb93a386Sopenharmony_ci    return true;
185cb93a386Sopenharmony_ci}
186cb93a386Sopenharmony_ci
187cb93a386Sopenharmony_ciGrVkDescriptorSetManager* GrVkDescriptorSetManager::Create(
188cb93a386Sopenharmony_ci        GrVkGpu* gpu, VkDescriptorType type,
189cb93a386Sopenharmony_ci        const SkTArray<uint32_t>& visibilities,
190cb93a386Sopenharmony_ci        const SkTArray<const GrVkSampler*>& immutableSamplers) {
191cb93a386Sopenharmony_ci#ifdef SK_DEBUG
192cb93a386Sopenharmony_ci    if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
193cb93a386Sopenharmony_ci        SkASSERT(visibilities.count() == immutableSamplers.count());
194cb93a386Sopenharmony_ci    } else {
195cb93a386Sopenharmony_ci        SkASSERT(immutableSamplers.count() == 0);
196cb93a386Sopenharmony_ci    }
197cb93a386Sopenharmony_ci#endif
198cb93a386Sopenharmony_ci
199cb93a386Sopenharmony_ci    VkDescriptorSetLayout descSetLayout;
200cb93a386Sopenharmony_ci    uint32_t descCountPerSet;
201cb93a386Sopenharmony_ci    if (!get_layout_and_desc_count(gpu, type, visibilities, immutableSamplers, &descSetLayout,
202cb93a386Sopenharmony_ci                                   &descCountPerSet)) {
203cb93a386Sopenharmony_ci        return nullptr;
204cb93a386Sopenharmony_ci    }
205cb93a386Sopenharmony_ci    return new GrVkDescriptorSetManager(gpu, type, descSetLayout, descCountPerSet, visibilities,
206cb93a386Sopenharmony_ci                                        immutableSamplers);
207cb93a386Sopenharmony_ci}
208cb93a386Sopenharmony_ci
209cb93a386Sopenharmony_ciGrVkDescriptorSetManager::GrVkDescriptorSetManager(
210cb93a386Sopenharmony_ci        GrVkGpu* gpu, VkDescriptorType type, VkDescriptorSetLayout descSetLayout,
211cb93a386Sopenharmony_ci        uint32_t descCountPerSet, const SkTArray<uint32_t>& visibilities,
212cb93a386Sopenharmony_ci        const SkTArray<const GrVkSampler*>& immutableSamplers)
213cb93a386Sopenharmony_ci    : fPoolManager(descSetLayout, type, descCountPerSet) {
214cb93a386Sopenharmony_ci    for (int i = 0; i < visibilities.count(); ++i) {
215cb93a386Sopenharmony_ci        fBindingVisibilities.push_back(visibilities[i]);
216cb93a386Sopenharmony_ci    }
217cb93a386Sopenharmony_ci    for (int i = 0; i < immutableSamplers.count(); ++i) {
218cb93a386Sopenharmony_ci        const GrVkSampler* sampler = immutableSamplers[i];
219cb93a386Sopenharmony_ci        if (sampler) {
220cb93a386Sopenharmony_ci            sampler->ref();
221cb93a386Sopenharmony_ci        }
222cb93a386Sopenharmony_ci        fImmutableSamplers.push_back(sampler);
223cb93a386Sopenharmony_ci    }
224cb93a386Sopenharmony_ci}
225cb93a386Sopenharmony_ci
226cb93a386Sopenharmony_ciconst GrVkDescriptorSet* GrVkDescriptorSetManager::getDescriptorSet(GrVkGpu* gpu,
227cb93a386Sopenharmony_ci                                                                    const Handle& handle) {
228cb93a386Sopenharmony_ci    const GrVkDescriptorSet* ds = nullptr;
229cb93a386Sopenharmony_ci    int count = fFreeSets.count();
230cb93a386Sopenharmony_ci    if (count > 0) {
231cb93a386Sopenharmony_ci        ds = fFreeSets[count - 1];
232cb93a386Sopenharmony_ci        fFreeSets.removeShuffle(count - 1);
233cb93a386Sopenharmony_ci    } else {
234cb93a386Sopenharmony_ci        VkDescriptorSet vkDS;
235cb93a386Sopenharmony_ci        if (!fPoolManager.getNewDescriptorSet(gpu, &vkDS)) {
236cb93a386Sopenharmony_ci            return nullptr;
237cb93a386Sopenharmony_ci        }
238cb93a386Sopenharmony_ci
239cb93a386Sopenharmony_ci        ds = new GrVkDescriptorSet(gpu, vkDS, fPoolManager.fPool, handle);
240cb93a386Sopenharmony_ci    }
241cb93a386Sopenharmony_ci    SkASSERT(ds);
242cb93a386Sopenharmony_ci    return ds;
243cb93a386Sopenharmony_ci}
244cb93a386Sopenharmony_ci
245cb93a386Sopenharmony_civoid GrVkDescriptorSetManager::recycleDescriptorSet(const GrVkDescriptorSet* descSet) {
246cb93a386Sopenharmony_ci    SkASSERT(descSet);
247cb93a386Sopenharmony_ci    fFreeSets.push_back(descSet);
248cb93a386Sopenharmony_ci}
249cb93a386Sopenharmony_ci
250cb93a386Sopenharmony_civoid GrVkDescriptorSetManager::release(GrVkGpu* gpu) {
251cb93a386Sopenharmony_ci    fPoolManager.freeGPUResources(gpu);
252cb93a386Sopenharmony_ci
253cb93a386Sopenharmony_ci    for (int i = 0; i < fFreeSets.count(); ++i) {
254cb93a386Sopenharmony_ci        fFreeSets[i]->unref();
255cb93a386Sopenharmony_ci    }
256cb93a386Sopenharmony_ci    fFreeSets.reset();
257cb93a386Sopenharmony_ci
258cb93a386Sopenharmony_ci    for (int i = 0; i < fImmutableSamplers.count(); ++i) {
259cb93a386Sopenharmony_ci        if (fImmutableSamplers[i]) {
260cb93a386Sopenharmony_ci            fImmutableSamplers[i]->unref();
261cb93a386Sopenharmony_ci        }
262cb93a386Sopenharmony_ci    }
263cb93a386Sopenharmony_ci    fImmutableSamplers.reset();
264cb93a386Sopenharmony_ci}
265cb93a386Sopenharmony_ci
266cb93a386Sopenharmony_cibool GrVkDescriptorSetManager::isCompatible(VkDescriptorType type,
267cb93a386Sopenharmony_ci                                            const GrVkUniformHandler* uniHandler) const {
268cb93a386Sopenharmony_ci    SkASSERT(uniHandler);
269cb93a386Sopenharmony_ci    if (type != fPoolManager.fDescType) {
270cb93a386Sopenharmony_ci        return false;
271cb93a386Sopenharmony_ci    }
272cb93a386Sopenharmony_ci
273cb93a386Sopenharmony_ci    SkASSERT(type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
274cb93a386Sopenharmony_ci    if (fBindingVisibilities.count() != uniHandler->numSamplers()) {
275cb93a386Sopenharmony_ci        return false;
276cb93a386Sopenharmony_ci    }
277cb93a386Sopenharmony_ci    for (int i = 0; i < uniHandler->numSamplers(); ++i) {
278cb93a386Sopenharmony_ci        if (uniHandler->samplerVisibility(i) != fBindingVisibilities[i] ||
279cb93a386Sopenharmony_ci            uniHandler->immutableSampler(i) != fImmutableSamplers[i]) {
280cb93a386Sopenharmony_ci            return false;
281cb93a386Sopenharmony_ci        }
282cb93a386Sopenharmony_ci    }
283cb93a386Sopenharmony_ci    return true;
284cb93a386Sopenharmony_ci}
285cb93a386Sopenharmony_ci
286cb93a386Sopenharmony_cibool GrVkDescriptorSetManager::isZeroSampler() const {
287cb93a386Sopenharmony_ci    if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER != fPoolManager.fDescType) {
288cb93a386Sopenharmony_ci        return false;
289cb93a386Sopenharmony_ci    }
290cb93a386Sopenharmony_ci    if (fBindingVisibilities.count()) {
291cb93a386Sopenharmony_ci        return false;
292cb93a386Sopenharmony_ci    }
293cb93a386Sopenharmony_ci    return true;
294cb93a386Sopenharmony_ci}
295cb93a386Sopenharmony_ci
296cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////////
297cb93a386Sopenharmony_ci
298cb93a386Sopenharmony_ciGrVkDescriptorSetManager::DescriptorPoolManager::DescriptorPoolManager(
299cb93a386Sopenharmony_ci        VkDescriptorSetLayout layout,
300cb93a386Sopenharmony_ci        VkDescriptorType type,
301cb93a386Sopenharmony_ci        uint32_t descCountPerSet)
302cb93a386Sopenharmony_ci    : fDescLayout(layout)
303cb93a386Sopenharmony_ci    , fDescType(type)
304cb93a386Sopenharmony_ci    , fDescCountPerSet(descCountPerSet)
305cb93a386Sopenharmony_ci    , fMaxDescriptors(kStartNumDescriptors)
306cb93a386Sopenharmony_ci    , fCurrentDescriptorCount(0)
307cb93a386Sopenharmony_ci    , fPool(nullptr) {
308cb93a386Sopenharmony_ci}
309cb93a386Sopenharmony_ci
310cb93a386Sopenharmony_cibool GrVkDescriptorSetManager::DescriptorPoolManager::getNewPool(GrVkGpu* gpu) {
311cb93a386Sopenharmony_ci    if (fPool) {
312cb93a386Sopenharmony_ci        fPool->unref();
313cb93a386Sopenharmony_ci        uint32_t newPoolSize = fMaxDescriptors + ((fMaxDescriptors + 1) >> 1);
314cb93a386Sopenharmony_ci        if (newPoolSize < kMaxDescriptors) {
315cb93a386Sopenharmony_ci            fMaxDescriptors = newPoolSize;
316cb93a386Sopenharmony_ci        } else {
317cb93a386Sopenharmony_ci            fMaxDescriptors = kMaxDescriptors;
318cb93a386Sopenharmony_ci        }
319cb93a386Sopenharmony_ci
320cb93a386Sopenharmony_ci    }
321cb93a386Sopenharmony_ci    fPool = gpu->resourceProvider().findOrCreateCompatibleDescriptorPool(fDescType,
322cb93a386Sopenharmony_ci                                                                         fMaxDescriptors);
323cb93a386Sopenharmony_ci    return SkToBool(fPool);
324cb93a386Sopenharmony_ci}
325cb93a386Sopenharmony_ci
326cb93a386Sopenharmony_cibool GrVkDescriptorSetManager::DescriptorPoolManager::getNewDescriptorSet(GrVkGpu* gpu,
327cb93a386Sopenharmony_ci                                                                          VkDescriptorSet* ds) {
328cb93a386Sopenharmony_ci    if (!fMaxDescriptors) {
329cb93a386Sopenharmony_ci        return false;
330cb93a386Sopenharmony_ci    }
331cb93a386Sopenharmony_ci    fCurrentDescriptorCount += fDescCountPerSet;
332cb93a386Sopenharmony_ci    if (!fPool || fCurrentDescriptorCount > fMaxDescriptors) {
333cb93a386Sopenharmony_ci        if (!this->getNewPool(gpu) ) {
334cb93a386Sopenharmony_ci            return false;
335cb93a386Sopenharmony_ci        }
336cb93a386Sopenharmony_ci        fCurrentDescriptorCount = fDescCountPerSet;
337cb93a386Sopenharmony_ci    }
338cb93a386Sopenharmony_ci
339cb93a386Sopenharmony_ci    VkDescriptorSetAllocateInfo dsAllocateInfo;
340cb93a386Sopenharmony_ci    memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo));
341cb93a386Sopenharmony_ci    dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
342cb93a386Sopenharmony_ci    dsAllocateInfo.pNext = nullptr;
343cb93a386Sopenharmony_ci    dsAllocateInfo.descriptorPool = fPool->descPool();
344cb93a386Sopenharmony_ci    dsAllocateInfo.descriptorSetCount = 1;
345cb93a386Sopenharmony_ci    dsAllocateInfo.pSetLayouts = &fDescLayout;
346cb93a386Sopenharmony_ci    VkResult result;
347cb93a386Sopenharmony_ci    GR_VK_CALL_RESULT(gpu, result, AllocateDescriptorSets(gpu->device(),
348cb93a386Sopenharmony_ci                                                          &dsAllocateInfo,
349cb93a386Sopenharmony_ci                                                          ds));
350cb93a386Sopenharmony_ci    return result == VK_SUCCESS;
351cb93a386Sopenharmony_ci}
352cb93a386Sopenharmony_ci
353cb93a386Sopenharmony_civoid GrVkDescriptorSetManager::DescriptorPoolManager::freeGPUResources(GrVkGpu* gpu) {
354cb93a386Sopenharmony_ci    if (fDescLayout) {
355cb93a386Sopenharmony_ci        GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDescLayout,
356cb93a386Sopenharmony_ci                                                                  nullptr));
357cb93a386Sopenharmony_ci        fDescLayout = VK_NULL_HANDLE;
358cb93a386Sopenharmony_ci    }
359cb93a386Sopenharmony_ci
360cb93a386Sopenharmony_ci    if (fPool) {
361cb93a386Sopenharmony_ci        fPool->unref();
362cb93a386Sopenharmony_ci        fPool = nullptr;
363cb93a386Sopenharmony_ci    }
364cb93a386Sopenharmony_ci}
365cb93a386Sopenharmony_ci
366