BsD3D11OcclusionQuery.cpp 2.4 KB

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