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