VkCommandBuffer.cpp 46 KB

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