This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Mali T604 and eglImageKHR and FBO

Note: This was originally posted on 12th June 2013 at http://forums.arm.com

Hi,

i'm implementing an Android application using the GPU and especially ImageKHR and FrameBuffer Objects.
In a thread and its GLES context i'm creating a texture and its eglImageKHR then i share the eglImageKHR handle with another thread. In this second thread i'm creating a FrameBuffer Object with the given eglImageKHR as color buffer and a renderbuffer (for the depth) . Then from this second thread i'm drawing using openGLES 1.x commands into the just created FBO. The result is displayed on screen by the First thread.

All that is working well with a MALI-400 but running that application on a nexus 10 which use MALI-T604 i have some issue.
1- NO GL ERROR appear.
2- the FBO status is OK

but the screen is sometime OK sometime completely black.

I try to replace the drawing operation by a simple clear color where the color is changing at each call and sometime i can see part of the screen with a color and part that is black.

Is someone aware of differences between MALI-400 and MALI-T604 that could cause such kind of issue. unfortunately i do not have any documentation on T604 to really understand what is happening. I tried to enable auto MIMAP generation in case of T604 as for (NVidia GPU it was a mandatory condition the make the texture "complete") but nothing has changed.

I suspect that it is coming from ImageKHR because i have a JAVA application where i'm uising FBO without ImageKHR and it seems to work fine.

Here is the sequence to create the FBO with EGLImageKHR:
glGenFramebuffersOES(1, (GLuint*) 0x777ada1c);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 1);

glGenRenderbuffersOES(1, (GLuint*) 0x777ada1c);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, 1);

glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, 1184, 694);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, 1);

glGenTextures(1, (GLuint *) 0x777ada0c);
glBindTexture(GL_TEXTURE_2D, 3);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES) 0x752d700c);

glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, 3, 0);

glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);



I hope someone will be able to help me to understand what i'm missing .

Br

