1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[dxgi] Add new functions to change the display mode of a monitor

This commit is contained in:
Philip Rebohle 2018-12-11 15:48:57 +01:00
parent 1db3c6d883
commit 1594a20b94
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 119 additions and 0 deletions

View File

@ -6,6 +6,27 @@ namespace dxvk {
std::unordered_map<HMONITOR, DXGI_VK_MONITOR_DATA> g_monitorData;
uint32_t GetMonitorFormatBpp(DXGI_FORMAT Format) {
switch (Format) {
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_R10G10B10A2_UNORM:
return 32;
case DXGI_FORMAT_R16G16B16A16_FLOAT:
return 64;
default:
Logger::warn(str::format(
"GetMonitorFormatBpp: Unknown format: ",
Format));
return 32;
}
}
HRESULT InitMonitorData(
HMONITOR hMonitor,
const DXGI_VK_MONITOR_DATA* pData) {
@ -44,4 +65,67 @@ namespace dxvk {
g_monitorMutex.unlock();
}
HRESULT GetMonitorDisplayMode(
HMONITOR hMonitor,
DWORD ModeNum,
DXGI_MODE_DESC* pMode) {
::MONITORINFOEXW monInfo;
monInfo.cbSize = sizeof(monInfo);
if (!::GetMonitorInfoW(hMonitor, reinterpret_cast<MONITORINFO*>(&monInfo))) {
Logger::err("DXGI: Failed to query monitor info");
return E_FAIL;
}
DEVMODEW devMode = { };
devMode.dmSize = sizeof(devMode);
if (!::EnumDisplaySettingsW(monInfo.szDevice, ModeNum, &devMode))
return DXGI_ERROR_NOT_FOUND;
pMode->Width = devMode.dmPelsWidth;
pMode->Height = devMode.dmPelsHeight;
pMode->RefreshRate = { devMode.dmDisplayFrequency, 1 };
pMode->Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; // FIXME
pMode->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
pMode->Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
return S_OK;
}
HRESULT SetMonitorDisplayMode(
HMONITOR hMonitor,
const DXGI_MODE_DESC* pMode) {
::MONITORINFOEXW monInfo;
monInfo.cbSize = sizeof(monInfo);
if (!::GetMonitorInfoW(hMonitor, reinterpret_cast<MONITORINFO*>(&monInfo))) {
Logger::err("DXGI: 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(pMode->Format);
if (pMode->RefreshRate.Numerator != 0) {
devMode.dmFields |= DM_DISPLAYFREQUENCY;
devMode.dmDisplayFrequency = pMode->RefreshRate.Numerator
/ pMode->RefreshRate.Denominator;
}
Logger::info(str::format("DXGI: Setting display mode: ",
devMode.dmPelsWidth, "x", devMode.dmPelsHeight, "@",
devMode.dmDisplayFrequency));
LONG status = ::ChangeDisplaySettingsExW(
monInfo.szDevice, &devMode, nullptr, CDS_FULLSCREEN, nullptr);
return status == DISP_CHANGE_SUCCESSFUL ? S_OK : DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;;
}
}

View File

@ -19,6 +19,16 @@ namespace dxvk {
};
/**
* \brief Queries bits per pixel for a format
*
* The format must be a valid swap chain format.
* \param [in] Format The DXGI format to query
* \returns Bits per pixel for this format
*/
uint32_t GetMonitorFormatBpp(
DXGI_FORMAT Format);
/**
* \brief Initializes monitor data
*
@ -51,4 +61,29 @@ namespace dxvk {
*/
void ReleaseMonitorData();
/**
* \brief Retrieves monitor display mode
*
* \param [in] hMonitor Monitor handle
* \param [in] ModeNum Mode number
* \param [out] Display mode properties
* \returns S_OK on success
*/
HRESULT GetMonitorDisplayMode(
HMONITOR hMonitor,
DWORD ModeNum,
DXGI_MODE_DESC* pMode);
/**
* \brief Sets monitor display mode
*
* \param [in] hMonitor Monitor handle
* \param [in] pMode Display mode properties
* \returns S_OK on success
*/
HRESULT SetMonitorDisplayMode(
HMONITOR hMonitor,
const DXGI_MODE_DESC* pMode);
}