Search Unity

CustomRenderTexture problem

Discussion in 'General Graphics' started by trepan, Apr 19, 2018.

  1. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    So I've been using CustomRenderTextures as a convenient way to maintain atlases of textures as part of a multi-stage procedural generation process (with a chain of textures representing different work stages). All was working great until I needed to add another pass (and so another CRT) into my pipeline - I now get a Unity crash with this callstack:

    Code (CSharp):
    1. Thread 0 Crashed:: CrBrowserMain Dispatch queue: com.apple.main-thread
    2. 0 libsystem_kernel.dylib 0x00007fff6f6bfe3e __pthread_kill + 10
    3. 1 libsystem_pthread.dylib 0x00007fff6f7fe150 pthread_kill + 333
    4. 2 libsystem_c.dylib 0x00007fff6f61c312 abort + 127
    5. 3 com.unity3d.UnityEditor5.x 0x0000000100fd3ae1 HandleSignal(int, __siginfo*, void*) + 81
    6. 4 libmono.0.dylib 0x0000000139805de0 mono_chain_signal + 75
    7. 5 libmono.0.dylib 0x000000013974d406 mono_sigsegv_signal_handler + 210
    8. 6 libsystem_platform.dylib 0x00007fff6f7f1f5a _sigtramp + 26
    9. 7 ??? 000000000000000000 0 + 0
    10. 8 com.unity3d.UnityEditor5.x 0x00000001009ef891 void std::__introsort_loop<CustomRenderTexture**, long, SortFunctor>(CustomRenderTexture**, CustomRenderTexture**, long, SortFunctor) + 321
    11. 9 com.unity3d.UnityEditor5.x 0x00000001009e144a CustomRenderTextureManager::UpdateCustomRenderTextures(dynamic_array<CustomRenderTexture*, 8ul>&, bool) + 122
    12. 10 com.unity3d.UnityEditor5.x 0x00000001009e09a4 CustomRenderTextureManager::Update(bool) + 404
    13. 11 com.unity3d.UnityEditor5.x 0x0000000100c304ad InitPlayerLoopCallbacks()::postLateUpdateUpdateCustomRenderTexturesRegistrator::Forward() + 93
    14. 12 com.unity3d.UnityEditor5.x 0x0000000100c315d3 PlayerLoop() + 1283
    15. 13 com.unity3d.UnityEditor5.x 0x00000001019a6d67 PlayerLoopController::UpdateScene(bool) + 567
    16. 14 com.unity3d.UnityEditor5.x 0x00000001019a742a PlayerLoopController::EnterPlayMode(bool) + 682
    17. 15 com.unity3d.UnityEditor5.x 0x00000001019a21e6 PlayerLoopController::SetIsPlaying(bool) + 278
    18. 16 com.unity3d.UnityEditor5.x 0x00000001019a1a35 Application::TickTimer() + 4069
    19. 17 com.apple.Foundation 0x00007fff49da6659 __NSFireTimer + 83
    20. 18 com.apple.CoreFoundation 0x00007fff47c66dd4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
    If I comment out the Update call for the new CRT it works. OR if I comment out a different CRT from my chain then that can run too. So it would seem to be related to how many CRTs I have chained and/or some problem with the inferred dependencies between them (which are totally linear although there are some stages where two earlier CRTs are associated with later materials).

    I first saw this under 2017.3.1p2 but I've also tried 2017.4.1f1 and 2018.1.0b13 which also crash just the same. Interestingly under 2018.2.0b1 I do NOT see the crash and my app runs, although I don't really want to have to rely on such an early Beta (plus some other assets I'm using aren't ready for this one yet).

    Unless anyone can see a solution I feel like I have no choice but to try and rework my pipeline to use less CRTs, otherwise I'm completely stuck. Of course if someone with access to the Unity source could see the cause of the crash from the above callstack and suggest a workaround that would be much appreciated!
     
  2. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    If I could get my head around how double buffering works for CustomRenderTextures I could likely be using that to 'simplify' my pipeline. But I've just been trying to explore that in a simple test project and not getting too far.

    Questions would include:
    - What happens during buffer swap: is this a case of the entire texture being blitted to a back buffer or are different update zones individually blitted?
    - When does the buffer swap actually occur? Is it done once before the next Update pass on the next game frame? Or will a swap occur prior to processing of a specific zone requesting 'needSwap', e.g. can there be multiple swaps (same frame) interleaved with zone processing?
    - ...If it isn't the case that double buffering occurs 'per update zone' then why are there per zone request flags?
    - ...If there's just a single full buffer swap then does setting any zone's flag trigger this?
    - How can I know whether I'm assigning the front or back buffer when I assign a CRT to another material?

    Generally I find Unity's docs to be pretty good, but it feels like the devil's really in the details with regard to CustomRenderTextures, and the detail (or examples) just seem to be sorely lacking :(
     
  3. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    ...Ok, so I have no clue how double buffering is supposed to work :(

    In the attached project I'm just trying to update one CRT (Work), read that texture in another (Final) to map the result to a cube. The result should be a simple color cycle. If I untick double buffering on the Work CRT that's what I get, with double-buffering enabled the cube just stays black...

    I was getting on fine with CRTs until I ran into the crash issue but double-buffering just seems completely broken?

    PS: One tip for anyone else trying to use CRTs that I previously learnt the hard way: when you're using update zones, you need to either initialize them in the inspector or assign them with a max sized array before calling Initialize otherwise the system will assign an array size of one that (I'm guessing) relates to the size of a shader global array that can never be re-sized differently.
     

    Attached Files:

  4. aubrian

    aubrian

    Joined:
    Apr 18, 2020
    Posts:
    8
    Three years later and CRT double buffering is still completely broken, at least on WebGL.

    Please check out and vote on the issue I opened almost two months ago: https://issuetracker.unity3d.com/is...s-not-updated-when-double-buffered-is-enabled

    My hypothesis is that Unity's CRT double buffering conflicts with WebGL's automatic double buffering implementation. But I'm far from an expert. I'm really hoping that the Unity team reprioritizes this issue next time they triage.