1 /*
2 * Copyright 2021 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5 #include "DescriptorSetVirtualization.h"
6
7 #include "Resources.h"
8 #include "util/log.h"
9
10 namespace gfxstream {
11 namespace vk {
12
clearReifiedDescriptorSet(ReifiedDescriptorSet * set)13 void clearReifiedDescriptorSet(ReifiedDescriptorSet* set) {
14 set->pool = VK_NULL_HANDLE;
15 set->setLayout = VK_NULL_HANDLE;
16 set->poolId = -1;
17 set->allocationPending = false;
18 set->allWrites.clear();
19 set->pendingWriteArrayRanges.clear();
20 }
21
initDescriptorWriteTable(const std::vector<VkDescriptorSetLayoutBinding> & layoutBindings,DescriptorWriteTable & table)22 void initDescriptorWriteTable(const std::vector<VkDescriptorSetLayoutBinding>& layoutBindings,
23 DescriptorWriteTable& table) {
24 uint32_t highestBindingNumber = 0;
25
26 for (uint32_t i = 0; i < layoutBindings.size(); ++i) {
27 if (layoutBindings[i].binding > highestBindingNumber) {
28 highestBindingNumber = layoutBindings[i].binding;
29 }
30 }
31
32 std::vector<uint32_t> countsEachBinding(highestBindingNumber + 1, 0);
33
34 for (uint32_t i = 0; i < layoutBindings.size(); ++i) {
35 countsEachBinding[layoutBindings[i].binding] = layoutBindings[i].descriptorCount;
36 }
37
38 table.resize(countsEachBinding.size());
39
40 for (uint32_t i = 0; i < table.size(); ++i) {
41 table[i].resize(countsEachBinding[i]);
42
43 for (uint32_t j = 0; j < countsEachBinding[i]; ++j) {
44 table[i][j].type = DescriptorWriteType::Empty;
45 table[i][j].dstArrayElement = 0;
46 }
47 }
48 }
49
initializeReifiedDescriptorSet(VkDescriptorPool pool,VkDescriptorSetLayout setLayout,ReifiedDescriptorSet * set)50 static void initializeReifiedDescriptorSet(VkDescriptorPool pool, VkDescriptorSetLayout setLayout,
51 ReifiedDescriptorSet* set) {
52 set->pendingWriteArrayRanges.clear();
53
54 const auto& layoutInfo = *(as_goldfish_VkDescriptorSetLayout(setLayout)->layoutInfo);
55
56 initDescriptorWriteTable(layoutInfo.bindings, set->allWrites);
57
58 for (size_t i = 0; i < layoutInfo.bindings.size(); ++i) {
59 // Bindings can be sparsely defined
60 const auto& binding = layoutInfo.bindings[i];
61 uint32_t bindingIndex = binding.binding;
62 if (set->bindingIsImmutableSampler.size() <= bindingIndex) {
63 set->bindingIsImmutableSampler.resize(bindingIndex + 1, false);
64 }
65 set->bindingIsImmutableSampler[bindingIndex] =
66 binding.descriptorCount > 0 &&
67 (binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
68 binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
69 binding.pImmutableSamplers;
70 }
71
72 set->pool = pool;
73 set->setLayout = setLayout;
74 set->allocationPending = true;
75 set->bindings = layoutInfo.bindings;
76 }
77
isDescriptorTypeImageInfo(VkDescriptorType descType)78 bool isDescriptorTypeImageInfo(VkDescriptorType descType) {
79 return (descType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
80 (descType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
81 (descType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
82 (descType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
83 (descType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
84 }
85
isDescriptorTypeBufferInfo(VkDescriptorType descType)86 bool isDescriptorTypeBufferInfo(VkDescriptorType descType) {
87 return (descType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
88 (descType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
89 (descType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
90 (descType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
91 }
92
isDescriptorTypeBufferView(VkDescriptorType descType)93 bool isDescriptorTypeBufferView(VkDescriptorType descType) {
94 return (descType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
95 (descType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
96 }
97
isDescriptorTypeInlineUniformBlock(VkDescriptorType descType)98 bool isDescriptorTypeInlineUniformBlock(VkDescriptorType descType) {
99 return descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
100 }
101
isDescriptorTypeAccelerationStructure(VkDescriptorType descType)102 bool isDescriptorTypeAccelerationStructure(VkDescriptorType descType) {
103 return descType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
104 }
105
doEmulatedDescriptorWrite(const VkWriteDescriptorSet * write,ReifiedDescriptorSet * toWrite)106 void doEmulatedDescriptorWrite(const VkWriteDescriptorSet* write, ReifiedDescriptorSet* toWrite) {
107 VkDescriptorType descType = write->descriptorType;
108 uint32_t dstBinding = write->dstBinding;
109 uint32_t dstArrayElement = write->dstArrayElement;
110 uint32_t descriptorCount = write->descriptorCount;
111
112 DescriptorWriteTable& table = toWrite->allWrites;
113
114 uint32_t arrOffset = dstArrayElement;
115
116 if (isDescriptorTypeImageInfo(descType)) {
117 uint32_t i = 0;
118 while (i < descriptorCount) {
119 assert(dstBinding < table.size());
120 if (arrOffset >= table[dstBinding].size()) {
121 ++dstBinding;
122 arrOffset = 0;
123 continue;
124 }
125 auto& entry = table[dstBinding][arrOffset];
126 entry.imageInfo = write->pImageInfo[i];
127 entry.type = DescriptorWriteType::ImageInfo;
128 entry.descriptorType = descType;
129 ++i;
130 ++arrOffset;
131 }
132 } else if (isDescriptorTypeBufferInfo(descType)) {
133 uint32_t i = 0;
134 while (i < descriptorCount) {
135 assert(dstBinding < table.size());
136 if (arrOffset >= table[dstBinding].size()) {
137 ++dstBinding;
138 arrOffset = 0;
139 continue;
140 }
141 auto& entry = table[dstBinding][arrOffset];
142 entry.bufferInfo = write->pBufferInfo[i];
143 entry.type = DescriptorWriteType::BufferInfo;
144 entry.descriptorType = descType;
145 ++i;
146 ++arrOffset;
147 }
148 } else if (isDescriptorTypeBufferView(descType)) {
149 uint32_t i = 0;
150 while (i < descriptorCount) {
151 assert(dstBinding < table.size());
152 if (arrOffset >= table[dstBinding].size()) {
153 ++dstBinding;
154 arrOffset = 0;
155 continue;
156 }
157 auto& entry = table[dstBinding][arrOffset];
158 entry.bufferView = write->pTexelBufferView[i];
159 entry.type = DescriptorWriteType::BufferView;
160 entry.descriptorType = descType;
161 ++i;
162 ++arrOffset;
163 }
164 } else if (isDescriptorTypeInlineUniformBlock(descType)) {
165 const VkWriteDescriptorSetInlineUniformBlock* descInlineUniformBlock =
166 static_cast<const VkWriteDescriptorSetInlineUniformBlock*>(write->pNext);
167 while (descInlineUniformBlock &&
168 descInlineUniformBlock->sType !=
169 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK) {
170 descInlineUniformBlock = static_cast<const VkWriteDescriptorSetInlineUniformBlock*>(
171 descInlineUniformBlock->pNext);
172 }
173 if (!descInlineUniformBlock) {
174 mesa_loge("%s: did not find inline uniform block\n", __func__);
175 return;
176 }
177 auto& entry = table[dstBinding][0];
178 entry.inlineUniformBlock = *descInlineUniformBlock;
179 entry.inlineUniformBlockBuffer.assign(
180 static_cast<const uint8_t*>(descInlineUniformBlock->pData),
181 static_cast<const uint8_t*>(descInlineUniformBlock->pData) +
182 descInlineUniformBlock->dataSize);
183 entry.type = DescriptorWriteType::InlineUniformBlock;
184 entry.descriptorType = descType;
185 entry.dstArrayElement = dstArrayElement;
186 } else if (isDescriptorTypeAccelerationStructure(descType)) {
187 // TODO
188 // Look for pNext inline uniform block or acceleration structure.
189 // Append new DescriptorWrite entry that holds the buffer
190 mesa_logw("%s: Ignoring emulated write for descriptor type 0x%x\n", __func__, descType);
191 }
192 }
193
doEmulatedDescriptorCopy(const VkCopyDescriptorSet * copy,const ReifiedDescriptorSet * src,ReifiedDescriptorSet * dst)194 void doEmulatedDescriptorCopy(const VkCopyDescriptorSet* copy, const ReifiedDescriptorSet* src,
195 ReifiedDescriptorSet* dst) {
196 const DescriptorWriteTable& srcTable = src->allWrites;
197 DescriptorWriteTable& dstTable = dst->allWrites;
198
199 // src/dst may be the same descriptor set, so we need to create a temporary array for that case.
200 // (TODO: Maybe just notice the pointers are the same? can aliasing in any other way happen?)
201
202 std::vector<DescriptorWrite> toCopy;
203 uint32_t currBinding = copy->srcBinding;
204 uint32_t arrOffset = copy->srcArrayElement;
205 uint32_t i = 0;
206 while (i < copy->descriptorCount) {
207 assert(currBinding < srcTable.size());
208 if (arrOffset >= srcTable[currBinding].size()) {
209 ++currBinding;
210 arrOffset = 0;
211 continue;
212 }
213 toCopy.push_back(srcTable[currBinding][arrOffset]);
214 ++i;
215 ++arrOffset;
216 }
217
218 currBinding = copy->dstBinding;
219 arrOffset = copy->dstArrayElement;
220 i = 0;
221 while (i < copy->descriptorCount) {
222 assert(currBinding < dstTable.size());
223 if (arrOffset >= dstTable[currBinding].size()) {
224 ++currBinding;
225 arrOffset = 0;
226 continue;
227 }
228 dstTable[currBinding][arrOffset] = toCopy[i];
229 ++i;
230 ++arrOffset;
231 }
232 }
233
doEmulatedDescriptorImageInfoWriteFromTemplate(VkDescriptorType descType,uint32_t binding,uint32_t dstArrayElement,uint32_t count,const VkDescriptorImageInfo * imageInfos,ReifiedDescriptorSet * set)234 void doEmulatedDescriptorImageInfoWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
235 uint32_t dstArrayElement, uint32_t count,
236 const VkDescriptorImageInfo* imageInfos,
237 ReifiedDescriptorSet* set) {
238 DescriptorWriteTable& table = set->allWrites;
239
240 uint32_t currBinding = binding;
241 uint32_t arrOffset = dstArrayElement;
242 uint32_t i = 0;
243 while (i < count) {
244 assert(currBinding < table.size());
245 if (arrOffset >= table[currBinding].size()) {
246 ++currBinding;
247 arrOffset = 0;
248 continue;
249 }
250 auto& entry = table[currBinding][arrOffset];
251 entry.imageInfo = imageInfos[i];
252 entry.type = DescriptorWriteType::ImageInfo;
253 entry.descriptorType = descType;
254 ++i;
255 ++arrOffset;
256 }
257 }
258
doEmulatedDescriptorBufferInfoWriteFromTemplate(VkDescriptorType descType,uint32_t binding,uint32_t dstArrayElement,uint32_t count,const VkDescriptorBufferInfo * bufferInfos,ReifiedDescriptorSet * set)259 void doEmulatedDescriptorBufferInfoWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
260 uint32_t dstArrayElement, uint32_t count,
261 const VkDescriptorBufferInfo* bufferInfos,
262 ReifiedDescriptorSet* set) {
263 DescriptorWriteTable& table = set->allWrites;
264
265 uint32_t currBinding = binding;
266 uint32_t arrOffset = dstArrayElement;
267 uint32_t i = 0;
268 while (i < count) {
269 assert(currBinding < table.size());
270 if (arrOffset >= table[currBinding].size()) {
271 ++currBinding;
272 arrOffset = 0;
273 continue;
274 }
275 auto& entry = table[currBinding][arrOffset];
276 entry.bufferInfo = bufferInfos[i];
277 entry.type = DescriptorWriteType::BufferInfo;
278 entry.descriptorType = descType;
279 ++i;
280 ++arrOffset;
281 }
282 }
283
doEmulatedDescriptorBufferViewWriteFromTemplate(VkDescriptorType descType,uint32_t binding,uint32_t dstArrayElement,uint32_t count,const VkBufferView * bufferViews,ReifiedDescriptorSet * set)284 void doEmulatedDescriptorBufferViewWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
285 uint32_t dstArrayElement, uint32_t count,
286 const VkBufferView* bufferViews,
287 ReifiedDescriptorSet* set) {
288 DescriptorWriteTable& table = set->allWrites;
289
290 uint32_t currBinding = binding;
291 uint32_t arrOffset = dstArrayElement;
292 uint32_t i = 0;
293 while (i < count) {
294 assert(currBinding < table.size());
295 if (arrOffset >= table[currBinding].size()) {
296 ++currBinding;
297 arrOffset = 0;
298 continue;
299 }
300 auto& entry = table[currBinding][arrOffset];
301 entry.bufferView = bufferViews[i];
302 entry.type = DescriptorWriteType::BufferView;
303 entry.descriptorType = descType;
304 ++i;
305 ++arrOffset;
306 }
307 }
308
doEmulatedDescriptorInlineUniformBlockFromTemplate(VkDescriptorType descType,uint32_t binding,uint32_t dstArrayElement,uint32_t count,const void * pData,ReifiedDescriptorSet * set)309 void doEmulatedDescriptorInlineUniformBlockFromTemplate(VkDescriptorType descType, uint32_t binding,
310 uint32_t dstArrayElement, uint32_t count,
311 const void* pData,
312 ReifiedDescriptorSet* set) {
313 DescriptorWriteTable& table = set->allWrites;
314 auto& entry = table[binding][0];
315 entry.dstArrayElement = dstArrayElement;
316 entry.inlineUniformBlockBuffer.assign(static_cast<const uint8_t*>(pData),
317 static_cast<const uint8_t*>(pData) + count);
318 entry.type = DescriptorWriteType::InlineUniformBlock;
319 entry.descriptorType = descType;
320 }
321
isBindingFeasibleForAlloc(const DescriptorPoolAllocationInfo::DescriptorCountInfo & countInfo,const VkDescriptorSetLayoutBinding & binding)322 static bool isBindingFeasibleForAlloc(
323 const DescriptorPoolAllocationInfo::DescriptorCountInfo& countInfo,
324 const VkDescriptorSetLayoutBinding& binding) {
325 if (binding.descriptorCount && (countInfo.type != binding.descriptorType)) {
326 return false;
327 }
328
329 uint32_t availDescriptorCount = countInfo.descriptorCount - countInfo.used;
330
331 if (availDescriptorCount < binding.descriptorCount) {
332 mesa_logd(
333 "%s: Ran out of descriptors of type 0x%x. "
334 "Wanted %u from layout but "
335 "we only have %u free (total in pool: %u)\n",
336 __func__, binding.descriptorType, binding.descriptorCount,
337 countInfo.descriptorCount - countInfo.used, countInfo.descriptorCount);
338 return false;
339 }
340
341 return true;
342 }
343
isBindingFeasibleForFree(const DescriptorPoolAllocationInfo::DescriptorCountInfo & countInfo,const VkDescriptorSetLayoutBinding & binding)344 static bool isBindingFeasibleForFree(
345 const DescriptorPoolAllocationInfo::DescriptorCountInfo& countInfo,
346 const VkDescriptorSetLayoutBinding& binding) {
347 if (countInfo.type != binding.descriptorType) return false;
348 if (countInfo.used < binding.descriptorCount) {
349 mesa_logd(
350 "%s: Was a descriptor set double freed? "
351 "Ran out of descriptors of type 0x%x. "
352 "Wanted to free %u from layout but "
353 "we only have %u used (total in pool: %u)\n",
354 __func__, binding.descriptorType, binding.descriptorCount, countInfo.used,
355 countInfo.descriptorCount);
356 return false;
357 }
358 return true;
359 }
360
allocBindingFeasible(const VkDescriptorSetLayoutBinding & binding,DescriptorPoolAllocationInfo::DescriptorCountInfo & poolState)361 static void allocBindingFeasible(const VkDescriptorSetLayoutBinding& binding,
362 DescriptorPoolAllocationInfo::DescriptorCountInfo& poolState) {
363 poolState.used += binding.descriptorCount;
364 }
365
freeBindingFeasible(const VkDescriptorSetLayoutBinding & binding,DescriptorPoolAllocationInfo::DescriptorCountInfo & poolState)366 static void freeBindingFeasible(const VkDescriptorSetLayoutBinding& binding,
367 DescriptorPoolAllocationInfo::DescriptorCountInfo& poolState) {
368 poolState.used -= binding.descriptorCount;
369 }
370
validateDescriptorSetAllocation(const VkDescriptorSetAllocateInfo * pAllocateInfo)371 static VkResult validateDescriptorSetAllocation(const VkDescriptorSetAllocateInfo* pAllocateInfo) {
372 VkDescriptorPool pool = pAllocateInfo->descriptorPool;
373 DescriptorPoolAllocationInfo* poolInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
374
375 // Check the number of sets available.
376 auto setsAvailable = poolInfo->maxSets - poolInfo->usedSets;
377
378 if (setsAvailable < pAllocateInfo->descriptorSetCount) {
379 mesa_logd(
380 "%s: Error: VkDescriptorSetAllocateInfo wants %u sets "
381 "but we only have %u available. "
382 "Bailing with VK_ERROR_OUT_OF_POOL_MEMORY.\n",
383 __func__, pAllocateInfo->descriptorSetCount, setsAvailable);
384 return VK_ERROR_OUT_OF_POOL_MEMORY;
385 }
386
387 // Perform simulated allocation and error out with
388 // VK_ERROR_OUT_OF_POOL_MEMORY if it fails.
389 std::vector<DescriptorPoolAllocationInfo::DescriptorCountInfo> descriptorCountCopy =
390 poolInfo->descriptorCountInfo;
391
392 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
393 if (!pAllocateInfo->pSetLayouts[i]) {
394 mesa_logd("%s: Error: Tried to allocate a descriptor set with null set layout.\n",
395 __func__);
396 return VK_ERROR_INITIALIZATION_FAILED;
397 }
398
399 auto setLayoutInfo =
400 as_goldfish_VkDescriptorSetLayout(pAllocateInfo->pSetLayouts[i])->layoutInfo;
401 if (!setLayoutInfo) {
402 return VK_ERROR_INITIALIZATION_FAILED;
403 }
404
405 for (const auto& binding : setLayoutInfo->bindings) {
406 bool success = false;
407 for (auto& pool : descriptorCountCopy) {
408 if (!isBindingFeasibleForAlloc(pool, binding)) continue;
409
410 success = true;
411 allocBindingFeasible(binding, pool);
412 break;
413 }
414
415 if (!success) {
416 return VK_ERROR_OUT_OF_POOL_MEMORY;
417 }
418 }
419 }
420 return VK_SUCCESS;
421 }
422
applyDescriptorSetAllocation(VkDescriptorPool pool,VkDescriptorSetLayout setLayout)423 void applyDescriptorSetAllocation(VkDescriptorPool pool, VkDescriptorSetLayout setLayout) {
424 auto allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
425 auto setLayoutInfo = as_goldfish_VkDescriptorSetLayout(setLayout)->layoutInfo;
426
427 ++allocInfo->usedSets;
428
429 for (const auto& binding : setLayoutInfo->bindings) {
430 for (auto& countForPool : allocInfo->descriptorCountInfo) {
431 if (!isBindingFeasibleForAlloc(countForPool, binding)) continue;
432 allocBindingFeasible(binding, countForPool);
433 break;
434 }
435 }
436 }
437
removeDescriptorSetAllocation(VkDescriptorPool pool,const std::vector<VkDescriptorSetLayoutBinding> & bindings)438 void removeDescriptorSetAllocation(VkDescriptorPool pool,
439 const std::vector<VkDescriptorSetLayoutBinding>& bindings) {
440 auto allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
441
442 if (0 == allocInfo->usedSets) {
443 mesa_logd("%s: Warning: a descriptor set was double freed.\n", __func__);
444 return;
445 }
446
447 --allocInfo->usedSets;
448
449 for (const auto& binding : bindings) {
450 for (auto& countForPool : allocInfo->descriptorCountInfo) {
451 if (!isBindingFeasibleForFree(countForPool, binding)) continue;
452 freeBindingFeasible(binding, countForPool);
453 break;
454 }
455 }
456 }
457
fillDescriptorSetInfoForPool(VkDescriptorPool pool,VkDescriptorSetLayout setLayout,VkDescriptorSet set)458 void fillDescriptorSetInfoForPool(VkDescriptorPool pool, VkDescriptorSetLayout setLayout,
459 VkDescriptorSet set) {
460 DescriptorPoolAllocationInfo* allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
461
462 ReifiedDescriptorSet* newReified = new ReifiedDescriptorSet;
463 newReified->poolId = as_goldfish_VkDescriptorSet(set)->underlying;
464 newReified->allocationPending = true;
465
466 as_goldfish_VkDescriptorSet(set)->reified = newReified;
467
468 allocInfo->allocedPoolIds.insert(newReified->poolId);
469 allocInfo->allocedSets.insert(set);
470
471 initializeReifiedDescriptorSet(pool, setLayout, newReified);
472 }
473
validateAndApplyVirtualDescriptorSetAllocation(const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pSets)474 VkResult validateAndApplyVirtualDescriptorSetAllocation(
475 const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pSets) {
476 VkResult validateRes = validateDescriptorSetAllocation(pAllocateInfo);
477
478 if (validateRes != VK_SUCCESS) return validateRes;
479
480 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
481 applyDescriptorSetAllocation(pAllocateInfo->descriptorPool, pAllocateInfo->pSetLayouts[i]);
482 }
483
484 VkDescriptorPool pool = pAllocateInfo->descriptorPool;
485 DescriptorPoolAllocationInfo* allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
486
487 if (allocInfo->freePoolIds.size() < pAllocateInfo->descriptorSetCount) {
488 mesa_loge(
489 "%s: FATAL: Somehow out of descriptor pool IDs. Wanted %u IDs but only have %u free "
490 "IDs remaining. The count for maxSets was %u and used was %u\n",
491 __func__, pAllocateInfo->descriptorSetCount, (uint32_t)allocInfo->freePoolIds.size(),
492 allocInfo->maxSets, allocInfo->usedSets);
493 abort();
494 }
495
496 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
497 uint64_t id = allocInfo->freePoolIds.back();
498 allocInfo->freePoolIds.pop_back();
499
500 VkDescriptorSet newSet = new_from_host_VkDescriptorSet((VkDescriptorSet)id);
501 pSets[i] = newSet;
502
503 fillDescriptorSetInfoForPool(pool, pAllocateInfo->pSetLayouts[i], newSet);
504 }
505
506 return VK_SUCCESS;
507 }
508
removeDescriptorSetFromPool(VkDescriptorSet set,bool usePoolIds)509 bool removeDescriptorSetFromPool(VkDescriptorSet set, bool usePoolIds) {
510 ReifiedDescriptorSet* reified = as_goldfish_VkDescriptorSet(set)->reified;
511
512 VkDescriptorPool pool = reified->pool;
513 DescriptorPoolAllocationInfo* allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
514
515 if (usePoolIds) {
516 // Look for the set's pool Id in the pool. If not found, then this wasn't really allocated,
517 // and bail.
518 if (allocInfo->allocedPoolIds.find(reified->poolId) == allocInfo->allocedPoolIds.end()) {
519 return false;
520 }
521 }
522
523 const std::vector<VkDescriptorSetLayoutBinding>& bindings = reified->bindings;
524 removeDescriptorSetAllocation(pool, bindings);
525
526 if (usePoolIds) {
527 allocInfo->freePoolIds.push_back(reified->poolId);
528 allocInfo->allocedPoolIds.erase(reified->poolId);
529 }
530 allocInfo->allocedSets.erase(set);
531
532 return true;
533 }
534
clearDescriptorPool(VkDescriptorPool pool,bool usePoolIds)535 std::vector<VkDescriptorSet> clearDescriptorPool(VkDescriptorPool pool, bool usePoolIds) {
536 std::vector<VkDescriptorSet> toClear;
537 for (auto set : as_goldfish_VkDescriptorPool(pool)->allocInfo->allocedSets) {
538 toClear.push_back(set);
539 }
540
541 for (auto set : toClear) {
542 removeDescriptorSetFromPool(set, usePoolIds);
543 }
544
545 return toClear;
546 }
547
548 } // namespace vk
549 } // namespace gfxstream
550