Skip to main content
replaced http://gamedev.stackexchange.com/ with https://gamedev.stackexchange.com/
Source Link

Okay, first of all, I would like you to consider forfeiting the notion of "best practice". There are no such things as "best practices". Some things work, some don't, and none do under all assumptions and scenarios, therefore being "best". Every time you use the words "best practice", God kills a kitten, so please think of the kittens.

Now, onto your problem. You certainly have given it a lot of thought, and most of your assumptions are correct. Let's start:

  • A Direct3D device can't render to multiple windows at the same time. In general, you will only have one window per Direct3D device. However, as you already know, you can certainly have multiple Direct3D devices per process, and you certainly have one per thread, which leads us to.

  • You can have multiple Direct3D devices in the same thread! Particularly, if my program wasn't very CPU intensive, I would create two Direct3D devices in the same thread, and render serially. For each iteration of your render loop, do everything you need to do for each Direct3D device. If, as you say, you can have 400+ fps, then you shouldn't have problem with two devices in the same thread. Keep everything in the same thread, and you won't have to care about synchronization at all.

  • DirectX is generally not thread-safe. This is different from the thread-hostility of Windows Forms, in which objects are owned by a thread and you can't generally do anything with them from a different thread (apartment). DirectX (9, which is what I mostly know) doesn't really care which thread you call functions for, as long as you don't call two API functions at the same time from different threads. You can opt in/out of thread safety when you create your device, but in general, as long as you synchronize access to your device, you can certainly do things from multiple threads. This doesn't mean you should though.

  • Windows Forms is not thread-friendly, so you certainly have to have all your windows in the same thread.

  • If you must separate the logic and Direct3D devices into different threads, then I would have three threads: one for the COM stuff (windows forms), and one for each device. You must then use some kind of synchronization to pass messages or data between threads, so make sure you keep it as simple as possible, because that is likely to become one of the most complex parts of your program.

  • There's nothing wrong with duplicating data for all devices. Video cards have humongous memory these days, and if you're reaching the limit with one device, there are other things you should worry about before adding a second device. However, you can share data between devices, and in fact, you can share data across processes, and even across different versions of Direct3D. That's a bit out of the scope of this question, but I have a more detailed answermore detailed answer, so check that one out as well.

In general, do what's best for your assumptions. I'd recommend you do what's easiest for you, and don't try to hunt for holy grails or "best practices". Do what's best for you, and go with that!

Okay, first of all, I would like you to consider forfeiting the notion of "best practice". There are no such things as "best practices". Some things work, some don't, and none do under all assumptions and scenarios, therefore being "best". Every time you use the words "best practice", God kills a kitten, so please think of the kittens.

Now, onto your problem. You certainly have given it a lot of thought, and most of your assumptions are correct. Let's start:

  • A Direct3D device can't render to multiple windows at the same time. In general, you will only have one window per Direct3D device. However, as you already know, you can certainly have multiple Direct3D devices per process, and you certainly have one per thread, which leads us to.

  • You can have multiple Direct3D devices in the same thread! Particularly, if my program wasn't very CPU intensive, I would create two Direct3D devices in the same thread, and render serially. For each iteration of your render loop, do everything you need to do for each Direct3D device. If, as you say, you can have 400+ fps, then you shouldn't have problem with two devices in the same thread. Keep everything in the same thread, and you won't have to care about synchronization at all.

  • DirectX is generally not thread-safe. This is different from the thread-hostility of Windows Forms, in which objects are owned by a thread and you can't generally do anything with them from a different thread (apartment). DirectX (9, which is what I mostly know) doesn't really care which thread you call functions for, as long as you don't call two API functions at the same time from different threads. You can opt in/out of thread safety when you create your device, but in general, as long as you synchronize access to your device, you can certainly do things from multiple threads. This doesn't mean you should though.

  • Windows Forms is not thread-friendly, so you certainly have to have all your windows in the same thread.

  • If you must separate the logic and Direct3D devices into different threads, then I would have three threads: one for the COM stuff (windows forms), and one for each device. You must then use some kind of synchronization to pass messages or data between threads, so make sure you keep it as simple as possible, because that is likely to become one of the most complex parts of your program.

  • There's nothing wrong with duplicating data for all devices. Video cards have humongous memory these days, and if you're reaching the limit with one device, there are other things you should worry about before adding a second device. However, you can share data between devices, and in fact, you can share data across processes, and even across different versions of Direct3D. That's a bit out of the scope of this question, but I have a more detailed answer, so check that one out as well.

In general, do what's best for your assumptions. I'd recommend you do what's easiest for you, and don't try to hunt for holy grails or "best practices". Do what's best for you, and go with that!

