Problem when upgrading Unity 2021 to 2022, URP for blit post process

I’m trying to upgrade to Unity 2022.

But my post process is broken if I use a RTHandle for a temporary render texure.

Here a working code with the obsolete API (RenderTargetHandle for a temporary render texture).

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class BlitMaterialFeature : ScriptableRendererFeature
{
    class RenderPass : ScriptableRenderPass
    {
        private string profilingName;
        private Material material;
        private int materialPassIndex;
        private RTHandle rtSource;
        private RTHandle rtTempTextureHandle;
        RenderTargetHandle tempTextureHandle;
        ProfilingSampler profilingSampler = new ProfilingSampler("Blit");

        public RenderPass(string profilingName, Material material, int passIndex) : base()
        {
            this.profilingName = profilingName;
            this.material = material;
            this.materialPassIndex = passIndex;
            //tempTextureHandle.Init("_TempBlitMaterialTexture");
            //RTHandles.Initialize(Screen.width, Screen.height);
            rtTempTextureHandle = RTHandles.Alloc("_TempBlitMaterialTexture2", name: "_TempBlitMaterialTexture2");
        }

        public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
        {
            ConfigureTarget(rtTempTextureHandle);
        }

        public void SetSource(RTHandle source)
        {
            rtSource = source;
        }

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            var cameraData = renderingData.cameraData;
            if (cameraData.camera.cameraType != CameraType.Game)
                return;

            CommandBuffer cmd = CommandBufferPool.Get(profilingName);

            RenderTextureDescriptor cameraTextureDesc = renderingData.cameraData.cameraTargetDescriptor;
            cameraTextureDesc.depthBufferBits = 0;

            //RenderingUtils.ReAllocateIfNeeded(ref rtTempTextureHandle, cameraTextureDesc, FilterMode.Bilinear);
            cmd.GetTemporaryRT(tempTextureHandle.id, cameraTextureDesc, FilterMode.Bilinear);
            //cmd.GetTemporaryRT(Shader.PropertyToID(rtTempTextureHandle.name), cameraTextureDesc, FilterMode.Bilinear);
            using (new ProfilingScope(cmd, profilingSampler))
            {
                //Blitter.BlitTexture(cmd, rtSource, rtTempTextureHandle, material, materialPassIndex);
                Blit(cmd, rtSource, /*rtTempTextureHandle*/tempTextureHandle.Identifier(), material, materialPassIndex);
                //Blitter.BlitCameraTexture(cmd, rtTempTextureHandle, rtSource);
                Blit(cmd, /*rtTempTextureHandle*/ tempTextureHandle.Identifier(), rtSource);
            }

            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
            CommandBufferPool.Release(cmd);
        }

        public void Dispose()
        {
            rtTempTextureHandle?.Release();
        }
    }

    [System.Serializable]
    public class Settings
    {
        public Material material;
        public int materialPassIndex = -1; // -1 means render all passes
        public RenderPassEvent renderEvent = RenderPassEvent.AfterRenderingOpaques;
    }

    [SerializeField]
    private Settings settings = new Settings();

    private RenderPass renderPass;

    public Material Material
    {
        get => settings.material;
    }

    public override void Create()
    {
        renderPass = new RenderPass(name, settings.material, settings.materialPassIndex);
        renderPass.renderPassEvent = settings.renderEvent;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        if (renderingData.cameraData.cameraType == CameraType.Game)
            renderer.EnqueuePass(renderPass); // letting the renderer know which passes will be used before allocation
    }

    public override void SetupRenderPasses(ScriptableRenderer renderer, in RenderingData renderingData)
    {
        if (renderingData.cameraData.cameraType == CameraType.Game)
        {
            // Calling ConfigureInput with the ScriptableRenderPassInput.Color argument
            // ensures that the opaque texture is available to the Render Pass.
            renderPass.ConfigureInput(ScriptableRenderPassInput.Color);
            renderPass.SetSource(renderer.cameraColorTargetHandle);  // use of target after allocation
        }
    }
}
RenderingUtils.ReAllocateIfNeeded(ref rtTempTextureHandle, cameraTextureDesc, FilterMode.Bilinear);

