CmD3D11VideoModeInfo.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "CmD3D11VideoModeInfo.h"
  2. #include "CmException.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. outputIdx++;
  12. mOutputs.push_back(cm_new<D3D11VideoOutputInfo>(output));
  13. }
  14. }
  15. D3D11VideoOutputInfo::D3D11VideoOutputInfo(IDXGIOutput* output)
  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, 0);
  23. if (FAILED(hr))
  24. {
  25. SAFE_RELEASE(output);
  26. CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes.");
  27. }
  28. DXGI_MODE_DESC* modeDesc = cm_newN<DXGI_MODE_DESC>(numModes);
  29. hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, modeDesc);
  30. if (FAILED(hr))
  31. {
  32. cm_deleteN(modeDesc, numModes);
  33. SAFE_RELEASE(output);
  34. CM_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. {
  45. bool foundRefreshRate = false;
  46. for (auto refreshRate : d3d11videoMode->mD3D11RefreshRates)
  47. {
  48. if (refreshRate.numerator != displayMode.RefreshRate.Numerator ||
  49. refreshRate.denominator != displayMode.RefreshRate.Denominator)
  50. {
  51. foundRefreshRate = true;
  52. break;
  53. }
  54. }
  55. if (!foundRefreshRate)
  56. {
  57. D3D11VideoMode::RefreshRate refreshRate;
  58. refreshRate.numerator = displayMode.RefreshRate.Numerator;
  59. refreshRate.denominator = displayMode.RefreshRate.Denominator;
  60. d3d11videoMode->mD3D11RefreshRates.push_back(refreshRate);
  61. d3d11videoMode->mRefreshRates.push_back(refreshRate.numerator / (float)refreshRate.denominator);
  62. }
  63. foundVideoMode = true;
  64. break;
  65. }
  66. }
  67. if (!foundVideoMode)
  68. {
  69. D3D11VideoMode* videoMode = cm_new<D3D11VideoMode>(displayMode.Width, displayMode.Height, this, displayMode);
  70. D3D11VideoMode::RefreshRate refreshRate;
  71. refreshRate.numerator = displayMode.RefreshRate.Numerator;
  72. refreshRate.denominator = displayMode.RefreshRate.Denominator;
  73. videoMode->mD3D11RefreshRates.push_back(refreshRate);
  74. videoMode->mRefreshRates.push_back(refreshRate.numerator / (float)refreshRate.denominator);
  75. mVideoModes.push_back(videoMode);
  76. }
  77. }
  78. cm_deleteN(modeDesc, numModes);
  79. // Get desktop display mode
  80. HMONITOR hMonitor = outputDesc.Monitor;
  81. MONITORINFOEX monitorInfo;
  82. monitorInfo.cbSize = sizeof(MONITORINFOEX);
  83. GetMonitorInfo(hMonitor, &monitorInfo);
  84. DEVMODE devMode;
  85. devMode.dmSize = sizeof(DEVMODE);
  86. devMode.dmDriverExtra = 0;
  87. EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
  88. DXGI_MODE_DESC currentMode;
  89. currentMode.Width = devMode.dmPelsWidth;
  90. currentMode.Height = devMode.dmPelsHeight;
  91. bool useDefaultRefreshRate = 1 == devMode.dmDisplayFrequency || 0 == devMode.dmDisplayFrequency;
  92. currentMode.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : devMode.dmDisplayFrequency;
  93. currentMode.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1;
  94. currentMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  95. currentMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  96. currentMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  97. DXGI_MODE_DESC nearestMode;
  98. ZeroMemory(&nearestMode, sizeof(nearestMode));
  99. output->FindClosestMatchingMode(&currentMode, &nearestMode, nullptr);
  100. mDesktopVideoMode = cm_new<D3D11VideoMode>(nearestMode.Width, nearestMode.Height, this, nearestMode);
  101. }
  102. D3D11VideoOutputInfo::~D3D11VideoOutputInfo()
  103. {
  104. SAFE_RELEASE(mDXGIOutput);
  105. }
  106. D3D11VideoMode::D3D11VideoMode(UINT32 width, UINT32 height, VideoOutputInfo* outputInfo, DXGI_MODE_DESC dxgiMode)
  107. :VideoMode(width, height, outputInfo), mDXGIMode(dxgiMode)
  108. { }
  109. }