Drawer.cpp 3.6 KB

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