You are viewing libv

Tired of ads? Upgrade to paid account and never see ads again!
LIBV Intentionally Breaks Videodrivers [entries|archive|friends|userinfo]
Luc Verhaegen

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

The linux desktop is dead! [Sep. 17th, 2010|03:41 pm]
Luc Verhaegen
[Tags|, , , , , , , , , , , ]
[Current Location |France, Toulouse, XDS2010]
[mood |blahblah]

Or so it will be, soon, if these guys get their way.

Apparently, and this has been the hot new idea for the last year or two; for Xserver 1.10 people want to get rid of one of the greatest things that XFree86 brought us, and one of the better changes that happened after the fork: modular graphics drivers.

While the current proposal is simply to undo the modularization work of the mid-naughties (thanks jezza!), it immediately sparked the imagination of others to go even further (to which Alanc answered rather strikingly). But merging drivers back is in itself already a very damaging move.

So what is the goal behind merging drivers?

The official reason for this is "cleaning up the API", but I fail to see any logical link between being able to clean up APIs and mashing everything together.

There is simply nothing that stops APIs from being improved when drivers are not a full and whole part of the xserver build tree.

A mashed-together tree has no more advantage than a buildsystem like our tinderbox.

And having modular drivers does not mean that one has to have a fully static API and ABI, you just need to have dependable ABI bumping, and, for the sake of overhead, sane and forward-looking API changes. Free software drivers are of course best able to keep in sync with API changes, but this is no different whether they are external or internal to the server build tree.

However, there is a difference in how one approaches API cleanups in a modular world, as one needs to think a bit more about how to do such API changes. This often leads to a cleaner design, a better structure, and it often means that people spend time trying to understand existing code, and how to best adjust it to fit the new needs, without throwing out the baby with the bathwater. By moving the drivers into the xserver tree, and outlawing the API, we will only open the door for having a libpciaccess type breakage every month.

So maybe this is the real wish behind wanting to merge back drivers: being able to pull crazy stunts with halfarsedly designed, badly structured and untested code, without implications, without accountability.

Apart from APIs degrading further, there are other more fundamental issues with this, with actually far reaching consequences.

When tying in the graphics drivers with the X server, the only way one could get driver updates, to get bugfixes, new features or new hardware support, is by installing a new Xserver.

This is probably going to be claimed as a benefit, as people want more testing of upstream code, but a slight increase in usage of upstream code, will mean a much bigger decrease in userbase on released code, and people will be even more afraid of updating anything in their system than today.

But this is how the kernel does it!

We've all heard this from our mothers: "If some other kid jumps off a cliff, is that a reason to jump off that cliff as well?"

Basically, while it might be a good idea for the often much simpler devices that have rather complete drivers (at least compared to graphics drivers :)) in the kernel to be a full and whole part of the kernel, it does not and will not work well for graphics drivers.

The complexity and the amount of movement in graphics drivers, especially with the many parts staying in userspace and the very unstable interfaces to them, makes this rather messy. And the only way that this is feasible is when those drivers are rather stable, and they definitely need to have a very stable ABI to userspace.

No-one will be able to maintain such a level of stability for graphics drivers, and i am sure that no-one will stand up to defend going that route, if this requirement is mixed into the discussion.

How to sneak in a 1 to 1 version dependency between xserver, mesa and the linux kernel... Pt. 1.

In January this year, in the run-up to xserver 1.8, there was a commit to the xserver, labelled "xserver: require libdri 7.8.0 to build", where an autoconf rule was added to depend on this version of "libdri". I believe that this was mainly because of DRI2 changes.

When I say depend here, there is not a complete dependency on a given version of libdri. One can always build the xserver without any DRI support whatsoever. But who, on the desktop, really wants that today?

So while this all-or-nothing decision is in itself questionable, there is another question to be asked here: what is this libdri?

There is a dri.pc on most systems today, and there is a on most systems today. The former is a package config file coming from the mesa tree, the latter, is an xserver internal convenience library (hence the lack of so versioning). Smells fishy, doesn't it?

Now, while you might want to spend time looking high and low for the libdri from mesa, you will not find it. Mesa comes with 10 or more different libdris, one for each driver it supports, with the whole of the mesa linked in statically, in the form of

Urgh, how broken is that?

So, the xserver now depends on 10 or more different, driver specific, enormous binaries, all because its dri support now depends on a given version of the dri protocol. Or, re-stating that, the xserver depends on a very specific version of the monolithic, 80s style, mesa tree.

Expanding the logic for the xserver and the drivers: why not just mash the mesa and xserver trees together then? :)

