Bringing back multiple mipmap levels to an EGL target using EGLImageTargetTexture2DOES

I’m a bit confused about the wording of OES_EGL_image spec :



"

The command



void EGLImageTargetTexture2DOES(enum target, eglImageOES image);



defines an entire two-dimensional texture array…

Any existing image arrays associated with any mipmap levels in the texture

object are freed (as if TexImage was called for each, with an image of

zero size).

"



The context for this question is that I want to bring back the existing mipmap levels stored in an EGLImage using the KHR_gl_texture_2D_image extension aside from the level specified in the parameter of the function in question.



But as the later part of the spec says above, any existing bound mip levels are cleared. The spec therefore implies that this snippet is wrong? :



glBindTexture(GL_TEXTURE_2D, textureId);

glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, level0);

glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, level1);

glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, level2);



where level[n] are EGLImages containing the levels of the texture



If the above code is incorrect, is there a specific way to resurrect those mipmap levels from EGLImage? As far as I know, I cannot specify more than one mipmap level in a single EGLImage using KHR_gl_texture_2D_image neither, can’t I?



Thanks!

Hi Xynopsis,



I’m afraid this is correct, as EGLImages are only specified for single-level images. There’s currently no way to pass along a MIP-Map chain like this I’m afraid. It should be noted the you can use glGenerateMipMaps() on the texture, though this should orphan the object, losing its ties to the original EGLImage.



I’m curious about your use case - perhaps there’s another way to do what you’re attempting? Would you be willing to share with us what it is you’re trying to do?



Thanks,

Tobias

Hello, thanks for the informative reply!



I'm afraid this is correct, as EGLImages are only specified for single-level images.


Quite interesting. In that case, wouldn't it mean that when you share a particular mip-map level of a source texture using an EGLImage, then later bring it back as a target texture, the new texture object would be incomplete because the other levels are left out (unless of course if the target texture is flattened i.e., the source level is turned into the base level of the target texture)?


I'm curious about your use case - perhaps there's another way to do what you're attempting? Would you be willing to share with us what it is you're trying to do?


Sure! I'm trying a to create a proof of concept multi-threaded renderer where textures are shared between a main drawing thread and some texture-loader threads. The sharing is synchronized. The texture-loader thread loads some textures and I would like to export the mip-map levels as well in one shot without re-specifying them again in the drawing thread.

Thanks!

Hi Xynopsis,



xynopsis said:

Quite interesting. In that case, wouldn't it mean that when you share a
particular mip-map level of a source texture using an EGLImage, then
later bring it back as a target texture, the new texture object would be
incomplete because the other levels are left out (unless of course if
the target texture is flattened i.e., the source level is turned into
the base level of the target texture)?

As you've put it, the texture is flattened: you can't actually set the level of the texture when pushing it back to OpenGL ES, as the command doesn't accept a "level" parameter. The level from the original texture is lost. When you call glEGLImageTargetTexture2DOES(), the data you pass in becomes the base texture level of whatever ID you have bound.

xynopsis said:

Sure! I'm trying a to create a proof of concept multi-threaded renderer where textures are shared between a main drawing thread and some texture-loader threads. The sharing is synchronized. The texture-loader thread loads some textures and I would like to export the mip-map levels as well in one shot without re-specifying them again in the drawing thread.

Thanks!



It sounds like you're trying to emulate the APPLE_copy_texture_levels extension? I'm not aware of any mechanism to do this in OpenGLES 1/2 with any other extension at present: The only way to copy a texture's mip-chain like this would be to render it to a 1:1 framebuffer, then use CopyTexture2D to get it into the new texture level. However doing such an operation would probably be slower than just recreating the texture.

OpenGL ES 3.0 has a TextureParameter, GL_TEXTURE_BASE_LEVEL, which can be used to incrementally add higher levels as you load them though, which may enable the sort of thing you're after, but I'm afraid that for earlier versions there's nothing really available.

Regards,
Tobias

Thanks a lot for the pointers! Yep, what I’m doing is quite similar indeed to what the Apple extension does. Anyways, efficiency is one of my primary requirements so I guess I’ll have to wait till GLES 3.0 gets a bit more widespread adoption.