Setting SV_RenderTargetArrayIndex on Metal does not work?

Hi there,

I have a rendering setup where many cameras each render to a different slice of a texture array simultaneously, so I only have to switch to the render target once instead of once per camera. This works by binding to all slices of the texture array:

_commandBuffer.SetRenderTarget(TextureArray, 0, CubemapFace.Unknown, -1);

and then setting which slice to output to in the vertex shader:

struct v2f
{
    float4 vertex : SV_POSITION;
    float4 eyeSpace : TEXCOORD0;
    uint slice : SV_RenderTargetArrayIndex;
};

This works fine on Windows and gives great performance improvements by not having to switch context in between draw calls. However, it appears that it does not work on iOS - all cameras appear to be writing to the first slice. Does anyone have any experience with this, am I missing something that’s specific to Metal?

I’d raise a bug for this :slight_smile:

It’s only supported Apple A12 GPUs and newer on iOS (on macOS it’s supported on all GPUs): https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf

That said, I don’t personally know whether it’s hooked up properly in Unity’s Metal backend or not.

On Windows / D3D11, it’s not supported on all systems when you use it from the vertex shader either: D3D11_FEATURE_DATA_D3D11_OPTIONS3 (d3d11.h) - Win32 apps | Microsoft Learn

Thanks for the responses! I’ve checked on a gen 3 iPad Pro which has the A12 chipset, but the problem persists. I have filed a bug report with a sample scene (1198097).

1 Like

To anyone running into this, the bug is now marked as resolved for 2020.1.0a18 and above.

Can anyone confirm this actually does work on Metal? I’m having the same issue in Unity 2022.1.23f1, where on an iPad my shader only draws to the first array element in a 2D RenderTexture array, despite using the SV_RenderTargetArrayIndex semantic, and despite setting depthSlice to -1 in Graphics.SetRenderTarget(). I can see in the compiled shader code that Unity has used “uint mtl_Layer [[ render_target_array_index ]]” and appears to be assigning to that variable correctly, so I assume that it is supposed to be supported in Unity, but I am having no luck finding any actual examples or proper documentation.