pub const BITONIC_SORT_GLSL: &str = r#"
#version 430 core
layout(local_size_x = 512) in;
layout(std430, binding = 0) buffer Keys { float keys[]; }; // depth values
layout(std430, binding = 1) buffer Values { uint values[]; }; // particle indices
uniform uint num_elements;
uniform uint block_size;
uniform uint sub_block_size;
uniform bool ascending;
shared float shared_keys[512];
shared uint shared_vals[512];
void main() {
uint gid = gl_GlobalInvocationID.x;
uint lid = gl_LocalInvocationID.x;
if (gid < num_elements) {
shared_keys[lid] = keys[gid];
shared_vals[lid] = values[gid];
} else {
shared_keys[lid] = ascending ? 1e38 : -1e38;
shared_vals[lid] = gid;
}
barrier();
for (uint stride = sub_block_size; stride > 0; stride >>= 1) {
uint idx_a = (gid / stride) * stride * 2 + (gid % stride);
uint idx_b = idx_a + stride;
if (idx_a < num_elements && idx_b < num_elements) {
bool swap_cond = ascending
? (shared_keys[idx_a % 512] > shared_keys[idx_b % 512])
: (shared_keys[idx_a % 512] < shared_keys[idx_b % 512]);
if (swap_cond) {
float tmp_k = shared_keys[idx_a % 512];
shared_keys[idx_a % 512] = shared_keys[idx_b % 512];
shared_keys[idx_b % 512] = tmp_k;
uint tmp_v = shared_vals[idx_a % 512];
shared_vals[idx_a % 512] = shared_vals[idx_b % 512];
shared_vals[idx_b % 512] = tmp_v;
}
}
barrier();
}
if (gid < num_elements) {
keys[gid] = shared_keys[lid];
values[gid] = shared_vals[lid];
}
}
"#;Expand description
Bitonic sort for GPU particle depth ordering.