Search Unity

requestedMipmapLevel doesn't seem to be working

Discussion in 'General Graphics' started by Dizzy-Dalvin, Sep 18, 2019.

  1. Dizzy-Dalvin

    Dizzy-Dalvin

    Joined:
    Jul 4, 2013
    Posts:
    54
    I tried setting requestedMipmapLevel for a specific texture and the only thing that seems to change is the result of the call to IsRequestedMipmapLevelLoaded. Whatever I do, the values stay the same:
    Code (CSharp):
    1. desiredMipmapLevel: -1
    2. loadedMipmapLevel: 2
    3. loadingMipmapLevel: 2
    4.  
    5. mipMapCount: 13
    6. currentTextureMemory: 8768306
    7. desiredTextureMemory: 0
    8. targetTextureMemory: 0
    9. totalTextureMemory: 0
    Memory budget in the quality settings is set to 4096.

    When I set requested level to 0 or 1, IsRequestedMipmapLevelLoaded returns false but nothing else changes, the levels aren't loaded. What's more important, when I set requested level to 6 or 7, the mip levels aren't unloaded and still take up memory (IsRequestedMipmapLevelLoaded returns true now).

    I'm using Unity 2019.2.3f1.
     
  2. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    66
    Have you enabled texture streaming in the quality settings (I assume yes as you mention the budget)
    And are you using a quality setting that has it enabled.
    If you are accidentally using a quality setting with texture mip streaming disabled then it will not update.

    The debug script listed in this document may be of help
    https://docs.google.com/document/d/...YSXe02h6YrkDcEpGM/edit#heading=h.d0luvjrps7mh

    Listed below for convenience

    Code (CSharp):
    1. using System;
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. public class ShowTextureStreamingSummary : MonoBehaviour
    6. {
    7.     public float X = 10;
    8.     public float Y = 20;
    9.     public int MemoryBudgetPercentThreshold = 80;
    10.     public int TextureStreamingPercentThreshold = 50;
    11.     private ulong HighestDesiredTextureMemory;
    12.     private Rect TextRect;
    13.  
    14.     public void Start()
    15.     {
    16.         HighestDesiredTextureMemory = 0;
    17.     }
    18.  
    19.     public string HumanReadableSize(ulong size)
    20.     {
    21.         return string.Format("{0:0.0}M", (float)size / (float)(1024 * 1024));
    22.     }
    23.  
    24.     void ShowText(string text)
    25.     {
    26.         float yInc = GUI.skin.font.lineHeight;
    27.         GUI.Label(TextRect, text);
    28.         TextRect.y += yInc;
    29.     }
    30.  
    31.     public void OnGUI()
    32.     {
    33.         TextRect = new Rect(X, Y, Screen.width - X, Screen.height - Y);
    34.  
    35.         if (!SystemInfo.supportsMipStreaming)
    36.             ShowText("Texture streaming unsupported");
    37.         if (!QualitySettings.streamingMipmapsActive)
    38.             ShowText("Texture streaming disabled");
    39.         else if (QualitySettings.streamingMipmapsMemoryBudget == 0)
    40.             ShowText("No texture streaming budget");
    41.         else if (Texture.totalTextureMemory == 0)
    42.             ShowText("No texture memory needed");
    43.         else
    44.         {
    45.             // Reduced highest memory usage
    46.             if (Texture.desiredTextureMemory > HighestDesiredTextureMemory)
    47.                 HighestDesiredTextureMemory = Texture.desiredTextureMemory;
    48.  
    49.             // Show stats
    50.             ulong budget = (ulong)(1024 * 1024 * QualitySettings.streamingMipmapsMemoryBudget);
    51.             float percentUsed = (float)(100 *Texture.desiredTextureMemory) / (float)budget;
    52.             ShowText(string.Format("Memory budget utilisation {0:0.0}% of {1} texture budget", percentUsed, HumanReadableSize(budget)));
    53.  
    54.             if (HighestDesiredTextureMemory > budget)
    55.             {
    56.                 ulong memoryExcess = HighestDesiredTextureMemory - budget;
    57.                 ShowText(string.Format("Memory exceeds budget by {0}", HumanReadableSize(memoryExcess)));
    58.             }
    59.             else
    60.             {
    61.                 ulong memorySaving = Texture.totalTextureMemory - HighestDesiredTextureMemory;
    62.                 float percentReduction = (float) (100 * HighestDesiredTextureMemory) / (float) Texture.totalTextureMemory;
    63.                 ShowText(string.Format("Memory saving at least {0} with streaming enabled ( at {1:0.0}% of original {2}) - ignoring caching", HumanReadableSize(memorySaving), percentReduction, HumanReadableSize(Texture.totalTextureMemory)));
    64.             }
    65.  
    66.             // Advice section
    67. #if UNITY_EDITOR
    68.             ShowText("Run in standalone app for accurate figures. When run in Play Mode the stats are biased by editor textures");
    69. #endif              
    70.             if (percentUsed < (float)MemoryBudgetPercentThreshold)
    71.                 ShowText(string.Format("Reduce the Memory Budget closer to {0}", HumanReadableSize(Texture.desiredTextureMemory)));
    72.             else if (Texture.desiredTextureMemory > budget)
    73.                 ShowText(string.Format("Raise Memory Budget above {0}", HumanReadableSize(Texture.desiredTextureMemory)));
    74.  
    75.             float percentStreaming = (float)(100 * (Texture.totalTextureMemory - Texture.nonStreamingTextureMemory)) / (float)Texture.totalTextureMemory;
    76.             if (percentStreaming < (float)TextureStreamingPercentThreshold)
    77.                 ShowText(string.Format("Mark more textures streaming to improve savings ({0:0.0}% texture memory marked as streaming)", percentStreaming));
    78.  
    79.             if (!Texture.streamingTextureDiscardUnusedMips)
    80.                 ShowText("Consider turning on Texture.streamingTextureDiscardUnusedMips to analyse without cached textures");
    81.         }
    82.     }
    83. }
    84.  
     
  3. Dizzy-Dalvin

    Dizzy-Dalvin

    Joined:
    Jul 4, 2013
    Posts:
    54
    Yes, I have now enabled it for all quality settings just to be sure, but still no luck.

    The debug script says "No texture memory needed".
     
  4. Dizzy-Dalvin

    Dizzy-Dalvin

    Joined:
    Jul 4, 2013
    Posts:
    54
    Okay, I added a MeshRenderer (I was using RawImage before, that was my mistake) and now the situation's a little different.
    The mip level now changes, but only if I set it to 1 or 2. If I use 0 I get this picture:
    Code (CSharp):
    1. desiredMipmapLevel: 0
    2. loadedMipmapLevel: 1
    3. loadingMipmapLevel: 1
    4. IsRequestedMipmapLevelLoaded(): false
    If I use 3, 4, etc.
    Code (CSharp):
    1. desiredMipmapLevel: 2
    2. loadedMipmapLevel: 1
    3. loadingMipmapLevel: 1
    4. IsRequestedMipmapLevelLoaded(): false
    I also just tried setting streamingTextureDiscardUnusedMips to true and it has some effect: now when I set required level to 2 or higher, loaded and loading levels become 2 instead of 1.
    But currently there are three problems:

    1. It never loads level 0.
    2. It never unloads mip maps when I set it to anything from 3 to 13. The desiredMipmapLevel remains 2.
    3. I would prefer not to use streamingTextureDiscardUnusedMips as it affects other textures and I just want to set maximum loaded mip level manually for one specific texture, in isolation, without affecting global state.
     
  5. Fewes

    Fewes

    Joined:
    Jul 1, 2014
    Posts:
    259
    I'm having a very similar/the exact same issue. Setting requestedMipmapLevel to anything above 2 does not seem to have any effect, and in fact setting it to something like 7 results in nothing being streamed out at all. Using Unity 2020.1.0a5.
     
  6. wwweh

    wwweh

    Joined:
    Oct 15, 2012
    Posts:
    18
    I'm having similar issues, the StreamingController method seems to work as you'd expect but the API doesn't load/release any textures other than 0/1 mip level.
     
  7. xuanyusong

    xuanyusong

    Joined:
    Apr 10, 2013
    Posts:
    49
    first requestedMipmapLevel can be work , but when after ClearRequestedMipmapLevel() call requestedMipmapLevel doesn't work
    Code (CSharp):
    1.     void Start()
    2.     {
    3.         mr = Instantiate<GameObject>(go1).GetComponent<MeshRenderer>();
    4.         t1 = mr.material.mainTexture as Texture2D;
    5.         t1.requestedMipmapLevel = 2; // work
    6.         t1.ClearRequestedMipmapLevel();
    7.         t1.requestedMipmapLevel = 5; // do not work!
    8.     }
    unity version 2019.3.0f3
     
    GridWanderer likes this.
  8. Fewes

    Fewes

    Joined:
    Jul 1, 2014
    Posts:
    259
    Any updates on this? Does the texture streaming system work at all or is it abandoned? Texture2D.requestedMipmapLevel doesn't seem to affect textures at all. Whenever I enable texture streaming any texture with it enabled just uses the lowest mipmap no matter what I do.
     
  9. JPDoiron

    JPDoiron

    Joined:
    Jan 11, 2013
    Posts:
    16

    What's the size of your original Texture ?
    Can you share a screenshot of the import setting ?
     
  10. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    883
    Any updates on this? Does the texture streaming system work at all or is it abandoned?
     
  11. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    66
    The issue you are seeing with requestedMipMapLevel is likely due to the texture steaming system clamping the mip level to the 'max level reduction' set in the quality settings
    https://docs.unity3d.com/Manual/TextureStreaming.html#enabling-system

    As this defaults to '2'. The values 0,1 and 2 will work as expected, but 3,4,5,etc will be clamped to 2.
    Try adjusting this max level reduction.

    Also the system will cache the mip level in memory where possible to avoid thrashing the IO.
    As indicated above, setting streamingTextureDiscardUnusedMips to true would force the unused mips to be discarded. This isn't advised in the final version due to the extra IO overheads, but can be useful in testing.
     
  12. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    883
    Does this system currently work with addressables? I've tried to use requestedMipMapLevel on textures loaded from addressables and it never loads any mipmaps with higher resolution, than set in max level reduction.
     
  13. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    66
    Yes it should work with addressables.

    Which platform are you working with?
    If its Android then its important to use LZ4 or LZ4HC compressed packages (rather than zip compressed) for the streaming to work.
     
  14. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    883
    On windows. But I draw meshes using a Graphics.DrawMesh. There are no MeshRenderers on the scene,
     
  15. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    66
    This could be a bug specific to not having any mesh renderer's since the system is designed primarily to work with mesh renderers. I'd suggest raising a bug report for this case.

    If you have a simple reproduction project that you can attach to the bug I'd recommend doing so, as it can speed up the process.
     
  16. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    883
    Ok I will prepare a reproducable project and will post a bug in a few days and will let you know. Thanks!
     
  17. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    66
    On further reflection I believe this should work and recall a fix being made in an old Unity version for this edge case. Which Unity version are you using?

    It could be worth checking are if you have sufficient memory budget set to support loading the desired mips.

    The following script could help.

    Apply it to a game object in the scene to display the texture streaming status. It is useful for determining the correct memory budget to set.


    Code (CSharp):
    1. using System;
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. public class ShowTextureStreamingSummary : MonoBehaviour
    6. {
    7.     public float X = 10;
    8.     public float Y = 20;
    9.     public int MemoryBudgetPercentThreshold = 80;
    10.     public int TextureStreamingPercentThreshold = 50;
    11.     private ulong HighestDesiredTextureMemory;
    12.     private Rect TextRect;
    13.  
    14.     public void Start()
    15.     {
    16.         HighestDesiredTextureMemory = 0;
    17.     }
    18.  
    19.     public string HumanReadableSize(ulong size)
    20.     {
    21.         return string.Format("{0:0.0}M", (float)size / (float)(1024 * 1024));
    22.     }
    23.  
    24.     void ShowText(string text)
    25.     {
    26.         float yInc = GUI.skin.font.lineHeight;
    27.         GUI.Label(TextRect, text);
    28.         TextRect.y += yInc;
    29.     }
    30.  
    31.     public void OnGUI()
    32.     {
    33.         TextRect = new Rect(X, Y, Screen.width - X, Screen.height - Y);
    34.  
    35.         if (!SystemInfo.supportsMipStreaming)
    36.             ShowText("Texture streaming unsupported");
    37.         if (!QualitySettings.streamingMipmapsActive)
    38.             ShowText("Texture streaming disabled");
    39.         else if (QualitySettings.streamingMipmapsMemoryBudget == 0)
    40.             ShowText("No texture streaming budget");
    41.         else if (Texture.totalTextureMemory == 0)
    42.             ShowText("No texture memory needed");
    43.         else
    44.         {
    45.             // Reduced highest memory usage
    46.             if (Texture.desiredTextureMemory > HighestDesiredTextureMemory)
    47.                 HighestDesiredTextureMemory = Texture.desiredTextureMemory;
    48.  
    49.             // Show stats
    50.             ulong budget = (ulong)(1024 * 1024 * QualitySettings.streamingMipmapsMemoryBudget);
    51.             float percentUsed = (float)(100 *Texture.desiredTextureMemory) / (float)budget;
    52.             ShowText(string.Format("Memory budget utilisation {0:0.0}% of {1} texture budget", percentUsed, HumanReadableSize(budget)));
    53.  
    54.             if (HighestDesiredTextureMemory > budget)
    55.             {
    56.                 ulong memoryExcess = HighestDesiredTextureMemory - budget;
    57.                 ShowText(string.Format("Memory exceeds budget by {0}", HumanReadableSize(memoryExcess)));
    58.             }
    59.             else
    60.             {
    61.                 ulong memorySaving = Texture.totalTextureMemory - HighestDesiredTextureMemory;
    62.                 float percentReduction = (float) (100 * HighestDesiredTextureMemory) / (float) Texture.totalTextureMemory;
    63.                 ShowText(string.Format("Memory saving at least {0} with streaming enabled ( at {1:0.0}% of original {2}) - ignoring caching", HumanReadableSize(memorySaving), percentReduction, HumanReadableSize(Texture.totalTextureMemory)));
    64.             }
    65.  
    66.             // Advice section
    67. #if UNITY_EDITOR
    68.             ShowText("Run in standalone app for accurate figures. When run in Play Mode the stats are biased by editor textures");
    69. #endif              
    70.             if (percentUsed < (float)MemoryBudgetPercentThreshold)
    71.                 ShowText(string.Format("Reduce the Memory Budget closer to {0}", HumanReadableSize(Texture.desiredTextureMemory)));
    72.             else if (Texture.desiredTextureMemory > budget)
    73.                 ShowText(string.Format("Raise Memory Budget above {0}", HumanReadableSize(Texture.desiredTextureMemory)));
    74.  
    75.             float percentStreaming = (float)(100 * (Texture.totalTextureMemory - Texture.nonStreamingTextureMemory)) / (float)Texture.totalTextureMemory;
    76.             if (percentStreaming < (float)TextureStreamingPercentThreshold)
    77.                 ShowText(string.Format("Mark more textures streaming to improve savings ({0:0.0}% texture memory marked as streaming)", percentStreaming));
    78.  
    79.             if (!Texture.streamingTextureDiscardUnusedMips)
    80.                 ShowText("Consider turning on Texture.streamingTextureDiscardUnusedMips to analyse without cached textures");
    81.         }
    82.     }
    83. }
    84.  
     
  18. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    883
    I am using Unity 2020.3.33, and memory budget set to 1024 Mb. But I will try it out, thank you!
     
  19. MarcGFJ

    MarcGFJ

    Joined:
    May 16, 2019
    Posts:
    24
    I am trying to use mipmap streaming and I'm hitting a similar problem in Unity 2022.2.11, but in my case it seems no matter what I do, Unity always loads mip 0 (the biggest).

    The project has only one scene. The scene contains a camera, a cube, a material on the cube with a 2048x2048 texture on it. The texture has no compression, has mipmaps, and uses Mip Streaming. My current quality setting also has Texture Streaming turned on, with the default 512 Mb budget, and max level reduction 3. The texture weights 16 Mb.

    In my testing code, I have something like this in an Update() function:
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         if (requestMipmap) // false by default
    4.         {
    5.             texture.requestedMipmapLevel = mipmapLevelToRequest;
    6.         }
    7.         else
    8.         {
    9.             texture.ClearRequestedMipmapLevel();
    10.         }
    And later some code printing various properties on the texture related to streaming.

    When I run the scene:
    - loadedMipmapLevel is 0.
    - If I start requesting mip 2, loadedMipmapLevel stays 0 (why?)
    - If I lower budget down to 4 Mb (which is higher than the full texture size), loadedMipmapLevel remains 0 (why?)
    - In every case, loadedMipmapLevel also remains 0 and IsRequestedMipmapLevelLoaded() always returns false, unless I request mip 0.
    - There are no error, warning or particular log.
    - The Texture Streaming menu in Scene View doesn't display any color like the doc indicates
    - Same behavior in Core and URP, except in URP I could not find the "Texture Streaming" debug menu in the Scene View.
    - Same behavior in built game.

    It's like the whole feature isn't active or something. What am I missing?

    I tried restarting the editor after having left max budget to 4 Mb. Only then, when I start the game, now it loads mip 3, as in my project settings. But if I set requestedMipmapLevel higher, it doesn't change anything and stays at mip 3.
    Similarly, if I set budget back to 512, restart the editor, and start the game, mip 0 gets loaded, but then setting requestedMipmapLevel to 2 does not change the current loaded mip, it stays at 0... the property seems to not work at all, unless there is some extra thing to do?
     
    Last edited: Sep 14, 2023
  20. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    66
    I suspect that the mip level is not reduced as you have suffient memory budget to keep all mips in the cpu texture cache.

    Try setting Texture.streamingTextureDiscardUnusedMips to true to disable the caching as suggested further up this thread.
     
  21. Fane_3504

    Fane_3504

    Joined:
    Mar 23, 2023
    Posts:
    3
    I found change Texture2D.requestedMipmapLevel sometime not unload unused mip even if setting Texture.streamingTextureDiscardUnusedMips to true. Repeatedly modifying this value(Texture2D.requestedMipmapLevel) will cause the memory occupied by the texture to continue to increase.
     
    Last edited: Sep 25, 2023
  22. Fane_3504

    Fane_3504

    Joined:
    Mar 23, 2023
    Posts:
    3
    A texture repeatedly changes its requestedMipmapLevel more than ten times, causing the memory to explode form 1.3M to 13.7M.
    upload_2023-9-25_18-1-49.png
     
  23. OlofAviron

    OlofAviron

    Unity Technologies

    Joined:
    Feb 18, 2021
    Posts:
    6
    Hey!
    This looks like a bug we want to fix.
    I would suggest reporting it using the Bug Reporter.
    (in the Editor: Help -> Report a Bug — make sure to include a reproduction project (as minimal as possible) with repro steps)
     
  24. Fane_3504

    Fane_3504

    Joined:
    Mar 23, 2023
    Posts:
    3
    This problem seems only occur on 2022.2.17. I updated the version and it was solved.

    But I found when mipLevel>5, the texture memory not reduce, which means one texture's memory would be 4.4KB No matter the loaded mip level is 5, 6, or 7.
    Is there any setting that limits the minimum size of a texture?
    upload_2023-10-11_10-58-46.png upload_2023-10-11_10-59-33.png
     

    Attached Files:

  25. OlofAviron

    OlofAviron

    Unity Technologies

    Joined:
    Feb 18, 2021
    Posts:
    6
    Happy to hear that you are not facing your previous issue anymore!

    Regarding this new issue: I would expect to see a change in the reported size if the loaded mipmap is different, this seems like a bug.
    I would recommend reporting this using the Bug Reporter.