2
0

Renderer.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  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. #include <AnKi/Renderer/Renderer.h>
  6. #include <AnKi/Renderer/RenderQueue.h>
  7. #include <AnKi/Util/Tracer.h>
  8. #include <AnKi/Util/ThreadHive.h>
  9. #include <AnKi/Core/ConfigSet.h>
  10. #include <AnKi/Util/HighRezTimer.h>
  11. #include <AnKi/Collision/Aabb.h>
  12. #include <AnKi/Collision/Plane.h>
  13. #include <AnKi/Collision/Functions.h>
  14. #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
  15. #include <AnKi/Renderer/ProbeReflections.h>
  16. #include <AnKi/Renderer/GBuffer.h>
  17. #include <AnKi/Renderer/GBufferPost.h>
  18. #include <AnKi/Renderer/LightShading.h>
  19. #include <AnKi/Renderer/ShadowMapping.h>
  20. #include <AnKi/Renderer/FinalComposite.h>
  21. #include <AnKi/Renderer/Bloom.h>
  22. #include <AnKi/Renderer/Tonemapping.h>
  23. #include <AnKi/Renderer/ForwardShading.h>
  24. #include <AnKi/Renderer/LensFlare.h>
  25. #include <AnKi/Renderer/Dbg.h>
  26. #include <AnKi/Renderer/DownscaleBlur.h>
  27. #include <AnKi/Renderer/VolumetricFog.h>
  28. #include <AnKi/Renderer/DepthDownscale.h>
  29. #include <AnKi/Renderer/TemporalAA.h>
  30. #include <AnKi/Renderer/UiStage.h>
  31. #include <AnKi/Renderer/IndirectSpecular.h>
  32. #include <AnKi/Renderer/VolumetricLightingAccumulation.h>
  33. #include <AnKi/Renderer/IndirectDiffuseProbes.h>
  34. #include <AnKi/Renderer/GenericCompute.h>
  35. #include <AnKi/Renderer/ShadowmapsResolve.h>
  36. #include <AnKi/Renderer/RtShadows.h>
  37. #include <AnKi/Renderer/AccelerationStructureBuilder.h>
  38. #include <AnKi/Renderer/MotionVectors.h>
  39. #include <AnKi/Renderer/ClusterBinning.h>
  40. #include <AnKi/Renderer/Scale.h>
  41. #include <AnKi/Renderer/IndirectDiffuse.h>
  42. #include <AnKi/Renderer/VrsSriGeneration.h>
  43. namespace anki {
  44. /// Generate a Halton jitter in [-0.5, 0.5]
  45. static Vec2 generateJitter(U32 frame)
  46. {
  47. // Halton jitter
  48. Vec2 result(0.0f);
  49. constexpr U32 baseX = 2;
  50. U32 index = frame + 1;
  51. F32 invBase = 1.0f / baseX;
  52. F32 fraction = invBase;
  53. while(index > 0)
  54. {
  55. result.x() += F32(index % baseX) * fraction;
  56. index /= baseX;
  57. fraction *= invBase;
  58. }
  59. constexpr U32 baseY = 3;
  60. index = frame + 1;
  61. invBase = 1.0f / baseY;
  62. fraction = invBase;
  63. while(index > 0)
  64. {
  65. result.y() += F32(index % baseY) * fraction;
  66. index /= baseY;
  67. fraction *= invBase;
  68. }
  69. result.x() -= 0.5f;
  70. result.y() -= 0.5f;
  71. return result;
  72. }
  73. Renderer::Renderer()
  74. : m_sceneDrawer(this)
  75. {
  76. }
  77. Renderer::~Renderer()
  78. {
  79. for(DebugRtInfo& info : m_debugRts)
  80. {
  81. info.m_rtName.destroy(getAllocator());
  82. }
  83. m_debugRts.destroy(getAllocator());
  84. m_currentDebugRtName.destroy(getAllocator());
  85. }
  86. Error Renderer::init(ThreadHive* hive, ResourceManager* resources, GrManager* gl, StagingGpuMemoryPool* stagingMem,
  87. UiManager* ui, HeapAllocator<U8> alloc, ConfigSet* config, Timestamp* globTimestamp,
  88. UVec2 swapchainSize)
  89. {
  90. ANKI_TRACE_SCOPED_EVENT(R_INIT);
  91. m_globTimestamp = globTimestamp;
  92. m_threadHive = hive;
  93. m_resources = resources;
  94. m_gr = gl;
  95. m_stagingMem = stagingMem;
  96. m_ui = ui;
  97. m_alloc = alloc;
  98. m_config = config;
  99. const Error err = initInternal(swapchainSize);
  100. if(err)
  101. {
  102. ANKI_R_LOGE("Failed to initialize the renderer");
  103. }
  104. return err;
  105. }
  106. Error Renderer::initInternal(UVec2 swapchainResolution)
  107. {
  108. m_frameCount = 0;
  109. // Set from the config
  110. m_postProcessResolution = UVec2(Vec2(swapchainResolution) * m_config->getRRenderScaling());
  111. alignRoundDown(2, m_postProcessResolution.x());
  112. alignRoundDown(2, m_postProcessResolution.y());
  113. m_internalResolution = UVec2(Vec2(m_postProcessResolution) * m_config->getRInternalRenderScaling());
  114. alignRoundDown(2, m_internalResolution.x());
  115. alignRoundDown(2, m_internalResolution.y());
  116. ANKI_R_LOGI("Initializing offscreen renderer. Resolution %ux%u. Internal resolution %ux%u",
  117. m_postProcessResolution.x(), m_postProcessResolution.y(), m_internalResolution.x(),
  118. m_internalResolution.y());
  119. m_tileSize = m_config->getRTileSize();
  120. m_tileCounts.x() = (m_internalResolution.x() + m_tileSize - 1) / m_tileSize;
  121. m_tileCounts.y() = (m_internalResolution.y() + m_tileSize - 1) / m_tileSize;
  122. m_zSplitCount = m_config->getRZSplitCount();
  123. // A few sanity checks
  124. if(m_internalResolution.x() < 64 || m_internalResolution.y() < 64)
  125. {
  126. ANKI_R_LOGE("Incorrect sizes");
  127. return Error::USER_DATA;
  128. }
  129. ANKI_CHECK(m_resources->loadResource("ShaderBinaries/ClearTextureCompute.ankiprogbin", m_clearTexComputeProg));
  130. // Dummy resources
  131. {
  132. TextureInitInfo texinit("RendererDummy");
  133. texinit.m_width = texinit.m_height = 4;
  134. texinit.m_usage = TextureUsageBit::kAllSampled | TextureUsageBit::kImageComputeWrite;
  135. texinit.m_format = Format::kR8G8B8A8_Unorm;
  136. TexturePtr tex = createAndClearRenderTarget(texinit, TextureUsageBit::kAllSampled);
  137. TextureViewInitInfo viewinit(tex);
  138. m_dummyTexView2d = getGrManager().newTextureView(viewinit);
  139. texinit.m_depth = 4;
  140. texinit.m_type = TextureType::k3D;
  141. tex = createAndClearRenderTarget(texinit, TextureUsageBit::kAllSampled);
  142. viewinit = TextureViewInitInfo(tex);
  143. m_dummyTexView3d = getGrManager().newTextureView(viewinit);
  144. m_dummyBuff = getGrManager().newBuffer(BufferInitInfo(
  145. 1024, BufferUsageBit::ALL_UNIFORM | BufferUsageBit::ALL_STORAGE, BufferMapAccessBit::NONE, "Dummy"));
  146. }
  147. // Init the stages. Careful with the order!!!!!!!!!!
  148. m_genericCompute.reset(m_alloc.newInstance<GenericCompute>(this));
  149. ANKI_CHECK(m_genericCompute->init());
  150. m_volumetricLightingAccumulation.reset(m_alloc.newInstance<VolumetricLightingAccumulation>(this));
  151. ANKI_CHECK(m_volumetricLightingAccumulation->init());
  152. m_indirectDiffuseProbes.reset(m_alloc.newInstance<IndirectDiffuseProbes>(this));
  153. ANKI_CHECK(m_indirectDiffuseProbes->init());
  154. m_probeReflections.reset(m_alloc.newInstance<ProbeReflections>(this));
  155. ANKI_CHECK(m_probeReflections->init());
  156. m_vrsSriGeneration.reset(m_alloc.newInstance<VrsSriGeneration>(this));
  157. ANKI_CHECK(m_vrsSriGeneration->init());
  158. m_scale.reset(m_alloc.newInstance<Scale>(this));
  159. ANKI_CHECK(m_scale->init());
  160. m_gbuffer.reset(m_alloc.newInstance<GBuffer>(this));
  161. ANKI_CHECK(m_gbuffer->init());
  162. m_gbufferPost.reset(m_alloc.newInstance<GBufferPost>(this));
  163. ANKI_CHECK(m_gbufferPost->init());
  164. m_shadowMapping.reset(m_alloc.newInstance<ShadowMapping>(this));
  165. ANKI_CHECK(m_shadowMapping->init());
  166. m_volumetricFog.reset(m_alloc.newInstance<VolumetricFog>(this));
  167. ANKI_CHECK(m_volumetricFog->init());
  168. m_lightShading.reset(m_alloc.newInstance<LightShading>(this));
  169. ANKI_CHECK(m_lightShading->init());
  170. m_depthDownscale.reset(m_alloc.newInstance<DepthDownscale>(this));
  171. ANKI_CHECK(m_depthDownscale->init());
  172. m_forwardShading.reset(m_alloc.newInstance<ForwardShading>(this));
  173. ANKI_CHECK(m_forwardShading->init());
  174. m_lensFlare.reset(m_alloc.newInstance<LensFlare>(this));
  175. ANKI_CHECK(m_lensFlare->init());
  176. m_downscaleBlur.reset(getAllocator().newInstance<DownscaleBlur>(this));
  177. ANKI_CHECK(m_downscaleBlur->init());
  178. m_indirectSpecular.reset(m_alloc.newInstance<IndirectSpecular>(this));
  179. ANKI_CHECK(m_indirectSpecular->init());
  180. m_tonemapping.reset(getAllocator().newInstance<Tonemapping>(this));
  181. ANKI_CHECK(m_tonemapping->init());
  182. m_temporalAA.reset(getAllocator().newInstance<TemporalAA>(this));
  183. ANKI_CHECK(m_temporalAA->init());
  184. m_bloom.reset(m_alloc.newInstance<Bloom>(this));
  185. ANKI_CHECK(m_bloom->init());
  186. m_finalComposite.reset(m_alloc.newInstance<FinalComposite>(this));
  187. ANKI_CHECK(m_finalComposite->init());
  188. m_dbg.reset(m_alloc.newInstance<Dbg>(this));
  189. ANKI_CHECK(m_dbg->init());
  190. m_uiStage.reset(m_alloc.newInstance<UiStage>(this));
  191. ANKI_CHECK(m_uiStage->init());
  192. m_indirectDiffuse.reset(m_alloc.newInstance<IndirectDiffuse>(this));
  193. ANKI_CHECK(m_indirectDiffuse->init());
  194. if(getGrManager().getDeviceCapabilities().m_rayTracingEnabled && getConfig().getSceneRayTracedShadows())
  195. {
  196. m_accelerationStructureBuilder.reset(m_alloc.newInstance<AccelerationStructureBuilder>(this));
  197. ANKI_CHECK(m_accelerationStructureBuilder->init());
  198. m_rtShadows.reset(m_alloc.newInstance<RtShadows>(this));
  199. ANKI_CHECK(m_rtShadows->init());
  200. }
  201. else
  202. {
  203. m_shadowmapsResolve.reset(m_alloc.newInstance<ShadowmapsResolve>(this));
  204. ANKI_CHECK(m_shadowmapsResolve->init());
  205. }
  206. m_motionVectors.reset(m_alloc.newInstance<MotionVectors>(this));
  207. ANKI_CHECK(m_motionVectors->init());
  208. m_clusterBinning.reset(m_alloc.newInstance<ClusterBinning>(this));
  209. ANKI_CHECK(m_clusterBinning->init());
  210. // Init samplers
  211. {
  212. SamplerInitInfo sinit("Renderer");
  213. sinit.m_addressing = SamplingAddressing::kClamp;
  214. sinit.m_mipmapFilter = SamplingFilter::kNearest;
  215. sinit.m_minMagFilter = SamplingFilter::kNearest;
  216. m_samplers.m_nearestNearestClamp = m_gr->newSampler(sinit);
  217. sinit.m_minMagFilter = SamplingFilter::kLinear;
  218. sinit.m_mipmapFilter = SamplingFilter::kLinear;
  219. m_samplers.m_trilinearClamp = m_gr->newSampler(sinit);
  220. sinit.m_addressing = SamplingAddressing::kRepeat;
  221. m_samplers.m_trilinearRepeat = m_gr->newSampler(sinit);
  222. sinit.m_anisotropyLevel = m_config->getRTextureAnisotropy();
  223. m_samplers.m_trilinearRepeatAniso = m_gr->newSampler(sinit);
  224. F32 scalingMipBias = log2(F32(m_internalResolution.x()) / F32(m_postProcessResolution.x()));
  225. if(getScale().getUsingGrUpscaler())
  226. {
  227. // DLSS wants more bias
  228. scalingMipBias -= 1.0f;
  229. }
  230. sinit.m_lodBias = scalingMipBias;
  231. m_samplers.m_trilinearRepeatAnisoResolutionScalingBias = m_gr->newSampler(sinit);
  232. }
  233. for(U32 i = 0; i < m_jitterOffsets.getSize(); ++i)
  234. {
  235. m_jitterOffsets[i] = generateJitter(i);
  236. }
  237. return Error::NONE;
  238. }
  239. Error Renderer::populateRenderGraph(RenderingContext& ctx)
  240. {
  241. ctx.m_prevMatrices = m_prevMatrices;
  242. ctx.m_matrices.m_cameraTransform = ctx.m_renderQueue->m_cameraTransform;
  243. ctx.m_matrices.m_view = ctx.m_renderQueue->m_viewMatrix;
  244. ctx.m_matrices.m_projection = ctx.m_renderQueue->m_projectionMatrix;
  245. ctx.m_matrices.m_viewProjection = ctx.m_renderQueue->m_viewProjectionMatrix;
  246. Vec2 jitter = m_jitterOffsets[m_frameCount & (m_jitterOffsets.getSize() - 1)]; // In [-0.5, 0.5]
  247. const Vec2 ndcPixelSize = 2.0f / Vec2(m_internalResolution);
  248. jitter *= ndcPixelSize;
  249. ctx.m_matrices.m_jitter = Mat4::getIdentity();
  250. ctx.m_matrices.m_jitter.setTranslationPart(Vec4(jitter, 0.0f, 1.0f));
  251. ctx.m_matrices.m_projectionJitter = ctx.m_matrices.m_jitter * ctx.m_matrices.m_projection;
  252. ctx.m_matrices.m_viewProjectionJitter =
  253. ctx.m_matrices.m_projectionJitter * Mat4(ctx.m_matrices.m_view, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
  254. ctx.m_matrices.m_invertedViewProjectionJitter = ctx.m_matrices.m_viewProjectionJitter.getInverse();
  255. ctx.m_matrices.m_invertedViewProjection = ctx.m_matrices.m_viewProjection.getInverse();
  256. ctx.m_matrices.m_invertedProjectionJitter = ctx.m_matrices.m_projectionJitter.getInverse();
  257. ctx.m_matrices.m_reprojection =
  258. ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_invertedViewProjectionJitter;
  259. ctx.m_matrices.m_unprojectionParameters = ctx.m_matrices.m_projection.extractPerspectiveUnprojectionParams();
  260. // Check if resources got loaded
  261. if(m_prevLoadRequestCount != m_resources->getLoadingRequestCount()
  262. || m_prevAsyncTasksCompleted != m_resources->getAsyncTaskCompletedCount())
  263. {
  264. m_prevLoadRequestCount = m_resources->getLoadingRequestCount();
  265. m_prevAsyncTasksCompleted = m_resources->getAsyncTaskCompletedCount();
  266. m_resourcesDirty = true;
  267. }
  268. else
  269. {
  270. m_resourcesDirty = false;
  271. }
  272. // Import RTs first
  273. m_downscaleBlur->importRenderTargets(ctx);
  274. m_tonemapping->importRenderTargets(ctx);
  275. m_depthDownscale->importRenderTargets(ctx);
  276. m_vrsSriGeneration->importRenderTargets(ctx);
  277. // Populate render graph. WARNING Watch the order
  278. m_genericCompute->populateRenderGraph(ctx);
  279. m_clusterBinning->populateRenderGraph(ctx);
  280. if(m_accelerationStructureBuilder)
  281. {
  282. m_accelerationStructureBuilder->populateRenderGraph(ctx);
  283. }
  284. m_shadowMapping->populateRenderGraph(ctx);
  285. m_indirectDiffuseProbes->populateRenderGraph(ctx);
  286. m_probeReflections->populateRenderGraph(ctx);
  287. m_volumetricLightingAccumulation->populateRenderGraph(ctx);
  288. m_gbuffer->populateRenderGraph(ctx);
  289. m_motionVectors->populateRenderGraph(ctx);
  290. m_gbufferPost->populateRenderGraph(ctx);
  291. m_depthDownscale->populateRenderGraph(ctx);
  292. if(m_rtShadows)
  293. {
  294. m_rtShadows->populateRenderGraph(ctx);
  295. }
  296. else
  297. {
  298. m_shadowmapsResolve->populateRenderGraph(ctx);
  299. }
  300. m_volumetricFog->populateRenderGraph(ctx);
  301. m_lensFlare->populateRenderGraph(ctx);
  302. m_indirectSpecular->populateRenderGraph(ctx);
  303. m_indirectDiffuse->populateRenderGraph(ctx);
  304. m_lightShading->populateRenderGraph(ctx);
  305. if(!getScale().getUsingGrUpscaler())
  306. {
  307. m_temporalAA->populateRenderGraph(ctx);
  308. }
  309. m_vrsSriGeneration->populateRenderGraph(ctx);
  310. m_scale->populateRenderGraph(ctx);
  311. m_downscaleBlur->populateRenderGraph(ctx);
  312. m_tonemapping->populateRenderGraph(ctx);
  313. m_bloom->populateRenderGraph(ctx);
  314. m_dbg->populateRenderGraph(ctx);
  315. m_finalComposite->populateRenderGraph(ctx);
  316. // Populate the uniforms
  317. m_clusterBinning->writeClusterBuffersAsync();
  318. return Error::NONE;
  319. }
  320. void Renderer::finalize(const RenderingContext& ctx)
  321. {
  322. ++m_frameCount;
  323. m_prevMatrices = ctx.m_matrices;
  324. // Inform about the HiZ map. Do it as late as possible
  325. if(ctx.m_renderQueue->m_fillCoverageBufferCallback)
  326. {
  327. F32* depthValues;
  328. U32 width;
  329. U32 height;
  330. m_depthDownscale->getClientDepthMapInfo(depthValues, width, height);
  331. ctx.m_renderQueue->m_fillCoverageBufferCallback(ctx.m_renderQueue->m_fillCoverageBufferCallbackUserData,
  332. depthValues, width, height);
  333. }
  334. }
  335. TextureInitInfo Renderer::create2DRenderTargetInitInfo(U32 w, U32 h, Format format, TextureUsageBit usage, CString name)
  336. {
  337. ANKI_ASSERT(!!(usage & TextureUsageBit::kFramebufferWrite) || !!(usage & TextureUsageBit::kImageComputeWrite));
  338. TextureInitInfo init(name);
  339. init.m_width = w;
  340. init.m_height = h;
  341. init.m_depth = 1;
  342. init.m_layerCount = 1;
  343. init.m_type = TextureType::k2D;
  344. init.m_format = format;
  345. init.m_mipmapCount = 1;
  346. init.m_samples = 1;
  347. init.m_usage = usage;
  348. return init;
  349. }
  350. RenderTargetDescription Renderer::create2DRenderTargetDescription(U32 w, U32 h, Format format, CString name)
  351. {
  352. RenderTargetDescription init(name);
  353. init.m_width = w;
  354. init.m_height = h;
  355. init.m_depth = 1;
  356. init.m_layerCount = 1;
  357. init.m_type = TextureType::k2D;
  358. init.m_format = format;
  359. init.m_mipmapCount = 1;
  360. init.m_samples = 1;
  361. init.m_usage = TextureUsageBit::kNone;
  362. return init;
  363. }
  364. TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, TextureUsageBit initialUsage,
  365. const ClearValue& clearVal)
  366. {
  367. ANKI_ASSERT(!!(inf.m_usage & TextureUsageBit::kFramebufferWrite)
  368. || !!(inf.m_usage & TextureUsageBit::kImageComputeWrite));
  369. const U faceCount = (inf.m_type == TextureType::kCube || inf.m_type == TextureType::kCubeArray) ? 6 : 1;
  370. Bool useCompute = false;
  371. if(!!(inf.m_usage & TextureUsageBit::kFramebufferWrite))
  372. {
  373. useCompute = false;
  374. }
  375. else if(!!(inf.m_usage & TextureUsageBit::kImageComputeWrite))
  376. {
  377. useCompute = true;
  378. }
  379. else
  380. {
  381. ANKI_ASSERT(!"Can't handle that");
  382. }
  383. // Create tex
  384. TexturePtr tex = m_gr->newTexture(inf);
  385. // Clear all surfaces
  386. CommandBufferInitInfo cmdbinit;
  387. cmdbinit.m_flags = CommandBufferFlag::GENERAL_WORK;
  388. if((inf.m_mipmapCount * faceCount * inf.m_layerCount * 4) < COMMAND_BUFFER_SMALL_BATCH_MAX_COMMANDS)
  389. {
  390. cmdbinit.m_flags |= CommandBufferFlag::SMALL_BATCH;
  391. }
  392. CommandBufferPtr cmdb = m_gr->newCommandBuffer(cmdbinit);
  393. for(U32 mip = 0; mip < inf.m_mipmapCount; ++mip)
  394. {
  395. for(U32 face = 0; face < faceCount; ++face)
  396. {
  397. for(U32 layer = 0; layer < inf.m_layerCount; ++layer)
  398. {
  399. TextureSurfaceInfo surf(mip, 0, face, layer);
  400. if(!useCompute)
  401. {
  402. FramebufferInitInfo fbInit("RendererClearRT");
  403. Array<TextureUsageBit, MAX_COLOR_ATTACHMENTS> colUsage = {};
  404. TextureUsageBit dsUsage = TextureUsageBit::kNone;
  405. if(getFormatInfo(inf.m_format).isDepthStencil())
  406. {
  407. DepthStencilAspectBit aspect = DepthStencilAspectBit::kNone;
  408. if(getFormatInfo(inf.m_format).isDepth())
  409. {
  410. aspect |= DepthStencilAspectBit::kDepth;
  411. }
  412. if(getFormatInfo(inf.m_format).isStencil())
  413. {
  414. aspect |= DepthStencilAspectBit::kStencil;
  415. }
  416. TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf, aspect));
  417. fbInit.m_depthStencilAttachment.m_textureView = view;
  418. fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::CLEAR;
  419. fbInit.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
  420. fbInit.m_depthStencilAttachment.m_clearValue = clearVal;
  421. dsUsage = TextureUsageBit::kFramebufferWrite;
  422. }
  423. else
  424. {
  425. TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf));
  426. fbInit.m_colorAttachmentCount = 1;
  427. fbInit.m_colorAttachments[0].m_textureView = view;
  428. fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
  429. fbInit.m_colorAttachments[0].m_clearValue = clearVal;
  430. colUsage[0] = TextureUsageBit::kFramebufferWrite;
  431. }
  432. FramebufferPtr fb = m_gr->newFramebuffer(fbInit);
  433. TextureBarrierInfo barrier = {tex.get(), TextureUsageBit::kNone, TextureUsageBit::kFramebufferWrite,
  434. surf};
  435. barrier.m_subresource.m_depthStencilAspect = tex->getDepthStencilAspect();
  436. cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
  437. cmdb->beginRenderPass(fb, colUsage, dsUsage);
  438. cmdb->endRenderPass();
  439. if(!!initialUsage)
  440. {
  441. barrier.m_previousUsage = TextureUsageBit::kFramebufferWrite;
  442. barrier.m_nextUsage = initialUsage;
  443. cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
  444. }
  445. }
  446. else
  447. {
  448. // Compute
  449. ShaderProgramResourceVariantInitInfo variantInitInfo(m_clearTexComputeProg);
  450. variantInitInfo.addMutation("TEXTURE_DIMENSIONS", I32((inf.m_type == TextureType::k3D) ? 3 : 2));
  451. const FormatInfo formatInfo = getFormatInfo(inf.m_format);
  452. I32 componentType = 0;
  453. if(formatInfo.m_shaderType == 0)
  454. {
  455. componentType = 0;
  456. }
  457. else if(formatInfo.m_shaderType == 1)
  458. {
  459. componentType = 1;
  460. }
  461. else
  462. {
  463. ANKI_ASSERT(!"Not supported");
  464. }
  465. variantInitInfo.addMutation("COMPONENT_TYPE", componentType);
  466. const ShaderProgramResourceVariant* variant;
  467. m_clearTexComputeProg->getOrCreateVariant(variantInitInfo, variant);
  468. cmdb->bindShaderProgram(variant->getProgram());
  469. cmdb->setPushConstants(&clearVal.m_colorf[0], sizeof(clearVal.m_colorf));
  470. TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf));
  471. cmdb->bindImage(0, 0, view);
  472. const TextureBarrierInfo barrier = {tex.get(), TextureUsageBit::kNone,
  473. TextureUsageBit::kImageComputeWrite, surf};
  474. cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
  475. UVec3 wgSize;
  476. wgSize.x() = (8 - 1 + (tex->getWidth() >> mip)) / 8;
  477. wgSize.y() = (8 - 1 + (tex->getHeight() >> mip)) / 8;
  478. wgSize.z() = (inf.m_type == TextureType::k3D) ? ((8 - 1 + (tex->getDepth() >> mip)) / 8) : 1;
  479. cmdb->dispatchCompute(wgSize.x(), wgSize.y(), wgSize.z());
  480. if(!!initialUsage)
  481. {
  482. const TextureBarrierInfo barrier = {tex.get(), TextureUsageBit::kImageComputeWrite,
  483. initialUsage, surf};
  484. cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
  485. }
  486. }
  487. }
  488. }
  489. }
  490. cmdb->flush();
  491. return tex;
  492. }
  493. void Renderer::registerDebugRenderTarget(RendererObject* obj, CString rtName)
  494. {
  495. #if ANKI_ENABLE_ASSERTIONS
  496. for(const DebugRtInfo& inf : m_debugRts)
  497. {
  498. ANKI_ASSERT(inf.m_rtName != rtName && "Choose different name");
  499. }
  500. #endif
  501. ANKI_ASSERT(obj);
  502. DebugRtInfo inf;
  503. inf.m_obj = obj;
  504. inf.m_rtName.create(getAllocator(), rtName);
  505. m_debugRts.emplaceBack(getAllocator(), std::move(inf));
  506. }
  507. Bool Renderer::getCurrentDebugRenderTarget(Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
  508. ShaderProgramPtr& optionalShaderProgram)
  509. {
  510. if(ANKI_LIKELY(m_currentDebugRtName.isEmpty()))
  511. {
  512. return false;
  513. }
  514. RendererObject* obj = nullptr;
  515. for(const DebugRtInfo& inf : m_debugRts)
  516. {
  517. if(inf.m_rtName == m_currentDebugRtName)
  518. {
  519. obj = inf.m_obj;
  520. }
  521. }
  522. ANKI_ASSERT(obj);
  523. obj->getDebugRenderTarget(m_currentDebugRtName, handles, optionalShaderProgram);
  524. return true;
  525. }
  526. void Renderer::setCurrentDebugRenderTarget(CString rtName)
  527. {
  528. m_currentDebugRtName.destroy(getAllocator());
  529. if(!rtName.isEmpty() && rtName.getLength() > 0)
  530. {
  531. m_currentDebugRtName.create(getAllocator(), rtName);
  532. }
  533. }
  534. Format Renderer::getHdrFormat() const
  535. {
  536. Format out;
  537. if(!m_config->getRHighQualityHdr())
  538. {
  539. out = Format::kB10G11R11_Ufloat_Pack32;
  540. }
  541. else if(m_gr->getDeviceCapabilities().m_unalignedBbpTextureFormats)
  542. {
  543. out = Format::kR16G16B16_Sfloat;
  544. }
  545. else
  546. {
  547. out = Format::kR16G16B16A16_Sfloat;
  548. }
  549. return out;
  550. }
  551. Format Renderer::getDepthNoStencilFormat() const
  552. {
  553. if(ANKI_PLATFORM_MOBILE)
  554. {
  555. return Format::kX8_D24_Unorm_Pack32;
  556. }
  557. else
  558. {
  559. return Format::kD32_Sfloat;
  560. }
  561. }
  562. } // end namespace anki