RendererObject.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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_preferComputeCVar)
  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. BufferHandle visibilityDep;
  150. BufferView visibleRenderableIndicesBuff, buildSbtIndirectArgsBuff;
  151. getRenderer().getAccelerationStructureBuilder().getVisibilityInfo(visibilityDep, visibleRenderableIndicesBuff, buildSbtIndirectArgsBuff);
  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(visibilityDep, BufferUsageBit::kIndirectCompute | BufferUsageBit::kSrvCompute);
  163. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kUavCompute);
  164. rpass.setWork([this, buildSbtIndirectArgsBuff, sbtBuffer, visibleRenderableIndicesBuff, lib = ShaderProgramPtr(library), sbtRecordSize,
  165. raygenHandleIdx, missHandleIdx](RenderPassWorkContext& rgraphCtx) {
  166. ANKI_TRACE_SCOPED_EVENT(btBuild);
  167. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  168. cmdb.bindShaderProgram(m_sbtBuildGrProg.get());
  169. cmdb.bindSrv(0, 0, GpuSceneArrays::Renderable::getSingleton().getBufferView());
  170. cmdb.bindSrv(1, 0, visibleRenderableIndicesBuff);
  171. cmdb.bindSrv(2, 0, BufferView(&lib->getShaderGroupHandlesGpuBuffer()));
  172. cmdb.bindUav(0, 0, sbtBuffer);
  173. RtShadowsSbtBuildConstants consts = {};
  174. ANKI_ASSERT(sbtRecordSize % 4 == 0);
  175. consts.m_sbtRecordDwordSize = sbtRecordSize / 4;
  176. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  177. ANKI_ASSERT(shaderHandleSize % 4 == 0);
  178. consts.m_shaderHandleDwordSize = shaderHandleSize / 4;
  179. consts.m_raygenHandleIndex = raygenHandleIdx;
  180. consts.m_missHandleIndex = missHandleIdx;
  181. cmdb.setFastConstants(&consts, sizeof(consts));
  182. cmdb.dispatchComputeIndirect(buildSbtIndirectArgsBuff);
  183. });
  184. }
  185. void RtMaterialFetchRendererObject::patchShaderBindingTablePass(CString passName, ShaderProgram* library, U32 raygenHandleIdx, U32 missHandleIdx,
  186. U32 sbtRecordSize, RenderGraphBuilder& rgraph, BufferHandle sbtHandle,
  187. BufferView sbtBuffer)
  188. {
  189. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass(passName);
  190. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kUavCompute);
  191. rpass.setWork(
  192. [this, sbtBuffer, lib = ShaderProgramPtr(library), sbtRecordSize, raygenHandleIdx, missHandleIdx](RenderPassWorkContext& rgraphCtx) {
  193. ANKI_TRACE_SCOPED_EVENT(btBuild);
  194. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  195. cmdb.bindShaderProgram(m_sbtPatchGrProg.get());
  196. cmdb.bindSrv(0, 0, BufferView(&lib->getShaderGroupHandlesGpuBuffer()));
  197. cmdb.bindUav(0, 0, sbtBuffer);
  198. RtShadowsSbtBuildConstants consts = {};
  199. ANKI_ASSERT(sbtRecordSize % 4 == 0);
  200. consts.m_sbtRecordDwordSize = sbtRecordSize / 4;
  201. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  202. ANKI_ASSERT(shaderHandleSize % 4 == 0);
  203. consts.m_shaderHandleDwordSize = shaderHandleSize / 4;
  204. consts.m_raygenHandleIndex = raygenHandleIdx;
  205. consts.m_missHandleIndex = missHandleIdx;
  206. cmdb.setFastConstants(&consts, sizeof(consts));
  207. cmdb.dispatchCompute(1, 1, 1);
  208. });
  209. }
  210. void RtMaterialFetchRendererObject::setRgenSpace2Dependencies(RenderPassBase& pass)
  211. {
  212. pass.newAccelerationStructureDependency(getAccelerationStructureBuilder().getAccelerationStructureHandle(),
  213. AccelerationStructureUsageBit::kSrvDispatchRays);
  214. if(getGeneratedSky().isEnabled())
  215. {
  216. pass.newTextureDependency(getGeneratedSky().getEnvironmentMapRt(), TextureUsageBit::kSrvDispatchRays);
  217. }
  218. pass.newTextureDependency(getShadowMapping().getShadowmapRt(), TextureUsageBit::kSrvDispatchRays);
  219. pass.newTextureDependency(getGBuffer().getDepthRt(), TextureUsageBit::kSrvDispatchRays);
  220. pass.newTextureDependency(getGBuffer().getColorRt(1), TextureUsageBit::kSrvDispatchRays);
  221. pass.newTextureDependency(getGBuffer().getColorRt(2), TextureUsageBit::kSrvDispatchRays);
  222. }
  223. void RtMaterialFetchRendererObject::bindRgenSpace2Resources(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
  224. {
  225. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  226. const U32 space = 2;
  227. U32 srv = 0;
  228. rgraphCtx.bindSrv(srv++, space, getAccelerationStructureBuilder().getAccelerationStructureHandle());
  229. const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
  230. const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
  231. const Bool bSkySolidColor =
  232. (!sky || sky->getSkyboxType() == SkyboxType::kSolidColor || (!dirLight && sky->getSkyboxType() == SkyboxType::kGenerated));
  233. if(bSkySolidColor)
  234. {
  235. cmdb.bindSrv(srv++, space, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  236. }
  237. else if(sky->getSkyboxType() == SkyboxType::kImage2D)
  238. {
  239. cmdb.bindSrv(srv++, space, TextureView(&sky->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  240. }
  241. else
  242. {
  243. rgraphCtx.bindSrv(srv++, space, getGeneratedSky().getEnvironmentMapRt());
  244. }
  245. rgraphCtx.bindSrv(srv++, space, getShadowMapping().getShadowmapRt());
  246. const auto& arr = GpuSceneArrays::GlobalIlluminationProbe::getSingleton();
  247. cmdb.bindSrv(srv++, space,
  248. (arr.getElementCount()) ? arr.getBufferView() : BufferView(getDummyGpuResources().m_buffer.get(), 0, arr.getElementSize()));
  249. rgraphCtx.bindSrv(srv++, space, getGBuffer().getDepthRt());
  250. rgraphCtx.bindSrv(srv++, space, getGBuffer().getColorRt(1));
  251. rgraphCtx.bindSrv(srv++, space, getGBuffer().getColorRt(2));
  252. // Someone else will have to bind comething if they use it
  253. cmdb.bindSrv(srv++, space, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(PixelFailedSsr)));
  254. cmdb.bindSampler(0, space, getRenderer().getSamplers().m_trilinearClamp.get());
  255. cmdb.bindSampler(1, space, getRenderer().getSamplers().m_trilinearClampShadow.get());
  256. cmdb.bindSampler(2, space, getRenderer().getSamplers().m_trilinearRepeat.get());
  257. cmdb.bindUav(0, space, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
  258. cmdb.bindUav(1, space, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
  259. cmdb.bindConstantBuffer(0, space, ctx.m_globalRenderingConstantsBuffer);
  260. }
  261. } // end namespace anki