Keeping the Screen Turned off While Getting Inputs

Vladimir Dergachev volodya at mindspring.com
Sun Aug 27 13:47:03 UTC 2023



On Sun, 27 Aug 2023, Ahmad Nouralizadeh wrote:

> > The framebuffer that is displayed on the monitor is always in video card
> > memory. There is a piece of hardware (CRTC) that continuously pulls data
> > from the framebuffer and transmits it to the monitor.
> 
> So the framebuffer memory should normally be in the kernel (Perhaps in special cases could be mapped in the userspace?!). IIUC, XServer works on the app GUI data in the userspace and sends it to the
> kernel to finally arrive at the framebuffer. Correct? Does it use some kind of ioctl()?
> 
>

Not necessarily - for very old cards you would issue a special command to 
transfer data or paint a line.

Modern video cards (and video drivers) usually work like this - the 
graphics card exposes several regions that work like memory over PCIe bus 
- i.e. the CPU can access them by issuing a "mov" command to an address 
outside main CPU memory (assuming the graphics card is a physical PCIe 
card).

One of the regions is the entire video card memory that includes the 
framebuffer. This way you can transfer data by simplying copying it to the 
memory mapped region.

This however is slow, even with modern CPUs, because of limitations of 
PCIe bandwidth and because the CPUs are not well suited to the task.

Instead a second memory region contains "registers" - special memory 
locations that, when written, make magic happen. Magic is an appropriate 
word here because the function of those registers is entirely arbitrary - 
their function is picked by hardware designers and there aren't any strict
constraints to force a particular structure.

For example, one register could contain starting x coordinate, another 
starting y, another ending x, another ending y, one more contain a color, 
and finally a special register that, when written, will draw a line in the 
framebuffer from start to end using that color.

This is much faster than using a CPU because only a few values are 
transferred - rest of the work is done by the video card.

And this is how video cards used to work a few decades back, and partially 
still do. However, for modern needs this is still too slow.

So one more feature of video cards is that they have "PCIe bus master" - 
the ability to access main CPU memory directly and retrieve (or write) 
data there.

So instead of transferring data to the framebuffer (for example) by having 
the CPU write there, the CPU will write to video card registers the 
addresses (plural) of memory regions to transfer and then trigger the 
transfer by writing a special register. The video card will do the work.

The transfer to the framebuffer is not very interesting, but what you can 
do is PCI bus master to registers instead. This is usually done by a 
dedicated unit, so it is not exactly like writing to the registers, but 
this makes for a good simplified explanation.

So now you have a memory region in main memory where CPU has assembled 
data like "address of register of starting X", "value of starting X", 
"register address for color of starting point", "value of color" and so 
on, finishing "address of trigger register", "Trigger !".

And this now looks like instructions for a very, very weird VLIW (very 
long instruction word) processor.

The OpenGL driver now works by taking OpenGL commands and compiling them 
to sequences of these weird GPU instructions that are placed into memory 
buffer. When enough of these accumulate, the video card is given the 
trigger to go and execute them, and something gets painted.

If you need to paint a picture, another buffer is allocated, picture data 
is written into it, and then a special command is created instructing to 
pull data from that buffer.

Now, over the past few decades the video cards evolved to be slightly less 
weird VLIW processors - they are getting rid of dedicated commands like 
draw a line from X to Y, in favor of commands like "compute  dot product 
between arrays of 4-dimensional vectors".

They still have the weird multi-tier PCIe bus master, and multiple caches
used to access multiple types of memory: framebuffer memory, texture 
memory, main memory and a few others. And a weird quirks that make doing 
interesting programming with GPUs tricky.

So now, if you start some OpenGL app on Linux and look into /proc/XXX/maps 
you should be able to find several memory regions that have been mapped by 
the graphics driver. Some of those is real memory, some are registers and 
are entirely virtual - there isn't any physical DRAM backing them.

These aren't all the regions exposed by video card, because if multiple 
apps write to video card register directly it will lock up hard, freezing 
PCIe bus. Instead, this is arbitrated by the kernel driver.

best

Vladimir Dergachev



More information about the xorg mailing list