All posts by Stefan

Installing the RadeonSI Driver and Steam on Ubuntu 14.04

This is a short guide detailing the steps to get Steam and older source-engine games like Team Fortress 2 up and running using the most recent open-source RadeonSI driver. By the end of this guide, hopefully you will be able to run Steam and Source-engine games using the newest open-source drivers for your ATI/AMD graphics card.

These instructions were last updated July 17, 2014, and are for Ubuntu Trusty (14.04) and Linux Mint 17 for a Radeon HD 7850.

When might you (not) want to use this guide?

If you’re not satisfied with the performance of the proprietary (fglrx) drivers and are mainly interested in playing older titles, the RadeonSI drivers may be a good choice. You should be comfortable with using the linux terminal and know the basics of package management, as these drivers are considered unstable and may be frequently updated (and possibly broken).

As of the date of this guide, the RadeonSI driver has less OpenGL compatibility than the official driver. Steam only reports access to OpenGL 3.0 features (compared to OpenGL 4.3 from the official drivers). You may have trouble running newer titles like DOTA 2 or Civilization V. If you’re not sure, you may want to find the OpenGL requirements for your games before continuing.

Getting Started: Removing any existing binary drivers

First, be sure to remove any binary driver and Catalyst Control Center. If you downloaded a recent version of the fglrx drivers, you can do this by running the uninstaller:

sudo /usr/share/ati/fglrx-uninstall.sh

Once the uninstaller finishes, you will need to restart your system.

If you are using the ‘fglrx’ or ‘fglrx-updates’ package from Driver Manager, you should switch back to the open source driver and restart.

Add the oibaf repository and install the RadeonSI drivers

Source: Phoronix

In order to install graphic drivers that haven’t made it into the main Ubuntu repositories yet, you can add the ‘oibaf’ repository to your system.

The following set of commands will add the repository and install additional OpenGL support packages.

sudo apt-add-repository ppa:oibaf/graphics-drivers && sudo apt-get update && sudo apt-get dist-upgrade

Read the instructions while adding the repository, and press Enter to confirm. The instructions for Ubuntu 14.04 at time of this writing suggest installing the following package:

sudo apt-get install mesa-vdpau-drivers

At this point, you will have the new graphics drivers, and should restart to ensure the new drivers are loaded.

How to Prevent and Fix Errors in Steam and Source-Engine Games

Source: ArchLinux Wiki
Source: Valve Software on GitHub

Fix for Common Errors from Steam and RadeonSI Drivers

OpenGL GLX context is not using direct rendering, which may cause performance problems
Could not find required OpenGL entry point 'glGetError'! 
Either your video card is unsupported, or your OpenGL driver needs to be updated.

The Steam Runtime comes bundled with older versions of certain libraries that are known to conflict with the RadeonSI driver. To fix this, you’ll need to move or remove one of Steam’s built-in versions of libgcc. If not removed, the RadeonSI driver will fail to load (you can see this by running steam in a terminal).

Move the 32-bit version of libgcc out of the Steam folder, in this case to the home directory (as a backup):

mv ~/.local/share/Steam/ubuntu12_32/steam-runtime/i386/lib/i386-linux-gnu/libgcc_s.so.1 ~/libgcc_s.so.1.i386

You may or may not need to back up the 64-bit version of libgcc. If Steam doesn’t run without errors, try this:

mv ~/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/lib/x86_64-linux-gnu/libgcc_s.so.1 ~/libgcc_s.so.1.amd64

If it still doesn’t work after removing these two files, check the ArchLinux source link at the top of this section for other possible fixes.

Additional Driver Support: Install S3TC texture support

How to Fix Common Errors in Source-Engine Games

This application requires either the GL_EXT_texture_compression_s3tc, 
or the GL_EXT_texture_compression_dxt1 + GL_ANGLE_texture_compression_dxt3 + 
GL_ANGLE_texture_compression_dxt5 OpenGL extensions. Please install S3TC texture support.

Source games require that you can install S3TC texture support for 32-bit and 64-bit architectures, which can be done with the following command:

sudo apt-get install libtxc-dxtn-s2tc0 libtxc-dxtn-s2tc0:i386

Conclusion

That should be all that’s necessary to have a basic setup of the RadeonSI driver and a working Steam install. You should also have at least one working game to test with – Team Fortress 2 (and possibly other source-engine games). In that case, have fun!

If you need to revert to the standard Ubuntu drivers, you can re-run the command for installing the oibaf repository, which provides removal instructions:

