Skip to main content

BITONIC_SORT_GLSL

Constant BITONIC_SORT_GLSL 

Source
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.