CmD3D9TimerQuery.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "CmD3D9TimerQuery.h"
  2. #include "CmD3D9RenderSystem.h"
  3. #include "CmDebug.h"
  4. namespace CamelotFramework
  5. {
  6. D3D9TimerQuery::D3D9TimerQuery()
  7. :mFinalized(false), mBeginQuery(nullptr), mFreqQuery(nullptr),
  8. mEndQuery(nullptr), mDisjointQuery(nullptr), mTimeDelta(0.0f)
  9. {
  10. IDirect3DDevice9* device = D3D9RenderSystem::getActiveD3D9Device();
  11. HRESULT hr = device->CreateQuery(D3DQUERYTYPE_TIMESTAMPDISJOINT, &mDisjointQuery);
  12. if(hr != S_OK)
  13. {
  14. CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
  15. }
  16. hr = device->CreateQuery(D3DQUERYTYPE_TIMESTAMPFREQ, &mFreqQuery);
  17. if(hr != S_OK)
  18. {
  19. CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
  20. }
  21. hr = device->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &mBeginQuery);
  22. if(hr != S_OK)
  23. {
  24. CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
  25. }
  26. hr = device->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &mEndQuery);
  27. if(hr != S_OK)
  28. {
  29. CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
  30. }
  31. }
  32. D3D9TimerQuery::~D3D9TimerQuery()
  33. {
  34. if(mBeginQuery != nullptr)
  35. mBeginQuery->Release();
  36. if(mEndQuery != nullptr)
  37. mEndQuery->Release();
  38. if(mDisjointQuery != nullptr)
  39. mDisjointQuery->Release();
  40. if(mFreqQuery != nullptr)
  41. mFreqQuery->Release();
  42. }
  43. void D3D9TimerQuery::begin()
  44. {
  45. mDisjointQuery->Issue(D3DISSUE_BEGIN);
  46. mFreqQuery->Issue(D3DISSUE_END);
  47. mBeginQuery->Issue(D3DISSUE_END);
  48. setActive(true);
  49. }
  50. void D3D9TimerQuery::end()
  51. {
  52. mEndQuery->Issue(D3DISSUE_END);
  53. mDisjointQuery->Issue(D3DISSUE_END);
  54. }
  55. bool D3D9TimerQuery::isReady() const
  56. {
  57. BOOL queryData;
  58. return mDisjointQuery->GetData(&queryData, sizeof(BOOL), 0) == S_OK;
  59. }
  60. float D3D9TimerQuery::getTimeMs()
  61. {
  62. if(!mFinalized && isReady())
  63. {
  64. finalize();
  65. }
  66. return mTimeDelta;
  67. }
  68. void D3D9TimerQuery::finalize()
  69. {
  70. BOOL disjoint;
  71. mDisjointQuery->GetData(&disjoint, sizeof(BOOL), 0);
  72. if(!disjoint)
  73. {
  74. UINT64 frequency;
  75. mFreqQuery->GetData(&frequency, sizeof(UINT64), 0);
  76. UINT64 timeStart, timeEnd;
  77. mBeginQuery->GetData(&timeStart, sizeof(UINT64), 0);
  78. mEndQuery->GetData(&timeEnd, sizeof(UINT64), 0);
  79. UINT64 delta = timeEnd - timeStart;
  80. mTimeDelta = (delta/(float)frequency) * 1000.0f;
  81. }
  82. else
  83. {
  84. LOGWRN("Unrealiable GPU timer query detected.");
  85. }
  86. }
  87. }