Author Topic: Debugging OpenGLES games  (Read 654 times)

gameblabla (OP)

  • *
  • Posts: 399
Debugging OpenGLES games
« on: October 06, 2016, 10:07:25 PM »
Hello guys,
i've been trying to port some OpenGLES games to the Zero but unfortunely, they all unexpectly crash on it.
Let's start with gltron, this one is really strange.

https://github.com/gameblabla/gltron_gcw0
https://github.com/gameblabla/gltron_gcw0/blob/master/gltron.elf.trace?raw=true
https://github.com/gameblabla/gltron_gcw0/raw/master/gltron.opk

The menu, (which is using OpenGLES), works fine but trying to start a game makes the GCW0 freeze..
Starting gltron without an initiliased EGL context does work however but then, you would have no graphics on screen.
Since it is freezing, i cannot debug it using GDB.
When i do try using GDB, it tells me it gets stuck in an ioctl call.
The source code doesn't have such a call.
Not helpful.
I tried apitrace and i got some errors with glDrawArrays so commented out all of them
but even after that, it still freezes.
There's a trace file for those who want to try.

Next, we have Lugaru.
The OpenGLES port was made by Pickle and using a EGL context on my PC and OpenGL ES 1.1, it works just fine.
However, it is different on my zero and it crashes when making any kind of OpenGLES calls.
When i disable the offenders, i only get a black screen after the (working) loading red screen.
On my PC, disabling the offenders gives me the expected results with menu partially working.
Yeah...

Btw, i can't debug it with Apitrace and gdb because it throws me a bunch of errors saying it can't load some libraries or something...
Yes, i even tried running the terminal and then running the game but it still gives me those errors.
Running it from a OPK file however, works just fine.

https://github.com/gameblabla/lugaru-gcw0
https://github.com/gameblabla/lugaru-gcw0/raw/master/lugaru.opk

How am i supposed to debug them if i am completely blind ?
Could some developpers here please try to compile them (or use the bundled binary in the opk file) and give it a try ?
What can i do ?

Btw, for me, there's no doubt the culprit here is etna_viv.
Perhaps it might be a good idea to release a GCW0 firmware using the Vivante's driver and test my games against it,
if it is more full-featured than etna_viv anyway.

Thanks
« Last Edit: October 06, 2016, 10:13:18 PM by gameblabla »

congusbongus

  • *
  • Posts: 74
    • congusbongusgames
Re: Debugging OpenGLES games
« Reply #1 on: October 06, 2016, 11:49:59 PM »
You can use strace to find out more about the ioctl call.

gameblabla (OP)

  • *
  • Posts: 399
Re: Debugging OpenGLES games
« Reply #2 on: October 07, 2016, 12:06:27 AM »
You can use strace to find out more about the ioctl call.
Thanks for the strace tip.
Sadly, i found nothing suspicious using strace. (it does not run ioctl after it freezes)

The strange thing is that the game apparently still continues to run in the background while everything else freezed.

Still looking for a solution for Lugaru.

EDIT: Thought about this for a while and the only conclusion i came to was to use a software renderer like TinyGLES
in order to port such software without working around driver's bugs.
Hope johnny can lend me his modifications to TinyGLES...
« Last Edit: October 07, 2016, 01:44:17 AM by gameblabla »

Senor Quack

  • *
  • Posts: 159
Re: Debugging OpenGLES games
« Reply #3 on: October 07, 2016, 09:55:46 PM »
Still looking for a solution for Lugaru.

EDIT: Thought about this for a while and the only conclusion i came to was to use a software renderer like TinyGLES

OK, first off, your Makefile.gcw: your LDFLAGS are wrong. You are linking in both GLES2 and GLES1 at the same time. The correct line should be: LDFLAGS +=  -lSDL -lopenal -ljpeg -lpng -logg -lvorbis -lvorbisfile -lz -lGLESv1_CM -lEGL -lm -lc

