public void Scan( ref ComputeBuffer cb_in, ref ComputeBuffer cb_out, int dataSize, int recurseNum = 0 ) { Profiler.BeginSample("BlellochSumScan"); int blellochGridSize = _gridSizes[recurseNum]; ComputeBuffer cb_sumScanBlockSum = cb_sumScanBlockSums[recurseNum]; ComputeShaderUtil.ZeroOut(ref cb_sumScanBlockSum, blellochGridSize); // sum scan data allocated to each block cs_blellochSumScan.SetInt(PropertyID.len, dataSize); cs_blellochSumScan.SetBuffer(kn_preSumScan, BufferID.cb_out, cb_out); cs_blellochSumScan.SetBuffer(kn_preSumScan, BufferID.cb_in, cb_in); cs_blellochSumScan.SetBuffer(kn_preSumScan, BufferID.cb_blockSums, cb_sumScanBlockSum); cs_blellochSumScan.Dispatch(kn_preSumScan, blellochGridSize, 1, 1); // sum scan total sums produced by each block // use basic implementation if number of total sums is <= 2 * Graphics.M_BLOCK_SZ // (this requires only one block to do the scan) if (blellochGridSize <= Graphics.S_BLOCK_SZ) { ComputeShaderUtil.ZeroOut(ref cb_dummyGrpSums, 1); ComputeBuffer cb_preSumScanTemp = cb_preSumScanTemps[recurseNum]; ComputeShaderUtil.CopyBuffer(ref cb_sumScanBlockSum, ref cb_preSumScanTemp, blellochGridSize); cs_blellochSumScan.SetInt(PropertyID.len, blellochGridSize); cs_blellochSumScan.SetBuffer(kn_preSumScan, BufferID.cb_out, cb_sumScanBlockSum); cs_blellochSumScan.SetBuffer(kn_preSumScan, BufferID.cb_in, cb_preSumScanTemp); cs_blellochSumScan.SetBuffer(kn_preSumScan, BufferID.cb_blockSums, cb_dummyGrpSums); cs_blellochSumScan.Dispatch(kn_preSumScan, 1, 1, 1); } else // else, recurse on this same function as you'll need the full-blown scan for the block sums { ComputeBuffer cb_inBlockSum = cb_inBlockSums[recurseNum]; ComputeShaderUtil.CopyBuffer(ref cb_sumScanBlockSum, ref cb_inBlockSum, blellochGridSize); Scan(ref cb_inBlockSum, ref cb_sumScanBlockSum, blellochGridSize, recurseNum + 1); } ComputeBuffer cb_addBlockSumsTemp = cb_addBlockSumsTemps[recurseNum]; ComputeShaderUtil.CopyBuffer(ref cb_out, ref cb_addBlockSumsTemp, dataSize); // add each block's total sum to its scan output in order to get the final, global scanned array cs_blellochSumScan.SetInt(PropertyID.len, dataSize); cs_blellochSumScan.SetBuffer(kn_addBlockSums, BufferID.cb_out, cb_out); cs_blellochSumScan.SetBuffer(kn_addBlockSums, BufferID.cb_in, cb_addBlockSumsTemp); cs_blellochSumScan.SetBuffer(kn_addBlockSums, BufferID.cb_blockSums, cb_sumScanBlockSum); cs_blellochSumScan.Dispatch(kn_addBlockSums, blellochGridSize, 1, 1); Profiler.EndSample(); }
public void Scan(ref ComputeBuffer cb_in) { Profiler.BeginSample("HillisSteeleSumScan"); cs_hillisSteeleSumScan.SetInt(PropertyID.len, _dataSize); cs_hillisSteeleSumScan.SetBuffer(kn_hillisSteeleSumScan, BufferID.cb_in, cb_in); cs_hillisSteeleSumScan.SetBuffer(kn_hillisSteeleSumScan, BufferID.cb_prev, cb_prev); for (int offset = 1; offset < _dataSize; offset <<= 1) { ComputeShaderUtil.CopyBuffer(ref cb_in, ref cb_prev, _dataSize); cs_hillisSteeleSumScan.SetInt(PropertyID.offset, offset); cs_hillisSteeleSumScan.Dispatch(kn_hillisSteeleSumScan, _gridSize, 1, 1); } Profiler.EndSample(); }