• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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