Full Acceleration Support for Radeon HD 7000 series

Posted by Hans de Ruiter

I'm pleased to announce (together with A-EON Technology) that the RadeonHD driver for AmigaOS 4.x now fully supports the Radeon HD 7000 series (Southern Islands chipsets). Full 2D acceleration including compositing has been implemented. This is another major milestone as the driver now supports the very latest graphics cards in the Radeon HD range. You can't get newer or more cutting edge than that. The RadeonHD_RM.resource also supports the 7000 series (a necessity for 2D acceleration too), which means that this latest series is also ready for its 3D drivers. This completes everything that was planned for version 1 of the driver.

It's Tough Without Documentation

Implementing Southern Islands GPU (Radeon HD 7000 series) support was a long and, at times, difficult endeavour. To begin with, this was the first of their Graphic Core Next (GCN) architecture, which mark some large-scale changes. The GPU's Instruction Set Architecture (ISA) was completely changed from previous Radeon HD generations. Complicating matter further was AMD's slowness in releasing the documentation for this new architecture.

With no documentation I had no choice but to fall back to using AMD's own code (in the Linux drivers) as documentation. Unfortunately, AMD decided that the EXA driver was obsolete, and all acceleration - both 2D and 3D - was going to go via Gallium 3D. From their viewpoint this was a completely logical decision, and I truly wish that I could have followed suit. However, the Gallium3D port for AmigaOS was still a work-in-progress, and, the Gallium3D driver for Southern Islands GPUs (radeonsi) was (and still is, as at 5 October 2012) not yet usable. As a result, I couldn't follow their lead, and neither did I have example 2D acceleration code to use as a reference. 2D acceleration code is much simpler and easier to follow than 3D driver code.

As you can see, the situation was rather difficult, but that wasn't going to stop me. I managed to decipher parts of the Southern Islands ISA via what I could glean from AMD's GCN presentations, and from the LLVM descriptor files in the radeonsi driver. From this I created a (very large) set of C macros, so that I could hand-assemble Southern Islands shader code. At this point things became a little easier, because the Southern Islands ISA is much easier to use than the ISA for previous generations. Eventually, I got the solid fill shader working, and then the other blitter shaders. Good progress.

Baffling Behaviour

Getting the blitter acceleration working was great, but that success soured quickly when the time came to implement compositing. The power of AmigaOS' compositing feature comes at the cost of greater driver complexity when compared to simple blitter functions. This means both more complicated driver code, and more complicated shaders. That, however, wasn't the biggest problem. After a while the compositing code eventually passed all of the basic tests; but, there were ugly vertical green and blue lines all over the place. Even worse, my Radeon HD 7770 would lock up within a few seconds when compositing was being used a lot unless it was underclocked by about 5%.

Try as I might, after weeks of effort I still could not find a solution to these two problems. After some email discussion with AMD software developers, I discovered that their radeonsi (Gallium3D) driver also suffered from the same vertical line problem. This only occurred if alpha blending was being used. So, the decision was made to put aside Southern Islands GPU support for a while. I asked the guys at AMD to let me know if they found a solution. In the meantime, I switched back to working on the memory management part of the RadeonHD_RM.resource, which was the last task needed to get the driver ready for 3D.

Eventually, I got an email from an AMD software developer who had discovered what was going wrong, and had found a solution. As it turned out, the shader export format that we had both used in our drivers was incompatible with 32-bit ARGB pixel formats. After changing the shader export format, compositing worked as it should. Well, almost. All blitter functions had to be updated to use the correct shader export format, as using the wrong format was corrupting the alpha channels of bitmaps. With that done, compositing worked as it should.

Power Problems

Alas, the battle was won, but the war was not quite over. Solving the compositing problem did not eliminate the GPU lockup problem as was hoped. My Radeon HD 7770 worked just fine in an x86 PC, so it was definitely a driver bug. The problem was eventually traced to a bug in the power table parsing code, which failed to transform a voltage tag to an actual voltage. As a result, when the driver ramped up the GPU' clock to full speed, the voltage was left at a minimal value. Running at high frequency but low voltage is a recipe for instability.

NOTE: Radeon HD 6000 and 7000 series cards initially start at minimal frequencies (GPU: 300 MHz, VRAM: 150 MHz) and voltages, because the BIOS/firmware does not have the microcode needed to set up the memory controllers. So, leaving the settings at their default is not an option.

Victory!

With the power table parsing bug fixed Radeon HD 7000 series was finally done. Everything worked as it should and there were no more lockups. Victory at last!

Implementing 7000 series support has been quite the (long) rollercoaster ride, but the effort was definitely worth it in the end. AmigaOS can now use the very latest in graphic card technology.