gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > heavy CPU usage and video flickering

#143512 - conejoroy - Tue Oct 23, 2007 1:54 am

Hello =)

I'm using mode 5, some sprites and a single background. once in a while I've to do a software drawing of some text on a buffer and, when drawn, that buffer is uploaded to sprite memory and used as a sprite thereafter. this process is expensive and every time it happens the screen flickers noticeably.

in fact it seems to me that it's spending more than 1/60 of a second of CPU time right? t.t?

so my question is... every task on the CPU needs to finish on a certain amount of time to avoid flickering? there is a way to delay the 2D engine or maybe making it stop refreshing? or perhaps using some kind of interrupt to stop the CPU when the graphic engine needs to draw? ._.?

how could be solved?

well thanks =)!

#143513 - tepples - Tue Oct 23, 2007 2:01 am

Try using two sprite cels in sprite VRAM. Draw to one and display the other. Or do you not have enough VRAM to double-buffer sprites that need it?

What method are you using to copy sprite cel data into VRAM? Is it memcpy(), DMA, or something else?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#143518 - conejoroy - Tue Oct 23, 2007 4:37 am

tepples wrote:
Try using two sprite cels in sprite VRAM. Draw to one and display the other. Or do you not have enough VRAM to double-buffer sprites that need it?

What method are you using to copy sprite cel data into VRAM? Is it memcpy(), DMA, or something else?


thanks ^^ I'm using several 32x16 vram sprite cells to form a sentence and a single 32x16 buffer in main memory to do a software blitting of every char that fits in a cell. but even if I just draw and update a single cell, the flickering does not ocurr in the sprite, but in the whole background instead (and it's very noticeable and annoying).

I'm using swiCopy to copy that 32*16 bytes of main memory to VRAM.

I was wondering if this flickering is the result of that very slow software blitting (busy CPU in a large period of time.. although about 5000 pixels 1 byte at once doesn't seem overkill to me) or maybe is something else...

#143520 - jetboy - Tue Oct 23, 2007 6:49 am

conejoroy wrote:


I'm using swiCopy to copy that 32*16 bytes of main memory to VRAM.

(busy CPU in a large period of time.. although about 5000 pixels 1 byte at once doesn't seem overkill to me)


1 byte a time? @_@ You got your answer here!
You would beter do all the drawing in main memory buffer, then copy all of that with one dma copy (and you need to do it durring vblank).
_________________
Colors! gallery -> http://colors.collectingsmiles.com
Any questions? Try http://colors.collectingsmiles.com/faq.php first, or official forums http://forum.brombra.net

#143521 - conejoroy - Tue Oct 23, 2007 8:31 am

jetboy wrote:

1 byte a time? @_@ You got your answer here!
You would beter do all the drawing in main memory buffer, then copy all of that with one dma copy (and you need to do it durring vblank).


yes, that's exactly what I'm doing, drawing on a main memory buffer (it could be optimized but for now I'm drawing 1 pixel at once) then uploading the buffer with swiCopy, swiFastCopy, dma, memcpy, it doesn't matter, the result is more or less the same, a strange flickering in the background.

the "flicker" is like a very fast translation (1 frame or so) of the background at scanline 140 or 150 and then back to normal (which, running at 60 fps, produces a "flicker" effect)

something funny: I found a relation between the code I comment or remove from the function that parse text and draws, and the "translation" of the background. with minimum code there is no artifacts or the translation is at scanline 1 or 2, without drawing at all or copying the buffer to vram (!!) its at about 50 or 60... it's driving me nuts x.x

well thanks =)

#143526 - conejoroy - Tue Oct 23, 2007 9:16 am

update:

same of the above but now it hangs. what I've done? nothing.. just commented out some debugging output on sub screen. (I always tested it on hardware).

The function I call to parse and draw takes 7 parameters (unsigned chars and some pointers) and then declares like 10 local variables and calls another function with 6 o 7 parameters which in turn calls another function... well nothing so terrible.

I had a very strange problem... somehow I could only read the first 8 bytes of a string pointer (the text to draw) passed to that function. So I rearranged the local variable declarations and "it worked" but somehow now it simply hangs.

as a side note the code works perfect, at least compiled for PC (the only "platform dependant" parte being just the upload to vram).

The flickering background could have any relation to this? there is any fixed limit to the stack or maybe I'm just overlooking something? ._.?

well thanks again =)

#143527 - simonjhall - Tue Oct 23, 2007 9:33 am

If it's anything like using texturing system on the 3D hardware, you've got to do your drawing during a small window of time during the frame. When are you drawing your data? I can easily make the (2D) display flicker if I do drawing outside of the vblank...
_________________
Big thanks to everyone who donated for Quake2

#143529 - Dark Knight ez - Tue Oct 23, 2007 9:55 am

dmaCopy, swiCopy, what-not... I consider them all to be evil.
Call it misuse, or whatever, but whenever I used them, they simply failed to work on some setups, sometimes even crashing them.
Meaning that if it happens to work on _your_ setup, it might not on others. And if you make slight changes in your code, it suddenly might fail for you to.
I believe that's what happened, conejoroy. Just use a simple for-loop which copies 2 bytes at a time.

Anyway, on the actual topic at hand, try doing the "sprite blitting" right after vblank if you can... all drawing functionality should be right after vblank anyway, and the game logic following the drawing functions. That way you stay out of trouble as much as possible.
_________________
AmplituDS website

#143530 - simonjhall - Tue Oct 23, 2007 10:16 am

Ah, you can't beat DMA...once you know what you're doing! I just think people just jump straight to using DMA or SWI copy straight away before they've got the rest of their program sorted, or have identified the need to require some kind of fast copy. Also it doesn't help that DMA is asynchronous and isn't cache-coherent.
You can't beat memcpy :-)
_________________
Big thanks to everyone who donated for Quake2

#143531 - Dark Knight ez - Tue Oct 23, 2007 10:36 am

Or in the case of copying to VRAM, a for-loop. ;) memcpy's not good for that.
_________________
AmplituDS website

