I recently started reading GPU Pro and it is outstanding! I love the full color and syntax highlighting! Many of the articles are even useful research for our own book. I’d like to write a full review but who knows when I’ll get through the 700+ pages. So I’m going to write a review as I read each section. These reviews will be more about the ideas the articles give me than a complete review of the contents, writing style, etc. But isn’t that the point of reading anyway – to get new ideas?
The 3D Engine Design section was the first section that peeked my interest. Of which, I read two of the four articles:
Porting Code between Direct3D 9 and OpenGL 2.0 – Wojciech Sterna
A chapter in our book is on designing an abstraction layer over OpenGL so the rest of the book can contain API agnostic discussion and code examples (with the exception of the use of GLSL for shaders). This isn’t just important for book writing, all major graphics applications should have a renderer abstraction layer for flexibility, portability, performance, and most importantly, ease of development.
If you count a graduate class project, this is third time I’ve designed such a layer (check it out on sourceforge). Every time, I’ve done so with OpenGL so I was excited to see this article on the differences between Direct3D and OpenGL. While designing the layer, I looked at the Direct3D documentation from time to time but I am not positive that it is ideal for both APIs so I looked forward to learning more from this article.
And I did learn quite a bit. Perhaps I should be embarrassed to say, but I didn’t know anything about the fine grain control available in Direct3D with memory pools. I also felt good learning that many things like vertex buffers and textures seem very similar between the two APIs.
I liked the mention of Cg – since I was recently asked why not use Cg instead of duplicating shaders in GLSL and HLSL. Although it sounds like two slightly different Cg shaders would need to be written anyway. If anyone has experience with maintaining shaders for different APIs, I’d like to hear about it.
Overall, this article was pretty good and I like that it was only 11 pages and right to the point. If I had to criticize it, I would have liked it to be about Direct3D 10/11 and OpenGL 3.2 core profile. But I understand that Direct3D 9 is still widely used and OpenGL 3.2 might not of even been out when this article was written. It would have also been nice to see more tips on designing an abstraction layer that allows for reasonable implementations using both APIs instead of just the API differences – although, the example code more than makes up for this.
Practical Thread Rendering for DirectX 9 – David Pangerl
This article also jumped out at me since I am preparing to write the threading material for our book. My focus is on using threads for out-of-core rendering: reading data from secondary storage, CPU intensive processing of that data (.e.g, computing normals, etc), then finally creating renderer resources (e.g., vertex buffers, textures, etc) – assuming I get all the example code working!
This short article is on another use of threading: using a dedicated thread for issuing rendering commands. The basic idea is to fill a command buffer instead of directly issuing Direct3D calls (I’m pretty sure this would also work with OpenGL). A dedicated rendering thread then executes the command buffer. Filling the command buffer is much faster than calling Direct3D functions, which reduces the CPU usage of your main thread. An interesting statistic from the article is the author found an average Direct3D function call takes 15,231 instructions. Using the dedicated rendering thread, the author saw improvements up to 200% in tests, and a 15% in a real-time game. Considering all that is going on in a game, 15% is great!
One thing I’m curious about is what happens when uploading large objects like vertex buffers and textures? Its not clear to me if a copy of the data is made for the rendering thread or if this falls into their category of commands that synchronize with the rendering thread and execute immediately. I’m also curious about operations like compiling and linking shaders which may be threaded by the driver anyway. I suppose this can happen offline in Direct3D.
It’s worth mentioning that if you have an abstraction layer over your rendering API (and you should!), this could all be done behind the scenes with the user having no idea that there is a dedicated rendering thread.
In closing, I think this is a worthwhile idea that I’d like to implement myself at some point. Also, I’m not sure how this compares to multithreaded rendering in Direct3D 11.