CmD3D11VideoModeList.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "CmD3D11VideoModeList.h"
  2. #include "CmException.h"
  3. #include "CmD3D11Driver.h"
  4. namespace CamelotFramework
  5. {
  6. D3D11VideoModeList::D3D11VideoModeList(D3D11Driver* driver, UINT32 adapterOutput)
  7. {
  8. if(driver == nullptr)
  9. CM_EXCEPT(InvalidParametersException, "driver parameter is NULL");
  10. mDriver = driver;
  11. enumerate(adapterOutput);
  12. }
  13. D3D11VideoModeList::~D3D11VideoModeList()
  14. {
  15. mDriver = NULL;
  16. mModeList.clear();
  17. }
  18. void D3D11VideoModeList::enumerate(UINT32 adapterOutput)
  19. {
  20. UINT adapter = mDriver->getAdapterNumber();
  21. HRESULT hr;
  22. IDXGIOutput* output;
  23. hr = mDriver->getDeviceAdapter()->EnumOutputs(adapterOutput, &output);
  24. if(hr == DXGI_ERROR_NOT_FOUND)
  25. CM_EXCEPT(InvalidParametersException, "Adapter output " + toString(adapterOutput) + " not found!");
  26. if(FAILED(hr))
  27. CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
  28. DXGI_OUTPUT_DESC outputDesc;
  29. output->GetDesc(&outputDesc);
  30. UINT32 numModes = 0;
  31. hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, 0);
  32. if(FAILED(hr))
  33. {
  34. SAFE_RELEASE(output);
  35. CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
  36. }
  37. DXGI_MODE_DESC* modeDesc = cm_newN<DXGI_MODE_DESC, ScratchAlloc>(numModes);
  38. hr = output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, modeDesc);
  39. if(FAILED(hr))
  40. {
  41. cm_deleteN<ScratchAlloc>(modeDesc, numModes);
  42. SAFE_RELEASE(output);
  43. CM_EXCEPT(InternalErrorException, "Error while enumerating adapter output video modes. Output index: " + toString(adapterOutput));
  44. }
  45. SAFE_RELEASE(output);
  46. for(UINT32 i = 0; i < numModes; i++)
  47. {
  48. DXGI_MODE_DESC displayMode = modeDesc[i];
  49. // Filter out low-resolutions
  50. if(displayMode.Width < 640 || displayMode.Height < 400)
  51. continue;
  52. // Check to see if it is already in the list (to filter out refresh rates)
  53. bool found = false;
  54. for(auto it = mModeList.begin(); it != mModeList.end(); it++)
  55. {
  56. DXGI_MODE_DESC existingMode = it->getModeDesc();
  57. if( existingMode.Width == displayMode.Width &&
  58. existingMode.Height == displayMode.Height &&
  59. existingMode.Format == displayMode.Format &&
  60. existingMode.RefreshRate.Numerator == displayMode.RefreshRate.Numerator &&
  61. existingMode.RefreshRate.Denominator == displayMode.RefreshRate.Denominator
  62. )
  63. {
  64. found = true;
  65. break;
  66. }
  67. }
  68. if(!found)
  69. mModeList.push_back(D3D11VideoMode(outputDesc, displayMode));
  70. }
  71. cm_deleteN<ScratchAlloc>(modeDesc, numModes);
  72. }
  73. UINT32 D3D11VideoModeList::count() const
  74. {
  75. return (UINT32)mModeList.size();
  76. }
  77. const D3D11VideoMode& D3D11VideoModeList::item(UINT32 idx) const
  78. {
  79. return mModeList.at(idx);
  80. }
  81. const D3D11VideoMode& D3D11VideoModeList::item(const String &name) const
  82. {
  83. for (auto iter = mModeList.begin(); iter != mModeList.end(); ++iter)
  84. {
  85. if (iter->getDescription() == name)
  86. return (*iter);
  87. }
  88. CM_EXCEPT(InvalidParametersException, "Cannot find video mode with the specified name.");
  89. }
  90. }