opengl - GL/CL 互操作性 : Shared Texture

标签 opengl opencl gpgpu gpu

我打算用OpenCL进行图形计算,例如光线转换、光线行进等。我想使用 OpenGL 来显示此计算的结果(像素图像)。我使用附加到帧缓冲区的纹理缓冲区。 OpenCL 将结果写入纹理,然后使用 glBlitFrameBuffer 函数将纹理数据复制到应用程序窗口帧缓冲区。 我在实现过程中遇到了 CL/GL inter 问题。我写了一个简单的例子来展示它。此示例显示帧缓冲区对象和纹理对象初始化、它们的结合、从 GL 纹理缓冲区创建 OpenCL 缓冲区。最后显示了主渲染循环。它包括在每帧中写入新数据的纹理、帧缓冲区附件以及该帧缓冲区的复制。

纹理初始化:

for (int i = 0; i < data.Length; i +=4) {
    data [i] = 255;
}
GL.BindTexture (TextureTarget.Texture2D, tboID [0]);
GL.TexImage2D<byte>(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, w, h, 0,
                    PixelFormat.Rgba, PixelType.UnsignedByte, data);
GL.BindTexture (TextureTarget.Texture2D, 0)

TBO+FBO初始化:

 GL.BindFramebuffer (FramebufferTarget.FramebufferExt, fboID [0]);
 GL.FramebufferTexture2D (FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0,
                          TextureTarget.Texture2D, tboID [0], 0);
 GL.BindFramebuffer (FramebufferTarget.FramebufferExt, 0);

CL/GL 初始化:

bufferID = CL.CreateFromGLTexture2D (context, memInfo, textureTarget, mipLevel, glBufferObject, out errorCode);

渲染循环:

 for (int i = 0; i < data.Length; i += 4) {
     data [i] = tt;
 }
 tt++;
 GL.BindTexture (TextureTarget.Texture2D, tboID [0]);
 GL.TexImage2D<byte> (TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, w, h, 0,
                      PixelFormat.Rgba, PixelType.UnsignedByte, data);

 GL.BindTexture (TextureTarget.Texture2D, 0);
 GL.BindFramebuffer (FramebufferTarget.FramebufferExt, fboID [0]);
 GL.FramebufferTexture2D (FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0,
                          TextureTarget.Texture2D, tboID [0], 0);
 GL.BindFramebuffer (FramebufferTarget.FramebufferExt, 0);GL.BindFramebuffer (FramebufferTarget.ReadFramebuffer, fboID [0]);

 GL.ReadBuffer (ReadBufferMode.ColorAttachment0);
 GL.DrawBuffer (DrawBufferMode.Back);

 GL.BlitFramebuffer (0, 0, w, h, 0, 0, w, h, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest);

 GL.BindFramebuffer (FramebufferTarget.ReadFramebuffer, 0);

乍一看这段代码看起来很奇怪,但它完全说明了我的问题。 CL在这里根本不起作用。在此应用程序中,创建了 OpenCL 上下文并进行了 OpenCL 缓冲区初始化。 这个工作应该很简单。屏幕颜色从黑色变为红色。它不会以这种方式工作。颜色与最初的红色(纹理初始化)相比没有变化。 但当我注释 CL/GL 初始化(从 GL 纹理创建 CL 缓冲区)时它工作正常。 为什么会这样呢?为什么 GL 缓冲区的行为会根据 CL 附件而改变?如何修复它并使其正常工作?

最佳答案

编辑2:

然后您需要检查为什么会收到InvalidImageFormatDescriptor。检查参数顺序是否正确以及 tbo 中的图像描述符是否具有误导性(内部图像结构 - 请参阅 OpenCL 规范)。从规范来看:

CL_INVALID_IMAGE_FORMAT_DESCRIPTOR if the OpenGL texture internal format does not map to a supported OpenCL image format.

<小时/>

编辑:

所以我知道 OpenTK 中的 OpenCL 功能是由一个名为 Cloo 的单独项目提供的。对于ComputeImage2D,他们的文档指出:

CreateFromGLTexture2D (ComputeContext context, ComputeMemoryFlags flags, int textureTarget, int mipLevel, int textureId)

与你的相比:

CreateFromGLTexture2D (context, MemFlags.MemReadWrite, TextureTarget.Texture2D, ((uint[])tboID.Clone()) [0], 0);

查看您的 mip 级别和 tbo 的顺序错误。错误的初始化可能会导致一些未知的行为。

<小时/> 很难从您提供的代码中判断可能存在什么问题。我现在也在关注 Interop,刚刚开始接触它。我要尝试的第一件事是在它周围放置一个 try/catch block ,并尝试获取任何可能的线索 error code .

您是否已验证显而易见的事实:您的设备上是否可以使用 cl_khr_gl_sharing 扩展程序?

另一个猜测,因为您只在示例代码中提供了实际 OpenCl/OpenGL 互操作的纹理/图像初始化:您是否获取了内存对象?

cl_int clEnqueueAcquireGLObjects (cl_command_queue command_queue,
  cl_uint num_objects.
  const cl_mem *mem_objects,
  cl_uint num_events_in_wait_list,
  const cl_event *event_wait_list,
  cl_event *event)

OpenCL 1.1 specifiction状态:

The function cl_int clEnqueueAcquireGLObjects is used to acquire OpenCL memory objects that have been created from OpenGL objects. These objects need to be acquired before they can be used by any OpenCL commands queued to a command-queue. The OpenGL objects are acquired by the OpenCL context associated with command_queue and can therefore be used by all command-queues associated with the OpenCL context.

所以问题可能是内存对象尚未绑定(bind)到特定的命令队列。

此外,还负责发出 glFinish() 以确保 OpenGL 端的所有初始化在获取内存对象之前完成。

关于opengl - GL/CL 互操作性 : Shared Texture,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8824269/

相关文章:

performance - OS X 上的 OpenGL 核心配置文件令人难以置信的减速

c++ - SIMD 内在函数 - 它们可以在 GPU 上使用吗?

performance - 为什么这个简单的 OpenCL 内核运行得这么慢?

opengl - 如何在OpenGL中实现没有重复顶点的平面着色?

opengl - GLSL - 从世界坐标计算屏幕坐标无法正常工作

c - OpenCL - 数组值被覆盖

cmake - 我如何 "tell"CMake 3.9+ 我想使用 NVIDIA 的 OpenCL 库?

OpenCL 与 OpenMP 性能对比

c - CUDA中的一些数学运算

c++ - GLuint64 的平台独立 printf 格式?