示例#1
0
        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();
        }
示例#2
0
        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();
        }