BsGLTimerQuery.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsGLTimerQuery.h"
  4. #include "BsGLCommandBuffer.h"
  5. #include "Math/BsMath.h"
  6. #include "Profiling/BsRenderStats.h"
  7. namespace bs { namespace ct
  8. {
  9. GLTimerQuery::GLTimerQuery(UINT32 deviceIdx)
  10. :mQueryStartObj(0), mQueryEndObj(0), mFinalized(false), mEndIssued(false), mTimeDelta(0.0f)
  11. {
  12. assert(deviceIdx == 0 && "Multiple GPUs not supported natively on OpenGL.");
  13. GLuint queries[2];
  14. glGenQueries(2, queries);
  15. BS_CHECK_GL_ERROR();
  16. mQueryStartObj = queries[0];
  17. mQueryEndObj = queries[1];
  18. BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
  19. }
  20. GLTimerQuery::~GLTimerQuery()
  21. {
  22. GLuint queries[2];
  23. queries[0] = mQueryStartObj;
  24. queries[1] = mQueryEndObj;
  25. glDeleteQueries(2, queries);
  26. BS_CHECK_GL_ERROR();
  27. BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
  28. }
  29. void GLTimerQuery::begin(const SPtr<CommandBuffer>& cb)
  30. {
  31. auto execute = [&]()
  32. {
  33. glQueryCounter(mQueryStartObj, GL_TIMESTAMP);
  34. BS_CHECK_GL_ERROR();
  35. setActive(true);
  36. mEndIssued = false;
  37. };
  38. if (cb == nullptr)
  39. execute();
  40. else
  41. {
  42. SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb);
  43. glCB->queueCommand(execute);
  44. }
  45. }
  46. void GLTimerQuery::end(const SPtr<CommandBuffer>& cb)
  47. {
  48. auto execute = [&]()
  49. {
  50. glQueryCounter(mQueryEndObj, GL_TIMESTAMP);
  51. BS_CHECK_GL_ERROR();
  52. mEndIssued = true;
  53. mFinalized = false;
  54. };
  55. if (cb == nullptr)
  56. execute();
  57. else
  58. {
  59. SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb);
  60. glCB->queueCommand(execute);
  61. }
  62. }
  63. bool GLTimerQuery::isReady() const
  64. {
  65. if (!mEndIssued)
  66. return false;
  67. GLint done = 0;
  68. glGetQueryObjectiv(mQueryEndObj, GL_QUERY_RESULT_AVAILABLE, &done);
  69. BS_CHECK_GL_ERROR();
  70. return done == GL_TRUE;
  71. }
  72. float GLTimerQuery::getTimeMs()
  73. {
  74. if(!mFinalized && isReady())
  75. {
  76. finalize();
  77. }
  78. return mTimeDelta;
  79. }
  80. void GLTimerQuery::finalize()
  81. {
  82. mFinalized = true;
  83. GLuint64 timeStart;
  84. GLuint64 timeEnd;
  85. glGetQueryObjectui64v(mQueryStartObj, GL_QUERY_RESULT, &timeStart);
  86. BS_CHECK_GL_ERROR();
  87. glGetQueryObjectui64v(mQueryEndObj, GL_QUERY_RESULT, &timeEnd);
  88. BS_CHECK_GL_ERROR();
  89. mTimeDelta = (timeEnd - timeStart) / 1000000.0f;
  90. }
  91. }}