BsD3D11TimerQuery.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "BsD3D11TimerQuery.h"
  2. #include "BsD3D11RenderSystem.h"
  3. #include "BsD3D11Device.h"
  4. #include "BsDebug.h"
  5. namespace BansheeEngine
  6. {
  7. D3D11TimerQuery::D3D11TimerQuery()
  8. :mFinalized(false), mContext(nullptr), mBeginQuery(nullptr),
  9. mEndQuery(nullptr), mDisjointQuery(nullptr), mTimeDelta(0.0f)
  10. {
  11. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  12. D3D11Device& device = rs->getPrimaryDevice();
  13. D3D11_QUERY_DESC queryDesc;
  14. queryDesc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;
  15. queryDesc.MiscFlags = 0;
  16. HRESULT hr = device.getD3D11Device()->CreateQuery(&queryDesc, &mDisjointQuery);
  17. if(hr != S_OK)
  18. {
  19. BS_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
  20. }
  21. queryDesc.Query = D3D11_QUERY_TIMESTAMP;
  22. hr = device.getD3D11Device()->CreateQuery(&queryDesc, &mBeginQuery);
  23. if(hr != S_OK)
  24. {
  25. BS_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
  26. }
  27. hr = device.getD3D11Device()->CreateQuery(&queryDesc, &mEndQuery);
  28. if(hr != S_OK)
  29. {
  30. BS_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
  31. }
  32. mContext = device.getImmediateContext();
  33. }
  34. D3D11TimerQuery::~D3D11TimerQuery()
  35. {
  36. if(mBeginQuery != nullptr)
  37. mBeginQuery->Release();
  38. if(mEndQuery != nullptr)
  39. mEndQuery->Release();
  40. if(mDisjointQuery != nullptr)
  41. mDisjointQuery->Release();
  42. }
  43. void D3D11TimerQuery::begin()
  44. {
  45. mContext->Begin(mDisjointQuery);
  46. mContext->End(mBeginQuery);
  47. setActive(true);
  48. }
  49. void D3D11TimerQuery::end()
  50. {
  51. mContext->End(mEndQuery);
  52. mContext->End(mDisjointQuery);
  53. }
  54. bool D3D11TimerQuery::isReady() const
  55. {
  56. D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjointData;
  57. return mContext->GetData(mDisjointQuery, &disjointData, sizeof(disjointData), 0) == S_OK;
  58. }
  59. float D3D11TimerQuery::getTimeMs()
  60. {
  61. if(!mFinalized && isReady())
  62. {
  63. finalize();
  64. }
  65. return mTimeDelta;
  66. }
  67. void D3D11TimerQuery::finalize()
  68. {
  69. UINT64 timeStart, timeEnd;
  70. mContext->GetData(mBeginQuery, &timeStart, sizeof(timeStart), 0);
  71. mContext->GetData(mEndQuery, &timeEnd, sizeof(timeEnd), 0);
  72. D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjointData;
  73. mContext->GetData(mDisjointQuery, &disjointData, sizeof(disjointData), 0);
  74. float time = 0.0f;
  75. if(disjointData.Disjoint == FALSE)
  76. {
  77. float frequency = static_cast<float>(disjointData.Frequency);
  78. UINT64 delta = timeEnd - timeStart;
  79. mTimeDelta = (delta / (float)frequency) * 1000.0f;
  80. }
  81. else
  82. {
  83. LOGWRN("Unrealiable GPU timer query detected.");
  84. }
  85. }
  86. }