BsD3D11VideoModeInfo.cpp 4.3 KB

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