Yeah, so I'm lazy and haven't updated this thing in quite a while now... The good news is I've finally arrived in Helsinki and got settled into the hotel etc. I'm going apartment hunting tomorrow, and I think I've found a nice looking place. :-)
On one of the flights I actually got asked by one of the flight attendants "Is that a pirated movie?" (In my defense, it could have been a really crappy rip of a DVD I just happen to own... ;-) I'm pretty sure he was joking about calling customs, though. At least I didn't get stopped at that airport...
I did get stopped at London for an explosives test. I think that was just because I got a bit lost and ended up being last through the security checkpoint. Maybe they thought I ran off to plant bombs or something. :-P
Oh, yeah. It's a good idea to remember to install the wireless firmware before you go to another country and track through a snow storm to find a USB memory stick so you can download them from the business center. ;-P Actually the computers in the business center wouldn't load the USB stick, so I decided to get a taxi to a net café this time... After all that the hotel's DHCP server was down, so fail all around... At lest I'm online now. :)
I'm waiting for OProfile to download (at an amazing 5kB/s) so I can figure out why X is eating up 40-70% CPU?
I managed to get fglrx 8.11 downloaded and installed yesterday, so I might start playing around with tracing a userspace process MMIO access from within the kernel. Revenge works pretty well, but there are cases where it can miss the packets from the first few tests. I think this is because the RB pointers get updated too fast for Revenge to see them.
I had a conversation with Dave Airlie about this, and tried the idea of intercepting fglrx ioctls. This does work, but I'm not convinced as to it's reliability either. The ioctls contain more than just pointers to packers, and I think this extra information may be used by the DRM to insert extra packets into the RB (eg flush etc.) The ioctls may also change between fglrx versions.
The advantage to kernel tracing is that it should be able to reliably trace everything the driver does, although there are a few kinks to work out... The PPPT stuff used on newer hardware might be a problem. I'll see how it goes.
Oh, yeah, someday I'll post the rest of the China Trip...
On one of the flights I actually got asked by one of the flight attendants "Is that a pirated movie?" (In my defense, it could have been a really crappy rip of a DVD I just happen to own... ;-) I'm pretty sure he was joking about calling customs, though. At least I didn't get stopped at that airport...
I did get stopped at London for an explosives test. I think that was just because I got a bit lost and ended up being last through the security checkpoint. Maybe they thought I ran off to plant bombs or something. :-P
Oh, yeah. It's a good idea to remember to install the wireless firmware before you go to another country and track through a snow storm to find a USB memory stick so you can download them from the business center. ;-P Actually the computers in the business center wouldn't load the USB stick, so I decided to get a taxi to a net café this time... After all that the hotel's DHCP server was down, so fail all around... At lest I'm online now. :)
I'm waiting for OProfile to download (at an amazing 5kB/s) so I can figure out why X is eating up 40-70% CPU?
I managed to get fglrx 8.11 downloaded and installed yesterday, so I might start playing around with tracing a userspace process MMIO access from within the kernel. Revenge works pretty well, but there are cases where it can miss the packets from the first few tests. I think this is because the RB pointers get updated too fast for Revenge to see them.
I had a conversation with Dave Airlie about this, and tried the idea of intercepting fglrx ioctls. This does work, but I'm not convinced as to it's reliability either. The ioctls contain more than just pointers to packers, and I think this extra information may be used by the DRM to insert extra packets into the RB (eg flush etc.) The ioctls may also change between fglrx versions.
The advantage to kernel tracing is that it should be able to reliably trace everything the driver does, although there are a few kinks to work out... The PPPT stuff used on newer hardware might be a problem. I'll see how it goes.
Oh, yeah, someday I'll post the rest of the China Trip...
I've been a bit slack about posting, but anyway... We've arrived in Chungchen (SP?) and had a few nights here. Last night I went out with John, Jonathan (Yes, that does get a bit confusing sometimes. ;-)), and a few others for dinner and some drinks.
We had a really good dinner at a Chinese restaurant, but I didn't catch the name of the restaurant, after that we went to a head massage/hair dresser which was quite nice, though they didn't have any proper gel or wax to spike my hair. :-(
John then took us to a street restaurant serving kabbabs of various meats and vegetables, most of which I couldn't identify. :-P
Eventually we ended up at Club Mayflower which was fucking awesome, even on a weeknight! Lasers and strobes everywhere, and awesome music too. I ended up dancing with some random people and getting free drinks. :-) We went home quite early, but I'm not sure about the exact time.
I'm going to insist that we go back there on Friday when there will be more people, but even on a weeknight this club puts any so-called clubs in New Zealand to shame.
I'm leaving in a few minutes to go chill out in the City with Johnathan. Not really sure about the details. Anyway, later...
P.S. Working around the China internet filtering is a major pain. It's extremely slow loading web pages via Tor. I think it's just the connection at this particular Hotel, though, as I was pulling some nice speeds from BitTorrent at the other Hotel by running the tracker connections through Tor, and finding an open port on the Hotel's network. :-D
P.P.S. This post was actually delayed by a few days because I was lazy about posting it. :-)
We had a really good dinner at a Chinese restaurant, but I didn't catch the name of the restaurant, after that we went to a head massage/hair dresser which was quite nice, though they didn't have any proper gel or wax to spike my hair. :-(
John then took us to a street restaurant serving kabbabs of various meats and vegetables, most of which I couldn't identify. :-P
Eventually we ended up at Club Mayflower which was fucking awesome, even on a weeknight! Lasers and strobes everywhere, and awesome music too. I ended up dancing with some random people and getting free drinks. :-) We went home quite early, but I'm not sure about the exact time.
I'm going to insist that we go back there on Friday when there will be more people, but even on a weeknight this club puts any so-called clubs in New Zealand to shame.
I'm leaving in a few minutes to go chill out in the City with Johnathan. Not really sure about the details. Anyway, later...
P.S. Working around the China internet filtering is a major pain. It's extremely slow loading web pages via Tor. I think it's just the connection at this particular Hotel, though, as I was pulling some nice speeds from BitTorrent at the other Hotel by running the tracker connections through Tor, and finding an open port on the Hotel's network. :-D
P.P.S. This post was actually delayed by a few days because I was lazy about posting it. :-)
We arrive in Hong Kong about a day ago, after a insanely long flight. I don't know whether it's just Air New Zealand who provides all of 4" of leg room on Economy flights, or all airlines... It really sucks. I feel sorry for those who were continuing on to London Heathrow without any break.
I didn't manage to sleep on the flight so I was only barely awake during the morning, but we still had a good look around some of the shops and malls. We didn't have time to buy anything yet; the place is massive.
I'll post some photos later tonight, or if not, they will be on Steve's Live Journal: http://dragonflamezor.livejournal.com/
I'd been thinking about dumping the 3rd Generation iPod Nano flash memory for
a while now, and recently saw that the Linux4Nano guys have already dumped the
2nd Generation flash... Which is BGA btw!
Originally I was going to wait until I actually had the dump in hand before
posting anything, considering it's my first project with an FPGA thats above
the trivial bitstream hacking level. However I felt I should let the
Linux4Nano guys know, at least...
I'll pickup the iPod from work on Thursday (staff sale :-) and probably a
camera that does decent macro shots; my current camera is pretty good, but
does terrible macro shots.
So until then... ;-)
a while now, and recently saw that the Linux4Nano guys have already dumped the
2nd Generation flash... Which is BGA btw!
Originally I was going to wait until I actually had the dump in hand before
posting anything, considering it's my first project with an FPGA thats above
the trivial bitstream hacking level. However I felt I should let the
Linux4Nano guys know, at least...
I'll pickup the iPod from work on Thursday (staff sale :-) and probably a
camera that does decent macro shots; my current camera is pretty good, but
does terrible macro shots.
So until then... ;-)
- Music:Kristoff - Night Addix 6
I just pushed Markus Amsler's VAP_CNTL patch, which cleans up a lot of the
nastyness we previously had with this register. It shouldn't break anything,
but you know the drill, test and report. :-)
P.S. Sorry about the delay, real life got in the way...
nastyness we previously had with this register. It shouldn't break anything,
but you know the drill, test and report. :-)
P.S. Sorry about the delay, real life got in the way...
I just merged Markus Amsler's VAP_CNTL patch into my local Mesa repo, and
tested it with glxgears, Quake 3, and Doom 3. Doom 3 actually has some serious
bugs, but it's mostly related to shadow volumes. I'll push Markus' patch some
time today and close the bug.
I'm currently running on Alex's DRM which has some additional commits correcting
the purge/flush code, as well as some other changes. I haven't tested this with
code that is known to cause lockups yet, but I'm pretty amazed that Doom 3 ran
without a single lockup... :-)
Here's a screenshot of the Doom 3 rendering bugs, for your viewing
(dis-)pleasure. ;-)

