Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved CommandBuffer.RequestAsyncReadbackIntoNativeArray size of buffer error

Discussion in 'High Definition Render Pipeline' started by CaseyHofland, Jan 17, 2022.

  1. CaseyHofland


    Mar 18, 2016
    I want to read a texture into a native array. It is my understanding that the following code should be perfectly fine:

    Code (CSharp):
    1. ReadExample(CommandBuffer cmd, RenderTexture source)
    2. {
    3.     var pixels = new NativeArray<byte>(source.width * source.height * 4, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
    5.     cmd.RequestAsyncReadbackIntoNativeArray(ref pixels, source, 0, (request) =>
    6.     {
    7.         pixels.Dispose();
    8.     });
    9. }
    And yet when I run this, I receive
    Size of buffer cannot be larger than the nativeArray to read into.

    The full stack trace:

    Code (CSharp):
    1. Size of buffer cannot be larger than the nativeArray to read into.
    2. UnityEngine.StackTraceUtility:ExtractStackTrace ()
    3. UnityEngine.Rendering.ScriptableRenderContext:Submit_Internal ()
    4. UnityEngine.Rendering.ScriptableRenderContext:Submit ()
    5. UnityEngine.Rendering.HighDefinition.HDRenderPipeline:Render (UnityEngine.Rendering.ScriptableRenderContext,System.Collections.Generic.List`1<UnityEngine.Camera>) (at Library/PackageCache/com.unity.render-pipelines.high-definition@12.1.3/Runtime/RenderPipeline/HDRenderPipeline.cs:1906)
    6. UnityEngine.Rendering.RenderPipeline:InternalRender (UnityEngine.Rendering.ScriptableRenderContext,System.Collections.Generic.List`1<UnityEngine.Camera>)
    7. UnityEngine.Rendering.RenderPipelineManager:DoRenderLoop_Internal (UnityEngine.Rendering.RenderPipelineAsset,intptr,System.Collections.Generic.List`1<UnityEngine.Camera/RenderRequest>,Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle)
    8. UnityEditor.EditorGUIUtility:RenderPlayModeViewCamerasInternal (UnityEngine.RenderTexture,int,UnityEngine.Vector2,bool,bool)
    9. UnityEditor.PlayModeView:RenderView (UnityEngine.Vector2,bool)
    10. UnityEditor.GameView:OnGUI ()
    11. UnityEditor.HostView:InvokeOnGUI (UnityEngine.Rect)
    12. UnityEditor.DockArea:DrawView (UnityEngine.Rect)
    13. UnityEditor.DockArea:OldOnGUI ()
    14. UnityEngine.UIElements.IMGUIContainer:DoOnGUI (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,bool,UnityEngine.Rect,System.Action,bool)
    15. UnityEngine.UIElements.IMGUIContainer:HandleIMGUIEvent (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,System.Action,bool)
    16. UnityEngine.UIElements.IMGUIContainer:DoIMGUIRepaint ()
    17. UnityEngine.UIElements.UIR.RenderChainCommand:ExecuteNonDrawMesh (UnityEngine.UIElements.UIR.DrawParams,single,System.Exception&)
    18. UnityEngine.UIElements.UIR.UIRenderDevice:EvaluateChain (UnityEngine.UIElements.UIR.RenderChainCommand,UnityEngine.Material,UnityEngine.Material,UnityEngine.Texture,UnityEngine.Texture,single,Unity.Collections.NativeSlice`1<UnityEngine.UIElements.UIR.Transform3x4>,Unity.Collections.NativeSlice`1<UnityEngine.Vector4>,UnityEngine.MaterialPropertyBlock,bool,System.Exception&)
    19. UnityEngine.UIElements.UIR.RenderChain:Render ()
    20. UnityEngine.UIElements.UIRRepaintUpdater:Update ()
    21. UnityEngine.UIElements.VisualTreeUpdater:UpdateVisualTreePhase (UnityEngine.UIElements.VisualTreeUpdatePhase)
    22. UnityEngine.UIElements.Panel:UpdateForRepaint ()
    23. UnityEngine.UIElements.Panel:Repaint (UnityEngine.Event)
    24. UnityEngine.UIElements.UIElementsUtility:DoDispatch (UnityEngine.UIElements.BaseVisualElementPanel)
    25. UnityEngine.UIElements.UIElementsUtility:UnityEngine.UIElements.IUIElementsUtility.ProcessEvent (int,intptr,bool&)
    26. UnityEngine.UIElements.UIEventRegistration:ProcessEvent (int,intptr)
    27. UnityEngine.UIElements.UIEventRegistration/<>c:<.cctor>b__1_2 (int,intptr)
    28. UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
    30. [C:\buildslave\unity\build\Runtime\Graphics\AsyncGPUReadbackManaged.cpp line 336]
    @richardkettlewell I saw you on another forum talking about an AsyncGPUReadback error so I though I would add you here as well.
  2. richardkettlewell


    Unity Technologies

    Sep 9, 2015
    what format is the RenderTexture?
  3. CaseyHofland


    Mar 18, 2016
    That source is the screen texture and we use it for a post processing effect.

    This code works perfectly fine when the Color Buffer Format in the quality settings is R11G11B10, but in our highest quality settings it is set to R16G16B16A16. Thank you so much! Sorry for taking your time with this one, I should have spotted it.

    This makes me wonder though: if you read back an R11G11B10 texture into a NativeArray<byte>, I assume you get incorrect results, with every 4 bytes being in the format: R8, R3G5, G6B2, B8. If so, would NativeArray<float> capture these values in the right format, or simple capture 1 float for every pixel in the format R11G11B10? Neither does much good: how do I go about capturing the NativeArray correctly?
  4. JulienF_Unity


    Unity Technologies

    Dec 17, 2015

    If you use NativeArray<float> or any compatible <T>, this will not perform a conversion of data, it is really just a reinterpretation, so yes it will only be the R11G11B10 data reinterpreted as float. What you can do is requesting Uint32 and extract RGB data manually with bitwise operations.

    It's worth noting that Async readback also supports some actual data conversion for textures. You can specify a destination texture format when performing a request, in that case the data on GPU will be converted to that format (if they differ). Not all conversions are supported and, if not, you'll get a request with the error flag set. Also note that the conversion comes at a cost on the render thread