Мы работаем над заданием для курса GPGPU. Мы выбрали алгоритм, внедрили его в процессор и теперь конвертируем его в OpenCL.
Алгоритм, который мы выбрали, загружает модель в виде набора треугольников и растеризует их до вокселей. Воксели определяются как VBO точечных данных. Затем мы используем геометрический шейдер для преобразования этих точек в воксели в виде треугольников.
Таким образом, нашей программе OpenCL необходимо взять список треугольников и вывести список переменных точек.
А вывод массива переменной длины кажется проблемой.
Решение, которое мы нашли, состоит в том, чтобы атомарно увеличивать счетчик и использовать этот счетчик в качестве индекса как выходного массива, так и конечного размера массива. За исключением ... оба наших графических процессора не поддерживают расширение для атомарных операций.
Это то, что мы имеем до сих пор:
#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable
#define POS1 i0 * 3 + 0
#define POS2 i0 * 3 + 1
#define POS3 i0 * 3 + 2
void WritePosition( __global float* OutBuffer, uint inIndex, __global float* inPosition )
{
OutBuffer[ inIndex * 3 ] = inPosition[0];
OutBuffer[ inIndex * 3 + 1] = inPosition[1];
OutBuffer[ inIndex * 3 + 2] = inPosition[2];
}
__kernel void Voxelize(
__global float* outPointcloudBuffer,
__global float* inTriangleBuffer,
__global uint* inoutIndex
)
{
size_t i0 = get_global_id(0);
size_t i1 = get_local_id(0);
WritePosition( outPointcloudBuffer, inIndex[0], &inTriangleBuffer[ i0 ] );
//atomic_inc(inoutIndex[0]);
inoutIndex[0] = max(inoutIndex[0], i0);
}
И результат этого очень странный. Мы тестируем очень маленькую модель (12 треугольников, 36 позиций, 108 поплавков), и в результате мы получаем 31, 63 или 95. Всегда кратно 16 минус 1.
Как мы можем получить длину нашего выходного массива переменной длины?
Заранее спасибо.