Seb
  • Note: This was originally posted on 24th June 2013 at http://forums.arm.com

    Hello SebDoe,
    [color="#444444"][font="arial"] Do you have a reproducer app that we could test on our end?[/font][/color]
    This will help us identify what the problem is, what the solution may be, and any workarounds that may be of use.

    Thanks in advance,

    McGeagh
  • Note: This was originally posted on 24th June 2013 at http://forums.arm.com

    Hi McGeagh,

    unfortunately it is very difficult for me to share my app. This app is split into three parts:
    - one part of OEM mobile phone images
    - one part downloaded from the market
    - one part downloaded from a server.

    Even if the graphic are a is not split over the three parts we need all of them to make the application working.


    As i tried to explain what i observed is that the same app was working fine on MALI 400 and the same app is working strangely having some time the screen black and sometime the right screen. My app is heavily using FBO (for off screen rendering) and EglImageKHR for exchanging textures between GLES contexts.

    EglImage seems important to me even if the app is muti-threaded and not multi-processes as i can share texture between context of different types (GLES 1.0 or GLES 2.0) and also as shared context seems badly supported by GPU on the market (not mali).


    I will try to bluid a new app using FBO and ImageKHR to see if i can duplicate the problem with that App.


    If you have any idea on possible mistake on my side let me know i will try.

    Br

    Seb
  • Note: This was originally posted on 23rd July 2013 at http://forums.arm.com

    Hi McGeagh,

    Sorry to come back so lately to you.
    I still have the issue with my application. i definitively think there is an issue with FBO + Image KHR as my application is working fine when i'm not using FrameBuffer Object but instead using PBuffer plus glCopyTexSubImage2D.

    As said before when using FBO sometime i see a frame, sometime screen is black (most of the time).

    The working data path is as follow.
    1- Draw in a PBuffer
    2- copy data from PBuffer into a texture (tex1)using glCopyTexSubImage2D + glEGLImageTargetTexture2DOES as i'm using Image KHR .
    3- copy data from tex1 to tex2 using fbo bound onto tex 2
    4- display on screen tex2

    The path having issue.
    1- Create and Bind FBO using Image KHR  APIs onto tex 1
    2- Draw directly into tex1 thanks to FBO
    3- copy data from tex1 to tex2 using a second fbo bound onto tex 2
    4 -display on screen tex2

    For information i'm using eglCreateImageKHR with parameter EGL_GL_TEXTURE_2D_KHR is it still supported ?

    The problem is that both are working fine on Mali-400 and may other GPU but on MALI T604 (Nexus 10) 2nd path is not working and NO ERROR is reported.
    I tried to attach the Mali trace tool and no error is raised.

    Are you aware of such issue ? is there any workaround ?


    Any help is welcomed as now i'm stuck on possible investigation.


    Thanks in advance for you help.

    Seb


    Hello SebDoe,
    [color="#444444"] Do you have a reproducer app that we could test on our end?[/color]
    This will help us identify what the problem is, what the solution may be, and any workarounds that may be of use.

    Thanks in advance,

    McGeagh
  • Note: This was originally posted on 24th July 2013 at http://forums.arm.com

    Some initial thoughts ...

    I assume each thread has it's own GLES context, and you are trying to get some kind of streaming load working?

    Exchange of surface and buffer data across contexts in GLES is not automatically synchronized; each context gets its own command stream and it will only be synchronized against other command streams if you force it to be so. Do you have any synchronization in your application to ensure the glCopyTex call has actually run before you use the image in the other thread?

    As a simple test if you insert a glFinish after the call to glCopyTex, and only use the EGL image in the other thread after that call has completed, does it work correctly? You can build something as a non-blocking equivalent using EGL fences (although it does require the consumer thread to poll or wait on the fence object).


    As a footnote - if you could cut down your application into a standalone test case it does make it much easier for us to help - the devil in most cases is in the detail, and if we can't see exactly what you are doing it is often very hard to reproduce, especially in cases with multiple contexts or threads!

    HTH, Iso
  • Note: This was originally posted on 24th July 2013 at http://forums.arm.com

    Hi,

    thanks a lot for your reply.

    Yes just adding a glFlush();glFinish() before unbinding the FBO , changing the context and then using the texture associated to FBO is making the all application working fine.

    Is the glFlush();glFinish() an acceptable fix or is it preferable to use other mechanism ?
    Is that behaviour specific to Mali-T604 as that was not needed on Mali-400 or even other GPU ?

    Again thanks a lot.

    Best regards,

    Seb


    Some initial thoughts ...

    I assume each thread has it's own GLES context, and you are trying to get some kind of streaming load working?

    Exchange of surface and buffer data across contexts in GLES is not automatically synchronized; each context gets its own command stream and it will only be synchronized if you force it to be so. Do you have any synchronization in your application to ensure the glCopyTex call has actually run before you use the image in the other thread?

    As a simple test if you insert a glFinish after the call to glCopyTex, and only use the EGL image in the other thread after that call, does it work correctly? You can build something as a non-blocking equivalent using EGL fences.
    As a footnote - if you could cut down your application into a standalone test case it does make it much easier for us to help - the devil in most cases is in the detail, and if we can't see exactly what you are doing it is often very hard to reproduce, especially in cases with multiple contexts or threads!

    HTH, Iso

  • Note: This was originally posted on 24th July 2013 at http://forums.arm.com

    Is the glFlush();glFinish() an acceptable fix or is it preferable to use other mechanism ?


    You shouldn't need the glFlush call; glFinish implies a flush of the stream.

    In terms of acceptability it is certainly functionally going to do what you want, but it will block the resource loading thraed until the GPU rendering has finished processing the glCopyTexImage2D call, so will stop that application thread processing other work. This may be acceptable for your use case, but if you want to keep that thread alive for processing Mali-T600 also supports the EGL fences. The thread loading the resource creates a fence after calling glCopyTexImage, and then calls glFlush. The other thread consuming the resource can either block waiting on the fence object, or poll it. 

    Is that behaviour specific to Mali-T604 as that was not needed on Mali-400 or even other GPU ?


    Without synchronization you are "out of spec", so while it might work on other implementations there are no guarantees it will work reliably.

    HTH,
    Iso