// Crest Water System // Copyright © 2024 Wave Harmonic. All rights reserved. using UnityEngine; using UnityEngine.Rendering; namespace WaveHarmonic.Crest { static class RenderPipelineCompatibilityHelper { // Taken from: // https://github.com/Unity-Technologies/Graphics/blob/19ec161f3f752db865597374b3ad1b3eaf110097/Packages/com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs#L588-L634 /// /// Return true if handle does not match descriptor /// /// RTHandle to check (can be null) /// Descriptor for the RTHandle to match /// Filtering mode of the RTHandle. /// Addressing mode of the RTHandle. /// Set to true if the depth buffer should be used as a shadow map. /// Anisotropic filtering level. /// Bias applied to mipmaps during filtering. /// Name of the RTHandle. /// Check if the RTHandle has auto scaling enabled if not, check the widths and heights /// internal static bool RTHandleNeedsReAlloc( RTHandle handle, in RenderTextureDescriptor descriptor, FilterMode filterMode, TextureWrapMode wrapMode, bool isShadowMap, int anisoLevel, float mipMapBias, string name, 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 handle.rt.descriptor.depthBufferBits != descriptor.depthBufferBits || (handle.rt.descriptor.depthBufferBits == (int)DepthBits.None && !isShadowMap && handle.rt.descriptor.graphicsFormat != descriptor.graphicsFormat) || handle.rt.descriptor.dimension != descriptor.dimension || handle.rt.descriptor.enableRandomWrite != descriptor.enableRandomWrite || handle.rt.descriptor.useMipMap != descriptor.useMipMap || handle.rt.descriptor.autoGenerateMips != descriptor.autoGenerateMips || handle.rt.descriptor.msaaSamples != descriptor.msaaSamples || handle.rt.descriptor.bindMS != descriptor.bindMS || handle.rt.descriptor.useDynamicScale != descriptor.useDynamicScale || handle.rt.descriptor.memoryless != descriptor.memoryless || handle.rt.filterMode != filterMode || handle.rt.wrapMode != wrapMode || handle.rt.anisoLevel != anisoLevel || handle.rt.mipMapBias != mipMapBias || handle.name != name; } // https://github.com/Unity-Technologies/Graphics/blob/19ec161f3f752db865597374b3ad1b3eaf110097/Packages/com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs#L666-L695 /// /// Re-allocate fixed-size RTHandle if it is not allocated or doesn't match the descriptor /// /// RTHandle to check (can be null) /// Descriptor for the RTHandle to match /// Filtering mode of the RTHandle. /// Addressing mode of the RTHandle. /// Set to true if the depth buffer should be used as a shadow map. /// Anisotropic filtering level. /// Bias applied to mipmaps during filtering. /// Name of the RTHandle. /// 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 = "") { if (RTHandleNeedsReAlloc(handle, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name, false)) { handle?.Release(); handle = RTHandles.Alloc(descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name); return true; } return false; } // https://github.com/Unity-Technologies/Graphics/blob/19ec161f3f752db865597374b3ad1b3eaf110097/Packages/com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs#L697-L729 /// /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor /// /// RTHandle to check (can be null) /// Constant scale for the RTHandle size computation. /// Descriptor for the RTHandle to match /// Filtering mode of the RTHandle. /// Addressing mode of the RTHandle. /// Set to true if the depth buffer should be used as a shadow map. /// Anisotropic filtering level. /// Bias applied to mipmaps during filtering. /// Name of the RTHandle. /// If the RTHandle should be re-allocated 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; if (!usingConstantScale || RTHandleNeedsReAlloc(handle, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name, true)) { handle?.Release(); handle = RTHandles.Alloc(scaleFactor, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name); return true; } return false; } // https://github.com/Unity-Technologies/Graphics/blob/19ec161f3f752db865597374b3ad1b3eaf110097/Packages/com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs#L731-L764 /// /// Re-allocate dynamically resized RTHandle if it is not allocated or doesn't match the descriptor /// /// RTHandle to check (can be null) /// Function used for the RTHandle size computation. /// Descriptor for the RTHandle to match /// Filtering mode of the RTHandle. /// Addressing mode of the RTHandle. /// Set to true if the depth buffer should be used as a shadow map. /// Anisotropic filtering level. /// Bias applied to mipmaps during filtering. /// Name of the RTHandle. /// If an allocation was done 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; if (!usingScaleFunction || RTHandleNeedsReAlloc(handle, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name, true)) { handle?.Release(); handle = RTHandles.Alloc(scaleFunc, descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name); return true; } return false; } } }