Actually I had to disable the two-sided stencil extension just to get that
screenshot, otherwise software rendering would be used... So some work is needed
on the stencil code...
tested it with glxgears, Quake 3, and Doom 3. Doom 3 actually has some serious
bugs, but it's mostly related to shadow volumes. I'll push Markus' patch some
time today and close the bug.
I'm currently running on Alex's DRM which has some additional commits correcting
the purge/flush code, as well as some other changes. I haven't tested this with
code that is known to cause lockups yet, but I'm pretty amazed that Doom 3 ran
without a single lockup... :-)
Here's a screenshot of the Doom 3 rendering bugs, for your viewing
(dis-)pleasure. ;-)

Actually I had to disable the two-sided stencil extension just to get that
screenshot, otherwise software rendering would be used... So some work is needed
on the stencil code...
I found out a few days ago that I didn't get the Google job, which I kind of
half-expected after reading about Google mass-targeting people on various
mailing lists, such as the Linux Kernel Mailing List.
Part of the email from the recruiter was "... though we don't have a position
that is a strong match with your qualifications at this time, we will
definitely be keeping your resume active in our system, and I'd love to stay
in touch with you in the future about opportunities." So maybe some time in
the future... :-)
I've been thinking about getting back into some hardware hacking. I have a
couple of FPGA boards sitting around here which I really should put to use. I
have a little project in mind, with time permitting. At least it's something
to motivate me to finally learn Verilog. I have already ordered a few parts
for this project, but I'll see how it goes before posting further details...
half-expected after reading about Google mass-targeting people on various
mailing lists, such as the Linux Kernel Mailing List.
Part of the email from the recruiter was "... though we don't have a position
that is a strong match with your qualifications at this time, we will
definitely be keeping your resume active in our system, and I'd love to stay
in touch with you in the future about opportunities." So maybe some time in
the future... :-)
I've been thinking about getting back into some hardware hacking. I have a
couple of FPGA boards sitting around here which I really should put to use. I
have a little project in mind, with time permitting. At least it's something
to motivate me to finally learn Verilog. I have already ordered a few parts
for this project, but I'll see how it goes before posting further details...
A few days ago I was contacted by an engineering recruiter from Google. I have
to admit my first reaction was that someone was playing a strange practical
joke, but after checking it out and replying to the recruiter, it's defiantly
legitimate. :-)
I've got a phone interview scheduled for Tuesday. Hopefully this goes well;
I'm really excited to be given a chance to work at Google, but I'm usually
quite nervous about interviews, so I'm hoping everything goes okay...
to admit my first reaction was that someone was playing a strange practical
joke, but after checking it out and replying to the recruiter, it's defiantly
legitimate. :-)
I've got a phone interview scheduled for Tuesday. Hopefully this goes well;
I'm really excited to be given a chance to work at Google, but I'm usually
quite nervous about interviews, so I'm hoping everything goes okay...
I normally don't care for or have any interest in governments or politics,
however I felt this troubling enough to write about... I apologize in advance
for this post not being filled with interesting Radeon hacking topics. :-)
Apparently the New Zealand government feels it's acceptable to automatically
enroll new employees in a KiwiSaver scheme, without prior permission or
agreement, and deduct 4% from my pay every pay day.
Fortunately it's possible to request an "opt-out" of this scheme, which I have
done. I still find it rather unsettling that you may be automatically enrolled
in a saving scheme, without any prior permission or agreement, and that you
must request an opt-out, as apposed to being guaranteed the
ability to opt-out.
Should I not be entitled to opt-out at will, and decide where my own money
goes? I would rather have the money in my bank account, where I may do with it
as I choose, than some semi-forced government saving scheme.
I don't think there will be any problems getting my opt-out request approved.
As far as I can tell, I meet all the criteria required... However the fact
that you must request an opt-out, and are not guaranteed one is
somewhat troubling...
however I felt this troubling enough to write about... I apologize in advance
for this post not being filled with interesting Radeon hacking topics. :-)
Apparently the New Zealand government feels it's acceptable to automatically
enroll new employees in a KiwiSaver scheme, without prior permission or
agreement, and deduct 4% from my pay every pay day.
Fortunately it's possible to request an "opt-out" of this scheme, which I have
done. I still find it rather unsettling that you may be automatically enrolled
in a saving scheme, without any prior permission or agreement, and that you
must request an opt-out, as apposed to being guaranteed the
ability to opt-out.
Should I not be entitled to opt-out at will, and decide where my own money
goes? I would rather have the money in my bank account, where I may do with it
as I choose, than some semi-forced government saving scheme.
I don't think there will be any problems getting my opt-out request approved.
As far as I can tell, I meet all the criteria required... However the fact
that you must request an opt-out, and are not guaranteed one is
somewhat troubling...
I've pushed some fixes from Markus Amsler which fix two bugs introduced by the
vertex program branch merge. The first was caused by a core Mesa change cherry
picked from the Gallium branch, and the second was a copy-and-paste error.
This should fix a couple of problems reported by various people. :-)
vertex program branch merge. The first was caused by a core Mesa change cherry
picked from the Gallium branch, and the second was a copy-and-paste error.
This should fix a couple of problems reported by various people. :-)
I finally got around to merging my vertex program branch into the mainline
Mesa tree. This changes the R300 drivers vertex program code to match AMD's
names and semantics; for example, the separation of Vector and Math engine
opcodes, etc.
This doesn't add any additional optimization of the vertex programs, but does
clean up the code, and make it easier to compare against the documentation.
Hopefully there are no regressions from this merge. I've tested with the Mesa
vertex program tests, glxgears, Quake 3, etc.
I've also pushed a patch to the DRM which corrects the R300_CMD_WAIT command;
you can read the commit log for the details, but briefly we would set the
wrong idle conditions, which lead to some lockups. Actually this was only seen
recently during an IRC discussion between myself, Jerome Glisse, and John
Bridgman. Thanks to John for pointing this out! :-)
I don't know exactly which lockups are fixed by this patch, so please test
your favorite OpenGL programs.
Anyway, I'm going to get some more sleep and hopefully get over this horrible
cold; hopefully before I get fired for taking too much sick leave. ;-)
Mesa tree. This changes the R300 drivers vertex program code to match AMD's
names and semantics; for example, the separation of Vector and Math engine
opcodes, etc.
This doesn't add any additional optimization of the vertex programs, but does
clean up the code, and make it easier to compare against the documentation.
Hopefully there are no regressions from this merge. I've tested with the Mesa
vertex program tests, glxgears, Quake 3, etc.
I've also pushed a patch to the DRM which corrects the R300_CMD_WAIT command;
you can read the commit log for the details, but briefly we would set the
wrong idle conditions, which lead to some lockups. Actually this was only seen
recently during an IRC discussion between myself, Jerome Glisse, and John
Bridgman. Thanks to John for pointing this out! :-)
I don't know exactly which lockups are fixed by this patch, so please test
your favorite OpenGL programs.
Anyway, I'm going to get some more sleep and hopefully get over this horrible
cold; hopefully before I get fired for taking too much sick leave. ;-)
I've started thinking about doing some work on a companion tool to Revenge,
which would be similar to r300_demo, but designed more for testing
implementation of the 3D documentation.
Currently we don't have a easy way to take something from the 3D
documentation, try a quickly written implementation, and see whether it works
before writing a proper implementation for the Mesa driver.
While this is possible by hacking the Mesa driver directly, you do not have
fine-grain control over exactly which commands are sent to the GPU, and
somewhat limited debugging ability.
I apologise that I've been kind of slack with getting the vertex program
branch merged. Between starting a job (working at Dick Smith Electronics),
moving from my Opteron to a Sempron box (about time I upgraded to PCI-E), and
cleaning up my home directory, I've been a bit pressed for time.
I'll try to get it merged before or over the weekend. :-)
which would be similar to r300_demo, but designed more for testing
implementation of the 3D documentation.
Currently we don't have a easy way to take something from the 3D
documentation, try a quickly written implementation, and see whether it works
before writing a proper implementation for the Mesa driver.
While this is possible by hacking the Mesa driver directly, you do not have
fine-grain control over exactly which commands are sent to the GPU, and
somewhat limited debugging ability.
I apologise that I've been kind of slack with getting the vertex program
branch merged. Between starting a job (working at Dick Smith Electronics),
moving from my Opteron to a Sempron box (about time I upgraded to PCI-E), and
cleaning up my home directory, I've been a bit pressed for time.
I'll try to get it merged before or over the weekend. :-)
I've published my work on the R300 DRI vertex program code, and hopefully
fixed the last couple of bugs. The MAD and SUB instructions have some
weirdness, but they should be working correctly now...
You're welcome to test and report any problems. Assuming no major problems,
I'll finish off by reworking the Vector/Math Engine macros, and pushing into
the main tree.
I also have some thoughts on how the vertex/fragment program code could be
further improved, but I'm not sure it's worth the effort with Gallium around
the corner... Really a full optimizing compiler is required, rather than a
simple Mesa-to-Hardware translator; this may still be the case with Gallium,
but I'm not sure.
I would be very interested to talk to AMD about their implementation. Though I
suspect they would have an easier time as they can target the whole graphics
stack specifically to ATI hardware...
fixed the last couple of bugs. The MAD and SUB instructions have some
weirdness, but they should be working correctly now...
You're welcome to test and report any problems. Assuming no major problems,
I'll finish off by reworking the Vector/Math Engine macros, and pushing into
the main tree.
I also have some thoughts on how the vertex/fragment program code could be
further improved, but I'm not sure it's worth the effort with Gallium around
the corner... Really a full optimizing compiler is required, rather than a
simple Mesa-to-Hardware translator; this may still be the case with Gallium,
but I'm not sure.
I would be very interested to talk to AMD about their implementation. Though I
suspect they would have an easier time as they can target the whole graphics
stack specifically to ATI hardware...
I've started hacking the vertex program code in R300 DRI based on the newly
released 3D documentation. Initially this started out as just register/define
renaming, but I'll probably end up restructuring the code again as currently
it's still a bit messy...
Christoff Brill has also made some patches renaming R300 DRI register names to
the names used in AMD's documentation, which was generally agreed to be a Good
Thing (TM).
I will probably finish the vertex program hacking today and commit either
today or tomorrow. There is currently a bug on the master branch that causes
my card to instantly lockup with any 3D program, so I need to track that down
first...
So there is work going on, even though not much of it has been pushed yet. :-)
released 3D documentation. Initially this started out as just register/define
renaming, but I'll probably end up restructuring the code again as currently
it's still a bit messy...
Christoff Brill has also made some patches renaming R300 DRI register names to
the names used in AMD's documentation, which was generally agreed to be a Good
Thing (TM).
I will probably finish the vertex program hacking today and commit either
today or tomorrow. There is currently a bug on the master branch that causes
my card to instantly lockup with any 3D program, so I need to track that down
first...
So there is work going on, even though not much of it has been pushed yet. :-)
- Music:Faithless - Insomnia (Kristoff Unreleased B2TF Remix)
I just got back from driving to the map point for a warehouse party, through
the morning traffic from hell, only to find out I was supposed to be there
tomorrow after 4 PM.
Awesome... :(
the morning traffic from hell, only to find out I was supposed to be there
tomorrow after 4 PM.
Awesome... :(
I've started looking into the AtomBIOS ROM format, and there is still a lot
that I don't understand completely, but I'm starting to get a better idea...
From what I can tell, there isn't any clear distinction between the bytecode
and data sections, but it's a bit confusing because the ParseTable function
seems to parse both tables and opcodes...
Anyway, just a quick update, hopefully I'll have something more concrete
soon...
that I don't understand completely, but I'm starting to get a better idea...
From what I can tell, there isn't any clear distinction between the bytecode
and data sections, but it's a bit confusing because the ParseTable function
seems to parse both tables and opcodes...
Anyway, just a quick update, hopefully I'll have something more concrete
soon...
I've been doing some work to optimize tangent space calculation in my
development engine, Trinity. A large amount of time is spent calculating the
reciprocal square root for vector normalization. I've done some profiling
(with the rdtsc instruction) of different ways to calculate the reciprocal
square root which might be interesting to read about.
Here are the results (clock cycles) of the profiling code running on a dual
AMD Opteron 246.
The rsqrtps instruction (operates on 4 floats simultaneously) would probably
be even faster than the rsqrtss instruction, but thats an optimization for
later...
You may be interested in Chris Lomont's Fast Inverse Square Root and Apple
Computer, Inc's Computing the Inverse Square Root (the Doom 3 function) paper
as further reading.
development engine, Trinity. A large amount of time is spent calculating the
reciprocal square root for vector normalization. I've done some profiling
(with the rdtsc instruction) of different ways to calculate the reciprocal
square root which might be interesting to read about.
Here are the results (clock cycles) of the profiling code running on a dual
AMD Opteron 246.
05: rdtsc_base 37: rdtsc_trinity_rsqrt 37: rdtsc_xreal_sse_rsqrt 43: rdtsc_quake3_rsqrt 44: rdtsc_doom3_rsqrt 51: rdtsc_xreal_rsqrt 60: rdtsc_doom3_invsqrt16_rsqrt 76: rdtsc_slow_rsqrt
The rsqrtps instruction (operates on 4 floats simultaneously) would probably
be even faster than the rsqrtss instruction, but thats an optimization for
later...
You may be interested in Chris Lomont's Fast Inverse Square Root and Apple
Computer, Inc's Computing the Inverse Square Root (the Doom 3 function) paper
as further reading.
- Music:John Digweed - Digweed Kiss100 (08-08-03)
I started doing some checking for floating point exceptions (NaN, inf, etc) in
my engine for performance reasons; these degenerate values can stall the CPU
quite badly.
After the GPU decided to lockup I didn't get my usual repeating buffer of
music, but rather a constant tone. Probably something to do with how the
kernel was buffering the audio...
It's kind of weird to see your PC grind to a halt and turn into a tone
generator. ;-) AMD, where are the 3D specs!
my engine for performance reasons; these degenerate values can stall the CPU
quite badly.
After the GPU decided to lockup I didn't get my usual repeating buffer of
music, but rather a constant tone. Probably something to do with how the
kernel was buffering the audio...
It's kind of weird to see your PC grind to a halt and turn into a tone
generator. ;-) AMD, where are the 3D specs!
Revenge 1.1 has a bug on X1600 Mobility PCI-E cards which probably effects all
RV530 (aka M56) hardware. The framebuffer is not detected correctly on this
hardware; you can work around this problem by disabling framebuffer mapping
with the following patch.
I have also decided that it would be a good idea to convert Revenge to use
PCI-ID identification. This means that hardware detection should be more
reliable, but that Revenge will only work on your hardware after you have
added your PCI-ID and associated information.
Without PCI-ID identification there will probably be too many subtle variances
between families and even individual chips for Revenge to work reliably on
every card...
I've also sent an email to the LinuxBIOS mailing list in response to some of
my AtomBIOS related entries, there does seem to be some interest... No code
has been written yet and it's just research at this point, but who knows, it
might lead to something... :-)
RV530 (aka M56) hardware. The framebuffer is not detected correctly on this
hardware; you can work around this problem by disabling framebuffer mapping
with the following patch.
I have also decided that it would be a good idea to convert Revenge to use
PCI-ID identification. This means that hardware detection should be more
reliable, but that Revenge will only work on your hardware after you have
added your PCI-ID and associated information.
Without PCI-ID identification there will probably be too many subtle variances
between families and even individual chips for Revenge to work reliably on
every card...
I've also sent an email to the LinuxBIOS mailing list in response to some of
my AtomBIOS related entries, there does seem to be some interest... No code
has been written yet and it's just research at this point, but who knows, it
might lead to something... :-)
- Music:Collateral Dreams (9 December 2007) - Part 2 with guest Myon
I've been wondering for some time how the newer id Software games (Doom 3,
Quake 4, ETQW, etc) create interactive GUI surfaces in the world.
I peeked inside the ETQW beta SDK and found they are using barycentric
coordinates. I found almost identical (but much more complete) code in
Christer Ericson's Real-Time Collision Detection book.
So I finally know how it's done, and since the code is published in a book, it
should be fair game. :-)
Now I need to make some time for R5XX hacking on r300_demo...
Quake 4, ETQW, etc) create interactive GUI surfaces in the world.
I peeked inside the ETQW beta SDK and found they are using barycentric
coordinates. I found almost identical (but much more complete) code in
Christer Ericson's Real-Time Collision Detection book.
So I finally know how it's done, and since the code is published in a book, it
should be fair game. :-)
Now I need to make some time for R5XX hacking on r300_demo...
