Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Texture.allowThreadedTextureCreation

Discussion in 'General Graphics' started by G33RT, Nov 12, 2019.

  1. G33RT

    G33RT

    Joined:
    Dec 27, 2013
    Posts:
    38
    Hi,

    I've been trying to create Textures on a non-main thread without succes, even though Texture.allowThreadedTextureCreation is set to true. I can't find too much info on this property either. Is this supposed to be working yet, how should we use/interpret it?

    Tnx,

    Geert
     
  2. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    38
    Hi, I'll try an help you. Can you give me some more information:
    • Which platform are you working with? (and which Unity version?)
    • Which texture type are you using (2d/3d)?
    • Which texture format are you using (crunch compressed, RGB 24 bit, etc)?
    • Is Texture.allowThreadedTextureCreation set to true on start up, or are you trying to set it to true?
    If its false on start up then Unity does not support threaded texture creation on that platform.
    If you try to set it to true, it will ping back to false if its unsupported.

    If this is true on start up then textures will be created on a thread where possible.

    How are you confirming whether this is working?
    • You can look in the unity profiler to check. Look for Gfx.CreateTextureThreaded rather than Gfx.CreateTexture.
    • Its easier to load the data into the Profile Analyzer tool to search for markers with specific names over a time range across a range of threads (make sure to search the main thread, render thread and job threads)
    Not all texture formats are supported, hence the second/third questions. For example 3D textures are not currently supported.

    Can I also ask what problem you are looking to solve so I can potentially offer other solutions.
     
    richardkettlewell and LeonhardP like this.
  3. G33RT

    G33RT

    Joined:
    Dec 27, 2013
    Posts:
    38
    Hi!

    Tnx for replying!

    I'm building for Windows, and allowThreadedTextureCreation is set to true (I've checked that at runtime). I was kind of hoping I could now "new Texture2D(width,height)" on a different thread, but that assumption is wrong I suppose?

    The problem I'm trying to solve: I'm streaming 3D data over http, I've succeeded to a very large extent to have as much work done on other threads than the main thread to have very fluent rendering while streaming. The only problem remaining are large textures as I must allocate them on the main thread ...

    Geert
     
  4. athenspire

    athenspire

    Joined:
    Dec 4, 2019
    Posts:
    1
    I am experiencing the same issue on Mac. After setting Texture2D.allowThreadedTextureCreation and confirming that it returns true, calling "new Texture2D(width,height)" from a separate thread results in runtime errors that state that texture creation can only be done in Main Thread.

    The documentation for Texture.allowThreadedTextureCreation is terse. Is there a prescribed technique to create textures from another thread?

    jeff
     
    Last edited: Jan 28, 2020
  5. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    140
    @Unity Can you please show an example on how to create a texture on another thread, as we are also not able to create a texture even if allowThreadedTextureCreation is true:

    Code (CSharp):
    1.     private void CreateTextureAsync()
    2.     {
    3.         //UnityException: SupportsTextureFormatNative can only be called from the main thread.
    4.         //Constructors and field initializers will be executed from the loading thread when loading a scene.
    5.         //Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
    6.         Texture2D tex = new Texture2D(256, 256);
    7.     }
    8.  
    9.  
    10.     private void StartCreateTexture()
    11.     {
    12.         Thread loadingThread = new Thread(CreateTextureAsync);
    13.         loadingThread.Start();
    14.     }
     
  6. G33RT

    G33RT

    Joined:
    Dec 27, 2013
    Posts:
    38
    I still can't get it to work either, tried several combinations/variations on each new (minor) Unity version. I really need this, and I am quite amazed that not too many others are kinda waiting for this.

    Texture.allowThreadedTextureCreation has been in the API for several months now. Anyone has any clue on how to use it or if it is possible in any way to create Textures or do a ImageConversion.LoadImage on another thread?
     
  7. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    38
    Hi, I'm afraid the documentation has probably created some confusion on this issue.
    The Texture.allowThreadedTextureCreation flag controls Unity internals for texture creation.

    When its set to true, the internal graphics APIs will create the texture on a worker thread, rather than the render thread. This will free up the render thread for other work and reduce hitches, due to moving some slower activity to a worker thread.

    Unfortunately you can't call the C# texture creation API's on a separate thread.
    You could create the texture on the main thread and then generate the data for the texture on a separate thread.
    Use Texture2D.GetRawTextureData to get a pointer to memory to fill in and pass this to your worker thread.
    The Texture2D.Apply function will still need to be called on the main thread though.
     
    Mic9 and richardkettlewell like this.
  8. G33RT

    G33RT

    Joined:
    Dec 27, 2013
    Posts:
    38
    Ok.

    Do you see any way of converting "raw png bytes" to "RawTextureData" on a non-main thread? (I currently simply use LoadImage for that). I suppose some kind of custom png decoder to start with?

    Geert
     
  9. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,838
    I think you could use a 3rd party PNG decoder (google shows a few), which you could use to populate the raw texture data yourself.
     
  10. Glader

    Glader

    Joined:
    Aug 19, 2013
    Posts:
    428
    Is it safe to use this pointer on another thread though or do we need to create a buffer copy of it before queueing it onto another thread?

    edit: Further googling seems like using NativeArray created on the main thread on another thread probably isn't safe.
     
  11. lyndon_unity

    lyndon_unity

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    38
    Note the caveat listed in the documentation for GetRawTextureData:
    https://docs.unity3d.com/ScriptReference/Texture2D.GetRawTextureData.html

    Note: The returned array can become invalid (i.e. it no longer points to valid memory) if modifications or uploads happen to the texture after you call this method. Therefore the recommended way to use this method is to get the data, and use or modify it immediately. You should not store the returned array for later use.
    Potentially you could use the pointer on another thread but there are definitely risks.
    A safer option is to create your texture data in some working memory and then perform the final copy to the texture on the main thread. (or if you need the original texture data, make a copy of that into the memory you own, modify it on a thread and then perform the final copy to the texture on the main thread).
     
unityunity