OpenCL/OpenGL纹理互操作/窗口的问题

Problems with OpenCL/OpenGL Texture interop / windows

本文关键字:问题 窗口 纹理 OpenGL OpenCL 互操作      更新时间:2023-10-16

为了提高渲染质量,我在OpenCL 1.1中编写了一个多功能可分离的降阶器。

基本图像(仅覆盖最终图像的一小部分)被渲染到非常大的framebuffer中。然后通过OpenCL对其颜色附加纹理进行下采样并放置到另一个纹理中。最后,呈现一个与屏幕对齐的四边形来显示结果。

到目前为止的想法。我们有什么:

  • 2个downscaler-kernel的实例(它存储交换坐标的结果(即(y,x))
  • inputTexture (rtt-framebuffer的颜色附件)
  • tempTexture, size: inputHeight x outputWidth,使用CL_MEM_READ_WRITE创建
  • outputTexture

运行kernel_instance_1( <otherParams>, inputTexture, tempTexture )产生所需的结果,但仅在第一帧中-不知何故,动画中发生的变化根本没有显示出来。由于我没有得到错误(见下文),我假设内核每帧都运行,但源纹理内容保持不变(事实并非如此,我也有该纹理的实时输出)。

Question: 我必须调用clCreateFromGLTexture2D()每次framebuffer的内容改变?

EDIT我刚刚意识到:inputTexture仍然附加到framebuffer对象的GL_COLOR_ATTACHMENT0 -这可能是一个问题吗? ENDEDIT

运行kernel_instance_2( <otherParams>, tempTexture, outputTexture )不会产生任何可见的结果,即使在两个内核调用之间排队了一个屏障。也就是说,outputTexture保持为空。

Question: 我是否需要在两个内核调用之间释放并重新获取纹理对象tempTexture,以便OpenCL看到变化?

只是为了看看opencl调用是什么,产生了以下输出:

clCreateKernel( separable_X )
clRetainMemObject( separable_X::convolution )
clCreateKernel( separable_Y )
clRetainMemObject( separable_Y::convolution )
clCreateFromGLTexture2D( separable_X::dst + separable_y::src, texID=24, usage=temporary (source and target) )
clCreateFromGLTexture2D( separable_Y::dst, texID=18, usage=target )
clCreateFromGLTexture2D( separable_X::src, texID=22, usage=source )
clRetainMemObject( separable_X::dst )
clRetainMemObject( separable_Y::src )
clRetainMemObject( separable_Y::dst )
clRetainMemObject( clearEmpty::dst )
clEnqueueAcquireGLObjects( count=3 )
clEnqueueBarrier()
clSetKernelArg( separable_X::convert )
clSetKernelArg( separable_X::offset )
clSetKernelArg( separable_X::convolution )
clSetKernelArg( separable_X::dst )
clSetKernelArg( separable_X::src )
clEnqueueNDRangeKernel( separable_X, (1440, 1080, 0), waiting4 0 events )
clSetKernelArg( separable_Y::convert )
clSetKernelArg( separable_Y::offset )
clEnqueueBarrier()
clSetKernelArg( separable_Y::convolution )
clSetKernelArg( separable_Y::dst )
clSetKernelArg( separable_Y::src )
clEnqueueNDRangeKernel( separable_Y, (540, 1440, 0), waiting4 0 events )
clEnqueueBarrier()
clEnqueueReleaseGLObjects( count=3 )

如果任何调用产生了错误,它应该在输出中。

另一种情况我得到很多次是clEnqueueReleaseGLObjects()返回错误代码-9999,有人提交为"NVidia:非法读取或写入缓冲区"。

Question: 如果任何组件超过1.0f且存储格式为RGBA8, write_imagef()是否不箝位颜色值?所以这实际上意味着必须写write_imagef( texture, (int2)coord, clamp( color, 0.f, 1.f ) );

提前非常感谢-这让我近一周以来一直在敲打我的头…

编辑一些可能值得一提的信息:

如何区分这两个实例?
在程序源代码中有两个不同名称的__kernel函数(separable_Xseparable_Y),它们都有相同的函数体调用separable() -函数。

如何在GL和CL之间同步?
负责获取GL对象的函数在调用clEnqueueAcquireGLObjects()之前会发出glFinish()
-我使用cl_events等待clEnqueueReleaseGLObjects()的完成(将来可能会改变)

你使用glFinish之前的clEnqueueAcquireGLObjects这是正确的,但你应该调用clFinish后的clenqueuerreleaseglobjects。请仔细阅读OpenCL 1.1规范的9.8.6.2节。

同样,对于你的其他问题:

我必须调用clCreateFromGLTexture2D()每次帧缓冲区的内容改变?

不,你只做一次从OpenGL纹理创建一个OpenCL图像。这应该在使用它的循环之前发生。

我需要释放和重新获取纹理对象tempTexture在两个内核调用之间,所以OpenCL看到的变化?

。一旦获得了OpenCL,你就可以在那里随心所欲地使用它。

可能是write_imagef()不箝位颜色值,如果任何组件超过1.0f和存储格式是RGBA8?

不,它工作得很好。我们一直在使用它