#version 430

layout(binding=0, r32i) uniform iimage2D pardexBucketPrefix;
layout(binding=1, r32i) uniform iimage2D pardexBucketCounts;
layout(binding=2, rgba32f) uniform image2D pardexPos;
layout(binding=3, r32i) uniform iimage2D pardexOfs;


ivec2 getTrip(int idt) {
    ivec2 triBufSize = imageSize(pardexPos)/2;
    ivec2 trip;
    trip.y = idt/triBufSize.x;
    trip.x = idt-trip.y*triBufSize.x;
   // trip.y = 0;
    return trip;
}

ivec2 getTripBucket(int idt) {
    ivec2 triBufSize = imageSize(pardexBucketCounts);
    ivec2 trip;
    trip.y = idt/triBufSize.x;
    trip.x = idt-trip.y*triBufSize.x;
   // trip.y = 0;
    return trip;
}

uniform mat4 viewMatrix;

uniform float partNum = 0.0;

void main() {
    ivec2 uv = ivec2(gl_FragCoord.xy);

    vec4 vp = imageLoad(pardexPos, uv);

    vp = viewMatrix*vec4(vp.xyz, 1.0);

  //  vp = projectionMatrix*vp;
    vp.xyz /= vp.w;

    float minZ = 0.0;
    float maxZ = 1200.0;

    float dz = 1.0-(-vp.z-minZ)/(maxZ-minZ);

   // if (dz > 0.5) discard;

    dz = clamp(dz, 0.0, 1.0);
    dz *= (1024.0*1024-1.0);

    dz = clamp(dz, 0.0, 1024.0*1024.0-1.0);

    ivec2 db = getTripBucket(int(dz));






  //  int pi = getTrip(uv);


    int pi = uv.x+uv.y*int(imageSize(pardexPos).x)/2;
    if (pi < partNum) {
        int bp = imageLoad(pardexBucketPrefix, db).x;
        int kk = imageAtomicAdd(pardexBucketCounts, db, 1);
        imageStore(pardexOfs, getTrip(bp+kk), ivec4(pi));
    }



/*
    int d2 = int(pow(2.0, loop))-1;
    int d2m1 = int(pow(2.0, loop+1.0))-1;
    int ib = getInd(uv)*int(pow(2.0, loop+1.0));
    int i0 = ib+d2;
    int i1 = ib+d2m1;

//    discard;

    if (loop > 18.5) {
        int v0 = imageLoad(pardexBucketPrefix, getTrip(i0)).x;
        int v1 = 0;

        imageStore(pardexBucketPrefix, getTrip(i0), ivec4(v1));
        imageStore(pardexBucketPrefix, getTrip(i1), ivec4(v0+v1));

    } else {
        int v0 = imageLoad(pardexBucketPrefix, getTrip(i0)).x;
        int v1 = imageLoad(pardexBucketPrefix, getTrip(i1)).x;

        imageStore(pardexBucketPrefix, getTrip(i0), ivec4(v1));
        imageStore(pardexBucketPrefix, getTrip(i1), ivec4(v0+v1));
    }
*/
//    imageStore(pardexBucketPrefix, uv, 1);

    discard;
}
