Search Unity

Question Why is this Compute Shader not writing to a texture unless I set a render target?

Discussion in 'Universal Render Pipeline' started by funkyCoty, Sep 28, 2022.

  1. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    Here is a simple example:

    Code (CSharp):
    1.  
    2. private void InitializeSDFFromMask(CommandBuffer command)
    3. {
    4.     var volumeDepth = Mask.volumeDepth;
    5.     var compute = volumeDepth > 1 ? settings.data.SDFComputeSPI : settings.data.SDFComputeMP;
    6.  
    7.     command.SetRandomWriteTarget(0, SDF.GetWriter());
    8.     command.SetComputeTextureParam(compute, kernal_Initialize, compute_id_SDFOutput, SDF.GetWriter(), 0, RenderTextureSubElement.Color);
    9.     command.DispatchCompute(compute, kernal_Initialize, SDF.GetWidth() / 8, SDF.GetHeight() / 8, volumeDepth);
    10.  
    11.     SDF.Swap();
    12. }
    13.  
    If I remove 'command.SetRandomWriteTarget(0, SDF.GetWriter());' - the texture will not be written to. If it's there, the texture IS written to.

    Here's a simplified version of the compute shader:

    Code (CSharp):
    1. [numthreads(8, 8, 1)]
    2. void Initialize(int3 id : SV_DispatchThreadID)
    3. {
    4.     SDFOutput[id.xy] = 1.0;
    5. }
    SDF is just a Render Texture pair (wrapper class to swap between calls). Also, another strange thing is that I see it's inserting unnecessary Clear() draws in the middle of my compute dispatches. What is going on here?

    Unity_0gkKVKrlte.png
     
  2. peterbay

    peterbay

    Unity Technologies

    Joined:
    Nov 2, 2017
    Posts:
    100
    How are you declaring SDFOutput in the compute shader?
     
  3. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    Simple version: it's just a RW_TEXTURE2D<float4>. It's actually a custom macro setup to handle SPI/MP VR rendering based on defines, but in this example it is just a RWTexture<float4> (even when i trim it down to this directly to keep it simple, same result)
     
    Last edited: Sep 29, 2022
  4. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    Alright so I managed to get it to work without any Clear()s. Instead of creating a RenderTexture and using that as a reference, I instead just added something like:

    Code (CSharp):
    1. MyCommandBuffer.GetTemporaryRT()
    For some reason, doing it this way doesn't do a clear and doesn't require using SetRandomWriteTarget(). I don't know if there's some bug with URP/SRP/Unity somewhere in the CommandBuffer/RenderTexture/ComputeShader combo or what. I think there is, but this method works so I'll just be moving forward with it. Overall its a decent speedup, since it doesn't clear.

    Here's a before/after pic of the frame debugger for reference.

    Unity_0gkKVKrlte.png Unity_erihsXZ7MZ.png