More parts come into play... (or dependency Pt. 2)

The xserver depends on the standard drm infrastructure, and this is compatible up to a 4+ year old release of libdrm, namely version 2.3.0, as the basic libdrm code has barely changed since.

Mesa, however, is a different story altogether. It depends, hard, on the latest version of libdrm, and this has been so since Oktober 2008, when intel introduced libdrm_intel in libdrm 2.4.0.

In essence, this libdrm_intel is nothing more than a driver-stack internal convenience library. It only contains code that is specific for intel hardware and the only dependencies are parts of the intel driver stack (if those parts were living separately already). There are no direct dependencies from anything else.

But, ever since Oktober 2008, both the intel x driver and the intel mesa driver depend on the latest libdrm version, and since then, both radeon and nouveau joined in the frenzy.

So, while there might be some backwards compatibility between dri drivers and libdrm drivers, the reality is that intel, radeon and nouveau are today playing hopscotch. Because mesa is monolithic, and at least one of its drivers is going to depend on the latest libdrm version, the whole of monolithic mesa simply depends on the latest libdrm version.

Since mesa has been depending on the latest libdrm for a few years now, and the xserver has been depending on the latest mesa version since the start of 2010, in turn, the xserver now depends on the latest libdrm version.


How does this tie in the kernel? (dependency Pt. 3).

Well, since libdrm has the driver specific sublibraries, those of course call drm driver specific ioctls, and of course, these ioctls change all the time. While some people claim that they try to abstract at this layer (and that this strategy is good enough for everyone...), and claim to try to keep the kernel to userspace interface stable, this of course is only true for a very limited range of kernel and userspace parts. Now, we have intel, radeon _and_ nouveau playing at this level, dividing whatever median compatibility range there is, by three.

The result is that libdrm can pretty much only be backwards compatible to the kernel by accident.

So, continuing our logic from earlier, the latest xserver depends on the latest mesa, the latest libdrm and the latest kernel.

Smashing lads! Well done! And all of this on a set of connections and foundations that make a house of cards look like a block of granite.

The root of the problem.

Graphics hardware is horribly complex. Several years ago, a single graphics card already broke the terraflop boundary, managing what a huge IBM supercomputer only managed a good decade earlier. Single graphics cards come with many hundreds of shader cores, running at frequencies above 1Ghz, have multiple gigabytes of ram, eat 200+ Watts, and can drive up to 6 displays today. There is no other single piece of hardware which is this complex.

And this complexity is of course also there in software.

You cannot count the different parts of a modern graphics driver stack on free software on one hand anymore. There is the kernel drm part, the firmware, the libdrm part, the X driver, a pair of mesa drivers, an xvmc and possibly another media acceleration driver. A graphics driver stack, can be made up of up to 8 parts today.

All of those parts are scattered over the system. There is 2 parts shipped with the kernel, 1 part shipped with libdrm, 2 drivers shipped with mesa, and the remainder can be found in an xf86-video tree.

Naturally, in order to work most optimally, these different parts have a very direct and acute dependency on each other. Bugs, new features and new hardware support usually incur changes to interfaces between those different parts all the time.

The way that those different parts are spread all over the place today make it almost impossible to have an optimal setup. Most of the time one is glad if it works at all. What's more, this spread is the core reason for the de-facto 1-1 version tie between kernel, libdrm, xserver and mesa.

The consequences of a 1-1 version tie between kernel, xserver and mesa.

With graphics hardware and graphics drivers being this complex, there is simply no way to have them in a bugfree or a constant "useful" state.

We just _have_ to live with the fact that graphics drivers will be buggy, and we should try to handle this as gracefully as possible.

This means that we should be able to replace all or parts of the graphics driver stack at any time, without negatively affecting other parts of the system.

This is what our audience, our customers as it were, expect from us.

But, by having kernel, libdrm, xserver and mesa tied together, and the different parts of the driver stack spread over them, it is impossible to exchange 1 part of the graphics driver stack, or to exchange just the graphics driver stack, without changing the whole.

By forcing our users to update all this infrastructure each, we will usually trigger a cascade of updates that reach far up the whole software stack, to the extent where trying to fix some small issue in the graphics driver, might mess up openOffice or another program that your average linux desktop user depends on.

Also, what is the chance of getting both wireless, suspend/resume and your graphics driver working to an acceptable level at the same time? This becomes very very small, and when it does work, you better not run into issues somewhere else, as an update might ruin that very precarious balance.

Killing the desktop for everyone.

