• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_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     void RenderCommand(const RenderCommandCopyAccelerationStructureInstances& renderCmd,
219         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
220         const StateCache& stateCache);
221 
222     void RenderCommand(const RenderCommandClearColorImage& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
223         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
224 
225     // dynamic states
226     static void RenderCommand(const RenderCommandDynamicStateViewport& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
227         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
228     static void RenderCommand(const RenderCommandDynamicStateScissor& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
229         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
230     static void RenderCommand(const RenderCommandDynamicStateLineWidth& renderCmd,
231         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
232         const StateCache& stateCache);
233     static void RenderCommand(const RenderCommandDynamicStateDepthBias& renderCmd,
234         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
235         const StateCache& stateCache);
236     static void RenderCommand(const RenderCommandDynamicStateBlendConstants& renderCmd,
237         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
238         const StateCache& stateCache);
239     static void RenderCommand(const RenderCommandDynamicStateDepthBounds& renderCmd,
240         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
241         const StateCache& stateCache);
242     static void RenderCommand(const RenderCommandDynamicStateStencil& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
243         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
244     void RenderCommand(const RenderCommandDynamicStateFragmentShadingRate& renderCmd,
245         const LowLevelCommandBufferVk& cmdBuf, NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr,
246         const StateCache& stateCache);
247 
248     void RenderCommand(const RenderCommandExecuteBackendFramePosition& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
249         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
250 
251     // queries
252     static void RenderCommand(const RenderCommandWriteTimestamp& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
253         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
254 
255     // markers
256 
257 #if (RENDER_DEBUG_MARKERS_ENABLED == 1) || (RENDER_DEBUG_COMMAND_MARKERS_ENABLED == 1)
258     void BeginDebugMarker(
259         const LowLevelCommandBufferVk& cmdBuf, const BASE_NS::string_view name, const BASE_NS::Math::Vec4 color);
260     void EndDebugMarker(const LowLevelCommandBufferVk& cmdBuf);
261 #endif
262 #if (RENDER_DEBUG_MARKERS_ENABLED == 1)
263     void RenderCommand(const RenderCommandBeginDebugMarker& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
264         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
265     void RenderCommand(const RenderCommandEndDebugMarker& renderCmd, const LowLevelCommandBufferVk& cmdBuf,
266         NodeContextPsoManager& psoMgr, const NodeContextPoolManager& poolMgr, const StateCache& stateCache);
267 #endif
268 
269     Device& device_;
270     DeviceVk& deviceVk_;
271     GpuResourceManager& gpuResourceMgr_;
272     CORE_NS::ITaskQueue* const queue_ { nullptr };
273 
274     CommandBufferSubmitter commandBufferSubmitter_;
275 
276     struct PresentationInfo {
277         bool useSwapchain { false };
278         bool validAcquire { false };
279         uint32_t swapchainImageIndex { ~0u };
280         VkSemaphore swapchainSemaphore { VK_NULL_HANDLE };
281         bool presentationLayoutChangeNeeded { false };
282         uint32_t renderNodeCommandListIndex { ~0u };
283         GpuResourceState renderGraphProcessedState;
284         ImageLayout imageLayout { ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED };
285         VkImage swapchainImage { VK_NULL_HANDLE };
286         VkSwapchainKHR swapchain { VK_NULL_HANDLE };
287         PerfCounters performanceCounters {};
288     };
289     struct PresentationData {
290         bool present { true };
291         BASE_NS::vector<PresentationInfo> infos;
292     };
293     PresentationData presentationData_;
294 
295     // process backend commands for all positions
296     BASE_NS::vector<ProcessBackendCommand> processBackendCommands_;
297 
298     // internal presentationInfo_ state change (called 0 or 1 time from random thread for presentation layout change)
299     void RenderPresentationLayout(const LowLevelCommandBufferVk& cmdBuf, uint32_t cmdBufferIdx);
300 
301 #if (RENDER_PERF_ENABLED == 1)
302 
303     void StartFrameTimers(RenderCommandFrameData& renderCommandFrameData);
304     void EndFrameTimers();
305 
306     void WritePerfTimeStamp(const LowLevelCommandBufferVk& cmdBuf, const BASE_NS::string_view name,
307         const uint32_t queryIndex, const VkPipelineStageFlagBits stageFlagBits, const StateCache& stateCache);
308     void CopyPerfTimeStamp(
309         const LowLevelCommandBufferVk& cmdBuf, const BASE_NS::string_view name, const StateCache& stateCache);
310 
311     BASE_NS::unique_ptr<GpuQueryManager> gpuQueryMgr_;
312     struct PerfDataSet {
313         EngineResourceHandle gpuHandle;
314         CpuTimer cpuTimer;
315 
316         uint32_t gpuBufferOffset { 0 };
317 
318         PerfCounters perfCounters;
319     };
320     BASE_NS::unordered_map<BASE_NS::string, PerfDataSet> timers_;
321 #if (RENDER_GPU_TIMESTAMP_QUERIES_ENABLED == 1)
322     struct PerfGpuTimerData {
323         uint32_t fullByteSize { 0 };
324         uint32_t frameByteSize { 0 };
325         uint32_t currentOffset { 0 };
326         BASE_NS::unique_ptr<GpuBuffer> gpuBuffer;
327         void* mappedData { nullptr };
328 
329         std::atomic_int64_t fullGpuCounter = 0;
330     };
331     PerfGpuTimerData perfGpuTimerData_;
332 #endif
333     struct CommonBackendCpuTimers {
334         CpuTimer full;
335         CpuTimer acquire;
336         CpuTimer execute;
337         CpuTimer submit;
338         CpuTimer present;
339     };
340     CommonBackendCpuTimers commonCpuTimers_;
341 #endif
342 };
343 RENDER_END_NAMESPACE()
344 
345 #endif // VULKAN_RENDER_BACKEND_VK_H
346