sudo apt-add-repository ppa:oibaf/graphics-drivers

It’s possible that I’ve missed something in preparing this guide, since it’s mostly a collection of other resources. If you have any comments or suggestions, feel free to leave a message in the comment box below.

Additional Resources

To check your installed OpenGL Version:
glxinfo | grep OpenGL

Steam-specific Troubleshooting

Game-specific Troubleshooting

Kernel Upgrade Guide for Ubuntu 14.04

 

Fixing the Endless Spinning Circle of Dots During Boot on Windows 8 (Mac Version, BootCamp)

In case this helps someone, I just wanted to share a fix to an issue I encountered that prevented me from booting into Windows 8 on a MacBook Pro (2012) running Mountain Lion and Boot Camp.

I had attempted to reboot into Windows 8, only to find that Windows would never finish booting, forever hanging at the startup screen with the Windows logo and and spinning circle of dots. Nothing seemed to work, and the Automatic Recovery tools were also on the other side of the spinning circle, unable to finish loading.

I ran into a fix for this issue that falls into the “one weird trick” category, using a feature of VMWare Fusion. I tested this with the standard version of VMWare Fusion 5, but there is a free trial of VMWare Fusion 6 available that should work as well.

In short, I followed this guide to boot the existing Boot Camp partition as a Virtual Machine.

Windows 8 Spinning Circle of Dots

After a short automated setup process, the virtual Windows 8 was able to start booting, and continued on beyond the spot where it would typically hang. The startup process complained about being unable to finish booting last time (and many times before that…) and offered up the Automatic Repair options (which I skipped).

After skipping the automatic repair, it was possible to get into the Advanced Startup Options and boot into Safe Mode.

Rebooting out of Safe Mode, the virtual Windows 8 install was able to start normally, without any issues!

As a last step, I rebooted the entire system, crossed my fingers, and Windows 8 made it past the spot that it was previously getting hung up on, and booted normally. Crisis averted, no data loss.

I’m hoping that this process won’t trigger Windows re-activation. It hasn’t so far, and I’ll add an update if that turns out to be a problem.

Stefan

Configuring Side Buttons on Logitech Mice under Ubuntu Linux

One of the first things I modify on a desktop Linux install is to change the behaviour of the side buttons away from the defaults of “Back” and “Forward”.

Here’s a quick guide to changing the side buttons on a 5-button Logitech mouse on Ubuntu 12.04 through 19.04, and Linux Mint. It may work with newer versions, but has not been tested. This method also works well for most generic 5-button mice I’ve seen in the wild.

Install necessary packages

$ sudo apt-get install xbindkeys xvkbd

If your package manager can’t find xvkbd, an alternative is to install xautomation and use its ‘xte’ command in later steps.

Create a default profile for xbindkeys

$ xbindkeys --defaults > ~/.xbindkeysrc

Edit the default profile

$ gedit ~/.xbindkeysrc

Comment out the provided examples to prevent conflicts and strange behaviour.

# Examples of commands:
 
#"xbindkeys_show"
# control+shift + q
 
# set directly keycode (here control + f with my keyboard)
#"xterm"
# c:41 + m:0x4
 
# specify a mouse button
#"xterm"
# control + b:2

Add new entries in .xbindkeysrc for side buttons

The xev1 command will show you the index bound to each of your buttons (8,9). The snippet below works on the MX518 and M570.

# side button page down
"xvkbd -xsendevent -text "\[Page_Down]""
m:0x0 + b:8

# side button page up
"xvkbd -xsendevent -text "\[Page_Up]""
m:0x0 + b:9

Start ‘xbindkeys’, and confirm that your side buttons are working.

Make your changes take effect on Startup

In Preferences -> Startup Applications, create an entry to run xbindkeys.

Done!

Arduino Leonardo Remote Control (Multimedia Keys) Support for Arduino 1.0.5

One of the perks of the Arduino Leonardo platform compared to the more traditional Arduino Uno is the ability to appear as a USB Human Interface Device to a host computer. Instead of communicating over serial, the Leonardo can appear as any of a variety of Human Interface Devices.

The Arduino software (as of 1.0.5) includes support for Keyboard and Mouse profiles, but in this post, I’ll go over how to add Remote Control and Multimedia Keys support to your Arduino Leonardo, Micro or ATMega32u4-based Arduino. This guide also reportedly works with the Arduino Due. If you find another platform that the guide works with, feel free to let me know and I’ll update this section.

