English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 14 December 2019, 00:07   #1
jotd
This cat is no more
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 48
Posts: 3,547
How to avoid flickering when using blitter directly?

I'm poking the blitter directly on an intuition screen.


Using Own/Disown blitter each time I'm accessing it. Multitasking still runs.


I'm using WaitTOF() to sync speed & be aware that I must redraw (to avoid blinks). It works most of the time but sometimes the display still blinks.


Is that the proper method? how to "emulate" it? by checking VPOS? if so how?
jotd is offline  
Old 14 December 2019, 02:47   #2
Chrille
Registered User

 
Join Date: Sep 2018
Location: Germany
Posts: 33
I think the proper method is using double buffering.

When I wrote such things (>20 years ago), I used ChangeVPBitMap() (only OS 3.0 / V39). May be there exists something similar on OS before V39.

Also notice if you would like to write a game, that this is very unusual. The only game I know, which is not using double buffering, is The Great Giana Sisters. May be Katakis (which uses dual play-fields). And i think also Hard'n'Heavy, which is nearly using the same code as Giana Sisters. And these games use direct hardware access instead of OS functions. Also all programs, which have not full frame-rate (50FPS/60FPS) use double buffering by design

btw because Giana Sisters is not using double buffering, the lag between joystick control and the display should be very small, I guess.

Which kind of program are you writing and what is your target system?
Chrille is offline  
Old 14 December 2019, 04:58   #3
Bruce Abbott
Registered User

Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 297
Large blits can take significant time to execute, and flickering may occur if the beam gets to where the blit is before it's finished.

What are the machine specs (cpu, chipset, OS etc.), color depth, screen mode, blit size and position? Can you show us your code?
Bruce Abbott is offline  
Old 14 December 2019, 11:03   #4
jotd
This cat is no more
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 48
Posts: 3,547
I'm porting "Bagman" to amiga. My code is C++ but I think you'll have a hard time to untangle everything, with objects and all.

ATM I think I'm wasting some time (had this idea tonight) because I'm waiting for TOF then computing THEN displaying. Whereas I should wait for TOF, display, then compute

Yeah, double buffering could be an idea, but the game has very few animation (just sprites/BOBs, no scrolling) and I'm not blitting the background everytime, just around the characters.

I'm using 32 colors, but it's only using 18 or 19. I think I can reduce to 16 to save a bitplane.

The specs of the machine are: the smallest possible ideally A500 and if it's not possible vanilla A1200.

Maybe OwnBlitter/DisownBlitter at each blit is a bit excessive? this may introduce overhead.
jotd is offline  
Old 14 December 2019, 13:28   #5
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,633
Quote:
Originally Posted by jotd View Post
The specs of the machine are: the smallest possible ideally A500 and if it's not possible vanilla A1200.

Maybe OwnBlitter/DisownBlitter at each blit is a bit excessive? this may introduce overhead.
It would certainly be worth a try, Amiga OS might be quite good but on an A500 it's still quite 'heavy'.

Considering the amount you'd need to blit for this game I find it extremely unlikely that the A500 can't handle the blitting so it pretty much has to be other overhead.

Another, more extreme, option could be to own the Blitter and forbid multitasking during blitting (and enable it outside of blitting). That way the blitting won't get interrupted by other tasks. Or use double buffering, but that was already offered as an idea
roondar is offline  
Old 14 December 2019, 16:20   #6
Chrille
Registered User

 
Join Date: Sep 2018
Location: Germany
Posts: 33
Quote:
Originally Posted by jotd View Post
Yeah, double buffering could be an idea, but the game has very few animation (just sprites/BOBs, no scrolling) and I'm not blitting the background everytime, just around the characters.
Ok, you target system is A500 Kick1.2 (V34). I can't remember exactly, but I think the OS-friendly way is using RethinkDisplay() for double buffering on v34. IIRC RethinkDisplay() costs more cpu time than ChangeVPBitMap() Also the disadvantages of double buffering are:
- it introduces a lag of 20ms (Pal) or 16,6 ms (NTSC) or less on screen modes like euro72
- wasting chip ram for one extra buffer
On the other hand, you have not to take care about any screen flickers.

Quote:
Originally Posted by jotd View Post
ATM I think I'm wasting some time (had this idea tonight) because I'm waiting for TOF then computing THEN displaying. Whereas I should wait for TOF, display, then compute
I think this is a good idea.

May be an idea for optimizing it, that you can wait for bottom of frame instead of top of frame. I forgot most of those things, but i would try to insert a copper command to trigger a level 3 interrupt and then signal() your task. But I don't know it is worth the effort and I have no idea how to implement it on any OS.

If you are not coding OS-friendly, you could use you own copper list. IIRC this could be done by using LoadView() also if you want to switch back to the OS.

Also I would try roondars advise to call a forbid() before blitting, at least for testing.
Chrille is offline  
Old 14 December 2019, 18:00   #7
jotd
This cat is no more
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 48
Posts: 3,547
thanks for the advice. I'm currently using intuition screen memory, but I'm not fixed on it.

I'll try to reduce the display depth first. Then I'll do double buffering if needed, using copperlist & hardware screen.

I was pretty sure that WaitTOF wasn't the best candidate. Some WaitBOF routine would be a plus... but with the OS running that seems difficult.

I've tried to compute & draw in VBLANK system interrupt but that pretty much crashed too
jotd is offline  
Old 14 December 2019, 18:55   #8
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,168
Have you looked into using QBSBlit()? That's what Workbench uses when you drag icons around. You can have your blits initiated immediately after the raster beam passes. Much better timing-wise than waiting for the start of frame with WaitTOF() (which busy-waits).

Also, use interleaved screen/bitmap so each object can be done with a single blit, as opposed to one per bitplane. That can be done "properly" on Kickstart 3.0+, but you could probably get it to work on Kickstart 2.04 too. Not sure about 1.2/1.3. (I seem to remember reading something about The Disney Animation Studio managing to use interleaved display on at least Kickstart 2.)

Maybe if you use your own View (as opposed to Screen) interleaved bitplanes will be no problem on Kickstart 1.x?
mark_k is offline  
Old 14 December 2019, 19:48   #9
jotd
This cat is no more
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 48
Posts: 3,547
> interleaved screen/bitmap so each object can be done with a single blit

Whaat? can you explain more?
jotd is offline  
Old 14 December 2019, 21:38   #10
Chrille
Registered User

 
Join Date: Sep 2018
Location: Germany
Posts: 33
Quote:
Originally Posted by jotd View Post
> interleaved screen/bitmap so each object can be done with a single blit

Whaat? can you explain more?
I'm not mark_k, but may be I can explain interleaved screens. They are using a structure like this:
1. Line Bitplane 1
1. Line Bitplane 2
..
1. Line Bitplane n
2. Line Bitplane 1
2. Line Bitplane 2
...
2. Line Bitplane n
...
You can minimize the flickering, but there is at least tearing when you blit into lines which are displayed.

Also your BOBs must have this structure
1. Line Bitplane 1
1. Line Bitplane 2
...
1. Line Bitplane n
2. Line Bitplane 1
2. Line Bitplane 2
...
2. Line Bitplane n times
...

and also the mask of the BOB must have a changed structure
1. line mask
1. line mask again
1. line mask again
...
1. line mask again (n-times)
2. line mask
2. line mask again
...
2. line mask again (n-times)
...

This is archived by using the appropriate modulos. So the modulos for bitplanes are something like n-1*line width in bytes instead of 0.
The disadvantage is that you are using more memory for the masks.
Then you can render a single bob with a single blit instead of n blits.

Interleaved bitmaps and BOBs are used in every (technically) good game, e.g. X-Out, Turrican, Brian the Lion, Apidiya and so on ...
Chrille is offline  
Old 15 December 2019, 00:14   #11
jotd
This cat is no more
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 48
Posts: 3,547
wow sounds impressive but pretty complex... damn bitplanes...

Seems like double buffering (with a tiny delay for responsive controls) is the only way. that's really a bummer since I almost got rid of the flickering with a VHPOS test, but my display is too high and I can't find a value of VHPOS to wait for. Without vertical overscan, there's plenty of time to blit stuff around, but not when most of the vertical lines are busy displaying something...
jotd is offline  
Old 15 December 2019, 00:56   #12
Antiriad_UK
OCS forever!

