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