BsD3D11OcclusionQuery.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "BsD3D11OcclusionQuery.h"
  2. #include "BsD3D11RenderAPI.h"
  3. #include "BsD3D11Device.h"
  4. #include "BsRenderStats.h"
  5. #include "BsMath.h"
  6. namespace BansheeEngine
  7. {
  8. D3D11OcclusionQuery::D3D11OcclusionQuery(bool binary)
  9. :OcclusionQuery(binary), mContext(nullptr), mQuery(nullptr), mNumSamples(0), mFinalized(false), mQueryEndCalled(false)
  10. {
  11. D3D11RenderAPI* rs = static_cast<D3D11RenderAPI*>(RenderAPICore::instancePtr());
  12. D3D11Device& device = rs->getPrimaryDevice();
  13. D3D11_QUERY_DESC queryDesc;
  14. queryDesc.Query = mBinary ? D3D11_QUERY_OCCLUSION_PREDICATE : D3D11_QUERY_OCCLUSION;
  15. queryDesc.MiscFlags = 0;
  16. HRESULT hr = device.getD3D11Device()->CreateQuery(&queryDesc, &mQuery);
  17. if (hr != S_OK)
  18. BS_EXCEPT(RenderingAPIException, "Failed to create an occlusion query.");
  19. mContext = device.getImmediateContext();
  20. BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
  21. }
  22. D3D11OcclusionQuery::~D3D11OcclusionQuery()
  23. {
  24. if (mQuery != nullptr)
  25. mQuery->Release();
  26. BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
  27. }
  28. void D3D11OcclusionQuery::begin()
  29. {
  30. mContext->Begin(mQuery);
  31. mNumSamples = 0;
  32. mQueryEndCalled = false;
  33. setActive(true);
  34. }
  35. void D3D11OcclusionQuery::end()
  36. {
  37. mContext->End(mQuery);
  38. mQueryEndCalled = true;
  39. mFinalized = false;
  40. }
  41. bool D3D11OcclusionQuery::isReady() const
  42. {
  43. if (!mQueryEndCalled)
  44. return false;
  45. if (mBinary)
  46. {
  47. BOOL anySamples = FALSE;
  48. return mContext->GetData(mQuery, &anySamples, sizeof(anySamples), 0) == S_OK;
  49. }
  50. else
  51. {
  52. UINT64 numSamples = 0;
  53. return mContext->GetData(mQuery, &numSamples, sizeof(numSamples), 0) == S_OK;
  54. }
  55. }
  56. UINT32 D3D11OcclusionQuery::getNumSamples()
  57. {
  58. if (!mFinalized && isReady())
  59. {
  60. finalize();
  61. }
  62. return mNumSamples;
  63. }
  64. void D3D11OcclusionQuery::finalize()
  65. {
  66. mFinalized = true;
  67. if (mBinary)
  68. {
  69. BOOL anySamples = FALSE;
  70. mContext->GetData(mQuery, &anySamples, sizeof(anySamples), 0);
  71. mNumSamples = anySamples == TRUE ? 1 : 0;
  72. }
  73. else
  74. {
  75. UINT64 numSamples = 0;
  76. mContext->GetData(mQuery, &numSamples, sizeof(numSamples), 0);
  77. mNumSamples = (UINT32)numSamples;
  78. }
  79. }
  80. }