RendererObject.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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. #include <AnKi/Renderer/RendererObject.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/Sky.h>
  8. #include <AnKi/Util/Enum.h>
  9. #include <AnKi/Util/Tracer.h>
  10. #include <AnKi/GpuMemory/GpuVisibleTransientMemoryPool.h>
  11. #include <AnKi/Scene/Components/SkyboxComponent.h>
  12. #include <AnKi/Renderer/AccelerationStructureBuilder.h>
  13. #include <AnKi/Renderer/ShadowMapping.h>
  14. #include <AnKi/Renderer/GBuffer.h>
  15. namespace anki {
  16. Renderer& RendererObject::getRenderer()
  17. {
  18. return Renderer::getSingleton();
  19. }
  20. void RendererObject::registerDebugRenderTarget(CString rtName)
  21. {
  22. getRenderer().registerDebugRenderTarget(this, rtName);
  23. }
  24. Error RendererObject::loadShaderProgram(CString filename, ConstWeakArray<SubMutation> mutators, ShaderProgramResourcePtr& rsrc,
  25. ShaderProgramPtr& grProg, CString technique, ShaderTypeBit shaderTypes)
  26. {
  27. if(!rsrc.isCreated())
  28. {
  29. ANKI_CHECK(ResourceManager::getSingleton().loadResource(filename, rsrc));
  30. }
  31. ShaderProgramResourceVariantInitInfo initInf(rsrc);
  32. for(SubMutation pair : mutators)
  33. {
  34. initInf.addMutation(pair.m_mutatorName, pair.m_value);
  35. }
  36. if(technique.isEmpty())
  37. {
  38. technique = "Unnamed";
  39. }
  40. if(!shaderTypes)
  41. {
  42. U32 techniqueIdx = kMaxU32;
  43. for(U32 i = 0; i < rsrc->getBinary().m_techniques.getSize(); ++i)
  44. {
  45. if(technique == rsrc->getBinary().m_techniques[i].m_name.getBegin())
  46. {
  47. techniqueIdx = i;
  48. break;
  49. }
  50. }
  51. ANKI_ASSERT(techniqueIdx != kMaxU32);
  52. const ShaderTypeBit techniqueShaderTypes = rsrc->getBinary().m_techniques[techniqueIdx].m_shaderTypes;
  53. if(techniqueShaderTypes == (ShaderTypeBit::kCompute | ShaderTypeBit::kPixel | ShaderTypeBit::kVertex))
  54. {
  55. if(g_cvarRenderPreferCompute)
  56. {
  57. shaderTypes = ShaderTypeBit::kCompute;
  58. }
  59. else
  60. {
  61. shaderTypes = ShaderTypeBit::kPixel | ShaderTypeBit::kVertex;
  62. }
  63. }
  64. else if(techniqueShaderTypes == ShaderTypeBit::kCompute)
  65. {
  66. shaderTypes = techniqueShaderTypes;
  67. }
  68. else if(techniqueShaderTypes == (ShaderTypeBit::kPixel | ShaderTypeBit::kVertex))
  69. {
  70. shaderTypes = techniqueShaderTypes;
  71. }
  72. else
  73. {
  74. ANKI_ASSERT(!"Can't figure out a sensible default");
  75. }
  76. }
  77. initInf.requestTechniqueAndTypes(shaderTypes, technique);
  78. const ShaderProgramResourceVariant* variant;
  79. rsrc->getOrCreateVariant(initInf, variant);
  80. if(variant)
  81. {
  82. grProg.reset(&variant->getProgram());
  83. }
  84. else
  85. {
  86. grProg.reset(nullptr);
  87. }
  88. return Error::kNone;
  89. }
  90. void RendererObject::zeroBuffer(Buffer* buff)
  91. {
  92. CommandBufferInitInfo cmdbInit("Zero buffer");
  93. cmdbInit.m_flags |= CommandBufferFlag::kSmallBatch;
  94. CommandBufferPtr cmdb = GrManager::getSingleton().newCommandBuffer(cmdbInit);
  95. cmdb->zeroBuffer(BufferView(buff));
  96. FencePtr fence;
  97. cmdb->endRecording();
  98. GrManager::getSingleton().submit(cmdb.get(), {}, &fence);
  99. fence->clientWait(16.0_sec);
  100. }
  101. CString RendererObject::generateTempPassName(const Char* fmt, ...)
  102. {
  103. Array<Char, 128> buffer;
  104. va_list args;
  105. va_start(args, fmt);
  106. const I len = vsnprintf(&buffer[0], sizeof(buffer), fmt, args);
  107. va_end(args);
  108. if(len > 0 && len < I(sizeof(buffer)))
  109. {
  110. Char* str = static_cast<Char*>(getRenderer().getFrameMemoryPool().allocate(len + 1, 1));
  111. memcpy(str, buffer.getBegin(), len + 1);
  112. return str;
  113. }
  114. else
  115. {
  116. ANKI_R_LOGE("generateTempPassName() failed. Ignoring error");
  117. return "**failed**";
  118. }
  119. }
  120. void RendererObject::fillBuffers(CommandBuffer& cmdb, ConstWeakArray<BufferView> buffers, U32 value)
  121. {
  122. ANKI_ASSERT(buffers.getSize() > 0);
  123. cmdb.pushDebugMarker("fillBuffers", Vec3(1.0, 1.0, 0.0));
  124. cmdb.bindShaderProgram(&getRenderer().getFillBufferProgram());
  125. for(const BufferView& view : buffers)
  126. {
  127. cmdb.bindUav(0, 0, BufferView(&view.getBuffer()));
  128. ANKI_ASSERT(view.getOffset() % sizeof(U32) == 0);
  129. ANKI_ASSERT(view.getRange() % sizeof(U32) == 0);
  130. const UVec4 consts(value, U32(view.getOffset() / sizeof(U32)), U32(view.getRange() / sizeof(U32)), 0);
  131. cmdb.setFastConstants(&consts, sizeof(consts));
  132. ANKI_ASSERT(view.getRange() % sizeof(U32) == 0);
  133. const U32 elementCount = U32(view.getRange() / sizeof(U32));
  134. cmdb.dispatchCompute((elementCount + 63) / 64, 1, 1);
  135. }
  136. cmdb.popDebugMarker();
  137. }
  138. Error RtMaterialFetchRendererObject::init()
  139. {
  140. ANKI_CHECK(loadShaderProgram("ShaderBinaries/RtSbtBuild.ankiprogbin", {{"TECHNIQUE", 1}}, m_sbtBuildProg, m_sbtBuildGrProg, "Build"));
  141. ANKI_CHECK(
  142. loadShaderProgram("ShaderBinaries/RtSbtBuild.ankiprogbin", {{"TECHNIQUE", 1}}, m_sbtBuildProg, m_sbtPatchGrProg, "PatchRaygenAndMiss"));
  143. return Error::kNone;
  144. }
  145. void RtMaterialFetchRendererObject::buildShaderBindingTablePass(CString passName, ShaderProgram* library, U32 raygenHandleIdx, U32 missHandleIdx,
  146. U32 sbtRecordSize, RenderGraphBuilder& rgraph, BufferHandle& sbtHandle,
  147. BufferView& sbtBuffer)
  148. {
  149. AccelerationStructureVisibilityInfo asVis;
  150. GpuVisibilityLocalLightsOutput lightVis;
  151. getAccelerationStructureBuilder().getVisibilityInfo(asVis, lightVis);
  152. // Allocate SBT
  153. U32 sbtAlignment = (GrManager::getSingleton().getDeviceCapabilities().m_structuredBufferNaturalAlignment)
  154. ? sizeof(U32)
  155. : GrManager::getSingleton().getDeviceCapabilities().m_structuredBufferBindOffsetAlignment;
  156. sbtAlignment = computeCompoundAlignment(sbtAlignment, GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment);
  157. sbtBuffer = GpuVisibleTransientMemoryPool::getSingleton().allocate(
  158. (GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount() + 2) * sbtRecordSize, sbtAlignment);
  159. sbtHandle = rgraph.importBuffer(sbtBuffer, BufferUsageBit::kNone);
  160. // Create the pass
  161. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass(passName);
  162. rpass.newBufferDependency(asVis.m_depedency, BufferUsageBit::kIndirectCompute | BufferUsageBit::kSrvCompute);
  163. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kUavCompute);
  164. rpass.setWork([this, buildSbtIndirectArgsBuff = asVis.m_buildSbtIndirectArgsBuffer, sbtBuffer,
  165. visibleRenderableIndicesBuff = asVis.m_visibleRenderablesBuffer, lib = ShaderProgramPtr(library), sbtRecordSize, raygenHandleIdx,
  166. missHandleIdx](RenderPassWorkContext& rgraphCtx) {
  167. ANKI_TRACE_SCOPED_EVENT(btBuild);
  168. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  169. cmdb.bindShaderProgram(m_sbtBuildGrProg.get());
  170. cmdb.bindSrv(0, 0, GpuSceneArrays::Renderable::getSingleton().getBufferView());
  171. cmdb.bindSrv(1, 0, visibleRenderableIndicesBuff);
  172. cmdb.bindSrv(2, 0, BufferView(&lib->getShaderGroupHandlesGpuBuffer()));
  173. cmdb.bindUav(0, 0, sbtBuffer);
  174. RtShadowsSbtBuildConstants consts = {};
  175. ANKI_ASSERT(sbtRecordSize % 4 == 0);
  176. consts.m_sbtRecordDwordSize = sbtRecordSize / 4;
  177. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  178. ANKI_ASSERT(shaderHandleSize % 4 == 0);
  179. consts.m_shaderHandleDwordSize = shaderHandleSize / 4;
  180. consts.m_raygenHandleIndex = raygenHandleIdx;
  181. consts.m_missHandleIndex = missHandleIdx;
  182. cmdb.setFastConstants(&consts, sizeof(consts));
  183. cmdb.dispatchComputeIndirect(buildSbtIndirectArgsBuff);
  184. });
  185. }
  186. void RtMaterialFetchRendererObject::patchShaderBindingTablePass(CString passName, ShaderProgram* library, U32 raygenHandleIdx, U32 missHandleIdx,
  187. U32 sbtRecordSize, RenderGraphBuilder& rgraph, BufferHandle sbtHandle,
  188. BufferView sbtBuffer)
  189. {
  190. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass(passName);
  191. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kUavCompute);
  192. rpass.setWork(
  193. [this, sbtBuffer, lib = ShaderProgramPtr(library), sbtRecordSize, raygenHandleIdx, missHandleIdx](RenderPassWorkContext& rgraphCtx) {
  194. ANKI_TRACE_SCOPED_EVENT(btBuild);
  195. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  196. cmdb.bindShaderProgram(m_sbtPatchGrProg.get());
  197. cmdb.bindSrv(0, 0, BufferView(&lib->getShaderGroupHandlesGpuBuffer()));
  198. cmdb.bindUav(0, 0, sbtBuffer);
  199. RtShadowsSbtBuildConstants consts = {};
  200. ANKI_ASSERT(sbtRecordSize % 4 == 0);
  201. consts.m_sbtRecordDwordSize = sbtRecordSize / 4;
  202. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  203. ANKI_ASSERT(shaderHandleSize % 4 == 0);
  204. consts.m_shaderHandleDwordSize = shaderHandleSize / 4;
  205. consts.m_raygenHandleIndex = raygenHandleIdx;
  206. consts.m_missHandleIndex = missHandleIdx;
  207. cmdb.setFastConstants(&consts, sizeof(consts));
  208. cmdb.dispatchCompute(1, 1, 1);
  209. });
  210. }
  211. void RtMaterialFetchRendererObject::setRgenSpace2Dependencies(RenderPassBase& pass, Bool isComputeDispatch)
  212. {
  213. const TextureUsageBit srvTexUsage = (isComputeDispatch) ? TextureUsageBit::kSrvCompute : TextureUsageBit::kSrvDispatchRays;
  214. const BufferUsageBit srvBuffUsage = (isComputeDispatch) ? BufferUsageBit::kSrvCompute : BufferUsageBit::kSrvDispatchRays;
  215. const AccelerationStructureUsageBit srvAsUsage =
  216. (isComputeDispatch) ? AccelerationStructureUsageBit::kSrvCompute : AccelerationStructureUsageBit::kSrvDispatchRays;
  217. pass.newAccelerationStructureDependency(getAccelerationStructureBuilder().getAccelerationStructureHandle(), srvAsUsage);
  218. if(getGeneratedSky().isEnabled())
  219. {
  220. pass.newTextureDependency(getGeneratedSky().getEnvironmentMapRt(), srvTexUsage);
  221. }
  222. pass.newTextureDependency(getShadowMapping().getShadowmapRt(), srvTexUsage);
  223. pass.newTextureDependency(getGBuffer().getDepthRt(), srvTexUsage);
  224. pass.newTextureDependency(getGBuffer().getColorRt(1), srvTexUsage);
  225. pass.newTextureDependency(getGBuffer().getColorRt(2), srvTexUsage);
  226. {
  227. AccelerationStructureVisibilityInfo asVis;
  228. GpuVisibilityLocalLightsOutput lightVis;
  229. getAccelerationStructureBuilder().getVisibilityInfo(asVis, lightVis);
  230. pass.newBufferDependency(lightVis.m_dependency, srvBuffUsage);
  231. }
  232. }
  233. void RtMaterialFetchRendererObject::bindRgenSpace2Resources(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
  234. {
  235. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  236. const U32 space = 2;
  237. U32 srv = 0;
  238. rgraphCtx.bindSrv(srv++, space, getAccelerationStructureBuilder().getAccelerationStructureHandle());
  239. const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
  240. const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
  241. const Bool bSkySolidColor =
  242. (!sky || sky->getSkyboxType() == SkyboxType::kSolidColor || (!dirLight && sky->getSkyboxType() == SkyboxType::kGenerated));
  243. if(bSkySolidColor)
  244. {
  245. cmdb.bindSrv(srv++, space, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  246. }
  247. else if(sky->getSkyboxType() == SkyboxType::kImage2D)
  248. {
  249. cmdb.bindSrv(srv++, space, TextureView(&sky->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  250. }
  251. else
  252. {
  253. rgraphCtx.bindSrv(srv++, space, getGeneratedSky().getEnvironmentMapRt());
  254. }
  255. rgraphCtx.bindSrv(srv++, space, getShadowMapping().getShadowmapRt());
  256. const auto& arr = GpuSceneArrays::GlobalIlluminationProbe::getSingleton();
  257. cmdb.bindSrv(srv++, space,
  258. (arr.getElementCount()) ? arr.getBufferView() : BufferView(getDummyGpuResources().m_buffer.get(), 0, arr.getElementSize()));
  259. rgraphCtx.bindSrv(srv++, space, getGBuffer().getDepthRt());
  260. rgraphCtx.bindSrv(srv++, space, getGBuffer().getColorRt(1));
  261. rgraphCtx.bindSrv(srv++, space, getGBuffer().getColorRt(2));
  262. // Someone else will have to bind comething if they use it
  263. cmdb.bindSrv(srv++, space, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(PixelFailedSsr)));
  264. {
  265. AccelerationStructureVisibilityInfo asVis;
  266. GpuVisibilityLocalLightsOutput lightVis;
  267. getAccelerationStructureBuilder().getVisibilityInfo(asVis, lightVis);
  268. const auto& arr = GpuSceneArrays::Light::getSingleton();
  269. cmdb.bindSrv(srv++, space,
  270. (arr.getElementCount()) ? arr.getBufferView() : BufferView(getDummyGpuResources().m_buffer.get(), 0, arr.getElementSize()));
  271. cmdb.bindSrv(srv++, space, lightVis.m_lightIndexCountsPerCellBuffer);
  272. cmdb.bindSrv(srv++, space, lightVis.m_lightIndexOffsetsPerCellBuffer);
  273. cmdb.bindSrv(srv++, space, lightVis.m_lightIndexListBuffer);
  274. }
  275. cmdb.bindSampler(0, space, getRenderer().getSamplers().m_trilinearClamp.get());
  276. cmdb.bindSampler(1, space, getRenderer().getSamplers().m_trilinearClampShadow.get());
  277. cmdb.bindSampler(2, space, getRenderer().getSamplers().m_trilinearRepeat.get());
  278. cmdb.bindUav(0, space, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
  279. cmdb.bindUav(1, space, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
  280. cmdb.bindConstantBuffer(0, space, ctx.m_globalRenderingConstantsBuffer);
  281. }
  282. } // end namespace anki