Android 从OpenGL ES mipmaps创建OpenCL内存对象

Android 从OpenGL ES mipmaps创建OpenCL内存对象,android,opengl-es,opengl-es-2.0,opencl,mipmaps,Android,Opengl Es,Opengl Es 2.0,Opencl,Mipmaps,我的android应用程序将OpenGL texture2D传递到我的OpenCL内核,但是当我将clCreateFromGLTexture2D()与mipmap级别1一起使用时,我得到了CL\u INVALID\u MIPLEVEL 我正在创建我的OpenGL纹理并生成mipmap,如下所示: GLES20.glGenTextures ( 2, targetTex, 0 ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, targetTe

我的android应用程序将OpenGL texture2D传递到我的OpenCL内核,但是当我将clCreateFromGLTexture2D()与mipmap级别1一起使用时,我得到了CL\u INVALID\u 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规范文档()说,一个可能的原因可能是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后,我就是这样生成mipmaps的:

    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内存对象时,仍然会遇到相同的错误。

在这段代码中,第二级mipmap的尺寸非常不寻常。mipmaplodn+1的维数应为lodn{w,h}/2。在GL中,可以有具有相同分辨率的LOD,但这些LOD将不是mipmaps。要使2D纹理mipmap完整,除了基础图像0,还需要log2(最大(宽度、高度))-1个LOD,每个LOD的分辨率应为最后一个分辨率的1/4(每个维度1/2)。在这一点上我必须同意CL,LOD 1并不是一个真正的mipmap

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


调用
GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D)确实应该在你进入FBO后移动到一个点。如果操作正确,则无需手动为较低细节mipmap LOD分配存储。此函数将为您处理此问题。因此,您实际上应该首先删除分配LOD 1的代码。

您好,我已经实现了更改,但仍然得到相同的错误。但是,+1作为解释。@amirhbp:在这种情况下,您必须拥有“不支持从非零mipmap级别创建的OpenGL实现”。因为假设
image\u width
image\u height
为非零,您现在应该拥有一个mipmap完整纹理。是否有必要检查这一点?另外,如果OpenGL实现不支持,那么OpenGL ES调用GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D)时不应该生成错误吗。这是否意味着Android不支持mipmap?因为我使用的是Android的OpenGL ES:/No,
GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D)
从基本图像级别生成一组mipmap,默认为0。这与您试图在CL代码中执行的操作不同。@amirhbp:我不知道,我从未尝试在嵌入式平台上使用OpenCL。但是,我可以肯定地告诉您,Android没有一个OpenGL ES实现。至少有4家主要的硬件供应商有自己的实现,我确信有几十家我从未听说过的小型供应商也有自己的实现。