Imagination PowerVR SDK Blog

OpenGL ES glDrawArrays calls block

pvrtrace

#1

Hi,



I run my application and after an inconsistent amount of time my OpenGL ES glDrawArrays calls stop working. I am able to get a partial stack trace on the thread that is doing the OpenGL ES call and it seems to be blocking on the glDrawArrays call on an ioctl (10)



when I do a cat on the /proc/pvr/ files i get:

shell@android # cat /proc/pvr/queue

Command Queues

Queue CmdPtr Pid Command Size DevInd DSC SSC #Data

c6e01d80





shell@android # cat /proc/pvr/nodes

Registered nodes

Addr Type Class Index Ref pvDev Size Res

c7bc8900 ?9 display 1 1 c725e740 56 (null)

c7a2f800 ?7 3D 0 1 c781c000 0 c7a99060



shell@android # cat /proc/pvr/version

Version CustomerGoogle_Android_ogles1_ogles2_GPL sgxddk 18 1.8@905891 (release) omap4430_android

System Version String: SGX revision = 1.2.0



The glDrawArrays is using a texture for drawing two triangles provided in STRIP mode. The same code seems to work several time and suddenly stop working. texture and vertex coords are constants and never change.



When the source texture is generated by FBO the application get stuck in glDrawArrays. BUT when the texture is obtained doing a glCopyTexImage2D then there is no more problem; So may be there is an interaction between the texture generation through FBO and the usage of that texture.



As i’m stuck in the ioctl call, and so i can’t investigate more.



I hope you will help me as i’m completely stuck and under pressure to deliver my project.



Best Regards



Seb


#2

Hi Seb,



Can you send a reproduction of this issue to us? (either post a link here, or email us at devtech@imgtec.com if you would rather share it privately).



Which device have you seen the problem on?



Thanks,

Joe


#3

Hi Joe,



thanks for your answer.

I’m currently using Galaxy Nexus.



Regarding sharing the app, i can’t due to legal issue and the fact that it is very big.

Continuing my investigation it seems that my thread is block on a FUTEX

futex(0x…, FUTEX_WAIT_PRIVATE, -114, 0)



as said the last trace i have is glDrawArrays and i never come back to print the next one just after the call.





BR



Seb


#4

Hi,



i’m coming back still having the problem.

It seems that i have a race and my thread is locked on a FUTEX

after investigation it seems it is in the POWERVR stack on a conditional variable which value is 0xfffffff2



__pthread_cond_timedwait_relative(cond=0x5beb8058, mutex=0x5beb054)

__pthread_cond_timedwait()

PVR+0ffset

PVRSRVLockMutex()



My problem is that it is always on the glDrawArrays(5, 0, 4);

and when i’m using FBO (the glDrawArrays is drawing in a texture and using a texture itself generated with FBO).



Are you aware of any issue like that ?

Could you advise me some test to perform in order to progress ?

May be any advise to ensure the state is good before stating the draw.



For info i tried to add glFinish() before the draw, to be sure that FBO is fully generated but nothing is changing. If i remember well some other discussions, for optimization on PowerVR the FBO is generated only when it is used, would that be possible that such optimization is causing me the lock ?



Thanks in advance for your help. You are my last chance for finding the issue without having driver sources.



Br



Sebastien


#5

Hi,



I’ve spoken to our driver team and they are not aware of this problem.



Out of curiosity - are you always calling glDrawArrays as “glDrawArrays(5, 0, 4);”? Is there any reason you are hard-coding the mode value instead of using GL_TRIANGLE_STRIP (or any of the other predefined mode values)?

Have you tried using VBOs/not using VBOs, or using glDrawElements instead to draw your quad? The driver bug may be specific to the method you’re using to upload the data to GL and draw it.



Depending on how the driver is configured, glFinish() may not behave as you expect. For testing purposes, you should use glReadPixels() to force the render (the reasons for this and an explanation of the drawbacks is discussed here).



It’s difficult to say what is causing the lock. If you can provide us with your app or a minimal reproduction of the issue, we can investigate on our end. Alternatively, you can use PVRTrace and send us the recording. It will be harder for us to investigate with the PVRTrace recording though as it will only contain data up to the point that your application crashes.



