VisibilityInternal.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. #pragma once
  6. #include <AnKi/Scene/SceneGraph.h>
  7. #include <AnKi/Scene/SoftwareRasterizer.h>
  8. #include <AnKi/Scene/Components/FrustumComponent.h>
  9. #include <AnKi/Scene/Octree.h>
  10. #include <AnKi/Util/Thread.h>
  11. #include <AnKi/Util/Tracer.h>
  12. #include <AnKi/Renderer/RenderQueue.h>
  13. namespace anki {
  14. /// @addtogroup scene
  15. /// @{
  16. static const U32 MAX_SPATIALS_PER_VIS_TEST = 48; ///< Num of spatials to test in a single ThreadHive task.
  17. static const U32 SW_RASTERIZER_WIDTH = 80;
  18. static const U32 SW_RASTERIZER_HEIGHT = 50;
  19. /// Sort objects on distance
  20. template<typename T>
  21. class DistanceSortFunctor
  22. {
  23. public:
  24. Bool operator()(const T& a, const T& b)
  25. {
  26. return a.m_distanceFromCamera < b.m_distanceFromCamera;
  27. }
  28. };
  29. template<typename T>
  30. class RevDistanceSortFunctor
  31. {
  32. public:
  33. Bool operator()(const T& a, const T& b)
  34. {
  35. return a.m_distanceFromCamera > b.m_distanceFromCamera;
  36. }
  37. };
  38. /// Sorts first by LOD and then by material (merge key).
  39. class MaterialDistanceSortFunctor
  40. {
  41. public:
  42. Bool operator()(const RenderableQueueElement& a, const RenderableQueueElement& b)
  43. {
  44. if(a.m_lod == b.m_lod)
  45. {
  46. return a.m_mergeKey < b.m_mergeKey;
  47. }
  48. else
  49. {
  50. return a.m_lod < b.m_lod;
  51. }
  52. }
  53. };
  54. /// Storage for a single element type.
  55. template<typename T, U32 INITIAL_STORAGE_SIZE = 32, U32 STORAGE_GROW_RATE = 4>
  56. class TRenderQueueElementStorage
  57. {
  58. public:
  59. T* m_elements = nullptr;
  60. U32 m_elementCount = 0;
  61. U32 m_elementStorage = 0;
  62. T* newElement(SceneFrameAllocator<T> alloc)
  63. {
  64. if(ANKI_UNLIKELY(m_elementCount + 1 > m_elementStorage))
  65. {
  66. m_elementStorage = max(INITIAL_STORAGE_SIZE, m_elementStorage * STORAGE_GROW_RATE);
  67. const T* oldElements = m_elements;
  68. m_elements = alloc.allocate(m_elementStorage);
  69. if(oldElements)
  70. {
  71. memcpy(m_elements, oldElements, sizeof(T) * m_elementCount);
  72. }
  73. }
  74. return &m_elements[m_elementCount++];
  75. }
  76. };
  77. class RenderQueueView
  78. {
  79. public:
  80. TRenderQueueElementStorage<RenderableQueueElement> m_renderables; ///< Deferred shading or shadow renderables.
  81. TRenderQueueElementStorage<RenderableQueueElement> m_forwardShadingRenderables;
  82. TRenderQueueElementStorage<RenderableQueueElement> m_earlyZRenderables;
  83. TRenderQueueElementStorage<PointLightQueueElement> m_pointLights;
  84. TRenderQueueElementStorage<SpotLightQueueElement> m_spotLights;
  85. DirectionalLightQueueElement m_directionalLight;
  86. TRenderQueueElementStorage<ReflectionProbeQueueElement> m_reflectionProbes;
  87. TRenderQueueElementStorage<LensFlareQueueElement> m_lensFlares;
  88. TRenderQueueElementStorage<DecalQueueElement> m_decals;
  89. TRenderQueueElementStorage<FogDensityQueueElement> m_fogDensityVolumes;
  90. TRenderQueueElementStorage<GlobalIlluminationProbeQueueElement> m_giProbes;
  91. TRenderQueueElementStorage<GenericGpuComputeJobQueueElement> m_genericGpuComputeJobs;
  92. TRenderQueueElementStorage<RayTracingInstanceQueueElement> m_rayTracingInstances;
  93. TRenderQueueElementStorage<UiQueueElement> m_uis;
  94. Timestamp m_timestamp = 0;
  95. RenderQueueView()
  96. {
  97. zeroMemory(m_directionalLight);
  98. }
  99. };
  100. static_assert(std::is_trivially_destructible<RenderQueueView>::value == true, "Should be trivially destructible");
  101. /// Data common for all tasks.
  102. class VisibilityContext
  103. {
  104. public:
  105. SceneGraph* m_scene = nullptr;
  106. Atomic<U32> m_testsCount = {0};
  107. F32 m_earlyZDist = -1.0f; ///< Cache this.
  108. List<const FrustumComponent*> m_testedFrcs;
  109. Mutex m_mtx;
  110. void submitNewWork(const FrustumComponent& frc, const FrustumComponent& primaryFrustum, RenderQueue& result,
  111. ThreadHive& hive);
  112. };
  113. /// A context for a specific test of a frustum component.
  114. /// @note Should be trivially destructible.
  115. class FrustumVisibilityContext
  116. {
  117. public:
  118. VisibilityContext* m_visCtx = nullptr;
  119. const FrustumComponent* m_frc = nullptr; ///< This is the frustum to be tested.
  120. const FrustumComponent* m_primaryFrustum = nullptr; ///< This is the primary camera frustum.
  121. // S/W rasterizer members
  122. SoftwareRasterizer* m_r = nullptr;
  123. DynamicArray<Vec3> m_verts;
  124. Atomic<U32> m_rasterizedVertCount = {0}; ///< That will be used by the RasterizeTrianglesTask.
  125. // Visibility test members
  126. DynamicArray<RenderQueueView> m_queueViews; ///< Sub result. Will be combined later.
  127. ThreadHiveSemaphore* m_visTestsSignalSem = nullptr;
  128. // Gather results members
  129. RenderQueue* m_renderQueue = nullptr;
  130. };
  131. /// ThreadHive task to set the depth map of the S/W rasterizer.
  132. class FillRasterizerWithCoverageTask
  133. {
  134. public:
  135. FrustumVisibilityContext* m_frcCtx = nullptr;
  136. FillRasterizerWithCoverageTask(FrustumVisibilityContext* frcCtx)
  137. : m_frcCtx(frcCtx)
  138. {
  139. ANKI_ASSERT(m_frcCtx);
  140. }
  141. void fill();
  142. };
  143. static_assert(std::is_trivially_destructible<FillRasterizerWithCoverageTask>::value == true,
  144. "Should be trivially destructible");
  145. /// ThreadHive task to get visible nodes from the octree.
  146. class GatherVisiblesFromOctreeTask
  147. {
  148. public:
  149. FrustumVisibilityContext* m_frcCtx = nullptr;
  150. GatherVisiblesFromOctreeTask(FrustumVisibilityContext* frcCtx)
  151. : m_frcCtx(frcCtx)
  152. {
  153. ANKI_ASSERT(m_frcCtx);
  154. }
  155. void gather(ThreadHive& hive);
  156. private:
  157. Array<SpatialComponent*, MAX_SPATIALS_PER_VIS_TEST> m_spatials;
  158. U32 m_spatialCount = 0;
  159. /// Submit tasks to test the m_spatials.
  160. void flush(ThreadHive& hive);
  161. };
  162. static_assert(std::is_trivially_destructible<GatherVisiblesFromOctreeTask>::value == true,
  163. "Should be trivially destructible");
  164. /// ThreadHive task that does the actual visibility tests.
  165. class VisibilityTestTask
  166. {
  167. public:
  168. FrustumVisibilityContext* m_frcCtx = nullptr;
  169. Array<SpatialComponent*, MAX_SPATIALS_PER_VIS_TEST> m_spatialsToTest;
  170. U32 m_spatialToTestCount = 0;
  171. VisibilityTestTask(FrustumVisibilityContext* frcCtx)
  172. : m_frcCtx(frcCtx)
  173. {
  174. ANKI_ASSERT(m_frcCtx);
  175. }
  176. void test(ThreadHive& hive, U32 taskId);
  177. private:
  178. ANKI_USE_RESULT Bool testAgainstRasterizer(const Aabb& aabb) const
  179. {
  180. return (m_frcCtx->m_r) ? m_frcCtx->m_r->visibilityTest(aabb) : true;
  181. }
  182. };
  183. static_assert(std::is_trivially_destructible<VisibilityTestTask>::value == true, "Should be trivially destructible");
  184. /// Task that combines and sorts the results.
  185. class CombineResultsTask
  186. {
  187. public:
  188. FrustumVisibilityContext* m_frcCtx = nullptr;
  189. CombineResultsTask(FrustumVisibilityContext* frcCtx)
  190. : m_frcCtx(frcCtx)
  191. {
  192. ANKI_ASSERT(m_frcCtx);
  193. }
  194. void combine();
  195. private:
  196. template<typename T>
  197. static void combineQueueElements(SceneFrameAllocator<U8>& alloc,
  198. WeakArray<TRenderQueueElementStorage<T>> subStorages,
  199. WeakArray<TRenderQueueElementStorage<U32>>* ptrSubStorage, WeakArray<T>& combined,
  200. WeakArray<T*>* ptrCombined);
  201. };
  202. static_assert(std::is_trivially_destructible<CombineResultsTask>::value == true, "Should be trivially destructible");
  203. /// @}
  204. } // end namespace anki