# Is Direct3D threading safe? - Locking a resource in another thread

This topic is 3625 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

##### Share on other sites
The D3D device isn't thread-safe unless you pass the D3DCREATE_MULTITHREADED flag to IDirect3D9::CreateDevice. If you do pass that, the device will use locks on nearly every operation which will cause noticable overhead. It's recommended that you handle locking and synchronization yourself, at least if performance is an issue.

##### Share on other sites
Ok,I don't use that flag, but what about making a Lock call in a thread,other than the main one(without using the D3DCREATE_MULTITHREADED flag)? As far as I know, when we make a D3D call, this call is recorded to a command buffer managed by the driver and then the driver sends those commands to the hardware.(When it sends them, I don't know. However the "Present" function seems a logical place to do it.) I think, that a Lock call from another thread will end up in the same command buffer of the driver, independent of the thread from which it was called. So, it doesn't seem to be a harmful operation to me. What are your thoughts on that?

##### Share on other sites
Quote:
 Original post by 67rtyusOk,I don't use that flag, but what about making a Lock call in a thread,other than the main one(without using the D3DCREATE_MULTITHREADED flag)? As far as I know, when we make a D3D call, this call is recorded to a command buffer managed by the driver and then the driver sends those commands to the hardware.(When it sends them, I don't know. However the "Present" function seems a logical place to do it.) I think, that a Lock call from another thread will end up in the same command buffer of the driver, independent of the thread from which it was called. So, it doesn't seem to be a harmful operation to me. What are your thoughts on that?
Doing anything with D3D from multiple threads without the D3DCREATE_MULTITHREADED is undefined behaviour. The Debug Runtimes will scream and shout at you for accessing D3D resources from multiple threads without the flag.

If you must do this, then lock the resource in the main thread, then pass the locked pointer to a worker thread. Once that's complete, signal the main thread and get it to Unlock() the resource.

If you lock the resource from a second thread, D3D might be accessing it to render it or upload it to the graphics card. In the best case, that'll crash and in the worst case, it'll give you weird undefined behaviour that'll be extremely hard to track down.
This could also give totally different behaviour on different OS's, D3D versions or drivers.

##### Share on other sites
Quote:
 Original post by 67rtyusIf I would follow the old single threaded approach here, I am worried that the frequent WM_MOUSEMOVE messages will hold the CPU busy most of time.

Just update the state of the GUI in another thread, but make actual modifications to the 3D objects in the main thread. Like:

//GUI threadbutton.Color = HoverColor;//Main threadvertexBuffer->Lock();...v->Color = button.Color;...gui->Draw();

##### Share on other sites
Quote:
 Original post by MJPThe D3D device isn't thread-safe unless you pass the D3DCREATE_MULTITHREADED flag to IDirect3D9::CreateDevice. If you do pass that, the device will use locks on nearly every operation which will cause noticable overhead. It's recommended that you handle locking and synchronization yourself, at least if performance is an issue.

The D3DCREATE_MULTITHREADED doesn't make it much more threadsafe if you're locking/destroying a texture or a vb (etc.) that another thread is using at the same time to draw.

The important is not necessarily the "thread" that calls into d3d (except for createdevice, testforcooperativelevel, reset, see my small article about running d3d9 devices in a multithreaded program ), but more that the "flow" of operations is serialized from the point of view of the device and that means clear design with critical sections, signals between concurrent threads (or leaving the responsibility of calling into the device to one single thread).

For the initial problem (MOUSEMOVE being called too often) why not simply update the mouse position variable during the message and traverse the tree only when you actually need that information (when you're refreshing the display or when you detected a mouse click). Also maybe you can optimize that tree traversal (index elements in a hash table per screen quadrants/tiles, reduce the size of the tree by only storing stuff that reacts to mouse over etc.)

LeGreg

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 14
• 12
• 9
• 12
• 37
• ### Forum Statistics

• Total Topics
631428
• Total Posts
3000027
×