1 // Copyright (C) 2021 The Android Open Source Project 2 // Copyright (C) 2021 Google Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 #pragma once 16 17 #include "android/base/containers/EntityManager.h" 18 19 #include <vulkan/vulkan.h> 20 21 #include <unordered_set> 22 #include <vector> 23 24 namespace goldfish_vk { 25 26 enum DescriptorWriteType { 27 Empty = 0, 28 ImageInfo = 1, 29 BufferInfo = 2, 30 BufferView = 3, 31 InlineUniformBlock = 4, 32 AccelerationStructure = 5, 33 }; 34 35 struct DescriptorWrite { 36 DescriptorWriteType type; 37 VkDescriptorType descriptorType; 38 39 uint32_t dstArrayElement; // Only used for inlineUniformBlock and accelerationStructure. 40 41 union { 42 VkDescriptorImageInfo imageInfo; 43 VkDescriptorBufferInfo bufferInfo; 44 VkBufferView bufferView; 45 VkWriteDescriptorSetInlineUniformBlockEXT inlineUniformBlock; 46 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructure; 47 }; 48 49 std::vector<uint8_t> inlineUniformBlockBuffer; 50 }; 51 52 using DescriptorWriteTable = std::vector<std::vector<DescriptorWrite>>; 53 54 struct DescriptorWriteArrayRange { 55 uint32_t begin; 56 uint32_t count; 57 }; 58 59 using DescriptorWriteDstArrayRangeTable = std::vector<std::vector<DescriptorWriteArrayRange>>; 60 61 struct ReifiedDescriptorSet { 62 VkDescriptorPool pool; 63 VkDescriptorSetLayout setLayout; 64 uint64_t poolId; 65 bool allocationPending; 66 67 // Indexed first by binding number 68 DescriptorWriteTable allWrites; 69 70 // Indexed first by binding number 71 DescriptorWriteDstArrayRangeTable pendingWriteArrayRanges; 72 73 // Indexed by binding number 74 std::vector<bool> bindingIsImmutableSampler; 75 76 // Copied from the descriptor set layout 77 std::vector<VkDescriptorSetLayoutBinding> bindings; 78 }; 79 80 struct DescriptorPoolAllocationInfo { 81 VkDevice device; 82 VkDescriptorPoolCreateFlags createFlags; 83 84 // TODO: This should be in a single fancy data structure of some kind. 85 std::vector<uint64_t> freePoolIds; 86 std::unordered_set<uint32_t> allocedPoolIds; 87 std::unordered_set<VkDescriptorSet> allocedSets; 88 uint32_t maxSets; 89 uint32_t usedSets; 90 91 // Fine-grained tracking of descriptor counts in individual pools 92 struct DescriptorCountInfo { 93 VkDescriptorType type; 94 uint32_t descriptorCount; 95 uint32_t used; 96 }; 97 std::vector<DescriptorCountInfo> descriptorCountInfo; 98 }; 99 100 struct DescriptorSetLayoutInfo { 101 std::vector<VkDescriptorSetLayoutBinding> bindings; 102 uint32_t refcount; 103 }; 104 105 void clearReifiedDescriptorSet(ReifiedDescriptorSet* set); 106 107 void initDescriptorWriteTable(const std::vector<VkDescriptorSetLayoutBinding>& layoutBindings, DescriptorWriteTable& table); 108 109 bool isDescriptorTypeImageInfo(VkDescriptorType descType); 110 bool isDescriptorTypeBufferInfo(VkDescriptorType descType); 111 bool isDescriptorTypeBufferView(VkDescriptorType descType); 112 bool isDescriptorTypeInlineUniformBlock(VkDescriptorType descType); 113 bool isDescriptorTypeAccelerationStructure(VkDescriptorType descType); 114 115 void doEmulatedDescriptorWrite(const VkWriteDescriptorSet* write, ReifiedDescriptorSet* toWrite); 116 void doEmulatedDescriptorCopy(const VkCopyDescriptorSet* copy, const ReifiedDescriptorSet* src, ReifiedDescriptorSet* dst); 117 118 void doEmulatedDescriptorImageInfoWriteFromTemplate( 119 VkDescriptorType descType, 120 uint32_t binding, 121 uint32_t dstArrayElement, 122 uint32_t count, 123 const VkDescriptorImageInfo* imageInfos, 124 ReifiedDescriptorSet* set); 125 126 void doEmulatedDescriptorBufferInfoWriteFromTemplate( 127 VkDescriptorType descType, 128 uint32_t binding, 129 uint32_t dstArrayElement, 130 uint32_t count, 131 const VkDescriptorBufferInfo* bufferInfos, 132 ReifiedDescriptorSet* set); 133 134 void doEmulatedDescriptorBufferViewWriteFromTemplate( 135 VkDescriptorType descType, 136 uint32_t binding, 137 uint32_t dstArrayElement, 138 uint32_t count, 139 const VkBufferView* bufferViews, 140 ReifiedDescriptorSet* set); 141 142 void applyDescriptorSetAllocation(VkDescriptorPool pool, VkDescriptorSetLayout setLayout); 143 void fillDescriptorSetInfoForPool(VkDescriptorPool pool, VkDescriptorSetLayout setLayout, VkDescriptorSet set); 144 VkResult validateAndApplyVirtualDescriptorSetAllocation(const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pSets); 145 146 // Returns false if set wasn't found in its pool. 147 bool removeDescriptorSetFromPool(VkDescriptorSet set, bool usePoolIds); 148 149 std::vector<VkDescriptorSet> clearDescriptorPool(VkDescriptorPool pool, bool usePoolIds); 150 151 } // namespace goldfish_vk 152