Antiriad_UK's Avatar
 
Join Date: Mar 2019
Location: Birmingham, UK
Posts: 179
I think interleaved bitplane data are used for 99% of demos/games. It's just way more efficient. If you have a BOB of 32 px high in 5 bitplanes and you want to blit that with non-interleaved its:
blit bpl1 32px
blitwait
blit bpl2 32px
blitwait
blit bpl3 32px
blitwait
blit bpl4 32px
blitwait
blit bpl5 32px
blitwait

Which is a pain. But with interleaved you go
blit 160px
which gives more time to do something constructive with the CPU.

This image kind of explains it: http://megaburken.net/~patrik/Scroll...nterleaved.gif but I think about it differently. I think of it as bitplanes side-by-side rather than one after another and then it doesn't seem quite so different.

Last edited by Antiriad_UK; 15 December 2019 at 01:04.
Antiriad_UK is offline  
Old 15 December 2019, 02:25   #13
Chrille
Registered User

 
Join Date: Sep 2018
Location: Germany
Posts: 33
Quote:
Originally Posted by Antiriad_UK View Post
Which is a pain. But with interleaved you go
blit 160px
which gives more time to do something constructive with the CPU.
Hmm, but if blitter has priority over cpu, the CPU gets no (or nearly no) memory cycles, if you have only chip ram. But yes if you have fast ram, you can do something constructive. Also no DMA-Cycles are lost, because the blitter is not loosing cycles when the blit starts again and again IIRC there are some cycles lost when the blitter is started and when it finishes the blit (may be 2-6 cycles/memory accesses or so). Also you have not to write to the blitters registers again and again, which is consuming the most of the time, I think.

@jodt may be you can save also some time to give the blitter priority over CPU, if you have not already done this. The OS gives the blitter not the priority, but if you are using WaitBlit() [graphics.library], it does not matter because ROM is like fast ram and CPU does not steal any cycles of the blitter in this case.
Chrille is offline  
Old 15 December 2019, 11:16   #14
Antiriad_UK
OCS forever!

Antiriad_UK's Avatar
 
Join Date: Mar 2019
Location: Birmingham, UK
Posts: 179
Quote:
Originally Posted by Chrille View Post
Hmm, but if blitter has priority over cpu, the CPU gets no (or nearly no) memory cycles, if you have only chip ram. But yes if you have fast ram, you can do something constructive. Also no DMA-Cycles are lost, because the blitter is not loosing cycles when the blit starts again and again IIRC there are some cycles lost when the blitter is started and when it finishes the blit (may be 2-6 cycles/memory accesses or so). Also you have not to write to the blitters registers again and again, which is consuming the most of the time, I think.
True the multiple setup/stop is probably the most likely and reliable saving. But in a massive clear/or basic fill then there's quite a usable overlap. In my simple vector routine all the music/rotate/perspective/hiddenline stuff happens during the clear screen. Then I've got some intro scripting/palette changing/copperlist writing during the fill.

For BOB stuff into ABCD source territory then yeah it's pretty much locked out of chipram. But still gets time during horizontal blank (I believe?) and the odd cycle if not using blitter nasty (I only use blitter nasty during blitwaits). I'd rather it execute a few cpu instructions than none. You can also be lucky if you hit a big shift/muls/divs instruction as once its read the instruction it will be off the bus for quite a while. I'd always done this stuff by testing/throwing up some timing bars. This time around I'm paying more attention to the reference manual and cycle diagrams to learn more

Edit: But jotd, back to double buffering. It's tricky enough when the system is killed to race the beam to avoid double buffering and that's without the OS doing its thing in the background. I did read that the WaitTOF call only returns _after_ vertb interrupt processing has completed so depending what the Amiga OS default vertb does that might be further down the screen than expected.

Last edited by Antiriad_UK; 15 December 2019 at 11:41.
Antiriad_UK is offline  
Old 15 December 2019, 12:37   #15
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,633
Regarding Blitter/CPU priority, it all depends on what your code is doing. If you're simply blitting one object after another, setting the Blitter to have priority will usually be faster overall. If your code has other useful work it does in between blits, then it's usually faster overall to not set Blitter priority.

