Sometimes I get this question. And since it happens frequent enough, I decided I should write it publicly so that others can benefit, and also so I don’t have to repeat myself every time 🙂
In case you don’t know me, I’m self taught. I started doing graphics programming at age 14. My first experience was Visual C++ 6.0 and dived straight into C, C++ and assembly and came out just fine. The basics I learnt by reading a random PDF I found back then “Aprenda C++ como si estuviera en primero” (in Spanish) which was a very simple introduction to the language in 87 pages. What a variable is, what an enum is. How to do basic hello world.
Then I learnt a lot by trial and error. I started with several open source Glide Wrappers which were popular at the time. I used the debugger a lot to see line by line how the variables evolved. I would often remove some snippet of code to see what would happen if I took it out. I also played a lot with XviD’s source code.
Back then I had the DirectX SDK 7.0 samples and documentation to play with and I learnt a lot from it. In particular, Mathematics of Direct3D lighting fascinated me. I ended up writing my own TnL C library written in SSE assembly. It wasn’t very useful and I haven’t really updated it in more than a decade, but it helped a lot paving my foundations for when I came into contact with Vertex & Pixel Shaders. I was shocked that what took me an entire summer vacation and lots of assembly instructions (e.g. a matrix multiplication) could be done in one line of vertex shader code.
Writing in assembly was a very enlightening experience. For example I discovered on my own what aliasing means, and why __restrict modifier is so important. In particular, one of my “SSE optimized” implementations of matrix multiplications looked something like this:
void multiply_matrix( float *out_result, float *matrix_a, float *matrix_b );
In my first implementation, I quickly discovered that if I called “multiply_matrix( a, a, b )”; the result would be wrong. This is because the result would be written into “a” while some values from it were still required for reading.
I then tried to fix it to properly work in this scenario. But turns out a lot more instructions were needed! I needed to first make a copy of A, or use temporary row copies, or be very clever with the register pressure, etc, etc.
Now it worked correctly if I called multiply_matrix( a, a, b ); but I was heavily penalizing the performance of operations such as multiply_matrix( c, a, b ) unnecessarily! Another solution was to document the function so that you couldn’t do that. i.e. “Don’t do that!”
Without reading or ever hearing what memory aliasing is or nothing about the __restrict keyword, I was instinctively learning about it. So the days I found out about memory aliasing and the __restrict keyword, it was all natural for me.
So that’s how I’ve learnt until this day. I’m all the time tinkering with the low level stuff whenever I can to find how things actually work; and by the time I get my hands on some higher level literature about it, it all comes natural and feels obvious.
Oh so you came here for resources right? How do I get my hands on that higher level literature about it?
First, always scoop for GDC & SIGGRAPH papers. GDC as a free vault section. SIGGRAPH doesn’t, but many authors who often publish on SIGGRAPH will have drafts publicly available from their website. Oh and more thing: DOWNLOAD EVERYTHING YOU FIND. The academic or personal website you’re visiting today may be down tomorrow. A university decides to migrate their servers, the author died, a company bankrupted, and all those juicy links go down.
Second, many graphics devs are on twitter and tweet often about this stuff with links to papers. Just take a look at the people I follow (note: it seems you need to be logged in to twitter to see it). Many of them announce themselves as Graphics Engineers of X company or working for AMD/NVIDIA/Intel, etc. You don’t need to be a genius to get it. If in doubt, take a quick glance at their timeline.
Also many whitepapers/presentations often end up with the author’s twitter handle at the end. And don’t forget to checkout the bibliography at the end. One thing leads to another.
Third, aside from learning trial and error, my main source of learning materials has been:
- MS DirectX SDK documentation.
- D3D10 Book Programming Vertex Geometry and Pixel Shaders (it’s a free book, a really good one to start up, all links seem to be dead so grab it here)
- Fabian Giesen’s blog. ALL OF IT. EXCELLENT BLOG. Particularly https://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part-1/
- GDC papers. Hunt for them in the GDC Vault. It has a free section. Start with GDC 06 and up; to understand how GPUs have been evolving (particularly “Batch! Batch! Batch!” is a really good old presentation. Lot has changed since then but the basic semantics still apply, and it gives you a good understanding of why things are now the way they are now)
- SIGGRAPH papers, you just hunt them on the web. Check out Self Shadow’s SIGGRAPH blog for each year; and also google “Advances in Real Time Graphics SIGGRAPH”.
- All of CryTek’s papers.
- Self Shadow’s blog in general.
- MJP’s blog in general.
- Adrian Courrege’s “Graphics Study” entries. He did thorough analysis for GTA 5, Doom 2016, among others.
- This blog has a lot of links for you to hunt: https://interplayoflight.wordpress.com/2013/12/30/readings-on-physically-based-rendering/
- Sven Andersson has a good collection of links to research: http://svenandersson.se/2014/realtime-rendering-blogs.html
- Simonschreibt’s blog
- GPUOpen blog.
- GPUOpen archive.
- Emil Persson’s website.
- CPU Caches and Why You Care, Scott Meyers, Ph.D.; ACCU 2011 Conference.
- Culling the Battlefield, Daniel Colling (DICE), GDC 2011
- Pitfalls of Object Oriented Programming, Tony Albrecht (SCEE), GCAP 09
Very technical about GPUs.
AMD has made their docs public. So public that there are Open Source drivers for Linux. Intel does the same and even pours money into Linux driver development. Even better, now with Vulkan several vendors seem to be publishing PDFs about how to better optimize for their hardware, which contains juicy stuff.
- Depth in Depth from Emil Persson. A bit old but still very valid. I couldn’t find any link so I uploaded it to Google Drive.
- Someone already did it for me.
- Latency hiding in GCN.
- AMD’s GCN instruction set documentation. Heavy, but powerful.
- Intel’s manuals.
- ARM® MaliTM GPU OpenGL ES 3.x Developer Guide
- ARM® MaliTM Application Developer Best Practices
I’m missing a lot of links. I can’t include them all. But take in mind some of these links contain massive links to more blogs and resources. And I’m sorry if I didn’t include your blog in this list, it probably deserves to be here.
By now, you have a lot of resources to start digging. I can’t do all the job for you. You have to do it on your own. I’m only giving you a bootstrap.
I you don’t like this post, then go visit Stephanie Hurblurt’s posts. She has a different approach on learning that bores me (sorry Steph’s!). I’m more of the learn-on-your-own kind of guy, she prefers mentoring. But not everyone is the same. She also keeps a twitter feed full of link with more learning resources.