選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

535 行
22 KiB

  1. unit uMainForm;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  6. Vulkan, VulkanUtils;
  7. type
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. TCustomAllocHandler = class(TvkuAllocationHandler)
  10. protected
  11. function AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; override;
  12. function ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; override;
  13. procedure FreeMemory(const aMemory: PVkVoid); override;
  14. end;
  15. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. TMainForm = class(TForm)
  17. RenderPanel: TPanel;
  18. procedure FormCreate(Sender: TObject);
  19. procedure FormDestroy(Sender: TObject);
  20. private
  21. fGraphicsQueueFamilyIndex: VkUint32;
  22. fGraphicsQueueNodeIndex: VkUint32;
  23. fPresentQueueNodeIndex: VkUint32;
  24. fSurfaceFormat: TVkFormat;
  25. fSurfaceColorSpace: TVkColorSpaceKHR;
  26. fAllocHandler: TCustomAllocHandler;
  27. fDebugReporter: TvkuConsoleDebugReporter;
  28. fInstance: TvkuInstance;
  29. fPhyDevice: TvkuPhysicalDevice;
  30. fDevice: TvkuDevice;
  31. fQueue: TvkuQueue;
  32. fSurface: TvkuSurface;
  33. fSwapChain: TvkuSwapChain;
  34. fImageViews: array of TvkuImageView;
  35. fRenderPass: TvkuRenderPass;
  36. fFrameBuffers: array of TvkuFrameBuffer;
  37. fDescSetLayout: TvkuDescriptorSetLayout;
  38. fPipelineLayout: TvkuPipelineLayout;
  39. fVertexShader: TvkuShaderModule;
  40. fFragmentShader: TvkuShaderModule;
  41. fPipeline: TvkuGraphicsPipeline;
  42. fCommandPool: TvkuCommandPool;
  43. fCommandBuffer: TvkuCommandBuffer;
  44. end;
  45. var
  46. MainForm: TMainForm;
  47. implementation
  48. {$R *.lfm}
  49. {$I Vulkan.inc}
  50. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  51. //TCustomAllocHandler////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  52. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. function TCustomAllocHandler.AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
  54. begin
  55. result := inherited AllocateMemory(aSize, aAlignment, aScope);
  56. WriteLn(Format(' MEM - %d bytes of memory allocated at %p', [ aSize, result ]));
  57. end;
  58. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. function TCustomAllocHandler.ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
  60. var p: PVkVoid;
  61. begin
  62. p := aOriginal;
  63. result := inherited ReallocateMemory(aOriginal, aSize, aAlignment, aScope);
  64. WriteLn(Format(' MEM - %d bytes of memory (from %p) reallocated at %p', [ aSize, p, result ]));
  65. end;
  66. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. procedure TCustomAllocHandler.FreeMemory(const aMemory: PVkVoid);
  68. begin
  69. WriteLn(Format(' MEM - free memory at %p', [ aMemory ]));
  70. inherited FreeMemory(aMemory);
  71. end;
  72. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  73. //TMainForm//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  75. procedure TMainForm.FormCreate(Sender: TObject);
  76. var
  77. PhyDevices: TVkPhysicalDeviceArr;
  78. InstanceFactory: TvkuInstanceFactory;
  79. DeviceFactory: TvkuDeviceFactory;
  80. SurfaceFactory: TvkuSurfaceFactory;
  81. CommandPoolFactory: TvkuCommandPoolFactory;
  82. SwapChainFactory: TvkuSwapChainFactory;
  83. ImageViewFactory: TvkuImageViewFactory;
  84. RenderPassFactory: TvkuRenderPassFactory;
  85. FrameBufferFactory: TvkuFrameBufferFactory;
  86. DescSetLayoutFactory: TvkuDescriptorSetLayoutFactory;
  87. PipelineLayoutFactory: TvkuPipelineLayoutFactory;
  88. ShaderModuleFactory: TvkuShaderModuleFactory;
  89. PipelineFactory: TvkuGraphicsPipelineFactory;
  90. QueueFamProps: TVkQueueFamilyPropertiesArr;
  91. DepthFormat: TVkFormat;
  92. f: TVkFormat;
  93. i: Integer;
  94. SrfFormats: TVkSurfaceFormatArr;
  95. SurfaceCapabilities: TVkSurfaceCapabilitiesKHR;
  96. PresentModes: TVkPresentModeArr;
  97. pm: TVkPresentModeKHR;
  98. Images: TVkImageArr;
  99. ComponentMapping: TVkComponentMapping;
  100. begin
  101. fAllocHandler := TCustomAllocHandler.Create;
  102. //////////////////////////////////////////////////////////////////////////////
  103. WriteLn('create instance: ');
  104. InstanceFactory := TvkuInstanceFactory.Create;
  105. try
  106. InstanceFactory.AllocHandler := fAllocHandler;
  107. InstanceFactory.EnabledExtensionNames.Add(VK_KHR_SURFACE_EXTENSION_NAME);
  108. InstanceFactory.EnabledExtensionNames.Add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
  109. InstanceFactory.EnabledExtensionNames.Add(TvkuSurface.GetPlatformSurfaceExtensionName);
  110. fInstance := InstanceFactory.CreateInstance;
  111. WriteLn(' handle: ', PtrUInt(fInstance.Handle));
  112. WriteLn(' done');
  113. finally
  114. FreeAndNil(InstanceFactory);
  115. end;
  116. fDebugReporter := TvkuConsoleDebugReporter.Create(fInstance.InstanceCommands, fAllocHandler);
  117. //////////////////////////////////////////////////////////////////////////////
  118. WriteLn('find suitable physical device');
  119. PhyDevices := fInstance.GetPhysicalDevices;
  120. if (Length(PhyDevices) <= 0) then
  121. raise TvkuException.Create('unable to get physical device');
  122. fPhyDevice := TvkuPhysicalDevice.Create(PhyDevices[0], fInstance.InstanceCommands);
  123. WriteLn(' handle: ', PtrUInt(fPhyDevice.Handle));
  124. Write(' find suitable graphics queue index... ');
  125. QueueFamProps := fPhyDevice.GetQueueFamilyProperties;
  126. fGraphicsQueueFamilyIndex := high(fGraphicsQueueFamilyIndex);
  127. for i := low(QueueFamProps) to high(QueueFamProps) do begin
  128. if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then begin
  129. fGraphicsQueueFamilyIndex := i;
  130. WriteLn(fGraphicsQueueFamilyIndex);
  131. break;
  132. end;
  133. end;
  134. if (fGraphicsQueueFamilyIndex = high(fGraphicsQueueFamilyIndex)) then
  135. raise TvkuException.Create('unable to find graphics queue index');
  136. Write(' find suitable depth format... ');
  137. f := VK_FORMAT_UNDEFINED;
  138. for f in [ VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM ] do begin
  139. if (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT in fPhyDevice.GetFormatProperties(f).optimalTilingFeatures) then begin
  140. DepthFormat := f;
  141. break;
  142. end;
  143. end;
  144. WriteLn(DepthFormat);
  145. WriteLn(' done');
  146. //////////////////////////////////////////////////////////////////////////////
  147. WriteLn('create device');
  148. DeviceFactory := TvkuDeviceFactory.Create(fInstance);
  149. try
  150. DeviceFactory.AllocHandler := fAllocHandler;
  151. DeviceFactory.EnabledExtensions.Add('VK_KHR_swapchain');
  152. DeviceFactory.QueueCreateInfos.Length := 1;
  153. with DeviceFactory.QueueCreateInfos[0] do begin
  154. Flags := 0;
  155. QueueFamilyIndex := fGraphicsQueueFamilyIndex;
  156. QueuePriorities.Length := 1;
  157. QueuePriorities[0] := 1.0;
  158. end;
  159. fDevice := DeviceFactory.CreateDevice(fPhyDevice.Handle);
  160. WriteLn(' handle: ', PtrUInt(fDevice.Handle));
  161. WriteLn(' done');
  162. finally
  163. FreeAndNil(DeviceFactory);
  164. end;
  165. //////////////////////////////////////////////////////////////////////////////
  166. WriteLn('find suitable queue');
  167. fQueue := TvkuQueue.Create(fDevice.GetQueue(fGraphicsQueueFamilyIndex, 0), fDevice.DeviceCommands);
  168. WriteLn(' handle: ', PtrUInt(fQueue.Handle));
  169. WriteLn(' done');
  170. //////////////////////////////////////////////////////////////////////////////
  171. WriteLn('create surface: ');
  172. SurfaceFactory := TvkuSurfaceFactory.Create(fInstance);
  173. try
  174. SurfaceFactory.AllocHandler := fAllocHandler;
  175. SurfaceFactory.WinControl := RenderPanel;
  176. fSurface := SurfaceFactory.CreateSurface;
  177. WriteLn(' handle: ', PtrUInt(fSurface.Handle));
  178. WriteLn(' find suitable graphics and present queue node index');
  179. fGraphicsQueueNodeIndex := high(fGraphicsQueueNodeIndex);
  180. fPresentQueueNodeIndex := high(fPresentQueueNodeIndex);
  181. QueueFamProps := fPhyDevice.GetQueueFamilyProperties;
  182. for i := low(QueueFamProps) to high(QueueFamProps) do begin
  183. if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then
  184. fGraphicsQueueNodeIndex := i;
  185. if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin
  186. fGraphicsQueueNodeIndex := i;
  187. fPresentQueueNodeIndex := i;
  188. break;
  189. end;
  190. end;
  191. if (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) then begin
  192. for i := low(QueueFamProps) to high(QueueFamProps) do begin
  193. if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin
  194. fPresentQueueNodeIndex := i;
  195. break;
  196. end;
  197. end;
  198. end;
  199. WriteLn(' graphics queue node index: ', fGraphicsQueueNodeIndex);
  200. WriteLn(' present queue node index: ', fPresentQueueNodeIndex);
  201. if (fGraphicsQueueNodeIndex = high(fGraphicsQueueNodeIndex)) or
  202. (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) or
  203. (fPresentQueueNodeIndex <> fGraphicsQueueNodeIndex) then
  204. raise TvkuException.Create('different graphic and present queue node index is not supported yet');
  205. WriteLn(' find suitable image format');
  206. SrfFormats := fPhyDevice.GetSurfaceFormats(fSurface.Handle);
  207. if (Length(SrfFormats) = 0) then
  208. raise TvkuException.Create('no suitable formats found');
  209. if (Length(SrfFormats) = 1) and (SrfFormats[0].format = VK_FORMAT_UNDEFINED) then begin
  210. fSurfaceFormat := VK_FORMAT_R8G8B8A8_UNORM;
  211. fSurfaceColorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR;
  212. end else begin
  213. fSurfaceFormat := SrfFormats[0].format;
  214. fSurfaceColorSpace := SrfFormats[0].colorSpace;
  215. end;
  216. WriteLn(' format: ', fSurfaceFormat);
  217. WriteLn(' color space: ', fSurfaceColorSpace);
  218. WriteLn(' done');
  219. finally
  220. FreeAndNil(SurfaceFactory);
  221. end;
  222. //////////////////////////////////////////////////////////////////////////////
  223. WriteLn('create command pool');
  224. CommandPoolFactory := TvkuCommandPoolFactory.Create(fDevice);
  225. try
  226. CommandPoolFactory.Flags := [ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT ];
  227. CommandPoolFactory.QueueFamilyIndex := fGraphicsQueueNodeIndex;
  228. fCommandPool := CommandPoolFactory.CreateCommandPool;
  229. WriteLn(' handle: ', PtrUInt(fCommandPool.Handle));
  230. WriteLn(' alloc command buffer');
  231. fCommandBuffer := TvkuCommandBuffer.Create(
  232. fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY),
  233. true, fCommandPool.Handle, fDevice.DeviceCommands);
  234. WriteLn(' handle: ', PtrUInt(fCommandBuffer.Handle));
  235. WriteLn(' done');
  236. finally
  237. FreeAndNil(CommandPoolFactory);
  238. end;
  239. //////////////////////////////////////////////////////////////////////////////
  240. WriteLn('create swap chain');
  241. SwapChainFactory := TvkuSwapChainFactory.Create(fDevice);
  242. try
  243. SwapChainFactory.AllocHandler := fAllocHandler;
  244. SwapChainFactory.Surface := fSurface.Handle;
  245. SwapChainFactory.ImageUsage := [ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ];
  246. SwapChainFactory.ImageArrayLayers := 1;
  247. SwapChainFactory.ImageSharingMode := VK_SHARING_MODE_EXCLUSIVE;
  248. SwapChainFactory.Clipped := true;
  249. SwapChainFactory.ComposideAlpha := [ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR ];
  250. SwapChainFactory.ImageFormat := fSurfaceFormat;
  251. SwapChainFactory.ImageColorSpace := fSurfaceColorSpace;
  252. WriteLn(' get surface capabilities');
  253. SurfaceCapabilities := fPhyDevice.GetSurfaceCapabilities(fSurface.Handle);
  254. if (SurfaceCapabilities.currentExtent.width = High(VkUint32)) then begin
  255. SurfaceCapabilities.currentExtent.width := ClientWidth;
  256. SurfaceCapabilities.currentExtent.height := ClientHeight;
  257. end else begin
  258. ClientWidth := SurfaceCapabilities.currentExtent.width;
  259. ClientHeight := SurfaceCapabilities.currentExtent.height;
  260. end;
  261. WriteLn(' width: ', SurfaceCapabilities.currentExtent.width);
  262. WriteLn(' height: ', SurfaceCapabilities.currentExtent.height);
  263. SwapChainFactory.ImageExtent := SurfaceCapabilities.currentExtent;
  264. Write(' set min image count... ');
  265. SwapChainFactory.MinImageCount := SurfaceCapabilities.minImageCount + 1;
  266. if (SurfaceCapabilities.maxImageCount > 0) and
  267. (SwapChainFactory.MinImageCount > SurfaceCapabilities.maxImageCount) then
  268. SwapChainFactory.MinImageCount := SurfaceCapabilities.maxImageCount;
  269. WriteLn(SwapChainFactory.MinImageCount);
  270. WriteLn(' set pre transform...');
  271. SwapChainFactory.PreTransform := SurfaceCapabilities.currentTransform;
  272. if (VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR in SurfaceCapabilities.supportedTransforms) then
  273. SwapChainFactory.PreTransform := [ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR ];
  274. Write(' find suitable present mode... ');
  275. PresentModes := fPhyDevice.GetSurfacePresentModes(fSurface.Handle);
  276. if (Length(PresentModes) = 0) then
  277. raise TvkuException.Create('unable to get present modes');
  278. for pm in PresentModes do begin
  279. if (pm = VK_PRESENT_MODE_MAILBOX_KHR) then begin
  280. SwapChainFactory.PresentMode := pm;
  281. break;
  282. end;
  283. end;
  284. WriteLn(SwapChainFactory.PresentMode);
  285. fSwapChain := SwapChainFactory.CreateSwapchain;
  286. WriteLn(' handle: ', PtrUInt(fSwapChain.Handle));
  287. WriteLn(' done');
  288. finally
  289. FreeAndNil(SwapChainFactory);
  290. end;
  291. //////////////////////////////////////////////////////////////////////////////
  292. WriteLn('create image views');
  293. Images := fSwapChain.GetImages;
  294. SetLength(fImageViews, Length(Images));
  295. ImageViewFactory := TvkuImageViewFactory.Create(fDevice);
  296. try
  297. ImageViewFactory.AllocHandler := fAllocHandler;
  298. ImageViewFactory.Format := fSurfaceFormat;
  299. ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D;
  300. with ImageViewFactory.SubresourceRange do begin
  301. AspectMask := [ VK_IMAGE_ASPECT_COLOR_BIT ];
  302. BaseMipLevel := 0;
  303. LevelCount := 1;
  304. BaseArrayLayer := 0;
  305. LayerCount := 1;
  306. end;
  307. with ImageViewFactory.Components do begin
  308. r := VK_COMPONENT_SWIZZLE_R;
  309. g := VK_COMPONENT_SWIZZLE_G;
  310. b := VK_COMPONENT_SWIZZLE_B;
  311. a := VK_COMPONENT_SWIZZLE_A;
  312. end;
  313. for i := Low(fImageViews) to High(fImageViews) do begin
  314. // TODO create image barrier
  315. ImageViewFactory.Image := Images[i];
  316. fImageViews[i] := ImageViewFactory.CreateImageView;
  317. WriteLn(' handle: ', PtrUInt(fImageViews[i].Handle));
  318. end;
  319. WriteLn(' done');
  320. finally
  321. FreeAndNil(ImageViewFactory);
  322. end;
  323. //////////////////////////////////////////////////////////////////////////////
  324. WriteLn('create render pass');
  325. RenderPassFactory := TvkuRenderPassFactory.Create(fDevice);
  326. try
  327. RenderPassFactory.Attachments.Length := 2;
  328. with RenderPassFactory.Attachments[0] do begin
  329. Format := fSurfaceFormat;
  330. Samples := [ VK_SAMPLE_COUNT_1_BIT ];
  331. LoadOp := VK_ATTACHMENT_LOAD_OP_CLEAR;
  332. StoreOp := VK_ATTACHMENT_STORE_OP_STORE;
  333. StencilLoadOp := VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  334. StencilStoreOp := VK_ATTACHMENT_STORE_OP_DONT_CARE;
  335. InitialLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  336. FinalLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  337. end;
  338. with RenderPassFactory.Attachments[1] do begin
  339. Format := DepthFormat;
  340. Samples := [ VK_SAMPLE_COUNT_1_BIT ];
  341. LoadOp := VK_ATTACHMENT_LOAD_OP_CLEAR;
  342. StoreOp := VK_ATTACHMENT_STORE_OP_STORE;
  343. StencilLoadOp := VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  344. StencilStoreOp := VK_ATTACHMENT_STORE_OP_DONT_CARE;
  345. InitialLayout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  346. FinalLayout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  347. end;
  348. RenderPassFactory.Subpasses.Length := 1;
  349. with RenderPassFactory.Subpasses[0] do begin
  350. PipelineBindPoint := VK_PIPELINE_BIND_POINT_GRAPHICS;
  351. ColorAttachments.Length := 1;
  352. ColorAttachments[0].Attachment := 0;
  353. ColorAttachments[0].Layout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  354. DepthStencilAttachments.Length := 1;
  355. DepthStencilAttachments[0].Attachment := 1;
  356. DepthStencilAttachments[0].Layout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  357. end;
  358. RenderPassFactory.AllocHandler := fAllocHandler;
  359. fRenderPass := RenderPassFactory.CreateRenderPass;
  360. WriteLn(' handle: ', PtrUInt(fRenderPass.Handle));
  361. WriteLn(' done');
  362. finally
  363. FreeAndNil(RenderPassFactory);
  364. end;
  365. //////////////////////////////////////////////////////////////////////////////
  366. WriteLn('create frame buffers');
  367. FrameBufferFactory := TvkuFrameBufferFactory.Create(fDevice);
  368. try
  369. SetLength(fFrameBuffers, Length(fImageViews));
  370. FrameBufferFactory.AllocHandler := fAllocHandler;
  371. FrameBufferFactory.RenderPass := fRenderPass.Handle;
  372. FrameBufferFactory.Width := SurfaceCapabilities.currentExtent.width;
  373. FrameBufferFactory.Height := SurfaceCapabilities.currentExtent.height;
  374. FrameBufferFactory.Layers := 1;
  375. FrameBufferFactory.Attachments.Length := 1;
  376. for i := low(fFrameBuffers) to high(fFrameBuffers) do begin
  377. FrameBufferFactory.Attachments[0] := fImageViews[i].Handle;
  378. fFrameBuffers[i] := FrameBufferFactory.CreateFrameBuffer;
  379. WriteLn(' handle: ', PtrUInt(fFrameBuffers[i].Handle));
  380. end;
  381. WriteLn(' done');
  382. finally
  383. FreeAndNil(FrameBufferFactory);
  384. end;
  385. //////////////////////////////////////////////////////////////////////////////
  386. WriteLn('create descriptor set layout');
  387. DescSetLayoutFactory := TvkuDescriptorSetLayoutFactory.Create(fDevice);
  388. try
  389. DescSetLayoutFactory.Bindings.Length := 1;
  390. with DescSetLayoutFactory.Bindings[0] do begin
  391. Binding := 0; // binding 0 (Uniform Buffer/Vertex Shader)
  392. DescriptorType := VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  393. DescriptorCount := 1;
  394. StageFlags := [ VK_SHADER_STAGE_VERTEX_BIT ];
  395. end;
  396. DescSetLayoutFactory.AllocHandler := fAllocHandler;
  397. fDescSetLayout := DescSetLayoutFactory.CreateDescriptorSetLayout;
  398. WriteLn(' handle: ', PtrUInt(fDescSetLayout.Handle));
  399. WriteLn(' done');
  400. finally
  401. FreeAndNil(DescSetLayoutFactory);
  402. end;
  403. //////////////////////////////////////////////////////////////////////////////
  404. WriteLn('create pipeline layout');
  405. PipelineLayoutFactory := TvkuPipelineLayoutFactory.Create(fDevice);
  406. try
  407. PipelineLayoutFactory.AllocHandler := fAllocHandler;
  408. PipelineLayoutFactory.SetLayouts.Length := 1;
  409. PipelineLayoutFactory.SetLayouts[0] := fDescSetLayout.Handle;
  410. fPipelineLayout := PipelineLayoutFactory.CreatePipelineLayout;
  411. WriteLn(' handle: ', PtrUInt(fPipelineLayout.Handle));
  412. WriteLn(' done');
  413. finally
  414. FreeAndNil(PipelineLayoutFactory);
  415. end;
  416. //////////////////////////////////////////////////////////////////////////////
  417. WriteLn('create shader modules');
  418. ShaderModuleFactory := TvkuShaderModuleFactory.Create(fDevice);
  419. try
  420. ShaderModuleFactory.AllocHandler := fAllocHandler;
  421. ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.vert', [ VK_SHADER_STAGE_VERTEX_BIT ]);
  422. fVertexShader := ShaderModuleFactory.CreateShaderModule;
  423. WriteLn(' vertex handle: ', PtrUInt(fVertexShader.Handle));
  424. ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag', [ VK_SHADER_STAGE_FRAGMENT_BIT ]);
  425. fFragmentShader := ShaderModuleFactory.CreateShaderModule;
  426. WriteLn(' fragment handle: ', PtrUInt(fFragmentShader.Handle));
  427. WriteLn(' done');
  428. finally
  429. FreeAndNil(ShaderModuleFactory);
  430. end;
  431. //////////////////////////////////////////////////////////////////////////////
  432. WriteLn('create graphics pipeline');
  433. PipelineFactory := TvkuGraphicsPipelineFactory.Create(fDevice);
  434. try
  435. PipelineFactory.AllocHandler := fAllocHandler;
  436. // TODO fPipeline := PipelineFactory.CreateGraphicsPipeline(VK_INVALID_NDP_HANDLE);
  437. finally
  438. FreeAndNil(PipelineFactory);
  439. end;
  440. end;
  441. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  442. procedure TMainForm.FormDestroy(Sender: TObject);
  443. procedure FreeAndNilFrameBuffers;
  444. var i: Integer;
  445. begin
  446. for i := Low(fFrameBuffers) to High(fFrameBuffers) do
  447. FreeAndNil(fFrameBuffers[i]);
  448. SetLength(fFrameBuffers, 0);
  449. end;
  450. procedure FreeAndNilImageViews;
  451. var i: Integer;
  452. begin
  453. for i := Low(fImageViews) to High(fImageViews) do
  454. FreeAndNil(fImageViews[i]);
  455. SetLength(fImageViews, 0);
  456. end;
  457. begin
  458. FreeAndNil(fPipeline);
  459. FreeAndNil(fFragmentShader);
  460. FreeAndNil(fVertexShader);
  461. FreeAndNil(fPipelineLayout);
  462. FreeAndNil(fDescSetLayout);
  463. FreeAndNilFrameBuffers;
  464. FreeAndNil(fRenderPass);
  465. FreeAndNilImageViews;
  466. FreeAndNil(fSwapChain);
  467. FreeAndNil(fSurface);
  468. FreeAndNil(fQueue);
  469. FreeAndNil(fDevice);
  470. FreeAndNil(fPhyDevice);
  471. FreeAndNil(fDebugReporter);
  472. FreeAndNil(fInstance);
  473. FreeAndNil(fAllocHandler);
  474. end;
  475. end.