FPU exception in IDirect3D9::CreateDevice - Win10

Started by
7 comments, last by Aleksid1 5 years, 11 months ago

Hi,

With the latest update of Windows 10 (April 2018) and laptops with dual graphics (NVIDIA + Intel) we have a critical problem - FPU exception ("floating point division by zero") when we call IDirect3D9::CreateDevice()

We found a temporary solution - globally disable all FPU exceptions in our app by calling Set8087CW($133F) when our app is started.

I'm sure that our code which works with DirectX is correct and there is no mistakes in parameters which I pass to CreateDevice().

This problem didn't happen with any previous version of Windows 10 or with Windows 8/7/Vista/XP. Also this problem doesn't occur if manually choose Intel video card for our app. Or run our app on external monitor on NVIDIA card. And no problems with AMD cards at all.

Our app is written on Delphi (Pascal).

We received many complains from our customers.

Should I report to NVIDIA or Microsoft about this problem?

Advertisement

Are you using the D3DCREATE_FPU_PRESERVE flag during initialization? If not, try adding it instead of your current workaround.

Yes, of course. I use D3DCREATE_FPU_PRESERVE

7 minutes ago, Hodgman said:

Are you using the D3DCREATE_FPU_PRESERVE flag during initialization? If not, try adding it instead of your current workaround.

I believe you've got the meaning of the flag the wrong way round.

If you use D3DCREATE_FPU_PRESERVE you need to ensure you don't have FP exceptions enabled.
If you don't use the flag, D3D9 should disable FP exceptions and put you into single precision.

If you desire to keep doubles doubles, you need to ensure like you do that FP exceptions are off, and probably hunt down whoever enabled it in your process.

To make it is hell. To fail is divine.

You should be able to see in the stack which component is doing the divide-by-zero. That should be your starting point for whose fault it is. If it's d3d9.dll, probably Microsoft's fault. If it's the NVIDIA or Intel driver, then there's the blame.

Thanks for your replies!

You're right, we need double-precision for FPU so we use D3DCREATE_FPU_PRESERVE.

If I remove D3DCREATE_FPU_PRESERVE flag, FPU exception doesn't appear.

Some parts of our app were initially written in 2006. And old DirectX documention said: "Indicates that the application needs either double-precision floating-point unit (FPU) or FPU exceptions enabled. Microsoft® Direct3D® sets the FPU state each time it is called. "

We thought that it's OK, we handle all exceptions and if some DirectX call generates FPU exception due to incorrect values we will handle that situation.

The latest DirectX documention strictly warns for D3DCREATE_FPU_PRESERVE:

"Portions of Direct3D assume floating-point unit exceptions are masked; unmasking these exceptions may result in undefined behavior."

I still think that it's incorrect that even simple and basic call CreateDevice() may produce FPU exception in the new update of Windows 10.

It's strange that double-precision is firmly linked with FPU exceptions now.

Dividing by zero in floating point, by default, won't crash a program... Unless someone has enabled that behaviour. If you divide by zero in your own code (right before initialising D3D), does it crash? 

i.e. Is your code enabling the divide by zero exception, or is MS/NVidia enabling the divide by zero exception? 

Exception (dividing by zero) occurs inside CreateDevice() call, in other words it occurs in DirectX or NVIDIA drivers. And CreateDevice() doesn't return IDirect3DDevice9. So our app can't correctly work.

If we disable globally all FPU exceptions in our app, CreateDevice() works correctly and returns IDirect3DDevice9.

We use Delphi (Pascal) to write our code.

This topic is closed to new replies.

Advertisement