title: HLSL: How to return one number from compute shader?
body: <p>I try to implement MarchingCubes algorithm on compute shader so I need to know actual number of generated triangles. I use Unreal Engine 4 and HLSL (Shader Model 5)
  How can I get back one single uint from shader?</p>
  
  <p>I tried to generate RWStructuredBuffer with one variable and increment it with InterlockedAdd but it always returns 0 (the triangles buffer works fine).</p>
  
  <p>Here is my code:</p>
  
  <p>Initialization and reading in UE:</p>
  
  <pre><code>struct FVertex
  {
      FVector position;
      FVector normal;
  };
  
  struct FTriangle
  {
      FVertex vertices[3];
  };
  
  void MeshGeneratorShaderHelper::Initialize(const float voxel_size_mm, const size_t slices, const size_t rows, const size_t columns, const size_t cube_size)
  {
      _constantParameters.voxel_size_mm = voxel_size_mm;
      _constantParameters.slices = slices;
      _constantParameters.rows = rows;
      _constantParameters.columns = columns;
      _constantParameters.cube_size = cube_size;
      _constantParameters.threshold = 0.95;
  
  
      // Setup buffers
      if (shaderOutDataBuffer != NULL)
      {
          shaderOutDataBuffer.SafeRelease();
      }
      // This is not very fine numbers
      size_t number_of_triangles = slices*rows;
      number_of_triangles = FMath::Min(10*(size_t)DEF_SIZE_VERT, number_of_triangles); 
      // Now init actual output of shader
      _meshData.Init(FTriangle(), number_of_triangles);
      TResourceArray&lt;FTriangle&gt; bufferData;
      bufferData.Init(FTriangle(), number_of_triangles);
      bufferData.SetAllowCPUAccess(true);
      FRHIResourceCreateInfo createInfo;
      createInfo.ResourceArray = &amp;bufferData;
  
      // This is FStructuredBufferRHIRef and FUnorderedAccessViewRHIRef
      shaderOutDataBuffer = RHICreateStructuredBuffer(sizeof(FTriangle), sizeof(FTriangle) * number_of_triangles, BUF_UnorderedAccess | BUF_ShaderResource, createInfo);
      shaderOutDataBufferUAV = RHICreateUnorderedAccessView(shaderOutDataBuffer, true, false);
  
      // This is one element buffer for intanced triangles number
      if (sizeOutBuffer != NULL)
      {
          sizeOutBuffer.SafeRelease();
      }
      TResourceArray&lt;uint32&gt; bufferData2;
      bufferData2.Init(0, 1);
      bufferData2.SetAllowCPUAccess(true);
      FRHIResourceCreateInfo sizeCreateInfo;
      sizeCreateInfo.ResourceArray = &amp;bufferData2;
      sizeOutBuffer = RHICreateStructuredBuffer(sizeof(uint32), sizeof(uint32), BUF_UnorderedAccess | BUF_ShaderResource, sizeCreateInfo);
      sizeOutBufferUAV = RHICreateUnorderedAccessView(sizeOutBuffer, true, false);
  
      // This is buffer for voxel input of shader
      if (voxelData != NULL)
      {
          voxelData.SafeRelease();
      }
      TResourceArray&lt;float&gt; bufferDataV;
      bufferDataV.Init(float(), columns*rows*slices);
      bufferDataV.SetAllowCPUAccess(true);
  
      FRHIResourceCreateInfo CreateInfoVoxel;
      CreateInfoVoxel.ResourceArray = &amp;bufferDataV;
      voxelData = RHICreateStructuredBuffer(sizeof(float),
          columns*rows*slices *sizeof(float),
          EBufferUsageFlags::BUF_UnorderedAccess | BUF_ShaderResource,
          CreateInfoVoxel
      );
      voxelDataUAV = RHICreateUnorderedAccessView(voxelData, true, false);
  }
  
  void MeshGeneratorShaderHelper::RetrieveDataInternal()
  {
      check(IsInRenderingThread());
  
      // Try to get number of triangles, always get 0
      uint32 total_size;
      uint8* srcPtr = (uint8*)RHILockStructuredBuffer(sizeOutBuffer, 0, sizeof(uint32), EResourceLockMode::RLM_ReadOnly);
      FMemory::Memcpy((uint8*)(&amp;total_size), srcPtr, sizeof(uint32));
      RHIUnlockStructuredBuffer(sizeOutBuffer);
  
      if (total_size == 0)
      {
          _meshData.Empty();
          result_size = total_size;
          //return;
          total_size = DEF_SIZE_VERT;
      }
  
      // This works fine
      _meshData.Init(FTriangle{ {FVector{-5,-5,-5}, FVector {-5,-5,-5}, FVector {-5,-5,-5}} }, total_size);
  
      srcPtr = (uint8*)RHILockStructuredBuffer(shaderOutDataBuffer, 0, sizeof(FTriangle) * total_size, EResourceLockMode::RLM_ReadOnly);
      // Reference pointer to first element for our destination ComputedColors
      uint8* dstPtr = (uint8*)_meshData.GetData();
      // Copy from GPU to main memory
      FMemory::Memcpy(dstPtr, srcPtr, sizeof(FTriangle) * total_size);
      //Unlock texture
      RHIUnlockStructuredBuffer(shaderOutDataBuffer);
  }
  </code></pre>
  
  <p>Shader code:</p>
  
  <pre><code>StructuredBuffer&lt;float&gt; DensityTexture; // voxel data
  
  struct Vertex
  {
      float3 Position;
      float3 Normal;
  };
  
  struct Triangle
  {
      Vertex vertices[3];
  };
  
  AppendStructuredBuffer&lt;Triangle&gt; MeshData; // this need to be counted
  RWStructuredBuffer&lt;uint&gt; ResultSize; // This is one num buffer
  
  ...
  
  [numthreads(SIMULATION_BLOCK_SIZE, 1, 1)]
  void MarchingCubes(
      uint3 Gid : SV_GroupID,
      uint3 DTid : SV_DispatchThreadID,
      uint3 GTid : SV_GroupThreadID,
      uint GI : SV_GroupIndex )
  {
     ...
     for(uint i = 0; i&lt;numVertsTable[cube_index]; i+=3)
          {
              Vertex vertices[3];
              for (uint j = 0; j&lt;3; ++j)
              {
                  Vertex v;
                  float3 Position = vertlist[triTable[cube_index][i + j]];
                  v.Normal = normalize(CalculateGradient(Position));
                  v.Position = Position;
                  vertices[j] = v;
              }
  
              Triangle t;
              t.vertices[0] = vertices[0];
              t.vertices[1] = vertices[1];
              t.vertices[2] = vertices[2];
              MeshData.Append(t);
              InterlockedAdd(ResultSize[0], 1); // Here I want to count data
          }
  }
  </code></pre>