VkCommandBuffer.cpp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300
  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/Gr/Vulkan/VkCommandBuffer.h>
  6. #include <AnKi/Gr/Vulkan/VkGrManager.h>
  7. #include <AnKi/Gr/AccelerationStructure.h>
  8. #include <AnKi/Gr/Vulkan/VkFence.h>
  9. #include <AnKi/Gr/Vulkan/VkGrUpscaler.h>
  10. #include <AnKi/Gr/Vulkan/VkOcclusionQuery.h>
  11. #include <AnKi/Gr/Vulkan/VkTimestampQuery.h>
  12. #include <AnKi/Gr/Vulkan/VkSampler.h>
  13. #include <AnKi/Gr/Vulkan/VkAccelerationStructure.h>
  14. #include <AnKi/Gr/Vulkan/VkShaderProgram.h>
  15. #if ANKI_DLSS
  16. # include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx.h>
  17. # include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers.h>
  18. # include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_vk.h>
  19. # include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers_vk.h>
  20. #endif
  21. namespace anki {
  22. CommandBuffer* CommandBuffer::newInstance(const CommandBufferInitInfo& init)
  23. {
  24. ANKI_TRACE_SCOPED_EVENT(VkNewCommandBuffer);
  25. CommandBufferImpl* impl = anki::newInstance<CommandBufferImpl>(GrMemoryPool::getSingleton(), init.getName());
  26. const Error err = impl->init(init);
  27. if(err)
  28. {
  29. deleteInstance(GrMemoryPool::getSingleton(), impl);
  30. impl = nullptr;
  31. }
  32. return impl;
  33. }
  34. void CommandBuffer::endRecording()
  35. {
  36. ANKI_VK_SELF(CommandBufferImpl);
  37. self.endRecording();
  38. }
  39. void CommandBuffer::bindVertexBuffer(U32 binding, const BufferView& buff, U32 stride, VertexStepRate stepRate)
  40. {
  41. ANKI_ASSERT(buff.isValid());
  42. ANKI_VK_SELF(CommandBufferImpl);
  43. self.commandCommon();
  44. self.m_graphicsState.bindVertexBuffer(binding, stepRate, stride);
  45. const VkBuffer vkbuff = static_cast<const BufferImpl&>(buff.getBuffer()).getHandle();
  46. vkCmdBindVertexBuffers(self.m_handle, binding, 1, &vkbuff, &buff.getOffset());
  47. }
  48. void CommandBuffer::setVertexAttribute(VertexAttributeSemantic attribute, U32 buffBinding, Format fmt, U32 relativeOffset)
  49. {
  50. ANKI_VK_SELF(CommandBufferImpl);
  51. self.commandCommon();
  52. self.m_graphicsState.setVertexAttribute(attribute, buffBinding, fmt, relativeOffset);
  53. }
  54. void CommandBuffer::bindIndexBuffer(const BufferView& buff, IndexType type)
  55. {
  56. ANKI_ASSERT(buff.isValid());
  57. ANKI_VK_SELF(CommandBufferImpl);
  58. self.commandCommon();
  59. const BufferImpl& buffi = static_cast<const BufferImpl&>(buff.getBuffer());
  60. ANKI_ASSERT(!!(buffi.getBufferUsage() & BufferUsageBit::kVertexOrIndex));
  61. vkCmdBindIndexBuffer(self.m_handle, buffi.getHandle(), buff.getOffset(), convertIndexType(type));
  62. }
  63. void CommandBuffer::setPrimitiveRestart(Bool enable)
  64. {
  65. ANKI_VK_SELF(CommandBufferImpl);
  66. self.commandCommon();
  67. self.m_graphicsState.setPrimitiveRestart(enable);
  68. }
  69. void CommandBuffer::setViewport(U32 minx, U32 miny, U32 width, U32 height)
  70. {
  71. ANKI_VK_SELF(CommandBufferImpl);
  72. ANKI_ASSERT(width > 0 && height > 0);
  73. self.commandCommon();
  74. self.m_graphicsState.setViewport(minx, miny, width, height);
  75. }
  76. void CommandBuffer::setScissor(U32 minx, U32 miny, U32 width, U32 height)
  77. {
  78. ANKI_VK_SELF(CommandBufferImpl);
  79. ANKI_ASSERT(width > 0 && height > 0);
  80. self.commandCommon();
  81. self.m_graphicsState.setScissor(minx, miny, width, height);
  82. }
  83. void CommandBuffer::setFillMode(FillMode mode)
  84. {
  85. ANKI_VK_SELF(CommandBufferImpl);
  86. self.commandCommon();
  87. self.m_graphicsState.setFillMode(mode);
  88. }
  89. void CommandBuffer::setCullMode(FaceSelectionBit mode)
  90. {
  91. ANKI_VK_SELF(CommandBufferImpl);
  92. self.commandCommon();
  93. self.m_graphicsState.setCullMode(mode);
  94. }
  95. void CommandBuffer::setPolygonOffset(F32 factor, F32 units)
  96. {
  97. ANKI_VK_SELF(CommandBufferImpl);
  98. self.commandCommon();
  99. self.m_graphicsState.setPolygonOffset(factor, units);
  100. vkCmdSetDepthBias(self.m_handle, factor, 0.0f, units);
  101. }
  102. void CommandBuffer::setStencilOperations(FaceSelectionBit face, StencilOperation stencilFail, StencilOperation stencilPassDepthFail,
  103. StencilOperation stencilPassDepthPass)
  104. {
  105. ANKI_VK_SELF(CommandBufferImpl);
  106. self.commandCommon();
  107. self.m_graphicsState.setStencilOperations(face, stencilFail, stencilPassDepthFail, stencilPassDepthPass);
  108. }
  109. void CommandBuffer::setStencilCompareOperation(FaceSelectionBit face, CompareOperation comp)
  110. {
  111. ANKI_VK_SELF(CommandBufferImpl);
  112. self.commandCommon();
  113. self.m_graphicsState.setStencilCompareOperation(face, comp);
  114. }
  115. void CommandBuffer::setStencilCompareMask(FaceSelectionBit face, U32 mask)
  116. {
  117. ANKI_VK_SELF(CommandBufferImpl);
  118. self.commandCommon();
  119. self.m_graphicsState.setStencilCompareMask(face, mask);
  120. }
  121. void CommandBuffer::setStencilWriteMask(FaceSelectionBit face, U32 mask)
  122. {
  123. ANKI_VK_SELF(CommandBufferImpl);
  124. self.commandCommon();
  125. self.m_graphicsState.setStencilWriteMask(face, mask);
  126. }
  127. void CommandBuffer::setStencilReference(FaceSelectionBit face, U32 ref)
  128. {
  129. ANKI_VK_SELF(CommandBufferImpl);
  130. self.commandCommon();
  131. self.m_graphicsState.setStencilReference(face, ref);
  132. }
  133. void CommandBuffer::setDepthWrite(Bool enable)
  134. {
  135. ANKI_VK_SELF(CommandBufferImpl);
  136. self.commandCommon();
  137. self.m_graphicsState.setDepthWrite(enable);
  138. }
  139. void CommandBuffer::setDepthCompareOperation(CompareOperation op)
  140. {
  141. ANKI_VK_SELF(CommandBufferImpl);
  142. self.commandCommon();
  143. self.m_graphicsState.setDepthCompareOperation(op);
  144. }
  145. void CommandBuffer::setAlphaToCoverage(Bool enable)
  146. {
  147. ANKI_VK_SELF(CommandBufferImpl);
  148. self.commandCommon();
  149. self.m_graphicsState.setAlphaToCoverage(enable);
  150. }
  151. void CommandBuffer::setColorChannelWriteMask(U32 attachment, ColorBit mask)
  152. {
  153. ANKI_VK_SELF(CommandBufferImpl);
  154. self.commandCommon();
  155. self.m_graphicsState.setColorChannelWriteMask(attachment, mask);
  156. }
  157. void CommandBuffer::setBlendFactors(U32 attachment, BlendFactor srcRgb, BlendFactor dstRgb, BlendFactor srcA, BlendFactor dstA)
  158. {
  159. ANKI_VK_SELF(CommandBufferImpl);
  160. self.commandCommon();
  161. self.m_graphicsState.setBlendFactors(attachment, srcRgb, dstRgb, srcA, dstA);
  162. }
  163. void CommandBuffer::setBlendOperation(U32 attachment, BlendOperation funcRgb, BlendOperation funcA)
  164. {
  165. ANKI_VK_SELF(CommandBufferImpl);
  166. self.commandCommon();
  167. self.m_graphicsState.setBlendOperation(attachment, funcRgb, funcA);
  168. }
  169. void CommandBuffer::bindSrv(U32 reg, U32 space, const TextureView& texView)
  170. {
  171. ANKI_VK_SELF(CommandBufferImpl);
  172. self.commandCommon();
  173. const TextureImpl& tex = static_cast<const TextureImpl&>(texView.getTexture());
  174. ANKI_ASSERT(texView.isGoodForSampling());
  175. const VkImageLayout lay = tex.computeLayout(TextureUsageBit::kAllSrv & tex.getTextureUsage());
  176. self.m_descriptorState.bindSampledTexture(space, reg, tex.getImageView(texView.getSubresource()), lay);
  177. }
  178. void CommandBuffer::bindUav(U32 reg, U32 space, const TextureView& texView)
  179. {
  180. ANKI_VK_SELF(CommandBufferImpl);
  181. self.commandCommon();
  182. const TextureImpl& tex = static_cast<const TextureImpl&>(texView.getTexture());
  183. ANKI_ASSERT(texView.isGoodForStorage());
  184. self.m_descriptorState.bindStorageTexture(space, reg, tex.getImageView(texView.getSubresource()));
  185. const Bool isPresentable = !!(tex.getTextureUsage() & TextureUsageBit::kPresent);
  186. if(isPresentable)
  187. {
  188. self.m_renderedToDefaultFb = true;
  189. }
  190. }
  191. void CommandBuffer::bindSampler(U32 reg, U32 space, Sampler* sampler)
  192. {
  193. ANKI_VK_SELF(CommandBufferImpl);
  194. self.commandCommon();
  195. const VkSampler handle = static_cast<const SamplerImpl&>(*sampler).m_sampler->getHandle();
  196. self.m_descriptorState.bindSampler(space, reg, handle);
  197. self.m_microCmdb->pushObjectRef(sampler);
  198. }
  199. void CommandBuffer::bindConstantBuffer(U32 reg, U32 space, const BufferView& buff)
  200. {
  201. ANKI_ASSERT(buff.isValid());
  202. ANKI_VK_SELF(CommandBufferImpl);
  203. self.commandCommon();
  204. const VkBuffer handle = static_cast<const BufferImpl&>(buff.getBuffer()).getHandle();
  205. self.m_descriptorState.bindUniformBuffer(space, reg, handle, buff.getOffset(), buff.getRange());
  206. }
  207. void CommandBuffer::bindSrv(U32 reg, U32 space, const BufferView& buff, Format fmt)
  208. {
  209. ANKI_ASSERT(buff.isValid());
  210. ANKI_VK_SELF(CommandBufferImpl);
  211. self.commandCommon();
  212. const VkBuffer handle = static_cast<const BufferImpl&>(buff.getBuffer()).getHandle();
  213. if(fmt == Format::kNone)
  214. {
  215. self.m_descriptorState.bindReadStorageBuffer(space, reg, handle, buff.getOffset(), buff.getRange());
  216. }
  217. else
  218. {
  219. const VkBufferView view = static_cast<const BufferImpl&>(buff.getBuffer()).getOrCreateBufferView(fmt, buff.getOffset(), buff.getRange());
  220. self.m_descriptorState.bindReadTexelBuffer(space, reg, view);
  221. }
  222. }
  223. void CommandBuffer::bindUav(U32 reg, U32 space, const BufferView& buff, Format fmt)
  224. {
  225. ANKI_ASSERT(buff.isValid());
  226. ANKI_VK_SELF(CommandBufferImpl);
  227. self.commandCommon();
  228. const VkBuffer handle = static_cast<const BufferImpl&>(buff.getBuffer()).getHandle();
  229. if(fmt == Format::kNone)
  230. {
  231. self.m_descriptorState.bindReadWriteStorageBuffer(space, reg, handle, buff.getOffset(), buff.getRange());
  232. }
  233. else
  234. {
  235. const VkBufferView view = static_cast<const BufferImpl&>(buff.getBuffer()).getOrCreateBufferView(fmt, buff.getOffset(), buff.getRange());
  236. self.m_descriptorState.bindReadWriteTexelBuffer(space, reg, view);
  237. }
  238. }
  239. void CommandBuffer::bindSrv(U32 reg, U32 space, AccelerationStructure* as)
  240. {
  241. ANKI_VK_SELF(CommandBufferImpl);
  242. self.commandCommon();
  243. const VkAccelerationStructureKHR& handle = static_cast<const AccelerationStructureImpl&>(*as).getHandle();
  244. self.m_descriptorState.bindAccelerationStructure(space, reg, &handle);
  245. self.m_microCmdb->pushObjectRef(as);
  246. }
  247. void CommandBuffer::bindShaderProgram(ShaderProgram* prog)
  248. {
  249. ANKI_VK_SELF(CommandBufferImpl);
  250. self.commandCommon();
  251. ShaderProgramImpl& impl = static_cast<ShaderProgramImpl&>(*prog);
  252. VkPipelineBindPoint bindPoint;
  253. if(impl.isGraphics())
  254. {
  255. self.m_graphicsProg = &impl;
  256. self.m_computeProg = nullptr; // Unbind the compute prog. Doesn't work like vulkan
  257. self.m_rtProg = nullptr; // See above
  258. self.m_graphicsState.bindShaderProgram(&impl);
  259. bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  260. }
  261. else if(!!(impl.getStages() & ShaderTypeBit::kCompute))
  262. {
  263. self.m_computeProg = &impl;
  264. self.m_graphicsProg = nullptr; // See comment in the if()
  265. self.m_rtProg = nullptr; // See above
  266. // Bind the pipeline now
  267. vkCmdBindPipeline(self.m_handle, VK_PIPELINE_BIND_POINT_COMPUTE, impl.getComputePipelineHandle());
  268. bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
  269. }
  270. else
  271. {
  272. ANKI_ASSERT(!!(impl.getStages() & ShaderTypeBit::kAllRayTracing));
  273. self.m_computeProg = nullptr;
  274. self.m_graphicsProg = nullptr;
  275. self.m_rtProg = &impl;
  276. // Bind now
  277. vkCmdBindPipeline(self.m_handle, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, impl.getRayTracingPipelineHandle());
  278. bindPoint = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR;
  279. }
  280. self.m_descriptorState.setPipelineLayout(&impl.getPipelineLayout(), bindPoint);
  281. self.m_microCmdb->pushObjectRef(prog);
  282. }
  283. void CommandBuffer::beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, const TextureView& vrsRt, U8 vrsRtTexelSizeX,
  284. U8 vrsRtTexelSizeY)
  285. {
  286. ANKI_VK_SELF(CommandBufferImpl);
  287. ANKI_ASSERT(!self.m_insideRenderpass);
  288. #if ANKI_ASSERTIONS_ENABLED
  289. self.m_insideRenderpass = true;
  290. #endif
  291. self.commandCommon();
  292. Array<VkRenderingAttachmentInfo, kMaxColorRenderTargets> vkColorAttachments;
  293. VkRenderingAttachmentInfo vkDepthAttachment;
  294. VkRenderingAttachmentInfo vkStencilAttachment;
  295. VkRenderingFragmentShadingRateAttachmentInfoKHR vkVrsAttachment;
  296. VkRenderingInfo info = {};
  297. Bool drawsToSwapchain = false;
  298. U32 fbWidth = 0;
  299. U32 fbHeight = 0;
  300. Array<Format, kMaxColorRenderTargets> colorFormats = {};
  301. Format dsFormat = Format::kNone;
  302. // Do color targets
  303. for(U32 i = 0; i < colorRts.getSize(); ++i)
  304. {
  305. const TextureView& view = colorRts[i].m_textureView;
  306. ANKI_ASSERT(!view.getDepthStencilAspect());
  307. const TextureImpl& tex = static_cast<const TextureImpl&>(view.getTexture());
  308. vkColorAttachments[i] = {};
  309. vkColorAttachments[i].sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
  310. vkColorAttachments[i].imageView = tex.getImageView(view.getSubresource());
  311. vkColorAttachments[i].imageLayout = tex.computeLayout(colorRts[i].m_usage);
  312. vkColorAttachments[i].loadOp = convertLoadOp(colorRts[i].m_loadOperation);
  313. vkColorAttachments[i].storeOp = convertStoreOp(colorRts[i].m_storeOperation);
  314. vkColorAttachments[i].clearValue.color.float32[0] = colorRts[i].m_clearValue.m_colorf[0];
  315. vkColorAttachments[i].clearValue.color.float32[1] = colorRts[i].m_clearValue.m_colorf[1];
  316. vkColorAttachments[i].clearValue.color.float32[2] = colorRts[i].m_clearValue.m_colorf[2];
  317. vkColorAttachments[i].clearValue.color.float32[3] = colorRts[i].m_clearValue.m_colorf[3];
  318. if(!!(tex.getTextureUsage() & TextureUsageBit::kPresent))
  319. {
  320. drawsToSwapchain = true;
  321. }
  322. ANKI_ASSERT(fbWidth == 0 || (fbWidth == tex.getWidth() >> view.getFirstMipmap()));
  323. ANKI_ASSERT(fbHeight == 0 || (fbHeight == tex.getHeight() >> view.getFirstMipmap()));
  324. fbWidth = tex.getWidth() >> view.getFirstMipmap();
  325. fbHeight = tex.getHeight() >> view.getFirstMipmap();
  326. colorFormats[i] = tex.getFormat();
  327. }
  328. if(colorRts.getSize())
  329. {
  330. info.colorAttachmentCount = colorRts.getSize();
  331. info.pColorAttachments = vkColorAttachments.getBegin();
  332. ANKI_ASSERT((!drawsToSwapchain || colorRts.getSize() == 1) && "Can't handle that");
  333. }
  334. // DS
  335. if(depthStencilRt)
  336. {
  337. const TextureView& view = depthStencilRt->m_textureView;
  338. ANKI_ASSERT(!!view.getDepthStencilAspect());
  339. const TextureImpl& tex = static_cast<const TextureImpl&>(view.getTexture());
  340. if(!!(view.getDepthStencilAspect() & DepthStencilAspectBit::kDepth))
  341. {
  342. vkDepthAttachment = {};
  343. vkDepthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
  344. vkDepthAttachment.imageView = tex.getImageView(view.getSubresource());
  345. vkDepthAttachment.imageLayout = tex.computeLayout(depthStencilRt->m_usage);
  346. vkDepthAttachment.loadOp = convertLoadOp(depthStencilRt->m_loadOperation);
  347. vkDepthAttachment.storeOp = convertStoreOp(depthStencilRt->m_storeOperation);
  348. vkDepthAttachment.clearValue.depthStencil.depth = depthStencilRt->m_clearValue.m_depthStencil.m_depth;
  349. vkDepthAttachment.clearValue.depthStencil.stencil = depthStencilRt->m_clearValue.m_depthStencil.m_stencil;
  350. info.pDepthAttachment = &vkDepthAttachment;
  351. }
  352. if(!!(view.getDepthStencilAspect() & DepthStencilAspectBit::kStencil) && getFormatInfo(tex.getFormat()).isStencil())
  353. {
  354. vkStencilAttachment = {};
  355. vkStencilAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
  356. vkStencilAttachment.imageView = tex.getImageView(view.getSubresource());
  357. vkStencilAttachment.imageLayout = tex.computeLayout(depthStencilRt->m_usage);
  358. vkStencilAttachment.loadOp = convertLoadOp(depthStencilRt->m_stencilLoadOperation);
  359. vkStencilAttachment.storeOp = convertStoreOp(depthStencilRt->m_stencilStoreOperation);
  360. vkStencilAttachment.clearValue.depthStencil.depth = depthStencilRt->m_clearValue.m_depthStencil.m_depth;
  361. vkStencilAttachment.clearValue.depthStencil.stencil = depthStencilRt->m_clearValue.m_depthStencil.m_stencil;
  362. info.pStencilAttachment = &vkStencilAttachment;
  363. }
  364. ANKI_ASSERT(fbWidth == 0 || (fbWidth == tex.getWidth() >> view.getFirstMipmap()));
  365. ANKI_ASSERT(fbHeight == 0 || (fbHeight == tex.getHeight() >> view.getFirstMipmap()));
  366. fbWidth = tex.getWidth() >> view.getFirstMipmap();
  367. fbHeight = tex.getHeight() >> view.getFirstMipmap();
  368. dsFormat = tex.getFormat();
  369. }
  370. if(vrsRt.isValid())
  371. {
  372. const TextureImpl& tex = static_cast<const TextureImpl&>(vrsRt.getTexture());
  373. vkVrsAttachment = {};
  374. vkVrsAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR;
  375. vkVrsAttachment.imageView = tex.getImageView(vrsRt.getSubresource());
  376. // Technically it's possible for SRI to be in other layout. Don't bother though
  377. vkVrsAttachment.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
  378. vkVrsAttachment.shadingRateAttachmentTexelSize.width = vrsRtTexelSizeX;
  379. vkVrsAttachment.shadingRateAttachmentTexelSize.height = vrsRtTexelSizeY;
  380. appendPNextList(info, &vkVrsAttachment);
  381. }
  382. info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
  383. info.layerCount = 1;
  384. // Set the render area
  385. info.renderArea.offset.x = 0;
  386. info.renderArea.offset.y = 0;
  387. info.renderArea.extent.width = fbWidth;
  388. info.renderArea.extent.height = fbHeight;
  389. // State bookkeeping
  390. self.m_graphicsState.beginRenderPass({colorFormats.getBegin(), colorRts.getSize()}, dsFormat, UVec2(fbWidth, fbHeight));
  391. if(drawsToSwapchain)
  392. {
  393. self.m_renderedToDefaultFb = true;
  394. }
  395. // Finaly
  396. vkCmdBeginRendering(self.m_handle, &info);
  397. }
  398. void CommandBuffer::endRenderPass()
  399. {
  400. ANKI_VK_SELF(CommandBufferImpl);
  401. ANKI_ASSERT(self.m_insideRenderpass);
  402. #if ANKI_ASSERTIONS_ENABLED
  403. self.m_insideRenderpass = false;
  404. #endif
  405. self.commandCommon();
  406. vkCmdEndRendering(self.m_handle);
  407. }
  408. void CommandBuffer::setVrsRate([[maybe_unused]] VrsRate rate)
  409. {
  410. ANKI_VK_SELF(CommandBufferImpl);
  411. ANKI_ASSERT(getGrManagerImpl().getDeviceCapabilities().m_vrs);
  412. ANKI_ASSERT(rate < VrsRate::kCount);
  413. self.commandCommon();
  414. ANKI_ASSERT(!"TODO");
  415. }
  416. void CommandBuffer::drawIndexed(PrimitiveTopology topology, U32 count, U32 instanceCount, U32 firstIndex, U32 baseVertex, U32 baseInstance)
  417. {
  418. ANKI_VK_SELF(CommandBufferImpl);
  419. self.m_graphicsState.setPrimitiveTopology(topology);
  420. self.drawcallCommon();
  421. vkCmdDrawIndexed(self.m_handle, count, instanceCount, firstIndex, baseVertex, baseInstance);
  422. }
  423. void CommandBuffer::draw(PrimitiveTopology topology, U32 count, U32 instanceCount, U32 first, U32 baseInstance)
  424. {
  425. ANKI_VK_SELF(CommandBufferImpl);
  426. self.m_graphicsState.setPrimitiveTopology(topology);
  427. self.drawcallCommon();
  428. vkCmdDraw(self.m_handle, count, instanceCount, first, baseInstance);
  429. }
  430. void CommandBuffer::drawIndirect(PrimitiveTopology topology, const BufferView& buff, U32 drawCount)
  431. {
  432. ANKI_ASSERT(buff.isValid());
  433. ANKI_ASSERT(drawCount > 0);
  434. ANKI_VK_SELF(CommandBufferImpl);
  435. self.m_graphicsState.setPrimitiveTopology(topology);
  436. self.drawcallCommon();
  437. const BufferImpl& impl = static_cast<const BufferImpl&>(buff.getBuffer());
  438. ANKI_ASSERT(impl.usageValid(BufferUsageBit::kIndirectDraw));
  439. ANKI_ASSERT((buff.getOffset() % 4) == 0);
  440. ANKI_ASSERT((buff.getRange() % sizeof(DrawIndirectArgs)) == 0);
  441. ANKI_ASSERT(sizeof(DrawIndirectArgs) * drawCount == buff.getRange());
  442. vkCmdDrawIndirect(self.m_handle, impl.getHandle(), buff.getOffset(), drawCount, sizeof(DrawIndirectArgs));
  443. }
  444. void CommandBuffer::drawIndexedIndirect(PrimitiveTopology topology, const BufferView& buff, U32 drawCount)
  445. {
  446. ANKI_ASSERT(buff.isValid());
  447. ANKI_ASSERT(drawCount > 0);
  448. ANKI_VK_SELF(CommandBufferImpl);
  449. self.m_graphicsState.setPrimitiveTopology(topology);
  450. self.drawcallCommon();
  451. const BufferImpl& impl = static_cast<const BufferImpl&>(buff.getBuffer());
  452. ANKI_ASSERT(impl.usageValid(BufferUsageBit::kIndirectDraw));
  453. ANKI_ASSERT((buff.getOffset() % 4) == 0);
  454. ANKI_ASSERT(sizeof(DrawIndexedIndirectArgs) * drawCount == buff.getRange());
  455. vkCmdDrawIndexedIndirect(self.m_handle, impl.getHandle(), buff.getOffset(), drawCount, sizeof(DrawIndexedIndirectArgs));
  456. }
  457. void CommandBuffer::drawIndexedIndirectCount(PrimitiveTopology topology, const BufferView& argBuffer, U32 argBufferStride,
  458. const BufferView& countBuffer, U32 maxDrawCount)
  459. {
  460. ANKI_ASSERT(argBuffer.isValid());
  461. ANKI_ASSERT(countBuffer.isValid());
  462. ANKI_VK_SELF(CommandBufferImpl);
  463. self.m_graphicsState.setPrimitiveTopology(topology);
  464. self.drawcallCommon();
  465. ANKI_ASSERT(argBufferStride >= sizeof(DrawIndexedIndirectArgs));
  466. const BufferImpl& argBufferImpl = static_cast<const BufferImpl&>(argBuffer.getBuffer());
  467. ANKI_ASSERT(argBufferImpl.usageValid(BufferUsageBit::kIndirectDraw));
  468. ANKI_ASSERT((argBuffer.getOffset() % 4) == 0);
  469. ANKI_ASSERT((argBuffer.getRange() % argBufferStride) == 0);
  470. ANKI_ASSERT(argBufferStride * maxDrawCount == argBuffer.getRange());
  471. const BufferImpl& countBufferImpl = static_cast<const BufferImpl&>(countBuffer.getBuffer());
  472. ANKI_ASSERT(countBufferImpl.usageValid(BufferUsageBit::kIndirectDraw));
  473. ANKI_ASSERT((countBuffer.getOffset() % 4) == 0);
  474. ANKI_ASSERT(countBuffer.getRange() == sizeof(U32));
  475. ANKI_ASSERT(maxDrawCount > 0 && maxDrawCount <= getGrManagerImpl().getDeviceCapabilities().m_maxDrawIndirectCount);
  476. vkCmdDrawIndexedIndirectCount(self.m_handle, argBufferImpl.getHandle(), argBuffer.getOffset(), countBufferImpl.getHandle(),
  477. countBuffer.getOffset(), maxDrawCount, argBufferStride);
  478. }
  479. void CommandBuffer::drawIndirectCount(PrimitiveTopology topology, const BufferView& argBuffer, U32 argBufferStride, const BufferView& countBuffer,
  480. U32 maxDrawCount)
  481. {
  482. ANKI_ASSERT(argBuffer.isValid());
  483. ANKI_ASSERT(countBuffer.isValid());
  484. ANKI_VK_SELF(CommandBufferImpl);
  485. self.m_graphicsState.setPrimitiveTopology(topology);
  486. self.drawcallCommon();
  487. ANKI_ASSERT(argBufferStride >= sizeof(DrawIndirectArgs));
  488. const BufferImpl& argBufferImpl = static_cast<const BufferImpl&>(argBuffer.getBuffer());
  489. ANKI_ASSERT(argBufferImpl.usageValid(BufferUsageBit::kIndirectDraw));
  490. ANKI_ASSERT((argBuffer.getOffset() % 4) == 0);
  491. ANKI_ASSERT(maxDrawCount * argBufferStride == argBuffer.getRange());
  492. const BufferImpl& countBufferImpl = static_cast<const BufferImpl&>(countBuffer.getBuffer());
  493. ANKI_ASSERT(countBufferImpl.usageValid(BufferUsageBit::kIndirectDraw));
  494. ANKI_ASSERT((countBuffer.getOffset() % 4) == 0);
  495. ANKI_ASSERT(countBuffer.getRange() == sizeof(U32));
  496. ANKI_ASSERT(maxDrawCount > 0 && maxDrawCount <= getGrManagerImpl().getDeviceCapabilities().m_maxDrawIndirectCount);
  497. vkCmdDrawIndirectCount(self.m_handle, argBufferImpl.getHandle(), argBuffer.getOffset(), countBufferImpl.getHandle(), countBuffer.getOffset(),
  498. maxDrawCount, argBufferStride);
  499. }
  500. void CommandBuffer::drawMeshTasks(U32 groupCountX, U32 groupCountY, U32 groupCountZ)
  501. {
  502. ANKI_VK_SELF(CommandBufferImpl);
  503. ANKI_ASSERT(!!(getGrManagerImpl().getExtensions() & VulkanExtensions::kEXT_mesh_shader));
  504. self.drawcallCommon();
  505. vkCmdDrawMeshTasksEXT(self.m_handle, groupCountX, groupCountY, groupCountZ);
  506. }
  507. void CommandBuffer::drawMeshTasksIndirect(const BufferView& argBuffer, U32 drawCount)
  508. {
  509. ANKI_ASSERT(argBuffer.isValid());
  510. ANKI_ASSERT(drawCount > 0);
  511. ANKI_ASSERT(!!(getGrManagerImpl().getExtensions() & VulkanExtensions::kEXT_mesh_shader));
  512. ANKI_ASSERT((argBuffer.getOffset() % 4) == 0);
  513. ANKI_ASSERT(drawCount * sizeof(DispatchIndirectArgs) == argBuffer.getRange());
  514. const BufferImpl& impl = static_cast<const BufferImpl&>(argBuffer.getBuffer());
  515. ANKI_ASSERT(impl.usageValid(BufferUsageBit::kIndirectDraw));
  516. ANKI_VK_SELF(CommandBufferImpl);
  517. self.m_graphicsState.setPrimitiveTopology(PrimitiveTopology::kTriangles); // Not sure if that's needed
  518. self.drawcallCommon();
  519. vkCmdDrawMeshTasksIndirectEXT(self.m_handle, impl.getHandle(), argBuffer.getOffset(), drawCount, sizeof(DispatchIndirectArgs));
  520. }
  521. void CommandBuffer::dispatchCompute(U32 groupCountX, U32 groupCountY, U32 groupCountZ)
  522. {
  523. ANKI_VK_SELF(CommandBufferImpl);
  524. ANKI_ASSERT(groupCountX > 0 && groupCountY > 0 && groupCountZ > 0);
  525. self.dispatchCommon();
  526. vkCmdDispatch(self.m_handle, groupCountX, groupCountY, groupCountZ);
  527. }
  528. void CommandBuffer::dispatchComputeIndirect(const BufferView& argBuffer)
  529. {
  530. ANKI_ASSERT(argBuffer.isValid());
  531. ANKI_ASSERT(sizeof(DispatchIndirectArgs) == argBuffer.getRange());
  532. ANKI_ASSERT(argBuffer.getOffset() % 4 == 0);
  533. ANKI_VK_SELF(CommandBufferImpl);
  534. self.dispatchCommon();
  535. vkCmdDispatchIndirect(self.m_handle, static_cast<BufferImpl&>(argBuffer.getBuffer()).getHandle(), argBuffer.getOffset());
  536. }
  537. void CommandBuffer::dispatchGraph([[maybe_unused]] const BufferView& scratchBuffer, [[maybe_unused]] const void* records,
  538. [[maybe_unused]] U32 recordCount, [[maybe_unused]] U32 recordStride)
  539. {
  540. ANKI_ASSERT(!"Not supported");
  541. }
  542. void CommandBuffer::traceRays(const BufferView& sbtBuffer, U32 sbtRecordSize32, U32 hitGroupSbtRecordCount, U32 rayTypeCount, U32 width, U32 height,
  543. U32 depth)
  544. {
  545. ANKI_VK_SELF(CommandBufferImpl);
  546. self.traceRaysInternal(sbtBuffer, sbtRecordSize32, hitGroupSbtRecordCount, rayTypeCount, width, height, depth, {});
  547. }
  548. void CommandBuffer::traceRaysIndirect(const BufferView& sbtBuffer, U32 sbtRecordSize32, U32 hitGroupSbtRecordCount, U32 rayTypeCount,
  549. BufferView argsBuffer)
  550. {
  551. ANKI_VK_SELF(CommandBufferImpl);
  552. self.traceRaysInternal(sbtBuffer, sbtRecordSize32, hitGroupSbtRecordCount, rayTypeCount, 0, 0, 0, argsBuffer);
  553. }
  554. void CommandBuffer::blitTexture([[maybe_unused]] const TextureView& srcView, [[maybe_unused]] const TextureView& destView)
  555. {
  556. ANKI_ASSERT(!"TODO");
  557. }
  558. void CommandBuffer::clearTexture(const TextureView& texView, const ClearValue& clearValue)
  559. {
  560. ANKI_VK_SELF(CommandBufferImpl);
  561. self.commandCommon();
  562. const TextureImpl& tex = static_cast<const TextureImpl&>(texView.getTexture());
  563. VkClearColorValue vclear;
  564. static_assert(sizeof(vclear) == sizeof(clearValue), "See file");
  565. memcpy(&vclear, &clearValue, sizeof(clearValue));
  566. if(!texView.getDepthStencilAspect())
  567. {
  568. const VkImageSubresourceRange vkRange = tex.computeVkImageSubresourceRange(texView.getSubresource());
  569. vkCmdClearColorImage(self.m_handle, tex.m_imageHandle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &vclear, 1, &vkRange);
  570. }
  571. else
  572. {
  573. ANKI_ASSERT(!"TODO");
  574. }
  575. }
  576. void CommandBuffer::copyBufferToTexture(const BufferView& buff, const TextureView& texView)
  577. {
  578. ANKI_ASSERT(buff.isValid());
  579. ANKI_VK_SELF(CommandBufferImpl);
  580. self.commandCommon();
  581. const TextureImpl& tex = static_cast<const TextureImpl&>(texView.getTexture());
  582. ANKI_ASSERT(tex.usageValid(TextureUsageBit::kCopyDestination));
  583. ANKI_ASSERT(texView.isGoodForCopyBufferToTexture());
  584. const VkImageLayout layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
  585. const VkImageSubresourceRange range = tex.computeVkImageSubresourceRange(texView.getSubresource());
  586. // Compute the sizes of the mip
  587. const U32 width = tex.getWidth() >> range.baseMipLevel;
  588. const U32 height = tex.getHeight() >> range.baseMipLevel;
  589. ANKI_ASSERT(width && height);
  590. const U32 depth = (tex.getTextureType() == TextureType::k3D) ? (tex.getDepth() >> range.baseMipLevel) : 1u;
  591. if(tex.getTextureType() != TextureType::k3D)
  592. {
  593. ANKI_ASSERT(buff.getRange() == computeSurfaceSize(width, height, tex.getFormat()));
  594. }
  595. else
  596. {
  597. ANKI_ASSERT(buff.getRange() == computeVolumeSize(width, height, depth, tex.getFormat()));
  598. }
  599. // Copy
  600. VkBufferImageCopy region;
  601. region.imageSubresource.aspectMask = range.aspectMask;
  602. region.imageSubresource.baseArrayLayer = range.baseArrayLayer;
  603. region.imageSubresource.layerCount = 1;
  604. region.imageSubresource.mipLevel = range.baseMipLevel;
  605. region.imageOffset = {0, 0, 0};
  606. region.imageExtent.width = width;
  607. region.imageExtent.height = height;
  608. region.imageExtent.depth = depth;
  609. region.bufferOffset = buff.getOffset();
  610. region.bufferImageHeight = 0;
  611. region.bufferRowLength = 0;
  612. vkCmdCopyBufferToImage(self.m_handle, static_cast<const BufferImpl&>(buff.getBuffer()).getHandle(), tex.m_imageHandle, layout, 1, &region);
  613. }
  614. void CommandBuffer::zeroBuffer(const BufferView& buff)
  615. {
  616. ANKI_ASSERT(buff.isValid());
  617. ANKI_VK_SELF(CommandBufferImpl);
  618. self.commandCommon();
  619. ANKI_ASSERT(!self.m_insideRenderpass);
  620. const BufferImpl& impl = static_cast<const BufferImpl&>(buff.getBuffer());
  621. ANKI_ASSERT(impl.usageValid(BufferUsageBit::kCopyDestination));
  622. ANKI_ASSERT((buff.getOffset() % 4) == 0 && "Should be multiple of 4");
  623. ANKI_ASSERT((buff.getRange() % 4) == 0 && "Should be multiple of 4");
  624. vkCmdFillBuffer(self.m_handle, impl.getHandle(), buff.getOffset(), buff.getRange(), 0);
  625. }
  626. void CommandBuffer::writeOcclusionQueriesResultToBuffer(ConstWeakArray<OcclusionQuery*> queries, const BufferView& buff)
  627. {
  628. ANKI_ASSERT(buff.isValid());
  629. ANKI_VK_SELF(CommandBufferImpl);
  630. ANKI_ASSERT(queries.getSize() > 0);
  631. self.commandCommon();
  632. ANKI_ASSERT(!self.m_insideRenderpass);
  633. ANKI_ASSERT(sizeof(U32) * queries.getSize() <= buff.getRange());
  634. ANKI_ASSERT((buff.getOffset() % 4) == 0);
  635. const BufferImpl& impl = static_cast<const BufferImpl&>(buff.getBuffer());
  636. ANKI_ASSERT(impl.usageValid(BufferUsageBit::kCopyDestination));
  637. for(U32 i = 0; i < queries.getSize(); ++i)
  638. {
  639. ANKI_ASSERT(queries[i]);
  640. OcclusionQueryImpl* q = static_cast<OcclusionQueryImpl*>(queries[i]);
  641. vkCmdCopyQueryPoolResults(self.m_handle, q->m_handle.getQueryPool(), q->m_handle.getQueryIndex(), 1, impl.getHandle(),
  642. buff.getOffset() * sizeof(U32) * i, sizeof(U32), VK_QUERY_RESULT_PARTIAL_BIT);
  643. self.m_microCmdb->pushObjectRef(q);
  644. }
  645. }
  646. void CommandBuffer::copyBufferToBuffer(Buffer* src, Buffer* dst, ConstWeakArray<CopyBufferToBufferInfo> copies)
  647. {
  648. ANKI_VK_SELF(CommandBufferImpl);
  649. ANKI_ASSERT(static_cast<const BufferImpl&>(*src).usageValid(BufferUsageBit::kCopySource));
  650. ANKI_ASSERT(static_cast<const BufferImpl&>(*dst).usageValid(BufferUsageBit::kCopyDestination));
  651. ANKI_ASSERT(copies.getSize() > 0);
  652. self.commandCommon();
  653. static_assert(sizeof(CopyBufferToBufferInfo) == sizeof(VkBufferCopy));
  654. const VkBufferCopy* vkCopies = reinterpret_cast<const VkBufferCopy*>(&copies[0]);
  655. vkCmdCopyBuffer(self.m_handle, static_cast<const BufferImpl&>(*src).getHandle(), static_cast<const BufferImpl&>(*dst).getHandle(),
  656. copies.getSize(), &vkCopies[0]);
  657. }
  658. void CommandBuffer::buildAccelerationStructure(AccelerationStructure* as, const BufferView& scratchBuffer)
  659. {
  660. ANKI_ASSERT(scratchBuffer.isValid());
  661. ANKI_ASSERT(as);
  662. ANKI_ASSERT(as->getBuildScratchBufferSize() <= scratchBuffer.getRange());
  663. ANKI_VK_SELF(CommandBufferImpl);
  664. self.commandCommon();
  665. // Get objects
  666. const AccelerationStructureImpl& asImpl = static_cast<AccelerationStructureImpl&>(*as);
  667. // Create the build info
  668. VkAccelerationStructureBuildGeometryInfoKHR buildInfo;
  669. VkAccelerationStructureBuildRangeInfoKHR rangeInfo;
  670. asImpl.generateBuildInfo(scratchBuffer.getBuffer().getGpuAddress() + scratchBuffer.getOffset(), buildInfo, rangeInfo);
  671. // Run the command
  672. Array<const VkAccelerationStructureBuildRangeInfoKHR*, 1> pRangeInfos = {&rangeInfo};
  673. vkCmdBuildAccelerationStructuresKHR(self.m_handle, 1, &buildInfo, &pRangeInfos[0]);
  674. }
  675. #if ANKI_DLSS
  676. /// Utility function to get the NGX's resource structure for a texture
  677. /// @param[in] tex the texture to generate the NVSDK_NGX_Resource_VK from
  678. static NVSDK_NGX_Resource_VK getNGXResourceFromAnkiTexture(const TextureView& view)
  679. {
  680. const TextureImpl& tex = static_cast<const TextureImpl&>(view.getTexture());
  681. const VkImageView imageView = tex.getImageView(view.getSubresource());
  682. const VkFormat format = tex.m_vkFormat;
  683. const VkImage image = tex.m_imageHandle;
  684. const VkImageSubresourceRange subresourceRange = tex.computeVkImageSubresourceRange(view.getSubresource());
  685. const Bool isUAV = !!(tex.m_vkUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT);
  686. // TODO Not sure if I should pass the width,height of the image or the view
  687. return NVSDK_NGX_Create_ImageView_Resource_VK(imageView, image, subresourceRange, format, tex.getWidth(), tex.getHeight(), isUAV);
  688. }
  689. #endif
  690. void CommandBuffer::upscale(GrUpscaler* upscaler, const TextureView& inColor, const TextureView& outUpscaledColor, const TextureView& motionVectors,
  691. const TextureView& depth, const TextureView& exposure, Bool resetAccumulation, const Vec2& jitterOffset,
  692. const Vec2& motionVectorsScale)
  693. {
  694. #if ANKI_DLSS
  695. ANKI_VK_SELF(CommandBufferImpl);
  696. ANKI_ASSERT(getGrManagerImpl().getDeviceCapabilities().m_dlss);
  697. ANKI_ASSERT(upscaler->getUpscalerType() == GrUpscalerType::kDlss2);
  698. self.commandCommon();
  699. const GrUpscalerImpl& upscalerImpl = static_cast<const GrUpscalerImpl&>(*upscaler);
  700. NVSDK_NGX_Resource_VK srcResVk = getNGXResourceFromAnkiTexture(inColor);
  701. NVSDK_NGX_Resource_VK dstResVk = getNGXResourceFromAnkiTexture(outUpscaledColor);
  702. NVSDK_NGX_Resource_VK mvResVk = getNGXResourceFromAnkiTexture(motionVectors);
  703. NVSDK_NGX_Resource_VK depthResVk = getNGXResourceFromAnkiTexture(depth);
  704. NVSDK_NGX_Resource_VK exposureResVk = getNGXResourceFromAnkiTexture(exposure);
  705. const U32 mipLevel = inColor.getFirstMipmap();
  706. const NVSDK_NGX_Coordinates renderingOffset = {0, 0};
  707. const NVSDK_NGX_Dimensions renderingSize = {inColor.getTexture().getWidth() >> mipLevel, inColor.getTexture().getHeight() >> mipLevel};
  708. NVSDK_NGX_VK_DLSS_Eval_Params vkDlssEvalParams;
  709. memset(&vkDlssEvalParams, 0, sizeof(vkDlssEvalParams));
  710. vkDlssEvalParams.Feature.pInColor = &srcResVk;
  711. vkDlssEvalParams.Feature.pInOutput = &dstResVk;
  712. vkDlssEvalParams.pInDepth = &depthResVk;
  713. vkDlssEvalParams.pInMotionVectors = &mvResVk;
  714. vkDlssEvalParams.pInExposureTexture = &exposureResVk;
  715. vkDlssEvalParams.InJitterOffsetX = jitterOffset.x();
  716. vkDlssEvalParams.InJitterOffsetY = jitterOffset.y();
  717. vkDlssEvalParams.InReset = resetAccumulation;
  718. vkDlssEvalParams.InMVScaleX = motionVectorsScale.x();
  719. vkDlssEvalParams.InMVScaleY = motionVectorsScale.y();
  720. vkDlssEvalParams.InColorSubrectBase = renderingOffset;
  721. vkDlssEvalParams.InDepthSubrectBase = renderingOffset;
  722. vkDlssEvalParams.InTranslucencySubrectBase = renderingOffset;
  723. vkDlssEvalParams.InMVSubrectBase = renderingOffset;
  724. vkDlssEvalParams.InRenderSubrectDimensions = renderingSize;
  725. NVSDK_NGX_Parameter* dlssParameters = &upscalerImpl.getParameters();
  726. NVSDK_NGX_Handle* dlssFeature = &upscalerImpl.getFeature();
  727. const NVSDK_NGX_Result result = NGX_VULKAN_EVALUATE_DLSS_EXT(self.m_handle, dlssFeature, dlssParameters, &vkDlssEvalParams);
  728. if(NVSDK_NGX_FAILED(result))
  729. {
  730. ANKI_VK_LOGF("Failed to NVSDK_NGX_VULKAN_EvaluateFeature for DLSS, code = 0x%08x, info: %ls", result, GetNGXResultAsString(result));
  731. }
  732. #else
  733. ANKI_ASSERT(0 && "Not supported");
  734. (void)upscaler;
  735. (void)inColor;
  736. (void)outUpscaledColor;
  737. (void)motionVectors;
  738. (void)depth;
  739. (void)exposure;
  740. (void)resetAccumulation;
  741. (void)jitterOffset;
  742. (void)motionVectorsScale;
  743. #endif
  744. }
  745. void CommandBuffer::setPipelineBarrier(ConstWeakArray<TextureBarrierInfo> textures, ConstWeakArray<BufferBarrierInfo> buffers,
  746. ConstWeakArray<AccelerationStructureBarrierInfo> accelerationStructures)
  747. {
  748. ANKI_VK_SELF(CommandBufferImpl);
  749. self.commandCommon();
  750. DynamicArray<VkImageMemoryBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> imageBarriers(self.m_pool);
  751. VkMemoryBarrier genericBarrier = {};
  752. genericBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
  753. VkPipelineStageFlags srcStageMask = 0;
  754. VkPipelineStageFlags dstStageMask = 0;
  755. for(const TextureBarrierInfo& barrier : textures)
  756. {
  757. const TextureImpl& impl = static_cast<const TextureImpl&>(barrier.m_textureView.getTexture());
  758. imageBarriers.emplaceBack(impl.computeBarrierInfo(barrier.m_previousUsage, barrier.m_nextUsage, barrier.m_textureView.getSubresource(),
  759. srcStageMask, dstStageMask));
  760. }
  761. for(const BufferBarrierInfo& barrier : buffers)
  762. {
  763. ANKI_ASSERT(barrier.m_bufferView.isValid());
  764. const BufferImpl& impl = static_cast<const BufferImpl&>(barrier.m_bufferView.getBuffer());
  765. const VkBufferMemoryBarrier akBarrier = impl.computeBarrierInfo(barrier.m_previousUsage, barrier.m_nextUsage, srcStageMask, dstStageMask);
  766. genericBarrier.srcAccessMask |= akBarrier.srcAccessMask;
  767. genericBarrier.dstAccessMask |= akBarrier.dstAccessMask;
  768. }
  769. for(const AccelerationStructureBarrierInfo& barrier : accelerationStructures)
  770. {
  771. ANKI_ASSERT(barrier.m_as);
  772. const VkMemoryBarrier memBarrier =
  773. AccelerationStructureImpl::computeBarrierInfo(barrier.m_previousUsage, barrier.m_nextUsage, srcStageMask, dstStageMask);
  774. genericBarrier.srcAccessMask |= memBarrier.srcAccessMask;
  775. genericBarrier.dstAccessMask |= memBarrier.dstAccessMask;
  776. self.m_microCmdb->pushObjectRef(barrier.m_as);
  777. }
  778. const Bool genericBarrierSet = genericBarrier.srcAccessMask != 0 && genericBarrier.dstAccessMask != 0;
  779. vkCmdPipelineBarrier(self.m_handle, srcStageMask, dstStageMask, 0, (genericBarrierSet) ? 1 : 0, (genericBarrierSet) ? &genericBarrier : nullptr,
  780. 0, nullptr, imageBarriers.getSize(), (imageBarriers.getSize()) ? &imageBarriers[0] : nullptr);
  781. ANKI_TRACE_INC_COUNTER(VkBarrier, 1);
  782. }
  783. void CommandBuffer::beginOcclusionQuery(OcclusionQuery* query)
  784. {
  785. ANKI_VK_SELF(CommandBufferImpl);
  786. self.commandCommon();
  787. const VkQueryPool handle = static_cast<const OcclusionQueryImpl&>(*query).m_handle.getQueryPool();
  788. const U32 idx = static_cast<const OcclusionQueryImpl&>(*query).m_handle.getQueryIndex();
  789. ANKI_ASSERT(handle);
  790. vkCmdBeginQuery(self.m_handle, handle, idx, 0);
  791. self.m_microCmdb->pushObjectRef(query);
  792. }
  793. void CommandBuffer::endOcclusionQuery(OcclusionQuery* query)
  794. {
  795. ANKI_VK_SELF(CommandBufferImpl);
  796. self.commandCommon();
  797. const VkQueryPool handle = static_cast<const OcclusionQueryImpl&>(*query).m_handle.getQueryPool();
  798. const U32 idx = static_cast<const OcclusionQueryImpl&>(*query).m_handle.getQueryIndex();
  799. ANKI_ASSERT(handle);
  800. vkCmdEndQuery(self.m_handle, handle, idx);
  801. self.m_microCmdb->pushObjectRef(query);
  802. }
  803. void CommandBuffer::beginPipelineQuery(PipelineQuery* query)
  804. {
  805. ANKI_VK_SELF(CommandBufferImpl);
  806. self.commandCommon();
  807. const VkQueryPool handle = static_cast<const PipelineQueryImpl&>(*query).m_handle.getQueryPool();
  808. const U32 idx = static_cast<const PipelineQueryImpl&>(*query).m_handle.getQueryIndex();
  809. ANKI_ASSERT(handle);
  810. vkCmdBeginQuery(self.m_handle, handle, idx, 0);
  811. self.m_microCmdb->pushObjectRef(query);
  812. }
  813. void CommandBuffer::endPipelineQuery(PipelineQuery* query)
  814. {
  815. ANKI_VK_SELF(CommandBufferImpl);
  816. self.commandCommon();
  817. const VkQueryPool handle = static_cast<const PipelineQueryImpl&>(*query).m_handle.getQueryPool();
  818. const U32 idx = static_cast<const PipelineQueryImpl&>(*query).m_handle.getQueryIndex();
  819. ANKI_ASSERT(handle);
  820. vkCmdEndQuery(self.m_handle, handle, idx);
  821. self.m_microCmdb->pushObjectRef(query);
  822. }
  823. void CommandBuffer::writeTimestamp(TimestampQuery* query)
  824. {
  825. ANKI_VK_SELF(CommandBufferImpl);
  826. self.commandCommon();
  827. const VkQueryPool handle = static_cast<const TimestampQueryImpl&>(*query).m_handle.getQueryPool();
  828. const U32 idx = static_cast<const TimestampQueryImpl&>(*query).m_handle.getQueryIndex();
  829. vkCmdWriteTimestamp(self.m_handle, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, handle, idx);
  830. self.m_microCmdb->pushObjectRef(query);
  831. }
  832. Bool CommandBuffer::isEmpty() const
  833. {
  834. ANKI_VK_SELF_CONST(CommandBufferImpl);
  835. return self.isEmpty();
  836. }
  837. void CommandBuffer::setFastConstants(const void* data, U32 dataSize)
  838. {
  839. ANKI_VK_SELF(CommandBufferImpl);
  840. ANKI_ASSERT(data && dataSize && dataSize % 16 == 0);
  841. // ANKI_ASSERT(static_cast<const ShaderProgramImpl&>(self.getBoundProgram()).getReflection().m_descriptor.m_fastConstantsSize == dataSize
  842. // && "The bound program should have push constants equal to the \"dataSize\" parameter");
  843. self.commandCommon();
  844. self.m_descriptorState.setFastConstants(data, dataSize);
  845. }
  846. void CommandBuffer::setLineWidth(F32 width)
  847. {
  848. ANKI_VK_SELF(CommandBufferImpl);
  849. self.commandCommon();
  850. self.m_graphicsState.setLineWidth(width);
  851. }
  852. void CommandBuffer::pushDebugMarker(CString name, Vec3 color)
  853. {
  854. ANKI_VK_SELF(CommandBufferImpl);
  855. if(self.m_debugMarkers) [[unlikely]]
  856. {
  857. self.commandCommon();
  858. VkDebugUtilsLabelEXT label = {};
  859. label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
  860. label.pLabelName = name.cstr();
  861. label.color[0] = color[0];
  862. label.color[1] = color[1];
  863. label.color[2] = color[2];
  864. label.color[3] = 1.0f;
  865. vkCmdBeginDebugUtilsLabelEXT(self.m_handle, &label);
  866. }
  867. #if ANKI_EXTRA_CHECKS
  868. ++self.m_debugMarkersPushed;
  869. #endif
  870. }
  871. void CommandBuffer::popDebugMarker()
  872. {
  873. ANKI_VK_SELF(CommandBufferImpl);
  874. if(self.m_debugMarkers) [[unlikely]]
  875. {
  876. self.commandCommon();
  877. vkCmdEndDebugUtilsLabelEXT(self.m_handle);
  878. }
  879. #if ANKI_EXTRA_CHECKS
  880. ANKI_ASSERT(self.m_debugMarkersPushed > 0);
  881. --self.m_debugMarkersPushed;
  882. #endif
  883. }
  884. CommandBufferImpl::~CommandBufferImpl()
  885. {
  886. if(m_empty)
  887. {
  888. ANKI_VK_LOGW("Command buffer was empty");
  889. }
  890. if(!m_finalized)
  891. {
  892. ANKI_VK_LOGW("Command buffer was not flushed");
  893. }
  894. #if ANKI_EXTRA_CHECKS
  895. ANKI_ASSERT(m_debugMarkersPushed == 0);
  896. if(!m_submitted)
  897. {
  898. ANKI_VK_LOGW("Command buffer not submitted");
  899. }
  900. #endif
  901. }
  902. Error CommandBufferImpl::init(const CommandBufferInitInfo& init)
  903. {
  904. m_tid = Thread::getCurrentThreadId();
  905. m_flags = init.m_flags;
  906. ANKI_CHECK(CommandBufferFactory::getSingleton().newCommandBuffer(m_tid, m_flags, m_microCmdb));
  907. m_handle = m_microCmdb->getHandle();
  908. m_pool = &m_microCmdb->getFastMemoryPool();
  909. m_descriptorState.init(m_pool);
  910. m_debugMarkers = !!(getGrManagerImpl().getExtensions() & VulkanExtensions::kEXT_debug_utils);
  911. return Error::kNone;
  912. }
  913. void CommandBufferImpl::setImageBarrier(VkPipelineStageFlags srcStage, VkAccessFlags srcAccess, VkImageLayout prevLayout,
  914. VkPipelineStageFlags dstStage, VkAccessFlags dstAccess, VkImageLayout newLayout, VkImage img,
  915. const VkImageSubresourceRange& range)
  916. {
  917. ANKI_ASSERT(img);
  918. commandCommon();
  919. VkImageMemoryBarrier inf = {};
  920. inf.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
  921. inf.srcAccessMask = srcAccess;
  922. inf.dstAccessMask = dstAccess;
  923. inf.oldLayout = prevLayout;
  924. inf.newLayout = newLayout;
  925. inf.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  926. inf.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  927. inf.image = img;
  928. inf.subresourceRange = range;
  929. vkCmdPipelineBarrier(m_handle, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &inf);
  930. ANKI_TRACE_INC_COUNTER(VkBarrier, 1);
  931. }
  932. void CommandBufferImpl::beginRecording()
  933. {
  934. // Do the begin
  935. VkCommandBufferInheritanceInfo inheritance = {};
  936. inheritance.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
  937. VkCommandBufferBeginInfo begin = {};
  938. begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  939. begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
  940. begin.pInheritanceInfo = &inheritance;
  941. vkBeginCommandBuffer(m_handle, &begin);
  942. // Stats
  943. if(!!(getGrManagerImpl().getExtensions() & VulkanExtensions::kKHR_pipeline_executable_properties))
  944. {
  945. m_graphicsState.setEnablePipelineStatistics(true);
  946. }
  947. }
  948. void CommandBufferImpl::endRecording()
  949. {
  950. commandCommon();
  951. ANKI_ASSERT(!m_finalized);
  952. ANKI_ASSERT(!m_empty);
  953. ANKI_VK_CHECKF(vkEndCommandBuffer(m_handle));
  954. m_finalized = true;
  955. #if ANKI_EXTRA_CHECKS
  956. static Atomic<U32> messagePrintCount(0);
  957. constexpr U32 MAX_PRINT_COUNT = 10;
  958. CString message;
  959. if(!!(m_flags & CommandBufferFlag::kSmallBatch))
  960. {
  961. if(m_commandCount > kCommandBufferSmallBatchMaxCommands * 4)
  962. {
  963. message = "Command buffer has too many commands%s: %u";
  964. }
  965. }
  966. else
  967. {
  968. if(m_commandCount <= kCommandBufferSmallBatchMaxCommands / 4)
  969. {
  970. message = "Command buffer has too few commands%s: %u";
  971. }
  972. }
  973. if(!message.isEmpty())
  974. {
  975. const U32 count = messagePrintCount.fetchAdd(1) + 1;
  976. if(count < MAX_PRINT_COUNT)
  977. {
  978. ANKI_VK_LOGW(message.cstr(), "", m_commandCount);
  979. }
  980. else if(count == MAX_PRINT_COUNT)
  981. {
  982. ANKI_VK_LOGW(message.cstr(), " (will ignore further warnings)", m_commandCount);
  983. }
  984. }
  985. #endif
  986. }
  987. void CommandBufferImpl::drawcallCommon()
  988. {
  989. // Preconditions
  990. commandCommon();
  991. ANKI_ASSERT(m_graphicsProg);
  992. ANKI_ASSERT(m_insideRenderpass);
  993. // Get or create ppline
  994. m_graphicsProg->getGraphicsPipelineFactory().flushState(m_graphicsState, m_handle);
  995. // Bind dsets
  996. m_descriptorState.flush(m_handle, m_microCmdb->getDSAllocator());
  997. ANKI_TRACE_INC_COUNTER(VkDrawcall, 1);
  998. }
  999. ANKI_FORCE_INLINE void CommandBufferImpl::dispatchCommon()
  1000. {
  1001. ANKI_ASSERT(m_computeProg);
  1002. commandCommon();
  1003. // Bind descriptors
  1004. m_descriptorState.flush(m_handle, m_microCmdb->getDSAllocator());
  1005. }
  1006. void CommandBufferImpl::traceRaysInternal(const BufferView& sbtBuffer, U32 sbtRecordSize32, U32 hitGroupSbtRecordCount, U32 rayTypeCount, U32 width,
  1007. U32 height, U32 depth, BufferView argsBuff)
  1008. {
  1009. ANKI_ASSERT(sbtBuffer.isValid());
  1010. const PtrSize sbtRecordSize = sbtRecordSize32;
  1011. ANKI_ASSERT(hitGroupSbtRecordCount > 0);
  1012. ANKI_ASSERT(m_rtProg);
  1013. [[maybe_unused]] const ShaderProgramImpl& sprog = static_cast<const ShaderProgramImpl&>(*m_rtProg);
  1014. ANKI_ASSERT((hitGroupSbtRecordCount % rayTypeCount) == 0);
  1015. const PtrSize sbtRecordCount = 1 + rayTypeCount + hitGroupSbtRecordCount;
  1016. [[maybe_unused]] const PtrSize sbtBufferSize = sbtRecordCount * sbtRecordSize;
  1017. ANKI_ASSERT(sbtBufferSize <= sbtBuffer.getRange());
  1018. ANKI_ASSERT(isAligned(getGrManagerImpl().getDeviceCapabilities().m_sbtRecordAlignment, sbtBuffer.getOffset()));
  1019. commandCommon();
  1020. // Bind descriptors
  1021. m_descriptorState.flush(m_handle, m_microCmdb->getDSAllocator());
  1022. Array<VkStridedDeviceAddressRegionKHR, 4> regions;
  1023. const U64 stbBufferAddress = sbtBuffer.getBuffer().getGpuAddress() + sbtBuffer.getOffset();
  1024. ANKI_ASSERT(isAligned(getGrManagerImpl().getDeviceCapabilities().m_sbtRecordAlignment, stbBufferAddress));
  1025. // Rgen
  1026. regions[0].deviceAddress = stbBufferAddress;
  1027. regions[0].stride = sbtRecordSize;
  1028. regions[0].size = sbtRecordSize;
  1029. // Miss
  1030. regions[1].deviceAddress = regions[0].deviceAddress + regions[0].size;
  1031. regions[1].stride = sbtRecordSize;
  1032. regions[1].size = sbtRecordSize * rayTypeCount;
  1033. // Hit
  1034. regions[2].deviceAddress = regions[1].deviceAddress + regions[1].size;
  1035. regions[2].stride = sbtRecordSize * rayTypeCount;
  1036. regions[2].size = sbtRecordSize * hitGroupSbtRecordCount;
  1037. // Callable, nothing for now
  1038. regions[3] = VkStridedDeviceAddressRegionKHR();
  1039. if(!argsBuff.isValid())
  1040. {
  1041. ANKI_ASSERT(width > 0 && height > 0 && depth > 0);
  1042. vkCmdTraceRaysKHR(m_handle, &regions[0], &regions[1], &regions[2], &regions[3], width, height, depth);
  1043. }
  1044. else
  1045. {
  1046. ANKI_ASSERT(argsBuff.getRange() == sizeof(DispatchIndirectArgs));
  1047. vkCmdTraceRaysIndirectKHR(m_handle, &regions[0], &regions[1], &regions[2], &regions[3],
  1048. argsBuff.getBuffer().getGpuAddress() + argsBuff.getOffset());
  1049. }
  1050. }
  1051. } // end namespace anki