Hi Leute!
Ich habe heute versucht, meine Render-Funktion in einem 2. Thread laufen zu lassen.
Das ganze funktioniert einen Frame lang, dann wirft D3D eine Exception:
|
Quellcode
|
1
|
D3D11: CORRUPTION: ID3D11DeviceContext::Map: Two threads were found to be executing functions associated with the same Device at the same time. This will cause corruption of memory. Appropriate thread synchronization needs to occur external to the Direct3D API. 1108 and 4732 are the implicated thread ids. [ MISCELLANEOUS CORRUPTION #28: CORRUPTED_MULTITHREADING ]
|
Das ganze liegt daran, dass im Update-Thread der ModelRenderer (und noch ein paar andere Objekte) seinen ConstantBuffer updated und im Render-Thread dieser ConstantBuffer schon wieder genutzt wird.
Ich hätte jetzt mehrere Vorangehensweisen:
1.) Deffered Device Contexts: Der UpdateThread und der RenderThread erhalten jeweils einen DDC, mit dem sie die jeweilige CommandList fleißig füllen. Im MainThread werden (wenn Update- und RenderThread mit dem Frame fertig sind) die beiden DDC-CommandListen auf den Immidiate Device Context gedingst, halt ausgeführt.
Nur weiß ich nicht, ob das klappt. Ratet mir lieber vorher davon ab, bevor ich es versuche zu implementieren
2.) Doch Update und Render im Main-Thread ausführen. D3D und PhysX belegen schon die restlichen Cores. Evtl. später noch Script- und KI-Threads per ThreadPool sollte reichen.
3.) Alles, was mit dem DC im Update-thread zu tun hat, im MainThread erledigen, wenn kein DC mehr in Anspruch genommen wird.
Ich persönlich würde 1.) nehmen, wenn es denn klappen würde. 2.) Hatte ich bis jetzt, lief ganz gut, will aber den RenderThread vom Update-Thread trennen. 3.) wäre ziemlich komplizier umzusetzen, da hier das Design ziemlich umständlich dreckig gemacht wird.
Was sagt ihr? Macht 1.) Sinn, oder sind DDCs dafür garnicht gedacht?