BsD3D11VideoModeInfo.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "BsD3D11VideoModeInfo.h"
  2. #include "BsException.h"
  3. namespace BansheeEngine
  4. {
  5. D3D11VideoModeInfo::D3D11VideoModeInfo(IDXGIAdapter* dxgiAdapter)
  6. {
  7. UINT32 outputIdx = 0;
  8. IDXGIOutput* output = nullptr;
  9. while (dxgiAdapter->EnumOutputs(outputIdx, &output) != DXGI_ERROR_NOT_FOUND)
  10. {
  11. mOutputs.push_back(bs_new<D3D11VideoOutputInfo>(output, outputIdx));
  12. outputIdx++;
  13. }
  14. }
  15. D3D11VideoOutputInfo::D3D11VideoOutputInfo(IDXGIOutput* output, UINT32 outputIdx)
  16. :mDXGIOutput(output)
  17. {
  18. DXGI_OUTPUT_DESC outputDesc;
  19. output->GetDesc(&outputDesc);
  20. mName = toString(WString(outputDesc.DeviceName));
  21. UINT32 numModes = 0;
  22. HRESULT hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, nullptr);
  23. if (FAILED(hr))
  24. {
  25. SAFE_RELEASE(output);
  26. BS_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes.");
  27. }
  28. DXGI_MODE_DESC* modeDesc = bs_newN<DXGI_MODE_DESC>(numModes);
  29. hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, modeDesc);
  30. if (FAILED(hr))
  31. {
  32. bs_deleteN(modeDesc, numModes);
  33. SAFE_RELEASE(output);
  34. BS_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes.");
  35. }
  36. for (UINT32 i = 0; i < numModes; i++)
  37. {
  38. DXGI_MODE_DESC displayMode = modeDesc[i];
  39. bool foundVideoMode = false;
  40. for (auto videoMode : mVideoModes)
  41. {
  42. D3D11VideoMode* d3d11videoMode = static_cast<D3D11VideoMode*>(videoMode);
  43. if (d3d11videoMode->mWidth == displayMode.Width && d3d11videoMode->mHeight == displayMode.Height &&
  44. d3d11videoMode->mRefreshRateNumerator == displayMode.RefreshRate.Numerator &&
  45. d3d11videoMode->mRefreshRateDenominator == displayMode.RefreshRate.Denominator)
  46. {
  47. foundVideoMode = true;
  48. break;
  49. }
  50. }
  51. if (!foundVideoMode)
  52. {
  53. float refreshRate = displayMode.RefreshRate.Numerator / (float)displayMode.RefreshRate.Denominator;
  54. D3D11VideoMode* videoMode = bs_new<D3D11VideoMode>(displayMode.Width, displayMode.Height, refreshRate,
  55. outputIdx, displayMode.RefreshRate.Numerator, displayMode.RefreshRate.Denominator, displayMode);
  56. mVideoModes.push_back(videoMode);
  57. }
  58. }
  59. bs_deleteN(modeDesc, numModes);
  60. // Get desktop display mode
  61. HMONITOR hMonitor = outputDesc.Monitor;
  62. MONITORINFOEX monitorInfo;
  63. monitorInfo.cbSize = sizeof(MONITORINFOEX);
  64. GetMonitorInfo(hMonitor, &monitorInfo);
  65. DEVMODE devMode;
  66. devMode.dmSize = sizeof(DEVMODE);
  67. devMode.dmDriverExtra = 0;
  68. EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
  69. DXGI_MODE_DESC currentMode;
  70. currentMode.Width = devMode.dmPelsWidth;
  71. currentMode.Height = devMode.dmPelsHeight;
  72. bool useDefaultRefreshRate = 1 == devMode.dmDisplayFrequency || 0 == devMode.dmDisplayFrequency;
  73. currentMode.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : devMode.dmDisplayFrequency;
  74. currentMode.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1;
  75. currentMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  76. currentMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  77. currentMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  78. DXGI_MODE_DESC nearestMode;
  79. ZeroMemory(&nearestMode, sizeof(nearestMode));
  80. output->FindClosestMatchingMode(&currentMode, &nearestMode, nullptr);
  81. float refreshRate = nearestMode.RefreshRate.Numerator / (float)nearestMode.RefreshRate.Denominator;
  82. mDesktopVideoMode = bs_new<D3D11VideoMode>(nearestMode.Width, nearestMode.Height, refreshRate,
  83. outputIdx, nearestMode.RefreshRate.Numerator, nearestMode.RefreshRate.Denominator, nearestMode);
  84. }
  85. D3D11VideoOutputInfo::~D3D11VideoOutputInfo()
  86. {
  87. SAFE_RELEASE(mDXGIOutput);
  88. }
  89. D3D11VideoMode::D3D11VideoMode(UINT32 width, UINT32 height, float refreshRate, UINT32 outputIdx,
  90. UINT32 refreshRateNumerator, UINT32 refreshRateDenominator, DXGI_MODE_DESC mode)
  91. :VideoMode(width, height, refreshRate, outputIdx), mRefreshRateNumerator(refreshRateNumerator),
  92. mRefreshRateDenominator(refreshRateDenominator), mD3D11Mode(mode)
  93. { }
  94. }