CL/GL-Interop错误的OpenGL纹理格式类型?

rdo*_*eui 5 opengl opencl texture2d libavcodec

我正在使用CUDA Toolkit 4.0在我的Geforce 330M上尝试使用OpenCL-OpenGL互操作.

我想捕获一个帧,将该数据用作Image2DOpenCL内核的输入图像().内核应该操纵数据并将其写入一个Image2DGL具有附加OpenGL纹理的图像对象.基本上它看起来像这样:

 _______________      RGB        _______________
|               |    uint8*     |               |   CL_RGBA / CL_UNORM_INT8
|   Grabber     | ------------> |   Image2D     | -------------------------.
|   avcodec     |               |   [input]     |                          |
|_______________|               |_______________|                          |
                                                                           |    
                                                                           V
 _______________                 _______________                       _______________
|               |               |               |                     |               |
|   Texture     | ------------> |   Image2DGL   | <-----------------> |    Kernel     |
|_______________|               |   [output]    |                     |_______________|
                                |_______________|
Internal
Format: GL_RGBA
Format: GL_RGBA
Type: ?
Run Code Online (Sandbox Code Playgroud)

我正在初始化纹理:

GLuint tex = 0;

void initTexture( int width, int height )
{
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_RECTANGLE, tex);
// now here is where I need assistance: The type parameter of the Texture (GL_FLOAT)
    glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL );
} 
Run Code Online (Sandbox Code Playgroud)


编辑:我也可以有一种类型GL_UNSIGNED_INT.


然后我创建了共享图像(Image2DGL):

texMems.push_back(Image2DGL(clw->context, CL_MEM_READ_WRITE, GL_TEXTURE_RECTANGLE, 0, tex, &err));
Run Code Online (Sandbox Code Playgroud)

然后我创建源图像(输入图像):

ImageFormat format;
format.image_channel_data_type = CL_UNORM_INT8;
format.image_channel_order = CL_RGBA;
srcImgBuffer = Image2D(clw->context, CL_MEM_READ_WRITE, format, width, height, 0, NULL, &err);
Run Code Online (Sandbox Code Playgroud)

在每个渲染循环中,我将数据写入srcImgBuffer:

// write the frame to the image buffer
clw->queue.enqueueWriteImage(srcImgBuffer, CL_TRUE, origin, region, 0, 0, (void*)data, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)

我也在为内核设置参数:

tex_kernel.setArg(0, texMems[0]);
tex_kernel.setArg(1, srcImgBuffer);
tex_kernel.setArg(2, width);
tex_kernel.setArg(3, height);
Run Code Online (Sandbox Code Playgroud)

在我获取并释放GL对象之前和之后.测试内核看起来像这样:

__kernel void init_texture_kernel(__write_only image2d_t out, __read_only image2d_t in, int w, int h)
{
    const sampler_t smp = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;

    int2 coords = { get_global_id(0), get_global_id(1) };
    float4 pixel = read_imagef(in, smp, coords);
    float4 test = { (float)coords.x/(float)w , 0, 0, 1};
    write_imagef( out, coords, pixel );
}
Run Code Online (Sandbox Code Playgroud)

image_channel_data_type可以理解为漂浮在内核和被解释为标准值.输出图像看起来不对,我有一个切片图片(线性),显然是因为错误的数据解释.正如我所提到的,我假设错误在纹理类型的初始化范围内.我尝试了GL_FLOAT(因为我写的是浮点到内核中的图像).

结果:图像从解码器转移PPM(左),纹理输出分散(右)

左边是PPM解码器,右边是我输出纹理的东西.

如果有人真的在这里读到:你有关于纹理类型的建议来解决问题吗?


编辑:如果我直接将捕获的帧绑定到纹理,视频播放正常.所以它必须以某种方式与CL-GL界面相关.


rdo*_*eui 1

我最终想出了解决方案,但没有看到明显的结果。我有一个 RGB 视频。因此我捕获了 RGB 格式的帧。这可以很好地显示在纹理上。然而,如果float4一次从只有三个通道的缓冲区中获取 a (如内核代码中所示),这当然会弄乱它。啊。

我也可以通过观察行数来假设我的错误:我在 512 行请求行中得到了 384 行,这很好地达到了 的比率.75

我只是要求我的抓取器(使用 libavcodec)抓取 RGBA,它会为我填充它以获得四通道图片。

我将标记这个问题以结束。