Regards,

Joe


#6

Hi Joe,



thanks for replying. regarding the glDrawArrays “glDrawArrays(5, 0, 4)” is a trace. In the program i’m using GL_TRIANGLE_STRIP. the other values 0, 4 are constant due to the fact i’m always drawing a quad made of two triangle defined in strip mode.

I made test without FBO and it is working fine but the problem is that i have to use glCopyTexSubImage2D which is much slower. it is why i think the problem is coming from FBO.

I also tried to draw in two different textures alternatively and use them also alternatively and doing that there is no problem but i have ta add an extra copy to ensure texture are always containing same data.



I’m going to try using glReadPixels to see if the problem is still present.



Br



Seb


#7

glCopyTexImage2D will force the GPU to render everything up to that point, which may be the reason that this approach works. Its possible that the driver is hitting a memory limit in the FBO path that is avoided when the render is kicked in your workaround path. I’d expect glReadPixels to solve the problem too as it will also force a render. It will incur a similar cost to glCopyTexImage2D though.



Are you using VBOs for your quads?



Thanks,

Joe


#8

yes i’m using FBO for the Quad.

I also forget to say that i’m using texture that are 2048x1024 as NPOT is not supported for GLES1.1 and my screen resolution is 1280x720.



i tested adding a glReadPixels on only 1,1 pixels size and it seems to fix the issue

BR



Seb


#9

Hi Seb,



I meant Vertex Buffer Objects (VBOs), where the vertex data is uploaded and cached by GL instead of being resubmitted every frame. You may find that using VBOs allows you to avoid the bug in the driver.



Thanks,

Joe


#10

Hi Joe,



can you develop on why VBO could impact FBO ? sorry for such question but i do not see how VBO usage can impact FBO rendering and avoid the dead lock.



BR



Seb


#11

The lock in the driver isn’t necessarily caused by the FBO. It may be the case that forcing the render to complete (i.e. calling glCopyTexImage2D or glReadPixels) allows the driver to avoid a bug that it would have otherwise hit.



As the bug could be caused by something else in your render and it only occurs when you draw your quads with glDrawArrays, changing the way that those quads are draw may allow you to work around the issue.



Thanks,

Joe


#12

Hi,



i made some tries changing glDrawArrays by glDrawElements (removing the glReadPixels) and the problem is still there.



It seems that using glReadPixels suing a small square (1,1) remove the problem but is impacting a lot the performances.

Could you advise some other tricks to avoid glReadPixels usage ?

Why a call to glReadPixels on a small amount of pixels (4 pixels in my case) is impacting so much my performances ?





BR



Seb


#13

Reading back any part of the render target forces the GPU to render everything that has been submitted so far. Reading back a 1x1 rather than a larger resolution merely keeps the amount of data transferred during the read to a minimum.



Unfortunately, there are no other ways of forcing a render that are less costly.



Have you tried using VBOs? If you need a reference, you can refer to our IntroducingPOD Example.



Regards,

Joe


#14

VBO are only accessible from OpenGLES 2.0 ?

if yes then i can’t because i’m using OpenGLES 1.1.



Br



Seb


#15

VBO’s are also available in OpenGL ES 1.x. They’re used in all of the variants of our IntroducingPOD Example.



Regards,

Joe


#16

I made the try with VBO and the problem is still present.



Br



Seb


#17

Hi Seb,



Have you been able to workaround this issue yet? Unfortunately, I’m not sure how to assist further without your app or a minimal reproduction of the problem.



Regards,

Joe


#18

Hi Joe,



no i haven’t been able to fix my problem. As said glReadPixels on single pixels seems to fix the problem but ther eis a huge performance impact and not usable solution.



BR



Seb


#19

Have you tried to use PVRTrace to record and analyse your GL calls? Would you be able to share the recording with us for analysis?



Regards,

Joe


#20

Regarding PVTrace i was not able to set it up. The only thing i could share with you is the gl command list that are sent to the GPU.



Regards,



Seb