CmD3D11Device.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "CmD3D11Device.h"
  2. #include "CmException.h"
  3. namespace CamelotEngine
  4. {
  5. D3D11Device::D3D11Device()
  6. :mD3D11Device(nullptr), mImmediateContext(nullptr), mClassLinkage(nullptr)
  7. {
  8. }
  9. D3D11Device::D3D11Device(ID3D11Device* device)
  10. : mD3D11Device(device)
  11. , mImmediateContext(nullptr)
  12. , mInfoQueue(nullptr)
  13. , mClassLinkage(nullptr)
  14. {
  15. assert(device != nullptr);
  16. if (device)
  17. {
  18. device->GetImmediateContext(&mImmediateContext);
  19. HRESULT hr = mD3D11Device->QueryInterface(__uuidof(ID3D11InfoQueue), (LPVOID*)&mInfoQueue);
  20. if (FAILED(hr))
  21. CM_EXCEPT(RenderingAPIException, "Unable to query D3D11InfoQueue");
  22. // If feature level is 11, create class linkage
  23. SAFE_RELEASE(mClassLinkage);
  24. if (mD3D11Device->GetFeatureLevel() == D3D_FEATURE_LEVEL_11_0)
  25. {
  26. HRESULT hr = mD3D11Device->CreateClassLinkage(&mClassLinkage);
  27. if (FAILED(hr))
  28. CM_EXCEPT(RenderingAPIException, "Unable to create class linkage.");
  29. }
  30. }
  31. }
  32. D3D11Device::~D3D11Device()
  33. {
  34. shutdown();
  35. }
  36. void D3D11Device::shutdown()
  37. {
  38. // Clear state
  39. if (mImmediateContext)
  40. {
  41. mImmediateContext->Flush();
  42. mImmediateContext->ClearState();
  43. }
  44. SAFE_RELEASE(mInfoQueue);
  45. SAFE_RELEASE(mD3D11Device);
  46. SAFE_RELEASE(mImmediateContext);
  47. SAFE_RELEASE(mClassLinkage);
  48. }
  49. String D3D11Device::getErrorDescription(bool doClearErrors)
  50. {
  51. if (mD3D11Device == nullptr)
  52. return "NULL device";
  53. String res;
  54. if (mInfoQueue != nullptr)
  55. {
  56. UINT64 numStoredMessages = mInfoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
  57. for (UINT64 i = 0 ; i < numStoredMessages ; i++ )
  58. {
  59. // Get the size of the message
  60. SIZE_T messageLength = 0;
  61. mInfoQueue->GetMessage(i, nullptr, &messageLength);
  62. // Allocate space and get the message
  63. D3D11_MESSAGE* pMessage = (D3D11_MESSAGE*)malloc(messageLength);
  64. mInfoQueue->GetMessage(i, pMessage, &messageLength);
  65. res = res + pMessage->pDescription + "\n";
  66. free(pMessage);
  67. }
  68. }
  69. if(doClearErrors)
  70. clearErrors();
  71. return res;
  72. }
  73. bool D3D11Device::hasError() const
  74. {
  75. if (mInfoQueue != nullptr)
  76. {
  77. UINT64 numStoredMessages = mInfoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
  78. if (numStoredMessages > 0)
  79. return true;
  80. return false;
  81. }
  82. else
  83. {
  84. return false;
  85. }
  86. }
  87. void D3D11Device::clearErrors()
  88. {
  89. if (mD3D11Device != nullptr && mInfoQueue != nullptr)
  90. {
  91. mInfoQueue->ClearStoredMessages();
  92. }
  93. }
  94. void D3D11Device::setExceptionsErrorLevel(const CM_D3D11_ERROR_LEVEL exceptionsErrorLevel)
  95. {
  96. if(mInfoQueue == nullptr)
  97. return;
  98. mInfoQueue->ClearRetrievalFilter();
  99. mInfoQueue->ClearStorageFilter();
  100. D3D11_INFO_QUEUE_FILTER filter;
  101. ZeroMemory(&filter, sizeof(D3D11_INFO_QUEUE_FILTER));
  102. std::vector<D3D11_MESSAGE_SEVERITY> severityList;
  103. switch(exceptionsErrorLevel)
  104. {
  105. case D3D11ERR_NO_EXCEPTION:
  106. severityList.push_back(D3D11_MESSAGE_SEVERITY_CORRUPTION);
  107. case D3D11ERR_CORRUPTION:
  108. severityList.push_back(D3D11_MESSAGE_SEVERITY_ERROR);
  109. case D3D11ERR_ERROR:
  110. severityList.push_back(D3D11_MESSAGE_SEVERITY_WARNING);
  111. case D3D11ERR_WARNING:
  112. case D3D11ERR_INFO:
  113. severityList.push_back(D3D11_MESSAGE_SEVERITY_INFO);
  114. default:
  115. break;
  116. }
  117. if (severityList.size() > 0)
  118. {
  119. filter.DenyList.NumSeverities = (UINT)severityList.size();
  120. filter.DenyList.pSeverityList = &severityList[0];
  121. }
  122. mInfoQueue->AddStorageFilterEntries(&filter);
  123. mInfoQueue->AddRetrievalFilterEntries(&filter);
  124. }
  125. }