• 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_RENDER_BACKEND_VK_H
17 #define VULKAN_RENDER_BACKEND_VK_H
18 
19 #include <vulkan/vulkan_core.h>
20 
21 #include <base/containers/array_view.h>
22 #include <base/containers/unique_ptr.h>
23 #include <base/containers/unordered_map.h>
24 #include <base/containers/vector.h>
25 #include <core/threading/intf_thread_pool.h>
26 #include <render/namespace.h>
27 
28 #include "nodecontext/render_command_list.h"
29 #include "render_backend.h"
30 #include "vulkan/device_vk.h"
31 #include "vulkan/pipeline_create_functions_vk.h"
32 
33 #if (RENDER_PERF_ENABLED == 1)
34 #include <atomic>
35 
36 #include "device/gpu_buffer.h"
37 #include "perf/cpu_timer.h"
38 #include "perf/gpu_query_manager.h"
39 #endif
40 
41 CORE_BEGIN_NAMESPACE()
42 class IThreadPool;
43 CORE_END_NAMESPACE()
44 RENDER_BEGIN_NAMESPACE()
45 class Device;
46 class DeviceVk;
47 class GpuResourceManager;
48 class NodeContextPsoManager;
49 class NodeContextPoolManager;
50 class RenderBarrierList;
51 class RenderCommandList;
52 struct LowLevelCommandBufferVk;
53 struct RenderCommandContext;
54 
55 struct NodeGraphBackBufferConfiguration;
56 
57 class IRenderBackendNode;
58 
59 struct CommandBufferSubmitter {
60     struct CommandBuffer {
61         VkCommandBuffer commandBuffer { VK_NULL_HANDLE };
62         VkSemaphore semaphore { VK_NULL_HANDLE };
63 
64         // not submitted, executed in primary command buffer
65         VkCommandBuffer secondaryCommandBuffer { VK_NULL_HANDLE };
66     };
67 
68     VkSemaphore presentationWaitSemaphore { VK_NULL_HANDLE };
69     BASE_NS::vector<CommandBuffer> commandBuffers;
70 };
71 
72 #if (RENDER_PERF_ENABLED == 1)
73 struct PerfCounters {
74     uint32_t drawCount { 0u };
75     uint32_t drawIndirectCount { 0u };
76     uint32_t dispatchCount { 0u };
77     uint32_t dispatchIndirectCount { 0u };
78 
79     uint32_t bindPipelineCount { 0u };
80     uint32_t renderPassCount { 0u };
81 
82     uint32_t updateDescriptorSetCount { 0u };
83     uint32_t bindDescriptorSetCount { 0u };
84 
85     uint32_t triangleCount { 0u };
86     uint32_t instanceCount { 0u };
87 };
88 #else
89 struct PerfCounters {};
90 #endif
91 
92 /**
93 RenderBackVk.
94 Vulkan render backend.
95 Gets a list of intermediate render command lists and creates a Vulkan command buffers in parallel.
96 Generally one render command list will generate one vulkan command buffer.
97 **/
98 class RenderBackendVk final : public RenderBackend {
99 public:
100     RenderBackendVk(Device& dev, GpuResourceManager& gpuResourceManager, CORE_NS::ITaskQueue* queue);
101     ~RenderBackendVk() override = default;
102 
103     void Render(RenderCommandFrameData& renderCommandFrameData,
104         const RenderBackendBackBufferConfiguration& backBufferConfig) override;
105     void Present(const RenderBackendBackBufferConfiguration& backBufferConfig) override;
106 
107     struct StateCache {
108         const RenderCommandBeginRenderPass* renderCommandBeginRenderPass { nullptr };
109         LowLevelRenderPassDataVk lowLevelRenderPassData;
110         LowLevelPipelineLayoutDataVk lowLevelPipelineLayoutData;
111         bool primaryRenderPass { false };      // related to secondary command buffers
112         bool secondaryCommandBuffer { false }; // related to secondary command buffers
113         bool validCommandList { true };
114         bool validBindings { true };
115 
116         IRenderBackendNode* backendNode { nullptr };
117 
118         // matching pso handle to pipeline layout
119         RenderHandle psoHandle;
120         VkPipeline pipeline { VK_NULL_HANDLE };
121         VkPipelineLayout pipelineLayout { VK_NULL_HANDLE };
122 
123         // has bitmask for immutable samplers with special handling needed resources
124         // every descriptor set uses 16 bits (for max descriptor set bindings)
125         uint64_t pipelineDescSetHash { 0u };
126 
127 #if (RENDER_PERF_ENABLED == 1)
128         mutable PerfCounters perfCounters;
129 #endif
130     };
131 
132 private:
133     struct MultiRenderCommandListDesc {
134         RenderCommandContext* baseContext { nullptr };
135 
136         uint32_t multiRenderCommandListIndex { 0 };
137         uint32_t multiRenderCommandListCount { 0 };
138         bool secondaryCommandBuffer { false };
139         bool multiRenderNodeCmdList { false };
140     };
141 
142     struct DebugNames {
143         BASE_NS::string_view renderCommandListName;
144         BASE_NS::string_view renderCommandBufferName; // multi-renderpass has the first render command list name
145     };
146 
147     // called once in the beginning of rendering to acquire and setup possible swapchain
148     void AcquirePresentationInfo(
149         RenderCommandFrameData& renderCommandFrameData, const RenderBackendBackBufferConfiguration& backBufferConfig);
150 
151     void UpdateGlobalDescriptorSets();
152 
153     void RenderProcessCommandLists(
154         RenderCommandFrameData& renderCommandFrameData, const RenderBackendBackBufferConfiguration& backBufferConfig);
155     void RenderProcessSubmitCommandLists(
156         RenderCommandFrameData& renderCommandFrameData, const RenderBackendBackBufferConfiguration& backBufferConfig);
157     void RenderSingleCommandList(RenderCommandContext& renderCommandCtx, uint32_t cmdBufIdx,
158         const MultiRenderCommandListDesc& mrclDesc, const DebugNames& debugNames);
159 
160     void UpdateCommandListDescriptorSets(
161         const RenderCommandList& renderCommandList, StateCache& stateCache, NodeContextDescriptorSetManager& ncdsm);
162 
163     // secondary command buffers related methods
164     void RenderPrimaryRenderPass(const RenderCommandFrameData& renderCommandFrameData,
165         RenderCommandContext& renderCommandCtx, uint32_t cmdBufIdx,
166         const MultiRenderCommandListDesc& multiRenderCommandListDesc, const DebugNames& debugNames);
167     static void RenderExecuteSecondaryCommandLists(
168         const LowLevelCommandBufferVk& cmdBuffer, const LowLevelCommandBufferVk& executeCmdBuffer);
169     static VkCommandBufferInheritanceInfo RenderGetCommandBufferInheritanceInfo(
170         const RenderCommandList& renderCommandList, NodeContextPoolManager& poolMgr);
171 
172     static void RenderCommand(const RenderCommandDraw& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
173         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
174     void RenderCommand(const RenderCommandDrawIndirect& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
175         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
176     static void RenderCommand(const RenderCommandDispatch& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
177         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
178     void RenderCommand(const RenderCommandDispatchIndirect& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
179         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
180 
181     static void RenderCommand(const RenderCommandBindPipeline& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
182         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, StateCache& stateCache);
183     void RenderCommand(const RenderCommandBindVertexBuffers& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
184         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
185     void RenderCommand(const RenderCommandBindIndexBuffer& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
186         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
187 
188     static void RenderCommand(const RenderCommandBeginRenderPass& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
189         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, StateCache& stateCache);
190     static void RenderCommand(const RenderCommandNextSubpass& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
191         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
192     static void RenderCommand(const RenderCommandEndRenderPass& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
193         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, StateCache& stateCache);
194 
195     void RenderCommand(const RenderCommandCopyBuffer& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
196         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
197     void RenderCommand(const RenderCommandCopyBufferImage& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
198         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
199     void RenderCommand(const RenderCommandCopyImage& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
200         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
201 
202     void RenderCommand(const RenderCommandBarrierPoint& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
203         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache,
204         const RenderBarrierList& rbl);
205 
206     void RenderCommand(const RenderCommandBlitImage& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
207         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
208 
209     void RenderCommand(const RenderCommandBindDescriptorSets& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
210         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, StateCache& stateCache,
211         NodeContextDescriptorSetManager& ncdsm);
212 
213     static void RenderCommand(const RenderCommandPushConstant& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
214         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
215 
216     void RenderCommand(const RenderCommandBuildAccelerationStructure& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
217         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
218 
219     void RenderCommand(const RenderCommandClearColorImage& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
220         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
221 
222     // dynamic states
223     static void RenderCommand(const RenderCommandDynamicStateViewport& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
224         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
225     static void RenderCommand(const RenderCommandDynamicStateScissor& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
226         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
227     static void RenderCommand(const RenderCommandDynamicStateLineWidth& renderCmd,
228         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
229         const StateCache& stateCache);
230     static void RenderCommand(const RenderCommandDynamicStateDepthBias& renderCmd,
231         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
232         const StateCache& stateCache);
233     static void RenderCommand(const RenderCommandDynamicStateBlendConstants& renderCmd,
234         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
235         const StateCache& stateCache);
236     static void RenderCommand(const RenderCommandDynamicStateDepthBounds& renderCmd,
237         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
238         const StateCache& stateCache);
239     static void RenderCommand(const RenderCommandDynamicStateStencil& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
240         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
241     void RenderCommand(const RenderCommandDynamicStateFragmentShadingRate& renderCmd,
242         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
243         const StateCache& stateCache);
244 
245     void RenderCommand(const RenderCommandExecuteBackendFramePosition& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
246         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
247 
248     // queries
249     static void RenderCommand(const RenderCommandWriteTimestamp& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
250         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
251 
252     // markers
253 
254 #if (RENDER_DEBUG_MARKERS_ENABLED == 1) || (RENDER_DEBUG_COMMAND_MARKERS_ENABLED == 1)
255     void BeginDebugMarker(
256         const LowLevelCommandBufferVk& cmdBuf, const BASE_NS::string_view name, const BASE_NS::Math::Vec4 color);
257     void EndDebugMarker(const LowLevelCommandBufferVk& cmdBuf);
258 #endif
259 #if (RENDER_DEBUG_MARKERS_ENABLED == 1)
260     void RenderCommand(const RenderCommandBeginDebugMarker& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
261         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
262     void RenderCommand(const RenderCommandEndDebugMarker& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
263         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
264 #endif
265 
266     Device& device_;
267     DeviceVk& deviceVk_;
268     GpuResourceManager& gpuResourceMgr_;
269     CORE_NS::ITaskQueue* const queue_ { nullptr };
270 
271     CommandBufferSubmitter commandBufferSubmitter_;
272 
273     struct PresentationInfo {
274         bool useSwapchain { false };
275         bool validAcquire { false };
276         uint32_t swapchainImageIndex { ~0u };
277         VkSemaphore swapchainSemaphore { VK_NULL_HANDLE };
278         bool presentationLayoutChangeNeeded { false };
279         uint32_t renderNodeCommandListIndex { ~0u };
280         GpuResourceState renderGraphProcessedState;
281         ImageLayout imageLayout { ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED };
282         VkImage swapchainImage { VK_NULL_HANDLE };
283         VkSwapchainKHR swapchain { VK_NULL_HANDLE };
284         PerfCounters performanceCounters {};
285     };
286     struct PresentationData {
287         bool present { true };
288         BASE_NS::vector<PresentationInfo> infos;
289     };
290     PresentationData presentationData_;
291 
292     // internal presentationInfo_ state change (called 0 or 1 time from random thread for presentation layout change)
293     void RenderPresentationLayout(const LowLevelCommandBufferVk& cmdBuf, uint32_t cmdBufferIdx);
294 
295 #if (RENDER_PERF_ENABLED == 1)
296 
297     void StartFrameTimers(RenderCommandFrameData& renderCommandFrameData);
298     void EndFrameTimers();
299 
300     void WritePerfTimeStamp(const LowLevelCommandBufferVk& cmdBuf, const BASE_NS::string_view name,
301         const uint32_t queryIndex, const VkPipelineStageFlagBits stageFlagBits, const StateCache& stateCache);
302     void CopyPerfTimeStamp(
303         const LowLevelCommandBufferVk& cmdBuf, const BASE_NS::string_view name, const StateCache& stateCache);
304 
305     BASE_NS::unique_ptr<GpuQueryManager> gpuQueryMgr_;
306     struct PerfDataSet {
307         EngineResourceHandle gpuHandle;
308         CpuTimer cpuTimer;
309 
310         uint32_t gpuBufferOffset { 0 };
311 
312         PerfCounters perfCounters;
313     };
314     BASE_NS::unordered_map<BASE_NS::string, PerfDataSet> timers_;
315 #if (RENDER_GPU_TIMESTAMP_QUERIES_ENABLED == 1)
316     struct PerfGpuTimerData {
317         uint32_t fullByteSize { 0 };
318         uint32_t frameByteSize { 0 };
319         uint32_t currentOffset { 0 };
320         BASE_NS::unique_ptr<GpuBuffer> gpuBuffer;
321         void* mappedData { nullptr };
322 
323         std::atomic_int64_t fullGpuCounter = 0;
324     };
325     PerfGpuTimerData perfGpuTimerData_;
326 #endif
327     struct CommonBackendCpuTimers {
328         CpuTimer full;
329         CpuTimer acquire;
330         CpuTimer execute;
331         CpuTimer submit;
332         CpuTimer present;
333     };
334     CommonBackendCpuTimers commonCpuTimers_;
335 #endif
336 };
337 RENDER_END_NAMESPACE()
338 
339 #endif // VULKAN_RENDER_BACKEND_VK_H
340