Always give me a black screen in the Frame debugger.

If I skip it I have null exception in the Blit method (rtTempTextureHandle is null).

I look at these threads but I’m still helpless:

https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@13.1/manual/upgrade-guide-2022-1.html

For example this version give me NullReferenceException

    //RenderingUtils.ReAllocateIfNeeded(ref rtTempTextureHandle, cameraTextureDesc, FilterMode.Bilinear);
            //cmd.GetTemporaryRT(tempTextureHandle.id, cameraTextureDesc, FilterMode.Bilinear);
            cmd.GetTemporaryRT(Shader.PropertyToID(rtTempTextureHandle.name), cameraTextureDesc, FilterMode.Bilinear);
            using (new ProfilingScope(cmd, profilingSampler))
            {
                //Blitter.BlitTexture(cmd, rtSource, rtTempTextureHandle, material, materialPassIndex);
                Blit(cmd, rtSource, rtTempTextureHandle/*tempTextureHandle.Identifier()*/, material, materialPassIndex);
                //Blitter.BlitCameraTexture(cmd, rtTempTextureHandle, rtSource);
                Blit(cmd, rtTempTextureHandle/* tempTextureHandle.Identifier()*/, rtSource);
            }
NullReferenceException: Object reference not set to an instance of an object
UnityEngine.Rendering.Universal.Internal.CopyDepthPass.ExecutePass (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.Internal.CopyDepthPass+PassData passData, UnityEngine.Rendering.CommandBuffer& cmd, UnityEngine.Rendering.Universal.CameraData& cameraData, UnityEngine.Rendering.RTHandle source, UnityEngine.Rendering.RTHandle destination) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/Passes/CopyDepthPass.cs:161)
UnityEngine.Rendering.Universal.Internal.CopyDepthPass.Execute (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/Passes/CopyDepthPass.cs:103)
UnityEngine.Rendering.Universal.ScriptableRenderer.ExecuteRenderPass (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.ScriptableRenderPass renderPass, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/ScriptableRenderer.cs:1446)
UnityEngine.Rendering.Universal.ScriptableRenderer.ExecuteBlock (System.Int32 blockIndex, UnityEngine.Rendering.Universal.ScriptableRenderer+RenderBlocks& renderBlocks, UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData, System.Boolean submit) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/ScriptableRenderer.cs:1402)
UnityEngine.Rendering.Universal.ScriptableRenderer.Execute (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/ScriptableRenderer.cs:1185)
UnityEngine.Rendering.Universal.UniversalRenderPipeline.RenderSingleCamera (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.CameraData& cameraData, System.Boolean anyPostProcessingEnabled) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/UniversalRenderPipeline.cs:642)
UnityEngine.Rendering.Universal.UniversalRenderPipeline.RenderSingleCameraInternal (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Camera camera) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/UniversalRenderPipeline.cs:527)
UnityEngine.Rendering.Universal.UniversalRenderPipeline.Render (UnityEngine.Rendering.ScriptableRenderContext renderContext, System.Collections.Generic.List`1[T] cameras) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/UniversalRenderPipeline.cs:369)
UnityEngine.Rendering.RenderPipeline.InternalRender (UnityEngine.Rendering.ScriptableRenderContext context, System.Collections.Generic.List`1[T] cameras) (at <0ae5

Hey
I had the exact same problem, and from the Frame Debugger, it seemed that the ReAllocateIfNeeded function was creating a RT with no color format.
So I got it working by simply creating a descriptor instead of using the camera one (maybe it is not initialized correctly?)

public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
    base.OnCameraSetup(cmd, ref renderingData);

    RenderTextureDescriptor descriptor = new RenderTextureDescriptor(128, 128, RenderTextureFormat.Default);
    RenderingUtils.ReAllocateIfNeeded(ref effectColorTarget, descriptor, name: "_Pixel_Buffer");
}

The GetTemporaryRT API seems to be “deprecated”, as in the new versions of URP expect you to use ReAllocateIfNeeded from what I could gather, this API is massively under-documented.
As I am trying to make a pixel effect, the fixed RT size is what I want, but you probably want to use the Screen size for yours.
Hope this helps!