1 /* 2 * Copyright (C) 2023 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.h> 21 22 #include <base/containers/array_view.h> 23 #include <base/containers/vector.h> 24 #include <render/namespace.h> 25 #include <render/resource_handle.h> 26 27 #include "device/gpu_resource_handle_util.h" 28 #include "nodecontext/node_context_descriptor_set_manager.h" 29 30 RENDER_BEGIN_NAMESPACE() 31 struct RenderPassBeginInfo; 32 class GpuResourceManager; 33 34 struct LowLevelDescriptorSetVk { 35 VkDescriptorSet descriptorSet { VK_NULL_HANDLE }; 36 // NOTE: descriptorSetLayout could be only one for buffering descriptor sets 37 VkDescriptorSetLayout descriptorSetLayout { VK_NULL_HANDLE }; 38 39 enum DescriptorSetLayoutFlagBits : uint32_t { 40 // immutable samplers bound in to the set (atm used only for ycbcr conversions which might need new psos) 41 DESCRIPTOR_SET_LAYOUT_IMMUTABLE_SAMPLER_BIT = 0x00000001, 42 }; 43 uint32_t flags { 0u }; 44 // has a bit set for the ones in 16 bindings that have immutable sampler 45 uint16_t immutableSamplerBitmask { 0u }; 46 }; 47 48 // storage counts 49 struct LowLevelDescriptorCountsVk { 50 uint32_t writeDescriptorCount { 0u }; 51 uint32_t bufferCount { 0u }; 52 uint32_t imageCount { 0u }; 53 uint32_t samplerCount { 0u }; 54 uint32_t accelCount { 0u }; 55 }; 56 57 struct LowLevelContextDescriptorPoolVk { 58 // buffering count of 3 (max) is used often with vulkan triple buffering 59 // gets the real used buffering count from the device 60 static constexpr uint32_t MAX_BUFFERING_COUNT { 3u }; 61 62 VkDescriptorPool descriptorPool { VK_NULL_HANDLE }; 63 // additional descriptor pool for one frame descriptor sets with platform buffer bindings 64 // reset and reserved every frame if needed, does not live through frames 65 VkDescriptorPool additionalPlatformDescriptorPool { VK_NULL_HANDLE }; 66 67 struct DescriptorSetData { 68 LowLevelDescriptorCountsVk descriptorCounts; 69 // indexed with frame buffering index 70 LowLevelDescriptorSetVk bufferingSet[MAX_BUFFERING_COUNT]; 71 72 // additional platform set used in case there are 73 // e.g. ycbcr hwbufferw with immutable samplers and sampler conversion 74 // one might change between normal combined_image_sampler every frame 75 // these do not override the bufferingSet 76 LowLevelDescriptorSetVk additionalPlatformSet; 77 }; 78 BASE_NS::vector<DescriptorSetData> descriptorSets; 79 }; 80 81 class NodeContextDescriptorSetManagerVk final : public NodeContextDescriptorSetManager { 82 public: 83 explicit NodeContextDescriptorSetManagerVk(Device& device); 84 ~NodeContextDescriptorSetManagerVk(); 85 86 void ResetAndReserve(const DescriptorCounts& descriptorCounts) override; 87 void BeginFrame() override; 88 // Call when starting processing this node context. Creates one frame descriptor pool. 89 void BeginBackendFrame(); 90 91 RenderHandle CreateDescriptorSet( 92 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override; 93 RenderHandle CreateOneFrameDescriptorSet( 94 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override; 95 96 const LowLevelDescriptorCountsVk& GetLowLevelDescriptorCounts(const RenderHandle handle); 97 const LowLevelDescriptorSetVk* GetDescriptorSet(const RenderHandle handle) const; 98 99 // deferred gpu descriptor set creation happens here 100 void UpdateDescriptorSetGpuHandle(const RenderHandle handle) override; 101 102 private: 103 Device& device_; 104 105 void CreateGpuDescriptorSet(const uint32_t bufferCount, const RenderHandle clientHandle, 106 const CpuDescriptorSet& cpuDescriptorSet, LowLevelContextDescriptorPoolVk& descriptorPool); 107 void DestroyPool(LowLevelContextDescriptorPoolVk& descriptorPool); 108 109 uint32_t bufferingCount_ { 0 }; 110 LowLevelContextDescriptorPoolVk descriptorPool_[DESCRIPTOR_SET_INDEX_TYPE_COUNT]; 111 112 struct PendingDeallocations { 113 uint64_t frameIndex { 0 }; 114 LowLevelContextDescriptorPoolVk descriptorPool; 115 }; 116 BASE_NS::vector<PendingDeallocations> pendingDeallocations_; 117 118 struct OneFrameDescriptorNeed { 119 static constexpr uint32_t DESCRIPTOR_ARRAY_SIZE = CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1; 120 uint8_t descriptorCount[DESCRIPTOR_ARRAY_SIZE] { 0 }; 121 }; 122 OneFrameDescriptorNeed oneFrameDescriptorNeed_; 123 124 LowLevelDescriptorCountsVk defaultLowLevelDescriptorSetMemoryStoreVk_; 125 126 // use same vector, so we do not re-create the same with every reset 127 // the memory allocation is small 128 BASE_NS::vector<VkDescriptorPoolSize> descriptorPoolSizes_; 129 130 uint32_t oneFrameDescSetGeneration_ { 0u }; 131 #if (RENDER_VALIDATION_ENABLED == 1) 132 static constexpr uint32_t MAX_ONE_FRAME_GENERATION_IDX { 16u }; 133 #endif 134 }; 135 RENDER_END_NAMESPACE() 136 137 #endif // VULKAN_NODE_CONTEXT_DESCRIPTOR_SET_MANAGER_VK_H 138