Нема описа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  1. using System;
  2. using System.Collections.Generic;
  3. using Unity.Collections;
  4. using Unity.Collections.LowLevel.Unsafe;
  5. using UnityEngine.Experimental.Rendering;
  6. using UnityEngine.Rendering.RenderGraphModule;
  7. using System.Diagnostics;
  8. namespace UnityEngine.Rendering.Universal
  9. {
  10. /// <summary>
  11. /// Contains properties and helper functions that you can use when rendering.
  12. /// </summary>
  13. public static class RenderingUtils
  14. {
  15. static List<ShaderTagId> m_LegacyShaderPassNames = new List<ShaderTagId>
  16. {
  17. new ShaderTagId("Always"),
  18. new ShaderTagId("ForwardBase"),
  19. new ShaderTagId("PrepassBase"),
  20. new ShaderTagId("Vertex"),
  21. new ShaderTagId("VertexLMRGBM"),
  22. new ShaderTagId("VertexLM"),
  23. };
  24. static AttachmentDescriptor s_EmptyAttachment = new AttachmentDescriptor(GraphicsFormat.None);
  25. internal static AttachmentDescriptor emptyAttachment
  26. {
  27. get
  28. {
  29. return s_EmptyAttachment;
  30. }
  31. }
  32. static Mesh s_FullscreenMesh = null;
  33. /// <summary>
  34. /// Returns a mesh that you can use with <see cref="CommandBuffer.DrawMesh(Mesh, Matrix4x4, Material)"/> to render full-screen effects.
  35. /// </summary>
  36. [Obsolete("Use Blitter.BlitCameraTexture instead of CommandBuffer.DrawMesh(fullscreenMesh, ...)")] // TODO OBSOLETE: need to fix the URP test failures when bumping
  37. public static Mesh fullscreenMesh
  38. {
  39. get
  40. {
  41. if (s_FullscreenMesh != null)
  42. return s_FullscreenMesh;
  43. float topV = 1.0f;
  44. float bottomV = 0.0f;
  45. s_FullscreenMesh = new Mesh { name = "Fullscreen Quad" };
  46. s_FullscreenMesh.SetVertices(new List<Vector3>
  47. {
  48. new Vector3(-1.0f, -1.0f, 0.0f),
  49. new Vector3(-1.0f, 1.0f, 0.0f),
  50. new Vector3(1.0f, -1.0f, 0.0f),
  51. new Vector3(1.0f, 1.0f, 0.0f)
  52. });
  53. s_FullscreenMesh.SetUVs(0, new List<Vector2>
  54. {
  55. new Vector2(0.0f, bottomV),
  56. new Vector2(0.0f, topV),
  57. new Vector2(1.0f, bottomV),
  58. new Vector2(1.0f, topV)
  59. });
  60. s_FullscreenMesh.SetIndices(new[] { 0, 1, 2, 2, 1, 3 }, MeshTopology.Triangles, 0, false);
  61. s_FullscreenMesh.UploadMeshData(true);
  62. return s_FullscreenMesh;
  63. }
  64. }
  65. internal static bool useStructuredBuffer
  66. {
  67. // There are some performance issues with StructuredBuffers in some platforms.
  68. // We fallback to UBO in those cases.
  69. get
  70. {
  71. // TODO: For now disabling SSBO until figure out Vulkan binding issues.
  72. // When enabling this also enable USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA in shader side in Input.hlsl
  73. return false;
  74. // We don't use SSBO in D3D because we can't figure out without adding shader variants if platforms is D3D10.
  75. //GraphicsDeviceType deviceType = SystemInfo.graphicsDeviceType;
  76. //return !Application.isMobilePlatform &&
  77. // (deviceType == GraphicsDeviceType.Metal || deviceType == GraphicsDeviceType.Vulkan ||
  78. // deviceType == GraphicsDeviceType.PlayStation4 || deviceType == GraphicsDeviceType.PlayStation5 || deviceType == GraphicsDeviceType.XboxOne);
  79. }
  80. }
  81. internal static bool SupportsLightLayers(GraphicsDeviceType type)
  82. {
  83. return true;
  84. }
  85. static Material s_ErrorMaterial;
  86. static Material errorMaterial
  87. {
  88. get
  89. {
  90. if (s_ErrorMaterial == null)
  91. {
  92. // TODO: When importing project, AssetPreviewUpdater::CreatePreviewForAsset will be called multiple times.
  93. // This might be in a point that some resources required for the pipeline are not finished importing yet.
  94. // Proper fix is to add a fence on asset import.
  95. try
  96. {
  97. s_ErrorMaterial = new Material(Shader.Find("Hidden/Universal Render Pipeline/FallbackError"));
  98. }
  99. catch { }
  100. }
  101. return s_ErrorMaterial;
  102. }
  103. }
  104. /// <summary>
  105. /// Set view and projection matrices.
  106. /// This function will set <c>UNITY_MATRIX_V</c>, <c>UNITY_MATRIX_P</c>, <c>UNITY_MATRIX_VP</c> to given view and projection matrices.
  107. /// If <c>setInverseMatrices</c> is set to true this function will also set <c>UNITY_MATRIX_I_V</c> and <c>UNITY_MATRIX_I_VP</c>.
  108. /// </summary>
  109. /// <param name="cmd">CommandBuffer to submit data to GPU.</param>
  110. /// <param name="viewMatrix">View matrix to be set.</param>
  111. /// <param name="projectionMatrix">Projection matrix to be set.</param>
  112. /// <param name="setInverseMatrices">Set this to true if you also need to set inverse camera matrices.</param>
  113. public static void SetViewAndProjectionMatrices(CommandBuffer cmd, Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix, bool setInverseMatrices) { SetViewAndProjectionMatrices(CommandBufferHelpers.GetRasterCommandBuffer(cmd), viewMatrix, projectionMatrix, setInverseMatrices); }
  114. internal static void SetViewAndProjectionMatrices(RasterCommandBuffer cmd, Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix, bool setInverseMatrices)
  115. {
  116. Matrix4x4 viewAndProjectionMatrix = projectionMatrix * viewMatrix;
  117. cmd.SetGlobalMatrix(ShaderPropertyId.viewMatrix, viewMatrix);
  118. cmd.SetGlobalMatrix(ShaderPropertyId.projectionMatrix, projectionMatrix);
  119. cmd.SetGlobalMatrix(ShaderPropertyId.viewAndProjectionMatrix, viewAndProjectionMatrix);
  120. if (setInverseMatrices)
  121. {
  122. Matrix4x4 inverseViewMatrix = Matrix4x4.Inverse(viewMatrix);
  123. Matrix4x4 inverseProjectionMatrix = Matrix4x4.Inverse(projectionMatrix);
  124. Matrix4x4 inverseViewProjection = inverseViewMatrix * inverseProjectionMatrix;
  125. cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewMatrix, inverseViewMatrix);
  126. cmd.SetGlobalMatrix(ShaderPropertyId.inverseProjectionMatrix, inverseProjectionMatrix);
  127. cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewAndProjectionMatrix, inverseViewProjection);
  128. }
  129. }
  130. //TODO FrameData: Merge these two SetScaleBiasRt() functions
  131. internal static void SetScaleBiasRt(RasterCommandBuffer cmd, in UniversalCameraData cameraData, RTHandle rTHandle)
  132. {
  133. // SetRenderTarget has logic to flip projection matrix when rendering to render texture. Flip the uv to account for that case.
  134. bool isCameraColorFinalTarget = (cameraData.cameraType == CameraType.Game && rTHandle.nameID == BuiltinRenderTextureType.CameraTarget && cameraData.camera.targetTexture == null);
  135. bool yflip = !isCameraColorFinalTarget;
  136. float flipSign = yflip ? -1.0f : 1.0f;
  137. Vector4 scaleBiasRt = (flipSign < 0.0f)
  138. ? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
  139. : new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
  140. cmd.SetGlobalVector(Shader.PropertyToID("_ScaleBiasRt"), scaleBiasRt);
  141. }
  142. internal static void SetScaleBiasRt(RasterCommandBuffer cmd, in RenderingData renderingData)
  143. {
  144. var renderer = renderingData.cameraData.renderer;
  145. // SetRenderTarget has logic to flip projection matrix when rendering to render texture. Flip the uv to account for that case.
  146. CameraData cameraData = renderingData.cameraData;
  147. // Disable obsolete warning for internal usage
  148. #pragma warning disable CS0618
  149. bool isCameraColorFinalTarget = (cameraData.cameraType == CameraType.Game && renderer.cameraColorTargetHandle.nameID == BuiltinRenderTextureType.CameraTarget && cameraData.camera.targetTexture == null);
  150. #pragma warning restore CS0618
  151. bool yflip = !isCameraColorFinalTarget;
  152. float flipSign = yflip ? -1.0f : 1.0f;
  153. Vector4 scaleBiasRt = (flipSign < 0.0f)
  154. ? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
  155. : new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
  156. cmd.SetGlobalVector(Shader.PropertyToID("_ScaleBiasRt"), scaleBiasRt);
  157. }
  158. internal static void Blit(CommandBuffer cmd,
  159. RTHandle source,
  160. Rect viewport,
  161. RTHandle destination,
  162. RenderBufferLoadAction loadAction,
  163. RenderBufferStoreAction storeAction,
  164. ClearFlag clearFlag,
  165. Color clearColor,
  166. Material material,
  167. int passIndex = 0)
  168. {
  169. Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
  170. CoreUtils.SetRenderTarget(cmd, destination, loadAction, storeAction, ClearFlag.None, Color.clear);
  171. cmd.SetViewport(viewport);
  172. Blitter.BlitTexture(cmd, source, viewportScale, material, passIndex);
  173. }
  174. internal static void Blit(CommandBuffer cmd,
  175. RTHandle source,
  176. Rect viewport,
  177. RTHandle destinationColor,
  178. RenderBufferLoadAction colorLoadAction,
  179. RenderBufferStoreAction colorStoreAction,
  180. RTHandle destinationDepthStencil,
  181. RenderBufferLoadAction depthStencilLoadAction,
  182. RenderBufferStoreAction depthStencilStoreAction,
  183. ClearFlag clearFlag,
  184. Color clearColor,
  185. Material material,
  186. int passIndex = 0)
  187. {
  188. Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
  189. CoreUtils.SetRenderTarget(cmd,
  190. destinationColor, colorLoadAction, colorStoreAction,
  191. destinationDepthStencil, depthStencilLoadAction, depthStencilStoreAction,
  192. clearFlag, clearColor); // implicit depth=1.0f stencil=0x0
  193. cmd.SetViewport(viewport);
  194. Blitter.BlitTexture(cmd, source, viewportScale, material, passIndex);
  195. }
  196. internal static void FinalBlit(
  197. CommandBuffer cmd,
  198. UniversalCameraData cameraData,
  199. RTHandle source,
  200. RTHandle destination,
  201. RenderBufferLoadAction loadAction,
  202. RenderBufferStoreAction storeAction,
  203. Material material, int passIndex)
  204. {
  205. bool isRenderToBackBufferTarget = !cameraData.isSceneViewCamera;
  206. #if ENABLE_VR && ENABLE_XR_MODULE
  207. if (cameraData.xr.enabled)
  208. isRenderToBackBufferTarget = new RenderTargetIdentifier(destination.nameID, 0, CubemapFace.Unknown, -1) == new RenderTargetIdentifier(cameraData.xr.renderTarget, 0, CubemapFace.Unknown, -1);
  209. #endif
  210. Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
  211. // We y-flip if
  212. // 1) we are blitting from render texture to back buffer(UV starts at bottom) and
  213. // 2) renderTexture starts UV at top
  214. bool yflip = isRenderToBackBufferTarget && cameraData.targetTexture == null && SystemInfo.graphicsUVStartsAtTop;
  215. Vector4 scaleBias = yflip ? new Vector4(viewportScale.x, -viewportScale.y, 0, viewportScale.y) : new Vector4(viewportScale.x, viewportScale.y, 0, 0);
  216. CoreUtils.SetRenderTarget(cmd, destination, loadAction, storeAction, ClearFlag.None, Color.clear);
  217. if (isRenderToBackBufferTarget)
  218. cmd.SetViewport(cameraData.pixelRect);
  219. // cmd.Blit must be used in Scene View for wireframe mode to make the full screen draw with fill mode
  220. // This branch of the if statement must be removed for render graph and the new command list with a novel way of using Blitter with fill mode
  221. if (GL.wireframe && cameraData.isSceneViewCamera)
  222. {
  223. // This set render target is necessary so we change the LOAD state to DontCare.
  224. cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget,
  225. loadAction, storeAction, // color
  226. RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare); // depth
  227. // Necessary to disable the wireframe here, since Vulkan is handling the wireframe differently
  228. // to handle the Terrain "Draw Instanced" scenario (Ono: case-1205332).
  229. if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan)
  230. {
  231. cmd.SetWireframe(false);
  232. cmd.Blit(source, destination);
  233. cmd.SetWireframe(true);
  234. }
  235. else
  236. {
  237. cmd.Blit(source, destination);
  238. }
  239. }
  240. else if (source.rt == null)
  241. Blitter.BlitTexture(cmd, source.nameID, scaleBias, material, passIndex); // Obsolete usage of RTHandle aliasing a RenderTargetIdentifier
  242. else
  243. Blitter.BlitTexture(cmd, source, scaleBias, material, passIndex);
  244. }
  245. // This is used to render materials that contain built-in shader passes not compatible with URP.
  246. // It will render those legacy passes with error/pink shader.
  247. [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
  248. internal static void CreateRendererParamsObjectsWithError(ref CullingResults cullResults, Camera camera, FilteringSettings filterSettings, SortingCriteria sortFlags, ref RendererListParams param)
  249. {
  250. SortingSettings sortingSettings = new SortingSettings(camera) { criteria = sortFlags };
  251. DrawingSettings errorSettings = new DrawingSettings(m_LegacyShaderPassNames[0], sortingSettings)
  252. {
  253. perObjectData = PerObjectData.None,
  254. overrideMaterial = errorMaterial,
  255. overrideMaterialPassIndex = 0
  256. };
  257. for (int i = 1; i < m_LegacyShaderPassNames.Count; ++i)
  258. errorSettings.SetShaderPassName(i, m_LegacyShaderPassNames[i]);
  259. param = new RendererListParams(cullResults, errorSettings, filterSettings);
  260. }
  261. [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
  262. internal static void CreateRendererListObjectsWithError(ScriptableRenderContext context, ref CullingResults cullResults, Camera camera, FilteringSettings filterSettings, SortingCriteria sortFlags, ref RendererList rl)
  263. {
  264. // TODO: When importing project, AssetPreviewUpdater::CreatePreviewForAsset will be called multiple times.
  265. // This might be in a point that some resources required for the pipeline are not finished importing yet.
  266. // Proper fix is to add a fence on asset import.
  267. if (errorMaterial == null)
  268. {
  269. rl = RendererList.nullRendererList;
  270. return;
  271. }
  272. RendererListParams param = new RendererListParams();
  273. CreateRendererParamsObjectsWithError(ref cullResults, camera, filterSettings, sortFlags, ref param);
  274. rl = context.CreateRendererList(ref param);
  275. }
  276. // This is used to render materials that contain built-in shader passes not compatible with URP.
  277. // It will render those legacy passes with error/pink shader.
  278. [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
  279. internal static void CreateRendererListObjectsWithError(RenderGraph renderGraph, ref CullingResults cullResults, Camera camera, FilteringSettings filterSettings, SortingCriteria sortFlags, ref RendererListHandle rl)
  280. {
  281. // TODO: When importing project, AssetPreviewUpdater::CreatePreviewForAsset will be called multiple times.
  282. // This might be in a point that some resources required for the pipeline are not finished importing yet.
  283. // Proper fix is to add a fence on asset import.
  284. if (errorMaterial == null)
  285. {
  286. rl = new RendererListHandle();
  287. return;
  288. }
  289. RendererListParams param = new RendererListParams();
  290. CreateRendererParamsObjectsWithError(ref cullResults, camera, filterSettings, sortFlags, ref param);
  291. rl = renderGraph.CreateRendererList(param);
  292. }
  293. [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
  294. internal static void DrawRendererListObjectsWithError(RasterCommandBuffer cmd, ref RendererList rl)
  295. {
  296. cmd.DrawRendererList(rl);
  297. }
  298. // Create a RendererList using a RenderStateBlock override is quite common so we have this optimized utility function for it
  299. internal static void CreateRendererListWithRenderStateBlock(ScriptableRenderContext context, ref CullingResults cullResults, DrawingSettings ds, FilteringSettings fs, RenderStateBlock rsb, ref RendererList rl)
  300. {
  301. RendererListParams param = new RendererListParams();
  302. unsafe
  303. {
  304. // Taking references to stack variables in the current function does not require any pinning (as long as you stay within the scope)
  305. // so we can safely alias it as a native array
  306. RenderStateBlock* rsbPtr = &rsb;
  307. var stateBlocks = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<RenderStateBlock>(rsbPtr, 1, Allocator.None);
  308. var shaderTag = ShaderTagId.none;
  309. var tagValues = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<ShaderTagId>(&shaderTag, 1, Allocator.None);
  310. // Inside CreateRendererList (below), we pass the NativeArrays to C++ by calling GetUnsafeReadOnlyPtr
  311. // This will check read access but NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray does not set up the SafetyHandle (by design) so create/add it here
  312. // NOTE: we explicitly share the handle
  313. #if ENABLE_UNITY_COLLECTIONS_CHECKS
  314. var safetyHandle = AtomicSafetyHandle.Create();
  315. AtomicSafetyHandle.SetAllowReadOrWriteAccess(safetyHandle, true);
  316. NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref stateBlocks, safetyHandle);
  317. NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref tagValues, safetyHandle);
  318. #endif
  319. // Create & schedule the RL
  320. param = new RendererListParams(cullResults, ds, fs)
  321. {
  322. tagValues = tagValues,
  323. stateBlocks = stateBlocks
  324. };
  325. rl = context.CreateRendererList(ref param);
  326. // we need to explicitly release the SafetyHandle
  327. #if ENABLE_UNITY_COLLECTIONS_CHECKS
  328. AtomicSafetyHandle.Release(safetyHandle);
  329. #endif
  330. }
  331. }
  332. static ShaderTagId[] s_ShaderTagValues = new ShaderTagId[1];
  333. static RenderStateBlock[] s_RenderStateBlocks = new RenderStateBlock[1];
  334. // Create a RendererList using a RenderStateBlock override is quite common so we have this optimized utility function for it
  335. internal static void CreateRendererListWithRenderStateBlock(RenderGraph renderGraph, ref CullingResults cullResults, DrawingSettings ds, FilteringSettings fs, RenderStateBlock rsb, ref RendererListHandle rl)
  336. {
  337. s_ShaderTagValues[0] = ShaderTagId.none;
  338. s_RenderStateBlocks[0] = rsb;
  339. NativeArray<ShaderTagId> tagValues = new NativeArray<ShaderTagId>(s_ShaderTagValues, Allocator.Temp);
  340. NativeArray<RenderStateBlock> stateBlocks = new NativeArray<RenderStateBlock>(s_RenderStateBlocks, Allocator.Temp);
  341. var param = new RendererListParams(cullResults, ds, fs)
  342. {
  343. tagValues = tagValues,
  344. stateBlocks = stateBlocks,
  345. isPassTagName = false
  346. };
  347. rl = renderGraph.CreateRendererList(param);
  348. }
  349. // Caches render texture format support. SystemInfo.SupportsRenderTextureFormat allocates memory due to boxing.
  350. static Dictionary<RenderTextureFormat, bool> m_RenderTextureFormatSupport = new Dictionary<RenderTextureFormat, bool>();
  351. internal static void ClearSystemInfoCache()
  352. {
  353. m_RenderTextureFormatSupport.Clear();
  354. }
  355. /// <summary>
  356. /// Checks if a render texture format is supported by the run-time system.
  357. /// Similar to <see cref="SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat)"/>, but doesn't allocate memory.
  358. /// </summary>
  359. /// <param name="format">The format to look up.</param>
  360. /// <returns>Returns true if the graphics card supports the given <c>RenderTextureFormat</c></returns>
  361. public static bool SupportsRenderTextureFormat(RenderTextureFormat format)
  362. {
  363. if (!m_RenderTextureFormatSupport.TryGetValue(format, out var support))
  364. {
  365. support = SystemInfo.SupportsRenderTextureFormat(format);
  366. m_RenderTextureFormatSupport.Add(format, support);
  367. }
  368. return support;
  369. }
  370. /// <summary>
  371. /// Obsolete. Use <see cref="SystemInfo.IsFormatSupported"/> instead.
  372. /// </summary>
  373. /// <param name="format">The format to look up.</param>
  374. /// <param name="usage">The format usage to look up.</param>
  375. /// <returns>Returns true if the graphics card supports the given <c>GraphicsFormat</c></returns>
  376. [Obsolete("Use SystemInfo.IsFormatSupported instead.", false)]
  377. public static bool SupportsGraphicsFormat(GraphicsFormat format, FormatUsage usage)
  378. {
  379. GraphicsFormatUsage graphicsFormatUsage = (GraphicsFormatUsage)(1 << (int)usage);
  380. return SystemInfo.IsFormatSupported(format, graphicsFormatUsage);
  381. }
  382. /// <summary>
  383. /// Return the last colorBuffer index actually referring to an existing RenderTarget
  384. /// </summary>
  385. /// <param name="colorBuffers"></param>
  386. /// <returns></returns>
  387. internal static int GetLastValidColorBufferIndex(RenderTargetIdentifier[] colorBuffers)
  388. {
  389. int i = colorBuffers.Length - 1;
  390. for (; i >= 0; --i)
  391. {
  392. if (colorBuffers[i] != 0)
  393. break;
  394. }
  395. return i;
  396. }
  397. /// <summary>
  398. /// Return the number of items in colorBuffers actually referring to an existing RenderTarget
  399. /// </summary>
  400. /// <param name="colorBuffers"></param>
  401. /// <returns></returns>
  402. internal static uint GetValidColorBufferCount(RTHandle[] colorBuffers)
  403. {
  404. uint nonNullColorBuffers = 0;
  405. if (colorBuffers != null)
  406. {
  407. foreach (var identifier in colorBuffers)
  408. {
  409. if (identifier != null && identifier.nameID != 0)
  410. ++nonNullColorBuffers;
  411. }
  412. }
  413. return nonNullColorBuffers;
  414. }
  415. /// <summary>
  416. /// Return true if colorBuffers is an actual MRT setup
  417. /// </summary>
  418. /// <param name="colorBuffers"></param>
  419. /// <returns></returns>
  420. internal static bool IsMRT(RTHandle[] colorBuffers)
  421. {
  422. return GetValidColorBufferCount(colorBuffers) > 1;
  423. }
  424. /// <summary>
  425. /// Return true if value can be found in source (without recurring to Linq)
  426. /// </summary>
  427. /// <param name="source"></param>
  428. /// <param name="value"></param>
  429. /// <returns></returns>
  430. internal static bool Contains(RenderTargetIdentifier[] source, RenderTargetIdentifier value)
  431. {
  432. foreach (var identifier in source)
  433. {
  434. if (identifier == value)
  435. return true;
  436. }
  437. return false;
  438. }
  439. /// <summary>
  440. /// Return the index where value was found source. Otherwise, return -1. (without recurring to Linq)
  441. /// </summary>
  442. /// <param name="source"></param>
  443. /// <param name="value"></param>
  444. /// <returns></returns>
  445. internal static int IndexOf(RTHandle[] source, RenderTargetIdentifier value)
  446. {
  447. for (int i = 0; i < source.Length; ++i)
  448. {
  449. if (source[i] == value)
  450. return i;
  451. }
  452. return -1;
  453. }
  454. /// <summary>
  455. /// Return the index where value was found source. Otherwise, return -1. (without recurring to Linq)
  456. /// </summary>
  457. /// <param name="source"></param>
  458. /// <param name="value"></param>
  459. /// <returns></returns>
  460. internal static int IndexOf(RTHandle[] source, RTHandle value) => IndexOf(source, value.nameID);
  461. /// <summary>
  462. /// Return the number of RenderTargetIdentifiers in "source" that are valid (not 0) and different from "value" (without recurring to Linq)
  463. /// </summary>
  464. /// <param name="source"></param>
  465. /// <param name="value"></param>
  466. /// <returns></returns>
  467. internal static uint CountDistinct(RTHandle[] source, RTHandle value)
  468. {
  469. uint count = 0;
  470. for (int i = 0; i < source.Length; ++i)
  471. {
  472. if (source[i] != null && source[i].nameID != 0 && source[i].nameID != value.nameID)
  473. ++count;
  474. }
  475. return count;
  476. }
  477. /// <summary>
  478. /// Return the index of last valid (i.e different from 0) RenderTargetIdentifiers in "source" (without recurring to Linq)
  479. /// </summary>
  480. /// <param name="source"></param>
  481. /// <returns></returns>
  482. internal static int LastValid(RTHandle[] source)
  483. {
  484. for (int i = source.Length - 1; i >= 0; --i)
  485. {
  486. if (source[i] != null && source[i].nameID != 0)
  487. return i;
  488. }
  489. return -1;
  490. }
  491. /// <summary>
  492. /// Return true if ClearFlag a contains ClearFlag b
  493. /// </summary>
  494. /// <param name="a"></param>
  495. /// <param name="b"></param>
  496. /// <returns></returns>
  497. internal static bool Contains(ClearFlag a, ClearFlag b)
  498. {
  499. return (a & b) == b;
  500. }
  501. /// <summary>
  502. /// Return true if "left" and "right" are the same (without recurring to Linq)
  503. /// </summary>
  504. /// <param name="left"></param>
  505. /// <param name="right"></param>
  506. /// <returns></returns>
  507. internal static bool SequenceEqual(RTHandle[] left, RTHandle[] right)
  508. {
  509. if (left.Length != right.Length)
  510. return false;
  511. for (int i = 0; i < left.Length; ++i)
  512. if (left[i].nameID != right[i].nameID)
  513. return false;
  514. return true;
  515. }
  516. internal static bool MultisampleDepthResolveSupported()
  517. {
  518. // Temporarily disabling depth resolve a driver bug on OSX when using some AMD graphics cards. Temporarily disabling depth resolve on that platform
  519. // TODO: re-enable once the issue is investigated/fixed
  520. if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer)
  521. return false;
  522. // Should we also check if the format has stencil and check stencil resolve capability only in that case?
  523. return SystemInfo.supportsMultisampleResolveDepth && SystemInfo.supportsMultisampleResolveStencil;
  524. }
  525. /// <summary>
  526. /// Return true if handle does not match descriptor
  527. /// </summary>
  528. /// <param name="handle">RTHandle to check (can be null)</param>
  529. /// <param name="descriptor">Descriptor for the RTHandle to match</param>
  530. /// <param name="filterMode">Filtering mode of the RTHandle.</param>
  531. /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
  532. /// <param name="anisoLevel">Anisotropic filtering level.</param>
  533. /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
  534. /// <param name="name">Name of the RTHandle.</param>
  535. /// <param name="scaled">Check if the RTHandle has auto scaling enabled if not, check the widths and heights</param>
  536. /// <returns></returns>
  537. internal static bool RTHandleNeedsReAlloc(
  538. RTHandle handle,
  539. in TextureDesc descriptor,
  540. bool scaled)
  541. {
  542. if (handle == null || handle.rt == null)
  543. return true;
  544. if (handle.useScaling != scaled)
  545. return true;
  546. if (!scaled && (handle.rt.width != descriptor.width || handle.rt.height != descriptor.height))
  547. return true;
  548. return
  549. (DepthBits)handle.rt.descriptor.depthBufferBits != descriptor.depthBufferBits ||
  550. (handle.rt.descriptor.depthBufferBits == (int)DepthBits.None && handle.rt.descriptor.graphicsFormat != descriptor.colorFormat) ||
  551. handle.rt.descriptor.dimension != descriptor.dimension ||
  552. handle.rt.descriptor.enableRandomWrite != descriptor.enableRandomWrite ||
  553. handle.rt.descriptor.useMipMap != descriptor.useMipMap ||
  554. handle.rt.descriptor.autoGenerateMips != descriptor.autoGenerateMips ||
  555. (MSAASamples)handle.rt.descriptor.msaaSamples != descriptor.msaaSamples ||
  556. handle.rt.descriptor.bindMS != descriptor.bindTextureMS ||
  557. handle.rt.descriptor.useDynamicScale != descriptor.useDynamicScale ||
  558. handle.rt.descriptor.memoryless != descriptor.memoryless ||
  559. handle.rt.filterMode != descriptor.filterMode ||
  560. handle.rt.wrapMode != descriptor.wrapMode ||
  561. handle.rt.anisoLevel != descriptor.anisoLevel ||
  562. handle.rt.mipMapBias != descriptor.mipMapBias ||
  563. handle.name != descriptor.name;
  564. }
  565. /// <summary>
  566. /// Returns the RenderTargetIdentifier of the current camera target.
  567. /// </summary>
  568. /// <param name="renderingData"></param>
  569. /// <returns></returns>
  570. internal static RenderTargetIdentifier GetCameraTargetIdentifier(ref RenderingData renderingData)
  571. {
  572. // Note: We need to get the cameraData.targetTexture as this will get the targetTexture of the camera stack.
  573. // Overlay cameras need to output to the target described in the base camera while doing camera stack.
  574. ref CameraData cameraData = ref renderingData.cameraData;
  575. RenderTargetIdentifier cameraTarget = (cameraData.targetTexture != null) ? new RenderTargetIdentifier(cameraData.targetTexture) : BuiltinRenderTextureType.CameraTarget;
  576. #if ENABLE_VR && ENABLE_XR_MODULE
  577. if (cameraData.xr.enabled)
  578. {
  579. if (cameraData.xr.singlePassEnabled)
  580. {
  581. cameraTarget = cameraData.xr.renderTarget;
  582. }
  583. else
  584. {
  585. int depthSlice = cameraData.xr.GetTextureArraySlice();
  586. cameraTarget = new RenderTargetIdentifier(cameraData.xr.renderTarget, 0, CubemapFace.Unknown, depthSlice);
  587. }
  588. }
  589. #endif
  590. return cameraTarget;
  591. }
  592. /// <summary>
  593. /// Re-allocate fixed-size RTHandle if it is not allocated or doesn't match the descriptor
  594. /// </summary>
  595. /// <param name="handle">RTHandle to check (can be null)</param>
  596. /// <param name="descriptor">Descriptor for the RTHandle to match</param>
  597. /// <param name="filterMode">Filtering mode of the RTHandle.</param>
  598. /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
  599. /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param>
  600. /// <param name="anisoLevel">Anisotropic filtering level.</param>
  601. /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
  602. /// <param name="name">Name of the RTHandle.</param>
  603. /// <returns>If an allocation was done.</returns>
  604. [Obsolete("This method will be removed in a future release. Please use ReAllocateHandleIfNeeded instead. #from(2023.3)")]
  605. public static bool ReAllocateIfNeeded(
  606. ref RTHandle handle,
  607. in RenderTextureDescriptor descriptor,
  608. FilterMode filterMode = FilterMode.Point,
  609. TextureWrapMode wrapMode = TextureWrapMode.Repeat,
  610. bool isShadowMap = false,
  611. int anisoLevel = 1,
  612. float mipMapBias = 0,
  613. string name = "")
  614. {
  615. TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Explicit, anisoLevel, 0, filterMode, wrapMode, name);
  616. if (RTHandleNeedsReAlloc(handle, requestRTDesc, false))
  617. {
  618. if (handle != null && handle.rt != null)
  619. {
  620. TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Explicit, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode, handle.name);
  621. AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
  622. }
  623. if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
  624. {
  625. return true;
  626. }
  627. else
  628. {
  629. handle = RTHandles.Alloc(descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name);
  630. return true;
  631. }
  632. }
  633. return false;
  634. }
  635. /// <summary>
  636. /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor
  637. /// </summary>
  638. /// <param name="handle">RTHandle to check (can be null)</param>
  639. /// <param name="scaleFactor">Constant scale for the RTHandle size computation.</param>
  640. /// <param name="descriptor">Descriptor for the RTHandle to match</param>
  641. /// <param name="filterMode">Filtering mode of the RTHandle.</param>
  642. /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
  643. /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param>
  644. /// <param name="anisoLevel">Anisotropic filtering level.</param>
  645. /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
  646. /// <param name="name">Name of the RTHandle.</param>
  647. /// <returns>If the RTHandle should be re-allocated</returns>
  648. [Obsolete("This method will be removed in a future release. Please use ReAllocateHandleIfNeeded instead. #from(2023.3)")]
  649. public static bool ReAllocateIfNeeded(
  650. ref RTHandle handle,
  651. Vector2 scaleFactor,
  652. in RenderTextureDescriptor descriptor,
  653. FilterMode filterMode = FilterMode.Point,
  654. TextureWrapMode wrapMode = TextureWrapMode.Repeat,
  655. bool isShadowMap = false,
  656. int anisoLevel = 1,
  657. float mipMapBias = 0,
  658. string name = "")
  659. {
  660. var usingConstantScale = handle != null && handle.useScaling && handle.scaleFactor == scaleFactor;
  661. TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Scale, anisoLevel, 0, filterMode, wrapMode);
  662. if (!usingConstantScale || RTHandleNeedsReAlloc(handle, requestRTDesc, true))
  663. {
  664. if (handle != null && handle.rt != null)
  665. {
  666. TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Scale, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode);
  667. AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
  668. }
  669. if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
  670. {
  671. return true;
  672. }
  673. else
  674. {
  675. handle = RTHandles.Alloc(scaleFactor, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name);
  676. return true;
  677. }
  678. }
  679. return false;
  680. }
  681. /// <summary>
  682. /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor
  683. /// </summary>
  684. /// <param name="handle">RTHandle to check (can be null)</param>
  685. /// <param name="scaleFunc">Function used for the RTHandle size computation.</param>
  686. /// <param name="descriptor">Descriptor for the RTHandle to match</param>
  687. /// <param name="filterMode">Filtering mode of the RTHandle.</param>
  688. /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
  689. /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param>
  690. /// <param name="anisoLevel">Anisotropic filtering level.</param>
  691. /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
  692. /// <param name="name">Name of the RTHandle.</param>
  693. /// <returns>If an allocation was done</returns>
  694. [Obsolete("This method will be removed in a future release. Please use ReAllocateHandleIfNeeded instead. #from(2023.3)")]
  695. public static bool ReAllocateIfNeeded(
  696. ref RTHandle handle,
  697. ScaleFunc scaleFunc,
  698. in RenderTextureDescriptor descriptor,
  699. FilterMode filterMode = FilterMode.Point,
  700. TextureWrapMode wrapMode = TextureWrapMode.Repeat,
  701. bool isShadowMap = false,
  702. int anisoLevel = 1,
  703. float mipMapBias = 0,
  704. string name = "")
  705. {
  706. var usingScaleFunction = handle != null && handle.useScaling && handle.scaleFactor == Vector2.zero;
  707. TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Functor, anisoLevel, 0, filterMode, wrapMode);
  708. if (!usingScaleFunction || RTHandleNeedsReAlloc(handle, requestRTDesc, true))
  709. {
  710. if (handle != null && handle.rt != null)
  711. {
  712. TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Functor, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode);
  713. AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
  714. }
  715. if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
  716. {
  717. return true;
  718. }
  719. else
  720. {
  721. handle = RTHandles.Alloc(scaleFunc, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name);
  722. return true;
  723. }
  724. }
  725. return false;
  726. }
  727. /// <summary>
  728. /// Re-allocate fixed-size RTHandle if it is not allocated or doesn't match the descriptor
  729. /// </summary>
  730. /// <param name="handle">RTHandle to check (can be null)</param>
  731. /// <param name="descriptor">Descriptor for the RTHandle to match</param>
  732. /// <param name="filterMode">Filtering mode of the RTHandle.</param>
  733. /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
  734. /// <param name="anisoLevel">Anisotropic filtering level.</param>
  735. /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
  736. /// <param name="name">Name of the RTHandle.</param>
  737. /// <returns>If an allocation was done.</returns>
  738. public static bool ReAllocateHandleIfNeeded(
  739. ref RTHandle handle,
  740. in RenderTextureDescriptor descriptor,
  741. FilterMode filterMode = FilterMode.Point,
  742. TextureWrapMode wrapMode = TextureWrapMode.Repeat,
  743. int anisoLevel = 1,
  744. float mipMapBias = 0,
  745. string name = "")
  746. {
  747. TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Explicit, anisoLevel, 0, filterMode, wrapMode, name);
  748. if (RTHandleNeedsReAlloc(handle, requestRTDesc, false))
  749. {
  750. if (handle != null && handle.rt != null)
  751. {
  752. TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Explicit, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode, handle.name);
  753. AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
  754. }
  755. if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
  756. {
  757. return true;
  758. }
  759. var actualFormat = descriptor.graphicsFormat != GraphicsFormat.None ? descriptor.graphicsFormat : descriptor.depthStencilFormat;
  760. RTHandleAllocInfo allocInfo = new RTHandleAllocInfo();
  761. allocInfo.slices = descriptor.volumeDepth;
  762. allocInfo.format = actualFormat;
  763. allocInfo.filterMode = filterMode;
  764. allocInfo.wrapModeU = wrapMode;
  765. allocInfo.wrapModeV = wrapMode;
  766. allocInfo.wrapModeW = wrapMode;
  767. allocInfo.dimension = descriptor.dimension;
  768. allocInfo.enableRandomWrite = descriptor.enableRandomWrite;
  769. allocInfo.useMipMap = descriptor.useMipMap;
  770. allocInfo.autoGenerateMips = descriptor.autoGenerateMips;
  771. allocInfo.anisoLevel = anisoLevel;
  772. allocInfo.mipMapBias = mipMapBias;
  773. allocInfo.msaaSamples = (MSAASamples)descriptor.msaaSamples;
  774. allocInfo.bindTextureMS = descriptor.bindMS;
  775. allocInfo.useDynamicScale = descriptor.useDynamicScale;
  776. allocInfo.memoryless = descriptor.memoryless;
  777. allocInfo.vrUsage = descriptor.vrUsage;
  778. allocInfo.name = name;
  779. handle = RTHandles.Alloc(descriptor.width, descriptor.height, allocInfo);
  780. return true;
  781. }
  782. return false;
  783. }
  784. /// <summary>
  785. /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor
  786. /// </summary>
  787. /// <param name="handle">RTHandle to check (can be null)</param>
  788. /// <param name="scaleFactor">Constant scale for the RTHandle size computation.</param>
  789. /// <param name="descriptor">Descriptor for the RTHandle to match</param>
  790. /// <param name="filterMode">Filtering mode of the RTHandle.</param>
  791. /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
  792. /// <param name="anisoLevel">Anisotropic filtering level.</param>
  793. /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
  794. /// <param name="name">Name of the RTHandle.</param>
  795. /// <returns>If an allocation was done.</returns>
  796. public static bool ReAllocateHandleIfNeeded(
  797. ref RTHandle handle,
  798. Vector2 scaleFactor,
  799. in RenderTextureDescriptor descriptor,
  800. FilterMode filterMode = FilterMode.Point,
  801. TextureWrapMode wrapMode = TextureWrapMode.Repeat,
  802. int anisoLevel = 1,
  803. float mipMapBias = 0,
  804. string name = "")
  805. {
  806. var usingConstantScale = handle != null && handle.useScaling && handle.scaleFactor == scaleFactor;
  807. TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Scale, anisoLevel, 0, filterMode, wrapMode);
  808. if (!usingConstantScale || RTHandleNeedsReAlloc(handle, requestRTDesc, true))
  809. {
  810. if (handle != null && handle.rt != null)
  811. {
  812. TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Scale, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode);
  813. AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
  814. }
  815. if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
  816. {
  817. return true;
  818. }
  819. var actualFormat = descriptor.graphicsFormat != GraphicsFormat.None ? descriptor.graphicsFormat : descriptor.depthStencilFormat;
  820. RTHandleAllocInfo allocInfo = new RTHandleAllocInfo();
  821. allocInfo.slices = descriptor.volumeDepth;
  822. allocInfo.format = actualFormat;
  823. allocInfo.filterMode = filterMode;
  824. allocInfo.wrapModeU = wrapMode;
  825. allocInfo.wrapModeV = wrapMode;
  826. allocInfo.wrapModeW = wrapMode;
  827. allocInfo.dimension = descriptor.dimension;
  828. allocInfo.enableRandomWrite = descriptor.enableRandomWrite;
  829. allocInfo.useMipMap = descriptor.useMipMap;
  830. allocInfo.autoGenerateMips = descriptor.autoGenerateMips;
  831. allocInfo.anisoLevel = anisoLevel;
  832. allocInfo.mipMapBias = mipMapBias;
  833. allocInfo.msaaSamples = (MSAASamples)descriptor.msaaSamples;
  834. allocInfo.bindTextureMS = descriptor.bindMS;
  835. allocInfo.useDynamicScale = descriptor.useDynamicScale;
  836. allocInfo.memoryless = descriptor.memoryless;
  837. allocInfo.vrUsage = descriptor.vrUsage;
  838. allocInfo.name = name;
  839. handle = RTHandles.Alloc(scaleFactor, allocInfo);
  840. return true;
  841. }
  842. return false;
  843. }
  844. /// <summary>
  845. /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor
  846. /// </summary>
  847. /// <param name="handle">RTHandle to check (can be null)</param>
  848. /// <param name="scaleFunc">Function used for the RTHandle size computation.</param>
  849. /// <param name="descriptor">Descriptor for the RTHandle to match</param>
  850. /// <param name="filterMode">Filtering mode of the RTHandle.</param>
  851. /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
  852. /// <param name="anisoLevel">Anisotropic filtering level.</param>
  853. /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
  854. /// <param name="name">Name of the RTHandle.</param>
  855. /// <returns>If an allocation was done.</returns>
  856. public static bool ReAllocateHandleIfNeeded(
  857. ref RTHandle handle,
  858. ScaleFunc scaleFunc,
  859. in RenderTextureDescriptor descriptor,
  860. FilterMode filterMode = FilterMode.Point,
  861. TextureWrapMode wrapMode = TextureWrapMode.Repeat,
  862. int anisoLevel = 1,
  863. float mipMapBias = 0,
  864. string name = "")
  865. {
  866. var usingScaleFunction = handle != null && handle.useScaling && handle.scaleFactor == Vector2.zero;
  867. TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Functor, anisoLevel, 0, filterMode, wrapMode);
  868. if (!usingScaleFunction || RTHandleNeedsReAlloc(handle, requestRTDesc, true))
  869. {
  870. if (handle != null && handle.rt != null)
  871. {
  872. TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Functor, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode);
  873. AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
  874. }
  875. if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
  876. {
  877. return true;
  878. }
  879. var actualFormat = descriptor.graphicsFormat != GraphicsFormat.None ? descriptor.graphicsFormat : descriptor.depthStencilFormat;
  880. RTHandleAllocInfo allocInfo = new RTHandleAllocInfo();
  881. allocInfo.slices = descriptor.volumeDepth;
  882. allocInfo.format = actualFormat;
  883. allocInfo.filterMode = filterMode;
  884. allocInfo.wrapModeU = wrapMode;
  885. allocInfo.wrapModeV = wrapMode;
  886. allocInfo.wrapModeW = wrapMode;
  887. allocInfo.dimension = descriptor.dimension;
  888. allocInfo.enableRandomWrite = descriptor.enableRandomWrite;
  889. allocInfo.useMipMap = descriptor.useMipMap;
  890. allocInfo.autoGenerateMips = descriptor.autoGenerateMips;
  891. allocInfo.anisoLevel = anisoLevel;
  892. allocInfo.mipMapBias = mipMapBias;
  893. allocInfo.msaaSamples = (MSAASamples)descriptor.msaaSamples;
  894. allocInfo.bindTextureMS = descriptor.bindMS;
  895. allocInfo.useDynamicScale = descriptor.useDynamicScale;
  896. allocInfo.memoryless = descriptor.memoryless;
  897. allocInfo.vrUsage = descriptor.vrUsage;
  898. allocInfo.name = name;
  899. handle = RTHandles.Alloc(scaleFunc, allocInfo);
  900. return true;
  901. }
  902. return false;
  903. }
  904. /// <summary>
  905. /// Resize the rthandle pool's max stale resource capacity. The default value is 32.
  906. /// Increasing the capacity may have a negative impact on the memory usage(dued to staled resources in pool).
  907. /// Increasing the capacity may improve runtime performance (by reducing the runtime RTHandle realloc count in multi view/multi camera setup).
  908. /// Setting capacity will purge the current pool. It is recommended to setup the capacity upfront and not changing it during the runtime.
  909. /// </summary>
  910. /// <param name="capacity">Max capacity to set</param>
  911. /// <returns> Return true if set successfully. Return false if URP is not initialized and pool does not exist yet. </returns>
  912. public static bool SetMaxRTHandlePoolCapacity(int capacity)
  913. {
  914. if (UniversalRenderPipeline.s_RTHandlePool == null)
  915. return false;
  916. UniversalRenderPipeline.s_RTHandlePool.staleResourceCapacity = capacity;
  917. return true;
  918. }
  919. /// <summary>
  920. /// Add stale rtHandle to pool so that it could be reused in the future.
  921. /// For stale rtHandle failed to add to pool(could happen when pool is reaching its max stale resource capacity), the stale resource will be released.
  922. /// </summary>
  923. internal static void AddStaleResourceToPoolOrRelease(TextureDesc desc, RTHandle handle)
  924. {
  925. if (!UniversalRenderPipeline.s_RTHandlePool.AddResourceToPool(desc, handle, Time.frameCount))
  926. RTHandles.Release(handle);
  927. }
  928. /// <summary>
  929. /// Creates <c>DrawingSettings</c> based on current the rendering state.
  930. /// </summary>
  931. /// <param name="shaderTagId">Shader pass tag to render.</param>
  932. /// <param name="renderingData">Current rendering state.</param>
  933. /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
  934. /// <returns></returns>
  935. /// <seealso cref="DrawingSettings"/>
  936. static public DrawingSettings CreateDrawingSettings(ShaderTagId shaderTagId, ref RenderingData renderingData, SortingCriteria sortingCriteria)
  937. {
  938. UniversalRenderingData universalRenderingData = renderingData.frameData.Get<UniversalRenderingData>();
  939. UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
  940. UniversalLightData lightData = renderingData.frameData.Get<UniversalLightData>();
  941. return CreateDrawingSettings(shaderTagId, universalRenderingData, cameraData, lightData, sortingCriteria);
  942. }
  943. /// <summary>
  944. /// Creates <c>DrawingSettings</c> based on current the rendering state.
  945. /// </summary>
  946. /// <param name="shaderTagId">Shader pass tag to render.</param>
  947. /// <param name="renderingData">Current rendering state.</param>
  948. /// <param name="cameraData">Current camera state.</param>
  949. /// <param name="lightData">Current light state.</param>
  950. /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
  951. /// <returns></returns>
  952. /// <seealso cref="DrawingSettings"/>
  953. static public DrawingSettings CreateDrawingSettings(ShaderTagId shaderTagId, UniversalRenderingData renderingData,
  954. UniversalCameraData cameraData, UniversalLightData lightData, SortingCriteria sortingCriteria)
  955. {
  956. Camera camera = cameraData.camera;
  957. SortingSettings sortingSettings = new SortingSettings(camera) { criteria = sortingCriteria };
  958. DrawingSettings settings = new DrawingSettings(shaderTagId, sortingSettings)
  959. {
  960. perObjectData = renderingData.perObjectData,
  961. mainLightIndex = lightData.mainLightIndex,
  962. enableDynamicBatching = renderingData.supportsDynamicBatching,
  963. // Disable instancing for preview cameras. This is consistent with the built-in forward renderer. Also fixes case 1127324.
  964. enableInstancing = camera.cameraType == CameraType.Preview ? false : true,
  965. };
  966. return settings;
  967. }
  968. /// <summary>
  969. /// Creates <c>DrawingSettings</c> based on current rendering state.
  970. /// </summary>
  971. /// <param name="shaderTagIdList">List of shader pass tag to render.</param>
  972. /// <param name="renderingData">Current rendering state.</param>
  973. /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
  974. /// <returns></returns>
  975. /// <seealso cref="DrawingSettings"/>
  976. static public DrawingSettings CreateDrawingSettings(List<ShaderTagId> shaderTagIdList,
  977. ref RenderingData renderingData, SortingCriteria sortingCriteria)
  978. {
  979. UniversalRenderingData universalRenderingData = renderingData.frameData.Get<UniversalRenderingData>();
  980. UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
  981. UniversalLightData lightData = renderingData.frameData.Get<UniversalLightData>();
  982. return CreateDrawingSettings(shaderTagIdList, universalRenderingData, cameraData, lightData, sortingCriteria);
  983. }
  984. /// <summary>
  985. /// Creates <c>DrawingSettings</c> based on current rendering state.
  986. /// </summary>
  987. /// <param name="shaderTagIdList">List of shader pass tag to render.</param>
  988. /// <param name="renderingData">Current rendering state.</param>
  989. /// <param name="cameraData">Current camera state.</param>
  990. /// <param name="lightData">Current light state.</param>
  991. /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
  992. /// <returns></returns>
  993. /// <seealso cref="DrawingSettings"/>
  994. static public DrawingSettings CreateDrawingSettings(List<ShaderTagId> shaderTagIdList,
  995. UniversalRenderingData renderingData, UniversalCameraData cameraData,
  996. UniversalLightData lightData, SortingCriteria sortingCriteria)
  997. {
  998. if (shaderTagIdList == null || shaderTagIdList.Count == 0)
  999. {
  1000. Debug.LogWarning("ShaderTagId list is invalid. DrawingSettings is created with default pipeline ShaderTagId");
  1001. return CreateDrawingSettings(new ShaderTagId("UniversalPipeline"), renderingData, cameraData, lightData, sortingCriteria);
  1002. }
  1003. DrawingSettings settings = CreateDrawingSettings(shaderTagIdList[0], renderingData, cameraData, lightData, sortingCriteria);
  1004. for (int i = 1; i < shaderTagIdList.Count; ++i)
  1005. settings.SetShaderPassName(i, shaderTagIdList[i]);
  1006. return settings;
  1007. }
  1008. /// <summary>
  1009. /// Returns the scale bias vector to use for final blits to the backbuffer, based on scaling mode and y-flip platform requirements.
  1010. /// </summary>
  1011. /// <param name="source"></param>
  1012. /// <param name="destination"></param>
  1013. /// <param name="cameraData"></param>
  1014. /// <returns></returns>
  1015. internal static Vector4 GetFinalBlitScaleBias(RTHandle source, RTHandle destination, UniversalCameraData cameraData)
  1016. {
  1017. Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
  1018. var yflip = cameraData.IsRenderTargetProjectionMatrixFlipped(destination);
  1019. Vector4 scaleBias = !yflip ? new Vector4(viewportScale.x, -viewportScale.y, 0, viewportScale.y) : new Vector4(viewportScale.x, viewportScale.y, 0, 0);
  1020. return scaleBias;
  1021. }
  1022. }
  1023. }