Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

README.md

gpuSort

A stable least-significant-digit radix sort, run entirely on the GPU, over a caller-owned array of u32 keys.

The three passes here are the body of one radix digit. They read a key array and a permutation and write a new permutation; they never touch whatever the keys describe, so any subsystem with a key per item can drive them. The caller supplies the keys, the identity seed, the per-pass constants and the dispatch sequence.

One pass

OrderShaderDispatch
1radix_histone workgroup of 256 per 256 items
2radix_scan{ 1, 1, 1 }
3radix_scatterone workgroup of 256 per 256 items

Each pass sorts on one 8-bit digit and keeps the relative order of items sharing that digit, so ceil(bits / 8) passes over the low digits upward compose into a total order on (key, item index).

Driving it

The caller owns six buffers: the keys, two permutation buffers the passes ping-pong between, the digit histogram (ceil(count / 256) * 256 entries) and one constants buffer per pass. A pass reads its constants as

WordMeaning
[0]item count
[1]block count, ceil(count / 256)
[2]this pass's digit shift — 0, 8, 16, 24
[3]1 on the last pass, 0 otherwise
[4]the key a dropped item carries

Every value is fixed for the life of the sorted array, so the constants are written once rather than re-uploaded per frame.

Each pass flips which buffer holds the permutation, so the parity of the pass count decides where the caller seeds the identity for the last scatter to land in the buffer the consumer reads.

An item the caller wants dropped takes a key at or past [4] — one past the last real key — which parks it in the tail of the permutation; the last pass resolves it to 0xffffffff, and the consumer reads that as "this slot draws nothing". A fixed dispatch size with a degenerate tail is what lets a consumer issue a constant draw with no read-back and no indirect arguments.