繁体   English   中英

使用clCreateFromGLTexture的opencl / opengl互操作无法绘制到纹理(纹理黑色)

[英]opencl/opengl interop using clCreateFromGLTexture fails to draw to texture (texture black)

设置有些复杂,所以我会尽力详细说明。

首先,我尝试使用openCL / openGL互操作。 该代码在不使用interop cl :: ImageGL时有效,因此基本知识就在那里。 该项目使用了3个主要的openGL上下文(花了很多时间在其中打开openCL上下文)。 我在上下文中使用QGLWidgets。 首先创建一个隐藏的QGLWidget,其他两个共享隐藏的上下文。 2个QGLWidgets中的每一个都在各自的线程中运行。 隐藏的QGLWidget将传输到创建openCL上下文的线程。

QGLFormat qglFormat;
qglFormat.setVersion(3, 3); 
qglFormat.setProfile(QGLFormat::CoreProfile);

m_hiddenGl=new GLHiddenWidget(qglFormat);
m_hiddenGl->setVisible(false);

m_view1=new GLWidget(qglFormat, m_hiddenGl);
m_view2=new GLWidget(qglFormat, m_hiddenGl);
 ...
 QThread *processThread=m_process.qThread();

m_hiddenGl->doneCurrent();
m_hiddenGl->context()->moveToThread(processThread);

GLWidget是一个自定义类,它启动其自己的线程并移动上下文,GLHiddenWidget再次是自定义类,但基本上只是重写了所有使makeCurrent避免被主线程调用的函数。

在启动过程线程内部如下

m_hiddenGl->makeCurrent();
hdc=wglGetCurrentDC();
glHandle=wglGetCurrentContext();

cl_context_properties clContextProps[]={ 
    CL_CONTEXT_PLATFORM, (cl_context_properties)m_openCLPlatform(),
    CL_WGL_HDC_KHR, (intptr_t) hdc,
    CL_GL_CONTEXT_KHR, (intptr_t) glHandle, 0
};

m_openCLContext=cl::Context(m_openCLDevice, clContextProps, NULL, NULL, &error);

这都是一个去。 从这一点出发,几个内核依次对输入数据(即图像)执行。 所有内核都成功(没有错误),但是使用openGL纹理写入数据的一个内核无法写入任何内容。 当使用openCL cl :: Image2d时,即使将openCL上下文创建为互操作,它也可以正常工作(产生正确的输出)。

在创建所有openGL上下文之后和openCL上下文创建之后(也在与openCL上下文相同的线程中),将创建openGL纹理。 在processThread的开始,纹理由隐藏的QGLWidget和glGenTextures生成。 然后,所有内核与其他openCL缓冲区和映像一起创建。 在内核执行之前,需要完成以下操作。

if(initBuffer) //runs only if buffer size is changed, allways runs first time
{
    m_hiddenGl->makeCurrent();

    glBindTexture(GL_TEXTURE_2D, m_texture);

    //I have attempted to put data in, result is always black from kernel
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);

    glFinish();

    //m_flags is CL_MEM_READ_WRITE
    m_imageGL=cl::ImageGL(m_openCLContext, m_flags, GL_TEXTURE_2D, 0, m_texture, &error);
}

和简化的内核。

__kernel void kernel1(__read_only image2d_t src1, __read_only image2d_t src2, __write_only image2d_t dst)
{
    int2 coord=(int2)(get_global_id(0), get_global_id(1));
    uint4 value=255;

    write_imageui(dst, coord, convert_uint4(value));
}

即使我不显示纹理,图像仍然是黑色的。 使用cl :: Image2d或cl :: ImageGL时,将从openCL读取图像并将其保存到硬盘。 对于cl :: Image2d,对于cl :: ImageGL是正确的,它是黑色的。

我遇到了同样的问题,并使用了write_imagef() (不要忘记将RGBA值除以255.0 !),而不是在OpenCL内核中解决了write_imageui() ,而没有更改OpenGL纹理的像素格式(您可以没有机会这样做,特别是如果它是现有的纹理,是在大型应用程序的其他位置创建的)。

您必须发布更多代码给我们,以查找错误。

无论如何,我已经编写了一个示例程序,该程序的功能非常相似。 它使用OpenCL来计算mandelbrot分形,然后使用OpenGL在QGLWidget绘制它。 源代码在这里: https : //github.com/kylelutz/compute/blob/master/example/mandelbrot.cpp

希望能有所帮助。

就像上面我在评论中指出的那样,我发现我的问题与openGL的纹理定义有关。 由于我在openCL内核中使用了write_imageui,因此必须按以下方式定义openGL纹理:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL);

从那时起,我花了一些时间创建了一个使用openGL / openCL互操作和线程化QGLWidgets的示例程序。 您可以在http://www.krazer.com/?p=109上阅读我对此的评论,和/或可以从github.com获取源代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM