Page 1 of 1
Mode 13h : Double buffer flickering horribly on VM
Posted: Thu Aug 04, 2022 10:57 am
by Dave08
Hi all,
I'm currently building a tiny graphical OS running in 16-bits Unreal Mode, and using video mode 13h (320x200, 256 colors) to display stuff. I'm currently testing it on QEMU, VirtualBox, VMWare and physical machine.
I am also programming a 3D software renderer which uses double-buffering. The problem is that, everytime I copy the backbuffer to the linear framebuffer (at address 0xA0000), virtual machines update the screen before everything is copied, every single time. Thus, it looks like every frame I render suffers from tearing, needless to say the result is horrible. I only saw this problem occur within VirtualBox and VMWare (I haven't seen this problem with QEMU nor on real PC).
At this point, it really looks like VMs update the entire screen everytime a single pixel is written in the linear framebuffer... I am copying my buffers with a loop. I have also tried copying with REP MOVSD, but this just makes the screen black. Again, QEMU and my PC still display things correctly...
I'm kind of stuck at this point, and it seems like Google doesn't want me to learn anything either.
Any help would be appreciated.
Re: Mode 13h : Double buffer flickering horribly on VM
Posted: Thu Aug 04, 2022 11:55 am
by kzinti
If you are copying the backbuffer to the frontbuffer, you are not using double buffering. Double buffering would mean having two framebuffers and swapping between them using hardware (VGA) registers.
If you insist on copying, you will need a way to obtain or guess the current scan line of the video display and time your copy accordingly. This is tricky and might or might not be possible with QEMU.
Re: Mode 13h : Double buffer flickering horribly on VM
Posted: Thu Aug 04, 2022 12:53 pm
by Octocontrabass
Dave08 wrote:16-bits Unreal Mode
If you're going to require a 32-bit CPU, why not use 32-bit protected mode?
Dave08 wrote:mode 13h (320x200, 256 colors)
Mode 13h doesn't have two buffers to do double buffering, so whatever it is you're doing is not double buffering. Look at "mode X" and its relatives if you want 256 colors with actual double buffering.
Dave08 wrote:I only saw this problem occur within VirtualBox and VMWare (I haven't seen this problem with QEMU nor on real PC).
How are you synchronizing with vblank?
Re: Mode 13h : Double buffer flickering horribly on VM
Posted: Fri Aug 05, 2022 2:41 am
by Dave08
Octocontrabass wrote:Dave08 wrote:16-bits Unreal Mode
If you're going to require a 32-bit CPU, why not use 32-bit protected mode?
I have to stay in real mode, because I need my software to be able to run on a USB stick and actively load and save stuff on it, and I nearly don't have enough time or mental power to make a USB mass storage driver. So right now, Int 0x13 is more than convenient.
Octocontrabass wrote:Dave08 wrote:I only saw this problem occur within VirtualBox and VMWare (I haven't seen this problem with QEMU nor on real PC).
How are you synchronizing with vblank?
I have tried looking at VGA documentation online to find how to synchronize with VBlank, but so far I have found nothing. I'm synchronizing using the PIT's periodic IRQ that I have set to about 30 Hz.
I also looked up Mode X, and it does seem worth the work (also square pixels, yay). Right now, I'm going to try the easiest solutions first. If none of them suit my needs, then I'll go for Mode X.
Re: Mode 13h : Double buffer flickering horribly on VM
Posted: Fri Aug 05, 2022 10:06 am
by nullplan
Dave08 wrote:I have to stay in real mode, because I need my software to be able to run on a USB stick and actively load and save stuff on it, and I nearly don't have enough time or mental power to make a USB mass storage driver. So right now, Int 0x13 is more than convenient.
BIOS can do a lot of things you don't know about. It can, for example, futz with your unreal mode and break it. Any time you call a BIOS interrupt, it might restore the segment limits. It also might not. You don't know. And especially with USB it might do so, because it might have to switch to 32-bit flat mode and then switch back.
USB driver in 32-bit unpaged mode is quite simple. You can pilfer the one from SeaBIOS, which is barely 1000 lines all told. You need PCI enumeration and dynamic allocation, however. That last one is the sticking point for me.
And even if you have that, the hard part is going to be finding out which device you are booting from. But then it is quite easy to just stay away from BIOS.
Re: Mode 13h : Double buffer flickering horribly on VM
Posted: Fri Aug 05, 2022 11:32 am
by Octocontrabass
Dave08 wrote:I have tried looking at VGA documentation online to find how to synchronize with VBlank, but so far I have found nothing.
Look for documentation that mentions port 0x3BA/0x3DA. If the hardware supports reporting vblank, bit 3 will be set during vblank. (If the hardware doesn't support reporting vblank, you'll still see bit 3 change, it just won't indicate anything useful.)
nullplan wrote:And even if you have that, the hard part is going to be finding out which device you are booting from.
I think INT 0x13 AH=0x48 is pretty reliable (at least when booting from USB).
Re: Mode 13h : Double buffer flickering horribly on VM
Posted: Mon Aug 08, 2022 7:16 am
by Gigasoft
The term "double buffering" just means that rendering is being done to a back buffer, irrespective if it is presented via flipping or copying or whether it resides in system or video memory.
Bit 3 of port 3DAh reports vertical retrace, not vertical blanking.
To synchronize with vertical display end, you can do the following:
- Busy wait until vertical retrace end (bit 3 in port 3DAh goes from 1 to 0)
- Set up a timer that fires at the vertical display end (13823 μs for mode 13h)
- When it does, set up a timer that fires just before the end of vertical retrace (449 μs for mode 13h minus some margin), and notify application
- When the second timer fires, repeat
Of course, you might as well just synchronize with the start or end of vertical retrace, and set the timer for (almost) a full frame.
Re: Mode 13h : Double buffer flickering horribly on VM
Posted: Mon Aug 08, 2022 10:37 am
by kzinti
Gigasoft wrote:The term "double buffering" just means that rendering is being done to a back buffer, irrespective if it is presented via flipping or copying or whether it resides in system or video memory.
I don't agree with that. Double implies two. Either you have two video memory buffers or you don't. Having a single non-video memory buffer to speed up read/writes to video memory is just... buffering. A single buffer.
I understand you are saying that you have one video memory buffer (the frame buffer) and one system memory buffer (the back buffer) and that this is two buffers. But they aren't the same and the term "double" usually refers to two of the same thing.
Maybe it is because of my background working on DirectDraw/3D drivers... Double buffer in that context always and only means two video memory buffer where one of them is active as the framebuffer (and you "swap" between the two buffers by programming the RAMDAC registers).
Re: Mode 13h : Double buffer flickering horribly on VM
Posted: Mon Aug 08, 2022 6:44 pm
by klange
kzinti wrote:I don't agree with that. Double implies two. Either you have two video memory buffers or you don't. Having a single non-video memory buffer to speed up read/writes to video memory is just... buffering. A single buffer.
It doesn't matter where the other buffer is, it's still double buffering. As Gigasoft says, page flipping and copying are both approaches to double buffering. It might help to consider some history about what
single buffering means to see how both page flipping
and copying are valid approaches to double buffering.
In the earliest days of video, there were
no buffers - you had to race the beam as it scanned across the screen, and in a time where memory was expensive there was no representations of a final image anywhere on the computer, CPU cycles had to be dedicated to the task of figuring out what to draw as the cathode moved. One of the first advancements in this space was
character generators - sure, you don't have the memory to store a full image, but mask ROMs (for glyph shapes) are cheap, and a handful of lines of a few dozen characters each
is feasible to store in memory - this is how we ended up with so many text-based systems back in the day, and it's still visible in legacy VGA text mode. As memory got cheaper, we got
frame buffers, and for most of computing history you were lucky to get
one - not just one in the video hardware, but one total. Memory was still expensive, and screens had gotten bigger (and users wanted more colors). In these setups, applications quite literally drew their window contents directly into the framebuffer, and if this was slow enough (as it often was) there were very noticeable artifacts, generally in the form of displayed elements being clearly drawn from bottom to top - the painter's algorithm in action, right on your screen. This was such a common problem
it became a meme.