从OpenGL ES mipmap创建OpenCL内存对象

时间:2014-05-12 15:35:38

标签: android opengl-es opengl-es-2.0 opencl mipmaps

我的Android应用程序将OpenGL texture2D传递给我的OpenCL内核,但是当我使用clCreateFromGLTexture2D()和mipmap level 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规范docs(http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateFromGLTexture2D.html)说可能的原因可能是OpenGL实现不支持从非零mipmap级别创建。但是我不知道这是否确实如此,我不知道如何找到答案。

修改 在Andon的回复之后,我将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();

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

1 个答案:

答案 0 :(得分:1)

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

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

您对GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);的来电确实应该移到 之后 ,这会吸引您的FBO。正确完成后,您无需为较低细节的mipmap LOD手动分配存储空间。此功能将为您处理。因此,您实际上应该首先删除分配LOD 1的代码。