#include "d3d9_monitor.h" #include "d3d9_format.h" namespace dxvk { uint32_t GetMonitorFormatBpp(D3D9Format Format) { switch (Format) { case D3D9Format::A8R8G8B8: case D3D9Format::X8R8G8B8: // This is still 32 bit even though the alpha is unspecified. case D3D9Format::A2R10G10B10: return 32; case D3D9Format::A1R5G5B5: case D3D9Format::X1R5G5B5: case D3D9Format::R5G6B5: return 16; default: Logger::warn(str::format( "GetMonitorFormatBpp: Unknown format: ", Format)); return 32; } } bool IsSupportedAdapterFormat( D3D9Format Format, BOOL Windowed) { return (Format == D3D9Format::A2R10G10B10 && !Windowed) || Format == D3D9Format::X8R8G8B8 || Format == D3D9Format::X1R5G5B5 || Format == D3D9Format::R5G6B5; } bool IsSupportedBackBufferFormat( D3D9Format AdapterFormat, D3D9Format BackBufferFormat, BOOL Windowed) { if (!IsSupportedAdapterFormat(AdapterFormat, Windowed)) return false; return AdapterFormat == BackBufferFormat || (AdapterFormat == D3D9Format::X8R8G8B8 && BackBufferFormat == D3D9Format::A8R8G8B8) || (AdapterFormat == D3D9Format::X1R5G5B5 && BackBufferFormat == D3D9Format::A1R5G5B5); } bool IsSupportedBackBufferFormat( D3D9Format BackBufferFormat, BOOL Windowed) { return (BackBufferFormat == D3D9Format::A2R10G10B10 && !Windowed) || BackBufferFormat == D3D9Format::A8R8G8B8 || BackBufferFormat == D3D9Format::X8R8G8B8 || BackBufferFormat == D3D9Format::A1R5G5B5 || BackBufferFormat == D3D9Format::X1R5G5B5 || BackBufferFormat == D3D9Format::R5G6B5; } HRESULT SetMonitorDisplayMode( HMONITOR hMonitor, const D3DDISPLAYMODEEX* pMode) { ::MONITORINFOEXW monInfo; monInfo.cbSize = sizeof(monInfo); if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { Logger::err("D3D9: Failed to query monitor info"); return E_FAIL; } DEVMODEW devMode = { }; devMode.dmSize = sizeof(devMode); devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; devMode.dmPelsWidth = pMode->Width; devMode.dmPelsHeight = pMode->Height; devMode.dmBitsPerPel = GetMonitorFormatBpp(EnumerateFormat(pMode->Format)); if (pMode->RefreshRate != 0) { devMode.dmFields |= DM_DISPLAYFREQUENCY; devMode.dmDisplayFrequency = pMode->RefreshRate; } Logger::info(str::format("D3D9: Setting display mode: ", devMode.dmPelsWidth, "x", devMode.dmPelsHeight, "@", devMode.dmDisplayFrequency)); LONG status = ::ChangeDisplaySettingsExW( monInfo.szDevice, &devMode, nullptr, CDS_FULLSCREEN, nullptr); if (status != DISP_CHANGE_SUCCESSFUL) { // Try again but without setting the frequency. devMode.dmFields &= ~DM_DISPLAYFREQUENCY; devMode.dmDisplayFrequency = 0; status = ::ChangeDisplaySettingsExW( monInfo.szDevice, &devMode, nullptr, CDS_FULLSCREEN, nullptr); } return status == DISP_CHANGE_SUCCESSFUL ? D3D_OK : D3DERR_NOTAVAILABLE; } }