设置有点复杂,所以我会尽力详细说明。
首先我尝试使用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上下文被创建为interop,它也能正常工作(产生正确的输出)。
在创建所有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是正确的,它是黑色的。
答案 0 :(得分:1)
我遇到了同样的问题并使用write_imagef()
(不要忘记将RGBA值除以255.0
!),而不是使用write_imageui()
在OpenCL内核中解决了它,没有改变OpenGL纹理的像素格式(你可能没有机会这样做,特别是如果它是一个现有的纹理,在大型应用程序的其他地方创建)。
答案 1 :(得分:0)
您必须为我们发布更多代码才能找到错误。
无论如何,我已经写了一个非常相似的示例程序。它使用OpenCL来计算mandelbrot分形,然后在QGLWidget
内使用OpenGL绘制它。来源位于:https://github.com/kylelutz/compute/blob/master/example/mandelbrot.cpp。
希望有所帮助。
答案 2 :(得分:0)
正如我在评论中所提到的,我发现我的问题与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获取来源