Esempio n. 1
0
        protected void CheckBufferChanged(GPUBufferVariable <T> source)
        {
            if (this.hashData.objectBufferSorted == null || this.hashData.objectBufferSorted.Size != source.Size)
            {
                //use source as object buffer
                this.hashData.objectBuffer.InitBuffer(source);
                //create new buffer for sorted data
                this.hashData.objectBufferSorted.InitBuffer(source.Size);
                //create new buffer for object index
                this.hashData.objectGridIndexBuffer.InitBuffer(source.Size);

                this.dispatcher = new ComputeShaderDispatcher <Kernel>(this.gridCS);
                foreach (Kernel k in Enum.GetValues(typeof(Kernel)))
                {
                    this.dispatcher.AddParameter(k, this.gridData);
                    this.dispatcher.AddParameter(k, this.hashData);
                }
            }
            else
            {
                this.hashData.objectBuffer.UpdateBuffer(source);
            }

            var gs = this.gridData.gridSize;

            this.hashData.hashTableSize = gs.x * gs.y * gs.z;
        }
Esempio n. 2
0
        public void Sort(ref GPUBufferVariable <T> source)
        {
            LogTool.LogAssertIsTrue(Mathf.IsPowerOfTwo(source.Size), "num of source should be power of 2");
            LogTool.LogAssertIsTrue(source.Size >= BITONIC_BLOCK_SIZE * TRANSPOSE_BLOCK_SIZE, "source size must bigger than " + (BITONIC_BLOCK_SIZE * TRANSPOSE_BLOCK_SIZE));

            if (this.tempBuffer == null || this.tempBuffer.Size != source.Size)
            {
                this.tempBuffer.InitBuffer(source.Size);
            }
            ComputeShader sortCS = this.bitonicCS;

            int KERNEL_ID_BITONICSORT = sortCS.FindKernel("BitonicSort");
            int KERNEL_ID_TRANSPOSE   = sortCS.FindKernel("MatrixTranspose");

            uint NUM_ELEMENTS  = (uint)source.Size;
            uint MATRIX_WIDTH  = BITONIC_BLOCK_SIZE;
            uint MATRIX_HEIGHT = (uint)NUM_ELEMENTS / BITONIC_BLOCK_SIZE;

            for (uint level = 2; level <= BITONIC_BLOCK_SIZE; level <<= 1)
            {
                SetGPUSortConstants(sortCS, level, level, MATRIX_HEIGHT, MATRIX_WIDTH);

                // Sort the row data
                sortCS.SetBuffer(KERNEL_ID_BITONICSORT, "Data", source);
                sortCS.Dispatch(KERNEL_ID_BITONICSORT, (int)(NUM_ELEMENTS / BITONIC_BLOCK_SIZE), 1, 1);
            }

            // Then sort the rows and columns for the levels > than the block size
            // Transpose. Sort the Columns. Transpose. Sort the Rows.
            for (uint level = (BITONIC_BLOCK_SIZE << 1); level <= NUM_ELEMENTS; level <<= 1)
            {
                // Transpose the data from buffer 1 into buffer 2
                SetGPUSortConstants(sortCS, level / BITONIC_BLOCK_SIZE, (level & ~NUM_ELEMENTS) / BITONIC_BLOCK_SIZE, MATRIX_WIDTH, MATRIX_HEIGHT);
                sortCS.SetBuffer(KERNEL_ID_TRANSPOSE, "Input", source);
                sortCS.SetBuffer(KERNEL_ID_TRANSPOSE, "Data", tempBuffer);
                sortCS.Dispatch(KERNEL_ID_TRANSPOSE, (int)(MATRIX_WIDTH / TRANSPOSE_BLOCK_SIZE), (int)(MATRIX_HEIGHT / TRANSPOSE_BLOCK_SIZE), 1);

                // Sort the transposed column data
                sortCS.SetBuffer(KERNEL_ID_BITONICSORT, "Data", tempBuffer);
                sortCS.Dispatch(KERNEL_ID_BITONICSORT, (int)(NUM_ELEMENTS / BITONIC_BLOCK_SIZE), 1, 1);

                // Transpose the data from buffer 2 back into buffer 1
                SetGPUSortConstants(sortCS, BITONIC_BLOCK_SIZE, level, MATRIX_HEIGHT, MATRIX_WIDTH);
                sortCS.SetBuffer(KERNEL_ID_TRANSPOSE, "Input", tempBuffer);
                sortCS.SetBuffer(KERNEL_ID_TRANSPOSE, "Data", source);
                sortCS.Dispatch(KERNEL_ID_TRANSPOSE, (int)(MATRIX_HEIGHT / TRANSPOSE_BLOCK_SIZE), (int)(MATRIX_WIDTH / TRANSPOSE_BLOCK_SIZE), 1);

                // Sort the row data
                sortCS.SetBuffer(KERNEL_ID_BITONICSORT, "Data", source);
                sortCS.Dispatch(KERNEL_ID_BITONICSORT, (int)(NUM_ELEMENTS / BITONIC_BLOCK_SIZE), 1, 1);
            }
        }
Esempio n. 3
0
        public void BuildSortedParticleGridIndex(GPUBufferVariable <T> source, out GPUBufferVariable <T> sortedBuffer)
        {
            sortedBuffer = default;

            this.CheckBufferChanged(source);

            this.dispatcher.Dispatch(Kernel.BuildHash, source.Size);
            this.Sort.Sort(ref this.hashData.objectGridIndexBuffer);

            var s = this.gridData.gridSize;

            this.dispatcher.Dispatch(Kernel.ClearIndex, s.x, s.y, s.z);
            this.dispatcher.Dispatch(Kernel.BuildIndex, source.Size);
            this.dispatcher.Dispatch(Kernel.BuildSortedObject, source.Size);

            sortedBuffer = this.hashData.objectBufferSorted;
        }