filum 0.1.2

Easy GPGPU powered by Vulkan
Documentation
#version 450

#define INDEX(_x, _y) ((_y) * WIDTH + (_x))
#define IS_CONNECTED(_i0, _i1) (values[_i0] >= 0 && values[_i1] >= 0)
#define LABEL(_idx) (values[_idx])

layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(constant_id = 0) const uint WIDTH = 8;
layout(constant_id = 1) const uint HEIGHT = 8;
layout(push_constant) uniform PushConstant {
    uint step_index;
};
layout(binding = 0) buffer Binding { 
    int values[];
};

int findRoot(uint index) {
    int v = LABEL(index);
    if (v < 0) {
        return v;
    }
    int w = int(index);
    while (v != w) {
        w = v;
        v = LABEL(v);
    }
    return v;
}

void merge(uint x0) {
    uint x1 = x0 + 1;
    for (uint y = 0; y < HEIGHT; ++y) {
        uint i0 = INDEX(x0, y);
        uint i1 = INDEX(x1, y);
        if (IS_CONNECTED(i0, i1)) {
            int v0 = findRoot(i0);
            int v1 = findRoot(i1);
            LABEL(max(v0, v1)) = LABEL(min(v0, v1));
        }
    }
}

void main() {
    uint id = gl_GlobalInvocationID.x;
    uint steps = WIDTH / (WIDTH >> (step_index + 1));
    uint x0 = (id * steps) + (1 << step_index) - 1;
    merge(x0);
}