How to rename a C++ thread in Visual Studio 2008 debugger?

January 10th, 2010

Sometimes it’s useful to rename your threads so you can find them easily in your Visual Studio debugger. In .NET-land it’s easy: you have to set the System.Threading.Thread.Name property of the thread you wish to rename and you’re done. It’s not that simple with native code, though.

For native code, when Visual Studio (and WinDbg) is attached, it listens for a specific exception being raised, with specific information in it.

struct VS_THREADNAME_INFO
{
	DWORD type;
	LPCSTR name;
	DWORD threadId;
	DWORD flags;
};

void SetThreadName(DWORD threadId, LPCSTR name)
{
	if (IsDebuggerPresent())
	{
		VS_THREADNAME_INFO tni = { 0x1000, name, threadId, 0 };

		__try
		{
			size_t s = sizeof(VS_THREADNAME_INFO) / sizeof(DWORD);
			RaiseException(0x406D1388, 0, s, (DWORD*)&tni);
		}
		__except (EXCEPTION_CONTINUE_EXECUTION) { /* do nothing */ }
	}
}

The code above should be pretty self-explanatory. Source: Setting a Thread Name (Unmanaged)

CComPtr<IDirect3D9> MemLeak Gotcha

November 17th, 2009

Everyone else but me probably has figured this out already, but I think there’s a chance this post will help someone else with this problem, too.

The other day it took me a good hour of guessing and cursing to get this one figured out. I got all cocky and thought: “Who the hell needs to read CComPtr documentation at all?!?”, and wrote this simple piece of code, before it turned out I should have read that documentation first:

#include <d3d9.h>                 // For IDirect3D9 and WinMain
#include <atlbase.h>              // For CComPtr<T>
#pragma comment(lib, "d3d9.lib")  // Add a reference to d3d9.lib for linking

INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	// Check for memory leaks at program shutdown
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	CComPtr<IDirect3D9> direct3d = Direct3DCreate9(D3D_SDK_VERSION);
	return 0;
}

After you run this under DirectX Debug Runtime, you will get useful information in your Output window in Visual Studio:

Direct3D9: (INFO) :MemFini!
Direct3D9: (ERROR) :Memory still allocated!  Alloc count = 10

One would think that when CComPtr gets out of the scope, it will Release() the COM resource it’s pointing to, and… he would be right. The less obvious thing is – when you assign a T* the CComPtr<T>, the assignment operator calls another AddRef(). The instance passed as a right-hand side argument of the assignment already has a reference count of 1. Therefore, if you assign it to the CComPtr, it will have a reference count of 2. When it gets out of scope, its destructor is called, and only one Release() is called for the IDirect3D interface, and therefore we have a resource leak.

The right way to assign the IDirect3D9 interface to CComPtr<IDirect3D9> is:

CComPtr<IDirect3D9> direct3d;
direct3d.Attach(Direct3DCreate9(D3D_SDK_VERSION));</span></pre>

If you hover your cursor over the Attach method, your trusty Intellisense or Visual Assist will tell you:

void CComPtrBase<IDirect3D9>::Attach(_In_opt IDirect3D9* p2) throw()
// Attach to an existing interface (does not AddRef)

Voila! Exactly what we need! The whole rest of the IDirect3DXxx references can be used as CComPtr<T> pointers. The DirectX 9 API will do the right thing for you. If you just consistently use CComPtr<T> for what it was designed for, you will probably never see a resource leak again. And yes, CComPtr<T> can be used whenever the Direct3D API expects T* as a parameter, even as an output parameter.

Blender, Direct3D, Meshes and You

July 10th, 2009

I’ve spent last couple of days writing a custom mesh exporter for Blender. It all seemed pretty trivial in the beginning (“it’s just conversion of data structures”). It’s easy to iterate over all the faces in the mesh, and then over vertices and then reading their position and normal. Everything seems fine, but there’s a difference in how Blender stores the data, and what format will a Direct3D VertexBuffer accept. Specifically I had two major annoyances.

First problem – flat faces vs smooth faces. If you look at Blender’s Python API Documentation, you will see, that a MFace is just marked as smooth and there’s all to it. If a face is smooth, the normals get interpolated for positions between the vertices. This works the same in Direct3D world. What about flat faces? Well, in Blender a MFace is not marked as smooth and has another attribute – no (short for “normal”). Therefore, if you want to have a flat-shaded face in Direct3D, you have to duplicate the vertices and use their original positions and replace their normals with face normals. This introduces another problem – your exported vertex buffer will have additional vertices in it, which won’t map easily (1-to-1) to the indices Blender has.

