Renderer.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. // Copyright (C) 2009-present, 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/Renderer/Common.h>
  7. #include <AnKi/Math.h>
  8. #include <AnKi/Gr.h>
  9. #include <AnKi/Resource/Forward.h>
  10. #include <AnKi/Collision/Forward.h>
  11. namespace anki {
  12. /// @addtogroup renderer
  13. /// @{
  14. ANKI_CVAR(
  15. NumericCVar<F32>, Render, InternalRenderScaling, 1.0f,
  16. [](F32 value) {
  17. return (value > 0.1f && value <= 8.0f) || value == 540.0f || value == 720.0f || value == 1080.0f || value == 1440.0f || value == 2160.0f;
  18. },
  19. "A factor over the requested swapchain resolution or some common resolution values (eg 1080, 720 etc). Applies to all passes up to TAA")
  20. ANKI_CVAR(
  21. NumericCVar<F32>, Render, RenderScaling, 1.0f,
  22. [](F32 value) {
  23. return (value > 0.1f && value <= 8.0f) || value == 540.0f || value == 720.0f || value == 1080.0f || value == 1440.0f || value == 2160.0f;
  24. },
  25. "A factor over the requested swapchain resolution. Applies to post-processing and UI")
  26. ANKI_CVAR(NumericCVar<U32>, Render, ZSplitCount, 64, 8, kMaxZsplitCount, "Clusterer number of Z splits")
  27. ANKI_CVAR(NumericCVar<U8>, Render, TextureAnisotropy, (ANKI_PLATFORM_MOBILE) ? 1 : 16, 1, 16, "Texture anisotropy for the main passes")
  28. ANKI_CVAR(BoolCVar, Render, PreferCompute, !ANKI_PLATFORM_MOBILE, "Prefer compute shaders")
  29. ANKI_CVAR(BoolCVar, Render, HighQualityHdr, !ANKI_PLATFORM_MOBILE, "If true use R16G16B16 for HDR images. Alternatively use B10G11R11")
  30. ANKI_CVAR(BoolCVar, Render, VrsLimitTo2x2, false, "If true the max rate will be 2x2")
  31. ANKI_CVAR(NumericCVar<U8>, Render, ShadowCascadeCount, (ANKI_PLATFORM_MOBILE) ? 3 : kMaxShadowCascades, 1, kMaxShadowCascades,
  32. "Max number of shadow cascades for directional lights")
  33. ANKI_CVAR(NumericCVar<F32>, Render, ShadowCascade0Distance, 18.0, 1.0, kMaxF32, "The distance of the 1st cascade")
  34. ANKI_CVAR(NumericCVar<F32>, Render, ShadowCascade1Distance, (ANKI_PLATFORM_MOBILE) ? 80.0f : 40.0, 1.0, kMaxF32, "The distance of the 2nd cascade")
  35. ANKI_CVAR(NumericCVar<F32>, Render, ShadowCascade2Distance, (ANKI_PLATFORM_MOBILE) ? 150.0f : 80.0, 1.0, kMaxF32, "The distance of the 3rd cascade")
  36. ANKI_CVAR(NumericCVar<F32>, Render, ShadowCascade3Distance, 200.0, 1.0, kMaxF32, "The distance of the 4th cascade")
  37. ANKI_CVAR(NumericCVar<F32>, Render, Lod0MaxDistance, 20.0f, 1.0f, kMaxF32, "Distance that will be used to calculate the LOD 0")
  38. ANKI_CVAR(NumericCVar<F32>, Render, Lod1MaxDistance, 40.0f, 2.0f, kMaxF32, "Distance that will be used to calculate the LOD 1")
  39. ANKI_SVAR(RendererGpuTime, StatCategory::kTime, "GPU frame", StatFlag::kMilisecond | StatFlag::kShowAverage | StatFlag::kMainThreadUpdates)
  40. /// Renderer statistics.
  41. class RendererPrecreatedSamplers
  42. {
  43. public:
  44. SamplerPtr m_nearestNearestClamp;
  45. SamplerPtr m_nearestNearestRepeat;
  46. SamplerPtr m_trilinearClamp;
  47. SamplerPtr m_trilinearRepeat;
  48. SamplerPtr m_trilinearRepeatAniso;
  49. SamplerPtr m_trilinearRepeatAnisoResolutionScalingBias;
  50. SamplerPtr m_trilinearClampShadow;
  51. };
  52. /// Some dummy resources to fill the slots.
  53. class DummyGpuResources
  54. {
  55. public:
  56. TexturePtr m_texture2DSrv;
  57. TexturePtr m_texture2DUintSrv;
  58. TexturePtr m_texture3DSrv;
  59. TexturePtr m_texture2DUav;
  60. TexturePtr m_texture3DUav;
  61. BufferPtr m_buffer;
  62. };
  63. enum class MeshletRenderingType
  64. {
  65. kNone,
  66. kMeshShaders,
  67. kSoftware
  68. };
  69. class RendererInitInfo
  70. {
  71. public:
  72. UVec2 m_swapchainSize = UVec2(0u);
  73. AllocAlignedCallback m_allocCallback = nullptr;
  74. void* m_allocCallbackUserData = nullptr;
  75. };
  76. /// Offscreen renderer.
  77. class Renderer : public MakeSingleton<Renderer>
  78. {
  79. friend class RendererObject;
  80. public:
  81. Renderer();
  82. ~Renderer();
  83. Error init(const RendererInitInfo& inf);
  84. Error render();
  85. #define ANKI_RENDERER_OBJECT_DEF(type, name, initCondition) \
  86. type& get##type() \
  87. { \
  88. ANKI_ASSERT(m_##name != nullptr && m_##name != numberToPtr<type*>(kMaxPtrSize)); \
  89. return *m_##name; \
  90. } \
  91. Bool is##type##Enabled() const \
  92. { \
  93. ANKI_ASSERT(m_##name != numberToPtr<type*>(kMaxPtrSize) && "Calling this before the renderer had a chance to decide if to initialize it"); \
  94. return m_##name != nullptr; \
  95. }
  96. #include <AnKi/Renderer/RendererObject.def.h>
  97. const UVec2& getInternalResolution() const
  98. {
  99. return m_internalResolution;
  100. }
  101. const UVec2& getPostProcessResolution() const
  102. {
  103. return m_postProcessResolution;
  104. }
  105. const UVec2& getSwapchainResolution() const
  106. {
  107. return m_swapchainResolution;
  108. }
  109. F32 getAspectRatio() const
  110. {
  111. return F32(m_internalResolution.x) / F32(m_internalResolution.y);
  112. }
  113. U64 getFrameCount() const
  114. {
  115. return m_frameCount;
  116. }
  117. MeshletRenderingType getMeshletRenderingType() const
  118. {
  119. return m_meshletRenderingType;
  120. }
  121. /// Create the init info for a 2D texture that will be used as a render target.
  122. [[nodiscard]] TextureInitInfo create2DRenderTargetInitInfo(U32 w, U32 h, Format format, TextureUsageBit usage, CString name = {});
  123. /// Create the init info for a 2D texture that will be used as a render target.
  124. [[nodiscard]] RenderTargetDesc create2DRenderTargetDescription(U32 w, U32 h, Format format, CString name = {});
  125. [[nodiscard]] TexturePtr createAndClearRenderTarget(const TextureInitInfo& inf, TextureUsageBit initialUsage,
  126. const ClearValue& clearVal = ClearValue());
  127. const RendererPrecreatedSamplers& getSamplers() const
  128. {
  129. return m_samplers;
  130. }
  131. const UVec2& getTileCounts() const
  132. {
  133. return m_tileCounts;
  134. }
  135. U32 getZSplitCount() const
  136. {
  137. return m_zSplitCount;
  138. }
  139. Format getHdrFormat() const;
  140. Format getDepthNoStencilFormat() const;
  141. BufferHandle getGpuSceneBufferHandle() const
  142. {
  143. return m_runCtx.m_gpuSceneHandle;
  144. }
  145. /// @name Debug render targets
  146. /// @{
  147. /// Register a debug render target.
  148. void registerDebugRenderTarget(RendererObject* obj, CString rtName);
  149. /// Set the render target you want to show.
  150. void setCurrentDebugRenderTarget(CString rtName, Bool disableTonemapping = false);
  151. /// Get the render target currently showing.
  152. CString getCurrentDebugRenderTarget() const
  153. {
  154. return m_currentDebugRtName;
  155. }
  156. // Need to call it after the handle is set by the RenderGraph.
  157. Bool getCurrentDebugRenderTarget(Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
  158. DebugRenderTargetDrawStyle& drawStyle);
  159. /// @}
  160. StackMemoryPool& getFrameMemoryPool()
  161. {
  162. return m_framePool;
  163. }
  164. ShaderProgram& getFillBufferProgram() const
  165. {
  166. return *m_fillBufferGrProg;
  167. }
  168. #if ANKI_STATS_ENABLED
  169. void appendPipelineQuery(PipelineQuery* q)
  170. {
  171. ANKI_ASSERT(q);
  172. LockGuard lock(m_pipelineQueriesMtx);
  173. m_pipelineQueries[m_frameCount % kMaxFramesInFlight].emplaceBack(q);
  174. }
  175. #endif
  176. template<typename TFunc>
  177. void iterateDebugRenderTargetNames(TFunc func) const
  178. {
  179. for(const auto& x : m_debugRts)
  180. {
  181. if(func(x.m_rtName) == FunctorContinue::kStop)
  182. {
  183. break;
  184. }
  185. }
  186. }
  187. private:
  188. class Cleanup
  189. {
  190. public:
  191. ~Cleanup()
  192. {
  193. RendererMemoryPool::freeSingleton();
  194. }
  195. } m_cleanup; // First so it will be called last in the renderer's destructor
  196. /// @name Rendering stages
  197. /// @{
  198. #define ANKI_RENDERER_OBJECT_DEF(name, name2, initCondition) name* m_##name2 = numberToPtr<name*>(kMaxPtrSize);
  199. #include <AnKi/Renderer/RendererObject.def.h>
  200. /// @}
  201. StackMemoryPool m_framePool;
  202. UVec2 m_internalResolution = UVec2(0u); ///< The resolution of all passes up until TAA.
  203. UVec2 m_postProcessResolution = UVec2(0u); ///< The resolution of post processing and following passes.
  204. UVec2 m_swapchainResolution = UVec2(0u);
  205. U64 m_frameCount; ///< Frame number
  206. CommonMatrices m_prevMatrices;
  207. Array<Vec2, 64> m_jitterOffsets;
  208. DummyGpuResources m_dummyResources;
  209. RendererPrecreatedSamplers m_samplers;
  210. ShaderProgramResourcePtr m_clearTexComputeProg;
  211. class DebugRtInfo
  212. {
  213. public:
  214. RendererObject* m_obj;
  215. RendererString m_rtName;
  216. };
  217. RendererDynamicArray<DebugRtInfo> m_debugRts;
  218. RendererString m_currentDebugRtName;
  219. Bool m_disableDebugRtTonemapping = false;
  220. ShaderProgramResourcePtr m_blitProg;
  221. ShaderProgramPtr m_blitGrProg;
  222. ShaderProgramResourcePtr m_fillBufferProg;
  223. ShaderProgramPtr m_fillBufferGrProg;
  224. RenderGraphPtr m_rgraph;
  225. UVec2 m_tileCounts = UVec2(0u);
  226. U32 m_zSplitCount = 0;
  227. class
  228. {
  229. public:
  230. BufferHandle m_gpuSceneHandle;
  231. } m_runCtx;
  232. #if ANKI_STATS_ENABLED
  233. Array<RendererDynamicArray<PipelineQueryPtr>, kMaxFramesInFlight> m_pipelineQueries;
  234. Mutex m_pipelineQueriesMtx;
  235. #endif
  236. MeshletRenderingType m_meshletRenderingType = MeshletRenderingType::kNone;
  237. Error initInternal(const RendererInitInfo& inf);
  238. void gpuSceneCopy(RenderingContext& ctx);
  239. #if ANKI_STATS_ENABLED
  240. void updatePipelineStats();
  241. #endif
  242. void writeGlobalRendererConstants(RenderingContext& ctx, GlobalRendererConstants& consts);
  243. /// This function does all the rendering stages and produces a final result.
  244. Error populateRenderGraph(RenderingContext& ctx);
  245. };
  246. /// @}
  247. } // end namespace anki