Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

430 lignes
19 KiB

  1. unit uvkuDevice;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. Vulkan, uvkuBase, uvkuTypes;
  7. type
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. TvkuDescriptorImageInfo = class(TvkuStructure)
  10. Sampler: VkSampler;
  11. ImageView: VkImageView;
  12. ImageLayout: TVkImageLayout;
  13. function GetStructure: TVkDescriptorImageInfo;
  14. procedure SetStructure(const aData: TVkDescriptorImageInfo);
  15. end;
  16. TvkuDescriptorImageInfoList = specialize TvkuObjList<TvkuDescriptorImageInfo>;
  17. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  18. TvkuDescriptorBufferInfo = class(TvkuStructure)
  19. Buffer: VkBuffer;
  20. Offset: VkDeviceSize;
  21. Range: VkDeviceSize;
  22. function GetStructure: TVkDescriptorBufferInfo;
  23. procedure SetStructure(const aData: TVkDescriptorBufferInfo);
  24. end;
  25. TvkuDescriptorBufferInfoList = specialize TvkuObjList<TvkuDescriptorBufferInfo>;
  26. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. TvkuWriteDescriptorSet = class(TvkuStructure)
  28. private
  29. fImageInfos: TvkuDescriptorImageInfoList;
  30. fBufferInfos: TvkuDescriptorBufferInfoList;
  31. fTexelBufferViews: TVkBufferViewList;
  32. fvkImageInfos: TVkDescriptorImageInfoArr;
  33. fvkBufferInfos: TVkDescriptorBufferInfoArr;
  34. public
  35. DstSet: VkDescriptorSet;
  36. DstBinding: VkUint32;
  37. DstArrayElement: VkUint32;
  38. DescriptorType: TVkDescriptorType;
  39. property ImageInfos: TvkuDescriptorImageInfoList read fImageInfos;
  40. property BufferInfos: TvkuDescriptorBufferInfoList read fBufferInfos;
  41. function GetStructure: TVkWriteDescriptorSet;
  42. procedure SetStructure(const aData: TVkWriteDescriptorSet);
  43. procedure AfterConstruction; override;
  44. procedure BeforeDestruction; override;
  45. end;
  46. TvkuWriteDescriptorSetList = specialize TvkuObjList<TvkuWriteDescriptorSet>;
  47. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  48. TvkuCopyDescriptorSet = class(TvkuStructure)
  49. public
  50. SrcSet: VkDescriptorSet;
  51. SrcBinding: VkUint32;
  52. SrcArrayElement: VkUint32;
  53. DstSet: VkDescriptorSet;
  54. DstBinding: VkUint32;
  55. DstArrayElement: VkUint32;
  56. DescriptorCount: VkUint32;
  57. function GetStructure: TVkCopyDescriptorSet;
  58. procedure SetStructure(const aData: TVkCopyDescriptorSet);
  59. end;
  60. TvkuCopyDescriptorSetList = specialize TvkuObjList<TvkuCopyDescriptorSet>;
  61. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  62. TvkuUpdateDescriptorSetHelper = class(TvkuCommandHelper)
  63. private
  64. fDeviceCommands: TVkDeviceCommands;
  65. fWriteDescriptorSets: TvkuWriteDescriptorSetList;
  66. fCopyDescriptorSets: TvkuCopyDescriptorSetList;
  67. public
  68. property WriteDescriptorSets: TvkuWriteDescriptorSetList read fWriteDescriptorSets;
  69. property CopyDescriptorSets: TvkuCopyDescriptorSetList read fCopyDescriptorSets;
  70. procedure Execute;
  71. constructor Create(const aDeviceCommands: TVkDeviceCommands);
  72. destructor Destroy; override;
  73. end;
  74. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  75. TvkuDevice = class(TvkuAllocHandle)
  76. private
  77. fHandle: VkDevice;
  78. fInstanceCommands: TVkInstanceCommands;
  79. fDeviceCommands: TVkDeviceCommands;
  80. procedure CreateHandle(
  81. const aPhyDevice: VkPhysicalDevice;
  82. const aCreateInfo: PVkDeviceCreateInfo);
  83. public
  84. property Handle: VkDevice read fHandle;
  85. property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
  86. function GetQueue(
  87. const aQueueFamilyIndex: VkUint32;
  88. const aQueueIndex: VkUint32): VkQueue;
  89. function AllocateMemory(
  90. const aSize: VkUint32;
  91. const aMemoryTypeIndex: VkUint32;
  92. aAllocCallbacks: PVkAllocationCallbacks = nil): VkDeviceMemory;
  93. procedure FreeMemory(
  94. const aMemory: VkDeviceMemory;
  95. aAllocCallbacks: PVkAllocationCallbacks = nil);
  96. procedure WaitIdle;
  97. function UpdateDescriptorSet: TvkuUpdateDescriptorSetHelper;
  98. constructor Create(
  99. const aPhysicalDevice: VkPhysicalDevice;
  100. const aCreateInfo: TVkDeviceCreateInfo;
  101. const aInstanceCommands: TVkInstanceCommands;
  102. const aAllocCallbacks: PVkAllocationCallbacks = nil);
  103. constructor Create(
  104. const aHandle: VkDevice;
  105. const aOwnsHandle: Boolean;
  106. const aInstanceCommands: TVkInstanceCommands;
  107. const aAllocCallbacks: PVkAllocationCallbacks = nil);
  108. destructor Destroy; override;
  109. end;
  110. implementation
  111. uses
  112. uvkuUtils;
  113. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  114. //TvkuDescriptorImageInfo////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  115. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  116. function TvkuDescriptorImageInfo.GetStructure: TVkDescriptorImageInfo;
  117. begin
  118. FillByte(result, SizeOf(result), 0);
  119. result.sampler := Sampler;
  120. result.imageView := ImageView;
  121. result.imageLayout := ImageLayout;
  122. end;
  123. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  124. procedure TvkuDescriptorImageInfo.SetStructure(const aData: TVkDescriptorImageInfo);
  125. begin
  126. Sampler := aData.sampler;
  127. ImageView := aData.imageView;
  128. ImageLayout := aData.imageLayout;
  129. end;
  130. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  131. //TvkuDescriptorBufferInfo///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  132. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  133. function TvkuDescriptorBufferInfo.GetStructure: TVkDescriptorBufferInfo;
  134. begin
  135. FillByte(result, SizeOf(result), 0);
  136. result.buffer := Buffer;
  137. result.offset := Offset;
  138. result.range := Range;
  139. end;
  140. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  141. procedure TvkuDescriptorBufferInfo.SetStructure(const aData: TVkDescriptorBufferInfo);
  142. begin
  143. Buffer := aData.buffer;
  144. Offset := aData.offset;
  145. Range := aData.range;
  146. end;
  147. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. //TvkuWriteDescriptorSet/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  149. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  150. function TvkuWriteDescriptorSet.GetStructure: TVkWriteDescriptorSet;
  151. var c, i: Integer;
  152. begin
  153. c := fImageInfos.Length;
  154. if (c < fBufferInfos.Length) then
  155. c := fBufferInfos.Length;
  156. if (c < fTexelBufferViews.Length) then
  157. c := fTexelBufferViews.Length;
  158. SetLength(fvkImageInfos, fImageInfos.Length);
  159. if (fImageInfos.Length <> 0) and (fImageInfos.Length <> c) then
  160. raise TvkuException.Create('ImageInfos, BufferInfos and TexelBufferViews must be empty or must have the same size!');
  161. for i := low(fvkImageInfos) to high(fvkImageInfos) do
  162. fvkImageInfos[i] := fImageInfos[i].GetStructure;
  163. SetLength(fvkBufferInfos, fBufferInfos.Length);
  164. if (fBufferInfos.Length <> 0) and (fBufferInfos.Length <> c) then
  165. raise TvkuException.Create('ImageInfos, BufferInfos and TexelBufferViews must be empty or must have the same size!');
  166. for i := low(fvkBufferInfos) to high(fvkBufferInfos) do
  167. fvkBufferInfos[i] := fBufferInfos[i].GetStructure;
  168. if (fTexelBufferViews.Length <> 0) and (fTexelBufferViews.Length <> c) then
  169. raise TvkuException.Create('ImageInfos, BufferInfos and TexelBufferViews must be empty or must have the same size!');
  170. FillByte(result, SizeOf(result), 0);
  171. result.sType := VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  172. result.pNext := nil;
  173. result.dstSet := DstSet;
  174. result.dstBinding := DstBinding;
  175. result.dstArrayElement := DstArrayElement;
  176. result.descriptorCount := c;
  177. result.descriptorType := DescriptorType;
  178. result.pImageInfo := @fvkImageInfos[0];
  179. result.pBufferInfo := @fvkBufferInfos[0];
  180. result.pTexelBufferView := fTexelBufferViews.PData;
  181. end;
  182. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  183. procedure TvkuWriteDescriptorSet.SetStructure(const aData: TVkWriteDescriptorSet);
  184. var i: Integer;
  185. begin
  186. if Assigned(aData.pImageInfo) then begin
  187. fImageInfos.Length := aData.descriptorCount;
  188. for i := 0 to fImageInfos.Length-1 do
  189. fImageInfos[i].SetStructure((aData.pImageInfo + i)^);
  190. end;
  191. if Assigned(aData.pBufferInfo) then begin
  192. fBufferInfos.Length := aData.descriptorCount;
  193. for i := 0 to fBufferInfos.Length-1 do
  194. fBufferInfos[i].SetStructure((aData.pBufferInfo + i)^);
  195. end;
  196. fTexelBufferViews.SetData(aData.pTexelBufferView, aData.descriptorCount);
  197. DstSet := aData.dstSet;
  198. DstBinding := aData.dstBinding;
  199. DstArrayElement := aData.dstArrayElement;
  200. DescriptorType := aData.descriptorType;
  201. end;
  202. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  203. procedure TvkuWriteDescriptorSet.AfterConstruction;
  204. begin
  205. inherited AfterConstruction;
  206. fImageInfos := TvkuDescriptorImageInfoList.Create;
  207. fBufferInfos := TvkuDescriptorBufferInfoList.Create;
  208. fTexelBufferViews := TVkBufferViewList.Create;
  209. end;
  210. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  211. procedure TvkuWriteDescriptorSet.BeforeDestruction;
  212. begin
  213. FreeAndNil(fImageInfos);
  214. FreeAndNil(fBufferInfos);
  215. FreeAndNil(fTexelBufferViews);
  216. inherited BeforeDestruction;
  217. end;
  218. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  219. //TvkuCopyDescriptorSet//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  220. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. function TvkuCopyDescriptorSet.GetStructure: TVkCopyDescriptorSet;
  222. begin
  223. result.sType := VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
  224. result.pNext := nil;
  225. result.srcSet := SrcSet;
  226. result.srcBinding := SrcBinding;
  227. result.srcArrayElement := SrcArrayElement;
  228. result.dstSet := DstSet;
  229. result.dstBinding := DstBinding;
  230. result.dstArrayElement := DstArrayElement;
  231. result.descriptorCount := DescriptorCount;
  232. end;
  233. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  234. procedure TvkuCopyDescriptorSet.SetStructure(const aData: TVkCopyDescriptorSet);
  235. begin
  236. SrcSet := aData.srcSet;
  237. SrcBinding := aData.srcBinding;
  238. SrcArrayElement := aData.srcArrayElement;
  239. DstSet := aData.dstSet;
  240. DstBinding := aData.dstBinding;
  241. DstArrayElement := aData.dstArrayElement;
  242. DescriptorCount := aData.descriptorCount;
  243. end;
  244. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  245. //TvkuUpdateDescriptorSetHelper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  246. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  247. procedure TvkuUpdateDescriptorSetHelper.Execute;
  248. var
  249. i: Integer;
  250. vkWriteDescriptorSets: array of TVkWriteDescriptorSet;
  251. vkCopyDescriptorSets: array of TVkCopyDescriptorSet;
  252. begin
  253. SetLength(vkWriteDescriptorSets, fWriteDescriptorSets.Length);
  254. for i := low(vkWriteDescriptorSets) to high(vkWriteDescriptorSets) do
  255. vkWriteDescriptorSets[i] := fWriteDescriptorSets[i].GetStructure;
  256. SetLength(vkCopyDescriptorSets, fCopyDescriptorSets.Length);
  257. for i := low(vkCopyDescriptorSets) to high(vkCopyDescriptorSets) do
  258. vkCopyDescriptorSets[i] := fCopyDescriptorSets[i].GetStructure;
  259. fDeviceCommands.vkUpdateDescriptorSets(
  260. fDeviceCommands.Device,
  261. Length(vkWriteDescriptorSets),
  262. @vkWriteDescriptorSets[0],
  263. Length(vkCopyDescriptorSets),
  264. @vkCopyDescriptorSets[0]);
  265. end;
  266. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  267. constructor TvkuUpdateDescriptorSetHelper.Create(const aDeviceCommands: TVkDeviceCommands);
  268. begin
  269. inherited Create;
  270. fDeviceCommands := aDeviceCommands;
  271. fWriteDescriptorSets := TvkuWriteDescriptorSetList.Create;
  272. fCopyDescriptorSets := TvkuCopyDescriptorSetList.Create;
  273. end;
  274. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  275. destructor TvkuUpdateDescriptorSetHelper.Destroy;
  276. begin
  277. FreeAndNil(fCopyDescriptorSets);
  278. FreeAndNil(fWriteDescriptorSets);
  279. inherited Destroy;
  280. end;
  281. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  282. //TvkuDevice/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  283. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  284. procedure TvkuDevice.CreateHandle(const aPhyDevice: VkPhysicalDevice; const aCreateInfo: PVkDeviceCreateInfo);
  285. var err: TVkResult;
  286. begin
  287. if not Assigned(fInstanceCommands.vkCreateDevice) then
  288. raise TvkuInvalidFuncPtrException.Create('vkCreateDevice');
  289. err := fInstanceCommands.vkCreateDevice(aPhyDevice, aCreateInfo, AllocCallbacks, @fHandle);
  290. if (err <> VK_SUCCESS) then
  291. raise TvkuErrorException.Create('unable to create device', err);
  292. fDeviceCommands := LoadDeviceCommands(fInstanceCommands.Instance, fHandle);
  293. if not Assigned(fDeviceCommands) then
  294. raise TvkuException.Create('unable to load device commands');
  295. end;
  296. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  297. function TvkuDevice.GetQueue(const aQueueFamilyIndex: VkUint32; const aQueueIndex: VkUint32): VkQueue;
  298. begin
  299. if not Assigned(fDeviceCommands.vkGetDeviceQueue) then
  300. raise TvkuInvalidFuncPtrException.Create('vkGetDeviceQueue');
  301. fDeviceCommands.vkGetDeviceQueue(fHandle, aQueueFamilyIndex, aQueueIndex, @result);
  302. if (result = VK_INVALID_HANDLE) then
  303. raise TvkuException.Create('unable to get device queue');
  304. end;
  305. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  306. function TvkuDevice.AllocateMemory(const aSize: VkUint32; const aMemoryTypeIndex: VkUint32;
  307. aAllocCallbacks: PVkAllocationCallbacks): VkDeviceMemory;
  308. var
  309. AllocInfo: TVkMemoryAllocateInfo;
  310. err: TVkResult;
  311. begin
  312. FillByte(AllocInfo, SizeOf(AllocInfo), 0);
  313. AllocInfo.sType := VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
  314. AllocInfo.pNext := nil;
  315. AllocInfo.allocationSize := aSize;
  316. AllocInfo.memoryTypeIndex := aMemoryTypeIndex;
  317. if not Assigned(aAllocCallbacks) then
  318. aAllocCallbacks := AllocCallbacks;
  319. err := fDeviceCommands.vkAllocateMemory(fHandle, @AllocInfo, aAllocCallbacks, @result);
  320. if (err <> VK_SUCCESS) then
  321. raise TvkuErrorException.Create('unable to allocate device memory', err);
  322. end;
  323. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  324. procedure TvkuDevice.FreeMemory(const aMemory: VkDeviceMemory; aAllocCallbacks: PVkAllocationCallbacks);
  325. begin
  326. if not Assigned(aAllocCallbacks) then
  327. aAllocCallbacks := AllocCallbacks;
  328. fDeviceCommands.vkFreeMemory(fHandle, aMemory, aAllocCallbacks);
  329. end;
  330. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  331. procedure TvkuDevice.WaitIdle;
  332. var err: TVkResult;
  333. begin
  334. err := fDeviceCommands.vkDeviceWaitIdle(fHandle);
  335. if (err <> VK_SUCCESS) then
  336. raise TvkuErrorException.Create('unable to wait for device idle', err);
  337. end;
  338. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  339. function TvkuDevice.UpdateDescriptorSet: TvkuUpdateDescriptorSetHelper;
  340. begin
  341. result := TvkuUpdateDescriptorSetHelper.Create(fDeviceCommands);
  342. end;
  343. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  344. constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo;
  345. const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
  346. begin
  347. inherited Create;
  348. fHandle := nil;
  349. fInstanceCommands := aInstanceCommands;
  350. SetAllocCallbacks(aAllocCallbacks);
  351. CreateHandle(aPhysicalDevice, @aCreateInfo);
  352. end;
  353. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  354. constructor TvkuDevice.Create(const aHandle: VkDevice; const aOwnsHandle: Boolean;
  355. const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
  356. begin
  357. inherited Create;
  358. fHandle := aHandle;
  359. fInstanceCommands := aInstanceCommands;
  360. OwnsHandle := aOwnsHandle;
  361. SetAllocCallbacks(aAllocCallbacks);
  362. end;
  363. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  364. destructor TvkuDevice.Destroy;
  365. begin
  366. if OwnsHandle and (fHandle <> VK_INVALID_HANDLE) then
  367. fDeviceCommands.vkDestroyDevice(fHandle, AllocCallbacks);
  368. fHandle := VK_INVALID_HANDLE;
  369. FreeAndNil(fDeviceCommands);
  370. inherited Destroy;
  371. end;
  372. end.