├── .gitignore ├── GPUBitonicSort ├── Assets │ ├── BitonicSortCS.meta │ ├── BitonicSortCS │ │ ├── BitonicSort.compute │ │ ├── BitonicSort.compute.meta │ │ ├── BitonicSortCS.cs │ │ ├── BitonicSortCS.cs.meta │ │ ├── BitonicSortCS.unity │ │ └── BitonicSortCS.unity.meta │ ├── BitonicSortRT.meta │ └── BitonicSortRT │ │ ├── BitonicSort.shader │ │ ├── BitonicSort.shader.meta │ │ ├── BitonicSortRT.cs │ │ ├── BitonicSortRT.cs.meta │ │ ├── BitonicSortRT.unity │ │ └── BitonicSortRT.unity.meta └── ProjectSettings │ ├── AudioManager.asset │ ├── ClusterInputManager.asset │ ├── DynamicsManager.asset │ ├── EditorBuildSettings.asset │ ├── EditorSettings.asset │ ├── GraphicsSettings.asset │ ├── InputManager.asset │ ├── NavMeshAreas.asset │ ├── NetworkManager.asset │ ├── Physics2DSettings.asset │ ├── ProjectSettings.asset │ ├── ProjectVersion.txt │ ├── QualitySettings.asset │ ├── TagManager.asset │ ├── TimeManager.asset │ ├── UnityAdsSettings.asset │ └── UnityConnectSettings.asset ├── LICENSE ├── README.md └── bitonicsort_image.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | /GPUBitonicSort/[Ll]ibrary/ 2 | /GPUBitonicSort/[Tt]emp/ 3 | /GPUBitonicSort/[Oo]bj/ 4 | /GPUBitonicSort/[Bb]uild/ 5 | /GPUBitonicSort/[Bb]uilds/ 6 | /GPUBitonicSort/Assets/AssetStoreTools* 7 | 8 | # Autogenerated VS/MD solution and project files 9 | ExportedObj/ 10 | *.csproj 11 | *.unityproj 12 | *.sln 13 | *.suo 14 | *.tmp 15 | *.user 16 | *.userprefs 17 | *.pidb 18 | *.booproj 19 | *.svd 20 | 21 | 22 | # Unity3D generated meta files 23 | *.pidb.meta 24 | 25 | # Unity3D Generated File On Crash Reports 26 | sysinfo.txt 27 | 28 | # Builds 29 | *.apk 30 | *.unitypackage 31 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortCS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 757a808be04a88b40b8a497ead251c3e 3 | folderAsset: yes 4 | timeCreated: 1474534365 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortCS/BitonicSort.compute: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // BitonicSort.compute 3 | // 4 | //-------------------------------------------------------------------------------------- 5 | 6 | //-------------------------------------------------------------------------------------- 7 | // Pragmas 8 | //-------------------------------------------------------------------------------------- 9 | 10 | #pragma kernel BitonicSort 11 | #pragma kernel MatrixTranspose 12 | 13 | //-------------------------------------------------------------------------------------- 14 | // Constants 15 | //-------------------------------------------------------------------------------------- 16 | 17 | #define BITONIC_BLOCK_SIZE 512 18 | #define TRANSPOSE_BLOCK_SIZE 16 19 | 20 | //-------------------------------------------------------------------------------------- 21 | // Constant Buffers 22 | //-------------------------------------------------------------------------------------- 23 | cbuffer CB 24 | { 25 | uint _Level; 26 | uint _LevelMask; 27 | uint _Width; 28 | uint _Height; 29 | }; 30 | 31 | //-------------------------------------------------------------------------------------- 32 | // Structured Buffers 33 | //-------------------------------------------------------------------------------------- 34 | StructuredBuffer Input : register(t0); 35 | RWStructuredBuffer Data : register(u0); 36 | 37 | //-------------------------------------------------------------------------------------- 38 | // Bitonic Sort Compute Shader 39 | //-------------------------------------------------------------------------------------- 40 | groupshared uint shared_data[BITONIC_BLOCK_SIZE]; 41 | 42 | [numthreads(BITONIC_BLOCK_SIZE, 1, 1)] 43 | void BitonicSort(uint3 Gid : SV_GroupID, 44 | uint3 DTid : SV_DispatchThreadID, 45 | uint3 GTid : SV_GroupThreadID, 46 | uint GI : SV_GroupIndex) 47 | { 48 | // Load shared data 49 | shared_data[GI] = Data[DTid.x]; 50 | GroupMemoryBarrierWithGroupSync(); 51 | 52 | // Sort the shared data 53 | for (uint j = _Level >> 1; j > 0; j >>= 1) 54 | { 55 | uint result = ((shared_data[GI & ~j] <= shared_data[GI | j]) == (bool)(_LevelMask & DTid.x)) ? shared_data[GI ^ j] : shared_data[GI]; 56 | GroupMemoryBarrierWithGroupSync(); 57 | shared_data[GI] = result; 58 | GroupMemoryBarrierWithGroupSync(); 59 | } 60 | 61 | // Store shared data 62 | Data[DTid.x] = shared_data[GI]; 63 | } 64 | 65 | //-------------------------------------------------------------------------------------- 66 | // Matrix Transpose Compute Shader 67 | //-------------------------------------------------------------------------------------- 68 | groupshared uint transpose_shared_data[TRANSPOSE_BLOCK_SIZE * TRANSPOSE_BLOCK_SIZE]; 69 | 70 | [numthreads(TRANSPOSE_BLOCK_SIZE, TRANSPOSE_BLOCK_SIZE, 1)] 71 | void MatrixTranspose(uint3 Gid : SV_GroupID, 72 | uint3 DTid : SV_DispatchThreadID, 73 | uint3 GTid : SV_GroupThreadID, 74 | uint GI : SV_GroupIndex) 75 | { 76 | transpose_shared_data[GI] = Input[DTid.y * _Width + DTid.x]; 77 | GroupMemoryBarrierWithGroupSync(); 78 | uint2 XY = DTid.yx - GTid.yx + GTid.xy; 79 | Data[XY.y * _Height + XY.x] = transpose_shared_data[GTid.x * TRANSPOSE_BLOCK_SIZE + GTid.y]; 80 | } 81 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortCS/BitonicSort.compute.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae617921b866670408b7514a91b540a0 3 | timeCreated: 1474538555 4 | licenseType: Pro 5 | ComputeShaderImporter: 6 | currentAPIMask: 4 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortCS/BitonicSortCS.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Runtime.InteropServices; 4 | 5 | public class BitonicSortCS : MonoBehaviour 6 | { 7 | public ComputeShader BitonicSortShader; 8 | 9 | const int BUFFER_SIZE = 2048; 10 | 11 | const uint BITONIC_BLOCK_SIZE = 512; 12 | const uint TRANSPOSE_BLOCK_SIZE = 16; 13 | 14 | const int KERNEL_ID_BITONICSORT = 0; 15 | const int KERNEL_ID_TRANSPOSE_MATRIX = 1; 16 | 17 | ComputeBuffer _inBuffer; 18 | ComputeBuffer _tempBuffer; 19 | 20 | void Start() 21 | { 22 | Debug.Log("1 key :Sort, 2 key : Reset"); 23 | 24 | Init(); 25 | } 26 | 27 | void Update() 28 | { 29 | if(Input.GetKeyUp("1")) 30 | { 31 | // Sort 32 | GPUSort(_inBuffer, _tempBuffer); 33 | ShowValuesOnConsole(_inBuffer, "sorted : "); 34 | } 35 | 36 | if (Input.GetKeyUp("2")) 37 | { 38 | // Reset 39 | Reset(); 40 | } 41 | } 42 | 43 | void Init() 44 | { 45 | _inBuffer = new ComputeBuffer(BUFFER_SIZE, Marshal.SizeOf(typeof(uint))); 46 | _tempBuffer = new ComputeBuffer(BUFFER_SIZE, Marshal.SizeOf(typeof(uint))); 47 | 48 | Reset(); 49 | } 50 | 51 | void Reset() 52 | { 53 | uint[] data = new uint[BUFFER_SIZE]; 54 | for (var i = 0; i < data.Length; i++) 55 | { 56 | data[i] = (uint)(Random.Range(0, BUFFER_SIZE)); 57 | } 58 | 59 | _inBuffer.SetData(data); 60 | _tempBuffer.SetData(data); 61 | 62 | ShowValuesOnConsole(_inBuffer, "No sort : "); 63 | } 64 | 65 | void GPUSort(ComputeBuffer inBuffer, ComputeBuffer tempBuffer) 66 | { 67 | ComputeShader shader = BitonicSortShader; 68 | // Determine parameters. 69 | uint NUM_ELEMENTS = (uint)BUFFER_SIZE; 70 | uint MATRIX_WIDTH = BITONIC_BLOCK_SIZE; 71 | uint MATRIX_HEIGHT = (uint)NUM_ELEMENTS / BITONIC_BLOCK_SIZE; 72 | 73 | // Sort the data 74 | // First sort the rows for the levels <= to the block size 75 | for (uint level = 2; level <= BITONIC_BLOCK_SIZE; level <<= 1) 76 | { 77 | SetGPUSortConstants(shader, level, level, MATRIX_HEIGHT, MATRIX_WIDTH); 78 | 79 | // Sort the row data 80 | shader.SetBuffer(KERNEL_ID_BITONICSORT, "Data", inBuffer); 81 | shader.Dispatch(KERNEL_ID_BITONICSORT, (int)(NUM_ELEMENTS / BITONIC_BLOCK_SIZE), 1, 1); 82 | } 83 | 84 | // Then sort the rows and columns for the levels > than the block size 85 | // Transpose. Sort the Columns. Transpose. Sort the Rows. 86 | for (uint level = (BITONIC_BLOCK_SIZE << 1); level <= NUM_ELEMENTS; level <<= 1) 87 | { 88 | // Transpose the data from buffer 1 into buffer 2 89 | SetGPUSortConstants(shader, (level / BITONIC_BLOCK_SIZE), (level & ~NUM_ELEMENTS) / BITONIC_BLOCK_SIZE, MATRIX_WIDTH, MATRIX_HEIGHT); 90 | shader.SetBuffer(KERNEL_ID_TRANSPOSE_MATRIX, "Input", inBuffer); 91 | shader.SetBuffer(KERNEL_ID_TRANSPOSE_MATRIX, "Data", tempBuffer); 92 | shader.Dispatch(KERNEL_ID_TRANSPOSE_MATRIX, (int)(MATRIX_WIDTH / TRANSPOSE_BLOCK_SIZE), (int)(MATRIX_HEIGHT / TRANSPOSE_BLOCK_SIZE), 1); 93 | 94 | // Sort the transposed column data 95 | shader.SetBuffer(KERNEL_ID_BITONICSORT, "Data", tempBuffer); 96 | shader.Dispatch(KERNEL_ID_BITONICSORT, (int)(NUM_ELEMENTS / BITONIC_BLOCK_SIZE), 1, 1); 97 | 98 | // Transpose the data from buffer 2 back into buffer 1 99 | SetGPUSortConstants(shader, BITONIC_BLOCK_SIZE, level, MATRIX_HEIGHT, MATRIX_WIDTH); 100 | shader.SetBuffer(KERNEL_ID_TRANSPOSE_MATRIX, "Input", tempBuffer); 101 | shader.SetBuffer(KERNEL_ID_TRANSPOSE_MATRIX, "Data", inBuffer); 102 | shader.Dispatch(KERNEL_ID_TRANSPOSE_MATRIX, (int)(MATRIX_HEIGHT / TRANSPOSE_BLOCK_SIZE), (int)(MATRIX_WIDTH / TRANSPOSE_BLOCK_SIZE), 1); 103 | 104 | // Sort the row data 105 | shader.SetBuffer(KERNEL_ID_BITONICSORT, "Data", inBuffer); 106 | shader.Dispatch(KERNEL_ID_BITONICSORT, (int)(NUM_ELEMENTS / BITONIC_BLOCK_SIZE), 1, 1); 107 | } 108 | } 109 | 110 | void SetGPUSortConstants(ComputeShader cs, uint level, uint levelMask, uint width, uint height) 111 | { 112 | cs.SetInt("_Level", (int)level ); 113 | cs.SetInt("_LevelMask", (int)levelMask); 114 | cs.SetInt("_Width", (int)width ); 115 | cs.SetInt("_Height", (int)height ); 116 | } 117 | 118 | void ShowValuesOnConsole(ComputeBuffer buffer, string label) 119 | { 120 | if (buffer == null || buffer.count == 0) return; 121 | var values = ""; 122 | var data = new uint[buffer.count]; 123 | buffer.GetData(data); 124 | for (var i = 0; i < data.Length; i++) 125 | { 126 | values += data[i] + " "; 127 | } 128 | Debug.Log(label + values); 129 | } 130 | 131 | void OnDestroy() 132 | { 133 | if(_inBuffer != null) 134 | { 135 | _inBuffer.Release(); 136 | } 137 | _inBuffer = null; 138 | 139 | if(_tempBuffer != null) 140 | { 141 | _tempBuffer.Release(); 142 | } 143 | _tempBuffer = null; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortCS/BitonicSortCS.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d0222eb51169d234c984a6aa9fbd9c5d 3 | timeCreated: 1474538892 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: 8 | - BitonicSortShader: {fileID: 7200000, guid: ae617921b866670408b7514a91b540a0, type: 3} 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortCS/BitonicSortCS.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/Assets/BitonicSortCS/BitonicSortCS.unity -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortCS/BitonicSortCS.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a1de8c0bc17fd324cb3694ea7958d8dc 3 | timeCreated: 1474540944 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortRT.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49437e4adc5be3d40ab868f6d22bceb2 3 | folderAsset: yes 4 | timeCreated: 1474534366 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortRT/BitonicSort.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/BitonicSort" 2 | { 3 | Properties 4 | { 5 | _MainTex("Texture", 2D) = "white" {} 6 | } 7 | 8 | CGINCLUDE 9 | #include "UnityCG.cginc" 10 | 11 | 12 | sampler2D _MainTex; 13 | float4 _MainTex_ST; 14 | 15 | float4 _TextureSize; 16 | float _SortBlockSize; 17 | float _SortSize; 18 | float _Offset; 19 | 20 | float2 convert1dto2d(float index) 21 | { 22 | float2 dst; 23 | 24 | dst.x = fmod(index, _TextureSize.x) / _TextureSize.x; 25 | dst.y = floor(index / _TextureSize.x) / _TextureSize.y; 26 | 27 | return dst; 28 | } 29 | 30 | 31 | float4 frag(v2f_img i) : SV_Target 32 | { 33 | float4 dst = (float4)0; 34 | 35 | float2 index2d = _TextureSize.xy * i.uv.xy; 36 | index2d = floor(index2d); 37 | 38 | float index1d = index2d.y * _TextureSize.x + index2d.x; 39 | 40 | float csign = (fmod(index1d, _SortBlockSize) < _Offset) ? 1 : -1; 41 | float cdir = (fmod(floor(index1d / _SortSize), 2.0) <= 0.5) ? 1 : -1; 42 | 43 | float4 val0 = tex2D(_MainTex, i.uv.xy); 44 | 45 | float adr1d = csign * _Offset + index1d; 46 | float2 adr2d = convert1dto2d(adr1d); 47 | float4 val1 = tex2D(_MainTex, adr2d); 48 | 49 | // a成分をソートのキーとして使用 50 | float4 cmin = (val0.a < val1.a) ? val0 : val1; 51 | float4 cmax = (val0.a < val1.a) ? val1 : val0; 52 | dst = (csign == cdir) ? cmin : cmax; 53 | 54 | return dst; 55 | } 56 | ENDCG 57 | 58 | SubShader 59 | { 60 | Tags{ "RenderType" = "Opaque" } 61 | LOD 100 62 | 63 | Pass 64 | { 65 | CGPROGRAM 66 | #pragma vertex vert_img 67 | #pragma fragment frag 68 | ENDCG 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortRT/BitonicSort.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf738e3163b80d14d9e4521f002927a9 3 | timeCreated: 1474534513 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortRT/BitonicSortRT.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class BitonicSortRT : MonoBehaviour 5 | { 6 | public Shader BitonicSortShader; 7 | 8 | Material _bitonicSortMat; 9 | 10 | Texture2D _seedTex; 11 | 12 | RenderTexture _sortBuffer; 13 | RenderTexture _sortTempBuffer; 14 | 15 | const int TEXTURE_WIDTH = 512; 16 | const int TEXTURE_HEIGHT = 512; 17 | 18 | int _logSize = 0; 19 | int _sortCount = 0; 20 | int _maxCountNeedToSort = 0; 21 | 22 | void Start() 23 | { 24 | Init(); 25 | 26 | Debug.Log("1 key :Sort one by one , 2 key : Sort at once, 3 key : Reset"); 27 | } 28 | 29 | void Update() 30 | { 31 | if (Input.GetKeyUp("1")) 32 | { 33 | GPUSortOneByOne(); 34 | } 35 | 36 | if (Input.GetKeyUp("2")) 37 | { 38 | GPUSort(); 39 | } 40 | 41 | if (Input.GetKeyUp("3")) 42 | { 43 | Reset(); 44 | } 45 | } 46 | 47 | void Init() 48 | { 49 | if (_bitonicSortMat == null) 50 | { 51 | _bitonicSortMat = new Material(BitonicSortShader); 52 | _bitonicSortMat.hideFlags = HideFlags.HideAndDontSave; 53 | } 54 | 55 | _logSize = Mathf.FloorToInt(Mathf.Log(TEXTURE_WIDTH * TEXTURE_HEIGHT, 2.0f)); 56 | _maxCountNeedToSort = Mathf.FloorToInt(_logSize * (_logSize + 1) / (float)2); 57 | 58 | // Create Seed Texture 59 | _seedTex = new Texture2D(TEXTURE_WIDTH, TEXTURE_HEIGHT, TextureFormat.RGBAFloat, false); 60 | _seedTex.filterMode = FilterMode.Point; 61 | _seedTex.wrapMode = TextureWrapMode.Clamp; 62 | _seedTex.hideFlags = HideFlags.HideAndDontSave; 63 | for (var x = 0; x < TEXTURE_WIDTH; x++) 64 | { 65 | for (var y = 0; y < TEXTURE_HEIGHT; y++) 66 | { 67 | var col = new Color(x / (float)TEXTURE_WIDTH, y / (float)TEXTURE_HEIGHT, 0.5f, Random.value); 68 | _seedTex.SetPixel(x, y, col); 69 | } 70 | } 71 | _seedTex.Apply(); 72 | 73 | // Create Sorted Buffer 74 | _sortBuffer = new RenderTexture(TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, RenderTextureFormat.ARGBFloat); 75 | _sortBuffer.filterMode = FilterMode.Point; 76 | _sortBuffer.wrapMode = TextureWrapMode.Clamp; 77 | _sortBuffer.hideFlags = HideFlags.HideAndDontSave; 78 | _sortTempBuffer = new RenderTexture(TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, RenderTextureFormat.ARGBFloat); 79 | _sortTempBuffer.filterMode = FilterMode.Point; 80 | _sortTempBuffer.wrapMode = TextureWrapMode.Clamp; 81 | _sortTempBuffer.hideFlags = HideFlags.HideAndDontSave; 82 | 83 | Graphics.Blit(_seedTex, _sortBuffer); 84 | Graphics.Blit(_seedTex, _sortTempBuffer); 85 | } 86 | 87 | void Reset() 88 | { 89 | for (var x = 0; x < TEXTURE_WIDTH; x++) 90 | { 91 | for (var y = 0; y < TEXTURE_HEIGHT; y++) 92 | { 93 | var col = new Color(x / (float)TEXTURE_WIDTH, y / (float)TEXTURE_HEIGHT, 0.5f, Random.value); 94 | _seedTex.SetPixel(x, y, col); 95 | } 96 | } 97 | _seedTex.Apply(); 98 | 99 | Graphics.Blit(_seedTex, _sortBuffer); 100 | Graphics.Blit(_seedTex, _sortTempBuffer); 101 | 102 | _sortCount = 0; 103 | } 104 | 105 | /// 106 | /// 一度にソート 107 | /// 108 | void GPUSort() 109 | { 110 | 111 | for (var i = 0; i < _maxCountNeedToSort; i++) 112 | { 113 | int step = i; 114 | int rank; 115 | for (rank = 0; rank < step; rank++) 116 | { 117 | step -= rank + 1; 118 | } 119 | 120 | float stepno = (float)(1 << (rank + 1)); 121 | float offset = (float)(1 << (rank - step)); 122 | float stage = 2 * offset; 123 | 124 | _bitonicSortMat.SetFloat("_SortBlockSize", stage); 125 | _bitonicSortMat.SetFloat("_SortSize", stepno); 126 | _bitonicSortMat.SetFloat("_Offset", offset); 127 | _bitonicSortMat.SetVector("_TextureSize", new Vector4(TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, 0)); 128 | Graphics.Blit(_sortBuffer, _sortTempBuffer, _bitonicSortMat); 129 | SwapBuffer(ref _sortBuffer, ref _sortTempBuffer); 130 | 131 | } 132 | 133 | Debug.Log("Sort"); 134 | } 135 | 136 | /// 137 | /// 順次ソート 138 | /// 139 | void GPUSortOneByOne() 140 | { 141 | 142 | int step = _sortCount; 143 | int rank; 144 | for (rank = 0; rank < step; rank++) 145 | { 146 | step -= rank + 1; 147 | } 148 | 149 | float stepno = (float)(1 << (rank + 1)); 150 | float offset = (float)(1 << (rank - step)); 151 | float stage = 2 * offset; 152 | 153 | Debug.Log("stepno : " + stepno + ", offset : " + offset + ", stage : " + stage); 154 | 155 | _bitonicSortMat.SetFloat("_SortBlockSize", stage); 156 | _bitonicSortMat.SetFloat("_SortSize", stepno); 157 | _bitonicSortMat.SetFloat("_Offset", offset); 158 | _bitonicSortMat.SetVector("_TextureSize", new Vector4(TEXTURE_WIDTH, TEXTURE_WIDTH, 0, 0)); 159 | Graphics.Blit(_sortBuffer, _sortTempBuffer, _bitonicSortMat); 160 | SwapBuffer(ref _sortBuffer, ref _sortTempBuffer); 161 | 162 | _sortCount++; 163 | } 164 | 165 | /// 166 | /// 167 | /// 168 | /// 169 | /// 170 | void SwapBuffer(ref RenderTexture ping, ref RenderTexture pong) 171 | { 172 | RenderTexture tmp = ping; 173 | ping = pong; 174 | pong = tmp; 175 | } 176 | 177 | void OnDestroy() 178 | { 179 | 180 | if (_bitonicSortMat != null) 181 | { 182 | DestroyImmediate(_bitonicSortMat); 183 | } 184 | _bitonicSortMat = null; 185 | 186 | if (_seedTex != null) 187 | { 188 | DestroyImmediate(_seedTex); 189 | } 190 | _seedTex = null; 191 | 192 | if (_sortBuffer != null) 193 | { 194 | _sortBuffer.Release(); 195 | } 196 | _sortBuffer = null; 197 | 198 | if (_sortTempBuffer != null) 199 | { 200 | _sortTempBuffer.Release(); 201 | } 202 | _sortTempBuffer = null; 203 | } 204 | 205 | void OnGUI() 206 | { 207 | var r00 = new Rect(TEXTURE_WIDTH * 0, TEXTURE_HEIGHT * 0, TEXTURE_WIDTH, TEXTURE_HEIGHT); 208 | var r10 = new Rect(TEXTURE_WIDTH * 1, TEXTURE_HEIGHT * 0, TEXTURE_WIDTH, TEXTURE_HEIGHT); 209 | 210 | GUI.skin.label.fontSize = 36; 211 | 212 | GUI.DrawTexture(r00, _seedTex); 213 | GUI.DrawTexture(r10, _sortBuffer); 214 | 215 | GUI.Label(r00, "SeedTex"); 216 | GUI.Label(r10, "SortBuffer"); 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortRT/BitonicSortRT.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 96a5a918a57ad5141ad4090bb2734d51 3 | timeCreated: 1474535587 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: 8 | - BitonicSortShader: {fileID: 4800000, guid: cf738e3163b80d14d9e4521f002927a9, type: 3} 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortRT/BitonicSortRT.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/Assets/BitonicSortRT/BitonicSortRT.unity -------------------------------------------------------------------------------- /GPUBitonicSort/Assets/BitonicSortRT/BitonicSortRT.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41b701685e8d11940b15ecd70ffc21ce 3 | timeCreated: 1474538520 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.3.5f1 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/UnityAdsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/UnityAdsSettings.asset -------------------------------------------------------------------------------- /GPUBitonicSort/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/GPUBitonicSort/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GPUBitonicSort 2 | ### 3 | - BitonicSortCS
4 | Bitonic sort is implemented using ComputeShader. 5 | 6 | - BitonicSortRT
7 | Bitonic sort is implemented using RenderTexture. 8 | 9 | ![image](https://github.com/hiroakioishi/UnityGPUBitonicSort/blob/master/bitonicsort_image.jpg) 10 | 11 | https://youtu.be/tGslc0d2EiA 12 | 13 | ### References 14 | ComputeShaderSort11
15 | https://code.msdn.microsoft.com/windowsdesktop/DirectCompute-Basic-Win32-7d5a7408 16 | 17 | http://t-pot.com/program/90_BitonicSort/index.html 18 | -------------------------------------------------------------------------------- /bitonicsort_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiroakioishi/UnityGPUBitonicSort/f803c1025e1bd3af4d5562f9bfcb28e2a7699803/bitonicsort_image.jpg --------------------------------------------------------------------------------