Every other frame is grey in TEXTURE2D_ARRAY

I am learning about Temporal Anitaliasing and want to store each frame, N, in a frame history buffer. I am implementing this in a Custom Pass script using Unity 6000.0.23f1, and DirectX12. And compiling my shader with #pragma use_dxc.

My buffer is a RTHandle with 8 slices, and I’m doing a color copy pass to a specific slice each frame. This color copy pass simply copies the blended result of the current frame, which is both displayed and stored.

The issue is that every other slice, index=[1, 3, 5, 7] is not correct, while the others index=[0, 2, 4, 6] are correct. I inspect my buffer in RenderDoc and this is what I see:

Screenshot in RenderDoc where slice 0 is correct:
https://i.imgur.com/zTUOgLB.png

Screenshot in RenderDoc where slice 1 is not correct:
https://i.imgur.com/SadMe30.png

Slices [1, 3, 5, 7] all look like slice 1.

What could possibly go wrong here?

Here is some of my code for the Custom Pass:

protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
{
    N = 0;

    volumeShader = Shader.Find("FullScreen/TemporalNanoVolumePass");
    mat = CoreUtils.CreateEngineMaterial(volumeShader);

    nextFrame = RTHandles.Alloc(
        Vector2.one, TextureXR.slices,
        colorFormat: GraphicsFormat.R16G16B16A16_SFloat, 
        dimension: TextureXR.dimension,
        name: "Next_Frame_Buffer"
    );

    frameHistory = RTHandles.Alloc(
        Vector2.one,
        slices: temporalFrames,
        colorFormat: GraphicsFormat.R16G16B16A16_SFloat, 
        dimension: TextureXR.dimension,
        name: "Frame_History_Buffer"
    );

    blendedFrame = RTHandles.Alloc(
        Vector2.one, TextureXR.slices, 
        colorFormat: GraphicsFormat.R16G16B16A16_SFloat, 
        dimension: TextureXR.dimension, 
        name: "Blended_Frame_Buffer"
    );
}

protected override void Execute(CustomPassContext ctx)
{
    if (!nanoVolumeLoaderComponent.IsLoaded())
    {
        return;
    }

    Vector4 scale = RTHandles.rtHandleProperties.rtHandleScale;

    SetUniforms();

    // Draw newest frame to a buffer
    CoreUtils.SetRenderTarget(ctx.cmd, nextFrame, ClearFlag.Color);
    CoreUtils.DrawFullScreen(ctx.cmd, mat, ctx.propertyBlock, shaderPassId: NANO_VOLUME_PASS_ID);

    // Combine new frame with old frames into another buffer
    ctx.propertyBlock.SetTexture("_NextFrame", nextFrame);
    ctx.propertyBlock.SetTexture("_FrameHistory", frameHistory);
    ctx.propertyBlock.SetInt("_FrameIndex", N);
    CoreUtils.SetRenderTarget(ctx.cmd, blendedFrame, ClearFlag.Color);
    CoreUtils.DrawFullScreen(ctx.cmd, mat, ctx.propertyBlock, shaderPassId: TEMPORAL_BLEND_PASS_ID);

    // Save blended frame to history at slice N
    ctx.propertyBlock.SetTexture("_BlendedFrame", blendedFrame);
    CoreUtils.SetRenderTarget(ctx.cmd, frameHistory, ClearFlag.Color, depthSlice: N);
    CoreUtils.DrawFullScreen(ctx.cmd, mat, ctx.propertyBlock, shaderPassId: COPY_COLOR_PASS_ID);

    // Display blended frame to camera
    ctx.cmd.Blit(blendedFrame, ctx.cameraColorBuffer, new Vector2(scale.x, scale.y), Vector2.zero, 0, 0);

    N = (N + 1) % temporalFrames;
}

And here is my Blend Pass which uses the frame history buffer (TAA not implemented yet obv):

TEXTURE2D_ARRAY(_FrameHistory);
TEXTURE2D_X(_NextFrame);
uniform int _TemporalFrames;
uniform int _FrameIndex;

float4 TemporalBlendPass(Varyings varyings) : SV_Target
{
    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
    float depth = LoadCameraDepth(varyings.positionCS.xy);
    PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);

    float2 scaling = _RTHandleScale.xy;
    float2 uv = posInput.positionNDC.xy * scaling;
    float4 nextFrame = SAMPLE_TEXTURE2D_X(_NextFrame, s_linear_clamp_sampler, uv);
    float4 lastFrame = SAMPLE_TEXTURE2D_ARRAY(_FrameHistory, s_linear_clamp_sampler, uv, (_FrameIndex - 1) % _TemporalFrames);

    // blend next and lastFrame
    float4 blendedFrame = lerp(lastFrame, nextFrame, 0.99);

    return blendedFrame;
}

I tried building a standalone version and opening that one in RenderDoc, and all slices are correct.

It seems there is something funky going on when running this in the Editor.

Also, while running in editor, when setting a Debug.Break() at frame 3, I’m not seeing the same pattern as before, where every other is a grey rectangle. Sometimes the slices are correct, but sometimes only one is wrong. Thus, I am no longer able to consistently reproduce this issue and have no idea what’s going on.

I think I know what the issue is. Holy crap …

I have two monitors, one is 144 hz and the other is 60 hz. I usually have my game window on the 60 hz monitor, which means every time I tested in the editor, it failed. Until I moved my game window to my 144 hz monitor, and the issues were gone. Tested this multiple times back and forth between my monitors and this seems to be causing the issue.

Nice