Renderer.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  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. #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/Ssr.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. namespace anki {
  43. Renderer::Renderer()
  44. : m_sceneDrawer(this)
  45. {
  46. }
  47. Renderer::~Renderer()
  48. {
  49. for(DebugRtInfo& info : m_debugRts)
  50. {
  51. info.m_rtName.destroy(getAllocator());
  52. }
  53. m_debugRts.destroy(getAllocator());
  54. m_currentDebugRtName.destroy(getAllocator());
  55. }
  56. Error Renderer::init(ThreadHive* hive, ResourceManager* resources, GrManager* gl, StagingGpuMemoryManager* stagingMem,
  57. UiManager* ui, HeapAllocator<U8> alloc, const ConfigSet& config, Timestamp* globTimestamp)
  58. {
  59. ANKI_TRACE_SCOPED_EVENT(R_INIT);
  60. m_globTimestamp = globTimestamp;
  61. m_threadHive = hive;
  62. m_resources = resources;
  63. m_gr = gl;
  64. m_stagingMem = stagingMem;
  65. m_ui = ui;
  66. m_alloc = alloc;
  67. Error err = initInternal(config);
  68. if(err)
  69. {
  70. ANKI_R_LOGE("Failed to initialize the renderer");
  71. }
  72. return err;
  73. }
  74. Error Renderer::initInternal(const ConfigSet& config)
  75. {
  76. m_frameCount = 0;
  77. // Set from the config
  78. const F32 renderScaling = config.getNumberF32("r_renderScaling");
  79. const F32 internalRenderScaling = min(config.getNumberF32("r_internalRenderScaling"), renderScaling);
  80. const Vec2 fresolution = Vec2(F32(config.getNumberU32("width")), F32(config.getNumberU32("height")));
  81. m_postProcessResolution = UVec2(fresolution * renderScaling);
  82. alignRoundDown(2, m_postProcessResolution.x());
  83. alignRoundDown(2, m_postProcessResolution.y());
  84. m_internalResolution = UVec2(fresolution * internalRenderScaling);
  85. alignRoundDown(2, m_internalResolution.x());
  86. alignRoundDown(2, m_internalResolution.y());
  87. ANKI_R_LOGI("Initializing offscreen renderer. Size %ux%u. Internal size %ux%u", m_postProcessResolution.x(),
  88. m_postProcessResolution.y(), m_internalResolution.x(), m_internalResolution.y());
  89. m_tileSize = config.getNumberU32("r_tileSize");
  90. m_tileCounts.x() = (m_internalResolution.x() + m_tileSize - 1) / m_tileSize;
  91. m_tileCounts.y() = (m_internalResolution.y() + m_tileSize - 1) / m_tileSize;
  92. m_zSplitCount = config.getNumberU32("r_zSplitCount");
  93. // A few sanity checks
  94. if(m_internalResolution.x() < 64 || m_internalResolution.y() < 64)
  95. {
  96. ANKI_R_LOGE("Incorrect sizes");
  97. return Error::USER_DATA;
  98. }
  99. {
  100. TextureInitInfo texinit("RendererDummy");
  101. texinit.m_width = texinit.m_height = 4;
  102. texinit.m_usage = TextureUsageBit::ALL_SAMPLED;
  103. texinit.m_format = Format::R8G8B8A8_UNORM;
  104. texinit.m_initialUsage = TextureUsageBit::ALL_SAMPLED;
  105. TexturePtr tex = getGrManager().newTexture(texinit);
  106. TextureViewInitInfo viewinit(tex);
  107. m_dummyTexView2d = getGrManager().newTextureView(viewinit);
  108. texinit.m_depth = 4;
  109. texinit.m_type = TextureType::_3D;
  110. tex = getGrManager().newTexture(texinit);
  111. viewinit = TextureViewInitInfo(tex);
  112. m_dummyTexView3d = getGrManager().newTextureView(viewinit);
  113. }
  114. m_dummyBuff = getGrManager().newBuffer(BufferInitInfo(
  115. 1024, BufferUsageBit::ALL_UNIFORM | BufferUsageBit::ALL_STORAGE, BufferMapAccessBit::NONE, "Dummy"));
  116. ANKI_CHECK(m_resources->loadResource("Shaders/ClearTextureCompute.ankiprog", m_clearTexComputeProg));
  117. // Init the stages. Careful with the order!!!!!!!!!!
  118. m_genericCompute.reset(m_alloc.newInstance<GenericCompute>(this));
  119. ANKI_CHECK(m_genericCompute->init(config));
  120. m_volumetricLightingAccumulation.reset(m_alloc.newInstance<VolumetricLightingAccumulation>(this));
  121. ANKI_CHECK(m_volumetricLightingAccumulation->init(config));
  122. m_indirectDiffuseProbes.reset(m_alloc.newInstance<IndirectDiffuseProbes>(this));
  123. ANKI_CHECK(m_indirectDiffuseProbes->init(config));
  124. m_probeReflections.reset(m_alloc.newInstance<ProbeReflections>(this));
  125. ANKI_CHECK(m_probeReflections->init(config));
  126. m_gbuffer.reset(m_alloc.newInstance<GBuffer>(this));
  127. ANKI_CHECK(m_gbuffer->init(config));
  128. m_gbufferPost.reset(m_alloc.newInstance<GBufferPost>(this));
  129. ANKI_CHECK(m_gbufferPost->init(config));
  130. m_shadowMapping.reset(m_alloc.newInstance<ShadowMapping>(this));
  131. ANKI_CHECK(m_shadowMapping->init(config));
  132. m_volumetricFog.reset(m_alloc.newInstance<VolumetricFog>(this));
  133. ANKI_CHECK(m_volumetricFog->init(config));
  134. m_lightShading.reset(m_alloc.newInstance<LightShading>(this));
  135. ANKI_CHECK(m_lightShading->init(config));
  136. m_depthDownscale.reset(m_alloc.newInstance<DepthDownscale>(this));
  137. ANKI_CHECK(m_depthDownscale->init(config));
  138. m_forwardShading.reset(m_alloc.newInstance<ForwardShading>(this));
  139. ANKI_CHECK(m_forwardShading->init(config));
  140. m_lensFlare.reset(m_alloc.newInstance<LensFlare>(this));
  141. ANKI_CHECK(m_lensFlare->init(config));
  142. m_downscaleBlur.reset(getAllocator().newInstance<DownscaleBlur>(this));
  143. ANKI_CHECK(m_downscaleBlur->init(config));
  144. m_ssr.reset(m_alloc.newInstance<Ssr>(this));
  145. ANKI_CHECK(m_ssr->init(config));
  146. m_tonemapping.reset(getAllocator().newInstance<Tonemapping>(this));
  147. ANKI_CHECK(m_tonemapping->init(config));
  148. m_temporalAA.reset(getAllocator().newInstance<TemporalAA>(this));
  149. ANKI_CHECK(m_temporalAA->init(config));
  150. m_bloom.reset(m_alloc.newInstance<Bloom>(this));
  151. ANKI_CHECK(m_bloom->init(config));
  152. m_finalComposite.reset(m_alloc.newInstance<FinalComposite>(this));
  153. ANKI_CHECK(m_finalComposite->init(config));
  154. m_dbg.reset(m_alloc.newInstance<Dbg>(this));
  155. ANKI_CHECK(m_dbg->init(config));
  156. m_uiStage.reset(m_alloc.newInstance<UiStage>(this));
  157. ANKI_CHECK(m_uiStage->init(config));
  158. m_scale.reset(m_alloc.newInstance<Scale>(this));
  159. ANKI_CHECK(m_scale->init(config));
  160. m_indirectDiffuse.reset(m_alloc.newInstance<IndirectDiffuse>(this));
  161. ANKI_CHECK(m_indirectDiffuse->init(config));
  162. if(getGrManager().getDeviceCapabilities().m_rayTracingEnabled && config.getBool("scene_rayTracedShadows"))
  163. {
  164. m_accelerationStructureBuilder.reset(m_alloc.newInstance<AccelerationStructureBuilder>(this));
  165. ANKI_CHECK(m_accelerationStructureBuilder->init(config));
  166. m_rtShadows.reset(m_alloc.newInstance<RtShadows>(this));
  167. ANKI_CHECK(m_rtShadows->init(config));
  168. }
  169. else
  170. {
  171. m_shadowmapsResolve.reset(m_alloc.newInstance<ShadowmapsResolve>(this));
  172. ANKI_CHECK(m_shadowmapsResolve->init(config));
  173. }
  174. m_motionVectors.reset(m_alloc.newInstance<MotionVectors>(this));
  175. ANKI_CHECK(m_motionVectors->init(config));
  176. m_clusterBinning.reset(m_alloc.newInstance<ClusterBinning>(this));
  177. ANKI_CHECK(m_clusterBinning->init(config));
  178. // Init samplers
  179. {
  180. SamplerInitInfo sinit("Renderer");
  181. sinit.m_addressing = SamplingAddressing::CLAMP;
  182. sinit.m_mipmapFilter = SamplingFilter::NEAREST;
  183. sinit.m_minMagFilter = SamplingFilter::NEAREST;
  184. m_samplers.m_nearestNearestClamp = m_gr->newSampler(sinit);
  185. sinit.m_minMagFilter = SamplingFilter::LINEAR;
  186. sinit.m_mipmapFilter = SamplingFilter::LINEAR;
  187. m_samplers.m_trilinearClamp = m_gr->newSampler(sinit);
  188. sinit.m_addressing = SamplingAddressing::REPEAT;
  189. m_samplers.m_trilinearRepeat = m_gr->newSampler(sinit);
  190. sinit.m_anisotropyLevel = U8(config.getNumberU32("r_textureAnisotropy"));
  191. m_samplers.m_trilinearRepeatAniso = m_gr->newSampler(sinit);
  192. const F32 scalingMipBias = log2(F32(m_internalResolution.x()) / F32(m_postProcessResolution.x()));
  193. sinit.m_lodBias = scalingMipBias;
  194. m_samplers.m_trilinearRepeatAnisoResolutionScalingBias = m_gr->newSampler(sinit);
  195. }
  196. initJitteredMats();
  197. return Error::NONE;
  198. }
  199. void Renderer::initJitteredMats()
  200. {
  201. static const Array<Vec2, 16> SAMPLE_LOCS_16 = {
  202. {Vec2(-8.0, 0.0), Vec2(-6.0, -4.0), Vec2(-3.0, -2.0), Vec2(-2.0, -6.0), Vec2(1.0, -1.0), Vec2(2.0, -5.0),
  203. Vec2(6.0, -7.0), Vec2(5.0, -3.0), Vec2(4.0, 1.0), Vec2(7.0, 4.0), Vec2(3.0, 5.0), Vec2(0.0, 7.0),
  204. Vec2(-1.0, 3.0), Vec2(-4.0, 6.0), Vec2(-7.0, 8.0), Vec2(-5.0, 2.0)}};
  205. for(U i = 0; i < 16; ++i)
  206. {
  207. Vec2 texSize(1.0f / Vec2(F32(m_internalResolution.x()), F32(m_internalResolution.y()))); // Texel size
  208. texSize *= 2.0f; // Move it to NDC
  209. Vec2 S = SAMPLE_LOCS_16[i] / 8.0f; // In [-1, 1]
  210. Vec2 subSample = S * texSize; // In [-texSize, texSize]
  211. subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
  212. m_jitteredMats16x[i] = Mat4::getIdentity();
  213. m_jitteredMats16x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
  214. }
  215. static const Array<Vec2, 8> SAMPLE_LOCS_8 = {Vec2(-7.0, 1.0), Vec2(-5.0, -5.0), Vec2(-1.0, -3.0), Vec2(3.0, -7.0),
  216. Vec2(5.0, -1.0), Vec2(7.0, 7.0), Vec2(1.0, 3.0), Vec2(-3.0, 5.0)};
  217. for(U i = 0; i < 8; ++i)
  218. {
  219. Vec2 texSize(1.0f / Vec2(F32(m_internalResolution.x()), F32(m_internalResolution.y()))); // Texel size
  220. texSize *= 2.0f; // Move it to NDC
  221. Vec2 S = SAMPLE_LOCS_8[i] / 8.0f; // In [-1, 1]
  222. Vec2 subSample = S * texSize; // In [-texSize, texSize]
  223. subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
  224. m_jitteredMats8x[i] = Mat4::getIdentity();
  225. m_jitteredMats8x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
  226. }
  227. }
  228. Error Renderer::populateRenderGraph(RenderingContext& ctx)
  229. {
  230. ctx.m_prevMatrices = m_prevMatrices;
  231. ctx.m_matrices.m_cameraTransform = ctx.m_renderQueue->m_cameraTransform;
  232. ctx.m_matrices.m_view = ctx.m_renderQueue->m_viewMatrix;
  233. ctx.m_matrices.m_projection = ctx.m_renderQueue->m_projectionMatrix;
  234. ctx.m_matrices.m_viewProjection = ctx.m_renderQueue->m_viewProjectionMatrix;
  235. ctx.m_matrices.m_viewRotation = ctx.m_renderQueue->m_viewMatrix.getRotationPart();
  236. ctx.m_matrices.m_jitter = m_jitteredMats8x[m_frameCount & (m_jitteredMats8x.getSize() - 1)];
  237. ctx.m_matrices.m_projectionJitter = ctx.m_matrices.m_jitter * ctx.m_matrices.m_projection;
  238. ctx.m_matrices.m_viewProjectionJitter = ctx.m_matrices.m_projectionJitter * ctx.m_matrices.m_view;
  239. ctx.m_matrices.m_invertedViewProjectionJitter = ctx.m_matrices.m_viewProjectionJitter.getInverse();
  240. ctx.m_matrices.m_invertedViewProjection = ctx.m_matrices.m_viewProjection.getInverse();
  241. ctx.m_matrices.m_invertedProjectionJitter = ctx.m_matrices.m_projectionJitter.getInverse();
  242. ctx.m_matrices.m_invertedView = ctx.m_matrices.m_view.getInverse();
  243. ctx.m_matrices.m_reprojection =
  244. ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_invertedViewProjectionJitter;
  245. ctx.m_matrices.m_unprojectionParameters = ctx.m_matrices.m_projection.extractPerspectiveUnprojectionParams();
  246. // Check if resources got loaded
  247. if(m_prevLoadRequestCount != m_resources->getLoadingRequestCount()
  248. || m_prevAsyncTasksCompleted != m_resources->getAsyncTaskCompletedCount())
  249. {
  250. m_prevLoadRequestCount = m_resources->getLoadingRequestCount();
  251. m_prevAsyncTasksCompleted = m_resources->getAsyncTaskCompletedCount();
  252. m_resourcesDirty = true;
  253. }
  254. else
  255. {
  256. m_resourcesDirty = false;
  257. }
  258. // Import RTs first
  259. m_downscaleBlur->importRenderTargets(ctx);
  260. m_tonemapping->importRenderTargets(ctx);
  261. m_depthDownscale->importRenderTargets(ctx);
  262. // Populate render graph. WARNING Watch the order
  263. m_genericCompute->populateRenderGraph(ctx);
  264. m_clusterBinning->populateRenderGraph(ctx);
  265. if(m_accelerationStructureBuilder)
  266. {
  267. m_accelerationStructureBuilder->populateRenderGraph(ctx);
  268. }
  269. m_shadowMapping->populateRenderGraph(ctx);
  270. m_indirectDiffuseProbes->populateRenderGraph(ctx);
  271. m_probeReflections->populateRenderGraph(ctx);
  272. m_volumetricLightingAccumulation->populateRenderGraph(ctx);
  273. m_gbuffer->populateRenderGraph(ctx);
  274. m_motionVectors->populateRenderGraph(ctx);
  275. m_gbufferPost->populateRenderGraph(ctx);
  276. m_depthDownscale->populateRenderGraph(ctx);
  277. if(m_rtShadows)
  278. {
  279. m_rtShadows->populateRenderGraph(ctx);
  280. }
  281. else
  282. {
  283. m_shadowmapsResolve->populateRenderGraph(ctx);
  284. }
  285. m_volumetricFog->populateRenderGraph(ctx);
  286. m_lensFlare->populateRenderGraph(ctx);
  287. m_ssr->populateRenderGraph(ctx);
  288. m_indirectDiffuse->populateRenderGraph(ctx);
  289. m_lightShading->populateRenderGraph(ctx);
  290. m_temporalAA->populateRenderGraph(ctx);
  291. m_scale->populateRenderGraph(ctx);
  292. m_downscaleBlur->populateRenderGraph(ctx);
  293. m_tonemapping->populateRenderGraph(ctx);
  294. m_bloom->populateRenderGraph(ctx);
  295. if(m_dbg->getEnabled())
  296. {
  297. m_dbg->populateRenderGraph(ctx);
  298. }
  299. m_finalComposite->populateRenderGraph(ctx);
  300. // Populate the uniforms
  301. m_clusterBinning->writeClusterBuffersAsync();
  302. return Error::NONE;
  303. }
  304. void Renderer::finalize(const RenderingContext& ctx)
  305. {
  306. ++m_frameCount;
  307. m_prevMatrices = ctx.m_matrices;
  308. // Inform about the HiZ map. Do it as late as possible
  309. if(ctx.m_renderQueue->m_fillCoverageBufferCallback)
  310. {
  311. F32* depthValues;
  312. U32 width;
  313. U32 height;
  314. m_depthDownscale->getClientDepthMapInfo(depthValues, width, height);
  315. ctx.m_renderQueue->m_fillCoverageBufferCallback(ctx.m_renderQueue->m_fillCoverageBufferCallbackUserData,
  316. depthValues, width, height);
  317. }
  318. }
  319. TextureInitInfo Renderer::create2DRenderTargetInitInfo(U32 w, U32 h, Format format, TextureUsageBit usage, CString name)
  320. {
  321. ANKI_ASSERT(!!(usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE)
  322. || !!(usage & TextureUsageBit::IMAGE_COMPUTE_WRITE));
  323. TextureInitInfo init(name);
  324. init.m_width = w;
  325. init.m_height = h;
  326. init.m_depth = 1;
  327. init.m_layerCount = 1;
  328. init.m_type = TextureType::_2D;
  329. init.m_format = format;
  330. init.m_mipmapCount = 1;
  331. init.m_samples = 1;
  332. init.m_usage = usage;
  333. return init;
  334. }
  335. RenderTargetDescription Renderer::create2DRenderTargetDescription(U32 w, U32 h, Format format, CString name)
  336. {
  337. RenderTargetDescription init(name);
  338. init.m_width = w;
  339. init.m_height = h;
  340. init.m_depth = 1;
  341. init.m_layerCount = 1;
  342. init.m_type = TextureType::_2D;
  343. init.m_format = format;
  344. init.m_mipmapCount = 1;
  345. init.m_samples = 1;
  346. init.m_usage = TextureUsageBit::NONE;
  347. return init;
  348. }
  349. TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, const ClearValue& clearVal)
  350. {
  351. ANKI_ASSERT(!!(inf.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE)
  352. || !!(inf.m_usage & TextureUsageBit::IMAGE_COMPUTE_WRITE));
  353. const U faceCount = (inf.m_type == TextureType::CUBE || inf.m_type == TextureType::CUBE_ARRAY) ? 6 : 1;
  354. Bool useCompute = false;
  355. if(!!(inf.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE))
  356. {
  357. useCompute = false;
  358. }
  359. else if(!!(inf.m_usage & TextureUsageBit::IMAGE_COMPUTE_WRITE))
  360. {
  361. useCompute = true;
  362. }
  363. else
  364. {
  365. ANKI_ASSERT(!"Can't handle that");
  366. }
  367. // Create tex
  368. TexturePtr tex = m_gr->newTexture(inf);
  369. // Clear all surfaces
  370. CommandBufferInitInfo cmdbinit;
  371. cmdbinit.m_flags = CommandBufferFlag::GENERAL_WORK;
  372. if((inf.m_mipmapCount * faceCount * inf.m_layerCount * 4) < COMMAND_BUFFER_SMALL_BATCH_MAX_COMMANDS)
  373. {
  374. cmdbinit.m_flags |= CommandBufferFlag::SMALL_BATCH;
  375. }
  376. CommandBufferPtr cmdb = m_gr->newCommandBuffer(cmdbinit);
  377. for(U32 mip = 0; mip < inf.m_mipmapCount; ++mip)
  378. {
  379. for(U32 face = 0; face < faceCount; ++face)
  380. {
  381. for(U32 layer = 0; layer < inf.m_layerCount; ++layer)
  382. {
  383. TextureSurfaceInfo surf(mip, 0, face, layer);
  384. if(!useCompute)
  385. {
  386. FramebufferInitInfo fbInit("RendererClearRT");
  387. Array<TextureUsageBit, MAX_COLOR_ATTACHMENTS> colUsage = {};
  388. TextureUsageBit dsUsage = TextureUsageBit::NONE;
  389. if(formatIsDepthStencil(inf.m_format))
  390. {
  391. DepthStencilAspectBit aspect = DepthStencilAspectBit::NONE;
  392. if(formatIsDepth(inf.m_format))
  393. {
  394. aspect |= DepthStencilAspectBit::DEPTH;
  395. }
  396. if(formatIsStencil(inf.m_format))
  397. {
  398. aspect |= DepthStencilAspectBit::STENCIL;
  399. }
  400. TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf, aspect));
  401. fbInit.m_depthStencilAttachment.m_textureView = view;
  402. fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::CLEAR;
  403. fbInit.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
  404. fbInit.m_depthStencilAttachment.m_clearValue = clearVal;
  405. dsUsage = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;
  406. }
  407. else
  408. {
  409. TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf));
  410. fbInit.m_colorAttachmentCount = 1;
  411. fbInit.m_colorAttachments[0].m_textureView = view;
  412. fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
  413. fbInit.m_colorAttachments[0].m_clearValue = clearVal;
  414. colUsage[0] = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;
  415. }
  416. FramebufferPtr fb = m_gr->newFramebuffer(fbInit);
  417. cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::NONE,
  418. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, surf);
  419. cmdb->beginRenderPass(fb, colUsage, dsUsage);
  420. cmdb->endRenderPass();
  421. if(!!inf.m_initialUsage)
  422. {
  423. cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
  424. inf.m_initialUsage, surf);
  425. }
  426. }
  427. else
  428. {
  429. // Compute
  430. ShaderProgramResourceVariantInitInfo variantInitInfo(m_clearTexComputeProg);
  431. variantInitInfo.addMutation("TEXTURE_DIMENSIONS", I32((inf.m_type == TextureType::_3D) ? 3 : 2));
  432. const FormatInfo formatInfo = getFormatInfo(inf.m_format);
  433. I32 componentType = 0;
  434. if(formatInfo.m_shaderType == 0)
  435. {
  436. componentType = 0;
  437. }
  438. else if(formatInfo.m_shaderType == 1)
  439. {
  440. componentType = 1;
  441. }
  442. else
  443. {
  444. ANKI_ASSERT(!"Not supported");
  445. }
  446. variantInitInfo.addMutation("COMPONENT_TYPE", componentType);
  447. const ShaderProgramResourceVariant* variant;
  448. m_clearTexComputeProg->getOrCreateVariant(variantInitInfo, variant);
  449. cmdb->bindShaderProgram(variant->getProgram());
  450. cmdb->setPushConstants(&clearVal.m_colorf[0], sizeof(clearVal.m_colorf));
  451. TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf));
  452. cmdb->bindImage(0, 0, view);
  453. cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::NONE, TextureUsageBit::IMAGE_COMPUTE_WRITE,
  454. surf);
  455. UVec3 wgSize;
  456. wgSize.x() = (8 - 1 + (tex->getWidth() >> mip)) / 8;
  457. wgSize.y() = (8 - 1 + (tex->getHeight() >> mip)) / 8;
  458. wgSize.z() = (inf.m_type == TextureType::_3D) ? ((8 - 1 + (tex->getDepth() >> mip)) / 8) : 1;
  459. cmdb->dispatchCompute(wgSize.x(), wgSize.y(), wgSize.z());
  460. if(!!inf.m_initialUsage)
  461. {
  462. cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::IMAGE_COMPUTE_WRITE, inf.m_initialUsage,
  463. surf);
  464. }
  465. }
  466. }
  467. }
  468. }
  469. cmdb->flush();
  470. return tex;
  471. }
  472. void Renderer::registerDebugRenderTarget(RendererObject* obj, CString rtName)
  473. {
  474. #if ANKI_ENABLE_ASSERTIONS
  475. for(const DebugRtInfo& inf : m_debugRts)
  476. {
  477. ANKI_ASSERT(inf.m_rtName != rtName && "Choose different name");
  478. }
  479. #endif
  480. ANKI_ASSERT(obj);
  481. DebugRtInfo inf;
  482. inf.m_obj = obj;
  483. inf.m_rtName.create(getAllocator(), rtName);
  484. m_debugRts.emplaceBack(getAllocator(), std::move(inf));
  485. }
  486. void Renderer::getCurrentDebugRenderTarget(RenderTargetHandle& handle, Bool& handleValid,
  487. ShaderProgramPtr& optionalShaderProgram)
  488. {
  489. if(ANKI_LIKELY(m_currentDebugRtName.isEmpty()))
  490. {
  491. handleValid = false;
  492. return;
  493. }
  494. RendererObject* obj = nullptr;
  495. for(const DebugRtInfo& inf : m_debugRts)
  496. {
  497. if(inf.m_rtName == m_currentDebugRtName)
  498. {
  499. obj = inf.m_obj;
  500. }
  501. }
  502. ANKI_ASSERT(obj);
  503. obj->getDebugRenderTarget(m_currentDebugRtName, handle, optionalShaderProgram);
  504. handleValid = true;
  505. }
  506. void Renderer::setCurrentDebugRenderTarget(CString rtName)
  507. {
  508. m_currentDebugRtName.destroy(getAllocator());
  509. if(!rtName.isEmpty() && rtName.getLength() > 0)
  510. {
  511. m_currentDebugRtName.create(getAllocator(), rtName);
  512. }
  513. }
  514. } // end namespace anki