1 /* 2 * Copyright 2021 Google LLC 3 * SPDX-License-Identifier: MIT 4 */ 5 #pragma once 6 7 #include <vulkan/vulkan.h> 8 9 #include <unordered_set> 10 #include <vector> 11 12 namespace gfxstream { 13 namespace vk { 14 15 enum DescriptorWriteType { 16 Empty = 0, 17 ImageInfo = 1, 18 BufferInfo = 2, 19 BufferView = 3, 20 InlineUniformBlock = 4, 21 AccelerationStructure = 5, 22 }; 23 24 struct DescriptorWrite { 25 DescriptorWriteType type; 26 VkDescriptorType descriptorType; 27 28 uint32_t dstArrayElement; // Only used for inlineUniformBlock and accelerationStructure. 29 30 union { 31 VkDescriptorImageInfo imageInfo; 32 VkDescriptorBufferInfo bufferInfo; 33 VkBufferView bufferView; 34 VkWriteDescriptorSetInlineUniformBlockEXT inlineUniformBlock; 35 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructure; 36 }; 37 38 std::vector<uint8_t> inlineUniformBlockBuffer; 39 }; 40 41 using DescriptorWriteTable = std::vector<std::vector<DescriptorWrite>>; 42 43 struct DescriptorWriteArrayRange { 44 uint32_t begin; 45 uint32_t count; 46 }; 47 48 using DescriptorWriteDstArrayRangeTable = std::vector<std::vector<DescriptorWriteArrayRange>>; 49 50 struct ReifiedDescriptorSet { 51 VkDescriptorPool pool; 52 VkDescriptorSetLayout setLayout; 53 uint64_t poolId; 54 bool allocationPending; 55 56 // Indexed first by binding number 57 DescriptorWriteTable allWrites; 58 59 // Indexed first by binding number 60 DescriptorWriteDstArrayRangeTable pendingWriteArrayRanges; 61 62 // Indexed by binding number 63 std::vector<bool> bindingIsImmutableSampler; 64 65 // Copied from the descriptor set layout 66 std::vector<VkDescriptorSetLayoutBinding> bindings; 67 }; 68 69 struct DescriptorPoolAllocationInfo { 70 VkDevice device; 71 VkDescriptorPoolCreateFlags createFlags; 72 73 // TODO: This should be in a single fancy data structure of some kind. 74 std::vector<uint64_t> freePoolIds; 75 std::unordered_set<uint32_t> allocedPoolIds; 76 std::unordered_set<VkDescriptorSet> allocedSets; 77 uint32_t maxSets; 78 uint32_t usedSets; 79 80 // Fine-grained tracking of descriptor counts in individual pools 81 struct DescriptorCountInfo { 82 VkDescriptorType type; 83 uint32_t descriptorCount; 84 uint32_t used; 85 }; 86 std::vector<DescriptorCountInfo> descriptorCountInfo; 87 }; 88 89 struct DescriptorSetLayoutInfo { 90 std::vector<VkDescriptorSetLayoutBinding> bindings; 91 uint32_t refcount; 92 }; 93 94 void clearReifiedDescriptorSet(ReifiedDescriptorSet* set); 95 96 void initDescriptorWriteTable(const std::vector<VkDescriptorSetLayoutBinding>& layoutBindings, 97 DescriptorWriteTable& table); 98 99 bool isDescriptorTypeImageInfo(VkDescriptorType descType); 100 bool isDescriptorTypeBufferInfo(VkDescriptorType descType); 101 bool isDescriptorTypeBufferView(VkDescriptorType descType); 102 bool isDescriptorTypeInlineUniformBlock(VkDescriptorType descType); 103 bool isDescriptorTypeAccelerationStructure(VkDescriptorType descType); 104 105 void doEmulatedDescriptorWrite(const VkWriteDescriptorSet* write, ReifiedDescriptorSet* toWrite); 106 void doEmulatedDescriptorCopy(const VkCopyDescriptorSet* copy, const ReifiedDescriptorSet* src, 107 ReifiedDescriptorSet* dst); 108 109 void doEmulatedDescriptorImageInfoWriteFromTemplate(VkDescriptorType descType, uint32_t binding, 110 uint32_t dstArrayElement, uint32_t count, 111 const VkDescriptorImageInfo* imageInfos, 112 ReifiedDescriptorSet* set); 113 114 void doEmulatedDescriptorBufferInfoWriteFromTemplate(VkDescriptorType descType, uint32_t binding, 115 uint32_t dstArrayElement, uint32_t count, 116 const VkDescriptorBufferInfo* bufferInfos, 117 ReifiedDescriptorSet* set); 118 119 void doEmulatedDescriptorBufferViewWriteFromTemplate(VkDescriptorType descType, uint32_t binding, 120 uint32_t dstArrayElement, uint32_t count, 121 const VkBufferView* bufferViews, 122 ReifiedDescriptorSet* set); 123 124 void doEmulatedDescriptorInlineUniformBlockFromTemplate(VkDescriptorType descType, uint32_t binding, 125 uint32_t dstArrayElement, uint32_t count, 126 const void* pData, 127 ReifiedDescriptorSet* set); 128 129 void applyDescriptorSetAllocation(VkDescriptorPool pool, VkDescriptorSetLayout setLayout); 130 void fillDescriptorSetInfoForPool(VkDescriptorPool pool, VkDescriptorSetLayout setLayout, 131 VkDescriptorSet set); 132 VkResult validateAndApplyVirtualDescriptorSetAllocation( 133 const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pSets); 134 135 // Returns false if set wasn't found in its pool. 136 bool removeDescriptorSetFromPool(VkDescriptorSet set, bool usePoolIds); 137 138 std::vector<VkDescriptorSet> clearDescriptorPool(VkDescriptorPool pool, bool usePoolIds); 139 140 } // namespace vk 141 } // namespace gfxstream 142