Okay, first of all, I would like you to consider forfeiting the notion of "best practice". There are no such things as "best practices". Some things work, some don't, and none do under all assumptions and scenarios, therefore being "best". Every time you use the words "best practice", God kills a kitten, so please think of the kittens.

Now, onto your problem. You certainly have given it a lot of thought, and most of your assumptions are correct. Let's start:

  • A Direct3D device can't render to multiple windows at the same time. In general, you will only have one window per Direct3D device. However, as you already know, you can certainly have multiple Direct3D devices per process, and you certainly have one per thread, which leads us to.

  • You can have multiple Direct3D devices in the same thread! Particularly, if my program wasn't very CPU intensive, I would create two Direct3D devices in the same thread, and render serially. For each iteration of your render loop, do everything you need to do for each Direct3D device. If, as you say, you can have 400+ fps, then you shouldn't have problem with two devices in the same thread. Keep everything in the same thread, and you won't have to care about synchronization at all.

  • DirectX is generally not thread-safe. This is different from the thread-hostility of Windows Forms, in which objects are owned by a thread and you can't generally do anything with them from a different thread (apartment). DirectX (9, which is what I mostly know) doesn't really care which thread you call functions for, as long as you don't call two API functions at the same time from different threads. You can opt in/out of thread safety when you create your device, but in general, as long as you synchronize access to your device, you can certainly do things from multiple threads. This doesn't mean you should though.

  • Windows Forms is not thread-friendly, so you certainly have to have all your windows in the same thread.

  • If you must separate the logic and Direct3D devices into different threads, then I would have three threads: one for the COM stuff (windows forms), and one for each device. You must then use some kind of synchronization to pass messages or data between threads, so make sure you keep it as simple as possible, because that is likely to become one of the most complex parts of your program.

  • There's nothing wrong with duplicating data for all devices. Video cards have humongous memory these days, and if you're reaching the limit with one device, there are other things you should worry about before adding a second device. However, you can share data between devices, and in fact, you can share data across processes, and even across different versions of Direct3D. That's a bit out of the scope of this question, but I have a more detailed answer, so check that one out as well.

In general, do what's best for your assumptions. I'd recommend you do what's easiest for you, and don't try to hunt for holy grails or "best practices". Do what's best for you, and go with that!

Source Link
Panda Pajama
  • 13.5k
  • 4
  • 47
  • 79

Okay, first of all, I would like you to consider forfeiting the notion of "best practice". There are no such things as "best practices". Some things work, some don't, and none do under all assumptions and scenarios, therefore being "best". Every time you use the words "best practice", God kills a kitten, so please think of the kittens.

Now, onto your problem. You certainly have given it a lot of thought, and most of your assumptions are correct. Let's start:

  • A Direct3D device can't render to multiple windows at the same time. In general, you will only have one window per Direct3D device. However, as you already know, you can certainly have multiple Direct3D devices per process, and you certainly have one per thread, which leads us to.

  • You can have multiple Direct3D devices in the same thread! Particularly, if my program wasn't very CPU intensive, I would create two Direct3D devices in the same thread, and render serially. For each iteration of your render loop, do everything you need to do for each Direct3D device. If, as you say, you can have 400+ fps, then you shouldn't have problem with two devices in the same thread. Keep everything in the same thread, and you won't have to care about synchronization at all.

  • DirectX is generally not thread-safe. This is different from the thread-hostility of Windows Forms, in which objects are owned by a thread and you can't generally do anything with them from a different thread (apartment). DirectX (9, which is what I mostly know) doesn't really care which thread you call functions for, as long as you don't call two API functions at the same time from different threads. You can opt in/out of thread safety when you create your device, but in general, as long as you synchronize access to your device, you can certainly do things from multiple threads. This doesn't mean you should though.

  • Windows Forms is not thread-friendly, so you certainly have to have all your windows in the same thread.

  • If you must separate the logic and Direct3D devices into different threads, then I would have three threads: one for the COM stuff (windows forms), and one for each device. You must then use some kind of synchronization to pass messages or data between threads, so make sure you keep it as simple as possible, because that is likely to become one of the most complex parts of your program.

  • There's nothing wrong with duplicating data for all devices. Video cards have humongous memory these days, and if you're reaching the limit with one device, there are other things you should worry about before adding a second device. However, you can share data between devices, and in fact, you can share data across processes, and even across different versions of Direct3D. That's a bit out of the scope of this question, but I have a more detailed answer, so check that one out as well.

In general, do what's best for your assumptions. I'd recommend you do what's easiest for you, and don't try to hunt for holy grails or "best practices". Do what's best for you, and go with that!