• Advertisement
Sign in to follow this  

ID3D11DeviceContext on multiple threads

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I am getting a crash due to accessing my immediate device context on multiple threads, which I found out is not allowed.

My situation is pretty simple. My application is mostly single threaded except I load some materials asynchronously. I use the GPU to "stretch" the material preview image to a thumbnail. Then I also call CopyResourse to copy the material data to CPU memory, followed by a Map on those materials to read the CPU memory. The Map is the method the debug output is complaining about.

I read this thread:

http://www.gamedev.n...source-sharing/


and see that "Map calls are executed immediately on deffered contexts since they are always followed up with user CPU interaction that can only be executed now and not stored up for later."

So it sounds like I could use a deferred device context for each thread to do the thumbnail render, CopyResource and Map.

I don't have much experience with multithreading. Is this the best strategy?

Also, should my main render thread hold the references to the ID3D11CommandList each thread records?

Share this post


Link to post
Share on other sites
Advertisement
The rendering in Hieroglyph uses mapping for constant buffer updates on either the immediate context, or on the deferred contexts in multithreaded mode. The driver will determine how the mapping is carried out, but it should be valid with the CPU side data that you are supplying the resource with. In short, I think your method should work (be aware that there is an issue with UpdateSubresource and deferred contexts...).

The command lists can be managed by whichever thread you want - as long as the deferred context generates it, and then it is only used by the immediate thread after that for rendering, then it works fine. You must manually ensure that sequence of events, but outside of that you can do whatever you want!

Share this post


Link to post
Share on other sites
Thanks for the reply. However, I am having doubts about this strategy. Each worker thread is supposed to generate a thumbnail preview, but if all the thread does is build a command list (and add command list to some queue for the main rendering thread to process), the system is not really "rendering in parallel" but just generating command lists in parallel, and the rendering will be done FIFO on the main rendering thread.

It also means I need to add extra mechanism to notify the worker threads that its command list actually was rendered on the main thread. This doesn't make sense though because the command list renders a simple preview image, copies the render target to STAGING resource, and then maps it to copy to CPU memory. If the render target has not been rendered to yet, how can I CopyResource and Map? It seems like I couldn't do this until after I got notification that the command list was processed. So it seems like the pseudocode would have to be:

1. Build command list in thread of only commands for rendering.
2. Submit command list to a queue on main rendering thread so immediate DC can process command list.
3. Wait to be notified that the command list was processed.
4. CopyResource to STAGING and Map (assumes this happens immediately on deferred DC).

Anyway, I'm thinking of just using a critical section and the immediate device context. The thumbnail parallelism was more for data loading than rendering.

Share this post


Link to post
Share on other sites
You are right about the sequence of events - you build the command list in parallel, and then perform the rendering in serial on the main thread. However, what other method would you expect? You only have one set of GPU facilities, so performing one command list at a time makes sense - doing it in parallel would only split your GPU into multiple tasks simultaneously, which would not help things.

However, generating the command list in parallel has some good benefits, some of which may help you and some which may not. By building the command list in parallel, you are spreading the cost of making API calls across multiple threads. Depending on how many calls you make per command list, this can result in a significant speed up. Regarding the contents of the texture resource that you are using - rendering operations will use the contents of the resource at the time of command list execution. Only operations that are mapping CPU contents to a GPU resource are implemented immediately (or appear to be immediately implemented to the API user). You can think of the command list as saying which resources to bind in which pipeline location, but their contents are used as they exist at the time of rendering the command list on the immediate context.

All of these things are dependent on the rendering scenario and hardware that you are running on. I would suggest that you either make your renderer configurable to switch between single and multithreaded mode, or profile in both scenarios on your target hardware and choose accordingly!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement