CmD3D11Device.cpp 3.7 KB

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