DirectX 12 Multi Threading

Started by
5 comments, last by Barnett 7 years, 7 months ago

I still have a great deal of uncertainty about what is and what is not thread safe in DX12.

I understand that ID3D12Device and ID3D12CommandQueue objects are free threaded. So your application only has to create one instance of these and can then use them on multiple threads that may call member functions of these objects simultaneously. On the other hand, ID3D12CommandAllocator and ID3D12GraphicsCommandList objects are not free threaded, so each thread needs to create its own instances of these.

But what about things like ID3D12RootSignature and ID3D12PipelineState? Can a single instance of these be used simultaneously on multiple threads?

Eg:


ID3D12CommandQueue* pCQ;
ID3D12GraphicsCommandList* pGCL_1;
ID3D12GraphicsCommandList* pGCL_2;
ID3D12RootSignature* pRS;

void Thread_1()
{
  pGCL_1->SetGraphicsRootSignature( pRS );
  //...
  pCQ->ExecuteCommandLists( 1, &pGCL_1 );
}
void Thread_2()
{
  pGCL_2->SetGraphicsRootSignature( pRS );
  //...
  pCQ->ExecuteCommandLists( 1, &pGCL_2 );
}

Whould this be safe to do? How can I tell what is being done to the shared ID3D12RootSignature object, and how do I know if it is thread safe?

Advertisement
Yes, ID3D12RootSignature and ID3D12PipelineState are immutable (e.g. SetGraphicsRootSignature only reads from them / doesn't modify the object), which makes them safe.
But what about things like ID3D12RootSignature and ID3D12PipelineState?

Root signature and pipeline state are immutable objects, so I'm pretty sure that they are thread safe. Of course, you have to make sure that pRS is initialized before threads run and that object pointed to by pRS is not destroyed while threads are still running.

OK, thanks, that makes sense.

What about sharing resources? Is is safe to call ID3D12Resource->GetGPUVirtualAddress() on more than one thread to use that same resource on different threads?

OK, thanks, that makes sense.

What about sharing resources? Is is safe to call ID3D12Resource->GetGPUVirtualAddress() on more than one thread to use that same resource on different threads?

That's fine as well.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

As a general rule of thumb, if the API is on a command list, it can only be called from one thread at a time, otherwise, it's thread-safe. It is safe to reference objects (i.e. pass them into APIs on any other interface) from multiple threads, unless the API modifies the object (e.g. Reset() targeting a command allocator modifies the allocator, Evict()/MakeResident() I think aren't thread-safe for a given resource).

As a general rule of thumb, if the API is on a command list, it can only be called from one thread at a time, otherwise, it's thread-safe.

Thanks. That is a lot more permissive than I expected. I am going to have to go through my code and see where I have been overly conservative.

This topic is closed to new replies.

Advertisement