1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef VULKAN_NODE_CONTEXT_DESCRIPTOR_SET_MANAGER_VK_H 17 #define VULKAN_NODE_CONTEXT_DESCRIPTOR_SET_MANAGER_VK_H 18 19 #include <cstdint> 20 #include <vulkan/vulkan_core.h> 21 22 #include <base/containers/array_view.h> 23 #include <base/containers/string.h> 24 #include <base/containers/vector.h> 25 #include <render/namespace.h> 26 #include <render/resource_handle.h> 27 28 #include "device/gpu_resource_handle_util.h" 29 #include "nodecontext/node_context_descriptor_set_manager.h" 30 31 RENDER_BEGIN_NAMESPACE() 32 struct RenderPassBeginInfo; 33 class GpuResourceManager; 34 35 struct LowLevelDescriptorSetVk { 36 VkDescriptorSet descriptorSet { VK_NULL_HANDLE }; 37 // NOTE: descriptorSetLayout could be only one for buffering descriptor sets 38 VkDescriptorSetLayout descriptorSetLayout { VK_NULL_HANDLE }; 39 40 enum DescriptorSetLayoutFlagBits : uint32_t { 41 // immutable samplers bound in to the set (atm used only for ycbcr conversions which might need new psos) 42 DESCRIPTOR_SET_LAYOUT_IMMUTABLE_SAMPLER_BIT = 0x00000001, 43 }; 44 uint32_t flags { 0u }; 45 // has a bit set for the ones in 16 bindings that have immutable sampler 46 uint16_t immutableSamplerBitmask { 0u }; 47 }; 48 49 struct LowLevelContextDescriptorPoolVk { 50 // buffering count of 3 (max) is used often with vulkan triple buffering 51 // gets the real used buffering count from the device 52 static constexpr uint32_t MAX_BUFFERING_COUNT { 3u }; 53 54 VkDescriptorPool descriptorPool { VK_NULL_HANDLE }; 55 // additional descriptor pool for one frame descriptor sets with platform buffer bindings 56 // reset and reserved every frame if needed, does not live through frames 57 VkDescriptorPool additionalPlatformDescriptorPool { VK_NULL_HANDLE }; 58 59 struct DescriptorSetData { 60 LowLevelDescriptorCounts descriptorCounts; 61 // indexed with frame buffering index 62 LowLevelDescriptorSetVk bufferingSet[MAX_BUFFERING_COUNT]; 63 64 // additional platform set used in case there are 65 // e.g. ycbcr hwbufferw with immutable samplers and sampler conversion 66 // one might change between normal combined_image_sampler every frame 67 // these do not override the bufferingSet 68 LowLevelDescriptorSetVk additionalPlatformSet; 69 }; 70 BASE_NS::vector<DescriptorSetData> descriptorSets; 71 }; 72 73 struct LowLevelContextDescriptorWriteDataVk { 74 BASE_NS::vector<VkWriteDescriptorSet> writeDescriptorSets; 75 BASE_NS::vector<VkDescriptorBufferInfo> descriptorBufferInfos; 76 BASE_NS::vector<VkDescriptorImageInfo> descriptorImageInfos; 77 BASE_NS::vector<VkDescriptorImageInfo> descriptorSamplerInfos; 78 #if (RENDER_VULKAN_RT_ENABLED == 1) 79 BASE_NS::vector<VkWriteDescriptorSetAccelerationStructureKHR> descriptorAccelInfos; 80 #endif 81 82 uint32_t writeBindingCount { 0U }; 83 uint32_t bufferBindingCount { 0U }; 84 uint32_t imageBindingCount { 0U }; 85 uint32_t samplerBindingCount { 0U }; 86 ClearLowLevelContextDescriptorWriteDataVk87 void Clear() 88 { 89 writeBindingCount = 0U; 90 bufferBindingCount = 0U; 91 imageBindingCount = 0U; 92 samplerBindingCount = 0U; 93 94 writeDescriptorSets.clear(); 95 descriptorBufferInfos.clear(); 96 descriptorImageInfos.clear(); 97 descriptorSamplerInfos.clear(); 98 #if (RENDER_VULKAN_RT_ENABLED == 1) 99 descriptorAccelInfos.clear(); 100 #endif 101 } 102 }; 103 104 struct PendingDeallocations { 105 uint64_t frameIndex { 0 }; 106 LowLevelContextDescriptorPoolVk descriptorPool; 107 }; 108 109 struct OneFrameDescriptorNeed { 110 static constexpr uint32_t DESCRIPTOR_ARRAY_SIZE = CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1; 111 uint8_t descriptorCount[DESCRIPTOR_ARRAY_SIZE] { 0 }; 112 }; 113 114 class DescriptorSetManagerVk final : public DescriptorSetManager { 115 public: 116 explicit DescriptorSetManagerVk(Device& device); 117 ~DescriptorSetManagerVk() override; 118 119 void BeginFrame() override; 120 void BeginBackendFrame(); 121 122 void CreateDescriptorSets(const uint32_t arrayIndex, const uint32_t descriptorSetCount, 123 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override; 124 void UpdateDescriptorSetGpuHandle(const RenderHandle& handle) override; 125 void UpdateCpuDescriptorSetPlatform(const DescriptorSetLayoutBindingResources& bindingResources) override; 126 127 const LowLevelDescriptorSetVk* GetDescriptorSet(const RenderHandle& handle) const; 128 LowLevelContextDescriptorWriteDataVk& GetLowLevelDescriptorWriteData(); 129 130 private: 131 VkDevice vkDevice_; 132 133 void ResizeDescriptorSetWriteData(); 134 135 BASE_NS::vector<PendingDeallocations> pendingDeallocations_; 136 137 uint32_t bufferingCount_ { LowLevelContextDescriptorPoolVk::MAX_BUFFERING_COUNT }; 138 139 BASE_NS::vector<LowLevelContextDescriptorPoolVk> lowLevelDescriptorPools_; 140 141 // use same vector, so we do not re-create the same with every reset 142 // the memory allocation is small 143 BASE_NS::vector<VkDescriptorPoolSize> descriptorPoolSizes_; 144 145 // needs to be locked 146 LowLevelContextDescriptorWriteDataVk lowLevelDescriptorWriteData_; 147 }; 148 149 class NodeContextDescriptorSetManagerVk final : public NodeContextDescriptorSetManager { 150 public: 151 explicit NodeContextDescriptorSetManagerVk(Device& device); 152 ~NodeContextDescriptorSetManagerVk() override; 153 154 void ResetAndReserve(const DescriptorCounts& descriptorCounts) override; 155 void BeginFrame() override; 156 // Call when starting processing this node context. Creates one frame descriptor pool. 157 void BeginBackendFrame(); 158 159 RenderHandle CreateDescriptorSet( 160 BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override; 161 RenderHandle CreateOneFrameDescriptorSet( 162 BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override; 163 164 const LowLevelDescriptorSetVk* GetDescriptorSet(RenderHandle handle) const; 165 LowLevelContextDescriptorWriteDataVk& GetLowLevelDescriptorWriteData(); 166 167 // deferred gpu descriptor set creation happens here 168 void UpdateDescriptorSetGpuHandle(RenderHandle handle) override; 169 void UpdateCpuDescriptorSetPlatform(const DescriptorSetLayoutBindingResources& bindingResources) override; 170 171 private: 172 Device& device_; 173 VkDevice vkDevice_; 174 175 void ClearDescriptorSetWriteData(); 176 void ResizeDescriptorSetWriteData(); 177 178 uint32_t bufferingCount_ { 0 }; 179 LowLevelContextDescriptorPoolVk descriptorPool_[DESCRIPTOR_SET_INDEX_TYPE_COUNT]; 180 181 BASE_NS::vector<PendingDeallocations> pendingDeallocations_; 182 183 OneFrameDescriptorNeed oneFrameDescriptorNeed_; 184 185 // use same vector, so we do not re-create the same with every reset 186 // the memory allocation is small 187 BASE_NS::vector<VkDescriptorPoolSize> descriptorPoolSizes_; 188 189 LowLevelContextDescriptorWriteDataVk lowLevelDescriptorWriteData_; 190 191 uint32_t oneFrameDescSetGeneration_ { 0u }; 192 193 #if (RENDER_VALIDATION_ENABLED == 1) 194 static constexpr uint32_t MAX_ONE_FRAME_GENERATION_IDX { 16u }; 195 #endif 196 }; 197 RENDER_END_NAMESPACE() 198 199 #endif // VULKAN_NODE_CONTEXT_DESCRIPTOR_SET_MANAGER_VK_H 200