Drawer.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright (C) 2009-2021, 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/ImageResource.h>
  8. #include <AnKi/Renderer/Renderer.h>
  9. #include <AnKi/Util/Tracer.h>
  10. #include <AnKi/Util/Logger.h>
  11. namespace anki {
  12. /// Drawer's context
  13. class DrawContext
  14. {
  15. public:
  16. RenderQueueDrawContext m_queueCtx;
  17. const RenderableQueueElement* m_renderableElement = nullptr;
  18. Array<RenderableQueueElement, MAX_INSTANCE_COUNT> m_cachedRenderElements;
  19. Array<U8, MAX_INSTANCE_COUNT> m_cachedRenderElementLods;
  20. Array<const void*, MAX_INSTANCE_COUNT> m_userData;
  21. U32 m_cachedRenderElementCount = 0;
  22. U8 m_minLod = 0;
  23. U8 m_maxLod = 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, U32 maxLod)
  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 && maxLod < MAX_LOD_COUNT);
  50. ctx.m_minLod = U8(minLod);
  51. ctx.m_maxLod = U8(maxLod);
  52. for(; begin != end; ++begin)
  53. {
  54. ctx.m_renderableElement = begin;
  55. drawSingle(ctx);
  56. }
  57. // Flush the last drawcall
  58. flushDrawcall(ctx);
  59. }
  60. void RenderableDrawer::flushDrawcall(DrawContext& ctx)
  61. {
  62. ctx.m_queueCtx.m_key.setLod(ctx.m_cachedRenderElementLods[0]);
  63. ctx.m_queueCtx.m_key.setInstanceCount(ctx.m_cachedRenderElementCount);
  64. ctx.m_cachedRenderElements[0].m_callback(
  65. ctx.m_queueCtx, ConstWeakArray<void*>(const_cast<void**>(&ctx.m_userData[0]), ctx.m_cachedRenderElementCount));
  66. // Rendered something, reset the cached transforms
  67. if(ctx.m_cachedRenderElementCount > 1)
  68. {
  69. ANKI_TRACE_INC_COUNTER(R_MERGED_DRAWCALLS, ctx.m_cachedRenderElementCount - 1);
  70. }
  71. ctx.m_cachedRenderElementCount = 0;
  72. }
  73. void RenderableDrawer::drawSingle(DrawContext& ctx)
  74. {
  75. if(ctx.m_cachedRenderElementCount == MAX_INSTANCE_COUNT)
  76. {
  77. flushDrawcall(ctx);
  78. }
  79. const RenderableQueueElement& rqel = *ctx.m_renderableElement;
  80. const U8 overridenLod = clamp(rqel.m_lod, ctx.m_minLod, ctx.m_maxLod);
  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] != overridenLod);
  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] = overridenLod;
  92. ctx.m_userData[ctx.m_cachedRenderElementCount] = rqel.m_userData;
  93. ++ctx.m_cachedRenderElementCount;
  94. }
  95. } // end namespace anki