Weird screen behavior

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

yeshua
Posts: 20
Joined: Mon Nov 30, 2009 10:54 am

Post by yeshua »

In all psps?
yeshua
Posts: 20
Joined: Mon Nov 30, 2009 10:54 am

Post by yeshua »

http://wololo.net/forum/viewtopic.php?f ... 8089#p8087

You may want to respond to this Raphael...
willow :--)
Posts: 107
Joined: Sat Jan 13, 2007 11:50 am

Post by willow :--) »

Raphael wrote:I took a look into JGE render setup and everything that happens in the hello world sample.
Thanks a lot for that!
Some things I found:
- The initial render setup is very rudimentary, a lot of modes aren't set explicitly. These include:
* GU_CULL_FACE and GU_CLIP_PLANES not disabled in 2D mode (but enabled, which is default anyway, in 3D mode)
* GU_COLOR_TEST, GU_ALPHA_TEST and GU_LIGHTING not disabled (though iirc they are disabled by default, still better to make it explicit)
* Most importantly: No depth buffer allocated, but GU_DEPTH_TEST not disabled and, what less people seem to know, depth writes (sceGuDepthMask(GU_TRUE)) not disabled! (On a side-note: sceGuDrawBuffer ALWAYS sets the depthbuffer to be drawbuffer+512*height*4 if it was not set before, which in the case of JGE will end up at the display buffer)
- JGfx.cpp includes both <vram.h> and <valloc.h>, which is wrong, since those are two alternative libraries to use (vram is faster, with more allocation size overhead, valloc is slower with as little as needed allocation overhead). Possibly both libraries are also linked in, so that should be changed too.
Thanks. I will try to clean that up.
- JRenderer::Destroy() is not a safe destruction of all objects involved (see below)

[...]
Regarding the new test method, which basically creates a new JRenderer every time SQUARE is pressed - the error is obviously, because the JRenderer::Destroy() function doesn't safely clean up everything, just calls sceGuTerm(). There's no freeing of allocated VRAM buffers, no freeing of allocated texture, vertices/object RAM.
This HAS TO cause some graphical glitch at some point.
Just so that we don't throw too much garbage on DR.Watson's work : JGE was never meant to be able to restart the display, and I coded this functionality very recently (2 days ago). I "did" the necessary vfree calls in Wagic's svn but I believe they haven't been correctly copied over to the "purplescreendebug" project.

Besides the frame_buffer and the disp_buffer, I believe that (please correct me if I'm wrong)
1) I shouldn't free the allocated textures (This is more or less the responsibility of the game to free its textures, rather than JGE),
2)Vertices and objects being dynamically allocated through sceGuGetMemory, I don't need to free them, especially since the "Gu Reset" call is called outside of the render process.

Regarding the look of the graphical glitch: it actually looks a lot like if the screen got rendered in 16bit mode, but displayed as 32bit (gonna try that out with a test image to verify). Hence there's also a very small possibility that it's either a bug in sceGu library or maybe even the hardware (though I'd rather not assume that).

In case the line from above fixes the error, we can be sure that the problem is that the hardwares "render buffer format" (PSM) register is at some place overwritten with a value other than 3 (NOT the buffer format variable in the sceGu context, since that one is used every frame to set the display format through sceDisplaySetFrameBuf and obviously sets 32bit correctly).

I think if it were a bug in the hardware or in the SDK, the issue would occur much more often than that, in lots of homebrews.
I've confirmed that the variables in the sceGu context do not get overwritten... is there any way that we overwrite a hardware register through a bug in the application ?
I noticed, since sceGuDrawBufferList changes the psm hardware register, but is supposed to be non-permanent (ie changed back to value given with sceGuDrawBuffer when a new display list is started with sceGuStart) it makes absolute sense to add that command in sceGuStart, since it already resets the draw buffer pointer as it's supposed to, just not the pixel format.
When you say "changed back to value given with sceGuDrawBuffer when a new display list is started with sceGuStart", do you mean that it's what the SDK should be doing but it doesn't (the bug you fixed)? Or do you mean that it's what already happens(In which case, since JGE correctly calls sceGuDrawBuffer there shouldn't be any issue?)
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

- JRenderer::Destroy() is not a safe destruction of all objects involved (see below)

[...]
Regarding the new test method, which basically creates a new JRenderer every time SQUARE is pressed - the error is obviously, because the JRenderer::Destroy() function doesn't safely clean up everything, just calls sceGuTerm(). There's no freeing of allocated VRAM buffers, no freeing of allocated texture, vertices/object RAM.
This HAS TO cause some graphical glitch at some point.
Just so that we don't throw too much garbage on DR.Watson's work : JGE was never meant to be able to restart the display, and I coded this functionality very recently (2 days ago). I "did" the necessary vfree calls in Wagic's svn but I believe they haven't been correctly copied over to the "purplescreendebug" project.