No normal person can then run a free software desktop system, and expect to use it, because an arbitrary mix of hardware cannot possibly work together acceptably, at least not for a measurable amount of time.

What will be left over is preloads and embedded system.

Preloads is when some OEM, either itself, or through a linux distributor, spends many many man-years on making all parts work together properly. In the end, images will be produced which install on a very specific system and cannot be updated or maintained, except by a specialised team of people. Embedded systems basically work the same way: one combination of hardware, one image, no updates for average users except those provided by the manufacturer or their partners.

So while people might buy a free software based system in a shop around the corner, and be somewhat happy with it for a while, normal desktop users will be left out in the cold.

Looking further, by shutting out our own users, we will take away the breeding ground that free software is based on.

What solution is there?

By now, that should be pretty obvious.

Bring the different parts of the graphics driver stack together, and make its parts independent of the infrastructure they depend on.

This allows driver developers to change internal structure and API at will, while at the same time providing the infrastructure compatibility that users, hardware and distribution vendors require.

All it takes is a little care in designing infrastructure APIs, and a little care in keeping driver stacks compatible, even if that compatibility comes at the cost of disabling some features for some combinations of the infrastructure.

This is not hard to do, and it is done in multiple places.

Why the Nvidia binary driver is that popular.

In a recent phoronix survey, the amount of users using Nvidia hardware and drivers is larger than the users using any other combination.

This has a reason, and it has nothing to do with Nvidia being a completely closed source shop. Nvidia gives users the ability to install any graphics driver stack, and it should mostly be compatible with the environment it is installed in. This is simply what our users need.

What is affected by Nvidia being binary only, is that Nvidia has to put in a lot of work on making things compatible. Free software drivers have a much much easier task, or at least they would, if they, and the infrastructure they depend on, was developed in a different fashion than is the case today.

An open proof of concept.

My talk at FOSDEM, of course mentions my unichrome driver a lot, as it pretty much is my playground these days.

Even though the featurelist of this driver is very limited, it is now integrating X, DRM and DRI drivers in one massively backwards compatible build-system, with autotools detecting all the API changes across all currently used versions of the necessary infrastructure. What one can see there is that, when some care is taking in structuring the driver, it is not that hard to achieve this: it basically just takes the will to do this.

When I talked at FOSDEM, some people were stating that, while it might be possible for DRM and the Xserver, it would be totally impossible on Mesa/DRI, but for Mesa/gallium it should be easy.

In the next month or so, I took all Mesa versions that were out in the wild, and split off the main libraries from the actual DRI drivers, created a set of headers as required by the drivers, created package config files, and then move the drivers out to their own git repositories. Basically, a DRI SDK was created, and the drivers were now building and running externally to this SDK. This across 3 years of DRI development.

When I took that back to the Mesa community, what I of course got was indifference, and, suddenly, claims that while this SDK might be possible for mesa/DRI it would definitely not be possible for Mesa/gallium!

The future?

The proposed future direction for graphics drivers is to create graphics driver stacks. If not, we, the developers, might just as well stop working on free software graphics drivers altogether.

And while the current situation currently is bad, it is not impossible to fix. The problems are known and clear, a path to the solution should by now also be clear, but the willingness to put in the bit of extra thought is simply lacking.

So guys, if you really want to move into the wrong direction, please state the real reasons for doing so, state the consequences to your users; and know what the end result will be.
link31 comments|post comment

The DRI SDK and modular DRI drivers. [Mar. 17th, 2010|01:31 am]
Luc Verhaegen
[Tags|, , , , , , , , , , ]
[Current Location |couch]
[mood |accomplished]
[music |Kinobe - Slip into something more comfortable.]

At FOSDEM I held a talk about "The free software graphics driver stack", analyzing the structure and the distribution of the different parts of the graphics driver stack, and, based on clear requirements, proposing a re-organization to be able to bring the individual parts of the graphics driver stack together. The slides for that talk are available here, and the audio and video of this talk have been made available too (Thanks Michael!).

Since I do not like to talk thin air, i also made a fully unified unichrome graphics driver stack available, proving that it is possible to unite all of Xorg, DRM and DRI drivers in one tree, and that it is possible to provide a reasonable amount of backwards compatibility (trivial for a stagnated driver) even in the Mesa/DRI driver.

My slides have a TODO section, and the most significant of those TODOs was for Mesa. This listed providing shared libraries, pkgconfig files and the necessary headerfiles for Mesa, much like the SDK that X has had ever since xfree86 4.0.0. Of course, such a thing would not happen on its own, so a bit after FOSDEM I set off and now I have implemented just that.