#143555 - conejoroy - Tue Oct 23, 2007 8:39 pm

Thank you all n.n!!

Yes I was warned about the evil'ness of swiCopy, dma and friends... but I never thougth they could have that potential to bug a program. and although I can comment that particular "buffer to vram" swiCopy/dma/whatever and the program is still buggy or will hang, I'm still using swiCopy/dma when uploading palettes (which happens only once) or updating OAM (once per frame after vBlank).

All of this functions (palette, text generation, etc) are called from lua. I'm doing something similar to "DSLua" so right from the start I assumed LUA wont be a problem.


So my determinations are:

- Remove evil functions that can cause strange or erratic behaviour (I'll use for loops of half words at once as Dark Knight ez suggested) no not even a single swiCopy or DMA or memcpy, even on main memory to main memory copies (now I don't trust them =p).

- Software draw one cell per frame, update to VRAM in the next, right after swiWaitForVBlank() taking the suggestion of simonjhall.

- Jump out of the window if everything else fails t.t

Thanks again n.n!!

#143654 - HyperHacker - Thu Oct 25, 2007 1:33 am

Wait, what's the problem with DMA? I dmaCopy() 96K from main RAM to VRAM every now and then and it works just fine, and much faster than a for loop (especially using all 4 channels at once :-D). It does have some graphical glitches when using a ton of CPU power, but it only uses that much because of a bug anyway. <_< If memcpy() is breaking things then you may have corrupted something.
_________________
I'm a PSP hacker now, but I still <3 DS.

#143686 - conejoroy - Thu Oct 25, 2007 9:08 am

yes maybe this is the case =p

no more swiCopy or DMA, no more glitches.. but the bug is still there and it's messing my code t.t

the "bug" can for example modify the contents of a variable. this is noticeable because this var controls text alignment and it is passed "as is" to the text generation function (I don't touch it in any part inside of the function). it could be set to 0, but then the text displays vertically aligned (flag 0x1), so somehow, it now has bit 0 set t.t

when I do a iprintf with that var it ignores the whole call to the function! it doesn't even print a thing! as if the processor was jumping parts of the code O_O

in another reincarnation of the bug, I can only read half of a string passed as a pointer to that function and the next is garbage, this is done right at the beginning (so no... it's not the execution of the logic inside of the function the problem right? t.t)

or it could hang in many ways in any part of the function depending on how much debugging code I add/remove. but always, always inside of that function... the rest of the code seems to work just fine.

tested with devkitarm 20 and now 21, same results. tested on PC and the logic and everything seems to work perfect.

really don't know what's happening, that's why I was asking if there is any limitation code-wise I'm not aware of t.t

these are the symtoms... what is the diagnosis? =p

well thanks t.t!

#143688 - simonjhall - Thu Oct 25, 2007 9:28 am

Sounds like some kind of stack corruption to me... Can you reproduce this bug? Can you slim the program down to a small enough example that can produce this?
Quote:
Wait, what's the problem with DMA?
Nothing, technically. I myself have never had a problem with it...
The real problem is that many people are unaware of how it works and what restrictions are placed on it. There are plenty of threads on here where people are having 'weird problems' with their toy DS program, and haven't realised that the culprit is using a DMA copy when they didn't really need it (and didn't realise it wasn't cache coherent).
_________________
Big thanks to everyone who donated for Quake2

#143748 - HyperHacker - Thu Oct 25, 2007 8:24 pm

By not being cache coherent you mean it ignores the cache and reads from memory directly? That might actually explain one glitch I've noticed. >_>
_________________
I'm a PSP hacker now, but I still <3 DS.

#143762 - tepples - Thu Oct 25, 2007 9:41 pm

HyperHacker wrote:
By not being cache coherent you mean it ignores the cache and reads from memory directly?

Yes. But would something like this (untested) help?
Code:
static inline void dmaCopyCoherent(const void *src, void *dst, size_t size) {
  DC_FlushRange(src, size);
  dmaCopy(src, dst, size);
  DC_InvalidateRange(dst, size);
}

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#143795 - conejoroy - Fri Oct 26, 2007 2:14 am

simonjhall wrote:
Sounds like some kind of stack corruption to me... Can you reproduce this bug? Can you slim the program down to a small enough example that can produce this?


Yes that's what I thought.. maybe I'm asking for more memory than the stack can hold (well It's just a guess t.t)

I'll try to reproduce it calling that function in a stand-alone program, not from LUA.

Now I'm doing this:

Main Loop -> Calling a LUA function -> that funtions calls another LUA funcions -> that in turn calls this problematic function, that declares many local variables and calls another C function... maybe I'm asking too much xD

Thanks =)

#143802 - HyperHacker - Fri Oct 26, 2007 6:25 am

tepples wrote:
HyperHacker wrote:
By not being cache coherent you mean it ignores the cache and reads from memory directly?

Yes.
Ah, I think I know what's been breaking my graphics then. X-)
_________________
I'm a PSP hacker now, but I still <3 DS.