Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

344 linhas
14 KiB

  1. unit uvkuCommandBuffer;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. Vulkan, uvkuBase, uvkuTypes;
  7. type
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. TvkuRenderPassBeginInfo = class(TvkuStructure)
  10. private
  11. fClearValues: TVkClearValueList;
  12. public
  13. RenderPass: VkRenderPass;
  14. Framebuffer: VkFramebuffer;
  15. RenderArea: TVkRect2D;
  16. property ClearValues: TVkClearValueList read fClearValues;
  17. function GetStructure: TVkRenderPassBeginInfo;
  18. procedure SetStructure(const aData: TVkRenderPassBeginInfo);
  19. constructor Create;
  20. destructor Destroy; override;
  21. end;
  22. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  23. TvkuBeginRenderPassHelper = class(TvkuCommandHelper)
  24. private
  25. fRenderPassBeginInfo: TvkuRenderPassBeginInfo;
  26. fDeviceCommands: TVkDeviceCommands;
  27. fCommandBuffer: VkCommandBuffer;
  28. public
  29. property RenderPassBeginInfo: TvkuRenderPassBeginInfo read fRenderPassBeginInfo;
  30. procedure Execute(const aContents: TVkSubpassContents);
  31. constructor Create(const aCommandBuffer: VkCommandBuffer; const aDeviceCommands: TVkDeviceCommands);
  32. destructor Destroy; override;
  33. end;
  34. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. TvkuCommandBuffer = class(TvkuHandle)
  36. private
  37. fHandle: VkCommandBuffer;
  38. fCommandPool: VkCommandPool;
  39. fDeviceCommands: TVkDeviceCommands;
  40. public
  41. property Handle: VkCommandBuffer read fHandle;
  42. property CommandPool: VkCommandPool read fCommandPool;
  43. property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
  44. procedure BeginCommand;
  45. procedure EndCommand;
  46. procedure PipelineBarrier(
  47. const aSrcStageMask: VkPipelineStageFlags;
  48. const aDstStageMask: VkPipelineStageFlags;
  49. const aDependencyFlags: VkDependencyFlags;
  50. const aMemoryBarriers: array of TVkMemoryBarrier;
  51. const aBufferMemoryBarriers: array of TVkBufferMemoryBarrier;
  52. const aImageMemoryBarriers: array of TVkImageMemoryBarrier);
  53. function BeginRenderPass: TvkuBeginRenderPassHelper;
  54. procedure EndRenderPass;
  55. procedure SetViewport(
  56. const aFirstViewport: VkUint32;
  57. const aViewports: array of TVkViewport);
  58. procedure SetScissors(
  59. const aFirstScissor: VkUint32;
  60. const aScissorss: array of TVkRect2D);
  61. procedure BindDescriptorSet(
  62. const aBindPoint: TVkPipelineBindPoint;
  63. const aLayout: VkPipelineLayout;
  64. const aFirstSet: VkUint32;
  65. const aDescriptorSets: array of VkDescriptorSet;
  66. const aDynamicOffsets: array of VkUint32);
  67. procedure BindPipeline(
  68. const aBindPoint: TVkPipelineBindPoint;
  69. const aPipeline: VkPipeline);
  70. procedure BindVertexBuffers(
  71. const aFirstBinding: VkUint32;
  72. const aBuffers: array of VkBuffer;
  73. const aOffsets: array of VkDeviceSize);
  74. procedure BindIndexBuffers(
  75. const aBuffer: VkBuffer;
  76. const aOffset: VkDeviceSize;
  77. const aIndexType: TVkIndexType);
  78. procedure DrawIndexed(
  79. const aIndexCount: VkUint32;
  80. const aInstanceCount: VkUint32;
  81. const aFirstIndex: VkUint32;
  82. const aVertexOffset: VkInt32;
  83. const aFirstInstance: VkUint32);
  84. constructor Create(
  85. const aHandle: VkCommandBuffer;
  86. const aOwnsHandle: Boolean;
  87. const aCommandPool: VkCommandPool;
  88. const aDeviceCommands: TVkDeviceCommands);
  89. destructor Destroy; override;
  90. end;
  91. implementation
  92. uses
  93. uvkuUtils;
  94. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  95. //TvkuRenderPassBeginInfo////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  96. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. function TvkuRenderPassBeginInfo.GetStructure: TVkRenderPassBeginInfo;
  98. begin
  99. FillByte(result, SizeOf(result), 0);
  100. result.sType := VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
  101. result.pNext := nil;
  102. result.renderPass := RenderPass;
  103. result.framebuffer := Framebuffer;
  104. result.renderArea := RenderArea;
  105. result.clearValueCount := fClearValues.Length;
  106. result.pClearValues := fClearValues.PData;
  107. end;
  108. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  109. procedure TvkuRenderPassBeginInfo.SetStructure(const aData: TVkRenderPassBeginInfo);
  110. begin
  111. RenderPass := aData.renderPass;
  112. Framebuffer := aData.framebuffer;
  113. RenderArea := aData.renderArea;
  114. ClearValues.SetData(aData.pClearValues, aData.clearValueCount);
  115. end;
  116. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  117. constructor TvkuRenderPassBeginInfo.Create;
  118. begin
  119. inherited Create;
  120. fClearValues := TVkClearValueList.Create;
  121. end;
  122. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. destructor TvkuRenderPassBeginInfo.Destroy;
  124. begin
  125. FreeAndNil(fClearValues);
  126. inherited Destroy;
  127. end;
  128. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  129. //TvkuBeginRenderPassHelper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  130. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  131. procedure TvkuBeginRenderPassHelper.Execute(const aContents: TVkSubpassContents);
  132. var info: TVkRenderPassBeginInfo;
  133. begin
  134. info := fRenderPassBeginInfo.GetStructure;
  135. fDeviceCommands.vkCmdBeginRenderPass(fCommandBuffer, @info, aContents);
  136. end;
  137. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  138. constructor TvkuBeginRenderPassHelper.Create(const aCommandBuffer: VkCommandBuffer; const aDeviceCommands: TVkDeviceCommands);
  139. begin
  140. inherited Create;
  141. fCommandBuffer := aCommandBuffer;
  142. fDeviceCommands := aDeviceCommands;
  143. fRenderPassBeginInfo := TvkuRenderPassBeginInfo.Create;
  144. end;
  145. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  146. destructor TvkuBeginRenderPassHelper.Destroy;
  147. begin
  148. FreeAndNil(fRenderPassBeginInfo);
  149. inherited Destroy;
  150. end;
  151. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  152. //TvkuCommandBuffer//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  153. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  154. procedure TvkuCommandBuffer.BeginCommand;
  155. var
  156. Info: TVkCommandBufferBeginInfo;
  157. err: TVkResult;
  158. begin
  159. FillByte(Info, SizeOf(Info), 0);
  160. Info.sType := VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  161. Info.pNext := nil;
  162. Info.flags := []; // TODO
  163. Info.pInheritanceInfo := nil; // TODO
  164. err := DeviceCommands.vkBeginCommandBuffer(fHandle, @Info);
  165. if (err <> VK_SUCCESS) then
  166. raise TvkuErrorException.Create('unable to begin command buffer', err);
  167. end;
  168. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  169. procedure TvkuCommandBuffer.EndCommand;
  170. var err: TVkResult;
  171. begin
  172. err := fDeviceCommands.vkEndCommandBuffer(fHandle);
  173. if (err <> VK_SUCCESS) then
  174. raise TvkuErrorException.Create('unable to end command buffer', err);
  175. end;
  176. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  177. procedure TvkuCommandBuffer.PipelineBarrier(const aSrcStageMask: VkPipelineStageFlags;
  178. const aDstStageMask: VkPipelineStageFlags; const aDependencyFlags: VkDependencyFlags;
  179. const aMemoryBarriers: array of TVkMemoryBarrier; const aBufferMemoryBarriers: array of TVkBufferMemoryBarrier;
  180. const aImageMemoryBarriers: array of TVkImageMemoryBarrier);
  181. begin
  182. DeviceCommands.vkCmdPipelineBarrier(
  183. fHandle,
  184. aSrcStageMask,
  185. aDstStageMask,
  186. aDependencyFlags,
  187. Length(aMemoryBarriers), @aMemoryBarriers[0],
  188. Length(aBufferMemoryBarriers), @aBufferMemoryBarriers[0],
  189. Length(aImageMemoryBarriers), @aImageMemoryBarriers[0]);
  190. end;
  191. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  192. function TvkuCommandBuffer.BeginRenderPass: TvkuBeginRenderPassHelper;
  193. begin
  194. result := TvkuBeginRenderPassHelper.Create(fHandle, fDeviceCommands);
  195. end;
  196. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  197. procedure TvkuCommandBuffer.EndRenderPass;
  198. begin
  199. fDeviceCommands.vkCmdEndRenderPass(fHandle);
  200. end;
  201. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  202. procedure TvkuCommandBuffer.SetViewport(const aFirstViewport: VkUint32; const aViewports: array of TVkViewport);
  203. begin
  204. fDeviceCommands.vkCmdSetViewport(
  205. fHandle,
  206. aFirstViewport,
  207. Length(aViewports),
  208. @aViewports[0]);
  209. end;
  210. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  211. procedure TvkuCommandBuffer.SetScissors(const aFirstScissor: VkUint32; const aScissorss: array of TVkRect2D);
  212. begin
  213. fDeviceCommands.vkCmdSetScissor(
  214. fHandle,
  215. aFirstScissor,
  216. Length(aScissorss),
  217. @aScissorss[0]);
  218. end;
  219. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  220. procedure TvkuCommandBuffer.BindDescriptorSet(const aBindPoint: TVkPipelineBindPoint; const aLayout: VkPipelineLayout;
  221. const aFirstSet: VkUint32; const aDescriptorSets: array of VkDescriptorSet; const aDynamicOffsets: array of VkUint32);
  222. var
  223. DescSetCount, DynOffsetCount: Integer;
  224. DescSets: PVkDescriptorSet;
  225. DynOffsets: PVkUint32;
  226. begin
  227. DescSetCount := Length(aDescriptorSets);
  228. DynOffsetCount := Length(aDynamicOffsets);
  229. if (DescSetCount > 0)
  230. then DescSets := @aDescriptorSets[0]
  231. else DescSets := nil;
  232. if (DynOffsetCount > 0)
  233. then DynOffsets := @aDynamicOffsets[0]
  234. else DynOffsets := nil;
  235. fDeviceCommands.vkCmdBindDescriptorSets(
  236. fHandle,
  237. aBindPoint,
  238. aLayout,
  239. aFirstSet,
  240. DescSetCount,
  241. DescSets,
  242. DynOffsetCount,
  243. DynOffsets);
  244. end;
  245. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  246. procedure TvkuCommandBuffer.BindPipeline(const aBindPoint: TVkPipelineBindPoint; const aPipeline: VkPipeline);
  247. begin
  248. fDeviceCommands.vkCmdBindPipeline(fHandle, aBindPoint, aPipeline);
  249. end;
  250. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  251. procedure TvkuCommandBuffer.BindVertexBuffers(const aFirstBinding: VkUint32; const aBuffers: array of VkBuffer;
  252. const aOffsets: array of VkDeviceSize);
  253. begin
  254. if (Length(aBuffers) <> Length(aOffsets)) then
  255. raise TvkuException.Create('aBuffers and aOffsets must have the same number of elements');
  256. fDeviceCommands.vkCmdBindVertexBuffers(
  257. fHandle,
  258. aFirstBinding,
  259. Length(aBuffers),
  260. @aBuffers[0],
  261. @aOffsets[0]);
  262. end;
  263. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  264. procedure TvkuCommandBuffer.BindIndexBuffers(const aBuffer: VkBuffer; const aOffset: VkDeviceSize;
  265. const aIndexType: TVkIndexType);
  266. begin
  267. fDeviceCommands.vkCmdBindIndexBuffer(
  268. fHandle,
  269. aBuffer,
  270. aOffset,
  271. aIndexType);
  272. end;
  273. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  274. procedure TvkuCommandBuffer.DrawIndexed(const aIndexCount: VkUint32; const aInstanceCount: VkUint32;
  275. const aFirstIndex: VkUint32; const aVertexOffset: VkInt32; const aFirstInstance: VkUint32);
  276. begin
  277. fDeviceCommands.vkCmdDrawIndexed(
  278. fHandle,
  279. aIndexCount,
  280. aInstanceCount,
  281. aFirstIndex,
  282. aVertexOffset,
  283. aFirstInstance);
  284. end;
  285. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  286. constructor TvkuCommandBuffer.Create(const aHandle: VkCommandBuffer; const aOwnsHandle: Boolean;
  287. const aCommandPool: VkCommandPool; const aDeviceCommands: TVkDeviceCommands);
  288. begin
  289. inherited Create;
  290. fHandle := aHandle;
  291. fCommandPool := aCommandPool;
  292. fDeviceCommands := aDeviceCommands;
  293. OwnsHandle := aOwnsHandle;
  294. end;
  295. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  296. destructor TvkuCommandBuffer.Destroy;
  297. begin
  298. if OwnsHandle and (fHandle <> VK_INVALID_HANDLE) then
  299. fDeviceCommands.vkFreeCommandBuffers(fDeviceCommands.Device, fCommandPool, 1, @fHandle);
  300. fHandle := VK_INVALID_HANDLE;
  301. inherited Destroy;
  302. end;
  303. end.