问题解决了!
从内核字符串中删除了共享的pragma。(使用opencl 1.2)
重新排序GL-VBO创建和CL-Context-Creating。首先从gl-context创建CL-context。然后创建GL-VBO。然后通过cl获取它。然后计算。然后由cl释放。然后用gl绑定。画。完成gl。重来。始终使用clFinish以确保它与gl同步。为了更快的速度,clflush可以是好的,甚至可以进行隐式同步,我没试过。
[来自这里的原始问题]
在C#中,opencl-gl-interop的上下文构造失败,因为句柄getter函数提供了错误的地址并导致System.AccessViolationException
。
C#部分:
[DllImport("opengl32.dll",EntryPoint="wglGetCurrentDC")]
extern static IntPtr wglGetCurrentDC();//CAl
[DllImport("opengl32.dll", EntryPoint = "wglGetCurrentContext")]
extern static IntPtr wglGetCurrentContext();// DCAl
opencl中的C ++部分(这是在C ++ opencl的包装类中):
pl = new cl_platform_id[2];
clGetPlatformIDs( 1, pl, NULL);
cl_context_properties props[] ={ CL_GL_CONTEXT_KHR, (cl_context_properties)CAl,
CL_WGL_HDC_KHR, (cl_context_properties)DCAl,CL_CONTEXT_PLATFORM,
(cl_context_properties)&pl[0], 0};
ctx=cl::Context(CL_DEVICE_TYPE_GPU,props,NULL,NULL,NULL);//error comes from here
//ctx=cl::Context(CL_DEVICE_TYPE_GPU); this does not interop >:c
这些部分有什么问题?当我将“opengl32.dll”更改为“opengl64.dll”时,编译器/链接器无法找到它。
加载wglGetCurrentDC()
后调用wglGetCurrentContext()
和glControl1
,但这些似乎提供了错误的地址。在这些之前调用wglMakeCurrent()
或glControl1.MakeCurrent()
也无法解决问题。
OS:64位windows7
主持人:fx8150
设备:HD7870
MSVC2012(Windows窗体应用程序)+ OpenTK(2010_10_6)+ Khronos opencl 1.2标头
构建目标是x64(发布)。
注意:opencl部分适用于计算(sgemm),而opengl部分正在绘制VBO(某些平面由三角形构成,带有一些颜色和法线)但opencl部分(上下文)拒绝互操作。
编辑:将#pragma OPENCL EXTENSION cl_khr_gl_sharing : enable
添加到内核字符串中无法解决问题。
编辑:在构建cl上下文后“创建GL VBO”,错误消失但opencl内核没有更新任何内容。奇怪的。 PLus,当我删除cl_khr_sharing编译指示时,3D形状开始出现伪像,这意味着opencl现在正在做一些事情,但它只是随机删除的像素和一些我在内核中没有写过的裁剪区域。 Weirdier。你可以在下面的图片中看到这一点(我试图让平蓝色的纸张消失,但它并没有完全消失,我也尝试改变颜色而且没有改变)
编辑:CMSoft的opencltemplate看起来像我需要学习/做的,但他们的示例代码只包含6-7行代码!我不知道在哪里放置计算内核以及在哪里获取/设置初始数据,但该示例效果很好(顺便提供了数百个“警告!ComputeBuffer {T}(575296656)泄露”。
编辑:如果您想知道,这里是C ++中的内核参数构造:
//v1,v2,v3,v4 are unsigned int taken from `bindbuffer` of GL in C#
//so v1 is buf[0] and v2 is buf[1] and so goes like this
glBuf1=cl::BufferGL(ctx,CL_MEM_READ_WRITE,v1,0);
glBuf2=cl::BufferGL(ctx,CL_MEM_READ_WRITE,v2,0);
glBuf3=cl::BufferGL(ctx,CL_MEM_READ_WRITE,v3,0);
glBuf4=cl::BufferGL(ctx,CL_MEM_READ_WRITE,v4,0);
以下是如何设置命令队列:
v.clear();
v.push_back(glBuf1);
v.push_back(glBuf2);
v.push_back(glBuf3);
v.push_back(glBuf4);
cq.enqueueAcquireGLObjects(&v,0,0);
cq.finish();
以下是我如何设置内核的参数:
kernel.setArg(0,glBuf1);
kernel.setArg(1,glBuf2);
kernel.setArg(2,glBuf3);
kernel.setArg(3,glBuf3);
这是执行方式:
cq.enqueueNDRangeKernel(kernel,referans,Global,Local);
cq.flush();
cq.finish();
这里是如何发布的:
cq.enqueueReleaseGLObjects(&v,0,0);
cq.finish();
模拟迭代:
for (int i = 0; i < 200; i++)
{
GL.Finish(); // lets cl take over
//cl acquires buffers in glTest
clh.glTest(gci.buf[0], gci.buf[1], gci.buf[2], gci.buf[3]);// then computes
// then releases
Thread.Sleep(50);
glControl1.MakeCurrent();
glControl1.Invalidate();
gci.ciz(); //draw
}