12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124 |
- using System;
- using System.Collections.Generic;
- using Unity.Collections;
- using Unity.Collections.LowLevel.Unsafe;
- using UnityEngine.Experimental.Rendering;
- using UnityEngine.Rendering.RenderGraphModule;
- using System.Diagnostics;
-
- namespace UnityEngine.Rendering.Universal
- {
- /// <summary>
- /// Contains properties and helper functions that you can use when rendering.
- /// </summary>
- public static class RenderingUtils
- {
- static List<ShaderTagId> m_LegacyShaderPassNames = new List<ShaderTagId>
- {
- new ShaderTagId("Always"),
- new ShaderTagId("ForwardBase"),
- new ShaderTagId("PrepassBase"),
- new ShaderTagId("Vertex"),
- new ShaderTagId("VertexLMRGBM"),
- new ShaderTagId("VertexLM"),
- };
-
- static AttachmentDescriptor s_EmptyAttachment = new AttachmentDescriptor(GraphicsFormat.None);
- internal static AttachmentDescriptor emptyAttachment
- {
- get
- {
- return s_EmptyAttachment;
- }
- }
-
- static Mesh s_FullscreenMesh = null;
-
- /// <summary>
- /// Returns a mesh that you can use with <see cref="CommandBuffer.DrawMesh(Mesh, Matrix4x4, Material)"/> to render full-screen effects.
- /// </summary>
- [Obsolete("Use Blitter.BlitCameraTexture instead of CommandBuffer.DrawMesh(fullscreenMesh, ...)")] // TODO OBSOLETE: need to fix the URP test failures when bumping
- public static Mesh fullscreenMesh
- {
- get
- {
- if (s_FullscreenMesh != null)
- return s_FullscreenMesh;
-
- float topV = 1.0f;
- float bottomV = 0.0f;
-
- s_FullscreenMesh = new Mesh { name = "Fullscreen Quad" };
- s_FullscreenMesh.SetVertices(new List<Vector3>
- {
- new Vector3(-1.0f, -1.0f, 0.0f),
- new Vector3(-1.0f, 1.0f, 0.0f),
- new Vector3(1.0f, -1.0f, 0.0f),
- new Vector3(1.0f, 1.0f, 0.0f)
- });
-
- s_FullscreenMesh.SetUVs(0, new List<Vector2>
- {
- new Vector2(0.0f, bottomV),
- new Vector2(0.0f, topV),
- new Vector2(1.0f, bottomV),
- new Vector2(1.0f, topV)
- });
-
- s_FullscreenMesh.SetIndices(new[] { 0, 1, 2, 2, 1, 3 }, MeshTopology.Triangles, 0, false);
- s_FullscreenMesh.UploadMeshData(true);
- return s_FullscreenMesh;
- }
- }
-
- internal static bool useStructuredBuffer
- {
- // There are some performance issues with StructuredBuffers in some platforms.
- // We fallback to UBO in those cases.
- get
- {
- // TODO: For now disabling SSBO until figure out Vulkan binding issues.
- // When enabling this also enable USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA in shader side in Input.hlsl
- return false;
-
- // We don't use SSBO in D3D because we can't figure out without adding shader variants if platforms is D3D10.
- //GraphicsDeviceType deviceType = SystemInfo.graphicsDeviceType;
- //return !Application.isMobilePlatform &&
- // (deviceType == GraphicsDeviceType.Metal || deviceType == GraphicsDeviceType.Vulkan ||
- // deviceType == GraphicsDeviceType.PlayStation4 || deviceType == GraphicsDeviceType.PlayStation5 || deviceType == GraphicsDeviceType.XboxOne);
- }
- }
-
- internal static bool SupportsLightLayers(GraphicsDeviceType type)
- {
- return true;
- }
-
- static Material s_ErrorMaterial;
- static Material errorMaterial
- {
- get
- {
- if (s_ErrorMaterial == null)
- {
- // TODO: When importing project, AssetPreviewUpdater::CreatePreviewForAsset will be called multiple times.
- // This might be in a point that some resources required for the pipeline are not finished importing yet.
- // Proper fix is to add a fence on asset import.
- try
- {
- s_ErrorMaterial = new Material(Shader.Find("Hidden/Universal Render Pipeline/FallbackError"));
- }
- catch { }
- }
-
- return s_ErrorMaterial;
- }
- }
-
- /// <summary>
- /// Set view and projection matrices.
- /// 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.
- /// 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>.
- /// </summary>
- /// <param name="cmd">CommandBuffer to submit data to GPU.</param>
- /// <param name="viewMatrix">View matrix to be set.</param>
- /// <param name="projectionMatrix">Projection matrix to be set.</param>
- /// <param name="setInverseMatrices">Set this to true if you also need to set inverse camera matrices.</param>
- public static void SetViewAndProjectionMatrices(CommandBuffer cmd, Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix, bool setInverseMatrices) { SetViewAndProjectionMatrices(CommandBufferHelpers.GetRasterCommandBuffer(cmd), viewMatrix, projectionMatrix, setInverseMatrices); }
- internal static void SetViewAndProjectionMatrices(RasterCommandBuffer cmd, Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix, bool setInverseMatrices)
- {
- Matrix4x4 viewAndProjectionMatrix = projectionMatrix * viewMatrix;
- cmd.SetGlobalMatrix(ShaderPropertyId.viewMatrix, viewMatrix);
- cmd.SetGlobalMatrix(ShaderPropertyId.projectionMatrix, projectionMatrix);
- cmd.SetGlobalMatrix(ShaderPropertyId.viewAndProjectionMatrix, viewAndProjectionMatrix);
-
- if (setInverseMatrices)
- {
- Matrix4x4 inverseViewMatrix = Matrix4x4.Inverse(viewMatrix);
- Matrix4x4 inverseProjectionMatrix = Matrix4x4.Inverse(projectionMatrix);
- Matrix4x4 inverseViewProjection = inverseViewMatrix * inverseProjectionMatrix;
- cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewMatrix, inverseViewMatrix);
- cmd.SetGlobalMatrix(ShaderPropertyId.inverseProjectionMatrix, inverseProjectionMatrix);
- cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewAndProjectionMatrix, inverseViewProjection);
- }
- }
-
- //TODO FrameData: Merge these two SetScaleBiasRt() functions
- internal static void SetScaleBiasRt(RasterCommandBuffer cmd, in UniversalCameraData cameraData, RTHandle rTHandle)
- {
- // SetRenderTarget has logic to flip projection matrix when rendering to render texture. Flip the uv to account for that case.
- bool isCameraColorFinalTarget = (cameraData.cameraType == CameraType.Game && rTHandle.nameID == BuiltinRenderTextureType.CameraTarget && cameraData.camera.targetTexture == null);
- bool yflip = !isCameraColorFinalTarget;
- float flipSign = yflip ? -1.0f : 1.0f;
- Vector4 scaleBiasRt = (flipSign < 0.0f)
- ? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
- : new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
- cmd.SetGlobalVector(Shader.PropertyToID("_ScaleBiasRt"), scaleBiasRt);
- }
-
- internal static void SetScaleBiasRt(RasterCommandBuffer cmd, in RenderingData renderingData)
- {
- var renderer = renderingData.cameraData.renderer;
-
- // SetRenderTarget has logic to flip projection matrix when rendering to render texture. Flip the uv to account for that case.
- CameraData cameraData = renderingData.cameraData;
-
- // Disable obsolete warning for internal usage
- #pragma warning disable CS0618
- bool isCameraColorFinalTarget = (cameraData.cameraType == CameraType.Game && renderer.cameraColorTargetHandle.nameID == BuiltinRenderTextureType.CameraTarget && cameraData.camera.targetTexture == null);
- #pragma warning restore CS0618
-
- bool yflip = !isCameraColorFinalTarget;
- float flipSign = yflip ? -1.0f : 1.0f;
-
- Vector4 scaleBiasRt = (flipSign < 0.0f)
- ? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
- : new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
-
- cmd.SetGlobalVector(Shader.PropertyToID("_ScaleBiasRt"), scaleBiasRt);
- }
-
- internal static void Blit(CommandBuffer cmd,
- RTHandle source,
- Rect viewport,
- RTHandle destination,
- RenderBufferLoadAction loadAction,
- RenderBufferStoreAction storeAction,
- ClearFlag clearFlag,
- Color clearColor,
- Material material,
- int passIndex = 0)
- {
- Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
- CoreUtils.SetRenderTarget(cmd, destination, loadAction, storeAction, ClearFlag.None, Color.clear);
- cmd.SetViewport(viewport);
- Blitter.BlitTexture(cmd, source, viewportScale, material, passIndex);
- }
-
- internal static void Blit(CommandBuffer cmd,
- RTHandle source,
- Rect viewport,
- RTHandle destinationColor,
- RenderBufferLoadAction colorLoadAction,
- RenderBufferStoreAction colorStoreAction,
- RTHandle destinationDepthStencil,
- RenderBufferLoadAction depthStencilLoadAction,
- RenderBufferStoreAction depthStencilStoreAction,
- ClearFlag clearFlag,
- Color clearColor,
- Material material,
- int passIndex = 0)
- {
- Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
- CoreUtils.SetRenderTarget(cmd,
- destinationColor, colorLoadAction, colorStoreAction,
- destinationDepthStencil, depthStencilLoadAction, depthStencilStoreAction,
- clearFlag, clearColor); // implicit depth=1.0f stencil=0x0
- cmd.SetViewport(viewport);
- Blitter.BlitTexture(cmd, source, viewportScale, material, passIndex);
- }
-
- internal static void FinalBlit(
- CommandBuffer cmd,
- UniversalCameraData cameraData,
- RTHandle source,
- RTHandle destination,
- RenderBufferLoadAction loadAction,
- RenderBufferStoreAction storeAction,
- Material material, int passIndex)
- {
- bool isRenderToBackBufferTarget = !cameraData.isSceneViewCamera;
- #if ENABLE_VR && ENABLE_XR_MODULE
- if (cameraData.xr.enabled)
- isRenderToBackBufferTarget = new RenderTargetIdentifier(destination.nameID, 0, CubemapFace.Unknown, -1) == new RenderTargetIdentifier(cameraData.xr.renderTarget, 0, CubemapFace.Unknown, -1);
- #endif
-
- Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
-
- // We y-flip if
- // 1) we are blitting from render texture to back buffer(UV starts at bottom) and
- // 2) renderTexture starts UV at top
- bool yflip = isRenderToBackBufferTarget && cameraData.targetTexture == null && SystemInfo.graphicsUVStartsAtTop;
- Vector4 scaleBias = yflip ? new Vector4(viewportScale.x, -viewportScale.y, 0, viewportScale.y) : new Vector4(viewportScale.x, viewportScale.y, 0, 0);
- CoreUtils.SetRenderTarget(cmd, destination, loadAction, storeAction, ClearFlag.None, Color.clear);
- if (isRenderToBackBufferTarget)
- cmd.SetViewport(cameraData.pixelRect);
-
- // cmd.Blit must be used in Scene View for wireframe mode to make the full screen draw with fill mode
- // 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
- if (GL.wireframe && cameraData.isSceneViewCamera)
- {
- // This set render target is necessary so we change the LOAD state to DontCare.
- cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget,
- loadAction, storeAction, // color
- RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare); // depth
-
- // Necessary to disable the wireframe here, since Vulkan is handling the wireframe differently
- // to handle the Terrain "Draw Instanced" scenario (Ono: case-1205332).
- if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan)
- {
- cmd.SetWireframe(false);
- cmd.Blit(source, destination);
- cmd.SetWireframe(true);
- }
- else
- {
- cmd.Blit(source, destination);
- }
- }
- else if (source.rt == null)
- Blitter.BlitTexture(cmd, source.nameID, scaleBias, material, passIndex); // Obsolete usage of RTHandle aliasing a RenderTargetIdentifier
- else
- Blitter.BlitTexture(cmd, source, scaleBias, material, passIndex);
- }
-
- // This is used to render materials that contain built-in shader passes not compatible with URP.
- // It will render those legacy passes with error/pink shader.
- [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
- internal static void CreateRendererParamsObjectsWithError(ref CullingResults cullResults, Camera camera, FilteringSettings filterSettings, SortingCriteria sortFlags, ref RendererListParams param)
- {
- SortingSettings sortingSettings = new SortingSettings(camera) { criteria = sortFlags };
- DrawingSettings errorSettings = new DrawingSettings(m_LegacyShaderPassNames[0], sortingSettings)
- {
- perObjectData = PerObjectData.None,
- overrideMaterial = errorMaterial,
- overrideMaterialPassIndex = 0
- };
- for (int i = 1; i < m_LegacyShaderPassNames.Count; ++i)
- errorSettings.SetShaderPassName(i, m_LegacyShaderPassNames[i]);
-
- param = new RendererListParams(cullResults, errorSettings, filterSettings);
- }
-
- [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
- internal static void CreateRendererListObjectsWithError(ScriptableRenderContext context, ref CullingResults cullResults, Camera camera, FilteringSettings filterSettings, SortingCriteria sortFlags, ref RendererList rl)
- {
- // TODO: When importing project, AssetPreviewUpdater::CreatePreviewForAsset will be called multiple times.
- // This might be in a point that some resources required for the pipeline are not finished importing yet.
- // Proper fix is to add a fence on asset import.
- if (errorMaterial == null)
- {
- rl = RendererList.nullRendererList;
- return;
- }
-
- RendererListParams param = new RendererListParams();
- CreateRendererParamsObjectsWithError(ref cullResults, camera, filterSettings, sortFlags, ref param);
- rl = context.CreateRendererList(ref param);
- }
-
- // This is used to render materials that contain built-in shader passes not compatible with URP.
- // It will render those legacy passes with error/pink shader.
- [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
- internal static void CreateRendererListObjectsWithError(RenderGraph renderGraph, ref CullingResults cullResults, Camera camera, FilteringSettings filterSettings, SortingCriteria sortFlags, ref RendererListHandle rl)
- {
- // TODO: When importing project, AssetPreviewUpdater::CreatePreviewForAsset will be called multiple times.
- // This might be in a point that some resources required for the pipeline are not finished importing yet.
- // Proper fix is to add a fence on asset import.
- if (errorMaterial == null)
- {
- rl = new RendererListHandle();
- return;
- }
-
- RendererListParams param = new RendererListParams();
- CreateRendererParamsObjectsWithError(ref cullResults, camera, filterSettings, sortFlags, ref param);
- rl = renderGraph.CreateRendererList(param);
- }
-
- [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
- internal static void DrawRendererListObjectsWithError(RasterCommandBuffer cmd, ref RendererList rl)
- {
- cmd.DrawRendererList(rl);
- }
-
- // Create a RendererList using a RenderStateBlock override is quite common so we have this optimized utility function for it
- internal static void CreateRendererListWithRenderStateBlock(ScriptableRenderContext context, ref CullingResults cullResults, DrawingSettings ds, FilteringSettings fs, RenderStateBlock rsb, ref RendererList rl)
- {
- RendererListParams param = new RendererListParams();
- unsafe
- {
- // Taking references to stack variables in the current function does not require any pinning (as long as you stay within the scope)
- // so we can safely alias it as a native array
- RenderStateBlock* rsbPtr = &rsb;
- var stateBlocks = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<RenderStateBlock>(rsbPtr, 1, Allocator.None);
-
- var shaderTag = ShaderTagId.none;
- var tagValues = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<ShaderTagId>(&shaderTag, 1, Allocator.None);
-
- // Inside CreateRendererList (below), we pass the NativeArrays to C++ by calling GetUnsafeReadOnlyPtr
- // This will check read access but NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray does not set up the SafetyHandle (by design) so create/add it here
- // NOTE: we explicitly share the handle
- #if ENABLE_UNITY_COLLECTIONS_CHECKS
- var safetyHandle = AtomicSafetyHandle.Create();
- AtomicSafetyHandle.SetAllowReadOrWriteAccess(safetyHandle, true);
-
- NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref stateBlocks, safetyHandle);
- NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref tagValues, safetyHandle);
- #endif
-
- // Create & schedule the RL
- param = new RendererListParams(cullResults, ds, fs)
- {
- tagValues = tagValues,
- stateBlocks = stateBlocks
-
- };
-
- rl = context.CreateRendererList(ref param);
-
- // we need to explicitly release the SafetyHandle
- #if ENABLE_UNITY_COLLECTIONS_CHECKS
- AtomicSafetyHandle.Release(safetyHandle);
- #endif
- }
- }
-
- static ShaderTagId[] s_ShaderTagValues = new ShaderTagId[1];
- static RenderStateBlock[] s_RenderStateBlocks = new RenderStateBlock[1];
- // Create a RendererList using a RenderStateBlock override is quite common so we have this optimized utility function for it
- internal static void CreateRendererListWithRenderStateBlock(RenderGraph renderGraph, ref CullingResults cullResults, DrawingSettings ds, FilteringSettings fs, RenderStateBlock rsb, ref RendererListHandle rl)
- {
- s_ShaderTagValues[0] = ShaderTagId.none;
- s_RenderStateBlocks[0] = rsb;
- NativeArray<ShaderTagId> tagValues = new NativeArray<ShaderTagId>(s_ShaderTagValues, Allocator.Temp);
- NativeArray<RenderStateBlock> stateBlocks = new NativeArray<RenderStateBlock>(s_RenderStateBlocks, Allocator.Temp);
- var param = new RendererListParams(cullResults, ds, fs)
- {
- tagValues = tagValues,
- stateBlocks = stateBlocks,
- isPassTagName = false
- };
- rl = renderGraph.CreateRendererList(param);
- }
-
- // Caches render texture format support. SystemInfo.SupportsRenderTextureFormat allocates memory due to boxing.
- static Dictionary<RenderTextureFormat, bool> m_RenderTextureFormatSupport = new Dictionary<RenderTextureFormat, bool>();
-
- internal static void ClearSystemInfoCache()
- {
- m_RenderTextureFormatSupport.Clear();
- }
-
- /// <summary>
- /// Checks if a render texture format is supported by the run-time system.
- /// Similar to <see cref="SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat)"/>, but doesn't allocate memory.
- /// </summary>
- /// <param name="format">The format to look up.</param>
- /// <returns>Returns true if the graphics card supports the given <c>RenderTextureFormat</c></returns>
- public static bool SupportsRenderTextureFormat(RenderTextureFormat format)
- {
- if (!m_RenderTextureFormatSupport.TryGetValue(format, out var support))
- {
- support = SystemInfo.SupportsRenderTextureFormat(format);
- m_RenderTextureFormatSupport.Add(format, support);
- }
-
- return support;
- }
-
- /// <summary>
- /// Obsolete. Use <see cref="SystemInfo.IsFormatSupported"/> instead.
- /// </summary>
- /// <param name="format">The format to look up.</param>
- /// <param name="usage">The format usage to look up.</param>
- /// <returns>Returns true if the graphics card supports the given <c>GraphicsFormat</c></returns>
- [Obsolete("Use SystemInfo.IsFormatSupported instead.", false)]
- public static bool SupportsGraphicsFormat(GraphicsFormat format, FormatUsage usage)
- {
- GraphicsFormatUsage graphicsFormatUsage = (GraphicsFormatUsage)(1 << (int)usage);
- return SystemInfo.IsFormatSupported(format, graphicsFormatUsage);
- }
-
- /// <summary>
- /// Return the last colorBuffer index actually referring to an existing RenderTarget
- /// </summary>
- /// <param name="colorBuffers"></param>
- /// <returns></returns>
- internal static int GetLastValidColorBufferIndex(RenderTargetIdentifier[] colorBuffers)
- {
- int i = colorBuffers.Length - 1;
- for (; i >= 0; --i)
- {
- if (colorBuffers[i] != 0)
- break;
- }
- return i;
- }
-
- /// <summary>
- /// Return the number of items in colorBuffers actually referring to an existing RenderTarget
- /// </summary>
- /// <param name="colorBuffers"></param>
- /// <returns></returns>
- internal static uint GetValidColorBufferCount(RTHandle[] colorBuffers)
- {
- uint nonNullColorBuffers = 0;
- if (colorBuffers != null)
- {
- foreach (var identifier in colorBuffers)
- {
- if (identifier != null && identifier.nameID != 0)
- ++nonNullColorBuffers;
- }
- }
- return nonNullColorBuffers;
- }
-
- /// <summary>
- /// Return true if colorBuffers is an actual MRT setup
- /// </summary>
- /// <param name="colorBuffers"></param>
- /// <returns></returns>
- internal static bool IsMRT(RTHandle[] colorBuffers)
- {
- return GetValidColorBufferCount(colorBuffers) > 1;
- }
-
- /// <summary>
- /// Return true if value can be found in source (without recurring to Linq)
- /// </summary>
- /// <param name="source"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- internal static bool Contains(RenderTargetIdentifier[] source, RenderTargetIdentifier value)
- {
- foreach (var identifier in source)
- {
- if (identifier == value)
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// Return the index where value was found source. Otherwise, return -1. (without recurring to Linq)
- /// </summary>
- /// <param name="source"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- internal static int IndexOf(RTHandle[] source, RenderTargetIdentifier value)
- {
- for (int i = 0; i < source.Length; ++i)
- {
- if (source[i] == value)
- return i;
- }
- return -1;
- }
-
- /// <summary>
- /// Return the index where value was found source. Otherwise, return -1. (without recurring to Linq)
- /// </summary>
- /// <param name="source"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- internal static int IndexOf(RTHandle[] source, RTHandle value) => IndexOf(source, value.nameID);
-
- /// <summary>
- /// Return the number of RenderTargetIdentifiers in "source" that are valid (not 0) and different from "value" (without recurring to Linq)
- /// </summary>
- /// <param name="source"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- internal static uint CountDistinct(RTHandle[] source, RTHandle value)
- {
- uint count = 0;
- for (int i = 0; i < source.Length; ++i)
- {
- if (source[i] != null && source[i].nameID != 0 && source[i].nameID != value.nameID)
- ++count;
- }
- return count;
- }
-
- /// <summary>
- /// Return the index of last valid (i.e different from 0) RenderTargetIdentifiers in "source" (without recurring to Linq)
- /// </summary>
- /// <param name="source"></param>
- /// <returns></returns>
- internal static int LastValid(RTHandle[] source)
- {
- for (int i = source.Length - 1; i >= 0; --i)
- {
- if (source[i] != null && source[i].nameID != 0)
- return i;
- }
- return -1;
- }
-
- /// <summary>
- /// Return true if ClearFlag a contains ClearFlag b
- /// </summary>
- /// <param name="a"></param>
- /// <param name="b"></param>
- /// <returns></returns>
- internal static bool Contains(ClearFlag a, ClearFlag b)
- {
- return (a & b) == b;
- }
-
- /// <summary>
- /// Return true if "left" and "right" are the same (without recurring to Linq)
- /// </summary>
- /// <param name="left"></param>
- /// <param name="right"></param>
- /// <returns></returns>
- internal static bool SequenceEqual(RTHandle[] left, RTHandle[] right)
- {
- if (left.Length != right.Length)
- return false;
-
- for (int i = 0; i < left.Length; ++i)
- if (left[i].nameID != right[i].nameID)
- return false;
-
- return true;
- }
-
- internal static bool MultisampleDepthResolveSupported()
- {
- // Temporarily disabling depth resolve a driver bug on OSX when using some AMD graphics cards. Temporarily disabling depth resolve on that platform
- // TODO: re-enable once the issue is investigated/fixed
- if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer)
- return false;
-
- // Should we also check if the format has stencil and check stencil resolve capability only in that case?
- return SystemInfo.supportsMultisampleResolveDepth && SystemInfo.supportsMultisampleResolveStencil;
- }
-
- /// <summary>
- /// Return true if handle does not match descriptor
- /// </summary>
- /// <param name="handle">RTHandle to check (can be null)</param>
- /// <param name="descriptor">Descriptor for the RTHandle to match</param>
- /// <param name="filterMode">Filtering mode of the RTHandle.</param>
- /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
- /// <param name="anisoLevel">Anisotropic filtering level.</param>
- /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
- /// <param name="name">Name of the RTHandle.</param>
- /// <param name="scaled">Check if the RTHandle has auto scaling enabled if not, check the widths and heights</param>
- /// <returns></returns>
- internal static bool RTHandleNeedsReAlloc(
- RTHandle handle,
- in TextureDesc descriptor,
- bool scaled)
- {
- if (handle == null || handle.rt == null)
- return true;
- if (handle.useScaling != scaled)
- return true;
- if (!scaled && (handle.rt.width != descriptor.width || handle.rt.height != descriptor.height))
- return true;
- return
- (DepthBits)handle.rt.descriptor.depthBufferBits != descriptor.depthBufferBits ||
- (handle.rt.descriptor.depthBufferBits == (int)DepthBits.None && handle.rt.descriptor.graphicsFormat != descriptor.colorFormat) ||
- handle.rt.descriptor.dimension != descriptor.dimension ||
- handle.rt.descriptor.enableRandomWrite != descriptor.enableRandomWrite ||
- handle.rt.descriptor.useMipMap != descriptor.useMipMap ||
- handle.rt.descriptor.autoGenerateMips != descriptor.autoGenerateMips ||
- (MSAASamples)handle.rt.descriptor.msaaSamples != descriptor.msaaSamples ||
- handle.rt.descriptor.bindMS != descriptor.bindTextureMS ||
- handle.rt.descriptor.useDynamicScale != descriptor.useDynamicScale ||
- handle.rt.descriptor.memoryless != descriptor.memoryless ||
- handle.rt.filterMode != descriptor.filterMode ||
- handle.rt.wrapMode != descriptor.wrapMode ||
- handle.rt.anisoLevel != descriptor.anisoLevel ||
- handle.rt.mipMapBias != descriptor.mipMapBias ||
- handle.name != descriptor.name;
- }
-
- /// <summary>
- /// Returns the RenderTargetIdentifier of the current camera target.
- /// </summary>
- /// <param name="renderingData"></param>
- /// <returns></returns>
- internal static RenderTargetIdentifier GetCameraTargetIdentifier(ref RenderingData renderingData)
- {
- // Note: We need to get the cameraData.targetTexture as this will get the targetTexture of the camera stack.
- // Overlay cameras need to output to the target described in the base camera while doing camera stack.
- ref CameraData cameraData = ref renderingData.cameraData;
-
- RenderTargetIdentifier cameraTarget = (cameraData.targetTexture != null) ? new RenderTargetIdentifier(cameraData.targetTexture) : BuiltinRenderTextureType.CameraTarget;
- #if ENABLE_VR && ENABLE_XR_MODULE
- if (cameraData.xr.enabled)
- {
- if (cameraData.xr.singlePassEnabled)
- {
- cameraTarget = cameraData.xr.renderTarget;
- }
- else
- {
- int depthSlice = cameraData.xr.GetTextureArraySlice();
- cameraTarget = new RenderTargetIdentifier(cameraData.xr.renderTarget, 0, CubemapFace.Unknown, depthSlice);
- }
- }
- #endif
-
- return cameraTarget;
- }
-
- /// <summary>
- /// Re-allocate fixed-size RTHandle if it is not allocated or doesn't match the descriptor
- /// </summary>
- /// <param name="handle">RTHandle to check (can be null)</param>
- /// <param name="descriptor">Descriptor for the RTHandle to match</param>
- /// <param name="filterMode">Filtering mode of the RTHandle.</param>
- /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
- /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param>
- /// <param name="anisoLevel">Anisotropic filtering level.</param>
- /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
- /// <param name="name">Name of the RTHandle.</param>
- /// <returns>If an allocation was done.</returns>
- [Obsolete("This method will be removed in a future release. Please use ReAllocateHandleIfNeeded instead. #from(2023.3)")]
- public static bool ReAllocateIfNeeded(
- ref RTHandle handle,
- in RenderTextureDescriptor descriptor,
- FilterMode filterMode = FilterMode.Point,
- TextureWrapMode wrapMode = TextureWrapMode.Repeat,
- bool isShadowMap = false,
- int anisoLevel = 1,
- float mipMapBias = 0,
- string name = "")
- {
- TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Explicit, anisoLevel, 0, filterMode, wrapMode, name);
- if (RTHandleNeedsReAlloc(handle, requestRTDesc, false))
- {
- if (handle != null && handle.rt != null)
- {
- TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Explicit, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode, handle.name);
- AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
- }
-
- if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
- {
- return true;
- }
- else
- {
- handle = RTHandles.Alloc(descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name);
- return true;
- }
- }
- return false;
- }
-
- /// <summary>
- /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor
- /// </summary>
- /// <param name="handle">RTHandle to check (can be null)</param>
- /// <param name="scaleFactor">Constant scale for the RTHandle size computation.</param>
- /// <param name="descriptor">Descriptor for the RTHandle to match</param>
- /// <param name="filterMode">Filtering mode of the RTHandle.</param>
- /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
- /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param>
- /// <param name="anisoLevel">Anisotropic filtering level.</param>
- /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
- /// <param name="name">Name of the RTHandle.</param>
- /// <returns>If the RTHandle should be re-allocated</returns>
- [Obsolete("This method will be removed in a future release. Please use ReAllocateHandleIfNeeded instead. #from(2023.3)")]
- public static bool ReAllocateIfNeeded(
- ref RTHandle handle,
- Vector2 scaleFactor,
- in RenderTextureDescriptor descriptor,
- FilterMode filterMode = FilterMode.Point,
- TextureWrapMode wrapMode = TextureWrapMode.Repeat,
- bool isShadowMap = false,
- int anisoLevel = 1,
- float mipMapBias = 0,
- string name = "")
- {
- var usingConstantScale = handle != null && handle.useScaling && handle.scaleFactor == scaleFactor;
- TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Scale, anisoLevel, 0, filterMode, wrapMode);
- if (!usingConstantScale || RTHandleNeedsReAlloc(handle, requestRTDesc, true))
- {
- if (handle != null && handle.rt != null)
- {
- TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Scale, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode);
- AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
- }
-
- if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
- {
- return true;
- }
- else
- {
- handle = RTHandles.Alloc(scaleFactor, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name);
- return true;
- }
- }
- return false;
- }
-
- /// <summary>
- /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor
- /// </summary>
- /// <param name="handle">RTHandle to check (can be null)</param>
- /// <param name="scaleFunc">Function used for the RTHandle size computation.</param>
- /// <param name="descriptor">Descriptor for the RTHandle to match</param>
- /// <param name="filterMode">Filtering mode of the RTHandle.</param>
- /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
- /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param>
- /// <param name="anisoLevel">Anisotropic filtering level.</param>
- /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
- /// <param name="name">Name of the RTHandle.</param>
- /// <returns>If an allocation was done</returns>
- [Obsolete("This method will be removed in a future release. Please use ReAllocateHandleIfNeeded instead. #from(2023.3)")]
- public static bool ReAllocateIfNeeded(
- ref RTHandle handle,
- ScaleFunc scaleFunc,
- in RenderTextureDescriptor descriptor,
- FilterMode filterMode = FilterMode.Point,
- TextureWrapMode wrapMode = TextureWrapMode.Repeat,
- bool isShadowMap = false,
- int anisoLevel = 1,
- float mipMapBias = 0,
- string name = "")
- {
- var usingScaleFunction = handle != null && handle.useScaling && handle.scaleFactor == Vector2.zero;
- TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Functor, anisoLevel, 0, filterMode, wrapMode);
- if (!usingScaleFunction || RTHandleNeedsReAlloc(handle, requestRTDesc, true))
- {
- if (handle != null && handle.rt != null)
- {
- TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Functor, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode);
- AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
- }
-
- if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
- {
- return true;
- }
- else
- {
- handle = RTHandles.Alloc(scaleFunc, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name);
- return true;
- }
- }
- return false;
- }
-
- /// <summary>
- /// Re-allocate fixed-size RTHandle if it is not allocated or doesn't match the descriptor
- /// </summary>
- /// <param name="handle">RTHandle to check (can be null)</param>
- /// <param name="descriptor">Descriptor for the RTHandle to match</param>
- /// <param name="filterMode">Filtering mode of the RTHandle.</param>
- /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
- /// <param name="anisoLevel">Anisotropic filtering level.</param>
- /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
- /// <param name="name">Name of the RTHandle.</param>
- /// <returns>If an allocation was done.</returns>
- public static bool ReAllocateHandleIfNeeded(
- ref RTHandle handle,
- in RenderTextureDescriptor descriptor,
- FilterMode filterMode = FilterMode.Point,
- TextureWrapMode wrapMode = TextureWrapMode.Repeat,
- int anisoLevel = 1,
- float mipMapBias = 0,
- string name = "")
- {
- TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Explicit, anisoLevel, 0, filterMode, wrapMode, name);
- if (RTHandleNeedsReAlloc(handle, requestRTDesc, false))
- {
- if (handle != null && handle.rt != null)
- {
- TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Explicit, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode, handle.name);
- AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
- }
-
- if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
- {
- return true;
- }
-
- var actualFormat = descriptor.graphicsFormat != GraphicsFormat.None ? descriptor.graphicsFormat : descriptor.depthStencilFormat;
-
- RTHandleAllocInfo allocInfo = new RTHandleAllocInfo();
- allocInfo.slices = descriptor.volumeDepth;
- allocInfo.format = actualFormat;
- allocInfo.filterMode = filterMode;
- allocInfo.wrapModeU = wrapMode;
- allocInfo.wrapModeV = wrapMode;
- allocInfo.wrapModeW = wrapMode;
- allocInfo.dimension = descriptor.dimension;
- allocInfo.enableRandomWrite = descriptor.enableRandomWrite;
- allocInfo.useMipMap = descriptor.useMipMap;
- allocInfo.autoGenerateMips = descriptor.autoGenerateMips;
- allocInfo.anisoLevel = anisoLevel;
- allocInfo.mipMapBias = mipMapBias;
- allocInfo.msaaSamples = (MSAASamples)descriptor.msaaSamples;
- allocInfo.bindTextureMS = descriptor.bindMS;
- allocInfo.useDynamicScale = descriptor.useDynamicScale;
- allocInfo.memoryless = descriptor.memoryless;
- allocInfo.vrUsage = descriptor.vrUsage;
- allocInfo.name = name;
-
- handle = RTHandles.Alloc(descriptor.width, descriptor.height, allocInfo);
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor
- /// </summary>
- /// <param name="handle">RTHandle to check (can be null)</param>
- /// <param name="scaleFactor">Constant scale for the RTHandle size computation.</param>
- /// <param name="descriptor">Descriptor for the RTHandle to match</param>
- /// <param name="filterMode">Filtering mode of the RTHandle.</param>
- /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
- /// <param name="anisoLevel">Anisotropic filtering level.</param>
- /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
- /// <param name="name">Name of the RTHandle.</param>
- /// <returns>If an allocation was done.</returns>
- public static bool ReAllocateHandleIfNeeded(
- ref RTHandle handle,
- Vector2 scaleFactor,
- in RenderTextureDescriptor descriptor,
- FilterMode filterMode = FilterMode.Point,
- TextureWrapMode wrapMode = TextureWrapMode.Repeat,
- int anisoLevel = 1,
- float mipMapBias = 0,
- string name = "")
- {
- var usingConstantScale = handle != null && handle.useScaling && handle.scaleFactor == scaleFactor;
- TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Scale, anisoLevel, 0, filterMode, wrapMode);
- if (!usingConstantScale || RTHandleNeedsReAlloc(handle, requestRTDesc, true))
- {
- if (handle != null && handle.rt != null)
- {
- TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Scale, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode);
- AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
- }
-
- if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
- {
- return true;
- }
-
- var actualFormat = descriptor.graphicsFormat != GraphicsFormat.None ? descriptor.graphicsFormat : descriptor.depthStencilFormat;
-
- RTHandleAllocInfo allocInfo = new RTHandleAllocInfo();
- allocInfo.slices = descriptor.volumeDepth;
- allocInfo.format = actualFormat;
- allocInfo.filterMode = filterMode;
- allocInfo.wrapModeU = wrapMode;
- allocInfo.wrapModeV = wrapMode;
- allocInfo.wrapModeW = wrapMode;
- allocInfo.dimension = descriptor.dimension;
- allocInfo.enableRandomWrite = descriptor.enableRandomWrite;
- allocInfo.useMipMap = descriptor.useMipMap;
- allocInfo.autoGenerateMips = descriptor.autoGenerateMips;
- allocInfo.anisoLevel = anisoLevel;
- allocInfo.mipMapBias = mipMapBias;
- allocInfo.msaaSamples = (MSAASamples)descriptor.msaaSamples;
- allocInfo.bindTextureMS = descriptor.bindMS;
- allocInfo.useDynamicScale = descriptor.useDynamicScale;
- allocInfo.memoryless = descriptor.memoryless;
- allocInfo.vrUsage = descriptor.vrUsage;
- allocInfo.name = name;
-
- handle = RTHandles.Alloc(scaleFactor, allocInfo);
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor
- /// </summary>
- /// <param name="handle">RTHandle to check (can be null)</param>
- /// <param name="scaleFunc">Function used for the RTHandle size computation.</param>
- /// <param name="descriptor">Descriptor for the RTHandle to match</param>
- /// <param name="filterMode">Filtering mode of the RTHandle.</param>
- /// <param name="wrapMode">Addressing mode of the RTHandle.</param>
- /// <param name="anisoLevel">Anisotropic filtering level.</param>
- /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param>
- /// <param name="name">Name of the RTHandle.</param>
- /// <returns>If an allocation was done.</returns>
- public static bool ReAllocateHandleIfNeeded(
- ref RTHandle handle,
- ScaleFunc scaleFunc,
- in RenderTextureDescriptor descriptor,
- FilterMode filterMode = FilterMode.Point,
- TextureWrapMode wrapMode = TextureWrapMode.Repeat,
- int anisoLevel = 1,
- float mipMapBias = 0,
- string name = "")
- {
- var usingScaleFunction = handle != null && handle.useScaling && handle.scaleFactor == Vector2.zero;
- TextureDesc requestRTDesc = RTHandleResourcePool.CreateTextureDesc(descriptor, TextureSizeMode.Functor, anisoLevel, 0, filterMode, wrapMode);
- if (!usingScaleFunction || RTHandleNeedsReAlloc(handle, requestRTDesc, true))
- {
- if (handle != null && handle.rt != null)
- {
- TextureDesc currentRTDesc = RTHandleResourcePool.CreateTextureDesc(handle.rt.descriptor, TextureSizeMode.Functor, handle.rt.anisoLevel, handle.rt.mipMapBias, handle.rt.filterMode, handle.rt.wrapMode);
- AddStaleResourceToPoolOrRelease(currentRTDesc, handle);
- }
-
- if (UniversalRenderPipeline.s_RTHandlePool.TryGetResource(requestRTDesc, out handle))
- {
- return true;
- }
-
- var actualFormat = descriptor.graphicsFormat != GraphicsFormat.None ? descriptor.graphicsFormat : descriptor.depthStencilFormat;
-
- RTHandleAllocInfo allocInfo = new RTHandleAllocInfo();
- allocInfo.slices = descriptor.volumeDepth;
- allocInfo.format = actualFormat;
- allocInfo.filterMode = filterMode;
- allocInfo.wrapModeU = wrapMode;
- allocInfo.wrapModeV = wrapMode;
- allocInfo.wrapModeW = wrapMode;
- allocInfo.dimension = descriptor.dimension;
- allocInfo.enableRandomWrite = descriptor.enableRandomWrite;
- allocInfo.useMipMap = descriptor.useMipMap;
- allocInfo.autoGenerateMips = descriptor.autoGenerateMips;
- allocInfo.anisoLevel = anisoLevel;
- allocInfo.mipMapBias = mipMapBias;
- allocInfo.msaaSamples = (MSAASamples)descriptor.msaaSamples;
- allocInfo.bindTextureMS = descriptor.bindMS;
- allocInfo.useDynamicScale = descriptor.useDynamicScale;
- allocInfo.memoryless = descriptor.memoryless;
- allocInfo.vrUsage = descriptor.vrUsage;
- allocInfo.name = name;
-
- handle = RTHandles.Alloc(scaleFunc, allocInfo);
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// Resize the rthandle pool's max stale resource capacity. The default value is 32.
- /// Increasing the capacity may have a negative impact on the memory usage(dued to staled resources in pool).
- /// Increasing the capacity may improve runtime performance (by reducing the runtime RTHandle realloc count in multi view/multi camera setup).
- /// Setting capacity will purge the current pool. It is recommended to setup the capacity upfront and not changing it during the runtime.
- /// </summary>
- /// <param name="capacity">Max capacity to set</param>
- /// <returns> Return true if set successfully. Return false if URP is not initialized and pool does not exist yet. </returns>
- public static bool SetMaxRTHandlePoolCapacity(int capacity)
- {
- if (UniversalRenderPipeline.s_RTHandlePool == null)
- return false;
-
- UniversalRenderPipeline.s_RTHandlePool.staleResourceCapacity = capacity;
- return true;
- }
-
- /// <summary>
- /// Add stale rtHandle to pool so that it could be reused in the future.
- /// 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.
- /// </summary>
- internal static void AddStaleResourceToPoolOrRelease(TextureDesc desc, RTHandle handle)
- {
- if (!UniversalRenderPipeline.s_RTHandlePool.AddResourceToPool(desc, handle, Time.frameCount))
- RTHandles.Release(handle);
- }
-
- /// <summary>
- /// Creates <c>DrawingSettings</c> based on current the rendering state.
- /// </summary>
- /// <param name="shaderTagId">Shader pass tag to render.</param>
- /// <param name="renderingData">Current rendering state.</param>
- /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
- /// <returns></returns>
- /// <seealso cref="DrawingSettings"/>
- static public DrawingSettings CreateDrawingSettings(ShaderTagId shaderTagId, ref RenderingData renderingData, SortingCriteria sortingCriteria)
- {
- UniversalRenderingData universalRenderingData = renderingData.frameData.Get<UniversalRenderingData>();
- UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
- UniversalLightData lightData = renderingData.frameData.Get<UniversalLightData>();
-
- return CreateDrawingSettings(shaderTagId, universalRenderingData, cameraData, lightData, sortingCriteria);
- }
-
- /// <summary>
- /// Creates <c>DrawingSettings</c> based on current the rendering state.
- /// </summary>
- /// <param name="shaderTagId">Shader pass tag to render.</param>
- /// <param name="renderingData">Current rendering state.</param>
- /// <param name="cameraData">Current camera state.</param>
- /// <param name="lightData">Current light state.</param>
- /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
- /// <returns></returns>
- /// <seealso cref="DrawingSettings"/>
- static public DrawingSettings CreateDrawingSettings(ShaderTagId shaderTagId, UniversalRenderingData renderingData,
- UniversalCameraData cameraData, UniversalLightData lightData, SortingCriteria sortingCriteria)
- {
- Camera camera = cameraData.camera;
- SortingSettings sortingSettings = new SortingSettings(camera) { criteria = sortingCriteria };
- DrawingSettings settings = new DrawingSettings(shaderTagId, sortingSettings)
- {
- perObjectData = renderingData.perObjectData,
- mainLightIndex = lightData.mainLightIndex,
- enableDynamicBatching = renderingData.supportsDynamicBatching,
-
- // Disable instancing for preview cameras. This is consistent with the built-in forward renderer. Also fixes case 1127324.
- enableInstancing = camera.cameraType == CameraType.Preview ? false : true,
- };
- return settings;
- }
-
- /// <summary>
- /// Creates <c>DrawingSettings</c> based on current rendering state.
- /// </summary>
- /// <param name="shaderTagIdList">List of shader pass tag to render.</param>
- /// <param name="renderingData">Current rendering state.</param>
- /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
- /// <returns></returns>
- /// <seealso cref="DrawingSettings"/>
- static public DrawingSettings CreateDrawingSettings(List<ShaderTagId> shaderTagIdList,
- ref RenderingData renderingData, SortingCriteria sortingCriteria)
- {
- UniversalRenderingData universalRenderingData = renderingData.frameData.Get<UniversalRenderingData>();
- UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
- UniversalLightData lightData = renderingData.frameData.Get<UniversalLightData>();
- return CreateDrawingSettings(shaderTagIdList, universalRenderingData, cameraData, lightData, sortingCriteria);
- }
-
- /// <summary>
- /// Creates <c>DrawingSettings</c> based on current rendering state.
- /// </summary>
- /// <param name="shaderTagIdList">List of shader pass tag to render.</param>
- /// <param name="renderingData">Current rendering state.</param>
- /// <param name="cameraData">Current camera state.</param>
- /// <param name="lightData">Current light state.</param>
- /// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
- /// <returns></returns>
- /// <seealso cref="DrawingSettings"/>
- static public DrawingSettings CreateDrawingSettings(List<ShaderTagId> shaderTagIdList,
- UniversalRenderingData renderingData, UniversalCameraData cameraData,
- UniversalLightData lightData, SortingCriteria sortingCriteria)
- {
- if (shaderTagIdList == null || shaderTagIdList.Count == 0)
- {
- Debug.LogWarning("ShaderTagId list is invalid. DrawingSettings is created with default pipeline ShaderTagId");
- return CreateDrawingSettings(new ShaderTagId("UniversalPipeline"), renderingData, cameraData, lightData, sortingCriteria);
- }
-
- DrawingSettings settings = CreateDrawingSettings(shaderTagIdList[0], renderingData, cameraData, lightData, sortingCriteria);
- for (int i = 1; i < shaderTagIdList.Count; ++i)
- settings.SetShaderPassName(i, shaderTagIdList[i]);
- return settings;
- }
-
- /// <summary>
- /// Returns the scale bias vector to use for final blits to the backbuffer, based on scaling mode and y-flip platform requirements.
- /// </summary>
- /// <param name="source"></param>
- /// <param name="destination"></param>
- /// <param name="cameraData"></param>
- /// <returns></returns>
- internal static Vector4 GetFinalBlitScaleBias(RTHandle source, RTHandle destination, UniversalCameraData cameraData)
- {
- Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
- var yflip = cameraData.IsRenderTargetProjectionMatrixFlipped(destination);
- Vector4 scaleBias = !yflip ? new Vector4(viewportScale.x, -viewportScale.y, 0, viewportScale.y) : new Vector4(viewportScale.x, viewportScale.y, 0, 0);
-
- return scaleBias;
- }
- }
- }
|