Weird screen behavior
-
- Posts: 107
- Joined: Sat Jan 13, 2007 11:50 am
Thanks a lot for that!Raphael wrote:I took a look into JGE render setup and everything that happens in the hello world sample.
Thanks. I will try to clean that up.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.
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.- 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.
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 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.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'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 ?
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 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.
I guess you are right, JGE wasn't meant to be restarted during one program cycle.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.- 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.
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.
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).
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.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.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'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 ?
However, as it seems, this fix also completely fixes the occurance of the PSD in JGE.
I meant that is what the SDK should have been doing (and is doing now).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 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.
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
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
I'll respond to this today evening, as I don't have my personal e-mail account login with me at work.yeshua wrote:http://wololo.net/forum/viewtopic.php?f ... 8089#p8087
You may want to respond to this Raphael...
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
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
-
- Posts: 107
- Joined: Sat Jan 13, 2007 11:50 am
Yes, thank you very much!Raphael wrote: At least I'm glad I could help you get rid of that nasty bug :)
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 :)
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?
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?
-
- Posts: 107
- Joined: Sat Jan 13, 2007 11:50 am
I took a quick look into the PSPSDK SVN revision log, but couldn't find anything related to that back from 2years.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?
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
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl