1 /* 2 * Copyright (c) 2022 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 "default_engine_constants.h" 29 #include "device/gpu_resource_handle_util.h" 30 #include "nodecontext/node_context_descriptor_set_manager.h" 31 32 RENDER_BEGIN_NAMESPACE() 33 struct RenderPassBeginInfo; 34 class GpuResourceManager; 35 36 struct LowLevelDescriptorSetVk { 37 VkDescriptorSet descriptorSet { VK_NULL_HANDLE }; 38 // NOTE: descriptorSetLayout could be only one for buffering descriptor sets 39 VkDescriptorSetLayout descriptorSetLayout { VK_NULL_HANDLE }; 40 41 enum DescriptorSetLayoutFlagBits : uint32_t { 42 // immutable samplers bound in to the set (atm used only for ycbcr conversions which might need new psos) 43 DESCRIPTOR_SET_LAYOUT_IMMUTABLE_SAMPLER_BIT = 0x00000001, 44 }; 45 uint32_t flags { 0u }; 46 // has a bit set for the ones in 16 bindings that have immutable sampler 47 uint16_t immutableSamplerBitmask { 0u }; 48 }; 49 50 struct LowLevelContextDescriptorPoolVk { 51 // buffering count of 3 (max) is used often with vulkan triple buffering 52 // gets the real used buffering count from the device 53 static constexpr uint32_t MAX_BUFFERING_COUNT { DeviceConstants::MAX_BUFFERING_COUNT }; 54 55 VkDescriptorPool descriptorPool { VK_NULL_HANDLE }; 56 // additional descriptor pool for one frame descriptor sets with platform buffer bindings 57 // reset and reserved every frame if needed, does not live through frames 58 VkDescriptorPool additionalPlatformDescriptorPool { VK_NULL_HANDLE }; 59 60 struct DescriptorSetData { 61 LowLevelDescriptorCounts descriptorCounts; 62 // indexed with frame buffering index 63 LowLevelDescriptorSetVk bufferingSet[MAX_BUFFERING_COUNT]; 64 65 // additional platform set used in case there are 66 // e.g. ycbcr hwbufferw with immutable samplers and sampler conversion 67 // one might change between normal combined_image_sampler every frame 68 // these do not override the bufferingSet 69 LowLevelDescriptorSetVk additionalPlatformSet; 70 }; 71 BASE_NS::vector<DescriptorSetData> descriptorSets; 72 }; 73 74 struct LowLevelContextDescriptorWriteDataVk { 75 BASE_NS::vector<VkWriteDescriptorSet> writeDescriptorSets; 76 BASE_NS::vector<VkDescriptorBufferInfo> descriptorBufferInfos; 77 BASE_NS::vector<VkDescriptorImageInfo> descriptorImageInfos; 78 BASE_NS::vector<VkDescriptorImageInfo> descriptorSamplerInfos; 79 #if (RENDER_VULKAN_RT_ENABLED == 1) 80 BASE_NS::vector<VkWriteDescriptorSetAccelerationStructureKHR> descriptorAccelInfos; 81 #endif 82 83 uint32_t writeBindingCount { 0U }; 84 uint32_t bufferBindingCount { 0U }; 85 uint32_t imageBindingCount { 0U }; 86 uint32_t samplerBindingCount { 0U }; 87 ClearLowLevelContextDescriptorWriteDataVk88 void Clear() 89 { 90 writeBindingCount = 0U; 91 bufferBindingCount = 0U; 92 imageBindingCount = 0U; 93 samplerBindingCount = 0U; 94 95 writeDescriptorSets.clear(); 96 descriptorBufferInfos.clear(); 97 descriptorImageInfos.clear(); 98 descriptorSamplerInfos.clear(); 99 #if (RENDER_VULKAN_RT_ENABLED == 1) 100 descriptorAccelInfos.clear(); 101 #endif 102 } 103 }; 104 105 struct PendingDeallocations { 106 uint64_t frameIndex { 0 }; 107 LowLevelContextDescriptorPoolVk descriptorPool; 108 }; 109 110 struct OneFrameDescriptorNeed { 111 // the acceleration structure is the eleventh 112 static constexpr uint32_t ACCELERATION_LOCAL_TYPE { 11U }; 113 static constexpr uint32_t DESCRIPTOR_ARRAY_SIZE = CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 2U; 114 uint32_t descriptorCount[DESCRIPTOR_ARRAY_SIZE] { 0 }; 115 }; 116 117 class DescriptorSetManagerVk final : public DescriptorSetManager { 118 public: 119 explicit DescriptorSetManagerVk(Device& device); 120 ~DescriptorSetManagerVk() override; 121 122 void BeginFrame() override; 123 void BeginBackendFrame(); 124 125 void CreateDescriptorSets(const uint32_t arrayIndex, const uint32_t descriptorSetCount, 126 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override; 127 bool UpdateDescriptorSetGpuHandle(const RenderHandle& handle) override; 128 void UpdateCpuDescriptorSetPlatform(const DescriptorSetLayoutBindingResources& bindingResources) override; 129 130 const LowLevelDescriptorSetVk* GetDescriptorSet(const RenderHandle& handle) const; 131 LowLevelContextDescriptorWriteDataVk& GetLowLevelDescriptorWriteData(); 132 133 private: 134 VkDevice vkDevice_; 135 136 void ResizeDescriptorSetWriteData(); 137 138 BASE_NS::vector<PendingDeallocations> pendingDeallocations_; 139 140 uint32_t bufferingCount_ { LowLevelContextDescriptorPoolVk::MAX_BUFFERING_COUNT }; 141 142 BASE_NS::vector<LowLevelContextDescriptorPoolVk> lowLevelDescriptorPools_; 143 144 // use same vector, so we do not re-create the same with every reset 145 // the memory allocation is small 146 BASE_NS::vector<VkDescriptorPoolSize> descriptorPoolSizes_; 147 148 // needs to be locked 149 LowLevelContextDescriptorWriteDataVk lowLevelDescriptorWriteData_; 150 }; 151 152 class NodeContextDescriptorSetManagerVk final : public NodeContextDescriptorSetManager { 153 public: 154 explicit NodeContextDescriptorSetManagerVk(Device& device); 155 ~NodeContextDescriptorSetManagerVk() override; 156 157 void ResetAndReserve(const DescriptorCounts& descriptorCounts) override; 158 void BeginFrame() override; 159 // Call when starting processing this node context. Creates one frame descriptor pool. 160 void BeginBackendFrame(); 161 162 RenderHandle CreateDescriptorSet( 163 BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override; 164 RenderHandle CreateOneFrameDescriptorSet( 165 BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override; 166 167 const LowLevelDescriptorSetVk* GetDescriptorSet(RenderHandle handle) const; 168 LowLevelContextDescriptorWriteDataVk& GetLowLevelDescriptorWriteData(); 169 170 // deferred gpu descriptor set creation happens here 171 bool UpdateDescriptorSetGpuHandle(RenderHandle handle) override; 172 void UpdateCpuDescriptorSetPlatform(const DescriptorSetLayoutBindingResources& bindingResources) override; 173 174 private: 175 Device& device_; 176 VkDevice vkDevice_; 177 178 void ClearDescriptorSetWriteData(); 179 void ResizeDescriptorSetWriteData(); 180 181 uint32_t bufferingCount_ { 0 }; 182 LowLevelContextDescriptorPoolVk descriptorPool_[DESCRIPTOR_SET_INDEX_TYPE_COUNT]; 183 184 BASE_NS::vector<PendingDeallocations> pendingDeallocations_; 185 186 OneFrameDescriptorNeed oneFrameDescriptorNeed_; 187 188 // use same vector, so we do not re-create the same with every reset 189 // the memory allocation is small 190 BASE_NS::vector<VkDescriptorPoolSize> descriptorPoolSizes_; 191 192 LowLevelContextDescriptorWriteDataVk lowLevelDescriptorWriteData_; 193 194 uint32_t oneFrameDescSetGeneration_ { 0u }; 195 196 #if (RENDER_VALIDATION_ENABLED == 1) 197 static constexpr uint32_t MAX_ONE_FRAME_GENERATION_IDX { 16u }; 198 #endif 199 }; 200 RENDER_END_NAMESPACE() 201 202 #endif // VULKAN_NODE_CONTEXT_DESCRIPTOR_SET_MANAGER_VK_H 203