Example #1
0
    public void Scan(ComputeBufferBase <int> buffer, int count)
    {
        uint gx, gy, gz;

        shader.GetKernelThreadGroupSizes(scanKernel, out gx, out gy, out gz);
        int numGroupsX = Mathf.CeilToInt((float)count / gx);

        shader.SetInt("count", count);
        shader.SetInt("lane_stride", LANE_STRIDE);
        shader.SetBuffer(scanKernel, "data", buffer.Buffer);
        shader.Dispatch(scanKernel, numGroupsX, 1, 1);

        // If we can't complete the scan within a single group.
        if (count > LANE_STRIDE * gx)
        {
            using (var groupData = new StructuredBuffer <int>((int)gx)) {
                shader.SetBuffer(scanGroupResultsKernel, "data", buffer.Buffer);
                shader.SetBuffer(scanGroupResultsKernel, "group_data", groupData.Buffer);
                shader.Dispatch(scanGroupResultsKernel, 1, 1, 1);

                shader.SetBuffer(addGroupResultsKernel, "data", buffer.Buffer);
                shader.SetBuffer(addGroupResultsKernel, "group_data", groupData.Buffer);
                shader.Dispatch(addGroupResultsKernel, numGroupsX, 1, 1);
            }
        }

        shader.SetBuffer(inclusiveToExclusiveKernel, "data", buffer.Buffer);
        shader.Dispatch(inclusiveToExclusiveKernel, 1, 1, 1);
    }
Example #2
0
    private void SortPow2(ComputeBufferBase <int> buffer, int count)
    {
        uint gx, gy, gz;

        shader.GetKernelThreadGroupSizes(sortKernel, out gx, out gy, out gz);
        int numGroupsX = Mathf.CeilToInt((count * 0.5f) / gx);

        shader.SetInt("count", count);
        shader.SetBuffer(sortKernel, "data", buffer.Buffer);
        shader.SetBuffer(sortSingleLevelKernel, "data", buffer.Buffer);

        int n = (int)Mathf.Pow(2, Mathf.Ceil(Mathf.Log(count, 2)));

        for (int i = 2; i <= n; i *= 2)
        {
            shader.SetInt("level", i);

            // For phases where the # of required pairwise comparisons exceeds
            // the groupsize, we need to do separate dispatches to synchronize
            // writes across work groups.
            for (int j = i / 2; j > gx; j /= 2)
            {
                shader.SetInt("single_level", j);
                shader.Dispatch(sortSingleLevelKernel, numGroupsX, 1, 1);
            }
            shader.Dispatch(sortKernel, numGroupsX, 1, 1);
        }
    }
Example #3
0
    public void Remove(ComputeBufferBase <int> values, ComputeBufferBase <int> results)
    {
        uint gx, gy, gz;

        shader.GetKernelThreadGroupSizes(removeKernel, out gx, out gy, out gz);
        int numGroupsX = Mathf.CeilToInt((float)values.Count / gx);

        BindHashSetCommon(removeKernel);
        BindKernelsCommon(removeKernel, values, results);
        shader.Dispatch(removeKernel, numGroupsX, 1, 1);
    }
Example #4
0
    private void CopyToOriginalBuffer(StructuredBuffer <int> copy, ComputeBufferBase <int> original, int count)
    {
        uint gx, gy, gz;

        shader.GetKernelThreadGroupSizes(copyBackKernel, out gx, out gy, out gz);
        int numGroupsX = Mathf.CeilToInt((float)count / gx);

        shader.SetInt("count", count);
        shader.SetBuffer(copyBackKernel, "data", original.Buffer);
        shader.SetBuffer(copyBackKernel, "copy", copy.Buffer);
        shader.Dispatch(copyBackKernel, numGroupsX, 1, 1);
    }
Example #5
0
 public void Sort(ComputeBufferBase <int> buffer, int count = 0)
 {
     if (Mathf.IsPowerOfTwo(count))
     {
         SortPow2(buffer, count);
     }
     else
     {
         using (var copy = CopyToPow2Buffer(buffer, count)) {
             SortPow2(copy, copy.Count);
             CopyToOriginalBuffer(copy, buffer, count);
         }
     }
 }
Example #6
0
    private StructuredBuffer <int> CopyToPow2Buffer(ComputeBufferBase <int> buffer, int count)
    {
        int n = (int)Mathf.Pow(2, Mathf.Ceil(Mathf.Log(count, 2)));
        StructuredBuffer <int> copy = new StructuredBuffer <int>(n);

        uint gx, gy, gz;

        shader.GetKernelThreadGroupSizes(copyAndFillKernel, out gx, out gy, out gz);
        int numGroupsX = Mathf.CeilToInt((float)n / gx);

        shader.SetInt("buffer_length", n);
        shader.SetInt("count", count);
        shader.SetBuffer(copyAndFillKernel, "data", buffer.Buffer);
        shader.SetBuffer(copyAndFillKernel, "copy", copy.Buffer);
        shader.Dispatch(copyAndFillKernel, numGroupsX, 1, 1);

        return(copy);
    }
Example #7
0
    public void Compact(ComputeBufferBase <int> buffer, ComputeBufferBase <int> keys, int count)
    {
        var scan = new NaiveScan();

        scan.Scan(keys, count);

        uint gx, gy, gz;

        shader.GetKernelThreadGroupSizes(compactKernel, out gx, out gy, out gz);
        int numGroupsX = Mathf.CeilToInt((float)count / gx);

        using (var tmp = new StructuredBuffer <int>(count)) {
            shader.SetInt("count", count);

            shader.SetBuffer(compactKernel, "data", buffer.Buffer);
            shader.SetBuffer(compactKernel, "output", tmp.Buffer);
            shader.SetBuffer(compactKernel, "keys", keys.Buffer);
            shader.Dispatch(compactKernel, numGroupsX, 1, 1);

            shader.SetBuffer(copyBackKernel, "data", tmp.Buffer);
            shader.SetBuffer(copyBackKernel, "output", buffer.Buffer);
            shader.Dispatch(copyBackKernel, numGroupsX, 1, 1);
        }
    }
Example #8
0
 public void ScanIndirect(ComputeBufferBase <int> buffer, ComputeBufferBase <uint> count)
 {
     throw new NotImplementedException();
 }
Example #9
0
 private void BindKernelsCommon(int kernel, ComputeBufferBase <int> values, ComputeBufferBase <int> results)
 {
     shader.SetInt("count", values.Count);
     shader.SetBuffer(kernel, "input", values.Buffer);
     shader.SetBuffer(kernel, "results", results.Buffer);
 }