Besides the frame_buffer and the disp_buffer, I believe that (please correct me if I'm wrong)
1) I shouldn't free the allocated textures (This is more or less the responsibility of the game to free its textures, rather than JGE),
2)Vertices and objects being dynamically allocated through sceGuGetMemory, I don't need to free them, especially since the "Gu Reset" call is called outside of the render process.
I guess you are right, JGE wasn't meant to be restarted during one program cycle.
Your are also right on your two assumptions. Textures and any dynamic data should be handled by the app itself, as well as anything allocated through sceGuGetMemory not needing to get freed (most of the time the display list is declared as global array, hence is static memory which cannot be freed anyway).
Regarding the look of the graphical glitch: it actually looks a lot like if the screen got rendered in 16bit mode, but displayed as 32bit (gonna try that out with a test image to verify). Hence there's also a very small possibility that it's either a bug in sceGu library or maybe even the hardware (though I'd rather not assume that).

In case the line from above fixes the error, we can be sure that the problem is that the hardwares "render buffer format" (PSM) register is at some place overwritten with a value other than 3 (NOT the buffer format variable in the sceGu context, since that one is used every frame to set the display format through sceDisplaySetFrameBuf and obviously sets 32bit correctly).

I think if it were a bug in the hardware or in the SDK, the issue would occur much more often than that, in lots of homebrews.
I've confirmed that the variables in the sceGu context do not get overwritten... is there any way that we overwrite a hardware register through a bug in the application ?
That's actually what makes me wonder if it really is a hardware/SDK bug. Well, actually, there WAS a small SDK bug in fact (see next quote), however the cause of this isn't what happens in JGE/Hello World sample.
However, as it seems, this fix also completely fixes the occurance of the PSD in JGE.
I noticed, since sceGuDrawBufferList changes the psm hardware register, but is supposed to be non-permanent (ie changed back to value given with sceGuDrawBuffer when a new display list is started with sceGuStart) it makes absolute sense to add that command in sceGuStart, since it already resets the draw buffer pointer as it's supposed to, just not the pixel format.
When you say "changed back to value given with sceGuDrawBuffer when a new display list is started with sceGuStart", do you mean that it's what the SDK should be doing but it doesn't (the bug you fixed)? Or do you mean that it's what already happens(In which case, since JGE correctly calls sceGuDrawBuffer there shouldn't be any issue?)
I meant that is what the SDK should have been doing (and is doing now).
Basically, there are two functions that set the current render pixelformat,
sceGuDrawBuffer and sceGuDrawBufferList.
The first one is the 'static' setup you call on initialization time, which defines the default render psm. The second one is a temporary change for the lifetime of the current displaylist (like for render to texture etc.).
Up till now, a new display list was only initialized with the current drawbuffer address and size, but not the pixelformat - hence why I call it a bug.
However, since JGE nowhere uses sceGuDrawBufferList, it makes me wonder what else could change this hardware register.
Will probably need further investigation if it is of any interest.

At least I'm glad I could help you get rid of that nasty bug :)
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

yeshua wrote:http://wololo.net/forum/viewtopic.php?f ... 8089#p8087

You may want to respond to this Raphael...
I'll respond to this today evening, as I don't have my personal e-mail account login with me at work.
Thanks for the notification :)
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
willow :--)
Posts: 107
Joined: Sat Jan 13, 2007 11:50 am

Post by willow :--) »

Raphael wrote: At least I'm glad I could help you get rid of that nasty bug :)
Yes, thank you very much!

This bug has actually plagued my game (and, probably, other JGE related games) for more than one year now (I posted a screenshot of the PSD on my blog on the 15th of august 2008 !)

I confirmed adding the call at the end of "BeginScene" removes any occurrence of the issue.

Strangely, in Wagic, repeatedly restarting the GU ends up with some icons/fonts becoming garbage. These textures are stored in the VRAM, so I'm assuming my code is still doing something nasty somewhere (which could well be the root cause).

I will continue investigate and I'll update this thread if something new comes up, but I confirm that this change got rid of the Purple Screen in JGE :)
yeshua
Posts: 20
Joined: Mon Nov 30, 2009 10:54 am

Post by yeshua »

Dr Watson posted here about the issue http://forums.ps2dev.org/viewtopic.php? ... bde2bd9537

This was in '07. Willow, you said that SDK changed around that time? What do you guys know about that? Could that have caused this bug?
willow :--)
Posts: 107
Joined: Sat Jan 13, 2007 11:50 am

Post by willow :--) »

The PSP SDK changes very often.
What changed around that time was JGE. It went from version 0.2 to version 1.0.
That's far in my memory, and I didn't know PSP programming at all at that time, so I don't know what changed exactly.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

yeshua wrote:Dr Watson posted here about the issue http://forums.ps2dev.org/viewtopic.php? ... bde2bd9537

This was in '07. Willow, you said that SDK changed around that time? What do you guys know about that? Could that have caused this bug?
I took a quick look into the PSPSDK SVN revision log, but couldn't find anything related to that back from 2years.
Actually I'm pretty sure nothing has changed to cause that behaviour of sceGuStart/sceGuDrawBuffer(List), rather the code was like that from the beginning.
As I stated in my post on the wagic forums, it's pretty unlikely that misbehaviour of pspgu was to be found in a normal way, since whenever you use sceGuDrawBufferList for some render to texture effects you *normally* switch back to your framebuffer renderformat with sceGuDrawBufferList again to finish rendering the current frame.

I'm still guessing there's another little software bug in JGE or Wagic that has caused that bug to appear (and appear so relatively steadily and reproducible), though a hardware glitch is not completely impossible to be the root (though more unlikely).
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Post Reply