In short, this will enable your Arduino sketches to use the Volume Up, Volume Down, Mute, Play, Pause, Stop, Next Track, Previous Track, Rewind and Fast Forward hotkeys (and more!).

This includes support for Windows, Mac, Linux, and even Android with a USB-OTG cable.

Source files for everything on this page are located in their own GitHub repository.

ArduinoLeonardo

Locating the Arduino Source

Windows

The default location for the source files on a Windows machine running a 64-bit OS is located at:

C:/Program Files (x86)/Arduino/hardware/arduino/cores/arduino/

Mac OS X

From Finder, navigate to your Applications

Right click on Arduino.app and select Show Package Contents

Inside the package, you’ll find the source files in /Resources/Java/hardware/arduino/cores/arduino/

Back up the original files

Make sure you take a backup of these two files before continuing:

USBAPI.h
HID.cpp

Optional – Grab the source from GitHub

You can grab the updated source files from this GitHub repository, or modify your own in the following sections.

Modifications to USBAPI.h

We want to add the headers for a new Remote class which can be called by Arduino sketches, and the methods that will send individual commands to the host computer.

After the headers for the Keyboard and Mouse classes are defined, add the following definition for Remote. (Line 137)

Here, each command is encoded as the integer value of a single bit, that when set will send a matching command to the host machine.

//================================================================================
//================================================================================
//	Remote 
 
#define REMOTE_CLEAR 0
#define VOLUME_UP 1
#define VOLUME_DOWN 2
#define VOLUME_MUTE 4
#define REMOTE_PLAY 8
#define REMOTE_PAUSE 16
#define REMOTE_STOP 32
#define REMOTE_NEXT 64
#define REMOTE_PREVIOUS 128
#define REMOTE_FAST_FORWARD 256
#define REMOTE_REWIND 512
 
class Remote_
{
private:
public:
	Remote_(void);
	void begin(void);
	void end(void);
 
	// Volume
	void increase(void);
	void decrease(void);
	void mute(void);
 
	// Playback
	void play(void);
	void pause(void);
	void stop(void);
 
	// Track Controls
	void next(void);
	void previous(void);
	void forward(void);
	void rewind(void);
 
	// Send an empty report to prevent repeated actions
	void clear(void);
};
extern Remote_ Remote;

Save the file, and you’re finished with the headers.

Adding Class to HID.cpp

You’ll want to declare a new singleton for the Remote class, located at the top of the source file.

//	Singletons for mouse and keyboard (and remote)
 
Mouse_ Mouse;
Keyboard_ Keyboard;
Remote_ Remote;

Skipping ahead to the very end of the file, we need to provide implementation details for the Remote object after the Mouse and Keyboard are defined. This can be added before the two trailing #endif statements in the file:

//================================================================================
//================================================================================
//	Remote
 
Remote_::Remote_(void)
{
}
 
void Remote_::begin(void) 
{
}
 
void Remote_::end(void) 
{
}
 
void Remote_::increase(void)
{
	u8 m[2];
	m[0] = VOLUME_UP;
	m[1] = 0;
	HID_SendReport(4,m,2);
}
 
void Remote_::decrease(void)
{
	u8 m[2];
	m[0] = VOLUME_DOWN;
	m[1] = 0;
	HID_SendReport(4,m,2);
}
 
void Remote_::mute(void)
{
	u8 m[2];
	m[0] = VOLUME_MUTE;
	m[1] = 0;
	HID_SendReport(4,m,2);
}
 
void Remote_::play(void)
{
	u8 m[2];
	m[0] = REMOTE_PLAY;
	m[1] = 0;
	HID_SendReport(4,m,2);
}
 
void Remote_::pause(void)
{
	u8 m[2];
	m[0] = REMOTE_PAUSE;
	m[1] = 0;
	HID_SendReport(4,m,2);
}
 
void Remote_::stop(void)
{
	u8 m[2];
	m[0] = REMOTE_STOP;
	m[1] = 0;
	HID_SendReport(4,m,2);
}
 
void Remote_::next(void)
{
	u8 m[2];
	m[0] = REMOTE_NEXT;
	m[1] = 0;
	HID_SendReport(4,m,2);
}
 
void Remote_::previous(void)
{
	u8 m[2];
	m[0] = REMOTE_PREVIOUS;
	m[1] = 0;
	HID_SendReport(4,m,2);
}
 
