A game about forced loneliness, made by TACStudios
at master 1257 lines 58 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Diagnostics; 4using System.Runtime.CompilerServices; 5using UnityEngine.Experimental.Rendering; 6using UnityEngine.Scripting.APIUpdating; 7// Typedefs for the in-engine RendererList API (to avoid conflicts with the experimental version) 8using CoreRendererList = UnityEngine.Rendering.RendererList; 9using CoreRendererListDesc = UnityEngine.Rendering.RendererUtils.RendererListDesc; 10 11namespace UnityEngine.Rendering.RenderGraphModule 12{ 13 /// <summary> 14 /// Basic properties of a RTHandle needed by the render graph compiler. It is not always possible to derive these 15 /// given an RTHandle so the user needs to pass these in. 16 /// 17 /// We don't use a full RenderTargetDescriptor here as filling out a full descriptor may not be trivial for users and not all 18 /// members of the descriptor are actually used by the render graph. This struct is the minimum set of info needed by the render graph. 19 /// If you want to develop some utility framework to work with render textures, etc. it's probably better to use RenderTargetDescriptor. 20 /// </summary> 21 [MovedFrom(true, "UnityEngine.Experimental.Rendering.RenderGraphModule", "UnityEngine.Rendering.RenderGraphModule")] 22 public struct RenderTargetInfo 23 { 24 /// <summary> 25 /// The width in pixels of the render texture. 26 /// </summary> 27 public int width; 28 /// <summary> 29 /// The height in pixels of the render texture. 30 /// </summary> 31 public int height; 32 /// <summary> 33 /// The number of volume/array slices of the render texture. 34 /// </summary> 35 public int volumeDepth; 36 /// <summary> 37 /// The number of msaa samples in the render texture. 38 /// </summary> 39 public int msaaSamples; 40 /// <summary> 41 /// The Graphics format of the render texture. 42 /// </summary> 43 public GraphicsFormat format; 44 /// <summary> 45 /// Set to true if the render texture needs to be bound as a multisampled texture in a shader. 46 /// </summary> 47 public bool bindMS; 48 } 49 50 /// <summary> 51 /// A helper struct describing the clear behavior of imported textures. 52 /// </summary> 53 public struct ImportResourceParams 54 { 55 /// <summary> 56 /// Clear the imported texture the first time it is used by the graph. 57 /// </summary> 58 public bool clearOnFirstUse; 59 /// <summary> 60 /// The color to clear with on first use. Ignored if clearOnFirstUse==false; 61 /// </summary> 62 public Color clearColor; 63 /// <summary> 64 /// Discard the imported texture the last time it is used by the graph. 65 /// If MSAA enabled, only the multisampled version is discarded while the MSAA surface is always resolved. 66 /// Fully discarding both multisampled and resolved data is not currently possible. 67 /// </summary> 68 public bool discardOnLastUse; 69 } 70 71 class RenderGraphResourceRegistry 72 { 73 const int kSharedResourceLifetime = 30; 74 75 static RenderGraphResourceRegistry m_CurrentRegistry; 76 internal static RenderGraphResourceRegistry current 77 { 78 get 79 { 80 // We assume that it's enough to only check in editor because we don't want to pay the cost at runtime. 81#if UNITY_EDITOR 82 if (m_CurrentRegistry == null) 83 { 84 throw new InvalidOperationException("Current Render Graph Resource Registry is not set. You are probably trying to cast a Render Graph handle to a resource outside of a Render Graph Pass."); 85 } 86#endif 87 return m_CurrentRegistry; 88 } 89 set 90 { 91 m_CurrentRegistry = value; 92 } 93 } 94 95 delegate bool ResourceCreateCallback(InternalRenderGraphContext rgContext, IRenderGraphResource res); 96 delegate void ResourceCallback(InternalRenderGraphContext rgContext, IRenderGraphResource res); 97 98 class RenderGraphResourcesData 99 { 100 public DynamicArray<IRenderGraphResource> resourceArray = new DynamicArray<IRenderGraphResource>(); 101 public int sharedResourcesCount; 102 public IRenderGraphResourcePool pool; 103 public ResourceCreateCallback createResourceCallback; 104 public ResourceCallback releaseResourceCallback; 105 106 public RenderGraphResourcesData() 107 { 108 resourceArray.Resize(1); // Element 0 is the null element 109 } 110 111 public void Clear(bool onException, int frameIndex) 112 { 113 resourceArray.Resize(sharedResourcesCount+1); // First N elements are reserved for shared persistent resources and are kept as is. Element 0 is null 114 115 if (pool != null) 116 pool.CheckFrameAllocation(onException, frameIndex); 117 } 118 119 public void Cleanup() 120 { 121 // Cleanup all shared resources. 122 for (int i = 1; i < sharedResourcesCount+1; ++i) 123 { 124 var resource = resourceArray[i]; 125 if (resource != null) 126 { 127 resource.ReleaseGraphicsResource(); 128 } 129 } 130 // Then cleanup the pool 131 if (pool != null) 132 pool.Cleanup(); 133 } 134 135 public void PurgeUnusedGraphicsResources(int frameIndex) 136 { 137 if (pool != null) 138 pool.PurgeUnusedResources(frameIndex); 139 } 140 141 public int AddNewRenderGraphResource<ResType>(out ResType outRes, bool pooledResource = true) 142 where ResType : IRenderGraphResource, new() 143 { 144 // In order to not create garbage, instead of using Add, we keep the content of the array while resizing and we just reset the existing ref (or create it if it's null). 145 int result = resourceArray.size; 146 resourceArray.Resize(resourceArray.size + 1, true); 147 if (resourceArray[result] == null) 148 resourceArray[result] = new ResType(); 149 150 outRes = resourceArray[result] as ResType; 151 outRes.Reset(pooledResource ? pool : null); 152 return result; 153 } 154 } 155 156 RenderGraphResourcesData[] m_RenderGraphResources = new RenderGraphResourcesData[(int)RenderGraphResourceType.Count]; 157 DynamicArray<RendererListResource> m_RendererListResources = new DynamicArray<RendererListResource>(); 158 DynamicArray<RendererListLegacyResource> m_RendererListLegacyResources = new DynamicArray<RendererListLegacyResource>(); 159 160 RenderGraphDebugParams m_RenderGraphDebug; 161 RenderGraphLogger m_ResourceLogger = new RenderGraphLogger(); 162 RenderGraphLogger m_FrameInformationLogger; // Comes from the RenderGraph instance. 163 int m_CurrentFrameIndex; 164 int m_ExecutionCount; 165 166 RTHandle m_CurrentBackbuffer; 167 168 const int kInitialRendererListCount = 256; 169 List<CoreRendererList> m_ActiveRendererLists = new List<CoreRendererList>(kInitialRendererListCount); 170 171 #region Internal Interface 172 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 173 void CheckTextureResource(TextureResource texResource) 174 { 175 if (texResource.graphicsResource == null && !texResource.imported) 176 throw new InvalidOperationException($"Trying to use a texture ({texResource.GetName()}) that was already released or not yet created. Make sure you declare it for reading in your pass or you don't read it before it's been written to at least once."); 177 } 178 179 internal RTHandle GetTexture(in TextureHandle handle) 180 { 181 if (!handle.IsValid()) 182 return null; 183 184 var texResource = GetTextureResource(handle.handle); 185 CheckTextureResource(texResource); 186 return texResource.graphicsResource; 187 } 188 189 // This index overload will not check frame validity. 190 // Its only purpose is because the NRP compiled graph stores resource handles that would not be frame valid when reused. 191 internal RTHandle GetTexture(int index) 192 { 193 var texResource = GetTextureResource(index); 194 CheckTextureResource(texResource); 195 return texResource.graphicsResource; 196 } 197 198 internal bool TextureNeedsFallback(in TextureHandle handle) 199 { 200 if (!handle.IsValid()) 201 return false; 202 203 return GetTextureResource(handle.handle).NeedsFallBack(); 204 } 205 206 internal CoreRendererList GetRendererList(in RendererListHandle handle) 207 { 208 if (!handle.IsValid()) 209 return CoreRendererList.nullRendererList; 210 211 switch (handle.type) 212 { 213 case RendererListHandleType.Renderers: 214 { 215 if (handle >= m_RendererListResources.size) 216 return CoreRendererList.nullRendererList; 217 return m_RendererListResources[handle].rendererList; 218 } 219 case RendererListHandleType.Legacy: 220 { 221 if (handle >= m_RendererListLegacyResources.size) 222 return CoreRendererList.nullRendererList; 223 if (!m_RendererListLegacyResources[handle].isActive) 224 return CoreRendererList.nullRendererList; 225 return m_RendererListLegacyResources[handle].rendererList; 226 } 227 } 228 229 return CoreRendererList.nullRendererList; 230 } 231 232 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 233 void CheckBufferResource(BufferResource bufferResource) 234 { 235 if (bufferResource.graphicsResource == null) 236 throw new InvalidOperationException($"Trying to use a graphics buffer ({bufferResource.GetName()}) that was already released or not yet created. Make sure you declare it for reading in your pass or you don't read it before it's been written to at least once."); 237 } 238 239 internal GraphicsBuffer GetBuffer(in BufferHandle handle) 240 { 241 if (!handle.IsValid()) 242 return null; 243 244 var bufferResource = GetBufferResource(handle.handle); 245 CheckBufferResource(bufferResource); 246 247 return bufferResource.graphicsResource; 248 } 249 250 // This index overload will not check frame validity. 251 // Its only purpose is because the NRP compiled graph stores resource handles that would not be frame valid when reused. 252 internal GraphicsBuffer GetBuffer(int index) 253 { 254 var bufferResource = GetBufferResource(index); 255 CheckBufferResource(bufferResource); 256 257 return bufferResource.graphicsResource; 258 } 259 260 internal RayTracingAccelerationStructure GetRayTracingAccelerationStructure(in RayTracingAccelerationStructureHandle handle) 261 { 262 if (!handle.IsValid()) 263 return null; 264 265 var accelStructureResource = GetRayTracingAccelerationStructureResource(handle.handle); 266 var resource = accelStructureResource.graphicsResource; 267#if DEVELOPMENT_BUILD || UNITY_EDITOR 268 if (resource == null) 269 throw new InvalidOperationException($"Trying to use a acceleration structure ({accelStructureResource.GetName()}) that was already released or not yet created. Make sure you declare it for reading in your pass or you don't read it before it's been written to at least once."); 270#endif 271 272 return resource; 273 } 274 275 internal int GetSharedResourceCount(RenderGraphResourceType type) 276 { 277 return m_RenderGraphResources[(int)type].sharedResourcesCount; 278 } 279 280 private RenderGraphResourceRegistry() 281 { 282 } 283 284 internal RenderGraphResourceRegistry(RenderGraphDebugParams renderGraphDebug, RenderGraphLogger frameInformationLogger) 285 { 286 m_RenderGraphDebug = renderGraphDebug; 287 m_FrameInformationLogger = frameInformationLogger; 288 289 for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i) 290 { 291 m_RenderGraphResources[i] = new RenderGraphResourcesData(); 292 } 293 294 m_RenderGraphResources[(int)RenderGraphResourceType.Texture].createResourceCallback = CreateTextureCallback; 295 m_RenderGraphResources[(int)RenderGraphResourceType.Texture].releaseResourceCallback = ReleaseTextureCallback; 296 m_RenderGraphResources[(int)RenderGraphResourceType.Texture].pool = new TexturePool(); 297 298 m_RenderGraphResources[(int)RenderGraphResourceType.Buffer].pool = new BufferPool(); 299 300 // RayTracingAccelerationStructures can be imported only. 301 m_RenderGraphResources[(int)RenderGraphResourceType.AccelerationStructure].pool = null; 302 } 303 304 internal void BeginRenderGraph(int executionCount) 305 { 306 m_ExecutionCount = executionCount; 307 ResourceHandle.NewFrame(executionCount); 308 309 // We can log independently of current execution name since resources are shared across all executions of render graph. 310 if (m_RenderGraphDebug.enableLogging) 311 m_ResourceLogger.Initialize("RenderGraph Resources"); 312 } 313 314 internal void BeginExecute(int currentFrameIndex) 315 { 316 m_CurrentFrameIndex = currentFrameIndex; 317 ManageSharedRenderGraphResources(); 318 current = this; 319 } 320 321 internal void EndExecute() 322 { 323 current = null; 324 } 325 326 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 327 [MethodImpl(MethodImplOptions.AggressiveInlining)] 328 void CheckHandleValidity(in ResourceHandle res) 329 { 330 CheckHandleValidity(res.type, res.index); 331 } 332 333 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 334 void CheckHandleValidity(RenderGraphResourceType type, int index) 335 { 336 if(RenderGraph.enableValidityChecks) 337 { 338 var resources = m_RenderGraphResources[(int)type].resourceArray; 339 if (index == 0) 340 throw new ArgumentException($"Trying to access resource of type {type} with an null resource index."); 341 if (index >= resources.size) 342 throw new ArgumentException($"Trying to access resource of type {type} with an invalid resource index {index}"); 343 } 344 } 345 346 internal void IncrementWriteCount(in ResourceHandle res) 347 { 348 CheckHandleValidity(res); 349 m_RenderGraphResources[res.iType].resourceArray[res.index].IncrementWriteCount(); 350 } 351 352 internal void NewVersion(in ResourceHandle res) 353 { 354 CheckHandleValidity(res); 355 m_RenderGraphResources[res.iType].resourceArray[res.index].NewVersion(); 356 } 357 358 internal ResourceHandle GetLatestVersionHandle(in ResourceHandle res) 359 { 360 CheckHandleValidity(res); 361 var ver = m_RenderGraphResources[res.iType].resourceArray[res.index].version; 362 if (IsRenderGraphResourceShared(res)) 363 { 364 ver -= m_ExecutionCount; //TODO(ddebaets) is this a good solution ? 365 } 366 return new ResourceHandle(res, ver); 367 } 368 369 internal int GetLatestVersionNumber(in ResourceHandle res) 370 { 371 CheckHandleValidity(res); 372 var ver = m_RenderGraphResources[res.iType].resourceArray[res.index].version; 373 if (IsRenderGraphResourceShared(res)) 374 { 375 ver -= m_ExecutionCount;//TODO(ddebaets) is this a good solution ? 376 } 377 return ver; 378 } 379 380 internal ResourceHandle GetZeroVersionedHandle(in ResourceHandle res) 381 { 382 CheckHandleValidity(res); 383 return new ResourceHandle(res, 0); 384 } 385 386 internal ResourceHandle GetNewVersionedHandle(in ResourceHandle res) 387 { 388 CheckHandleValidity(res); 389 var ver = m_RenderGraphResources[res.iType].resourceArray[res.index].NewVersion(); 390 if (IsRenderGraphResourceShared(res)) 391 { 392 ver -= m_ExecutionCount;//TODO(ddebaets) is this a good solution ? 393 } 394 return new ResourceHandle(res, ver); 395 } 396 397 internal IRenderGraphResource GetResourceLowLevel(in ResourceHandle res) 398 { 399 CheckHandleValidity(res); 400 return m_RenderGraphResources[res.iType].resourceArray[res.index]; 401 } 402 403 internal string GetRenderGraphResourceName(in ResourceHandle res) 404 { 405 CheckHandleValidity(res); 406 return m_RenderGraphResources[res.iType].resourceArray[res.index].GetName(); 407 } 408 409 internal string GetRenderGraphResourceName(RenderGraphResourceType type, int index) 410 { 411 CheckHandleValidity(type, index); 412 return m_RenderGraphResources[(int)type].resourceArray[index].GetName(); 413 } 414 415 internal bool IsRenderGraphResourceImported(in ResourceHandle res) 416 { 417 CheckHandleValidity(res); 418 return m_RenderGraphResources[res.iType].resourceArray[res.index].imported; 419 } 420 421 internal bool IsRenderGraphResourceForceReleased(RenderGraphResourceType type, int index) 422 { 423 CheckHandleValidity(type, index); 424 return m_RenderGraphResources[(int)type].resourceArray[index].forceRelease; 425 } 426 427 internal bool IsRenderGraphResourceShared(RenderGraphResourceType type, int index) 428 { 429 CheckHandleValidity(type, index); 430 return index <= m_RenderGraphResources[(int)type].sharedResourcesCount; 431 } 432 433 internal bool IsRenderGraphResourceShared(in ResourceHandle res) => IsRenderGraphResourceShared(res.type, res.index); 434 435 internal bool IsGraphicsResourceCreated(in ResourceHandle res) 436 { 437 CheckHandleValidity(res); 438 return m_RenderGraphResources[res.iType].resourceArray[res.index].IsCreated(); 439 } 440 441 internal bool IsRendererListCreated(in RendererListHandle res) 442 { 443 switch (res.type) 444 { 445 case RendererListHandleType.Renderers: 446 return m_RendererListResources[res].rendererList.isValid; 447 case RendererListHandleType.Legacy: 448 return m_RendererListLegacyResources[res].isActive && m_RendererListLegacyResources[res].rendererList.isValid; 449 } 450 return false; 451 } 452 453 internal bool IsRenderGraphResourceImported(RenderGraphResourceType type, int index) 454 { 455 CheckHandleValidity(type, index); 456 return m_RenderGraphResources[(int)type].resourceArray[index].imported; 457 } 458 459 internal int GetRenderGraphResourceTransientIndex(in ResourceHandle res) 460 { 461 CheckHandleValidity(res); 462 return m_RenderGraphResources[res.iType].resourceArray[res.index].transientPassIndex; 463 } 464 465 // Texture Creation/Import APIs are internal because creation should only go through RenderGraph 466 internal TextureHandle ImportTexture(in RTHandle rt, bool isBuiltin = false) 467 { 468 ImportResourceParams importParams = new ImportResourceParams(); 469 importParams.clearOnFirstUse = false; 470 importParams.discardOnLastUse = false; 471 472 return ImportTexture(rt, importParams, isBuiltin); 473 } 474 475 // Texture Creation/Import APIs are internal because creation should only go through RenderGraph 476 internal TextureHandle ImportTexture(in RTHandle rt, in ImportResourceParams importParams, bool isBuiltin = false) 477 { 478 // Apparently existing code tries to import null textures !?? So we sort of allow them then :( 479 // Not sure what this actually "means" it allocates a RG handle but nothing is behind it 480 if (rt != null) 481 { 482 // Imported, try to get back to the original handle we imported and get the properties from there 483 if (rt.m_RT != null) 484 { 485 // RTHandle wrapping a RenderTexture, ok we can get properties from that 486 } 487 else if (rt.m_ExternalTexture != null) 488 { 489 // RTHandle wrapping a regular 2D texture we can't render to that 490 } 491#if DEVELOPMENT_BUILD || UNITY_EDITOR 492 else if (rt.m_NameID != emptyId) 493 { 494 495 // RTHandle wrapping a RenderTargetIdentifier 496 throw new Exception("Invalid import, you are importing a texture handle that wraps a RenderTargetIdentifier. The render graph can't know the properties of these textures so please use the ImportTexture overload that takes a RenderTargetInfo argument instead."); 497 } 498 else 499 { 500 throw new Exception("Invalid render target handle: RT, External texture and NameID are all null or zero."); 501 } 502#endif 503 } 504 505 int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out TextureResource texResource); 506 texResource.graphicsResource = rt; 507 texResource.imported = true; 508 509 RenderTexture renderTexture = (rt != null) ? ((rt.m_RT != null) ? rt.m_RT : (rt.m_ExternalTexture as RenderTexture)) : null; 510 if (renderTexture) 511 { 512 texResource.desc = new TextureDesc(renderTexture); 513 texResource.validDesc = true; 514 } 515 texResource.desc.clearBuffer = importParams.clearOnFirstUse; 516 texResource.desc.clearColor = importParams.clearColor; 517 texResource.desc.discardBuffer = importParams.discardOnLastUse; 518 519 var texHandle = new TextureHandle(newHandle, false, isBuiltin); 520 521 // Try getting the info straight away so if something is wrong we throw at import time. 522 // It is invalid to import a texture if we can't get its info somehow. 523 // (The alternative is for the code calling ImportTexture to use the overload that takes a RenderTargetInfo). 524 if(rt != null) 525 ValidateRenderTarget(texHandle.handle); 526 527 return texHandle; 528 } 529 530 // Texture Creation/Import APIs are internal because creation should only go through RenderGraph 531 internal TextureHandle ImportTexture(in RTHandle rt, RenderTargetInfo info, in ImportResourceParams importParams) 532 { 533 int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out TextureResource texResource); 534 texResource.graphicsResource = rt; 535 texResource.imported = true; 536 // Be sure to clear the desc to the default state 537 texResource.desc = new TextureDesc(); 538 539 // Apparently existing code tries to import null textures !?? So we sort of allow them then :( 540 if (rt != null) 541 { 542 if (rt.m_NameID != emptyId) 543 { 544 // Store the info in the descriptor structure to avoid having a separate info structure being saved per resource 545 // This descriptor will then be used to reconstruct the info (see GetRenderTargetInfo) but is not a full featured descriptor. 546 // This is ok as this descriptor will never be used to create textures (as they are imported into the graph and thus externally created). 547 548 texResource.desc.format = info.format; 549 texResource.desc.width = info.width; 550 texResource.desc.height = info.height; 551 texResource.desc.slices = info.volumeDepth; 552 texResource.desc.msaaSamples = (MSAASamples)info.msaaSamples; 553 texResource.desc.bindTextureMS = info.bindMS; 554 texResource.desc.clearBuffer = importParams.clearOnFirstUse; 555 texResource.desc.clearColor = importParams.clearColor; 556 texResource.desc.discardBuffer = importParams.discardOnLastUse; 557 texResource.validDesc = false; // The desc above just contains enough info to make RenderTargetInfo not a full descriptor. 558 // This means GetRenderTargetInfo will work for the handle but GetTextureResourceDesc will throw 559 } 560 // Anything else is an error and should take the overload not taking a RenderTargetInfo 561 else 562 { 563#if DEVELOPMENT_BUILD || UNITY_EDITOR 564 throw new Exception("Invalid import, you are importing a texture handle that isn't wrapping a RenderTargetIdentifier. You cannot use the overload taking RenderTargetInfo as the graph will automatically determine the texture properties based on the passed in handle."); 565#endif 566 } 567 } 568 else 569 { 570#if DEVELOPMENT_BUILD || UNITY_EDITOR 571 throw new Exception("Invalid import, null handle."); 572#endif 573 } 574 575 var texHandle = new TextureHandle(newHandle); 576 577 // Try getting the info straight away so if something is wrong we throw at import time. 578 ValidateRenderTarget(texHandle.handle); 579 580 return texHandle; 581 } 582 583 internal TextureHandle CreateSharedTexture(in TextureDesc desc, bool explicitRelease) 584 { 585 var textureResources = m_RenderGraphResources[(int)RenderGraphResourceType.Texture]; 586 int sharedTextureCount = textureResources.sharedResourcesCount; 587 588 Debug.Assert(textureResources.resourceArray.size <= sharedTextureCount+1); 589 590 // try to find an available slot. 591 TextureResource texResource = null; 592 int textureIndex = -1; 593 594 for (int i = 1; i < sharedTextureCount+1; ++i) 595 { 596 var resource = textureResources.resourceArray[i]; 597 if (resource.shared == false) // unused 598 { 599 texResource = (TextureResource)textureResources.resourceArray[i]; 600 textureIndex = i; 601 break; 602 } 603 } 604 605 // if none is available, add a new resource. 606 if (texResource == null) 607 { 608 textureIndex = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out texResource, pooledResource: false); 609 textureResources.sharedResourcesCount++; 610 } 611 612 texResource.imported = true; 613 texResource.shared = true; 614 texResource.sharedExplicitRelease = explicitRelease; 615 texResource.desc = desc; 616 texResource.validDesc = true; 617 618 return new TextureHandle(textureIndex, shared: true); 619 } 620 621 internal void RefreshSharedTextureDesc(in TextureHandle texture, in TextureDesc desc) 622 { 623#if DEVELOPMENT_BUILD || UNITY_EDITOR 624 if (!IsRenderGraphResourceShared(RenderGraphResourceType.Texture, texture.handle.index)) 625 { 626 throw new InvalidOperationException($"Trying to refresh texture {texture} that is not a shared resource."); 627 } 628#endif 629 var texResource = GetTextureResource(texture.handle); 630 texResource.ReleaseGraphicsResource(); 631 texResource.desc = desc; 632 } 633 634 internal void ReleaseSharedTexture(in TextureHandle texture) 635 { 636 var texResources = m_RenderGraphResources[(int)RenderGraphResourceType.Texture]; 637 638#if DEVELOPMENT_BUILD || UNITY_EDITOR 639 if (texture.handle.index == 0 || texture.handle.index >= texResources.sharedResourcesCount+1) 640 throw new InvalidOperationException("Tried to release a non shared texture."); 641#endif 642 643 // Decrement if we release the last one. 644 if (texture.handle.index == (texResources.sharedResourcesCount)) 645 texResources.sharedResourcesCount--; 646 647 var texResource = GetTextureResource(texture.handle); 648 texResource.ReleaseGraphicsResource(); 649 texResource.Reset(); 650 } 651 652 internal TextureHandle ImportBackbuffer(RenderTargetIdentifier rt, in RenderTargetInfo info, in ImportResourceParams importParams) 653 { 654 if (m_CurrentBackbuffer != null) 655 m_CurrentBackbuffer.SetTexture(rt); 656 else 657 m_CurrentBackbuffer = RTHandles.Alloc(rt, "Backbuffer"); 658 659 int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out TextureResource texResource); 660 texResource.graphicsResource = m_CurrentBackbuffer; 661 texResource.imported = true; 662 texResource.desc = new TextureDesc(); 663 texResource.desc.width = info.width; 664 texResource.desc.height = info.height; 665 texResource.desc.slices = info.volumeDepth; 666 texResource.desc.msaaSamples = (MSAASamples)info.msaaSamples; 667 texResource.desc.bindTextureMS = info.bindMS; 668 texResource.desc.format = info.format; 669 texResource.desc.clearBuffer = importParams.clearOnFirstUse; 670 texResource.desc.clearColor = importParams.clearColor; 671 texResource.desc.discardBuffer = importParams.discardOnLastUse; 672 texResource.validDesc = false;// The desc above just contains enough info to make RenderTargetInfo not a full descriptor. 673 // This means GetRenderTargetInfo will work for the handle but GetTextureResourceDesc will throw 674 675 var texHandle = new TextureHandle(newHandle); 676 677 // Try getting the info straight away so if something wrong we get the exceptions directly at import time. 678 ValidateRenderTarget(texHandle.handle); 679 680 return texHandle; 681 } 682 683 static RenderTargetIdentifier emptyId = new RenderTargetIdentifier(); 684 static RenderTargetIdentifier builtinCameraRenderTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget); 685 686 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 687 private void ValidateRenderTarget(in ResourceHandle res) 688 { 689 if(RenderGraph.enableValidityChecks) 690 { 691 RenderTargetInfo outInfo; 692 GetRenderTargetInfo(res, out outInfo); 693 } 694 } 695 696 internal void GetRenderTargetInfo(in ResourceHandle res, out RenderTargetInfo outInfo) 697 { 698#if DEVELOPMENT_BUILD || UNITY_EDITOR 699 if (res.iType != (int)RenderGraphResourceType.Texture) 700 { 701 outInfo = new RenderTargetInfo(); 702 throw new ArgumentException("Invalid Resource Handle passed to GetRenderTargetInfo"); 703 } 704#endif 705 // You can never have enough ways to reference a render target... 706 // Lots of legacy if's and but's 707 TextureResource tex = GetTextureResource(res); 708 if (tex.imported) 709 { 710 // Imported, try to get back to the original handle we imported and get the properties from there 711 RTHandle handle = tex.graphicsResource; 712 if (handle == null) 713 { 714 // Apparently existing code tries to import null textures !?? So we sort of allow them then :( 715 // throw new Exception("Invalid imported texture. The RTHandle provided was null."); 716 outInfo = new RenderTargetInfo(); 717 } 718 else if (handle.m_RT != null) 719 { 720 outInfo = new RenderTargetInfo(); 721 outInfo.width = handle.m_RT.width; 722 outInfo.height = handle.m_RT.height; 723 outInfo.volumeDepth = handle.m_RT.volumeDepth; 724 outInfo.format = GetFormat(handle.m_RT.graphicsFormat, handle.m_RT.depthStencilFormat); 725 outInfo.msaaSamples = handle.m_RT.antiAliasing; 726 outInfo.bindMS = handle.m_RT.bindTextureMS; 727 } 728 else if (handle.m_ExternalTexture != null) 729 { 730 outInfo = new RenderTargetInfo(); 731 outInfo.width = handle.m_ExternalTexture.width; 732 outInfo.height = handle.m_ExternalTexture.height; 733 outInfo.volumeDepth = 1; // XRTODO: Check dimension instead? 734 if (handle.m_ExternalTexture is RenderTexture) 735 { 736 RenderTexture rt = (RenderTexture)handle.m_ExternalTexture; 737 outInfo.format = GetFormat(rt.graphicsFormat, rt.depthStencilFormat); 738 outInfo.msaaSamples = rt.antiAliasing; 739 } 740 else 741 { 742 //Note: This case will likely not work when used as an actual rendertarget. This is a regular 2D, Cube,... 743 //texture an not a rendertarget texture so it will fail when bound as a rendertarget later. 744 outInfo.format = handle.m_ExternalTexture.graphicsFormat; 745 outInfo.msaaSamples = 1; 746 } 747 outInfo.bindMS = false; 748 } 749 else if (handle.m_NameID != emptyId) 750 { 751 // WE can't really get info about RenderTargetIdentifier back. It simply doesn't expose this info. 752 // But in some cases like the camera built-in target it also cant. If it's a BuiltinRenderTextureType 753 // we can't know from the size/format/... from the enum. It's implicitly defined by the current camera, 754 // screen resolution,.... we can't even hope to know or replicate the size calculation here 755 // so we just say we don't know what this rt is and rely on the user passing in the info to us. 756 var desc = GetTextureResourceDesc(res, true); 757 outInfo = new RenderTargetInfo(); 758#if DEVELOPMENT_BUILD || UNITY_EDITOR 759 if (desc.width == 0 || desc.height == 0 || desc.slices == 0 || desc.msaaSamples == 0 || desc.format == GraphicsFormat.None) 760 { 761 throw new Exception("Invalid imported texture. A RTHandle wrapping an RenderTargetIdentifier was imported without providing valid RenderTargetInfo."); 762 } 763#endif 764 outInfo.width = desc.width; 765 outInfo.height = desc.height; 766 outInfo.volumeDepth = desc.slices; 767 768 outInfo.msaaSamples = (int)desc.msaaSamples; 769 outInfo.format = desc.format; 770 outInfo.bindMS = desc.bindTextureMS; 771 } 772 else 773 { 774 throw new Exception("Invalid imported texture. The RTHandle provided is invalid."); 775 } 776 } 777 else 778 { 779 // Managed by rendergraph, it might not be created yet so we look at the desc to find out 780 var desc = GetTextureResourceDesc(res); 781 var dim = desc.CalculateFinalDimensions(); 782 outInfo = new RenderTargetInfo(); 783 outInfo.width = dim.x; 784 outInfo.height = dim.y; 785 outInfo.volumeDepth = desc.slices; 786 787 outInfo.msaaSamples = (int)desc.msaaSamples; 788 outInfo.bindMS = desc.bindTextureMS; 789 outInfo.format = desc.format; 790 } 791 } 792 793 internal GraphicsFormat GetFormat(GraphicsFormat color, GraphicsFormat depthStencil) 794 { 795 ValidateFormat(color, depthStencil); 796 return (depthStencil != GraphicsFormat.None) ? depthStencil : color; 797 } 798 799 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 800 internal void ValidateFormat(GraphicsFormat color, GraphicsFormat depthStencil) 801 { 802 if (RenderGraph.enableValidityChecks) 803 { 804 if (color != GraphicsFormat.None && depthStencil != GraphicsFormat.None) 805 { 806 throw new Exception("Invalid imported texture. Both a color and a depthStencil format are provided. The texture needs to either have a color format or a depth stencil format."); 807 } 808 } 809 } 810 811 internal TextureHandle CreateTexture(in TextureDesc desc, int transientPassIndex = -1) 812 { 813 ValidateTextureDesc(desc); 814 815 int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out TextureResource texResource); 816 texResource.desc = desc; 817 texResource.validDesc = true; 818 texResource.transientPassIndex = transientPassIndex; 819 texResource.requestFallBack = desc.fallBackToBlackTexture; 820 return new TextureHandle(newHandle); 821 } 822 823 internal int GetResourceCount(RenderGraphResourceType type) 824 { 825 return m_RenderGraphResources[(int)type].resourceArray.size; 826 } 827 828 internal int GetTextureResourceCount() 829 { 830 return GetResourceCount(RenderGraphResourceType.Texture); 831 } 832 833 internal TextureResource GetTextureResource(in ResourceHandle handle) 834 { 835 Debug.Assert(handle.type == RenderGraphResourceType.Texture); 836 return m_RenderGraphResources[(int)RenderGraphResourceType.Texture].resourceArray[handle.index] as TextureResource; 837 } 838 839 internal TextureResource GetTextureResource(int index) 840 { 841 return m_RenderGraphResources[(int)RenderGraphResourceType.Texture].resourceArray[index] as TextureResource; 842 } 843 844 internal TextureDesc GetTextureResourceDesc(in ResourceHandle handle, bool noThrowOnInvalidDesc = false) 845 { 846 Debug.Assert(handle.type == RenderGraphResourceType.Texture); 847 var texture = (m_RenderGraphResources[(int)RenderGraphResourceType.Texture].resourceArray[handle.index] as TextureResource); 848 if (!texture.validDesc && !noThrowOnInvalidDesc) 849 throw new ArgumentException("The passed in texture handle does not have a valid descriptor. (This is most commonly cause by the handle referencing a built-in texture such as the system back buffer.)", "handle"); 850 return texture.desc; 851 } 852 853 internal RendererListHandle CreateRendererList(in CoreRendererListDesc desc) 854 { 855 ValidateRendererListDesc(desc); 856 857 int newHandle = m_RendererListResources.Add(new RendererListResource(CoreRendererListDesc.ConvertToParameters(desc))); 858 return new RendererListHandle(newHandle); 859 } 860 861 internal RendererListHandle CreateRendererList(in RendererListParams desc) 862 { 863 int newHandle = m_RendererListResources.Add(new RendererListResource(desc)); 864 return new RendererListHandle(newHandle); 865 } 866 867 internal RendererListHandle CreateShadowRendererList(ScriptableRenderContext context, ref ShadowDrawingSettings shadowDrawinSettings) 868 { 869 RendererListLegacyResource resource = new RendererListLegacyResource(); 870 resource.rendererList = context.CreateShadowRendererList(ref shadowDrawinSettings); 871 int newHandle = m_RendererListLegacyResources.Add(resource); 872 return new RendererListHandle(newHandle, RendererListHandleType.Legacy); 873 } 874 875 internal RendererListHandle CreateGizmoRendererList(ScriptableRenderContext context, in Camera camera, in GizmoSubset gizmoSubset) 876 { 877 RendererListLegacyResource resource = new RendererListLegacyResource(); 878 resource.rendererList = context.CreateGizmoRendererList(camera, gizmoSubset); 879 int newHandle = m_RendererListLegacyResources.Add(resource); 880 return new RendererListHandle(newHandle, RendererListHandleType.Legacy); 881 } 882 883 internal RendererListHandle CreateUIOverlayRendererList(ScriptableRenderContext context, in Camera camera, in UISubset uiSubset) 884 { 885 RendererListLegacyResource resource = new RendererListLegacyResource(); 886 resource.rendererList = context.CreateUIOverlayRendererList(camera, uiSubset); 887 int newHandle = m_RendererListLegacyResources.Add(resource); 888 return new RendererListHandle(newHandle, RendererListHandleType.Legacy); 889 } 890 891 internal RendererListHandle CreateWireOverlayRendererList(ScriptableRenderContext context, in Camera camera) 892 { 893 RendererListLegacyResource resource = new RendererListLegacyResource(); 894 resource.rendererList = context.CreateWireOverlayRendererList(camera); 895 int newHandle = m_RendererListLegacyResources.Add(resource); 896 return new RendererListHandle(newHandle, RendererListHandleType.Legacy); 897 } 898 899 internal RendererListHandle CreateSkyboxRendererList(ScriptableRenderContext context, in Camera camera) 900 { 901 RendererListLegacyResource resource = new RendererListLegacyResource(); 902 resource.rendererList = context.CreateSkyboxRendererList(camera); 903 int newHandle = m_RendererListLegacyResources.Add(resource); 904 return new RendererListHandle(newHandle, RendererListHandleType.Legacy); 905 } 906 907 internal RendererListHandle CreateSkyboxRendererList(ScriptableRenderContext context, in Camera camera, Matrix4x4 projectionMatrix, Matrix4x4 viewMatrix) 908 { 909 RendererListLegacyResource resource = new RendererListLegacyResource(); 910 resource.rendererList = context.CreateSkyboxRendererList(camera, projectionMatrix, viewMatrix); 911 int newHandle = m_RendererListLegacyResources.Add(resource); 912 return new RendererListHandle(newHandle, RendererListHandleType.Legacy); 913 } 914 915 internal RendererListHandle CreateSkyboxRendererList(ScriptableRenderContext context, in Camera camera, Matrix4x4 projectionMatrixL, Matrix4x4 viewMatrixL, Matrix4x4 projectionMatrixR, Matrix4x4 viewMatrixR) 916 { 917 RendererListLegacyResource resource = new RendererListLegacyResource(); 918 resource.rendererList = context.CreateSkyboxRendererList(camera, projectionMatrixL, viewMatrixL, projectionMatrixR, viewMatrixR); 919 int newHandle = m_RendererListLegacyResources.Add(resource); 920 return new RendererListHandle(newHandle, RendererListHandleType.Legacy); 921 } 922 923 internal BufferHandle ImportBuffer(GraphicsBuffer graphicsBuffer, bool forceRelease = false) 924 { 925 int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Buffer].AddNewRenderGraphResource(out BufferResource bufferResource); 926 bufferResource.graphicsResource = graphicsBuffer; 927 bufferResource.imported = true; 928 bufferResource.forceRelease = forceRelease; 929 bufferResource.validDesc = false; 930 931 return new BufferHandle(newHandle); 932 } 933 934 internal BufferHandle CreateBuffer(in BufferDesc desc, int transientPassIndex = -1) 935 { 936 ValidateBufferDesc(desc); 937 938 int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Buffer].AddNewRenderGraphResource(out BufferResource bufferResource); 939 bufferResource.desc = desc; 940 bufferResource.validDesc = true; 941 bufferResource.transientPassIndex = transientPassIndex; 942 943 return new BufferHandle(newHandle); 944 } 945 946 internal BufferDesc GetBufferResourceDesc(in ResourceHandle handle, bool noThrowOnInvalidDesc = false) 947 { 948 Debug.Assert(handle.type == RenderGraphResourceType.Buffer); 949 var buffer = (m_RenderGraphResources[(int)RenderGraphResourceType.Buffer].resourceArray[handle.index] as BufferResource); 950 if (!buffer.validDesc && !noThrowOnInvalidDesc) 951 throw new ArgumentException("The passed in buffer handle does not have a valid descriptor. (This is most commonly cause by importing the buffer.)", "handle"); 952 return buffer.desc; 953 } 954 955 internal int GetBufferResourceCount() 956 { 957 return GetResourceCount(RenderGraphResourceType.Buffer); 958 } 959 960 BufferResource GetBufferResource(in ResourceHandle handle) 961 { 962 Debug.Assert(handle.type == RenderGraphResourceType.Buffer); 963 return m_RenderGraphResources[(int)RenderGraphResourceType.Buffer].resourceArray[handle.index] as BufferResource; 964 } 965 966 BufferResource GetBufferResource(int index) 967 { 968 return m_RenderGraphResources[(int)RenderGraphResourceType.Buffer].resourceArray[index] as BufferResource; 969 } 970 971 RayTracingAccelerationStructureResource GetRayTracingAccelerationStructureResource(in ResourceHandle handle) 972 { 973 return m_RenderGraphResources[(int)RenderGraphResourceType.AccelerationStructure].resourceArray[handle.index] as RayTracingAccelerationStructureResource; 974 } 975 976 internal int GetRayTracingAccelerationStructureResourceCount() 977 { 978 return GetResourceCount(RenderGraphResourceType.AccelerationStructure); 979 } 980 981 internal RayTracingAccelerationStructureHandle ImportRayTracingAccelerationStructure(in RayTracingAccelerationStructure accelStruct, string name) 982 { 983 int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.AccelerationStructure].AddNewRenderGraphResource(out RayTracingAccelerationStructureResource accelStructureResource, false); 984 accelStructureResource.graphicsResource = accelStruct; 985 accelStructureResource.imported = true; 986 accelStructureResource.forceRelease = false; 987 accelStructureResource.desc.name = name; 988 989 return new RayTracingAccelerationStructureHandle(newHandle); 990 } 991 992 internal void UpdateSharedResourceLastFrameIndex(int type, int index) 993 { 994 m_RenderGraphResources[type].resourceArray[index].sharedResourceLastFrameUsed = m_ExecutionCount; 995 } 996 internal void UpdateSharedResourceLastFrameIndex(in ResourceHandle handle) => UpdateSharedResourceLastFrameIndex((int)handle.type, handle.index); 997 998 999 void ManageSharedRenderGraphResources() 1000 { 1001 for (int type = 0; type < (int)RenderGraphResourceType.Count; ++type) 1002 { 1003 var resources = m_RenderGraphResources[type]; 1004 for (int i = 1; i < resources.sharedResourcesCount+1; ++i) 1005 { 1006 var resource = m_RenderGraphResources[type].resourceArray[i]; 1007 bool isCreated = resource.IsCreated(); 1008 // Alloc if needed 1009 if (resource.sharedResourceLastFrameUsed == m_ExecutionCount && !isCreated) 1010 { 1011 // User name provided through the resource desc will be used 1012 resource.CreateGraphicsResource(); 1013 } 1014 // Release if not used anymore 1015 else if (isCreated && !resource.sharedExplicitRelease && ((resource.sharedResourceLastFrameUsed + kSharedResourceLifetime) < m_ExecutionCount)) 1016 { 1017 resource.ReleaseGraphicsResource(); 1018 } 1019 } 1020 } 1021 } 1022 1023 internal bool CreatePooledResource(InternalRenderGraphContext rgContext, int type, int index) 1024 { 1025 Debug.Assert(index != 0, "Index 0 indicates the null object it can't be used here"); 1026 1027 bool? executedWork = false; 1028 var resource = m_RenderGraphResources[type].resourceArray[index]; 1029 if (!resource.imported) 1030 { 1031 resource.CreatePooledGraphicsResource(); 1032 1033 if (m_RenderGraphDebug.enableLogging) 1034 resource.LogCreation(m_FrameInformationLogger); 1035 1036 executedWork = m_RenderGraphResources[type].createResourceCallback?.Invoke(rgContext, resource); 1037 } 1038 1039 return executedWork ?? false; 1040 } 1041 1042 [MethodImpl(MethodImplOptions.AggressiveInlining)] 1043 internal bool CreatePooledResource(InternalRenderGraphContext rgContext, in ResourceHandle handle) 1044 { 1045 return CreatePooledResource(rgContext, handle.iType, handle.index); 1046 } 1047 1048 // Only modified by native compiler when using native render pass 1049 internal bool forceManualClearOfResource = true; 1050 1051 bool CreateTextureCallback(InternalRenderGraphContext rgContext, IRenderGraphResource res) 1052 { 1053 var resource = res as TextureResource; 1054 1055#if UNITY_2020_2_OR_NEWER 1056 var fastMemDesc = resource.desc.fastMemoryDesc; 1057 if (fastMemDesc.inFastMemory) 1058 { 1059 resource.graphicsResource.SwitchToFastMemory(rgContext.cmd, fastMemDesc.residencyFraction, fastMemDesc.flags); 1060 } 1061#endif 1062 1063 bool executedWork = false; 1064 if ((forceManualClearOfResource && resource.desc.clearBuffer) || m_RenderGraphDebug.clearRenderTargetsAtCreation) 1065 { 1066 bool debugClear = m_RenderGraphDebug.clearRenderTargetsAtCreation && !resource.desc.clearBuffer; 1067 var clearFlag = GraphicsFormatUtility.IsDepthStencilFormat(resource.desc.format) ? ClearFlag.DepthStencil : ClearFlag.Color; 1068 var clearColor = debugClear ? Color.magenta : resource.desc.clearColor; 1069 CoreUtils.SetRenderTarget(rgContext.cmd, resource.graphicsResource, clearFlag, clearColor); 1070 executedWork = true; 1071 } 1072 return executedWork; 1073 } 1074 1075 internal void ReleasePooledResource(InternalRenderGraphContext rgContext, int type, int index) 1076 { 1077 var resource = m_RenderGraphResources[type].resourceArray[index]; 1078 1079 if (!resource.imported || resource.forceRelease) 1080 { 1081 m_RenderGraphResources[type].releaseResourceCallback?.Invoke(rgContext, resource); 1082 1083 if (m_RenderGraphDebug.enableLogging) 1084 { 1085 resource.LogRelease(m_FrameInformationLogger); 1086 } 1087 1088 resource.ReleasePooledGraphicsResource(m_CurrentFrameIndex); 1089 } 1090 } 1091 1092 [MethodImpl(MethodImplOptions.AggressiveInlining)] 1093 internal void ReleasePooledResource(InternalRenderGraphContext rgContext, in ResourceHandle handle) 1094 { 1095 ReleasePooledResource(rgContext, handle.iType, handle.index); 1096 } 1097 1098 void ReleaseTextureCallback(InternalRenderGraphContext rgContext, IRenderGraphResource res) 1099 { 1100 var resource = res as TextureResource; 1101 1102 if (m_RenderGraphDebug.clearRenderTargetsAtRelease) 1103 { 1104 var clearFlag = GraphicsFormatUtility.IsDepthStencilFormat(resource.desc.format)? ClearFlag.DepthStencil : ClearFlag.Color; 1105 CoreUtils.SetRenderTarget(rgContext.cmd, resource.graphicsResource, clearFlag, Color.magenta); 1106 } 1107 } 1108 1109 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 1110 void ValidateTextureDesc(in TextureDesc desc) 1111 { 1112 if(RenderGraph.enableValidityChecks) 1113 { 1114 if (desc.format == GraphicsFormat.None ) 1115 { 1116 throw new ArgumentException("Texture was created with with no format. The texture needs to either have a color format or a depth stencil format."); 1117 } 1118 1119 if (desc.dimension == TextureDimension.None) 1120 { 1121 throw new ArgumentException("Texture was created with an invalid texture dimension."); 1122 } 1123 1124 if (desc.slices == 0) 1125 { 1126 throw new ArgumentException("Texture was created with a slices parameter value of zero."); 1127 } 1128 1129 if (desc.sizeMode == TextureSizeMode.Explicit) 1130 { 1131 if (desc.width == 0 || desc.height == 0) 1132 throw new ArgumentException("Texture using Explicit size mode was create with either width or height at zero."); 1133 } 1134 } 1135 } 1136 1137 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 1138 void ValidateRendererListDesc(in CoreRendererListDesc desc) 1139 { 1140 if(RenderGraph.enableValidityChecks) 1141 { 1142 if (!desc.IsValid()) 1143 { 1144 throw new ArgumentException("Renderer List descriptor is not valid."); 1145 } 1146 1147 if (desc.renderQueueRange.lowerBound == 0 && desc.renderQueueRange.upperBound == 0) 1148 { 1149 throw new ArgumentException("Renderer List creation descriptor must have a valid RenderQueueRange."); 1150 } 1151 } 1152 } 1153 1154 [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] 1155 void ValidateBufferDesc(in BufferDesc desc) 1156 { 1157 if(RenderGraph.enableValidityChecks) 1158 { 1159 if (desc.stride % 4 != 0) 1160 { 1161 throw new ArgumentException("Invalid Graphics Buffer creation descriptor: Graphics Buffer stride must be at least 4."); 1162 } 1163 if (desc.count == 0) 1164 { 1165 throw new ArgumentException("Invalid Graphics Buffer creation descriptor: Graphics Buffer count must be non zero."); 1166 } 1167 } 1168 } 1169 1170 internal void CreateRendererLists(List<RendererListHandle> rendererLists, ScriptableRenderContext context, bool manualDispatch = false) 1171 { 1172 // We gather the active renderer lists of a frame in a list/array before we pass it in the core API for batch processing 1173 m_ActiveRendererLists.Clear(); 1174 1175 foreach (var rendererList in rendererLists) 1176 { 1177 switch(rendererList.type) 1178 { 1179 case RendererListHandleType.Renderers: 1180 { 1181 ref var rendererListResource = ref m_RendererListResources[rendererList]; 1182 ref var desc = ref rendererListResource.desc; 1183 rendererListResource.rendererList = context.CreateRendererList(ref desc); 1184 m_ActiveRendererLists.Add(rendererListResource.rendererList); 1185 break; 1186 } 1187 case RendererListHandleType.Legacy: 1188 { 1189 // Legacy rendererLists are created upfront in recording phase. Simply activate them. 1190 ref var rendererListResource = ref m_RendererListLegacyResources[rendererList]; 1191 rendererListResource.isActive = true; 1192 break; 1193 } 1194#if DEVELOPMENT_BUILD || UNITY_EDITOR 1195 default: 1196 { 1197 throw new ArgumentException("Invalid RendererListHandle: RendererListHandleType is not recognized."); 1198 } 1199#endif 1200 } 1201 1202 } 1203 1204 if (manualDispatch) 1205 context.PrepareRendererListsAsync(m_ActiveRendererLists); 1206 } 1207 1208 internal void Clear(bool onException) 1209 { 1210 LogResources(); 1211 1212 for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i) 1213 m_RenderGraphResources[i].Clear(onException, m_CurrentFrameIndex); 1214 m_RendererListResources.Clear(); 1215 m_RendererListLegacyResources.Clear(); 1216 m_ActiveRendererLists.Clear(); 1217 } 1218 1219 internal void PurgeUnusedGraphicsResources() 1220 { 1221 for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i) 1222 m_RenderGraphResources[i].PurgeUnusedGraphicsResources(m_CurrentFrameIndex); 1223 } 1224 1225 internal void Cleanup() 1226 { 1227 for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i) 1228 m_RenderGraphResources[i].Cleanup(); 1229 1230 RTHandles.Release(m_CurrentBackbuffer); 1231 } 1232 1233 internal void FlushLogs() 1234 { 1235 Debug.Log(m_ResourceLogger.GetAllLogs()); 1236 } 1237 1238 void LogResources() 1239 { 1240 if (m_RenderGraphDebug.enableLogging) 1241 { 1242 m_ResourceLogger.LogLine("==== Allocated Resources ====\n"); 1243 1244 for (int type = 0; type < (int)RenderGraphResourceType.Count; ++type) 1245 { 1246 if (m_RenderGraphResources[type].pool != null) 1247 { 1248 m_RenderGraphResources[type].pool.LogResources(m_ResourceLogger); 1249 m_ResourceLogger.LogLine(""); 1250 } 1251 } 1252 } 1253 } 1254 1255 #endregion 1256 } 1257}