You can find the SDK enabled Mesa DRI tree here, and the individual drivers can also be found in my personal git repositories. A README like document is available too, to explain what one should do to build and install the SDK and to build and install the drivers.

What this gets you, once the SDK is properly installed, is the ability to build and install just the DRI driver to be able to fix bugs, get some performance gains, or just provide the driver developers with good feedback (provided that someone updated the driver tree to the latest compatible changes that is ;)). This without having to replace your libGL, which is where all the dependencies come weighing in. Anyone who has had to update this so far, knows how painful such an update is, and that it is often easier to do a major distribution upgrade.

So this brings us another step closer to make the free software desktop happen: the ability to easily update our graphics driver stack without touching anything else in our system!
link9 comments|post comment

VIA Technologies takes the blue pill. [Mar. 7th, 2010|02:03 am]
Luc Verhaegen
[Tags|, ]
[Current Location |couch]
[mood |amusedamused]
[music |Queens Of The Stone Age - Queens Of The Stone Age - Regular John]

@IanRomanick, with his post on a little cultural problem that VIA encountered.

I actually had some issues when was first created in Q2 2004. Some commit emails would get caught by the spamfilter. There was an interesting struct in this headerfile.

A quick grep of VIAs current codedrops does not show much of an improvement. The same structs name is now preceded with "NEW".
linkpost comment

Hardware MPEG2 Slice decoding added to unichrome driver. [Nov. 4th, 2009|10:24 pm]
Luc Verhaegen
[Tags|, , , , ]
[Current Location |couch]
[music |The Dust Brothers - Medula Oblongata]

I just pushed out code which adds MPEG2 slice decoding to my graphics driver. It is based on XvMC, but unlike "standard" XvMC implementations, it sends MPEG slices over to the graphics driver over the X protocol.

The base idea is the following: The MPEG engine gets MPEG slices, and outputs to a buffer. This buffer needs to then be displayed by the overlay engine. So, we need to spend most of our time managing the communication and syncing of those engines. We already have the other video engines implemented nicely, so, why not stick the MPEG code next to that and have a nice and clean implementation?

The XvMC protocol, X-wise, is mostly about telling the driver that the MPEG hardware is in use, and subsequently claiming buffers in the framebuffer, managed by the X driver. Everything else is expected to happen in the client library. For what reason, i do not know, but part of it could be that, this way, X is not seen to eat any CPU cycles. In any case, this makes it a very weird protocol, with things spread all over the stack.

Things were made worse with the advent of the XvMC wrapper. Instead of expanding the XvMC protocol slightly to provide the name of the XvMC client library to be loaded, DRI is abused for this purpose. So... a pointless hard dependency on DRI is added, and now, no working DRI means no working XvMC... Curious. Makes the pointless dependency on Shm look harmless.

So what i did now is send all the data over the X protocol, over a tiny X extenstion, so that it could be fed into the hardware and synced inside the X driver. An XvPutImage with a longword buffer containing the mpeg buffer id then makes sure that everything gets displayed correctly. And while the overlay is being set up, the mpeg engine can finish its work, and at the very last minute, the overlay code waits for the mpeg engine to finish, and then the overlay gets told to display the new image.

Other XvMC implementations went and completely reimplemented the overlay in the client library, and even involved 2d acceleration to be able to send mpeg slices to the hw a bit faster. A syncing nightmare. Another advantage is that my implementation can implement the newer mpeg2 engines in just a few hundred highly hardware specific lines.

Of course, sending this data over the X protocol in tiny bits does incur some more cpu cycles, and i also am not feeding mpeg data into the hardware over the command buffers. Because of this, my code uses about 30-35% for a normal DVD (write a comment if you guessed which :)) on a VIA C3 Samuel2 (yes, half speed FPU, not quite PPro compatible) at 600Mhz, while openchrome uses 20-25%, roughly 2/3rds. But the performance of my code is still very good, good enough to not bother with speeding things up just yet.

As usual, it is easy to get this new code. It builds and runs against all Xorg versions that are common, and the debian package build system has also been updated for the xvmc code.

For xine there is one caveat, due to the horrible implementation of video_out_xxmc. We need to fool xine into thinking that we do support subpictures (we don't as it the xxmc way of implementing things didn't even get close to how the hardware implemented it). For that, the following option needs to be set:

Option "XvMCBrokenXine" "True"

in the device section of xorg.conf.

link3 comments|post comment

Coreboot native VGA support. [Jul. 23rd, 2009|02:51 pm]
Luc Verhaegen
[Tags|, , , ]
[Current Location |couch]
[mood |accomplished]
[music |dEUS - Vantage Point 06 - Architect]

