При каждом вызове вычислительного шейдера GLSL запись в переменную SSBO без условий гонки

Я пытаюсь написать простой вычислительный шейдер, который будет принимать массив точек, а также две точки, определяющие линию. Я хотел бы вызвать шейдер для каждой точки в массиве, рассчитать все расстояния параллельно, а затем заставить каждый вызов ждать своей очереди в цикле занятости, чтобы обновить данные самой дальней точки. Мой вычислительный шейдер выглядит так

#version 430 core

layout(std430, binding = 0) buffer BufferObjectIn {
    vec3 data[];

} pointData;

layout(std430, binding = 1) buffer BufferObjectOut{
    uint inLeftIndex;
    uint inRightIndex;
    uint inPointCount;
    int outFarthestIndex; 
    float outFarthestDist;
    int mutex;
} ssbo;

layout(local_size_x = 64) in;

float signedDistance(vec3 linePoint1, vec3 linePoint2, vec3 p) {
   return (linePoint2.x - linePoint1.x) * (linePoint1.y - p.y) - (linePoint2.y - linePoint1.y) * (linePoint1.x - p.x);
}

void main(void) {
    uint threadIndex = gl_GlobalInvocationID.x;

    if (threadIndex >= ssbo.inPointCount) {
        return;
    }

    vec3 leftPoint = pointData.data[ssbo.inLeftIndex];
    vec3 rightPoint = pointData.data[ssbo.inRightIndex];
    vec3 thisPoint = pointData.data[threadIndex];

    float dist = signedDistance(leftPoint, rightPoint, thisPoint);

    if (dist < 0){
        return;
    }

    do {
        lock = atomicCompSwap(ssbo.mutex, 0, 1);
    } while (lock == 0);

    barrier();
    if (dist > ssbo.outFarthestDist) {
        ssbo.outFarthestDist = dist;
        ssbo.outFarthestIndex = int(threadIndex);
    }

    ssbo.mutex = 0;
}

Я обнаружил, что мое приложение будет показывать разные результаты, даже если я запускаю его с одним и тем же набором данных. Я сделал что-то не так?


person EliteWalrus    schedule 16.03.2021    source источник
comment
Я не уверен, что это та же проблема, но здесь вы полагаетесь на то, что занятые ожидающие потоки не блокируют ваши другие потоки от достижения части записи: посмотрите здесь для более подробной информации. Также обратите внимание, что если вы ждете с атомарной операцией, вам, вероятно, также следует использовать atomicExchange для освобождения мьютекса.   -  person BDL    schedule 17.03.2021