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