English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 24 December 2021, 22:00   #1
mateusz_s
Registered User
 
Join Date: Jan 2020
Location: Poland
Posts: 181
[RTG] Need help with double/triple buffering to avoid tearing in RTG modes..

Hello,
I successfuly used triple buffering to avoid screen tearing on my FPS raycaster engine... but it works only below certain fps like 200 fps in 320x200x32

The Emu68 was able to run much above 200 fps in some moments but then the tearing was noticable. I tried on V1200 (when floor was turned off) and I got like 170-180 fps and no tearing effect. So let say that below that value triple buffering is enought.

I tried many different approaches. Right now I am using this one:
http://eab.abime.net/showthread.php?t=109186
(I changed it from double to triple buffering)

Do you know any better way? or how to correct this double buffering code?
Please note that when I run the orginal double buffered code I got tearing in 60-80 fps so that was not enough. I got rid of it making triple buffering. But again its not enought for higher rates.

this is example of tearing in over 200 fps (about 0:14s)
as you can see when resolution is higher the fps drops
so no tearing is visible no more:
[ Show youtube player ]
mateusz_s is offline  
Old 24 December 2021, 23:22   #2
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
P96 has a bug when allocating multiple buffers in early releases, I think. Try allocating a triple-tall buffer and scroll the view super-bitmap style to access the buffers stacked vertically.
Samurai_Crow is online now  
Old 25 December 2021, 00:18   #3
mateusz_s
Registered User
 
Join Date: Jan 2020
Location: Poland
Posts: 181
Quote:
Originally Posted by Samurai_Crow View Post
P96 has a bug when allocating multiple buffers in early releases, I think. Try allocating a triple-tall buffer and scroll the view super-bitmap style to access the buffers stacked vertically.
Do you mean problems with AllocScreenBuffers? I noticed that its not allocating them ( only if it connected with screen bitmap).. but thats no problem, because after AllocScreenBufeer i am allocating nitmaps myself and then switching the pointer in screenbuffer structure. So I am Ok with that.

The double or triple buffering works overall.. the problem is with switching buffers sync.

For example the Payback game (Amiga 3d GTA clone) works ultra fast in 320x200 or 640x400 and no tearing occurs
mateusz_s is offline  
Old 25 December 2021, 10:31   #4
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,215
Quote:
Originally Posted by mateusz_s View Post
Hello,
I successfuly used triple buffering to avoid screen tearing on my FPS raycaster engine... but it works only below certain fps like 200 fps in 320x200x32

There is none, or none that works in general. To avoid tearing, you need to synchronize to the vertical sync of the screen, which would limit you to the vertical refresh frequency of the screen. It does obviously not make sense to refresh the screen more often because the result would not be visible anyhow.


The typical approach of syncing to vertical sync is either WaitTOF() or WaitBOVP(), both in the graphics.library. WaitTOF() has unfortunately the issue that it waits for a vertical raster interrupt of the corresponding VGA chip that drives the graphics, but not all RTG cards have this interrupt connected, so it does not work in all cases. For cards that cannot generate interupts, WaitTOF() falls back to the system WaitTOF(), i.e. it waits for the vertical retrace of the native chipset then.


WaitBOVP() works always, but it is a busy-wait, by continuously polling the vertical scan position of the RTG chipset, and returning only at the end of the display. This means that it burns a lot of CPU time.
Thomas Richter is offline  
Old 25 December 2021, 13:24   #5
mateusz_s
Registered User
 
Join Date: Jan 2020
Location: Poland
Posts: 181
Quote:
Originally Posted by Thomas Richter View Post
There is none, or none that works in general. To avoid tearing, you need to synchronize to the vertical sync of the screen, which would limit you to the vertical refresh frequency of the screen. It does obviously not make sense to refresh the screen more often because the result would not be visible anyhow.


The typical approach of syncing to vertical sync is either WaitTOF() or WaitBOVP(), both in the graphics.library. WaitTOF() has unfortunately the issue that it waits for a vertical raster interrupt of the corresponding VGA chip that drives the graphics, but not all RTG cards have this interrupt connected, so it does not work in all cases. For cards that cannot generate interupts, WaitTOF() falls back to the system WaitTOF(), i.e. it waits for the vertical retrace of the native chipset then.