Also, one small word about ROM WaitBlit(): while it will access the bus a great deal less often than a Chip RAM based WaitBlit(), it will still access the bus for the test it does. This means that it will still slow down blitting compared to giving the Blitter priority, though a lot less than using your own code.
roondar is offline  
Old 15 December 2019, 12:58   #16
jotd
This cat is no more
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 48
Posts: 3,547
So if I consider that I can't avoid double buffering, can I use WaitTOF as a sync ?

I'm currently using something like this as a loop:

Code:
  while(true)
{
	 OwnBlitter();
     //WaitTOF();
	  while (true)
	    {
	      int x = custom.vhposr;
	      if (x>0xFF00) break;
	    }	  
  video_update(20);
  DisownBlitter();

}
So video_update could update one screen whereas copperlist is showing the other screen. Would this work? (I'm also not sure about the VHPOSR value)
jotd is offline  
Old 15 December 2019, 16:00   #17
Chrille
Registered User

 
Join Date: Sep 2018
Location: Germany
Posts: 33
Quote:
Originally Posted by jotd View Post
So if I consider that I can't avoid double buffering, can I use WaitTOF as a sync ?
Yes, IIRC you can use WaitTOF as a sync and you do not need to query vhposr any more. You just need to initialize two screen buffers. Render one buffer while the other buffer is displayed and change the buffers in the screens rastport after WaitTOF and may be you have to call something like RethinkDisplay() on V34 IIRC.

But remember may be I'm wrong, as this is for me longer than 20 years ago and I think i have forgotten too many things. May be someone can help you, who is actively developing newer code. I can only help you when you are using ChangeVPBitMap() as I could look into the source of my unfinished game as a reference. Other things I can tell is more guessing than knowing.
Chrille is offline  
Old 15 December 2019, 23:27   #18
Asman
68k

Asman's Avatar
 
Join Date: Sep 2005
Location: Somewhere
Posts: 717
Quote:
Originally Posted by jotd View Post
wow sounds impressive but pretty complex... damn bitplanes...

Seems like double buffering (with a tiny delay for responsive controls) is the only way. that's really a bummer since I almost got rid of the flickering with a VHPOS test, but my display is too high and I can't find a value of VHPOS to wait for. Without vertical overscan, there's plenty of time to blit stuff around, but not when most of the vertical lines are busy displaying something...
Double buffering is not for free . Handling of animation objects will be more complicated than in one screen. I mean about cases when objects/items should be removed from dbl buffering screen.
Asman is offline  
Old 15 December 2019, 23:39   #19
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,168
Quote:
Originally Posted by jotd View Post
> interleaved screen/bitmap so each object can be done with a single blit

Whaat? can you explain more?
If you do things the system-legal way, graphics.library will handle the blits for you.

(This is on Kickstart 3.0+)
Open your Screen with SA_INTERLEAVED tag to have it use interleaved bitplances.
Allocate memory for BitMaps with AllocBitMap(), use the BMF_INTERLEAVED flag.

Try to experiment with QBSBlit(), especially if you're blitting a relatively small number of small objects, it may be more than good enough to be (almost) flicker-free. And no busy-waiting/time-wasting WaitTOF() needed.
mark_k is offline  
Old 17 December 2019, 01:37   #20
DanScott
Lemon. / Core Design

DanScott's Avatar
 
Join Date: Mar 2016
Location: Sunny Bournemouth, UK
Posts: 539
There should be no "flickering" with a double buffered screen

With a single buffered screen, try sorting your objects from top to bottom, you may be able to blit them before the "raster" reaches and overtakes
DanScott is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Immediate Blitter & Wait for Blitter... volvo_0ne support.WinUAE 29 10 December 2018 18:56
Block ID errors, how do I avoid them? -Acid- support.Hardware 12 21 November 2015 04:23
Blitter busy flag with blitter DMA off? NorthWay Coders. Asm / Hardware 9 23 February 2014 22:05
Games To Avoid (WHDLoad) Tempest 2084 Amiga scene 42 25 August 2009 14:59
Avoid debug output? Flinx support.WinUAE 0 23 July 2002 10:35

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 11:15.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.
Page generated in 0.10074 seconds with 14 queries