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