説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

RenderGraphPass.cs 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. using System;
  2. using System.Diagnostics;
  3. using System.Collections.Generic;
  4. using System.Runtime.CompilerServices;
  5. namespace UnityEngine.Rendering.RenderGraphModule
  6. {
  7. [DebuggerDisplay("RenderPass: {name} (Index:{index} Async:{enableAsyncCompute})")]
  8. abstract class RenderGraphPass
  9. {
  10. public abstract void Execute(InternalRenderGraphContext renderGraphContext);
  11. public abstract void Release(RenderGraphObjectPool pool);
  12. public abstract bool HasRenderFunc();
  13. public abstract int GetRenderFuncHash();
  14. public string name { get; protected set; }
  15. public int index { get; protected set; }
  16. public RenderGraphPassType type { get; internal set; }
  17. public ProfilingSampler customSampler { get; protected set; }
  18. public bool enableAsyncCompute { get; protected set; }
  19. public bool allowPassCulling { get; protected set; }
  20. public bool allowGlobalState { get; protected set; }
  21. public bool enableFoveatedRasterization { get; protected set; }
  22. // Before using the AccessFlags use resourceHandle.isValid()
  23. // to make sure that the data in the colorBuffer/fragmentInput/randomAccessResource buffers are up to date
  24. public TextureAccess depthAccess { get; protected set; }
  25. public TextureAccess[] colorBufferAccess { get; protected set; } = new TextureAccess[RenderGraph.kMaxMRTCount];
  26. public int colorBufferMaxIndex { get; protected set; } = -1;
  27. // Used by native pass compiler only
  28. public TextureAccess[] fragmentInputAccess { get; protected set; } = new TextureAccess[RenderGraph.kMaxMRTCount];
  29. public int fragmentInputMaxIndex { get; protected set; } = -1;
  30. public struct RandomWriteResourceInfo
  31. {
  32. public ResourceHandle h;
  33. public bool preserveCounterValue;
  34. }
  35. // This list can contain both texture and buffer resources based on their binding index.
  36. public RandomWriteResourceInfo[] randomAccessResource { get; protected set; } = new RandomWriteResourceInfo[RenderGraph.kMaxMRTCount];
  37. public int randomAccessResourceMaxIndex { get; protected set; } = -1;
  38. public bool generateDebugData { get; protected set; }
  39. public bool allowRendererListCulling { get; protected set; }
  40. public List<ResourceHandle>[] resourceReadLists = new List<ResourceHandle>[(int)RenderGraphResourceType.Count];
  41. public List<ResourceHandle>[] resourceWriteLists = new List<ResourceHandle>[(int)RenderGraphResourceType.Count];
  42. public List<ResourceHandle>[] transientResourceList = new List<ResourceHandle>[(int)RenderGraphResourceType.Count];
  43. public List<RendererListHandle> usedRendererListList = new List<RendererListHandle>();
  44. public List<ValueTuple<TextureHandle, int>> setGlobalsList = new List<ValueTuple<TextureHandle, int>>();
  45. public bool useAllGlobalTextures;
  46. public List<ResourceHandle> implicitReadsList = new List<ResourceHandle>();
  47. public RenderGraphPass()
  48. {
  49. for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i)
  50. {
  51. resourceReadLists[i] = new List<ResourceHandle>();
  52. resourceWriteLists[i] = new List<ResourceHandle>();
  53. transientResourceList[i] = new List<ResourceHandle>();
  54. }
  55. }
  56. public void Clear()
  57. {
  58. name = "";
  59. index = -1;
  60. customSampler = null;
  61. for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i)
  62. {
  63. resourceReadLists[i].Clear();
  64. resourceWriteLists[i].Clear();
  65. transientResourceList[i].Clear();
  66. }
  67. usedRendererListList.Clear();
  68. setGlobalsList.Clear();
  69. useAllGlobalTextures = false;
  70. implicitReadsList.Clear();
  71. enableAsyncCompute = false;
  72. allowPassCulling = true;
  73. allowRendererListCulling = true;
  74. allowGlobalState = false;
  75. enableFoveatedRasterization = false;
  76. generateDebugData = true;
  77. // Invalidate the buffers without clearing them, as it is too costly
  78. // Use IsValid() to make sure that the data in the colorBuffer/fragmentInput/randomAccessResource buffers are up to date
  79. colorBufferMaxIndex = -1;
  80. fragmentInputMaxIndex = -1;
  81. randomAccessResourceMaxIndex = -1;
  82. }
  83. // Check if the pass has any render targets set-up
  84. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  85. public bool HasRenderAttachments()
  86. {
  87. return depthAccess.textureHandle.IsValid() || colorBufferAccess[0].textureHandle.IsValid() || colorBufferMaxIndex > 0;
  88. }
  89. // Checks if the resource is involved in this pass
  90. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  91. public bool IsTransient(in ResourceHandle res)
  92. {
  93. return transientResourceList[res.iType].Contains(res);
  94. }
  95. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  96. public bool IsWritten(in ResourceHandle res)
  97. {
  98. // You can only ever write to the latest version so we ignore it when looking in the list
  99. for (int i = 0; i < resourceWriteLists[res.iType].Count; i++)
  100. {
  101. if (resourceWriteLists[res.iType][i].index == res.index)
  102. {
  103. return true;
  104. }
  105. }
  106. return false;
  107. }
  108. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  109. public bool IsRead(in ResourceHandle res)
  110. {
  111. if (res.IsVersioned)
  112. {
  113. return resourceReadLists[res.iType].Contains(res);
  114. }
  115. else
  116. {
  117. // Just look if we are reading any version of this texture.
  118. // Note that in theory this pass could read from several versions of the same texture
  119. // e.g. ColorBuffer,v3 and ColorBuffer,v5 so this check is always conservative
  120. for (int i = 0; i < resourceReadLists[res.iType].Count; i++)
  121. {
  122. if (resourceReadLists[res.iType][i].index == res.index)
  123. {
  124. return true;
  125. }
  126. }
  127. return false;
  128. }
  129. }
  130. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  131. public bool IsAttachment(in TextureHandle res)
  132. {
  133. // We ignore the version when checking, if any version is used it is considered a match
  134. if (depthAccess.textureHandle.IsValid() && depthAccess.textureHandle.handle.index == res.handle.index) return true;
  135. for (int i = 0; i < colorBufferAccess.Length; i++)
  136. {
  137. if (colorBufferAccess[i].textureHandle.IsValid() && colorBufferAccess[i].textureHandle.handle.index == res.handle.index) return true;
  138. }
  139. return false;
  140. }
  141. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  142. public void AddResourceWrite(in ResourceHandle res)
  143. {
  144. resourceWriteLists[res.iType].Add(res);
  145. }
  146. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  147. public void AddResourceRead(in ResourceHandle res)
  148. {
  149. resourceReadLists[res.iType].Add(res);
  150. }
  151. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  152. public void AddTransientResource(in ResourceHandle res)
  153. {
  154. transientResourceList[res.iType].Add(res);
  155. }
  156. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  157. public void UseRendererList(in RendererListHandle rendererList)
  158. {
  159. usedRendererListList.Add(rendererList);
  160. }
  161. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  162. public void EnableAsyncCompute(bool value)
  163. {
  164. enableAsyncCompute = value;
  165. }
  166. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  167. public void AllowPassCulling(bool value)
  168. {
  169. allowPassCulling = value;
  170. }
  171. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  172. public void EnableFoveatedRasterization(bool value)
  173. {
  174. enableFoveatedRasterization = value;
  175. }
  176. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  177. public void AllowRendererListCulling(bool value)
  178. {
  179. allowRendererListCulling = value;
  180. }
  181. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  182. public void AllowGlobalState(bool value)
  183. {
  184. allowGlobalState = value;
  185. }
  186. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  187. public void GenerateDebugData(bool value)
  188. {
  189. generateDebugData = value;
  190. }
  191. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  192. public void SetColorBuffer(in TextureHandle resource, int index)
  193. {
  194. Debug.Assert(index < RenderGraph.kMaxMRTCount && index >= 0);
  195. colorBufferMaxIndex = Math.Max(colorBufferMaxIndex, index);
  196. colorBufferAccess[index].textureHandle = resource;
  197. AddResourceWrite(resource.handle);
  198. }
  199. // Sets up the color buffer for this pass but not any resource Read/Writes for it
  200. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  201. public void SetColorBufferRaw(in TextureHandle resource, int index, AccessFlags accessFlags, int mipLevel, int depthSlice)
  202. {
  203. Debug.Assert(index < RenderGraph.kMaxMRTCount && index >= 0);
  204. if (colorBufferAccess[index].textureHandle.handle.Equals(resource.handle) || !colorBufferAccess[index].textureHandle.IsValid())
  205. {
  206. colorBufferMaxIndex = Math.Max(colorBufferMaxIndex, index);
  207. colorBufferAccess[index].textureHandle = resource;
  208. colorBufferAccess[index].flags = accessFlags;
  209. colorBufferAccess[index].mipLevel = mipLevel;
  210. colorBufferAccess[index].depthSlice = depthSlice;
  211. }
  212. else
  213. {
  214. #if DEVELOPMENT_BUILD || UNITY_EDITOR
  215. // You tried to do SetRenderAttachment(tex1, 1, ..); SetRenderAttachment(tex2, 1, ..); that is not valid for different textures on the same index
  216. throw new InvalidOperationException("You can only bind a single texture to an MRT index. Verify your indexes are correct.");
  217. #endif
  218. }
  219. }
  220. // Sets up the color buffer for this pass but not any resource Read/Writes for it
  221. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  222. public void SetFragmentInputRaw(in TextureHandle resource, int index, AccessFlags accessFlags, int mipLevel, int depthSlice)
  223. {
  224. Debug.Assert(index < RenderGraph.kMaxMRTCount && index >= 0);
  225. if (fragmentInputAccess[index].textureHandle.handle.Equals(resource.handle) || !fragmentInputAccess[index].textureHandle.IsValid())
  226. {
  227. fragmentInputMaxIndex = Math.Max(fragmentInputMaxIndex, index);
  228. fragmentInputAccess[index].textureHandle = resource;
  229. fragmentInputAccess[index].flags = accessFlags;
  230. fragmentInputAccess[index].mipLevel = mipLevel;
  231. fragmentInputAccess[index].depthSlice = depthSlice;
  232. }
  233. else
  234. {
  235. #if DEVELOPMENT_BUILD || UNITY_EDITOR
  236. // You tried to do SetRenderAttachment(tex1, 1, ..); SetRenderAttachment(tex2, 1, ..); that is not valid for different textures on the same index
  237. throw new InvalidOperationException("You can only bind a single texture to an fragment input index. Verify your indexes are correct.");
  238. #endif
  239. }
  240. }
  241. // Sets up the color buffer for this pass but not any resource Read/Writes for it
  242. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  243. public void SetRandomWriteResourceRaw(in ResourceHandle resource, int index, bool preserveCounterValue, AccessFlags accessFlags)
  244. {
  245. Debug.Assert(index < RenderGraph.kMaxMRTCount && index >= 0);
  246. if (randomAccessResource[index].h.Equals(resource) || !randomAccessResource[index].h.IsValid())
  247. {
  248. randomAccessResourceMaxIndex = Math.Max(randomAccessResourceMaxIndex, index);
  249. ref var info = ref randomAccessResource[index];
  250. info.h = resource;
  251. info.preserveCounterValue = preserveCounterValue;
  252. }
  253. else
  254. {
  255. // You tried to do SetRenderAttachment(tex1, 1, ..); SetRenderAttachment(tex2, 1, ..); that is not valid for different textures on the same index
  256. throw new InvalidOperationException("You can only bind a single texture to an random write input index. Verify your indexes are correct.");
  257. }
  258. }
  259. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  260. public void SetDepthBuffer(in TextureHandle resource, DepthAccess flags)
  261. {
  262. depthAccess = new TextureAccess(resource, (AccessFlags)flags, 0, 0);
  263. if ((flags & DepthAccess.Read) != 0)
  264. AddResourceRead(resource.handle);
  265. if ((flags & DepthAccess.Write) != 0)
  266. AddResourceWrite(resource.handle);
  267. }
  268. // Sets up the depth buffer for this pass but not any resource Read/Writes for it
  269. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  270. public void SetDepthBufferRaw(in TextureHandle resource, AccessFlags accessFlags, int mipLevel, int depthSlice)
  271. {
  272. // If no depth buffer yet or if it is the same one as the previous one, allow the call otherwise log an error.
  273. if (depthAccess.textureHandle.handle.Equals(resource.handle) || !depthAccess.textureHandle.IsValid())
  274. {
  275. depthAccess = new TextureAccess(resource, accessFlags, mipLevel, depthSlice);
  276. }
  277. #if DEVELOPMENT_BUILD || UNITY_EDITOR
  278. else
  279. {
  280. throw new InvalidOperationException("You can only set a single depth texture per pass.");
  281. }
  282. #endif
  283. }
  284. // Here we want to keep computation to a minimum and only hash what will influence NRP compiler: Pass merging, load/store actions etc.
  285. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  286. void ComputeTextureHash(ref int hash, in ResourceHandle handle, RenderGraphResourceRegistry resources)
  287. {
  288. if (handle.index == 0)
  289. return;
  290. if (resources.IsRenderGraphResourceImported(handle))
  291. {
  292. var res = resources.GetTextureResource(handle);
  293. if (res.graphicsResource.externalTexture != null) // External texture
  294. {
  295. var externalTexture = res.graphicsResource.externalTexture;
  296. hash = hash * 23 + (int)externalTexture.graphicsFormat;
  297. hash = hash * 23 + (int)externalTexture.dimension;
  298. hash = hash * 23 + externalTexture.width;
  299. hash = hash * 23 + externalTexture.height;
  300. if (externalTexture is RenderTexture externalRT)
  301. hash = hash * 23 + externalRT.antiAliasing;
  302. }
  303. else if (res.graphicsResource.rt != null) // Regular RTHandle
  304. {
  305. var rt = res.graphicsResource.rt;
  306. hash = hash * 23 + (int)rt.graphicsFormat;
  307. hash = hash * 23 + (int)rt.dimension;
  308. hash = hash * 23 + rt.antiAliasing;
  309. if (res.graphicsResource.useScaling)
  310. {
  311. if (res.graphicsResource.scaleFunc != null)
  312. hash = hash * 23 + CustomGetHashCode(res.graphicsResource.scaleFunc);
  313. else
  314. hash = hash * 23 + res.graphicsResource.scaleFactor.GetHashCode();
  315. }
  316. else
  317. {
  318. hash = hash * 23 + rt.width;
  319. hash = hash * 23 + rt.height;
  320. }
  321. }
  322. else if (res.graphicsResource.nameID != default) // External RTI
  323. {
  324. // The only info we have is from the provided desc upon importing.
  325. ref var desc = ref res.desc;
  326. hash = hash * 23 + (int)desc.colorFormat;
  327. hash = hash * 23 + (int)desc.dimension;
  328. hash = hash * 23 + (int)desc.msaaSamples;
  329. hash = hash * 23 + desc.width;
  330. hash = hash * 23 + desc.height;
  331. }
  332. // Add the clear/discard buffer flags to the hash (used in all the cases above)
  333. hash = hash * 23 + res.desc.clearBuffer.GetHashCode();
  334. hash = hash * 23 + res.desc.discardBuffer.GetHashCode();
  335. }
  336. else
  337. {
  338. var desc = resources.GetTextureResourceDesc(handle);
  339. hash = hash * 23 + (int)desc.colorFormat;
  340. hash = hash * 23 + (int)desc.dimension;
  341. hash = hash * 23 + (int)desc.msaaSamples;
  342. hash = hash * 23 + desc.clearBuffer.GetHashCode();
  343. hash = hash * 23 + desc.discardBuffer.GetHashCode();
  344. switch (desc.sizeMode)
  345. {
  346. case TextureSizeMode.Explicit:
  347. hash = hash * 23 + desc.width;
  348. hash = hash * 23 + desc.height;
  349. break;
  350. case TextureSizeMode.Scale:
  351. hash = hash * 23 + desc.scale.GetHashCode();
  352. break;
  353. case TextureSizeMode.Functor:
  354. hash = hash * 23 + CustomGetHashCode(desc.func);
  355. break;
  356. }
  357. }
  358. }
  359. // This function is performance sensitive.
  360. // Avoid mass function calls to get the hashCode and compute locally instead.
  361. public int ComputeHash(RenderGraphResourceRegistry resources)
  362. {
  363. int hash = index;
  364. hash = hash * 23 + (int)type;
  365. hash = hash * 23 + (enableAsyncCompute ? 1 : 0);
  366. hash = hash * 23 + (allowPassCulling ? 1 : 0);
  367. hash = hash * 23 + (allowGlobalState ? 1 : 0);
  368. hash = hash * 23 + (enableFoveatedRasterization ? 1 : 0);
  369. var depthHandle = depthAccess.textureHandle.handle;
  370. if (depthHandle.IsValid())
  371. {
  372. hash = hash * 23 + depthHandle.index;
  373. hash = hash * 23 + (int)depthAccess.flags;
  374. hash = hash * 23 + depthAccess.mipLevel;
  375. hash = hash * 23 + depthAccess.depthSlice;
  376. ComputeTextureHash(ref hash, depthHandle, resources);
  377. }
  378. for (int i = 0; i < colorBufferMaxIndex + 1; ++i)
  379. {
  380. var colorBufferAccessElement = colorBufferAccess[i];
  381. var handle = colorBufferAccessElement.textureHandle.handle;
  382. if (handle.IsValid())
  383. {
  384. ComputeTextureHash(ref hash, handle, resources);
  385. hash = hash * 23 + handle.index;
  386. hash = hash * 23 + (int)colorBufferAccessElement.flags;
  387. hash = hash * 23 + colorBufferAccessElement.mipLevel;
  388. hash = hash * 23 + colorBufferAccessElement.depthSlice;
  389. }
  390. }
  391. hash = hash * 23 + colorBufferMaxIndex;
  392. for (int i = 0; i < fragmentInputMaxIndex + 1; ++i)
  393. {
  394. var fragmentInputAccessElement = fragmentInputAccess[i];
  395. var handle = fragmentInputAccessElement.textureHandle.handle;
  396. if (handle.IsValid())
  397. {
  398. ComputeTextureHash(ref hash, handle, resources);
  399. hash = hash * 23 + handle.index;
  400. hash = hash * 23 + (int)fragmentInputAccessElement.flags;
  401. hash = hash * 23 + fragmentInputAccessElement.mipLevel;
  402. hash = hash * 23 + fragmentInputAccessElement.depthSlice;
  403. }
  404. }
  405. for (int i = 0; i < randomAccessResourceMaxIndex + 1; ++i)
  406. {
  407. var rar = randomAccessResource[i];
  408. if (rar.h.IsValid())
  409. {
  410. hash = hash * 23 + rar.h.index;
  411. hash = hash * 23 + (rar.preserveCounterValue ? 1 : 0);
  412. }
  413. }
  414. hash = hash * 23 + randomAccessResourceMaxIndex;
  415. hash = hash * 23 + fragmentInputMaxIndex;
  416. hash = hash * 23 + (generateDebugData ? 1 : 0);
  417. hash = hash * 23 + (allowRendererListCulling ? 1 : 0);
  418. for (int resType = 0; resType < (int)RenderGraphResourceType.Count; resType++)
  419. {
  420. var resourceReads = resourceReadLists[resType];
  421. for (int i = 0; i < resourceReads.Count; ++i)
  422. hash = hash * 23 + resourceReads[i].index;
  423. var resourceWrites = resourceWriteLists[resType];
  424. for (int i = 0; i < resourceWrites.Count; ++i)
  425. hash = hash * 23 + resourceWrites[i].index;
  426. var resourceTransient = transientResourceList[resType];
  427. for (int i = 0; i < resourceTransient.Count; ++i)
  428. hash = hash * 23 + resourceTransient[i].index;
  429. }
  430. for (int i = 0; i < usedRendererListList.Count; ++i)
  431. hash = hash * 23 + usedRendererListList[i].handle;
  432. for (int i = 0; i < setGlobalsList.Count; ++i)
  433. {
  434. var global = setGlobalsList[i];
  435. hash = hash * 23 + global.Item1.handle.index;
  436. hash = hash * 23 + global.Item2;
  437. }
  438. hash = hash * 23 + (useAllGlobalTextures ? 1 : 0);
  439. for (int i = 0; i < implicitReadsList.Count; ++i)
  440. hash = hash * 23 + implicitReadsList[i].index;
  441. hash = hash * 23 + GetRenderFuncHash();
  442. return hash;
  443. }
  444. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  445. protected static int CustomGetHashCode(Delegate del)
  446. {
  447. return del.Method.GetHashCode() ^ RuntimeHelpers.GetHashCode(del.Target);
  448. }
  449. }
  450. // This used to have an extra generic argument 'RenderGraphContext' abstracting the context and avoiding
  451. // the RenderGraphPass/ComputeRenderGraphPass/RasterRenderGraphPass/UnsafeRenderGraphPass classes below
  452. // but this confuses IL2CPP and causes garbage when boxing the context created (even though they are structs)
  453. [DebuggerDisplay("RenderPass: {name} (Index:{index} Async:{enableAsyncCompute})")]
  454. internal abstract class BaseRenderGraphPass<PassData, TRenderGraphContext> : RenderGraphPass
  455. where PassData : class, new()
  456. {
  457. internal PassData data;
  458. internal BaseRenderFunc<PassData, TRenderGraphContext> renderFunc;
  459. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  460. public void Initialize(int passIndex, PassData passData, string passName, RenderGraphPassType passType, ProfilingSampler sampler)
  461. {
  462. Clear();
  463. index = passIndex;
  464. data = passData;
  465. name = passName;
  466. type = passType;
  467. customSampler = sampler;
  468. }
  469. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  470. public override void Release(RenderGraphObjectPool pool)
  471. {
  472. pool.Release(data);
  473. data = null;
  474. renderFunc = null;
  475. }
  476. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  477. public override bool HasRenderFunc()
  478. {
  479. return renderFunc != null;
  480. }
  481. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  482. public override int GetRenderFuncHash()
  483. {
  484. return renderFunc != null ? CustomGetHashCode(renderFunc) : 0;
  485. }
  486. }
  487. [DebuggerDisplay("RenderPass: {name} (Index:{index} Async:{enableAsyncCompute})")]
  488. internal sealed class RenderGraphPass<PassData> : BaseRenderGraphPass<PassData, RenderGraphContext>
  489. where PassData : class, new()
  490. {
  491. internal static RenderGraphContext c = new RenderGraphContext();
  492. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  493. public override void Execute(InternalRenderGraphContext renderGraphContext)
  494. {
  495. c.FromInternalContext(renderGraphContext);
  496. renderFunc(data, c);
  497. }
  498. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  499. public override void Release(RenderGraphObjectPool pool)
  500. {
  501. base.Release(pool);
  502. // We need to do the release from here because we need the final type.
  503. pool.Release(this);
  504. }
  505. }
  506. [DebuggerDisplay("RenderPass: {name} (Index:{index} Async:{enableAsyncCompute})")]
  507. internal sealed class ComputeRenderGraphPass<PassData> : BaseRenderGraphPass<PassData, ComputeGraphContext>
  508. where PassData : class, new()
  509. {
  510. internal static ComputeGraphContext c = new ComputeGraphContext();
  511. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  512. public override void Execute(InternalRenderGraphContext renderGraphContext)
  513. {
  514. c.FromInternalContext(renderGraphContext);
  515. renderFunc(data, c);
  516. }
  517. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  518. public override void Release(RenderGraphObjectPool pool)
  519. {
  520. base.Release(pool);
  521. // We need to do the release from here because we need the final type.
  522. pool.Release(this);
  523. }
  524. }
  525. [DebuggerDisplay("RenderPass: {name} (Index:{index} Async:{enableAsyncCompute})")]
  526. internal sealed class RasterRenderGraphPass<PassData> : BaseRenderGraphPass<PassData, RasterGraphContext>
  527. where PassData : class, new()
  528. {
  529. internal static RasterGraphContext c = new RasterGraphContext();
  530. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  531. public override void Execute(InternalRenderGraphContext renderGraphContext)
  532. {
  533. c.FromInternalContext(renderGraphContext);
  534. renderFunc(data, c);
  535. }
  536. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  537. public override void Release(RenderGraphObjectPool pool)
  538. {
  539. base.Release(pool);
  540. // We need to do the release from here because we need the final type.
  541. pool.Release(this);
  542. }
  543. }
  544. [DebuggerDisplay("RenderPass: {name} (Index:{index} Async:{enableAsyncCompute})")]
  545. internal sealed class UnsafeRenderGraphPass<PassData> : BaseRenderGraphPass<PassData, UnsafeGraphContext>
  546. where PassData : class, new()
  547. {
  548. internal static UnsafeGraphContext c = new UnsafeGraphContext();
  549. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  550. public override void Execute(InternalRenderGraphContext renderGraphContext)
  551. {
  552. c.FromInternalContext(renderGraphContext);
  553. renderFunc(data, c);
  554. }
  555. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  556. public override void Release(RenderGraphObjectPool pool)
  557. {
  558. base.Release(pool);
  559. // We need to do the release from here because we need the final type.
  560. pool.Release(this);
  561. }
  562. }
  563. }