I didn't exactly intend to time this in the middle of Novell's Hackweek, as my personal hackweek pretty much started the day after FOSDEM. But oh well, it finally did happen and it happened just now. And it was much overdue, since it was mostly written in the months before i even joined SuSE. And when i was at SUSE it got pushed aside while we were freeing AMD graphics hardware and were busy fixing bugs in so that it could still ship with new openSUSE/SLED releases.

On the other hand, this very week, it has been 6 years since i got the EPIA-M board that got me started on graphics driver development. This might not seem that important to you, and some people have worked hard to minimalise the importance of this too; but this board has quite significantly changed the world of free graphics drivers.

Anyway, here it is, finally; Coreboot native VGA textmode!

For those who don't know Coreboot; Coreboot provides the basic HW initialisation needed to bring up a motherboard so that an operating system or other payloads can be loaded. It was called LinuxBIOS until 2008, when everyone agreed that LinuxBIOS was too much of a misnomer. Now if you want to rid yourself of proprietary/closed source software properly, then replacing your machines BIOS with coreboot (and a payload) is the way to go.

Until now, if you wanted working graphics with coreboot, you were still tied to the PCI option rom of your graphics card. This code i just pushed out makes even this last vestige of non-free software disappear.

So if you happen to have a VIA motherboard with a K8M890 Northbridge (AMD PCI-Express) with a Chrome 9 IGP, that is supported by coreboot; then you can have native VGA textmode today.

Introducing the Asus M2V-MX SE: a nice little micro-atx motherboard with AM2 support, DDR2, VIA Chrome 9 IGP. It has absolutely stellar coreboot support, and it can be often seen at trade shows, showing off working suspend/resume and even windows 7 booting. Now if you do not want something like windows 7 booting, then you can get rid of the VGA BIOS completely and get a nice working text console with, for instance, linux.

Don't ask me what sort of fancy modes you can set with this. What you get here is just 80x25 VGA textmode. Yeah, that's right; proper old-style VGA textmode, the sort that everything PC out there supports. The sort that, when things go slightly awry, you are always happy to see. The sort that has saved you so often.

It should be clear that my intention with this was not to re-invent some BIOS infrastructure to do modesetting, or to provide an INT10 or VESA implementation. To me, having fought BIOSes for graphics for the best part of this decade, that sounds pretty pointless. And as you might remember, my unichrome driver has been able to bring up un-posted hardware without issues for quite a while. What I wanted here is the basic infrastructure to see what is going wrong with a booting system, before a proper driver has kicked in, and be able to fix it without having to rely on a serial console.

This code achieves just that goal, and it consists of two parts.

First of all, there is the general, standard part, that any IBM PC compatible graphics adapter from the last 20 years should be able to use: the VGA side of things; vga io routines, and an actual VGA 80x25 modeset complete with cursor and font handling. This code was already committed late May in the hope that my EPIA-M would stop fighting back soon, and partly thanks to the font included, it was quite a big blob of code that got pushed into coreboot then.

The second part, is the K8M890/Chrome 9 specific part: initialising the hw in such a way that a full VGA modeset can use the hw happily. This is barely a few hundred lines of code.

Why just a few hundred lines? Well, this is IGP hardware, so the gpu is sitting off the northbridge, and has a (in this case, semi-)direct route to the systems main RAM and uses part of that for its framebuffer. There is also little of this running-things-on-the-absolute-edge nonsense that is so common on discrete cards. Coreboot sets up the ram for us, it sets up the BARs and io/irq routing for us; all we have to do is set up a vga mode, and fill in the bit in between.

On a board as well supported as the Asus M2V-MX SE this bring-up was a walk in the park, it basically took the best part of yesterday morning. And this exercise is very reproducable for the other unichromes as well. But the first one after this should still be my 6y old Epia-m board into shape with coreboot still (ints and VT8235 IDE *rolls eyes*), this board deserves nothing less.

Oh, one more thing; if you have an M2V-MX SE and wish to try this code, then i would like to advice you to hold off a bit. We need to still shore up the cmos settings and make it more foolproof. I seriously doubt that people enjoy having their machines stop during RAM initialisation because they tried to change the default framebuffer size. This is due to other settings in a badly initialized CMOS getting validated when the videoram size setting fixes the checksum. It shouldn't take long to fix this, and then, running coreboot on this board shouldn't be that scary for even the less experienced hacker.
link4 comments|post comment

[ viewing | most recent entries ]