VisibilityInternal.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. // Copyright (C) 2009-2022, 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. SkyboxQueueElement m_skybox;
  95. Bool m_skyboxSet = false;
  96. Timestamp m_timestamp = 0;
  97. RenderQueueView()
  98. {
  99. zeroMemory(m_directionalLight);
  100. zeroMemory(m_skybox);
  101. }
  102. };
  103. static_assert(std::is_trivially_destructible<RenderQueueView>::value == true, "Should be trivially destructible");
  104. /// Data common for all tasks.
  105. class VisibilityContext
  106. {
  107. public:
  108. SceneGraph* m_scene = nullptr;
  109. Atomic<U32> m_testsCount = {0};
  110. F32 m_earlyZDist = -1.0f; ///< Cache this.
  111. List<const FrustumComponent*> m_testedFrcs;
  112. Mutex m_mtx;
  113. void submitNewWork(const FrustumComponent& frc, const FrustumComponent& primaryFrustum, RenderQueue& result,
  114. ThreadHive& hive);
  115. };
  116. /// A context for a specific test of a frustum component.
  117. /// @note Should be trivially destructible.
  118. class FrustumVisibilityContext
  119. {
  120. public:
  121. VisibilityContext* m_visCtx = nullptr;
  122. const FrustumComponent* m_frc = nullptr; ///< This is the frustum to be tested.
  123. const FrustumComponent* m_primaryFrustum = nullptr; ///< This is the primary camera frustum.
  124. // S/W rasterizer members
  125. SoftwareRasterizer* m_r = nullptr;
  126. DynamicArray<Vec3> m_verts;
  127. Atomic<U32> m_rasterizedVertCount = {0}; ///< That will be used by the RasterizeTrianglesTask.
  128. // Visibility test members
  129. DynamicArray<RenderQueueView> m_queueViews; ///< Sub result. Will be combined later.
  130. ThreadHiveSemaphore* m_visTestsSignalSem = nullptr;
  131. // Gather results members
  132. RenderQueue* m_renderQueue = nullptr;
  133. };
  134. /// ThreadHive task to set the depth map of the S/W rasterizer.
  135. class FillRasterizerWithCoverageTask
  136. {
  137. public:
  138. FrustumVisibilityContext* m_frcCtx = nullptr;
  139. FillRasterizerWithCoverageTask(FrustumVisibilityContext* frcCtx)
  140. : m_frcCtx(frcCtx)
  141. {
  142. ANKI_ASSERT(m_frcCtx);
  143. }
  144. void fill();
  145. };
  146. static_assert(std::is_trivially_destructible<FillRasterizerWithCoverageTask>::value == true,
  147. "Should be trivially destructible");
  148. /// ThreadHive task to get visible nodes from the octree.
  149. class GatherVisiblesFromOctreeTask
  150. {
  151. public:
  152. FrustumVisibilityContext* m_frcCtx = nullptr;
  153. GatherVisiblesFromOctreeTask(FrustumVisibilityContext* frcCtx)
  154. : m_frcCtx(frcCtx)
  155. {
  156. ANKI_ASSERT(m_frcCtx);
  157. }
  158. void gather(ThreadHive& hive);
  159. private:
  160. Array<SpatialComponent*, MAX_SPATIALS_PER_VIS_TEST> m_spatials;
  161. U32 m_spatialCount = 0;
  162. /// Submit tasks to test the m_spatials.
  163. void flush(ThreadHive& hive);
  164. };
  165. static_assert(std::is_trivially_destructible<GatherVisiblesFromOctreeTask>::value == true,
  166. "Should be trivially destructible");
  167. /// ThreadHive task that does the actual visibility tests.
  168. class VisibilityTestTask
  169. {
  170. public:
  171. FrustumVisibilityContext* m_frcCtx = nullptr;
  172. Array<SpatialComponent*, MAX_SPATIALS_PER_VIS_TEST> m_spatialsToTest;
  173. U32 m_spatialToTestCount = 0;
  174. VisibilityTestTask(FrustumVisibilityContext* frcCtx)
  175. : m_frcCtx(frcCtx)
  176. {
  177. ANKI_ASSERT(m_frcCtx);
  178. }
  179. void test(ThreadHive& hive, U32 taskId);
  180. private:
  181. [[nodiscard]] Bool testAgainstRasterizer(const Aabb& aabb) const
  182. {
  183. return (m_frcCtx->m_r) ? m_frcCtx->m_r->visibilityTest(aabb) : true;
  184. }
  185. };
  186. static_assert(std::is_trivially_destructible<VisibilityTestTask>::value == true, "Should be trivially destructible");
  187. /// Task that combines and sorts the results.
  188. class CombineResultsTask
  189. {
  190. public:
  191. FrustumVisibilityContext* m_frcCtx = nullptr;
  192. CombineResultsTask(FrustumVisibilityContext* frcCtx)
  193. : m_frcCtx(frcCtx)
  194. {
  195. ANKI_ASSERT(m_frcCtx);
  196. }
  197. void combine();
  198. private:
  199. template<typename T>
  200. static void combineQueueElements(SceneFrameAllocator<U8>& alloc,
  201. WeakArray<TRenderQueueElementStorage<T>> subStorages,
  202. WeakArray<TRenderQueueElementStorage<U32>>* ptrSubStorage, WeakArray<T>& combined,
  203. WeakArray<T*>* ptrCombined);
  204. };
  205. static_assert(std::is_trivially_destructible<CombineResultsTask>::value == true, "Should be trivially destructible");
  206. /// @}
  207. } // end namespace anki