1

问题解决了!

  • 从内核字符串中删除了共享的编译指示。(使用 opencl 1.2)

  • 重新排序 GL-VBO-creating 和 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()之前那些也没有解决问题。

操作系统:64位windows7

主机:FX8150

设备:HD7870

MSVC2012(windows forms application) + OpenTK(2010_10_6) + Khronos opencl 1.2 headers

构建目标是 x64(发布)。

注意:opencl 部分在计算(sgemm)方面运行良好,opengl 部分在绘制 VBO 方面表现良好(一些平面由具有一些颜色和法线的三角形构成)但 opencl 部分(上下文)拒绝互操作。

编辑:添加#pragma OPENCL EXTENSION cl_khr_gl_sharing : enable到内核字符串中并没有解决问题。

编辑:在构建 cl 上下文“之后”创建 GL VBO,错误消失但 opencl 内核没有更新任何内容。诡异的。另外,当我删除 cl_khr_sharing pragma 时,3D 形状开始出现伪影,这意味着 opencl 现在正在做某事,但它只是随机删除的像素和一些我没有在内核中编写的裁剪区域。更奇怪。您可以在下图中看到这一点(我正在尝试使平坦的蓝色纸张消失,但它并没有完全消失,而且我尝试改变颜色并且没有改变)

这里

编辑: 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
}
4

0 回答 0