Подсчет сортировки на графическом процессоре - как использовать атомарные функции?

Я реализую алгоритм сортировки подсчета (для частиц в трехмерном пространстве) с вычислением шейдеров directx11 в vvvv , графической среде программирования (только шейдеры записываются в тексте, все остальное (средство визуализации, буферы и т. Д.) Выполняется путем соединения узлов, следовательно, здесь сложнее поделиться ...).

Я успешно разделил свое пространство на ячейки, подсчитал количество частиц на ячейку и создал префиксную сумму / включающее сканирование количества ячеек. На последнем этапе я сначала копирую буфер суммы префиксов в RWStructuredBuffer следующим образом:

      StructuredBuffer<uint> InputBuffer;  
RWStructuredBuffer<uint> Prefix : PREFIXBUFFER;

[numthreads(1,1,1)]
void CS(uint3 tid : SV_DispatchThreadID)
{
    if (tid.x >= elementCount)
        return;
    Prefix[tid.x] = InputBuffer[tid.x];
}

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

Затем для каждой ячейки частицы я ищу значение буфера суммы префикса, использую его в качестве позиции индекса в выходном буфере для соответствующей частицы, затем увеличиваю буфер суммы префикса на 1:

      StructuredBuffer<particleID> ParticleIDs;
RWStructuredBuffer<uint> Prefix : PREFIXBUFFER;
RWStructuredBuffer<particleID> ResultBuffer : RESULTBUFFER;

[numthreads(64,1,1)]
void CS(uint3 tid : SV_DispatchThreadID)
{
    if (tid.x >= elementCount)
        return;
        
    particleID partID = ParticleIDs[tid.x];
    uint oldval;
    InterlockedAdd(Prefix[partID.cellID],1,oldval);
    ResultBuffer[oldval] = partID;
    
}

Структура частиц, которую я здесь использую, выглядит так и предварительно вычислена:

      struct particleID
{
    uint pID; //particleID
    uint cellID;
};

К сожалению, это не работает. Кажется, что полученный буфер имеет нормальные идентификаторы ячеек, но идентификаторы pID мерцают при тестировании с фиксированными положениями частиц.

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

Сначала я сбрасываю счетчик на 0:

      RWStructuredBuffer<uint> OutputBuffer : BACKBUFFER;

[numthreads(1,1,1)]
void CS(uint3 tid : SV_DispatchThreadID)
{
        OutputBuffer[tid.x] = 0;    
}

Тогда я так считаю:

      StructuredBuffer<particleID> ParticleIDs;
RWStructuredBuffer<uint> OutputBuffer : BACKBUFFER;   

[numthreads(64,1,1)]
void CS(uint3 tid : SV_DispatchThreadID)
{
    if (tid.x >= elementCount)
        return;
    
    uint oldval;
    InterlockedAdd(OutputBuffer[ParticleIDs[tid.x].cellID],1,oldval);

}

Это нормально работает. Я не вижу здесь разницы, кроме того, что я использую 2 буфера, в которые пишу, вместо 1... любая помощь очень ценится!

Спасибо!

0 ответов

Другие вопросы по тегам