Second problem – UV mapping. In Blender you can create a UVLayer. It’s just a set of UV coordinates mapped to vertices in faces. What does Direct3D expect? UV coordinates mapped to vertices… not faces. Blender stores UV coordinates as an attribute of MFace, as list of UV vectors. Notice how a single vertex can belong to multiple faces, and therefore can be assigned a different set of UV coordinates for every face. This means we can’t reuse this vertex in VertexBuffer (or I don’t know a way to do so). Direct3D VertexBuffer will have to hold a copy of this vertex with its original position and normal for every pair of UV coordinates it’s assigned. This again introduces problem of vertex indices not mapping easily (1-to-1) between Blender world and Direct3D world.

The indices problem can be solved by reindexing the newly created vertices and matching them with the faces. Of course that would work, as long as it would be done in a deterministic way (vertices not changing their indices between exports and mesh modifications). And everyone knows indices are needed for the DrawIndexedPrimitive call.

After spending a couple of hours thinking about an elegant solution, I gave up. I’ve decided to go with less elegant, simpler DrawPrimitive calls. So I just iterate over all the faces in the mesh and create vertices as I go – three new vertices per every face. I realize there will be more data to process for the GPU, but I’m just beginning to write my engine and need to make progress. I have more interesting problems to solve at this very moment. After all, I write abstractions for the low-level stuff and can always optimize the mesh later. Using NvTriStrip comes to mind as one of possible ways to achieve that. Or something smart, as I’ll get to know more about Blender and Direct3D.

From C to C# to C++

July 3rd, 2009

It’s amazing, how much computing has evolved in just a dozen years. In 1997 I started learning C, just after I got comfortable with MC680×0 and x86 Assembly. It was natural to think about the data structures in terms of their layout and alignment in memory. It was natural to think about “what will the CPU do if I do that”. It was very natural to think of all these details, to the level of bare silicon. I remember how happy I was when my first inline assembly optimization started working. I remember spending hours with a simple debugger, watching the memory and CPU registers change after every instruction – and I remember enjoying this time a lot. Every little optimization counted, because the resources at hand were very scarce. My PC at that time was a Pentium MMX running at a whopping speed of 75MHz, with 64MB of RAM and S3 ViRGE video card. Can you imagine using one of those today? The code people used to write wasn’t even called “native”. There was no “managed” code yet. The code was just “code”. A couple of months later I started learning C++ and were using the two alternately, whenever I wanted.

Fast forward to 2003, the time of .NET Framework version 1.1. Somehow I have never seriously used Java, therefore C# and .NET Framework was my first “managed” programming environment. I loved C# for its readability and simplicity. There were no pointers and memory allocations that needed to be taken care of. There was no header file mess, everything got neatly compiled. The managed environment took a lot of burden off the programmer, but not without a cost. The programs written in managed code were really resource hungry, which wouldn’t be acceptable six years earlier. The focus was on writing code fast, instead of writing fast code. Of course it had its advantages – I learned quite a lot about real object oriented programming, software architecture, design patterns (well, I learned the names of some tricks I’ve been using, and learned a couple of new ones) and code maintainability. I think I wouldn’t be able to learn that if I were using C++. I worked on semi-enterprise level applications.

I used .NET and C# for six years. Then I decided I needed a change.

Right now I’m re-learning C++, and learning the modern approach to C++ programming (existence of which I wasn’t even aware). The first few weeks were a horror. I couldn’t live without good refactoring tools (Visual Assist X isn’t even half as good as Resharper). I’ve made total mess in my code, because I was used to not having to think about the header files. Class construction worked the opposite way I was used to. Resource leaks in my code were ubiquitous. The C++ syntax caused pain in my fingers. And a couple of weeks later, I still make newbie mistakes I wouldn’t make in C#. And again, I’m enjoying the hell out of my time in front of computer screen, solving problems that would be nonexistent in “managed” code. It’s fun, because again it feels like solving a puzzle. And again, programming till late night is a fun thing to do.

I think everyone should try something new (or old) every now and then. It’s really refreshing.

Besides, all modern games are written in “native” code for a reason…

The Spring Project

April 9th, 2009

A short post, due to lack of time.

I stumbled upon an interesting project while researching frameworks and engines I could use for my game. The Spring Project is an open source 3D RTS engine, which looks pretty extensible, and the screenshots look all right, too. I briefly skimmed over its code, and saw it’s nice and object-oriented – definitely something worth having a look at.