MTLPerfQuery.mm 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright 2022 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "VideoBackends/Metal/MTLPerfQuery.h"
  4. #include "VideoBackends/Metal/MTLStateTracker.h"
  5. void Metal::PerfQuery::EnableQuery(PerfQueryGroup type)
  6. {
  7. if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP)
  8. g_state_tracker->EnablePerfQuery(type, m_current_query);
  9. }
  10. void Metal::PerfQuery::DisableQuery(PerfQueryGroup type)
  11. {
  12. if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP)
  13. g_state_tracker->DisablePerfQuery();
  14. }
  15. void Metal::PerfQuery::ResetQuery()
  16. {
  17. std::lock_guard<std::mutex> lock(m_results_mtx);
  18. m_current_query++;
  19. for (std::atomic<u32>& result : m_results)
  20. result.store(0, std::memory_order_relaxed);
  21. }
  22. u32 Metal::PerfQuery::GetQueryResult(PerfQueryType type)
  23. {
  24. u32 result = 0;
  25. if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC)
  26. {
  27. result = m_results[PQG_ZCOMP_ZCOMPLOC].load(std::memory_order_relaxed);
  28. }
  29. else if (type == PQ_ZCOMP_INPUT || type == PQ_ZCOMP_OUTPUT)
  30. {
  31. result = m_results[PQG_ZCOMP].load(std::memory_order_relaxed);
  32. }
  33. else if (type == PQ_BLEND_INPUT)
  34. {
  35. result = m_results[PQG_ZCOMP].load(std::memory_order_relaxed) +
  36. m_results[PQG_ZCOMP_ZCOMPLOC].load(std::memory_order_relaxed);
  37. }
  38. else if (type == PQ_EFB_COPY_CLOCKS)
  39. {
  40. result = m_results[PQG_EFB_COPY_CLOCKS].load(std::memory_order_relaxed);
  41. }
  42. return result / 4;
  43. }
  44. void Metal::PerfQuery::FlushResults()
  45. {
  46. if (IsFlushed())
  47. return;
  48. // There's a possibility that some active performance queries are unflushed
  49. g_state_tracker->FlushEncoders();
  50. g_state_tracker->NotifyOfCPUGPUSync();
  51. std::unique_lock<std::mutex> lock(m_results_mtx);
  52. while (!IsFlushed())
  53. m_cv.wait(lock);
  54. }
  55. bool Metal::PerfQuery::IsFlushed() const
  56. {
  57. return m_query_count.load(std::memory_order_acquire) == 0;
  58. }
  59. void Metal::PerfQuery::ReturnResults(const u64* data, const PerfQueryGroup* groups, size_t count,
  60. u32 query_id)
  61. {
  62. {
  63. std::lock_guard<std::mutex> lock(m_results_mtx);
  64. if (m_current_query == query_id)
  65. {
  66. for (size_t i = 0; i < count; ++i)
  67. {
  68. u64 native_res_result =
  69. data[i] * (EFB_WIDTH * EFB_HEIGHT) /
  70. (g_framebuffer_manager->GetEFBWidth() * g_framebuffer_manager->GetEFBHeight());
  71. native_res_result /= g_ActiveConfig.iMultisamples;
  72. m_results[groups[i]].fetch_add(native_res_result, std::memory_order_relaxed);
  73. }
  74. }
  75. m_query_count.fetch_sub(1, std::memory_order_release);
  76. }
  77. m_cv.notify_one();
  78. }