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/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 struct LowLevelContextDescriptorWriteDataVk {
82     BASE_NS::vector<VkWriteDescriptorSet> writeDescriptorSets;
83     BASE_NS::vector<VkDescriptorBufferInfo> descriptorBufferInfos;
84     BASE_NS::vector<VkDescriptorImageInfo> descriptorImageInfos;
85     BASE_NS::vector<VkDescriptorImageInfo> descriptorSamplerInfos;
86 #if (RENDER_VULKAN_RT_ENABLED == 1)
87     BASE_NS::vector<VkWriteDescriptorSetAccelerationStructureKHR> descriptorAccelInfos;
88 #endif
89 
90     uint32_t writeBindingCount { 0U };
91     uint32_t bufferBindingCount { 0U };
92     uint32_t imageBindingCount { 0U };
93     uint32_t samplerBindingCount { 0U };
94 
ClearLowLevelContextDescriptorWriteDataVk95     void Clear()
96     {
97         writeBindingCount = 0U;
98         bufferBindingCount = 0U;
99         imageBindingCount = 0U;
100         samplerBindingCount = 0U;
101 
102         writeDescriptorSets.clear();
103         descriptorBufferInfos.clear();
104         descriptorImageInfos.clear();
105         descriptorSamplerInfos.clear();
106 #if (RENDER_VULKAN_RT_ENABLED == 1)
107         descriptorAccelInfos.clear();
108 #endif
109     }
110 };
111 
112 class NodeContextDescriptorSetManagerVk final : public NodeContextDescriptorSetManager {
113 public:
114     explicit NodeContextDescriptorSetManagerVk(Device& device);
115     ~NodeContextDescriptorSetManagerVk();
116 
117     void ResetAndReserve(const DescriptorCounts& descriptorCounts) override;
118     void BeginFrame() override;
119     // Call when starting processing this node context. Creates one frame descriptor pool.
120     void BeginBackendFrame();
121 
122     RenderHandle CreateDescriptorSet(
123         const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override;
124     RenderHandle CreateOneFrameDescriptorSet(
125         const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings) override;
126 
127     const LowLevelDescriptorCountsVk& GetLowLevelDescriptorCounts(const RenderHandle handle);
128     const LowLevelDescriptorSetVk* GetDescriptorSet(const RenderHandle handle) const;
129 
130     LowLevelContextDescriptorWriteDataVk& GetLowLevelDescriptorWriteData();
131 
132     // deferred gpu descriptor set creation happens here
133     void UpdateDescriptorSetGpuHandle(const RenderHandle handle) override;
134     void UpdateCpuDescriptorSetPlatform(const DescriptorSetLayoutBindingResources& bindingResources) override;
135 
136 private:
137     Device& device_;
138 
139     void CreateGpuDescriptorSet(const uint32_t bufferCount, const RenderHandle clientHandle,
140         const CpuDescriptorSet& cpuDescriptorSet, LowLevelContextDescriptorPoolVk& descriptorPool);
141     void DestroyPool(LowLevelContextDescriptorPoolVk& descriptorPool);
142     void ClearDescriptorSetWriteData();
143     void ResizeDescriptorSetWriteData();
144 
145     uint32_t bufferingCount_ { 0 };
146     LowLevelContextDescriptorPoolVk descriptorPool_[DESCRIPTOR_SET_INDEX_TYPE_COUNT];
147 
148     struct PendingDeallocations {
149         uint64_t frameIndex { 0 };
150         LowLevelContextDescriptorPoolVk descriptorPool;
151     };
152     BASE_NS::vector<PendingDeallocations> pendingDeallocations_;
153 
154     struct OneFrameDescriptorNeed {
155         static constexpr uint32_t DESCRIPTOR_ARRAY_SIZE = CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1;
156         uint8_t descriptorCount[DESCRIPTOR_ARRAY_SIZE] { 0 };
157     };
158     OneFrameDescriptorNeed oneFrameDescriptorNeed_;
159 
160     LowLevelDescriptorCountsVk defaultLowLevelDescriptorSetMemoryStoreVk_;
161 
162     // use same vector, so we do not re-create the same with every reset
163     // the memory allocation is small
164     BASE_NS::vector<VkDescriptorPoolSize> descriptorPoolSizes_;
165 
166     LowLevelContextDescriptorWriteDataVk lowLevelDescriptorWriteData_;
167 
168     uint32_t oneFrameDescSetGeneration_ { 0u };
169 #if (RENDER_VALIDATION_ENABLED == 1)
170     static constexpr uint32_t MAX_ONE_FRAME_GENERATION_IDX { 16u };
171 #endif
172 };
173 RENDER_END_NAMESPACE()
174 
175 #endif // VULKAN_NODE_CONTEXT_DESCRIPTOR_SET_MANAGER_VK_H
176