Skip to content

Instantly share code, notes, and snippets.

@redmcg
Last active June 17, 2022 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save redmcg/5b11d2d18ff29da5d9d4886b2e1699a1 to your computer and use it in GitHub Desktop.
Save redmcg/5b11d2d18ff29da5d9d4886b2e1699a1 to your computer and use it in GitHub Desktop.
Get number of D3D9 adapters
// compile with: x86_64-w64-mingw32-g++ d3d9Test.cpp
#include <d3d9.h>
#include <stdio.h>
static BOOL Monitorenumproc(
HMONITOR hMonitor,
HDC unnamedParam2,
LPRECT bounds,
LPARAM unnamedParam4
) {
MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
if(GetMonitorInfo(hMonitor, &mi)) {
printf("%p: %s\n", hMonitor, mi.szDevice);
printf("%d, %d, %d, %d\n", bounds->left, bounds->top, bounds->right, bounds->bottom);
} else {
printf("GetMonitorInfo failed for %p\n", hMonitor);
}
return TRUE;
}
int main(int argc, char **argv) {
HRESULT hr = E_FAIL;
HMODULE libHandle = NULL;
UINT m_uD3DAdapterCount = 0;
HMONITOR *hMonitor = NULL;
// Manually load the d3d9.dll library.
libHandle = LoadLibrary("d3d9.dll");
if (libHandle != NULL) {
// Define a function pointer to the Direct3DCreate9Ex function.
typedef HRESULT
(WINAPI *LPDIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);
// Obtain the address of the Direct3DCreate9Ex function.
LPDIRECT3DCREATE9EX Direct3DCreate9ExPtr = NULL;
Direct3DCreate9ExPtr = (LPDIRECT3DCREATE9EX) GetProcAddress(libHandle,
"Direct3DCreate9Ex");
if (Direct3DCreate9ExPtr != NULL) {
// Direct3DCreate9Ex is supported.
hr = S_OK;
IDirect3D9Ex *pD3D = NULL;
if (FAILED(hr = Direct3DCreate9ExPtr(D3D_SDK_VERSION, &pD3D))) {
printf("Failed\n");
} else {
m_uD3DAdapterCount = pD3D->GetAdapterCount();
hMonitor = (HMONITOR*) calloc(m_uD3DAdapterCount, sizeof(*hMonitor));
printf("\nD3D9 says you have %d adapter(s):\n", m_uD3DAdapterCount);
for (UINT i = 0; i < m_uD3DAdapterCount; i++) {
D3DADAPTER_IDENTIFIER9 id;
pD3D->GetAdapterIdentifier(i, 0, &id);
HMONITOR mon = pD3D->GetAdapterMonitor(i);
printf(" - %s (%s) %p\n", id.DeviceName, id.Description, mon);
}
pD3D->Release();
}
} else {
// Direct3DCreate9Ex is not supported on this
// operating system.
hr = ERROR_NOT_SUPPORTED;
printf("Not supported\n");
}
// Free the library.
FreeLibrary(libHandle);
}
printf("\nEnumDisplayDevices:\n");
UINT m_rgpDisplaysCount = 0;
for (UINT uDevice = 0; true; uDevice++) {
DISPLAY_DEVICE dd;
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);
if (!EnumDisplayDevices(NULL, uDevice, &dd, 0))
break; // no more devices
printf("- %d: %s", uDevice, dd.DeviceName);
if (!(dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
printf(" (not attached to desktop)\n");
continue;
}
if (dd.StateFlags
& (DISPLAY_DEVICE_REMOTE | DISPLAY_DEVICE_MIRRORING_DRIVER)) {
if (dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) {
printf(" (mirroring driver)\n");
continue; // mirror devices are considered hidden and should
// be excluded as display. Remembering that a
// non-local device is present is sufficient for
// now.
}
}
m_rgpDisplaysCount++;
printf(" (OK)\n");
}
printf("\nEnumDisplayDevices says %d device(s) are OK\n\n", m_rgpDisplaysCount);
// If DX reported adapters that m_rgpDisplays doesn't have, dotnet assumes it's due to mode change.
if (m_uD3DAdapterCount > m_rgpDisplaysCount) {
printf("DotNet assumes a mode change, which causes issues in rendering, when m_uD3DAdapterCount > m_rgpDisplaysCount (%d > %d)\n",
m_uD3DAdapterCount, m_rgpDisplaysCount);
printf("See https://github.com/dotnet/wpf/blob/c4e74175da6108104491e1ae64982444d7c8713d/src/Microsoft.DotNet.Wpf/src/WpfGfx/core/common/display.cpp#L1629\n");
} else {
printf("DotNet should be happy\n");
}
printf("\nEnumDisplayMonitors:\n");
BOOL ret = EnumDisplayMonitors(NULL, NULL, Monitorenumproc, NULL);
if (!ret) printf("EnumDisplayMonitors ret: %d\n", ret);
return hr;
}
@redmcg
Copy link
Author

redmcg commented Jun 9, 2022

compile with: x86_64-w64-mingw32-g++ d3d9Test.cpp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment