🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Message pump and D3D11 DXGI in separate threads

Started by
5 comments, last by hplus0603 1 year, 7 months ago

I have read:
https://learn.microsoft.com/en-us/windows/win32/direct3darticles/dxgi-best-practices#multithreading-and-dxgi
https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/d3d10-graphics-programming-guide-dxgi#multithread-considerations

Threading setup
---------------
Main thread (Main loop): Create window and run the message pump (PeekMessage()).
Add messages (keyboard, mouse, ...) to a thread safe double buffered queue.

Render thread (Render loop): Create DirectX 11 stuff (Device, ...).
Read game state N from game thread. Update GPU buffers, draw calls, swapchain present.

Game Thread (Game loop): Create game world. Game logic, physics, update game state N + 1.

Thread pool: spawn additional worker threads.


According to the posted links, DXGI may call SendMessage (synchronous call), which can lead to deadlock
when the message pump and DXGI are on separate threads. But as far as I understand it,
there shouldn't be any problems in this case with the main thread, because the only thing it does is to
pump messages and add them to a thread safe queue. or am I missing something?
Can a deadlock still occur when switching to an exclusive fullscreen mode?
Calling the swapchain present? or other DXGI calls?
I won't add any other code in the main thread that could make the message pump thread wait on the render thread.

If this is ok, how do I reduce the CPU usage in the main thread? Running this loop will consume 100% of the CPU core. But at the same time, we want the input to feel responsive.

Advertisement

Its not about the thread safe queue in this case, and really depends on which messages you put in the queue and handle later. If that main thread can instantly handle your window messsages I dont think you get into trouble but if thats what you are capturing too you will stall or even deadlock the application here.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

Sorry for the late reply. The purpose of the main thread is to remove messages from the internal queue, timestamp them, and add them to my thread-safe queue. The game thread and render thread will handle these messages. Do you see any problem with this?

As I said before it really depends on which messages you delay because DXGI expects the messages it sends to be handled immediately.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

I understand. The Render Thread may be blocked if any of the DXGI functions call SendMessage, which in turn causes the Render Thread to be unable to read messages from the thread safe double buffered queue. The only way to solve this is to let the Main Thread handle window messages.

Yes, you really do want the main thread to run the message pump and DXGI stuff. This is how Win32 works.

Also, D3D11 isn't particularly good at multi-threading. To get the best performance out of multiple cores and multiple GPU resources, you need to use D3D12 – that's one of the main reasons that API version exists!

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement