【问题标题】:Applying cuFFT to OpenGL Vertex Buffer Objects将 cuFFT 应用于 OpenGL 顶点缓冲区对象
【发布时间】:2016-05-24 22:26:25
【问题描述】:

所以cufftComplex 类型是一个带有n 结构的数组,带有xy 字段,分别代表每个复数的实部和虚部。

另一方面,如果我想在 OpenGL 中创建一个带有 x-y- 字段的顶点缓冲区对象,即 2D 顶点或也代表 n 复数的顶点缓冲区对象,我必须创建一个 2n 大小的浮点数组,其布局如下:

x0 y0 | x1 y1 | ... | xn yn

然后我通过调用将其写入 VBO:

glBufferData(GL_ARRAY_BUFFER, n * sizeof(GLfloat), complex_values_array, GL_DYNAMIC_DRAW);

我想用 cuFFT 对图像进行傅里叶变换,并显示例如复数值的大小。如何解决这两种数据类型之间的不兼容问题? cuFFT 有没有办法作用于 VBO?

编辑:

也许我应该编写一个 CUDA 内核,它采用 cufftComplex 类型并将每个复数的大小映射到 1D-VBO。或将 cufftComplex 类型映射到 2D-VBO 的 CUDA 内核。我不知道开销是多少,因为它是设备-> 设备,我希望它是可管理的。

【问题讨论】:

  • cufft 可以跨步和分散其输入和输出,就像 FFTW 一样。但是如果你想显示复杂值的magnitude,那是一个单独的问题。它需要计算。这不仅仅是“两种数据类型之间的不兼容”。
  • 是的,但我认为我可以将复杂的值提供给顶点着色器并在那里计算幅度。
  • 也许你可以。这是我在问题中看到的第一次提到您打算编写着色器的意图,尽管我承认其标记为glsl。无论如何,它不是数据类型之间的不兼容。这是必须执行的计算; cufft 不会为您这样做。您可以在 CUDA 内核中执行此操作(也可以在此处进行任何必要的数据混洗),或者在着色器中执行此操作。无论如何,使用 CUDA-OpenGL Interop,您可以将 OpenGL 资源映射到 CUDA。 CUFFT(或您的幅度/随机播放内核)可以填充该资源,然后您可以将其转回 OpenGL。
  • 这就是我最终所做的,一个接受 cufftComplex 并将其写入 openGL 资源的 CUDA 内核。性能影响还不错。
  • @PatronBernard:您能否将您的解决方案添加为答案,以便这个问题从未回答的队列中消失?

标签: opengl cuda glsl cufft


【解决方案1】:

我设法通过编写如下内核来解决这个问题:

__global__ void cufftComplex2Float(float* vbo_magnitude, Complex *z, const int width, const int height){
    unsigned int i = blockIdx.x*blockDim.x + threadIdx.x;
    unsigned int j = blockIdx.y*blockDim.y + threadIdx.y;
    float magnitude = pow(z[j*height + i].x, (float)2) + pow(z[j*height + i].y, (float)2);
    vbo_magnitude[j*height + i] = (PI2 + atanf(sqrt(0.1*magnitude))) / PI;
};

它不涉及主机设备传输,因此非常快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多