void Remote_::forward(void)
{
	u8 m[2];
	m[0] = 0;
	m[1] = REMOTE_FAST_FORWARD >> 8;
	HID_SendReport(4,m,2);
}
 
void Remote_::rewind(void)
{
	u8 m[2];
	m[0] = 0;
	m[1] = REMOTE_REWIND >> 8;
	HID_SendReport(4,m,2);
}
 
void Remote_::clear(void)
{
	u8 m[2];
	m[0] = 0;
	m[1] = 0;
	HID_SendReport(4,m,2);
}

We will add one more change to the code, adding a USB HID Descriptor for the Consumer Control Page, which hosts the typical Remote Control and Multimedia Keys available to modern operating systems.

From the Wikipedia Entry on USB Human Interface Devices:

Devices define their data packets and then present a “HID descriptor” to the host. The HID descriptor is a hard coded array of bytes that describe the device’s data packets. This includes: how many packets the device supports, the size of the packets, and the purpose of each byte and bit in the packet. For example, a keyboard with a calculator program button can tell the host that the button’s pressed/released state is stored as the 2nd bit in the 6th byte in data packet number 4.

The USB Descriptor will be added after this section in the Arduino source:

#if RAWHID_ENABLED
	//	RAW HID
    ...
#endif

Note that in the following snippet, each of the “Usage” lines corresponds to a bit of data defined in the USBAPI.h file. The final block leaves six bits remaining for passing your own additional functionality.

//-----------------------------------------------------------------------------

    /* Cross-platform support for controls found on IR Remotes */

    0x05, 0x0c,                    //	Usage Page (Consumer Devices)
    0x09, 0x01,                    //	Usage (Consumer Control)
    0xa1, 0x01,                    //	Collection (Application)
    0x85, 0x04,                    //	REPORT_ID (4)
    0x15, 0x00,                    //	Logical Minimum (0)
    0x25, 0x01,                    //	Logical Maximum (1)
    0x09, 0xe9,                    //	Usage (Volume Up)
    0x09, 0xea,                    //	Usage (Volume Down)
    0x75, 0x01,                    //	Report Size (1)
    0x95, 0x02,                    //	Report Count (2)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x09, 0xe2,                    //	Usage (Mute)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x09, 0xb0,                    //	Usage (Play)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x09, 0xb1,                    //	Usage (Pause)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x09, 0xb7,                    //	Usage (Stop)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x09, 0xb5,                    //	Usage (Next)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x09, 0xb6,                    //	Usage (Previous)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x09, 0xb3,                    //	Usage (Fast Forward)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x09, 0xb4,                    //	Usage (Rewind)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)

    0x95, 0x06,                    //	Report Count (6) Number of bits remaining in byte
    0x81, 0x07,                    //	Input (Constant, Variable, Relative) 
    0xc0                           //	End Collection

That’s everything you need to do with the Arduino source. Save your work and try compiling a sketch with the profile for the ‘Arduino Leonardo’ board. If any problems persist, you can always compare with the source on GitHub.

Sample Sketch for Arduino Multimedia Keys

Uploading this to an Arduino should alternately mute and un-mute the system volume every five seconds. Calling Remote.clear() after each action is recommended.

/* 
   Sample sketch for Multimedia Keys
   Alternately mute and un-mute the system volume every five seconds.
 
   https://stefanjones.ca/blog/arduino-leonardo-remote-multimedia-keys/
*/
void setup() { 
}
 
void loop() {
  delay(5000); 
 
  // Prevent duplicate activation
  Remote.mute();
  Remote.clear(); 
}

Advanced Usage

You can add additional features from the Consumer Page by referring to Page 75 of the USB HID Usage Tables and adding them to the descriptor:

    0x09, 0xbc,                    //	Usage (Repeat, with usage code 'BC' from tables)
    0x95, 0x01,                    //	Report Count (1)
    0x81, 0x06,                    //	Input (Data, Variable, Relative)
    0x95, 0x05,                    //	'Blank' Report Count decreased from six to five entries

USBAPI.h

#define REMOTE_REPEAT 1024
...
void repeat(void);

HID.cpp

void Remote_::repeat(void)
{
	u8 m[2];
	m[0] = 0;
	m[1] = REMOTE_REPEAT >> 8;
	HID_SendReport(4,m,2);
}

In a follow-up post, I’ll be providing a method I found useful for using an IR Sensor with the Leonardo, and a version of the AdaFruit IR-Commander and Raw-IR-Decoder sketches with reduced memory requirements.