• 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 DEVICE_GPU_RESOURCE_MANAGER_H
17 #define DEVICE_GPU_RESOURCE_MANAGER_H
18 
19 #include <mutex>
20 
21 #include <base/containers/array_view.h>
22 #include <base/containers/string.h>
23 #include <base/containers/unique_ptr.h>
24 #include <base/containers/unordered_map.h>
25 #include <base/containers/vector.h>
26 #include <render/device/gpu_resource_desc.h>
27 #include <render/device/intf_gpu_resource_manager.h>
28 #include <render/namespace.h>
29 
30 #include "device/gpu_buffer.h"
31 #include "device/gpu_image.h"
32 #include "device/gpu_resource_handle_util.h" // for hash<RenderHandle>
33 #include "device/gpu_resource_manager_base.h"
34 
35 RENDER_BEGIN_NAMESPACE()
36 class Device;
37 class GpuBuffer;
38 class GpuBufferManager;
39 class GpuImage;
40 class GpuImageManager;
41 class GpuSampler;
42 class GpuSamplerManager;
43 
44 /** Staging Gpu resource copy struct */
45 struct StagingCopyStruct {
46     /** Data type enumeration */
47     enum class DataType : uint8_t {
48         /** Vector */
49         DATA_TYPE_VECTOR = 0,
50         /** Image container */
51         DATA_TYPE_IMAGE_CONTAINER = 1,
52         /** Direct copy from src, no CPU data with stagingData or imageContainerPtr */
53         DATA_TYPE_DIRECT_SRC_COPY = 2,
54         /** Resource to resource copy with graphics commands */
55         DATA_TYPE_SRC_TO_DST_COPY = 2,
56     };
57     /** Copy type enumeration */
58     enum class CopyType : uint8_t {
59         /** Undefined */
60         UNDEFINED = 0,
61         /** Buffer to buffer */
62         BUFFER_TO_BUFFER,
63         /** Buffer to image */
64         BUFFER_TO_IMAGE,
65         /** Image to buffer */
66         IMAGE_TO_BUFFER,
67         /** Image to image */
68         IMAGE_TO_IMAGE,
69         /** Cpu to buffer */
70         CPU_TO_BUFFER,
71     };
72 
73     /** Data type, default vector */
74     DataType dataType { DataType::DATA_TYPE_VECTOR };
75 
76     /** Source handle */
77     RenderHandleReference srcHandle;
78     /** Destination handle */
79     RenderHandleReference dstHandle;
80 
81     /** Begin index */
82     uint32_t beginIndex { 0 };
83     /** Count */
84     uint32_t count { 0 };
85 
86     /** Staging data */
87     BASE_NS::vector<uint8_t> stagingData;
88     /** Image container pointer */
89     CORE_NS::IImageContainer::Ptr imageContainerPtr;
90 
91     /** Optional format for scaling */
92     BASE_NS::Format format { BASE_NS::Format::BASE_FORMAT_UNDEFINED };
93 
94     /** Staging buffer bytesize. */
95     uint32_t stagingBufferByteSize { 0u };
96 
97     /** Invalid operation which should be ignored. Might be a copy that has been removed during processing. */
98     bool invalidOperation { false };
99 };
100 
101 /** Staging image scaling info struct. Uses the same scaling image for all with the format */
102 struct StagingImageScalingStruct {
103     /** Handle to the resource which is created just before staging */
104     RenderHandleReference handle;
105     /** Format of the scaling image */
106     BASE_NS::Format format { BASE_NS::Format::BASE_FORMAT_UNDEFINED };
107     /** Maximum width of the scaling image */
108     uint32_t maxWidth { 0u };
109     /** Maximum height of the scaling image */
110     uint32_t maxHeight { 0u };
111 };
112 
113 /** All staging scaling image data */
114 struct ScalingImageDataStruct {
115     /** Scaling resource infos (used for fast iteration) */
116     BASE_NS::vector<StagingImageScalingStruct> scalingImages;
117     /** Map with format to image scaling struct index */
118     BASE_NS::unordered_map<uint32_t, size_t> formatToScalingImages;
119 };
120 
121 /** Staging Gpu resource consume struct, this contains all staged resources for this frame */
122 struct StagingConsumeStruct {
123     /** Buffer to buffer */
124     BASE_NS::vector<StagingCopyStruct> bufferToBuffer;
125     /** Buffer to image */
126     BASE_NS::vector<StagingCopyStruct> bufferToImage;
127     /** Image to buffer */
128     BASE_NS::vector<StagingCopyStruct> imageToBuffer;
129     /** Image to image */
130     BASE_NS::vector<StagingCopyStruct> imageToImage;
131     /** Direct CPU copy to buffer */
132     BASE_NS::vector<StagingCopyStruct> cpuToBuffer;
133 
134     /** Buffer copies */
135     BASE_NS::vector<BufferCopy> bufferCopies;
136     /** Buffer image copies */
137     BASE_NS::vector<BufferImageCopy> bufferImageCopies;
138     /** Image copies */
139     BASE_NS::vector<ImageCopy> imageCopies;
140 
141     /** Scaling image data */
142     ScalingImageDataStruct scalingImageData;
143 };
144 
145 /** Per frame work loop:
146  *
147  * 1. renderer.cpp calls HandlePendingAllocations() before any RenderNode-method calls
148  * 2. renderer.cpp calls LockFrameStagingData() before RenderNode::ExecuteFrame call
149  * 3. renderer.cpp calls HandlePendingAllocations() before RenderNode::ExecuteFrame call
150  * 4. RenderBackendXX.cpp calls renderBackendHandleRemapping() before going through render command lists
151  *
152  * NOTE:
153  *    - There are no allocations or deallocations after RenderNode::ExecuteFrame()
154  *
155  * Creation process:
156  *
157  * 1. Create-method is called. It will call StoreAllocation-method.
158  * 2. StoreAllocation-method checks:
159  *     - if replacing old resource with new (when creating with a same name)
160  *     - if there exists handles (array slots) for recycle/reuse
161  *     - if needs to Create new handle (push_backs several vectors)
162  *     - push into pending allocation list
163  *     - quite a lot of processing due to replacing handles and removing old staging ops etc.
164  * 3. handlePendingAllocation is called from Render.cpp
165  *     - allocates the actual new gpu resources
166  *
167  * Destruction process:
168  *
169  * 1. Destroy-method is called
170  *     - invalidates nameToClientHandle
171  *     - push into pending deallocation list
172  * 2. handlePendingAllocation is called from Render.cpp
173  *     - deallocates the actual gpu resources
174  *     - sends the array index (handle array index) for recycling
175  *
176  * NOTE: It is safe to Destroy in RenderNode::ExecuteFrame()
177  * The client handle has been added to render command list
178  * and it is not invalidated in this particular frame.
179  *
180  * NOTE: Simplification would come from not able to replace handles with staging
181  */
182 class GpuResourceManager final : public IGpuResourceManager {
183 public:
184     static GpuBufferDesc GetStagingBufferDesc(const uint32_t byteSize);
185 
186     enum GpuResourceManagerFlagBits : uint32_t {
187         /** Use direct copy with integrated GPUs were device memory is always host visible.
188          * If this flag is set. Device is checked for availability.
189          **/
190         GPU_RESOURCE_MANAGER_OPTIMIZE_STAGING_MEMORY = (1 << 0),
191     };
192     using GpuResourceManagerFlags = uint32_t;
193 
194     struct CreateInfo {
195         GpuResourceManagerFlags flags { 0 };
196     };
197 
198     GpuResourceManager(Device& device, const CreateInfo& createInfo);
199     ~GpuResourceManager() override;
200 
201     GpuResourceManager(const GpuResourceManager&) = delete;
202     GpuResourceManager& operator=(const GpuResourceManager&) = delete;
203 
204     RenderHandleReference Get(const RenderHandle& handle) const override;
205 
206     RenderHandleReference Create(const BASE_NS::string_view name, const GpuBufferDesc& desc) override;
207     RenderHandleReference Create(const BASE_NS::string_view name, const GpuBufferDesc& desc,
208         const BASE_NS::array_view<const uint8_t> data) override;
209 
210     RenderHandleReference Create(const GpuBufferDesc& desc, const BASE_NS::array_view<const uint8_t> data) override;
211     RenderHandleReference Create(const RenderHandleReference& replacedHandle, const GpuBufferDesc& desc) override;
212     RenderHandleReference Create(const GpuBufferDesc& desc) override;
213 
214     RenderHandleReference Create(const BASE_NS::string_view name, const GpuImageDesc& desc) override;
215     RenderHandleReference Create(const BASE_NS::string_view name, const GpuImageDesc& desc,
216         const BASE_NS::array_view<const uint8_t> data) override;
217     RenderHandleReference Create(const RenderHandleReference& replacedHandle, const GpuImageDesc& desc) override;
218     RenderHandleReference Create(
219         const BASE_NS::string_view name, const GpuImageDesc& desc, CORE_NS::IImageContainer::Ptr image) override;
220     RenderHandleReference Create(const BASE_NS::string_view name, const GpuImageDesc& desc,
221         const BASE_NS::array_view<const uint8_t> data,
222         const BASE_NS::array_view<const BufferImageCopy> bufferImageCopies) override;
223 
224     /* Create a GpuImage with unique image name from external texture. Immediate resource creation not deferred. */
225     RenderHandleReference CreateView(const BASE_NS::string_view name, const GpuImageDesc& desc,
226         const BackendSpecificImageDesc& backendSpecificData) override;
227     /* Create gpu image view for platform resource. Immediate creation not deferred. */
228     RenderHandleReference CreateView(
229         const BASE_NS::string_view name, const GpuImageDesc& desc, const GpuImagePlatformData& gpuImagePlatformData);
230 
231     RenderHandleReference Create(const GpuImageDesc& desc) override;
232     RenderHandleReference Create(const GpuImageDesc& desc, const BASE_NS::array_view<const uint8_t> data) override;
233     RenderHandleReference Create(const GpuImageDesc& desc, const BASE_NS::array_view<const uint8_t> data,
234         const BASE_NS::array_view<const BufferImageCopy> bufferImageCopies) override;
235     RenderHandleReference Create(const GpuImageDesc& desc, CORE_NS::IImageContainer::Ptr image) override;
236 
237     RenderHandleReference Create(const GpuAccelerationStructureDesc& desc) override;
238     RenderHandleReference Create(const BASE_NS::string_view name, const GpuAccelerationStructureDesc& desc) override;
239     RenderHandleReference Create(
240         const RenderHandleReference& replacedHandle, const GpuAccelerationStructureDesc& desc) override;
241 
242     /** Remap gpu image handle to some valid gpu image handle. Resources are not destroyed.
243     @param clientHandle A valid client image handle.
244     @param clientHandleGpuResource A valid gpu image handle with a valid gpu resource.
245     clientHandle resource need to be created with CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS
246     */
247     void RemapGpuImageHandle(const RenderHandle& clientHandle, const RenderHandle& clientHandleGpuResource);
248 
249     RenderHandleReference Create(const BASE_NS::string_view name, const GpuSamplerDesc& desc) override;
250     RenderHandleReference Create(const RenderHandleReference& replacedHandle, const GpuSamplerDesc& desc) override;
251     RenderHandleReference Create(const GpuSamplerDesc& desc) override;
252 
253     RenderHandleReference GetBufferHandle(const BASE_NS::string_view name) const override;
254     RenderHandleReference GetImageHandle(const BASE_NS::string_view name) const override;
255     RenderHandleReference GetSamplerHandle(const BASE_NS::string_view name) const override;
256     RenderHandleReference GetAccelerationStructureHandle(const BASE_NS::string_view name) const override;
257 
258     RenderHandle GetBufferRawHandle(const BASE_NS::string_view name) const;
259     RenderHandle GetImageRawHandle(const BASE_NS::string_view name) const;
260     RenderHandle GetSamplerRawHandle(const BASE_NS::string_view name) const;
261     RenderHandle GetAccelerationStructureRawHandle(const BASE_NS::string_view name) const;
262 
263     GpuBufferDesc GetBufferDescriptor(const RenderHandleReference& handle) const override;
264     GpuImageDesc GetImageDescriptor(const RenderHandleReference& handle) const override;
265     GpuSamplerDesc GetSamplerDescriptor(const RenderHandleReference& handle) const override;
266     GpuAccelerationStructureDesc GetAccelerationStructureDescriptor(const RenderHandleReference& handle) const override;
267 
268     GpuBufferDesc GetBufferDescriptor(const RenderHandle& handle) const;
269     GpuImageDesc GetImageDescriptor(const RenderHandle& handle) const;
270     GpuSamplerDesc GetSamplerDescriptor(const RenderHandle& handle) const;
271     GpuAccelerationStructureDesc GetAccelerationStructureDescriptor(const RenderHandle& handle) const;
272 
273     /** Forward allocation/deallocation requests to actual resource managers. Not thread safe.
274     Called only from Renderer. */
275     void HandlePendingAllocations();
276     /** Called from the Renderer after the frame has been rendered with the backend. */
277     void EndFrame();
278 
279     /** Special un-safe call from render backends, to re-map swapchain.
280     This method is un-safe and should only be called from specific location(s). */
281     void RenderBackendImmediateRemapGpuImageHandle(
282         const RenderHandle& clientHandle, const RenderHandle& clientHandleGpuResource);
283 
284     /** The staging data is locked for this frame consumable sets. */
285     void LockFrameStagingData();
286 
287     bool HasStagingData() const;
288     StagingConsumeStruct ConsumeStagingData();
289 
290     struct StateDestroyConsumeStruct {
291         // gpu image or gpu buffers
292         BASE_NS::vector<RenderHandle> resources;
293     };
294     StateDestroyConsumeStruct ConsumeStateDestroyData();
295 
296     void* MapBuffer(const RenderHandleReference& handle) const;
297     void* MapBufferMemory(const RenderHandleReference& handle) const override;
298     void UnmapBuffer(const RenderHandleReference& handle) const override;
299 
300     void* MapBuffer(const RenderHandle& handle) const;
301     void* MapBufferMemory(const RenderHandle& handle) const;
302     void UnmapBuffer(const RenderHandle& handle) const;
303 
304     void WaitForIdleAndDestroyGpuResources() override;
305 
306     EngineResourceHandle GetGpuHandle(const RenderHandle& clientHandle) const;
307 
308     GpuBuffer* GetBuffer(const RenderHandle& gpuHandle) const;
309     GpuImage* GetImage(const RenderHandle& gpuHandle) const;
310     GpuSampler* GetSampler(const RenderHandle& gpuHandle) const;
311     GpuAccelerationStructure* GetAccelerationStructure(const RenderHandle& gpuHandle) const;
312 
313     template<typename T>
GetBuffer(const RenderHandle & handle)314     T* GetBuffer(const RenderHandle& handle) const
315     {
316         return static_cast<T*>(GetBuffer(handle));
317     }
318     template<typename T>
GetImage(const RenderHandle & handle)319     T* GetImage(const RenderHandle& handle) const
320     {
321         return static_cast<T*>(GetImage(handle));
322     }
323     template<typename T>
GetSampler(const RenderHandle & handle)324     T* GetSampler(const RenderHandle& handle) const
325     {
326         return static_cast<T*>(GetSampler(handle));
327     }
328     template<typename T>
GetAccelerationStructure(const RenderHandle & handle)329     T* GetAccelerationStructure(const RenderHandle& handle) const
330     {
331         return static_cast<T*>(GetAccelerationStructure(handle));
332     }
333 
334     // for render graph to resizing (non-locked access only valid in certain positions)
335     uint32_t GetBufferHandleCount() const;
336     uint32_t GetImageHandleCount() const;
337 
338     bool IsGpuBuffer(const RenderHandleReference& handle) const override;
339     bool IsGpuImage(const RenderHandleReference& handle) const override;
340     bool IsGpuSampler(const RenderHandleReference& handle) const override;
341     bool IsGpuAccelerationStructure(const RenderHandleReference& handle) const override;
342     bool IsMappableOutsideRender(const RenderHandleReference& handle) const override;
343     bool IsGpuBuffer(const RenderHandle& handle) const;
344     bool IsGpuImage(const RenderHandle& handle) const;
345     bool IsGpuSampler(const RenderHandle& handle) const;
346     bool IsGpuAccelerationStructure(const RenderHandle& handle) const;
347     bool IsValid(const RenderHandle& handle) const;
348 
349     FormatProperties GetFormatProperties(const RenderHandleReference& handle) const override;
350     FormatProperties GetFormatProperties(const RenderHandle& handle) const;
351     FormatProperties GetFormatProperties(const BASE_NS::Format& format) const override;
352 
353     GpuImageDesc CreateGpuImageDesc(const CORE_NS::IImageContainer::ImageDesc& desc) const override;
354 
355     BASE_NS::string GetName(const RenderHandle& handle) const;
356     BASE_NS::string GetName(const RenderHandleReference& handle) const override;
357 
358 private:
359     Device& device_;
360 
361     GpuResourceManagerFlags gpuResourceMgrFlags_ { 0 };
362 
363     BASE_NS::unique_ptr<GpuResourceManagerTyped<GpuBuffer, GpuBufferDesc>> gpuBufferMgr_;
364     BASE_NS::unique_ptr<GpuResourceManagerTyped<GpuImage, GpuImageDesc>> gpuImageMgr_;
365     BASE_NS::unique_ptr<GpuResourceManagerTyped<GpuSampler, GpuSamplerDesc>> gpuSamplerMgr_;
366     BASE_NS::unique_ptr<GpuResourceManagerTyped<GpuAccelerationStructure, GpuAccelerationStructureDesc>>
367         gpuAccelerationStructureMgr_;
368 
369     union ResourceDescriptor {
ResourceDescriptor(const GpuBufferDesc & descriptor)370         explicit ResourceDescriptor(const GpuBufferDesc& descriptor) : bufferDescriptor(descriptor) {}
ResourceDescriptor(const GpuImageDesc & descriptor)371         explicit ResourceDescriptor(const GpuImageDesc& descriptor) : imageDescriptor(descriptor) {}
ResourceDescriptor(const GpuSamplerDesc & descriptor)372         explicit ResourceDescriptor(const GpuSamplerDesc& descriptor) : samplerDescriptor(descriptor) {}
ResourceDescriptor(const GpuAccelerationStructureDesc & descriptor)373         explicit ResourceDescriptor(const GpuAccelerationStructureDesc& descriptor) : accelerationDescriptor(descriptor)
374         {}
375         GpuBufferDesc bufferDescriptor;
376         GpuImageDesc imageDescriptor;
377         GpuSamplerDesc samplerDescriptor;
378         GpuAccelerationStructureDesc accelerationDescriptor;
379     };
380 
381     // combine alloc and de-alloc
382     // removed is a handle that is removed before pending allocation is called (i.e. destroyed)
383     enum class AllocType : uint8_t {
384         UNDEFINED = 0,
385         ALLOC = 1,
386         DEALLOC = 2,
387         REMOVED = 3,
388     };
389 
390     struct OperationDescription {
OperationDescriptionOperationDescription391         OperationDescription(
392             RenderHandle handle, ResourceDescriptor descriptor, AllocType allocType, uint32_t optResourceIndex)
393             : handle(handle), descriptor(descriptor), allocType(allocType), optionalResourceIndex(optResourceIndex),
394               optionalStagingVectorIndex(~0u), optionalStagingCopyType(StagingCopyStruct::CopyType::UNDEFINED)
395         {}
396 
397         RenderHandle handle;
398         ResourceDescriptor descriptor;
399         AllocType allocType { AllocType::UNDEFINED };
400         uint32_t optionalResourceIndex { ~0u };
401         uint32_t optionalStagingVectorIndex { ~0u };
402         StagingCopyStruct::CopyType optionalStagingCopyType { StagingCopyStruct::CopyType::UNDEFINED };
403     };
404     struct RemapDescription {
405         RenderHandle shallowClientHandle;
406         RenderHandle resourceClientHandle;
407     };
408     using BufferVector = BASE_NS::vector<BASE_NS::unique_ptr<GpuBuffer>>;
409     using ImageVector = BASE_NS::vector<BASE_NS::unique_ptr<GpuImage>>;
410 
411     struct PendingData {
412         BASE_NS::vector<OperationDescription> allocations;
413         // optional
414         BASE_NS::vector<BASE_NS::unique_ptr<GpuBuffer>> buffers; // pre-created
415         BASE_NS::vector<BASE_NS::unique_ptr<GpuImage>> images;   // pre-created
416         BASE_NS::vector<RemapDescription> remaps;
417     };
418 
419     struct AdditionalData {
420         uintptr_t resourcePtr { 0 };
421         uint32_t indexToPendingData { ~0u }; // cleared to default when processed
422     };
423 
424     struct PerManagerStore {
425         const RenderHandleType handleType { RenderHandleType::UNDEFINED };
426         GpuResourceManagerBase* mgr { nullptr };
427 
428         // client access lock
429         mutable std::mutex clientMutex {};
430 
431         // the following needs be locked with clientMutex
432         BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToClientIndex {};
433         // resource descriptions, accessed with RenderHandle array index
434         BASE_NS::vector<ResourceDescriptor> descriptions {};
435 
436         // handles might be invalid (when invalid generation is stored in high-bits, i.e. the handle is invalid)
437         BASE_NS::vector<RenderHandleReference> clientHandles {};
438 
439         // index to pending data, ptr to possible gpu buffer mapped data
440         BASE_NS::vector<AdditionalData> additionalData {};
441 
442         // handle ids which can be re-used
443         BASE_NS::vector<uint64_t> availableHandleIds {};
444 
445         PendingData pendingData {};
446 
447         // the following are not locked (ever)
448 
449         // handles might be invalid (when invalid generation is stored in high - bits, i.e.the handle is invalid)
450         BASE_NS::vector<EngineResourceHandle> gpuHandles {};
451         // ogl object name tagging not supported ATM
452 #if (RENDER_VULKAN_VALIDATION_ENABLED == 1)
453         BASE_NS::vector<RenderHandle> debugTagAllocations {};
454 #endif
455     };
456     PerManagerStore bufferStore_ { RenderHandleType::GPU_BUFFER };
457     PerManagerStore imageStore_ { RenderHandleType::GPU_IMAGE };
458     PerManagerStore samplerStore_ { RenderHandleType::GPU_SAMPLER };
459     PerManagerStore accelStore_ { RenderHandleType::GPU_BUFFER };
460 
461     // needs to be locked when called
462     static uint64_t GetNextAvailableHandleId(PerManagerStore& mgrStore);
463 
464     struct StoreAllocationData {
465         RenderHandleReference handle;
466         size_t allocationIndex { ~0u };
467     };
468 
469     void HandlePendingAllocationsImpl(const bool isEndFrame);
470     void Destroy(const RenderHandle& handle);
471     // Destroy staging buffers. Not thread safe. Called from gpu resource manager
472     void DestroyFrameStaging();
473 
474     // needs to be locked when called
475     StoreAllocationData CreateBuffer(
476         const BASE_NS::string_view name, const RenderHandle& replacedHandle, const GpuBufferDesc& desc);
477     // needs to be locked when called
478     StoreAllocationData CreateImage(
479         const BASE_NS::string_view name, const RenderHandle& replacedHandle, const GpuImageDesc& desc);
480     RenderHandleReference CreateStagingBuffer(const GpuBufferDesc& desc);
481     // needs to be locked when called
482     StoreAllocationData CreateAccelerationStructure(
483         const BASE_NS::string_view name, const RenderHandle& replacedHandle, const GpuAccelerationStructureDesc& desc);
484 
485     RenderHandle CreateClientHandle(const RenderHandleType type, const ResourceDescriptor& resourceDescriptor,
486         const uint64_t handleId, const uint32_t hasNameId, const uint32_t additionalInfoFlags);
487 
488     // needs to be locked when called
489     StoreAllocationData StoreAllocation(PerManagerStore& store, const BASE_NS::string_view name,
490         const RenderHandle& replacedHandle, RenderHandleType handleType, const ResourceDescriptor& descriptor,
491         uint32_t optionalResourceIndex, uint32_t additionalHandleFlags);
492 
493     void CreateGpuResource(const OperationDescription& op, const uint32_t arrayIndex,
494         const RenderHandleType resourceType, const uintptr_t preCreateData);
495 
496     // needs to be locked when called
497     void DestroyGpuResource(const OperationDescription& operation, const uint32_t arrayIndex,
498         const RenderHandleType resourceType, PerManagerStore& store);
499 
500     RenderHandleReference GetHandle(const PerManagerStore& store, const BASE_NS::string_view name) const;
501     RenderHandle GetRawHandle(const PerManagerStore& store, const BASE_NS::string_view name) const;
502 
503     EngineResourceHandle GetGpuHandle(const PerManagerStore& store, const RenderHandle& clientHandle) const;
504 
505     // destroydHandle store needs to be locked, staging locked inside and bufferstore if not already locked
506     void RemoveStagingOperations(const OperationDescription& destroyAlloc);
507     // needs to be locked outside
508     void Destroy(PerManagerStore& store, const RenderHandle& handle);
509     // needs to be locked when called
510     void DestroyImmediate(PerManagerStore& store, const RenderHandle& handle);
511 
512     void HandlePendingRemappings(const BASE_NS::vector<RemapDescription>& pendingShallowRemappings,
513         BASE_NS::vector<EngineResourceHandle>& gpuHandles);
514 
515     PendingData CommitPendingData(PerManagerStore& store);
516 
517     // needs to be locked when called
518     uint32_t GetPendingOptionalResourceIndex(
519         const PerManagerStore& store, const RenderHandle& handle, const BASE_NS::string_view name);
520 
521     void DebugPrintValidCounts();
522 
523     // list of handles that state data should be destroyed
524     // (e.g. handle is replaced with a new resource or destroyed)
525     // information is passed to render graph
526     StateDestroyConsumeStruct clientHandleStateDestroy_;
527 
528     mutable std::mutex stagingMutex_;
529     StagingConsumeStruct stagingOperations_;   // needs to be locked
530     StagingConsumeStruct perFrameStagingData_; // per frame data after LockFrameStagingData()
531     BASE_NS::vector<RenderHandleReference> perFrameStagingBuffers_;
532     BASE_NS::vector<RenderHandleReference> perFrameStagingScalingImages_;
533 
534     // ogl object name tagging not supported ATM
535 #if (RENDER_VULKAN_VALIDATION_ENABLED == 1)
536     void ProcessDebugTags();
537 #endif
538 };
539 
540 class RenderNodeGpuResourceManager final : public IRenderNodeGpuResourceManager {
541 public:
542     explicit RenderNodeGpuResourceManager(GpuResourceManager& gpuResourceManager);
543     ~RenderNodeGpuResourceManager();
544 
545     RenderHandleReference Get(const RenderHandle& handle) const override;
546 
547     RenderHandleReference Create(const GpuBufferDesc& desc) override;
548     RenderHandleReference Create(const BASE_NS::string_view name, const GpuBufferDesc& desc) override;
549     RenderHandleReference Create(const RenderHandleReference& handle, const GpuBufferDesc& desc) override;
550     RenderHandleReference Create(const BASE_NS::string_view name, const GpuBufferDesc& desc,
551         const BASE_NS::array_view<const uint8_t> data) override;
552 
553     RenderHandleReference Create(const GpuImageDesc& desc) override;
554     RenderHandleReference Create(const BASE_NS::string_view name, const GpuImageDesc& desc) override;
555     RenderHandleReference Create(const RenderHandleReference& handle, const GpuImageDesc& desc) override;
556     RenderHandleReference Create(const BASE_NS::string_view name, const GpuImageDesc& desc,
557         const BASE_NS::array_view<const uint8_t> data) override;
558 
559     RenderHandleReference Create(const GpuSamplerDesc& desc) override;
560     RenderHandleReference Create(const BASE_NS::string_view name, const GpuSamplerDesc& desc) override;
561     RenderHandleReference Create(const RenderHandleReference& handle, const GpuSamplerDesc& desc) override;
562 
563     RenderHandleReference Create(const GpuAccelerationStructureDesc& desc) override;
564     RenderHandleReference Create(const BASE_NS::string_view name, const GpuAccelerationStructureDesc& desc) override;
565     RenderHandleReference Create(
566         const RenderHandleReference& handle, const GpuAccelerationStructureDesc& desc) override;
567 
568     RenderHandle GetBufferHandle(const BASE_NS::string_view name) const override;
569     RenderHandle GetImageHandle(const BASE_NS::string_view name) const override;
570     RenderHandle GetSamplerHandle(const BASE_NS::string_view name) const override;
571     RenderHandle GetAccelerationStructureHandle(const BASE_NS::string_view name) const override;
572 
573     GpuBufferDesc GetBufferDescriptor(const RenderHandle& handle) const override;
574     GpuImageDesc GetImageDescriptor(const RenderHandle& handle) const override;
575     GpuSamplerDesc GetSamplerDescriptor(const RenderHandle& handle) const override;
576     GpuAccelerationStructureDesc GetAccelerationStructureDescriptor(const RenderHandle& handle) const override;
577 
578     bool HasStagingData() const;
579     StagingConsumeStruct ConsumeStagingData();
580 
581     void* MapBuffer(const RenderHandle& handle) const override;
582     void* MapBufferMemory(const RenderHandle& handle) const override;
583     void UnmapBuffer(const RenderHandle& handle) const override;
584 
585     GpuResourceManager& GetGpuResourceManager();
586 
587     bool IsValid(const RenderHandle& handle) const override;
588     bool IsGpuBuffer(const RenderHandle& handle) const override;
589     bool IsGpuImage(const RenderHandle& handle) const override;
590     bool IsGpuSampler(const RenderHandle& handle) const override;
591 
592     FormatProperties GetFormatProperties(const RenderHandle& handle) const override;
593     FormatProperties GetFormatProperties(const BASE_NS::Format format) const override;
594 
595     BASE_NS::string GetName(const RenderHandle& handle) const override;
596 
597 private:
598     GpuResourceManager& gpuResourceMgr_;
599 };
600 RENDER_END_NAMESPACE()
601 
602 #endif // DEVICE_GPU_RESOURCE_MANAGER_H
603