C#opengl上下文句柄getter返回错误的地址

时间:2013-08-12 13:23:55

标签: c# c++ opengl interop opencl

问题解决了!

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

  • 重新排序GL-VBO创建和CL-Context-Creating。首先从gl-context创建CL-context。然后创建GL-VBO。然后通过cl获取它。然后计算。然后由cl释放。然后用gl绑定。画。完成gl。重来。始终使用clFinish以确保它与gl同步。为了更快的速度,clflush可以是好的,甚至可以进行隐式同步,我没试过。

okey

[来自这里的原始问题]

在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。你可以在下面的图片中看到这一点(我试图让平蓝色的纸张消失,但它并没有完全消失,我也尝试改变颜色而且没有改变)

here

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

0 个答案:

没有答案