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); }
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); } }
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); }
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); }
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); } } }
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); }
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); } }
public void ScanIndirect(ComputeBufferBase <int> buffer, ComputeBufferBase <uint> count) { throw new NotImplementedException(); }
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); }