0
\$\begingroup\$

I am writing an offline renderer using SlimDX and Direct3D 10 that will need to be run on machines without graphics cards (servers). On these machines, I'll be using the WARP software renderer.

Is it possible to tell if a hardware device is present without throwing an exception in SlimDX? Currently I'm having to do this:

            try
            {
                Device device = new Device1(DriverType.Hardware, deviceCreationFlags,
                    FeatureLevel.Level_10_1);

                return device;
            }
            catch (Direct3D10Exception)
            {
                return null;
            }

And then create a WARP device if null is returned.

However, each time the exception is thrown, it breaks Visual Studio, which is annoying, and it doesn't seem like I should be catching an exception to determine if a feature is available.

Any way to do this?

\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

In general you can use SlimDX.Configuration.ThrowOnError to almost-globally enable or disable exceptions. You can also set up more complex exception exclusions via SlimDX.Configuration.AddResultWatch.

You cannot, however, prevent SlimDX from throwing exceptions of a constructor (by design). This is because that's the only way to signal failure of a construction aside from constructing an object in a zombie state (which is ugly). The static method Device.CreateWithSwapChain should be usable for constructing your device without throwing (if you disable exceptions). If this doesn't work, please file a bug on the SlimDX issue tracker.

You are correct that it's generally preferable to avoid relying on exceptions for flow control (that is, it's better to be able to ask if something will fail than to have to try it and wait for it to fail, although this is not always possible). SlimDX should support this and if not, it's a bug.

As an aside, you probably have "break on throw" enabled in Visual Studio via the Debug -> Exceptions menu. You can configure how VS reacts to exceptions from that window -- unchecking everything will prevent the debugger from triggering a breakpoint when an exception is raised.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks Josh. Unfortunately Device.CreateWithSwapChain won't work for me - I need a customized swap chain. I know about "break on throw", thanks ;) I switch this off most of the time to avoid this exception, but that means I occasionally miss something. I'd rather know when exceptions happen. \$\endgroup\$
    – Groky
    Commented Sep 1, 2011 at 22:30
  • \$\begingroup\$ You can configure them on a specific type-by-type basis, although that will still squelch (or not) all D3D10 exceptions. Sounds like we need to provide you with a static CreateDevice() wrapper (or expose whatever the native free function is for testing device capabilities in 10). Probably your best bet will be to file a bug. We'll try to get it fixed ASAP. \$\endgroup\$
    – user1430
    Commented Sep 1, 2011 at 22:33
  • \$\begingroup\$ Looking at the documentation, it seems something is already available to do the same in D3D11 - you can query feature levels before creating the device. I guess I need something like that? \$\endgroup\$
    – Groky
    Commented Sep 1, 2011 at 22:35
0
\$\begingroup\$

Why not? Exceptions are how you signal error conditions in objects. If a constructor fails, throwing an exception is the only way to signal that failure.

You ask the Device constructor to create a D3D10 device. If no such device exists, what should it do? Create a broken Device object that you can't use, which you have to check to see if it is a working? That's basically assuming that your users will properly code the proper fallbacks into their applications. That's a recipe for disaster; it's much better to use an exception to force the user to code fallbacks, rather than hope that they'll do the right thing.

As for "breaking Visual Studio", I have never seen VS "break" under throwing an exception. What kind of breakage are you experiencing? VS will only halt if the exception goes uncaught. Maybe you're not catching the right type of exception?

\$\endgroup\$
10
  • \$\begingroup\$ Note that this code is C#, so the comment regarding catching exceptions by reference doesn't apply (exceptions are reference types). \$\endgroup\$
    – user1430
    Commented Sep 1, 2011 at 22:21
  • \$\begingroup\$ I'd like to test if creating such a device is possible before trying to create the device. It will be a common occurance, and not exceptional at all. \$\endgroup\$
    – Groky
    Commented Sep 1, 2011 at 22:26
  • \$\begingroup\$ And by 'breaking visual studio' I mean the exception causes visual studio to enter debug mode, as if a breakpoint had been set. I believe this term is commonly used, see System.Diagnostics.Debugger.Break(). \$\endgroup\$
    – Groky
    Commented Sep 1, 2011 at 22:27
  • \$\begingroup\$ An exception in a constructor? Why in the world would you ever need to have an exception in a constructor anyway? AFAIK it's a poor programming practice to throw exceptions in constructors and should never be done unless particularly necessary, which I don't think it would be the case of a DX wrapper such as SlimDX. \$\endgroup\$ Commented Sep 1, 2011 at 22:42
  • \$\begingroup\$ @Pablo: That's standard programming practice. The only way to signal a failed object construction is to throw an exception in a constructor. And while there are many programmers who take efforts to avoid them (which are bad for the reasons I explained), it is the only mechanism that forces the user to deal with the error. It forces you to write correct code. And in a good API, it should be impossible to write bad code. A throwing constructor prevents ignoring the error. \$\endgroup\$ Commented Sep 1, 2011 at 22:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .