Readback.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Renderer/Utils/Readback.h>
  6. namespace anki {
  7. U32 ReadbackManager::findBestSlot(const MultiframeReadbackToken& token) const
  8. {
  9. const U64 earliestFrame = m_frameId - (kMaxFramesInFlight - 1);
  10. U32 bestSlot = kMaxU32;
  11. U32 secondBestSlot = kMaxU32;
  12. for(U32 i = 0; i < kMaxFramesInFlight; ++i)
  13. {
  14. if(token.m_frameIds[i] == earliestFrame && token.m_allocations[i].isValid())
  15. {
  16. bestSlot = i;
  17. break;
  18. }
  19. else if(token.m_frameIds[i] < earliestFrame && token.m_allocations[i].isValid())
  20. {
  21. secondBestSlot = i;
  22. }
  23. }
  24. const U32 slot = (bestSlot != kMaxU32) ? bestSlot : secondBestSlot;
  25. return slot;
  26. }
  27. void ReadbackManager::readMostRecentData(const MultiframeReadbackToken& token, void* data, PtrSize dataSize, PtrSize& dataOut) const
  28. {
  29. ANKI_ASSERT(data && dataSize > 0);
  30. dataOut = 0;
  31. const U32 slot = findBestSlot(token);
  32. if(slot == kMaxU32)
  33. {
  34. return;
  35. }
  36. const GpuReadbackMemoryAllocation& allocation = token.m_allocations[slot];
  37. dataOut = min(dataSize, PtrSize(allocation.getAllocatedSize()));
  38. memcpy(data, static_cast<const U8*>(allocation.getMappedMemory()), dataOut);
  39. }
  40. void ReadbackManager::endFrame(Fence* fence)
  41. {
  42. ANKI_ASSERT(fence);
  43. // Release fences
  44. for(Frame& frame : m_frames)
  45. {
  46. if(frame.m_fence.isCreated())
  47. {
  48. if(frame.m_fence->clientWait(0.0))
  49. {
  50. frame.m_fence.reset(nullptr);
  51. }
  52. }
  53. }
  54. Frame& frame = m_frames[m_frameId % m_frames.getSize()];
  55. if(frame.m_fence.isCreated()) [[unlikely]]
  56. {
  57. ANKI_R_LOGW("Readback fence is not signaled. Need to wait it");
  58. const Bool signaled = frame.m_fence->clientWait(10.0_sec);
  59. if(!signaled)
  60. {
  61. ANKI_R_LOGF("Fence won't signal. Can't recover");
  62. }
  63. }
  64. frame.m_fence.reset(fence);
  65. ++m_frameId;
  66. }
  67. } // end namespace anki