I think your problems are deeper than just a bug in Etnaviv holding you back. I tried for an hour or two to get anywhere, but still get the crash in libgallium, with a corrupted stack preventing a backtrace.   I tried several things in Source/eglport.cpp that I thought might help with no luck (I am pretty familiar with using Pickle's eglport code).  I got as far along as going into Source/GameInitDispose.cpp and looking at Game::LoadTexture() function, which horrified me.  Someone has been modifiying/commenting-out code with no comments to indicate which is what nor when it was modified, which sucks.

It seems code in LoadTexture() has been commented out and I have no idea whether it was you or not, but the code that has been commented out is responsible for loading the texture into GL memory as well as tracking its handle in a vector.  It is suspicious to me that the glTexImage2D() line has GL_BGRA_EXT and GL_UNSIGNED_INT_8_8_8_8_REV:  That is probably not going to fly using GLES1 or Etnaviv. If it's really using BGRA pixel ordering (something you usually only see on ports of DirectX games), you need to get it in the correct RGBA ordering before calling GLES1's glTexImage2D.

Anyway, I changed LoadTexture to the followinghttp://pastebin.com/mh8aEwek   
Low and behold, what seems to be a buggy main menu finally appeared.  Note that I had to disable the call to gluBuild2DMipmaps to finally get it to stop crashing. I don't know much about mipmaps, maybe you should be using https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenerateMipmap.xml  ?
« Last Edit: October 07, 2016, 10:30:14 PM by Senor Quack »

gameblabla (OP)

  • *
  • Posts: 399
Re: Debugging OpenGLES games
« Reply #4 on: October 07, 2016, 10:44:59 PM »
Quote
OK, first off, your Makefile.gcw: your LDFLAGS are wrong. You are linking in both GLES2 and GLES1 at the same time. The correct line should be: LDFLAGS +=  -lSDL -lopenal -ljpeg -lpng -logg -lvorbis -lvorbisfile -lz -lGLESv1_CM -lEGL -lm -lc
Actually i added the GLES2 link thingy because i thought it might fix the "Load library" error or something.
It didn't unfortunely, but i was hopeless. (it was clear it was not going to do anything good)

Quote
I think your problems are deeper than just a bug in Etnaviv holding you back. I tried for an hour or two to get anywhere, but still get the crash in libgallium, with a corrupted stack preventing a backtrace.   I tried several things in Source/eglport.cpp that I thought might help with no luck (I am pretty familiar with using Pickle's eglport code).  I got as far along as going into Source/GameInitDispose.cpp and looking at Game::LoadTexture() function, which horrified me.  Someone has been modifiying/commenting-out code with no comments to indicate which is what nor when it was modified, which sucks.
Funny, i suspected something funny with what he did with LoadTexture but i decided to do nothing about it becaues it was working fine on mah PC.
I'll try your modifications, thanks !
Btw : The guy who did the OpenGLES port (including the commented-out functions) was, surprise, Pickle himself.

Quote
It seems code in LoadTexture() has been commented out and I have no idea whether it was you or not, but the code that has been commented out is responsible for loading the texture into GL memory as well as tracking its handle in a vector.  It is suspicious to me that the glTexImage2D() line has GL_BGRA_EXT and GL_UNSIGNED_INT_8_8_8_8_REV:  That is probably not going to fly using GLES1 or Etnaviv. If it's really using BGRA pixel ordering (something you usually only see on ports of DirectX games), you need to get it in the correct RGBA ordering before calling GLES1's glTexImage2D.
RGBA888 might be problematic on the GCW0 yeah but as far i know (and tested), it does not use it thankfully.
EDIT: Actually, you were right but it seems there might be a way to get it to work if texture.bpp is set to 24.
Will try that

Quote
Low and behold, what seems to be a buggy main menu finally appeared.  Note that I had to disable the call to gluBuild2DMipmaps to finally get it to stop crashing. I don't know much about mipmaps, maybe you should be using https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenerateMipmap.xml  ?
Hmm... well, it just seems GLUES does not work properly on the GCW0...
Strangely though on my PC, with the disabled call, the menu works fine but ingame obviously, it looks wrong.

Thank you for the bug testing Squack, i'll continue to work on it and improve the controls.
I admit i'm not familiar with OpenGL/ES at all.
I will still try to see if TinyGLES can actually be used though, it might fix the strange crashes with GLUES.
(because once again, it works on mah pc with gles so it should on dah zero)
« Last Edit: October 07, 2016, 10:57:55 PM by gameblabla »

Senor Quack

  • *
  • Posts: 159
Re: Debugging OpenGLES games
« Reply #5 on: October 07, 2016, 11:04:48 PM »
Funny, i suspected something funny with what he did with LoadTexture but i decided to do nothing about it becaues it was working fine on mah PC.
I'll try your modifications, thanks !

No problem.. also, beware that LoadTextureSave() also was modified in a similar manner but I didn't bother to touch it. Probably need to get that corrected the same way. I'm not sure what his intentions behind not using the textures[] vector was, if it maybe was something he was adding and never got around to finishing, or if it was there all along.

Quote
RGBA888 might be problematic on the GCW0 yeah but as far i know (and tested), it does not use it thankfully.
Nah, RGBA8888 or RGB888 are fine, that is the correct format for OpenGLES textures.  BGRA, however, (DirectX style pixel ordering) might not work on our GLES1, as it requires a GL extension to be present and I've never tried it under Etnaviv.  If you were using GLES2 you could easily change the texture's pixel ordering inside the pixel shader program, but the whole game would have to be ported, which wouldn't be much fun :(
« Last Edit: October 07, 2016, 11:12:43 PM by Senor Quack »

gameblabla (OP)

  • *
  • Posts: 399
Re: Debugging OpenGLES games
« Reply #6 on: October 07, 2016, 11:40:21 PM »
I looked at the mipmap issue and it was easier than i thought, i just need to set mipmap to 0 and tada,
it works without gluBuild2DMipmaps being set.
Code: [Select]
void Game::LoadTexture(const char *fileName, GLuint *textureid,int mipmap, bool hasalpha)
{
    GLuint      type;
 
    LOGFUNC;
 
    LOG(std::string("Loading texture...") + fileName);
   
    mipmap = 0;
 
    // Fix filename so that is os appropreate
    char * fixedFN = ConvertFileName(fileName);
 
    unsigned char fileNamep[256];
    CopyCStringToPascal(fixedFN, fileNamep);
    //Load Image
    upload_image( fileNamep ,hasalpha);
 
    std::string fname(fileName);
    std::transform(fname.begin(), fname.end(), fname.begin(), ::tolower);
    TexIter it = textures.find(fname);
 
    //Is it valid?
    if(textures.end() == it)
    {
        //Alpha channel?
if ( texture.bpp == 24 )
            type = GL_RGB;
else
            type = GL_RGBA;
        //type = GL_RGB;
 
        glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
 
        if(!*textureid)glGenTextures( 1, textureid );
        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
 
        glBindTexture( GL_TEXTURE_2D, *textureid);
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
       
        /*if(trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
        if(!trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
        if(!mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );*/
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
 
        glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0,
                  type, GL_UNSIGNED_BYTE, texture.data);
 
        //senquack - Disabled this, and main menu crashes went away
//gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, type, GL_UNSIGNED_BYTE, texture.data );
/*gluBuild2DMipmaps(GLenum target, GLint internalFormat,GLsizei width, GLsizei height,GLenum format, GLenum type, const void *data)*/

        textures.insert(std::make_pair(fname, *textureid));
    }
    else
    {
        *textureid = it->second;
    }

}

Quote
Nah, RGBA8888 or RGB888 are fine, that is the correct format for OpenGLES textures.  BGRA, however, (DirectX style pixel ordering) might not work on our GLES1, as it requires a GL extension to be present and I've never tried it under Etnaviv.  If you were using GLES2 you could easily change the texture's pixel ordering inside the pixel shader program, but the whole game would have to be ported, which wouldn't be much fun :(
Oh, okay then, no need to convert to 16-bits texture (this would have been too difficult).
BGRA doesn't seem to be used at all, thankfully.

Now i need to try this on my zero to see if the menu looks correct.

Senor Quack

  • *
  • Posts: 159
Re: Debugging OpenGLES games
« Reply #7 on: October 07, 2016, 11:54:54 PM »
Mipmaps help with performance, as a smaller size texture will be used automatically for objects farther from view, when on-screen object is tiny, allowing optimal use of texture cache/prefetch (and L1/L2 cache/prefetch on a GPU like ours sharing RAM with CPU).   So, it's definitely something to look into later when everything is working.
« Last Edit: October 08, 2016, 12:05:19 AM by Senor Quack »

gameblabla (OP)

  • *
  • Posts: 399
Re: Debugging OpenGLES games
« Reply #8 on: October 08, 2016, 08:54:55 PM »
I shall look at mipmaps again after i got everything working, yeah.

I'm making some progress with Lugaru :
I have implemented the analog stick (which emulates the mouse) so now you can go around the menu and start a game.
Unfortunely, it crashes right after you start a mission.

Plus, for some reason, i can't connect to my GCW0 using ssh now, only telnet.
Really strange...

Senor quack, how you managed to run the binary on your zero without the Can't load library error ?

Senor Quack

  • *
  • Posts: 159
Re: Debugging OpenGLES games
« Reply #9 on: October 09, 2016, 01:42:11 PM »
Plus, for some reason, i can't connect to my GCW0 using ssh now, only telnet.
Really strange...
Senor quack, how you managed to run the binary on your zero without the Can't load library error ?


First, I would advise changing the following three lines like so, as if you have both a Dingoo A320 and GCW0 toolchain in your path, it will use the wrong compiler depending on which toolchain is first in your path:
#CXX = mipsel-linux-g++
#CC = mipsel-linux-gcc
#LD = mipsel-linux-g++
TOOLCHAIN = /opt/gcw0-toolchain
CXX = $(TOOLCHAIN)/usr/bin/mipsel-linux-g++
CC = $(TOOLCHAIN)/usr/bin/mipsel-linux-gcc
LD = $(TOOLCHAIN)/usr/bin/mipsel-linux-g++

Then, I modified your Makefile.gcw0 to include the following lines before CFLAGS/LDFLAGS get assigned:
SDL_CONFIG = /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/sdl-config
CFLAGS += `$(SDL_CONFIG) --cflags`
LDFLAGS += `$(SDL_CONFIG) --libs`

(after this is added, you can remove the -lSDL from the LDFLAGS line you already had if you like, but I don't think it really matters)

For my purposes, I also modified the Makefile.gcw0 to not make an OPK and upload it automatically, just a bare binary.

I made a folder in my home dir called lugaru, and I uploaded all the files in the opk/ directory to it. Then, I compiled and uploaded a binary lugaru-bin..  I just telnet in and run it, no problem even using gdb.  I'm running a stock 2014 firmware on a dev unit.   What are the errors it is giving you, specifically?
« Last Edit: October 09, 2016, 02:17:18 PM by Senor Quack »

gameblabla (OP)

  • *
  • Posts: 399
Re: Debugging OpenGLES games
« Reply #10 on: October 09, 2016, 08:14:08 PM »
Plus, for some reason, i can't connect to my GCW0 using ssh now, only telnet.
Really strange...
Senor quack, how you managed to run the binary on your zero without the Can't load library error ?


First, I would advise changing the following three lines like so, as if you have both a Dingoo A320 and GCW0 toolchain in your path, it will use the wrong compiler depending on which toolchain is first in your path:
#CXX = mipsel-linux-g++
#CC = mipsel-linux-gcc
#LD = mipsel-linux-g++
TOOLCHAIN = /opt/gcw0-toolchain
CXX = $(TOOLCHAIN)/usr/bin/mipsel-linux-g++
CC = $(TOOLCHAIN)/usr/bin/mipsel-linux-gcc
LD = $(TOOLCHAIN)/usr/bin/mipsel-linux-g++

Then, I modified your Makefile.gcw0 to include the following lines before CFLAGS/LDFLAGS get assigned:
SDL_CONFIG = /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/sdl-config
CFLAGS += `$(SDL_CONFIG) --cflags`
LDFLAGS += `$(SDL_CONFIG) --libs`

(after this is added, you can remove the -lSDL from the LDFLAGS line you already had if you like, but I don't think it really matters)

For my purposes, I also modified the Makefile.gcw0 to not make an OPK and upload it automatically, just a bare binary.

I made a folder in my home dir called lugaru, and I uploaded all the files in the opk/ directory to it. Then, I compiled and uploaded a binary lugaru-bin..  I just telnet in and run it, no problem even using gdb.  I'm running a stock 2014 firmware on a dev unit.   What are the errors it is giving you, specifically?

Thanks Senor Quack !
Sadly though, it does not run under telnet.
I made your changes, uploaded the executable to a home directory with all the data on it, ran chmod +x on the executable.
I opened the terminal app on my zero and ran Lugaru but it refuses to run the executable :
Quote
./lugaru-bin: can't load library 'glGetIntegerv'

Btw, i had manually flashed my GCW0 and it is still the same.
I feel like we are not using the same toolchain ? I took it from the officla gcw-zero.com website.

Anyway, could somebody debug it for me and tell me what's wrong ?
Or at least has an idea as how to with it works on Senquack's GCW0 but not mine ?
The game runs from an OPK file btw.
Thanks

 

Post a new topic
Post a new topic