Search Unity

How to use memoryless?

Discussion in 'Shaders' started by AcidArrow, Aug 29, 2017.

  1. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,794
    Since having MSAA roughly doubles the ram usage of rendertextures, I thought I'd try using memoryless mode.

    The problem is, I probably don't know how to use it...

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class memoryless : MonoBehaviour
    4. {
    5.     RenderTextureDescriptor mainrtdesc;
    6.  
    7.     RenderTexture rt;
    8.  
    9.     void Awake()
    10.     {
    11.         mainrtdesc = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.Default, 24);
    12.         mainrtdesc.memoryless = RenderTextureMemoryless.MSAA;
    13.         mainrtdesc.useMipMap = false;
    14.         mainrtdesc.msaaSamples = 2;
    15.     }
    16.  
    17.     void OnPreRender()
    18.     {
    19.         rt = RenderTexture.GetTemporary(mainrtdesc);
    20.         GetComponent<Camera>().targetTexture = rt;
    21.     }  
    22.     void OnPostRender()
    23.     {
    24.         GetComponent<Camera>().targetTexture = null;
    25.         Graphics.Blit(rt, null as RenderTexture);
    26.         RenderTexture.ReleaseTemporary(rt);
    27.     }
    28. }
    But it doesn't seem to work. I was assuming that by setting the MSAA as memoryless, that I'd have the rt only have the resolved texture and save some memory. But it doesn't work. I build on a Shield Tablet K1 with Vulkan, and memory usage is exactly the same as without the memoryless flag (I checked with Unity's MemoryProfiler from bitbucket).

    So I probably have some fundamental misunderstanding of how this works.

    Any examples of this working, I looked but there isn't a lot of info.

    (also, is there no way to set both MSAA and Depth as memoryless?)
     
  2. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,794
  3. LukasCh

    LukasCh

    Unity Technologies

    Joined:
    Mar 9, 2015
    Posts:
    102
    Hey, RenderTextureMemoryless.MSAA is not supported on Vulkan (https://docs.unity3d.com/ScriptReference/RenderTextureMemoryless.MSAA.html).
    I don't remember specifics, but its basically Vulkan limitation.

    You are correct, this is how it works in metal.
     
    Lin-Dong and AcidArrow like this.
  4. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,794
    Ah, I did notice that Vulkan was missing from the docs page for MSAA, but I assumed it was a docs error, since all other modes do mention Vulkan. The rest should work on Vulkan, (like .Depth) right?

    Thank you for the reply.
     
  5. LukasCh

    LukasCh

    Unity Technologies

    Joined:
    Mar 9, 2015
    Posts:
    102
    Yes, if not - report a bug
     
    AcidArrow likes this.
  6. bryanDDI

    bryanDDI

    Joined:
    Feb 16, 2017
    Posts:
    8
    Hey LukasCh, I'm trying to use memoryless RenderTextures for my project but it's not working as I expect.
    I'm trying to have cameras render to a render texture and then set the render texture as the texture on a material to be rendered by another camera. The render textures appear to not be getting populated when I set them to memoryless. Here's an example of how I'm trying to use them. Can I not use memoryless this way?

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class MemorylessTest : MonoBehaviour
    5. {
    6.     public Camera ViewCamera;
    7.     public Renderer ViewMonitor;
    8.  
    9.     private RenderTexture renderTexture;
    10.  
    11.     void Awake()
    12.     {
    13.         renderTexture = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.Default);
    14.         renderTexture.useMipMap = false;
    15.         renderTexture.antiAliasing = 1;
    16.  
    17.         // Color and Depth and Color only don't work
    18.         renderTexture.memorylessMode = RenderTextureMemoryless.Color | RenderTextureMemoryless.Depth;
    19.         //renderTexture.memorylessMode = RenderTextureMemoryless.Color;
    20.  
    21.         // Depth only works
    22.         //renderTexture.memorylessMode = RenderTextureMemoryless.Depth;
    23.  
    24.         renderTexture.Create();
    25.  
    26.         ViewCamera.targetTexture = renderTexture;
    27.         ViewMonitor.material.mainTexture = renderTexture;
    28.     }
    29.  
    30.     void OnDestroy()
    31.     {
    32.         renderTexture.Release();
    33.         renderTexture = null;
    34.     }
    35. }
    36.  
     
  7. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,794
    @bryanDDI what are you trying to achieve by setting .Color to memoryless? Setting it to memoryless means you don't really have direct access to it.
     
  8. bryanDDI

    bryanDDI

    Joined:
    Feb 16, 2017
    Posts:
    8
    The main goal is to save general memory for the rest of the game. It seems there could also be some rendering speed performance gains from not needing to transfer the render textures from general memory to the GPU for each frame render too.
     
  9. LukasCh

    LukasCh

    Unity Technologies

    Joined:
    Mar 9, 2015
    Posts:
    102
    @bryanDDI First of all thanks for testing it. What you are trying to achieve in test is not valid and I will try to explain.

    So basically what your script is doing (Without memoryless flag):
    - ViewCamera renders scene objects into renderTexture
    - Camera does storeAction to save renderTexture from tile memory to system memory
    - Then renderTexture system memory copy is used as shader resource for ViewMonitor
    - Lastly some other camera renders ViewMonitor (Where u probably use for testing if it works or not)

    Once u enable the memoryless flag, storeAction cannot be done as renderTexture doesn't have system memory for it. So that leads that renderTexture will stay to the color it was created (Most likely gray - internally we even ignore all memoryless rendertexture setting on materials as it is not valid).

    Yes this will increase your general memory, however for performance you don't really need memoryless as it is controlled by load/store actions. (Just not sure are we expose this in camera, https://docs.unity3d.com/ScriptReference/RenderTargetSetup.html)
     
    AlejMC likes this.
  10. bryanDDI

    bryanDDI

    Joined:
    Feb 16, 2017
    Posts:
    8
    OK, thanks for confirming my suspicion.
     
  11. DavidSWu

    DavidSWu

    Joined:
    Jun 20, 2016
    Posts:
    183
    What is the best way to set store actions for cameras with render targets?
    Thanks!
     
  12. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,794
    Was there a regression for this recently? (or maybe an iOS 12 bug?). I clearly remember confirming it was working properly a couple of months ago (so before iOS 12 and with an older version of Unity), but I just started memory profiling our game again and it seems something's off.

    I am doing tests with code pretty similar to the one on my first post, and it seems that enabling and disabling AA results in very different RenderTexture sizes (like the one with 4x MSAA takes approx 4 times the memory).

    I submitted a bug report, it's Case 1095432.
     
  13. tangwilliam

    tangwilliam

    Joined:
    May 4, 2016
    Posts:
    22
    Hi, I came into the same problem. There is a big size memory usage when profiling by XCode and Unity Profiler with MSAA on . Do you know how to reduce the memory taken by MSAA now ? My Unity version is 2018.4 and my device is iPhone 11( iOS 13 )
     
  14. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,794
    If I remember correctly, this specific bug was simply that the memory profiler was not accounting for memoryless and was showing x4 the memory, even though memoryless was working.

    Not sure if what you're seeing is the same thing.
     
  15. tangwilliam

    tangwilliam

    Joined:
    May 4, 2016
    Posts:
    22
    Thank you. How do you know the memoryless was working ? I don't known how to check wether it really works.
     
  16. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,794
    I think XCode was showing the correct ram usage for me, but to be completely truthful, I don't quite remember :p
     
  17. tangwilliam

    tangwilliam

    Joined:
    May 4, 2016
    Posts:
    22
    Thanks for your help. :)
     
  18. tangwilliam

    tangwilliam

    Joined:
    May 4, 2016
    Posts:
    22
    Hi, I used the code provided by AcidArrow on the top of this thread. Supposed that memory for renderTexture to be x1, but it is still x4 in XCode. Seems like the memoryless.MSAA does not work. Do you know how to use the memoryless.MSAA correctly? (My Unity version is 2018.4.22)
     
  19. caletbak-sp

    caletbak-sp

    Joined:
    Dec 11, 2018
    Posts:
    6
    Hi I would be very interested in the memoryless feature of the render targets, at it seems to improve performance. The issue is that I am experiencing this kind of tiled rendering situation in my iPad Pro and also in iPhone12Mini:

    IMG_5076.PNG

    This is my code for generating the RT:

    Code (CSharp):
    1. RenderTextureDescriptor desc = new RenderTextureDescriptor(finalRenderTargetSizeX, finalRenderTargetSizeY, RenderTextureFormat.Default,32, 0);
    2. desc.memoryless = RenderTextureMemoryless.Depth | RenderTextureMemoryless.MSAA;
    3. desc.msaaSamples = 2;
    4. desc.useDynamicScale = true;
    5. desc.autoGenerateMips = false;
    6. desc.useMipMap = false;
    7. desc.dimension = TextureDimension.Tex2D;
    8. desc.stencilFormat = GraphicsFormat.None;
    9.  
    10. _renderTexture = RenderTexture.GetTemporary(desc);
    11.  
    It is also happening with only using MSAA mask as memoryless RT option.

    I am just setting this render texture to the camera, and then I pass it to a UI shader as a texture resource in order to render it.

    I am using Unity 2020.1.4f1 with URP 8.2, but I also tried in Unity 2020.3.5f1 with URP 10.4 and the same happens.
    URP Quality option for AA (MSAA) is set to 2x.

    Maybe @LukasCh can help or someone in Unity? :p

    Thanks!
     
    Last edited: Jun 7, 2021