Mode 13h : Double buffer flickering horribly on VM

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Dave08
Posts: 8
Joined: Mon May 27, 2019 11:32 am
Location: France
Contact:

Mode 13h : Double buffer flickering horribly on VM

Post 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.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: Mode 13h : Double buffer flickering horribly on VM

Post 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.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Mode 13h : Double buffer flickering horribly on VM

Post 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?
User avatar
Dave08
Posts: 8
Joined: Mon May 27, 2019 11:32 am
Location: France
Contact:

Re: Mode 13h : Double buffer flickering horribly on VM

Post 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.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Mode 13h : Double buffer flickering horribly on VM

Post 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.
Carpe diem!
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Mode 13h : Double buffer flickering horribly on VM

Post 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).
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Mode 13h : Double buffer flickering horribly on VM

Post 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.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: Mode 13h : Double buffer flickering horribly on VM

Post 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).
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: Mode 13h : Double buffer flickering horribly on VM

Post 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.
Post Reply