BsD3D11VideoModeInfo.cpp 4.3 KB

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