Jump to navigation
"const now means the same thing as mutable".
On our trip through CudaRaster
, Samuli Laine and Tero Karras' open sourced implementation of their High-Performance Software Rasterization on GPUs
paper, it's time to check out triangle setup. This is in fact the first step in the process, so we're going backwards here. Each thread takes care of one triangle, so there's few headaches this time in keeping the GPU busy. The challenge is efficient triangle setup, clipping, and correct subpixel snapping and culling.
I keep forgetting this fine print, so I'll just type up a cheat sheet here. Most of it comes from digesting the fantastic agner.org
. That doesn't guarantee I got everything 100% correct though.
In the quest to demistify the high performance magic of CudaRaster
by Samuli Laine and Tero Karras, it's time for a closer look at the coarse rasterization stage. As the paper
explains, this stage merges the per-bin queues, and adds the triangles to a queue for each coarse tile it overlaps. Thanks to the authors' generous open-sourcing of the code, we can take a look at how that works exactly.
In the CudaRaster project
, Samuli Laine and Tero Karras have implemented a complete triangle rasterizer in Cuda. They explain how it works, and why, in their excellent High-Performance Software Rasterization on GPUs
paper. What's more, they've open sourced the implementation, which is fantastic. The code is full of little and big gems, highly efficient ways and tricks to keep those cores busy. It took me a while to wrap my head around it, so in this post I want to share my attempt at demystifying the bin rasterizer phase a little, just to start somewhere.
Man it's like 1992 all over.
Hm let's see if this works.
Say, what's up with these new fangled toys...?
Posting code for all to see is near suicidal, especially if you didn't really test it all that much... but what the hell, who cares :)
Personal notes on templates / cheat sheet. Not sure how much of this is still true or accurate in C++11.
And there was much rejoicing!
The extremely tricky way in which it introduced a bidirectional dependency, completely different from regular header files, made for great pillow talk though. But alas, no more!
So here's an obscure D3D9 compiler error that google gives barely 10 hits for:
"error X4509: invalid register semantic 'i0', or variable must be bound to multiple register banks (c register binding required)"
Planets have always been the
poster child for procedural rendering, or shaders approximating that, and the latest expansion to Eve added some great examples. There's now a blog post about how it works
. Too bad I wasn't on this task, it sounds like the team was having a blast :)
A quick visual summary of the three main types of Compute Shader IDs. Nothing new let alone spectacular here, just a quick reminder for myself. I like pictures.
I've contacted the authors of the truly excellent Advanced Global Illumination
book to forward a couple of Errata; until their busy schedules allow an update, here's a copy for Google.
Link to deliberately terrible code
for a calculator that appears to work, but really doesn't. The comments are nonsensical, it "optimizes" adding two floats, subtracts using strlen, multiplies using addition, caches the result of division, has four names for the same thing, is inconsistent, and is just generally a disaster for readability while appearing to actually make sense and follow reasonable guidelines. Silliness from the OMGWTF contest two years ago.
Google video called OO Design for Testability
I'm a big fan of unit testing, even though I rarely do it in production code (blame management). Why? Because just the possibility that some code might
be tested in isolation automatically works as a very strong repellent against erring on the side of singletons, other forms of global state, God classes, or chasing around all sorts of references -- an effect I've now learned is called a Law of Demeter Violation
In this regard, testing is similar to exceptions in C++, another great example of the Just Pretend Trick: if you pretend you use exceptions, design automatically gravitates toward things like RAII, and that's a definite plus. The fact that you never actually use exceptions is irrelevant.
Also; I used to be enamored with the environment pattern, which passes a service locator to anybody that needs it; after Jon Watte. But what the guy says in the video matches my experience with it; it's hard to identify the exact subset of dependencies that anybody needs, and so you don't know how to stub it out properly without looking at the user code. So that's something to reconsider...
In Episode 4a of this very entertaining MIT Course on LISP
, Gerald Jay Sussman talks about a program to simplify algebraic expressions. Rather than writing such a program, he writes a general system which you can feed rules, and out comes a transformed expression. So instead of hardcoding that "x + 0" is just "x", a general rule says "replace anything
followed by '+' followed by '0' with just that anything
". Letting this rulebook run on "x + 0" automatically gives you "x".
Naturally, while watching that, I got a nasty itch to try this in C++, at compile time
. Disclaimer: this is a nothing-on-TV-again hack, so don't take this too seriously. I tested with one (count'em, one) expression, and it seemed to work...