WaitBOVP() works always, but it is a busy-wait, by continuously polling the vertical scan position of the RTG chipset, and returning only at the end of the display. This means that it burns a lot of CPU time.
Thanks for help. I didnt Try but Maybe putting WaitBOVP() in separate task would not affect the main loop.
mateusz_s is offline  
Old 25 December 2021, 14:24   #6
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
Quote:
Originally Posted by Thomas Richter View Post
WaitBOVP() works always, but it is a busy-wait, by continuously polling the vertical scan position of the RTG chipset, and returning only at the end of the display. This means that it burns a lot of CPU time.

Why can't WaitBOVP() poll position once, calculate how much time is left until end of display and then wait using timer.device?
aros-sg is offline  
Old 25 December 2021, 15:12   #7
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Quote:
Originally Posted by aros-sg View Post
Why can't WaitBOVP() poll position once, calculate how much time is left until end of display and then wait using timer.device?
Because timer.device doesn't support the timing resolution needed. You could try using a CIA timer to do that though.
Samurai_Crow is online now  
Old 26 December 2021, 10:06   #8
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,215
Well, there is a timer.device unit that supplies below-frame resolution, because it is actually based on the CIA timers. That is timer.device unit 1.

But, all that aside, it doesn't solve the problem. Just because main thread waits does not save you from burning CPU time in a side thread, CPU time that is not available for anything else. We only have a single CPU core, and this is with the suggested design simply busy by polling the VGA registers - either in a separate thread, or in the main thread.
Thomas Richter is offline  
Old 26 December 2021, 13:20   #9
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
No, no. That's not what I mean. If WaitBOVP() polls scan position once, shouldn't it be able to figure out how much time will need to pass until scan position will reach bottom of viewport and then just wait that amount of time using timer.device. So for example if the polled scan position indicates that you are on line number 200, and you know that bottom of viewport is line number "x" (for example 400) and that one frame lasts time "t" (and how much time one line lasts), do the math to calculate how much time will need to pass until that point in time. And then just wait this amount of time. No busy polling.
aros-sg is offline  
Old 26 December 2021, 22:45   #10
hooverphonique
ex. demoscener "Bigmama"
 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
Quote:
Originally Posted by aros-sg View Post
Why can't WaitBOVP() poll position once, calculate how much time is left until end of display and then wait using timer.device?
Well, I think you should be able to eliminate a great deal of busy-waiting by delaying until close to BOVP, then busy-wait for the rest to get an exact result.
hooverphonique is offline  
Old 27 December 2021, 00:17   #11
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,215
Quote:
Originally Posted by aros-sg View Post
No, no. That's not what I mean. If WaitBOVP() polls scan position once, shouldn't it be able to figure out how much time will need to pass until scan position will reach bottom of viewport and then just wait that amount of time using timer.device.
The problem with this approach is that there is no publicly available API to request the current scan position. I could add one the Picasso96API.library, though, as in principle this information is available at driver level. Well, almost always, the pre-3.1.0 CVision3D driver did not supply this information for Zorro-II due to some idiocracies of the card. But this will probably not happen before the 3.3.0 release of P96, and that's a bit away. I'm currently only making bug fixes and do not add features, too late for 3.2.0.
Thomas Richter is offline  
Old 27 December 2021, 07:34   #12
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
Quote:
Originally Posted by Thomas Richter View Post
The problem with this approach is that there is no publicly available API to request the current scan position.
Why does it need to be public? The poll-scan-position-once-then-calc-delay-then-wait-with-timerdevice-thing only needs to be done internally inside the WaitBOVP() function (and maybe inside WaitTOF()) too), for gfx cards where interrupt does not work. Not by apps themselves.

You said "WaitBOVP() works always, but it is a busy-wait, by continuously polling the vertical scan position of the RTG chipset", so WaitBOVP() already has the means to request the current scan position.
aros-sg 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
How can I use RTG modes? Foebane support.WinUAE 2 14 December 2018 15:32
Tearing in double/triple buffered screen with WinUAE 4.0.1 (issue from 4.0.0b8+) Leandro Jardim support.WinUAE 14 18 September 2018 13:28
No RTG video modes whizkid support.WinUAE 8 24 August 2017 16:15
Scaling in RTG modes mark_k support.WinUAE 4 08 March 2012 15:57
Paula audio in RTG modes Mad-Matt support.WinUAE 8 13 May 2007 15:28

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 04:39.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.08577 seconds with 15 queries