0

我的 android 应用程序将一个 OpenGL texture2D 传递给我的 OpenCL 内核,但是当我将 clCreateFromGLTexture2D() 与 mipmap 级别 1 一起使用时,我得到 CL_INVALID_MIPLEVEL。

我正在创建我的 OpenGL 纹理并生成这样的 mipmap:

    GLES20.glGenTextures ( 2, targetTex, 0 );
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, targetTex[0]);
    GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, image_width, image_height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 1, GLES20.GL_RGBA, image_width, image_height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

然后通过将纹理与 FBO 绑定来渲染纹理:

    targetFramebuffer = IntBuffer.allocate(1);
    GLES20.glGenFramebuffers(1, targetFramebuffer);
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, targetFramebuffer.get(0));
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, targetTex[0], 0);
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);

然后我像这样创建一个 cl 内存对象:

    mem_images[0] = clCreateFromGLTexture2D(m_clContext, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 1, in_tex, &err);

当 miplevel 设置为 0 并且所有内核工作正常时,内存对象创建成功。只有当 miplevel 设置为上述函数调用时才会出现 CL_INVALID_MIPLEVEL 错误。

OpenCL 规范文档(http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateFromGLTexture2D.html)说,一个可能的原因可能是 OpenGL 实现不支持从非零 mipmap 级别。但是我不知道这是否确实如此,也不知道如何找出答案。

编辑: 在安东的回复之后,我将 OpenGL 纹理生成更改为以下内容:

    GLES20.glGenTextures ( 2, targetTex, 0 );
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, targetTex[0]);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR_MIPMAP_NEAREST);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, image_width, image_height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
    GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

在绘制到与纹理绑定的 FBO 之后,这就是我生成 mipmap 的方式:

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, targetTex[0]);
    GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
    GLES20.glFinish();

尝试从 mipmap 级别不等于 0 的 GL 纹理创建 CL 内存对象时,我仍然遇到相同的错误。

4

1 回答 1

1

在这段代码中,您的二级 mipmap 的尺寸有一些非常不寻常的地方。mipmap LOD N+1的尺寸应该是 LOD N{w,h}/2。您可以在 GL 中拥有具有相同分辨率的 LOD,但这些 LOD 不会是 mipmap。为了使您的 2D 纹理 mipmap 完整,除了基本图像0之外,您还需要 log2 (max (width,height))-1 LOD ,并且每个 LOD 应该是最后一个分辨率的 1/4(每个维度的 1/2)。我必须同意 CL 的观点,LOD 1 并不是真正的 mipmap。

此外,您正在调用glGenerateMipmap (...)一个没有数据存储的新创建的纹理。这是一件毫无意义的事情,glGenerateMipmap (...)将从基础 LOD 图像开始为您构建您的 mip 链;在你调用这个的时候,没有基本的 LOD。

在您进入 FBO之后,您的呼叫GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);真的应该转移到一个点。正确完成后,您不必手动为细节较低的 mipmap LOD 分配存储空间。此功能将为您处理。因此,您实际上应该首先删除分配 LOD 1 的代码。

于 2014-05-12T19:26:15.397 回答