Drawer.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright (C) 2009-2020, 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/Drawer.h>
  6. #include <anki/renderer/RenderQueue.h>
  7. #include <anki/resource/TextureResource.h>
  8. #include <anki/renderer/Renderer.h>
  9. #include <anki/util/Tracer.h>
  10. #include <anki/util/Logger.h>
  11. namespace anki
  12. {
  13. /// Drawer's context
  14. class DrawContext
  15. {
  16. public:
  17. RenderQueueDrawContext m_queueCtx;
  18. const RenderableQueueElement* m_renderableElement = nullptr;
  19. Array<RenderableQueueElement, MAX_INSTANCES> m_cachedRenderElements;
  20. Array<U8, MAX_INSTANCES> m_cachedRenderElementLods;
  21. Array<const void*, MAX_INSTANCES> m_userData;
  22. U32 m_cachedRenderElementCount = 0;
  23. U32 m_minLod = 0;
  24. };
  25. /// Check if the drawcalls can be merged.
  26. static Bool canMergeRenderableQueueElements(const RenderableQueueElement& a, const RenderableQueueElement& b)
  27. {
  28. return a.m_callback == b.m_callback && a.m_mergeKey != 0 && a.m_mergeKey == b.m_mergeKey;
  29. }
  30. RenderableDrawer::~RenderableDrawer()
  31. {
  32. }
  33. void RenderableDrawer::drawRange(Pass pass, const Mat4& viewMat, const Mat4& viewProjMat, const Mat4& prevViewProjMat,
  34. CommandBufferPtr cmdb, SamplerPtr sampler, const RenderableQueueElement* begin,
  35. const RenderableQueueElement* end, U32 minLod)
  36. {
  37. ANKI_ASSERT(begin && end && begin < end);
  38. DrawContext ctx;
  39. ctx.m_queueCtx.m_viewMatrix = viewMat;
  40. ctx.m_queueCtx.m_viewProjectionMatrix = viewProjMat;
  41. ctx.m_queueCtx.m_projectionMatrix = Mat4::getIdentity(); // TODO
  42. ctx.m_queueCtx.m_previousViewProjectionMatrix = prevViewProjMat;
  43. ctx.m_queueCtx.m_cameraTransform = ctx.m_queueCtx.m_viewMatrix.getInverse();
  44. ctx.m_queueCtx.m_stagingGpuAllocator = &m_r->getStagingGpuMemoryManager();
  45. ctx.m_queueCtx.m_commandBuffer = cmdb;
  46. ctx.m_queueCtx.m_sampler = sampler;
  47. ctx.m_queueCtx.m_key = RenderingKey(pass, 0, 1, false, false);
  48. ctx.m_queueCtx.m_debugDraw = false;
  49. ANKI_ASSERT(minLod < MAX_LOD_COUNT);
  50. ctx.m_minLod = minLod;
  51. for(; begin != end; ++begin)
  52. {
  53. ctx.m_renderableElement = begin;
  54. drawSingle(ctx);
  55. }
  56. // Flush the last drawcall
  57. flushDrawcall(ctx);
  58. }
  59. void RenderableDrawer::flushDrawcall(DrawContext& ctx)
  60. {
  61. ctx.m_queueCtx.m_key.setLod(ctx.m_cachedRenderElementLods[0]);
  62. ctx.m_queueCtx.m_key.setInstanceCount(ctx.m_cachedRenderElementCount);
  63. ctx.m_cachedRenderElements[0].m_callback(
  64. ctx.m_queueCtx, ConstWeakArray<void*>(const_cast<void**>(&ctx.m_userData[0]), ctx.m_cachedRenderElementCount));
  65. // Rendered something, reset the cached transforms
  66. if(ctx.m_cachedRenderElementCount > 1)
  67. {
  68. ANKI_TRACE_INC_COUNTER(R_MERGED_DRAWCALLS, ctx.m_cachedRenderElementCount - 1);
  69. }
  70. ctx.m_cachedRenderElementCount = 0;
  71. }
  72. void RenderableDrawer::drawSingle(DrawContext& ctx)
  73. {
  74. if(ctx.m_cachedRenderElementCount == MAX_INSTANCES)
  75. {
  76. flushDrawcall(ctx);
  77. }
  78. const RenderableQueueElement& rqel = *ctx.m_renderableElement;
  79. U32 lod = min(m_r->calculateLod(rqel.m_distanceFromCamera), MAX_LOD_COUNT - 1);
  80. lod = max(lod, ctx.m_minLod);
  81. const Bool shouldFlush =
  82. ctx.m_cachedRenderElementCount > 0
  83. && (!canMergeRenderableQueueElements(ctx.m_cachedRenderElements[ctx.m_cachedRenderElementCount - 1], rqel)
  84. || ctx.m_cachedRenderElementLods[ctx.m_cachedRenderElementCount - 1] != lod);
  85. if(shouldFlush)
  86. {
  87. flushDrawcall(ctx);
  88. }
  89. // Cache the new one
  90. ctx.m_cachedRenderElements[ctx.m_cachedRenderElementCount] = rqel;
  91. ctx.m_cachedRenderElementLods[ctx.m_cachedRenderElementCount] = U8(lod);
  92. ctx.m_userData[ctx.m_cachedRenderElementCount] = rqel.m_userData;
  93. ++ctx.m_cachedRenderElementCount;
  94. }
  95. } // end namespace anki