Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Framebuffer Fetch not working on Vulkan?

Discussion in 'Shaders' started by lordzargon, Jan 11, 2024.

  1. lordzargon

    lordzargon

    Joined:
    Nov 8, 2013
    Posts:
    8
    Hi,

    I've got a simple shader together that works with Framebuffer Fetch on openGL just fine. However, when I switch to Vulkan, Framebuffer Fetch is no longer working.

    I suspect this is because Vulkan's implementation is different (i.e. its part of Vulkan subpasses) - but I am not clear on this.

    Additionally, as far as I can find out through searches, Vulkan subpasses do not work on mobile XR devices using the URP (Quest 2+ is the target platform). I can't find concrete evidence, but I'm not familiar with how to write custom passes & subpasses enough to test myself.

    Can anyone shed any more light on this or offer any help in either getting Framebuffer Fetch working on Vulkan in some form, or point me in a direction?


    Here is the shader:

    Code (CSharp):
    1. Shader "Unlit/OculusQuestFrameBufferFetch"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.         _Color ("Color", color) = (0.0,1.0,0.0)
    7.     }
    8.     SubShader
    9.     {
    10.         Tags { "RenderType"="Opaque" "Queue"="AlphaTest+10"}
    11.         LOD 100
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.            
    18.             #include "UnityCG.cginc"
    19.             struct appdata
    20.             {
    21.                 float4 vertex : POSITION;
    22.                 float2 uv : TEXCOORD0;
    23.             };
    24.             struct v2f
    25.             {
    26.                 float2 uv : TEXCOORD0;
    27.                 float4 vertex : SV_POSITION;
    28.             };
    29.             sampler2D _MainTex;
    30.             float4 _MainTex_ST;
    31.             half4 _Color;
    32.             v2f vert (appdata v)
    33.             {
    34.                 v2f o;
    35.                 o.vertex = UnityObjectToClipPos(v.vertex);
    36.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    37.                 return o;
    38.             }
    39.             void frag(v2f i, inout fixed4 ocol : SV_Target)
    40.             {
    41.                 // sample the texture
    42.                 fixed4 col = tex2D(_MainTex, i.uv);
    43.                 #ifdef UNITY_FRAMEBUFFER_FETCH_AVAILABLE
    44.                     fixed4 framebufferColor = ocol;
    45.                     ocol = frac(sin(_Time.x * 45)) * ocol + col * _Color;
    46.                 #else
    47.                     ocol = fixed4(1,0,0,1);
    48.                 #endif
    49.             }
    50.             ENDCG
    51.         }
    52.     }
    53. }
    Unity 2023.3.0a13, URP, tested on Meta Quest 3.
     
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,055
    Hi!
    There is currently no framebuffer fetch support enabled for Vulkan.
    It looks like the recommended way to go forward with this is to use the RenderPass API.
     
    lordzargon likes this.
  3. lordzargon

    lordzargon

    Joined:
    Nov 8, 2013
    Posts:
    8
    Thanks - the issue we have is that any additional render passes are prohibitively expensive. An additional pass is 1-2ms of slowdown from memory bandwidth limitations on Quest 2 - as we only have 13.8ms total frametime, that's up to 1/7th of our entire budget waiting on the system.

    The only options we really have on this platform is framebuffer fetch, which is OpenGL-based (which would remove other features only available in Vulkan), or to use Vulkan Subpasses.

    From this post, 11 months ago (Unity 2023.1.0a26, URP 15.0.3), Subpasses appear to not be working in Vulkan Multiview, as it only displays in the left eye:
    Why doesn't URP support using NativeRenderPass on the XR platform?

    I guess I answered my own question - I'm out of luck with this right now. There is a Meta fork of UE4 that uses Vulkan subpasses on XR for color correction, so the hardware definitely works with this.

    Any extra info you might have would be welcome!

    Thanks
     
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,055
    It may have been fixed since. If not, you can file a bug report :)
     
    lordzargon likes this.
  5. AljoshaD

    AljoshaD

    Unity Technologies

    Joined:
    May 27, 2019
    Posts:
    281
    They do. Our GDC talk on Rendering Customization and Performance in Unity 6 goes into detail about RenderGraph and how to benefit from pass merging, using framebuffer fetch, etc . You can find the recording freely available here.

    You can find more info in this thread as well.