• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef 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 = 2,
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 
226     RenderHandleReference GetOrCreate(BASE_NS::string_view name, const GpuImageDesc& desc) override;
227     RenderHandleReference Create(BASE_NS::string_view name, const GpuImageDesc& desc) override;
228     RenderHandleReference Create(
229         BASE_NS::string_view name, const GpuImageDesc& desc, BASE_NS::array_view<const uint8_t> data) override;
230     RenderHandleReference Create(const RenderHandleReference& replacedHandle, const GpuImageDesc& desc) override;
231     RenderHandleReference Create(
232         BASE_NS::string_view name, const GpuImageDesc& desc, CORE_NS::IImageContainer::Ptr image) override;
233     RenderHandleReference Create(BASE_NS::string_view name, const GpuImageDesc& desc,
234         BASE_NS::array_view<const uint8_t> data, BASE_NS::array_view<const BufferImageCopy> bufferImageCopies) override;
235 
236     /* Create a GpuImage with unique image name from external texture. Immediate resource creation not deferred. */
237     RenderHandleReference CreateView(BASE_NS::string_view name, const GpuImageDesc& desc,
238         const BackendSpecificImageDesc& backendSpecificData) override;
239     /* Create gpu image view for platform resource. Immediate creation not deferred. */
240     RenderHandleReference CreateView(
241         BASE_NS::string_view name, const GpuImageDesc& desc, const GpuImagePlatformData& gpuImagePlatformData);
242 
243     RenderHandleReference Create(const GpuImageDesc& desc) override;
244     RenderHandleReference Create(const GpuImageDesc& desc, BASE_NS::array_view<const uint8_t> data) override;
245     RenderHandleReference Create(const GpuImageDesc& desc, BASE_NS::array_view<const uint8_t> data,
246         BASE_NS::array_view<const BufferImageCopy> bufferImageCopies) override;
247     RenderHandleReference Create(const GpuImageDesc& desc, CORE_NS::IImageContainer::Ptr image) override;
248 
249     RenderHandleReference Create(const GpuAccelerationStructureDesc& desc) override;
250     RenderHandleReference Create(BASE_NS::string_view name, const GpuAccelerationStructureDesc& desc) override;
251     RenderHandleReference Create(
252         const RenderHandleReference& replacedHandle, const GpuAccelerationStructureDesc& desc) override;
253 
254     /** Remap gpu image handle to some valid gpu image handle. Resources are not destroyed.
255     @param clientHandle A valid client image handle.
256     @param clientHandleGpuResource A valid gpu image handle with a valid gpu resource.
257     clientHandle resource need to be created with CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS
258     */
259     void RemapGpuImageHandle(const RenderHandle& clientHandle, const RenderHandle& clientHandleGpuResource);
260 
261     RenderHandleReference GetOrCreate(BASE_NS::string_view name, const GpuSamplerDesc& desc) override;
262     RenderHandleReference Create(BASE_NS::string_view name, const GpuSamplerDesc& desc) override;
263     RenderHandleReference Create(const RenderHandleReference& replacedHandle, const GpuSamplerDesc& desc) override;
264     RenderHandleReference Create(const GpuSamplerDesc& desc) override;
265 
266     RenderHandleReference CreateSwapchainImage(
267         const RenderHandleReference& replacedHandle, BASE_NS::string_view name, const GpuImageDesc& desc);
268 
269     /** Does not have GPU backed data. Will be remapped to other handle */
270     RenderHandleReference CreateShallowHandle(const GpuImageDesc& desc);
271 
272     RenderHandleReference GetBufferHandle(BASE_NS::string_view name) const override;
273     RenderHandleReference GetImageHandle(BASE_NS::string_view name) const override;
274     RenderHandleReference GetSamplerHandle(BASE_NS::string_view name) const override;
275 
276     bool HasBuffer(BASE_NS::string_view name) const override;
277     bool HasImage(BASE_NS::string_view name) const override;
278     bool HasSampler(BASE_NS::string_view name) const override;
279 
280     RenderHandle GetBufferRawHandle(BASE_NS::string_view name) const;
281     RenderHandle GetImageRawHandle(BASE_NS::string_view name) const;
282     RenderHandle GetSamplerRawHandle(BASE_NS::string_view name) const;
283 
284     GpuBufferDesc GetBufferDescriptor(const RenderHandleReference& handle) const override;
285     GpuImageDesc GetImageDescriptor(const RenderHandleReference& handle) const override;
286     GpuSamplerDesc GetSamplerDescriptor(const RenderHandleReference& handle) const override;
287     GpuAccelerationStructureDesc GetAccelerationStructureDescriptor(const RenderHandleReference& handle) const override;
288 
289     GpuBufferDesc GetBufferDescriptor(const RenderHandle& handle) const;
290     GpuImageDesc GetImageDescriptor(const RenderHandle& handle) const;
291     GpuSamplerDesc GetSamplerDescriptor(const RenderHandle& handle) const;
292     GpuAccelerationStructureDesc GetAccelerationStructureDescriptor(const RenderHandle& handle) const;
293 
294     /** Forward allocation/deallocation requests to actual resource managers. Not thread safe.
295     Called only from Renderer. */
296     void HandlePendingAllocations();
297     /** Called from the Renderer after the frame has been rendered with the backend. */
298     void EndFrame();
299 
300     /** Special un-safe call from render backends, to re-map swapchain.
301     This method is un-safe and should only be called from specific location(s). */
302     void RenderBackendImmediateRemapGpuImageHandle(
303         const RenderHandle& clientHandle, const RenderHandle& clientHandleGpuResource);
304 
305     /** The staging data is locked for this frame consumable sets. */
306     void LockFrameStagingData();
307 
308     bool HasStagingData() const;
309     StagingConsumeStruct ConsumeStagingData();
310     void MapRenderTimeGpuBuffers();
311     void UnmapRenderTimeGpuBuffers() const;
312 
313     struct StateDestroyConsumeStruct {
314         // gpu image or gpu buffers
315         BASE_NS::vector<RenderHandle> resources;
316     };
317     StateDestroyConsumeStruct ConsumeStateDestroyData();
318 
319     void* MapBuffer(const RenderHandleReference& handle) const;
320     void* MapBufferMemory(const RenderHandleReference& handle) const override;
321     void UnmapBuffer(const RenderHandleReference& handle) const override;
322 
323     void* MapBuffer(const RenderHandle& handle) const;
324     void* MapBufferMemory(const RenderHandle& handle) const;
325     void UnmapBuffer(const RenderHandle& handle) const;
326 
327     void WaitForIdleAndDestroyGpuResources() override;
328 
329     EngineResourceHandle GetGpuHandle(const RenderHandle& clientHandle) const;
330 
331     GpuBuffer* GetBuffer(const RenderHandle& gpuHandle) const;
332     GpuImage* GetImage(const RenderHandle& gpuHandle) const;
333     GpuSampler* GetSampler(const RenderHandle& gpuHandle) const;
334 
335     template<typename T>
GetBuffer(const RenderHandle & handle)336     T* GetBuffer(const RenderHandle& handle) const
337     {
338         return static_cast<T*>(GetBuffer(handle));
339     }
340     template<typename T>
GetImage(const RenderHandle & handle)341     T* GetImage(const RenderHandle& handle) const
342     {
343         return static_cast<T*>(GetImage(handle));
344     }
345     template<typename T>
GetSampler(const RenderHandle & handle)346     T* GetSampler(const RenderHandle& handle) const
347     {
348         return static_cast<T*>(GetSampler(handle));
349     }
350 
351     // for render graph to resizing (non-locked access only valid in certain positions)
352     uint32_t GetBufferHandleCount() const;
353     uint32_t GetImageHandleCount() const;
354 
355     bool IsGpuBuffer(const RenderHandleReference& handle) const override;
356     bool IsGpuImage(const RenderHandleReference& handle) const override;
357     bool IsGpuSampler(const RenderHandleReference& handle) const override;
358     bool IsGpuAccelerationStructure(const RenderHandleReference& handle) const override;
359     bool IsSwapchain(const RenderHandleReference& handle) const override;
360     bool IsMappableOutsideRender(const RenderHandleReference& handle) const override;
361     bool IsGpuBuffer(const RenderHandle& handle) const;
362     bool IsGpuImage(const RenderHandle& handle) const;
363     bool IsGpuSampler(const RenderHandle& handle) const;
364     bool IsGpuAccelerationStructure(const RenderHandle& handle) const;
365     bool IsSwapchain(const RenderHandle& handle) const;
366     bool IsValid(const RenderHandle& handle) const;
367 
368     FormatProperties GetFormatProperties(const RenderHandleReference& handle) const override;
369     FormatProperties GetFormatProperties(const RenderHandle& handle) const;
370     FormatProperties GetFormatProperties(BASE_NS::Format format) const override;
371 
372     GpuImageDesc CreateGpuImageDesc(const CORE_NS::IImageContainer::ImageDesc& desc) const override;
373 
374     BASE_NS::string GetName(const RenderHandle& handle) const;
375     BASE_NS::string GetName(const RenderHandleReference& handle) const override;
376 
377     BASE_NS::vector<RenderHandleReference> GetBufferHandles() const override;
378     BASE_NS::vector<RenderHandleReference> GetImageHandles() const override;
379     BASE_NS::vector<RenderHandleReference> GetSamplerHandles() const override;
380 
381     BASE_NS::vector<RenderHandle> GetRawBufferHandles() const;
382     BASE_NS::vector<RenderHandle> GetRawImageHandles() const;
383     BASE_NS::vector<RenderHandle> GetRawSamplerHandles() const;
384 
385     void SetDefaultGpuBufferCreationFlags(BufferUsageFlags usageFlags) override;
386     void SetDefaultGpuImageCreationFlags(ImageUsageFlags usageFlags) override;
387 
388     IGpuResourceCache& GetGpuResourceCache() const override;
389 
390     ImageAspectFlags GetImageAspectFlags(const RenderHandle& handle) const;
391     ImageAspectFlags GetImageAspectFlags(const RenderHandleReference& handle) const override;
392     ImageAspectFlags GetImageAspectFlags(BASE_NS::Format format) const override;
393 
394     BASE_NS::ColorSpaceFlags GetColorSpaceFlags() const override;
395     BASE_NS::Format GetColorSpaceFormat(
396         BASE_NS::Format format, BASE_NS::ColorSpaceFlags colorSpaceFlags) const override;
397 
398     SurfaceTransformFlags GetSurfaceTransformFlags(const RenderHandleReference& handle) const override;
399     SurfaceTransformFlags GetSurfaceTransformFlags(const RenderHandle& handle) const;
400 
401     RenderHandle ReserveRenderTimeGpuBuffer(uint32_t byteSize);
402     IRenderNodeGpuResourceManager::MappedGpuBufferData AcquireRenderTimeGpuBuffer(RenderHandle handle) const;
403 
404     enum class RenderTimeState : uint8_t {
405         UNDEFINED = 0,
406         RENDER_PRE_EXECUTE = 1,
407         RENDER_EXECUTE = 2,
408         RENDER_BACKEND = 3,
409     };
410     void SetState(RenderTimeState rts);
411 
412 private:
413     Device& device_;
414 
415     GpuResourceManagerFlags gpuResourceMgrFlags_ { 0 };
416 
417     BASE_NS::unique_ptr<GpuResourceManagerTyped<GpuBuffer, GpuBufferDesc>> gpuBufferMgr_;
418     BASE_NS::unique_ptr<GpuResourceManagerTyped<GpuImage, GpuImageDesc>> gpuImageMgr_;
419     BASE_NS::unique_ptr<GpuResourceManagerTyped<GpuSampler, GpuSamplerDesc>> gpuSamplerMgr_;
420 
421     BASE_NS::unique_ptr<GpuResourceCache> gpuResourceCache_;
422 
423     union ResourceDescriptor {
ResourceDescriptor(const GpuBufferDesc & descriptor)424         explicit ResourceDescriptor(const GpuBufferDesc& descriptor) : combinedBufDescriptor { {}, descriptor } {}
ResourceDescriptor(const GpuImageDesc & descriptor)425         explicit ResourceDescriptor(const GpuImageDesc& descriptor) : imageDescriptor(descriptor) {}
ResourceDescriptor(const GpuSamplerDesc & descriptor)426         explicit ResourceDescriptor(const GpuSamplerDesc& descriptor) : samplerDescriptor(descriptor) {}
ResourceDescriptor(const GpuAccelerationStructureDesc & descriptor)427         explicit ResourceDescriptor(const GpuAccelerationStructureDesc& descriptor) : combinedBufDescriptor(descriptor)
428         {}
429         // used for GpuBufferDesc as well
430         GpuAccelerationStructureDesc combinedBufDescriptor;
431         GpuImageDesc imageDescriptor;
432         GpuSamplerDesc samplerDescriptor;
433     };
434 
435     // combine alloc and de-alloc
436     // removed is a handle that is removed before pending allocation is called (i.e. destroyed)
437     enum class AllocType : uint8_t {
438         UNDEFINED = 0,
439         ALLOC = 1,
440         DEALLOC = 2,
441         REMOVED = 3,
442     };
443 
444     struct OperationDescription {
OperationDescriptionOperationDescription445         OperationDescription(
446             RenderHandle handle, const ResourceDescriptor& descriptor, AllocType allocType, uint32_t optResourceIndex)
447             : handle(handle), descriptor(descriptor), allocType(allocType), optionalResourceIndex(optResourceIndex),
448               optionalStagingVectorIndex(~0u), optionalStagingCopyType(StagingCopyStruct::CopyType::UNDEFINED)
449         {}
450 
451         RenderHandle handle;
452         ResourceDescriptor descriptor;
453         AllocType allocType { AllocType::UNDEFINED };
454         uint32_t optionalResourceIndex { ~0u };
455         uint32_t optionalStagingVectorIndex { ~0u };
456         StagingCopyStruct::CopyType optionalStagingCopyType { StagingCopyStruct::CopyType::UNDEFINED };
457     };
458     struct RemapDescription {
459         RenderHandle shallowClientHandle;
460         RenderHandle resourceClientHandle;
461     };
462     using BufferVector = BASE_NS::vector<BASE_NS::unique_ptr<GpuBuffer>>;
463     using ImageVector = BASE_NS::vector<BASE_NS::unique_ptr<GpuImage>>;
464 
465     struct PendingData {
466         BASE_NS::vector<OperationDescription> allocations;
467         // optional
468         BASE_NS::vector<BASE_NS::unique_ptr<GpuBuffer>> buffers; // pre-created
469         BASE_NS::vector<BASE_NS::unique_ptr<GpuImage>> images;   // pre-created
470         BASE_NS::vector<RemapDescription> remaps;
471     };
472 
473     mutable std::mutex allocationMutex_;
474     struct AdditionalData {
475         uintptr_t resourcePtr { 0 };
476         uint32_t indexToPendingData { ~0u }; // cleared to default when processed
477     };
478 
479     struct PerManagerStore {
480         const RenderHandleType handleType { RenderHandleType::UNDEFINED };
481         GpuResourceManagerBase* mgr { nullptr };
482 
483         // client access lock
484         mutable std::shared_mutex clientMutex {};
485 
486         // the following needs be locked with clientMutex
487         BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToClientIndex {};
488         // resource descriptions, accessed with RenderHandle array index
489         BASE_NS::vector<ResourceDescriptor> descriptions {};
490 
491         // handles might be invalid (when invalid generation is stored in high-bits, i.e. the handle is invalid)
492         BASE_NS::vector<RenderHandleReference> clientHandles {};
493 
494         // index to pending data, ptr to possible gpu buffer mapped data
495         BASE_NS::vector<AdditionalData> additionalData {};
496 
497         // handle ids which can be re-used
498         BASE_NS::vector<uint64_t> availableHandleIds {};
499 
500         PendingData pendingData {};
501 
502         // the following are not locked (ever)
503 
504         // handles might be invalid (when invalid generation is stored in high - bits, i.e.the handle is invalid)
505         BASE_NS::vector<EngineResourceHandle> gpuHandles {};
506         // ogl object name tagging not supported ATM
507 #if (RENDER_VULKAN_VALIDATION_ENABLED == 1)
508         BASE_NS::vector<RenderHandle> debugTagAllocations {};
509 #endif
510         void HandleRemoved(uint32_t arrayIndex, const OperationDescription& operation);
511         void HandleAlloc(uint32_t allocationIndex, const OperationDescription& operation);
512         bool HandleDealloc(uint32_t allocationIndex, const OperationDescription& operation, bool isFrameEnd);
513     };
514     PerManagerStore bufferStore_ { RenderHandleType::GPU_BUFFER };
515     PerManagerStore imageStore_ { RenderHandleType::GPU_IMAGE };
516     PerManagerStore samplerStore_ { RenderHandleType::GPU_SAMPLER };
517 
518     // needs to be locked when called
519     static uint64_t GetNextAvailableHandleId(PerManagerStore& mgrStore);
520 
521     struct StoreAllocationData {
522         RenderHandleReference handle;
523         size_t allocationIndex { ~0u };
524     };
525     struct StoreAllocationInfo {
526         ResourceDescriptor descriptor;
527         BASE_NS::string_view name;
528         RenderHandle replacedHandle {};
529         RenderHandleType type {};
530         uint32_t optResourceIndex { ~0u };
531         uint32_t addHandleFlags { 0u };
532         AllocType allocType { AllocType::ALLOC };
533     };
534 
535     void HandlePendingAllocationsImpl(bool isFrameEnd);
536     void HandleStorePendingAllocations(bool isFrameEnd, PerManagerStore& store);
537     void Destroy(const RenderHandle& handle);
538     // Destroy staging buffers. Not thread safe. Called from gpu resource manager
539     void DestroyFrameStaging();
540 
541     // needs to be locked when called
542     StoreAllocationData CreateBuffer(
543         BASE_NS::string_view name, const RenderHandle& replacedHandle, const GpuBufferDesc& desc);
544     // needs to be locked when called
545     StoreAllocationData CreateImage(
546         BASE_NS::string_view name, const RenderHandle& replacedHandle, const GpuImageDesc& desc);
547     RenderHandleReference CreateStagingBuffer(const GpuBufferDesc& desc);
548     // needs to be locked when called
549     StoreAllocationData CreateAccelerationStructure(
550         BASE_NS::string_view name, const RenderHandle& replacedHandle, const GpuAccelerationStructureDesc& desc);
551 
552     static RenderHandle CreateClientHandle(RenderHandleType type, const ResourceDescriptor& resourceDescriptor,
553         uint64_t handleId, uint32_t hasNameId, uint32_t additionalInfoFlags);
554 
555     // needs to be locked when called
556     StoreAllocationData StoreAllocation(PerManagerStore& store, const StoreAllocationInfo& info);
557 
558     void CreateGpuResource(
559         const OperationDescription& op, uint32_t arrayIndex, RenderHandleType resourceType, uintptr_t preCreateData);
560 
561     // needs to be locked when called
562     static void DestroyGpuResource(const OperationDescription& operation, uint32_t arrayIndex,
563         RenderHandleType resourceType, PerManagerStore& store);
564 
565     static RenderHandleReference GetHandle(const PerManagerStore& store, BASE_NS::string_view name);
566     static RenderHandleReference GetHandleNoLock(const PerManagerStore& store, BASE_NS::string_view name);
567     static RenderHandle GetRawHandle(const PerManagerStore& store, BASE_NS::string_view name);
568     static bool HasNamedResource(const PerManagerStore& store, BASE_NS::string_view name);
569 
570     static EngineResourceHandle GetGpuHandle(const PerManagerStore& store, const RenderHandle& clientHandle);
571 
572     // destroydHandle store needs to be locked, staging locked inside and bufferstore if not already locked
573     void RemoveStagingOperations(const OperationDescription& destroyAlloc);
574     // needs to be locked outside
575     void Destroy(PerManagerStore& store, const RenderHandle& handle);
576     // needs to be locked when called
577     static void DestroyImmediate(PerManagerStore& store, const RenderHandle& handle);
578 
579     static void HandlePendingRemappings(const BASE_NS::vector<RemapDescription>& pendingShallowRemappings,
580         BASE_NS::vector<EngineResourceHandle>& gpuHandles);
581 
582     static PendingData CommitPendingData(PerManagerStore& store);
583 
584     // needs to be locked when called
585     static uint32_t GetPendingOptionalResourceIndex(
586         const PerManagerStore& store, const RenderHandle& handle, BASE_NS::string_view name);
587 
588     // locked inside
589     static BASE_NS::vector<RenderHandleReference> GetHandles(const PerManagerStore& store);
590     static BASE_NS::vector<RenderHandle> GetRawHandles(const PerManagerStore& store);
591 
592     void DebugPrintValidCounts();
593 
594     // list of handles that state data should be destroyed
595     // (e.g. handle is replaced with a new resource or destroyed)
596     // information is passed to render graph
597     StateDestroyConsumeStruct clientHandleStateDestroy_;
598 
599     mutable std::mutex stagingMutex_;
600     StagingConsumeStruct stagingOperations_;   // needs to be locked
601     StagingConsumeStruct perFrameStagingData_; // per frame data after LockFrameStagingData()
602     BASE_NS::vector<RenderHandleReference> perFrameStagingBuffers_;
603     BASE_NS::vector<RenderHandleReference> perFrameStagingScalingImages_;
604 
605     // combined with bitwise OR buffer usage flags
606     BufferUsageFlags defaultBufferUsageFlags_ { 0u };
607     // combined with bitwise OR image usage flags
608     ImageUsageFlags defaultImageUsageFlags_ { 0u };
609 
610     struct RenderTimeReservedGpuBuffer {
611         // not threaded usage
612         RenderHandle baseHandle;
613         RenderHandleReference handle;
614 
615         void* mappedData { nullptr };
616         uint32_t neededByteSize { 0U };
617         uint32_t storedByteSize { 0U };
618 
619         struct SingleValue {
620             uint32_t byteOffset { 0U };
621             uint32_t byteSize { 0U };
622         };
623 
624         BASE_NS::vector<SingleValue> values;
625         BASE_NS::vector<SingleValue> executeValues;
626     };
627     RenderTimeReservedGpuBuffer renderTimeReservedGpuBuffer_;
628 
629     RenderTimeState renderTimeState_ { RenderTimeState::UNDEFINED };
630 
631     // ogl object name tagging not supported ATM
632 #if (RENDER_VULKAN_VALIDATION_ENABLED == 1)
633     void ProcessDebugTags();
634 #endif
635 };
636 
637 class RenderNodeGpuResourceManager final : public IRenderNodeGpuResourceManager {
638 public:
639     explicit RenderNodeGpuResourceManager(GpuResourceManager& gpuResourceManager);
640     ~RenderNodeGpuResourceManager() override;
641 
642     RenderHandleReference Get(const RenderHandle& handle) const override;
643     RenderHandle GetRawHandle(const RenderHandle& handle) const override;
644 
645     RenderHandleReference Create(const GpuBufferDesc& desc) override;
646     RenderHandleReference Create(BASE_NS::string_view name, const GpuBufferDesc& desc) override;
647     RenderHandleReference Create(const RenderHandleReference& handle, const GpuBufferDesc& desc) override;
648     RenderHandleReference Create(
649         BASE_NS::string_view name, const GpuBufferDesc& desc, BASE_NS::array_view<const uint8_t> data) override;
650 
651     RenderHandleReference Create(const GpuImageDesc& desc) override;
652     RenderHandleReference Create(BASE_NS::string_view name, const GpuImageDesc& desc) override;
653     RenderHandleReference Create(const RenderHandleReference& handle, const GpuImageDesc& desc) override;
654     RenderHandleReference Create(
655         BASE_NS::string_view name, const GpuImageDesc& desc, BASE_NS::array_view<const uint8_t> data) override;
656 
657     RenderHandleReference Create(const GpuSamplerDesc& desc) override;
658     RenderHandleReference Create(BASE_NS::string_view name, const GpuSamplerDesc& desc) override;
659     RenderHandleReference Create(const RenderHandleReference& handle, const GpuSamplerDesc& desc) override;
660 
661     RenderHandleReference Create(const GpuAccelerationStructureDesc& desc) override;
662     RenderHandleReference Create(BASE_NS::string_view name, const GpuAccelerationStructureDesc& desc) override;
663     RenderHandleReference Create(
664         const RenderHandleReference& handle, const GpuAccelerationStructureDesc& desc) override;
665 
666     RenderHandle GetBufferHandle(BASE_NS::string_view name) const override;
667     RenderHandle GetImageHandle(BASE_NS::string_view name) const override;
668     RenderHandle GetSamplerHandle(BASE_NS::string_view name) const override;
669 
670     GpuBufferDesc GetBufferDescriptor(const RenderHandle& handle) const override;
671     GpuImageDesc GetImageDescriptor(const RenderHandle& handle) const override;
672     GpuSamplerDesc GetSamplerDescriptor(const RenderHandle& handle) const override;
673     GpuAccelerationStructureDesc GetAccelerationStructureDescriptor(const RenderHandle& handle) const override;
674 
675     bool HasStagingData() const;
676     StagingConsumeStruct ConsumeStagingData();
677 
678     void* MapBuffer(const RenderHandle& handle) const override;
679     void* MapBufferMemory(const RenderHandle& handle) const override;
680     void UnmapBuffer(const RenderHandle& handle) const override;
681 
682     GpuResourceManager& GetGpuResourceManager();
683 
684     bool IsValid(const RenderHandle& handle) const override;
685     bool IsGpuBuffer(const RenderHandle& handle) const override;
686     bool IsGpuImage(const RenderHandle& handle) const override;
687     bool IsGpuSampler(const RenderHandle& handle) const override;
688     bool IsGpuAccelerationStructure(const RenderHandle& handle) const override;
689     bool IsSwapchain(const RenderHandle& handle) const override;
690 
691     FormatProperties GetFormatProperties(const RenderHandle& handle) const override;
692     FormatProperties GetFormatProperties(BASE_NS::Format format) const override;
693 
694     BASE_NS::string GetName(const RenderHandle& handle) const override;
695 
696     BASE_NS::vector<RenderHandle> GetBufferHandles() const override;
697     BASE_NS::vector<RenderHandle> GetImageHandles() const override;
698     BASE_NS::vector<RenderHandle> GetSamplerHandles() const override;
699 
700     IGpuResourceCache& GetGpuResourceCache() const override;
701 
702     ImageAspectFlags GetImageAspectFlags(const RenderHandle& handle) const override;
703     ImageAspectFlags GetImageAspectFlags(BASE_NS::Format format) const override;
704 
705     BASE_NS::ColorSpaceFlags GetColorSpaceFlags() const override;
706     BASE_NS::Format GetColorSpaceFormat(
707         BASE_NS::Format format, BASE_NS::ColorSpaceFlags colorSpaceFlags) const override;
708 
709     SurfaceTransformFlags GetSurfaceTransformFlags(const RenderHandle& handle) const override;
710 
711     RenderHandle ReserveGpuBuffer(uint32_t byteSize) override;
712     MappedGpuBufferData AcquireGpubuffer(RenderHandle handle) override;
713 
714 private:
715     GpuResourceManager& gpuResourceMgr_;
716 };
717 RENDER_END_NAMESPACE()
718 
719 #endif // DEVICE_GPU_RESOURCE_MANAGER_H
720