1

MSDN on IDirect3D9Ex::CreateDeviceEx says:

If BackBufferFormat equals D3DFMT_UNKNOWN before the method is called, it will be changed when the method returns.

So this should print something other than format: 0 (nowadays usually format: 22 for D3DFMT_X8R8G8B8):

#include <cstdio>
#include <d3d9.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"User32.lib")
int main(int argc, char **argv)
{
    IDirect3D9* d3d = Direct3DCreate9(D3D_SDK_VERSION);
    if (!d3d) {
        printf("No d3d!\n");
        return 0;
    }
    D3DPRESENT_PARAMETERS pp = {};
    pp.BackBufferWidth = 1;
    pp.BackBufferHeight = 1;
    pp.BackBufferFormat = D3DFMT_UNKNOWN;
    pp.BackBufferCount = 1;
    pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    pp.Windowed = TRUE;
    IDirect3DDevice9* device = NULL;
    HRESULT hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &device);
    if (FAILED(hr)) {
        printf("Failed!\n");
        return 0;
    }
    printf("format: %i\n", pp.BackBufferFormat);
    device->Release();
    d3d->Release();
}

And this always worked in my experience. Now recently sometimes this does not work as expected anymore. It prints format: 0. Why?

This was observed on some Windows 10 PCs for a few days recently. Later it magically started working again. Is this possibly related to the Windows 10 Anniversary update?

Peter
  • 3,322
  • 3
  • 27
  • 41

1 Answers1

0

I would expect it to print 0 in cases where the HRESULT returned failure in your code. Try:

IDirect3D9* d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (!d3d) 
    return false;

...

HRESULT hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
    GetDesktopWindow(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp,
    &device);
if (FAILED(hr))
    return false;
printf("format: %i\n", pp.BackBufferFormat);

The legacy Direct3D 9 API exists in Windows 10 for BackCompat. It was already being emulated back in Windows Vista. Direct3D9Ex exposes more of the 'real' behavior of modern Windows since it's aware of DXGI, but in general Direct3D 11 is the primarily codepath tested and used by modern software. As such, legacy Direct3D 9 continues to get a bit quirkier with each release of Windows.

Note that the "Developer Runtime" (aka Debug Device) for Direct3D 9 is not supported on Windows 8.0, Windows 8.1, or Windows 10.

Using Direct3D 9 also generally means the use of the deprecated D3DX support library which is only available in the end-of-life DirectX SDK. Deployment of D3DX requires the use of the legacy DirectX Runtime End-User Redistribution package. See Living without D3DX and Not So Direct Setup

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • I edited the sample code in the question adding your suggestions. (The checks were already the actual application.) The `HRESULT` does not indicate any failure. It still prints 0 on those PCs. (And I'm already trying to switch to D3D11, but WPF still requires some D3D9...) – Peter Sep 29 '16 at 14:04
  • Take a look at [WPFDXInterop](https://github.com/Microsoft/WPFDXInterop) – Chuck Walbourn Sep 29 '16 at 15:31
  • It's on my TODO list, thanks. For legacy software it would still be nice to know why the `BackBufferFormat` remains `0` sometimes after installing Win10. Any ideas? Could it be some driver update or some additional Windows update that fixed this again? – Peter Sep 30 '16 at 07:50