VisibilityInternal.h 6.7 KB

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