Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ AMD Tahiti上的OpenCL/OpenGL隐式同步_C++_Opengl_Opencl_Amd - Fatal编程技术网

C++ AMD Tahiti上的OpenCL/OpenGL隐式同步

C++ AMD Tahiti上的OpenCL/OpenGL隐式同步,c++,opengl,opencl,amd,C++,Opengl,Opencl,Amd,在AMD Tahiti(AMD Radeon HD 7900系列)设备上,OpenCL和OpenGL的“隐式同步”有问题。该设备具有cl/gl扩展、cl_khr_gl_共享和cl_khr_gl_事件 当我运行这个程序时,它只是一个简单的vbo更新内核,并用简单的着色器将它画成一条白线,它会像疯了一样打嗝,每次更新都会暂停2-4帧。我可以确认我用来更新和绘制缓冲区的不是cl内核或gl着色器,因为如果我在获取和释放cl更新的gl对象之前和之后放置glFinish和commandQueue.finis

在AMD Tahiti(AMD Radeon HD 7900系列)设备上,OpenCL和OpenGL的“隐式同步”有问题。该设备具有cl/gl扩展、cl_khr_gl_共享和cl_khr_gl_事件

当我运行这个程序时,它只是一个简单的vbo更新内核,并用简单的着色器将它画成一条白线,它会像疯了一样打嗝,每次更新都会暂停2-4帧。我可以确认我用来更新和绘制缓冲区的不是cl内核或gl着色器,因为如果我在获取和释放cl更新的gl对象之前和之后放置glFinish和commandQueue.finish(),一切都会正常工作

所以,我想我需要“启用”事件扩展

#pragma OPENCL EXTENSION cl_khr_gl_event : enable
…在cl程序中,但这会引发错误。我假设这个扩展不是面向客户端的扩展,应该按照“预期”工作,这就是为什么我不能启用它

我注意到的第三个行为……如果我取出glFinish()和commandQueue.finish(),并在CodeXL调试中运行它,隐式同步就会工作。如中所示,在不更改代码库的情况下(如使用finish强制同步),CodeXL允许隐式同步。因此,隐式同步显然是有效的,但我无法通过VisualStudio定期运行应用程序并强制同步来实现它


很明显我遗漏了什么,但我真的看不出来。如果您有任何想法或解释,我将不胜感激,因为我希望保持隐式同步。

我猜您没有使用GLsync-cl_事件同步器(
GL_ARB_cl_事件
cl_khr_GL_事件
扩展),这就是为什么添加cl/glFinish和CodeXL的开销会有所帮助的原因

我猜您的代码如下所示:

A1. clEnqueueNDRangeKernel
A2. clEnqueueReleaseObjects
[here is where you inserted clFinish]
B1. glDraw*
B2. wgl/glXSwapBuffers
[here is where you inserted glFinish]
C1. clEnqueueAcquireObjects
[repeat from A1]
相反,你应该:

  • CL->GL synchro:让
    ClenqueureReleaseObjects
    创建一个(输出)事件以传递给
    glCreateSyncFromCLeventARB
    ,然后使用
    glWaitSync
    (而不是
    glClientWaitSync
    ——在这种情况下,它与
    clFinish
    )相同

  • GL->CL synchro:have
    clEnqueueAcquireObjects
    获取(输入)事件,该事件将使用
    clCreateFromGLsync
    创建,从
    glFenceSync
    获取同步对象

  • 总的来说,应该是:

    A1. `clEnqueueNDRangeKernel`
    
    [Option 1.1:]
    A2. `clEnqueueReleaseObjects`( ..., 0, NULL, &eve1)
    
    [Option 1.2:]
    A2. `clEnqueueReleaseObjects`( ..., 0, NULL, NULL)
    A2'. `clEnqueueMarker`(&eve1)
    
    A3. sync1 = glCreateSyncFromCLeventARB(eve1)
    * clReleaseEvent(eve1)
    A4. glWaitSync(sync1)
    * glDeleteSync(sync1)
    B1. glDraw*
    B2. wgl/glXSwapBuffers
    B3. sync2 = glFenceSync
    B4. eve2 = clCreateFromGLSync(sync2)
    * glDeleteSync(sync2)
    
    [Option 2.1:]
    C1. clEnqueueAcquireObjects(, ..., 1, &eve2, NULL)
    * clReleaseEvent(eve2)
    
    [Option 2.2:]
    B5. clEnqueueWaitForEvents(1, &eve2)
    * clReleaseEvent(eve2)
    C1. clEnqueueAcquireObjects(, ..., 0, NULL, NULL)
    
    [Repeat from A1]
    
    (如果在将控制权移交给另一个API之前,您事先不确切知道最后一次排队是什么,则选项1.2/2.2更好)


    作为补充说明,我假设您没有为OpenCL使用无序队列(在这种情况下,确实不需要这样做)-如果您使用了,当然,您还必须同步
    clEnqueueAcquire
    ->
    clEnqueueNDRange
    ->
    clEnqueueRelease

    我理解使用glSync和clEvent显式同步行为。然而,从OpenCL扩展(cl_khr_gl_事件)来看,它说“……该扩展修改了clEnqueueAcquireGLObjects和clEnqueueReleaseGLObjects的行为,以隐式地保证与绑定在同一线程中的OpenGL上下文同步……”这就是为什么我相信CodeXL可以按预期工作的原因。某些开关被翻转,但不会自动翻转。我想我想知道的是,既然支持隐式同步,为什么我必须创建显式同步?或者这是一个AMD错误?正确;如果存在这些扩展,则根据您引用的规范的部分,不需要clFinish/glFinish调用。然而,只有当你在同一个线程上工作时。是这样吗?我注意到的第三个行为……如果我取出glFinish()和commandQueue.finish(),并在CodeXL调试中运行它,隐式同步就会工作。你肯定吗?由于这是一个调试器,我倾向于相信它在锁步中运行,而不是像驱动程序通常那样排队3-4帧的命令(AMD称之为驱动程序中的翻转队列大小)。我相信每次在CodeXL中交换缓冲区时,
    glFinish(…)
    命令都会有效地插入到命令流中(如果它与gDEBugger类似的话)。这肯定可以解释同步从何而来,但仍然不能解释为什么设备不允许从cl_khr_gl_事件扩展进行隐式同步。