Search Unity

Question AsyncGPUReadback w. ComputeShader in EditorWindow

Discussion in 'Shaders' started by MaxRoetzler, Dec 21, 2020.

  1. MaxRoetzler

    MaxRoetzler

    Joined:
    Jan 3, 2010
    Posts:
    136
    I'm trying to figure out the proper setup to run compute shaders from an editor window, but I must clearly be doing something wrong. The current setup usually runs for like a minute before the new texture is created in the project. (128x128 res, Unity 2020.2.0f1c1)

    Any hints on what is wrong with this setup?

    Editor Window
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEditor;
    4. using System.IO;
    5.  
    6. public class ComputeTest : EditorWindow
    7. {
    8.     private Texture2D m_Input;
    9.     private Texture2D m_Output;
    10.     private RenderTexture m_RenderTexture;
    11.     private ComputeShader m_ComputeShader;
    12.  
    13.     private void OnGUI ()
    14.     {
    15.         m_ComputeShader = EditorGUILayout.ObjectField (new GUIContent ("Compute Shader"), m_ComputeShader, typeof (ComputeShader), false) as ComputeShader;
    16.         m_Input = EditorGUILayout.ObjectField (new GUIContent ("Input Texture"), m_Input, typeof (Texture2D), false) as Texture2D;
    17.         EditorGUILayout.Space ();
    18.  
    19.         if (GUILayout.Button ("Compute"))
    20.         {
    21.             if (m_Input == null)
    22.             {
    23.                 return;
    24.             }
    25.  
    26.             int size = m_Input.width;
    27.  
    28.             m_Output = new Texture2D (size, size, TextureFormat.ARGB32, false);
    29.             m_RenderTexture = new RenderTexture (size, size, 0, RenderTextureFormat.ARGB32)
    30.             {
    31.                 enableRandomWrite = true
    32.             };
    33.             m_RenderTexture.Create ();
    34.  
    35.             int kernel = m_ComputeShader.FindKernel ("CSMain");
    36.             m_ComputeShader.SetTexture (kernel, "Input", m_Input);
    37.             m_ComputeShader.SetTexture (kernel, "Output", m_RenderTexture);
    38.  
    39.             EditorUtility.DisplayProgressBar ("Compute", "Running Compute Shader", 0.5f);
    40.  
    41.             // Submit compute shader
    42.             m_ComputeShader.Dispatch (kernel,size/8, size/8, 1);
    43.             AsyncGPUReadback.Request (m_RenderTexture, 0, TextureFormat.ARGB32, OnCompleteReadback);
    44.         }
    45.     }
    46.  
    47.     private void OnCompleteReadback (AsyncGPUReadbackRequest request)
    48.     {
    49.         if (request.hasError)
    50.         {
    51.             Debug.Log ("GPU readback error detected.");
    52.             return;
    53.         }
    54.  
    55.         // Get output filepath
    56.         string filePath = AssetDatabase.GetAssetPath (m_Input);
    57.         string directory = Path.GetDirectoryName (filePath);
    58.         string extension = Path.GetExtension (filePath);
    59.         filePath = Path.Combine (directory, "Output" + extension);
    60.  
    61.         // Retrieve texture, save to disk
    62.         m_Output.LoadRawTextureData (request.GetData<uint>());
    63.         m_Output.Apply ();
    64.  
    65.         File.WriteAllBytes (filePath, ImageConversion.EncodeToTGA (m_Output));
    66.         DestroyImmediate (m_Output);
    67.  
    68.         // Update asset database
    69.         AssetDatabase.ImportAsset (filePath, ImportAssetOptions.ForceUpdate);
    70.         AssetDatabase.Refresh ();
    71.  
    72.         EditorUtility.ClearProgressBar ();
    73.     }
    74.  
    75.     [MenuItem ("Tools/ComputeTest")]
    76.     private static void Open ()
    77.     {
    78.         GetWindow<ComputeTest> ().Show ();
    79.     }
    80. }
    Compute Shader
    Code (CSharp):
    1. #pragma kernel CSMain
    2.  
    3. Texture2D<float4> Input;
    4. RWTexture2D<float4> Output;
    5.  
    6. [numthreads(8,8,1)]
    7. void CSMain (uint3 id : SV_DispatchThreadID)
    8. {
    9.     Output[id.xy] = 1.0f - Input[id.xy];
    10. }
     
  2. MaxRoetzler

    MaxRoetzler

    Joined:
    Jan 3, 2010
    Posts:
    136
    Seems like this was fixed since then, as it works fine now in Unity 2020.3.