Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

676 rindas
28 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. fDepthFormat: TVkFormat;
  27. fAllocHandler: TCustomAllocHandler;
  28. fDebugReporter: TvkuConsoleDebugReporter;
  29. fInstance: TvkuInstance;
  30. fPhyDevice: TvkuPhysicalDevice;
  31. fDevice: TvkuDevice;
  32. fQueue: TvkuQueue;
  33. fSurface: TvkuSurface;
  34. fSwapChain: TvkuSwapChain;
  35. fImages: array of TvkuImage;
  36. fImageViews: array of TvkuImageView;
  37. fRenderPass: TvkuRenderPass;
  38. fFrameBuffers: array of TvkuFrameBuffer;
  39. fDescSetLayout: TvkuDescriptorSetLayout;
  40. fPipelineLayout: TvkuPipelineLayout;
  41. fVertexShader: TvkuShaderModule;
  42. fFragmentShader: TvkuShaderModule;
  43. fPipeline: TvkuGraphicsPipeline;
  44. fCommandPool: TvkuCommandPool;
  45. fDrawCommandBuffers: array of TvkuCommandBuffer;
  46. fPostPresentCommandBuffer: TvkuCommandBuffer;
  47. fDepthStencilImage: TvkuImage;
  48. fDepthStencilImageView: TvkuImageView;
  49. fPipelineCache: TvkuPipelineCache;
  50. end;
  51. var
  52. MainForm: TMainForm;
  53. implementation
  54. {$R *.lfm}
  55. {$I Vulkan.inc}
  56. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. //TCustomAllocHandler////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. function TCustomAllocHandler.AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
  60. begin
  61. result := inherited AllocateMemory(aSize, aAlignment, aScope);
  62. WriteLn(Format(' MEM - %d bytes of memory allocated at %p', [ aSize, result ]));
  63. end;
  64. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. function TCustomAllocHandler.ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
  66. var p: PVkVoid;
  67. begin
  68. p := aOriginal;
  69. result := inherited ReallocateMemory(aOriginal, aSize, aAlignment, aScope);
  70. WriteLn(Format(' MEM - %d bytes of memory (from %p) reallocated at %p', [ aSize, p, result ]));
  71. end;
  72. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  73. procedure TCustomAllocHandler.FreeMemory(const aMemory: PVkVoid);
  74. begin
  75. WriteLn(Format(' MEM - free memory at %p', [ aMemory ]));
  76. inherited FreeMemory(aMemory);
  77. end;
  78. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  79. //TMainForm//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  80. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. procedure TMainForm.FormCreate(Sender: TObject);
  82. var
  83. PhyDevices: TVkPhysicalDeviceArr;
  84. InstanceFactory: TvkuInstanceFactory;
  85. DeviceFactory: TvkuDeviceFactory;
  86. SurfaceFactory: TvkuSurfaceFactory;
  87. CommandPoolFactory: TvkuCommandPoolFactory;
  88. SwapChainFactory: TvkuSwapChainFactory;
  89. ImageFactory: TvkuImageFactory;
  90. ImageViewFactory: TvkuImageViewFactory;
  91. RenderPassFactory: TvkuRenderPassFactory;
  92. FrameBufferFactory: TvkuFrameBufferFactory;
  93. DescSetLayoutFactory: TvkuDescriptorSetLayoutFactory;
  94. PipelineLayoutFactory: TvkuPipelineLayoutFactory;
  95. ShaderModuleFactory: TvkuShaderModuleFactory;
  96. PipelineFactory: TvkuGraphicsPipelineFactory;
  97. PipelineCacheFactory: TvkuPipelineCacheFactory;
  98. SetupCommandBuffer: TvkuCommandBuffer;
  99. QueueFamProps: TVkQueueFamilyPropertiesArr;
  100. f: TVkFormat;
  101. i: Integer;
  102. SrfFormats: TVkSurfaceFormatArr;
  103. SurfaceCapabilities: TVkSurfaceCapabilitiesKHR;
  104. PresentModes: TVkPresentModeArr;
  105. pm: TVkPresentModeKHR;
  106. Images: TVkImageArr;
  107. AllocCallbacks: TVkAllocationCallbacks;
  108. ImageMemoryBarrier: TVkImageMemoryBarrier;
  109. CommandBuffers: TVkCommandBufferArr;
  110. begin
  111. try
  112. fAllocHandler := TCustomAllocHandler.Create;
  113. AllocCallbacks := fAllocHandler.GetStructure;
  114. //////////////////////////////////////////////////////////////////////////////
  115. WriteLn('create instance: ');
  116. InstanceFactory := TvkuInstanceFactory.Create;
  117. try
  118. InstanceFactory.AllocHandler := fAllocHandler;
  119. InstanceFactory.EnabledExtensionNames.Add(VK_KHR_SURFACE_EXTENSION_NAME);
  120. InstanceFactory.EnabledExtensionNames.Add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
  121. InstanceFactory.EnabledExtensionNames.Add(TvkuSurface.GetPlatformSurfaceExtensionName);
  122. fInstance := InstanceFactory.CreateInstance;
  123. WriteLn(' handle: ', PtrUInt(fInstance.Handle));
  124. WriteLn(' done');
  125. finally
  126. FreeAndNil(InstanceFactory);
  127. end;
  128. fDebugReporter := TvkuConsoleDebugReporter.Create(fInstance.InstanceCommands, fAllocHandler);
  129. //////////////////////////////////////////////////////////////////////////////
  130. WriteLn('find suitable physical device');
  131. PhyDevices := fInstance.GetPhysicalDevices;
  132. if (Length(PhyDevices) <= 0) then
  133. raise TvkuException.Create('unable to get physical device');
  134. fPhyDevice := TvkuPhysicalDevice.Create(PhyDevices[0], fInstance.InstanceCommands);
  135. WriteLn(' handle: ', PtrUInt(fPhyDevice.Handle));
  136. Write(' find suitable graphics queue index... ');
  137. QueueFamProps := fPhyDevice.GetQueueFamilyProperties;
  138. fGraphicsQueueFamilyIndex := high(fGraphicsQueueFamilyIndex);
  139. for i := low(QueueFamProps) to high(QueueFamProps) do begin
  140. if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then begin
  141. fGraphicsQueueFamilyIndex := i;
  142. WriteLn(fGraphicsQueueFamilyIndex);
  143. break;
  144. end;
  145. end;
  146. if (fGraphicsQueueFamilyIndex = high(fGraphicsQueueFamilyIndex)) then
  147. raise TvkuException.Create('unable to find graphics queue index');
  148. Write(' find suitable depth format... ');
  149. f := VK_FORMAT_UNDEFINED;
  150. for f in [ VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM ] do begin
  151. if (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT in fPhyDevice.GetFormatProperties(f).optimalTilingFeatures) then begin
  152. fDepthFormat := f;
  153. break;
  154. end;
  155. end;
  156. WriteLn(fDepthFormat);
  157. WriteLn(' done');
  158. //////////////////////////////////////////////////////////////////////////////
  159. WriteLn('create device');
  160. DeviceFactory := TvkuDeviceFactory.Create(fInstance);
  161. try
  162. DeviceFactory.AllocHandler := fAllocHandler;
  163. DeviceFactory.EnabledExtensions.Add('VK_KHR_swapchain');
  164. DeviceFactory.QueueCreateInfos.Length := 1;
  165. with DeviceFactory.QueueCreateInfos[0] do begin
  166. Flags := 0;
  167. QueueFamilyIndex := fGraphicsQueueFamilyIndex;
  168. QueuePriorities.Length := 1;
  169. QueuePriorities[0] := 1.0;
  170. end;
  171. fDevice := DeviceFactory.CreateDevice(fPhyDevice.Handle);
  172. WriteLn(' handle: ', PtrUInt(fDevice.Handle));
  173. WriteLn(' done');
  174. finally
  175. FreeAndNil(DeviceFactory);
  176. end;
  177. //////////////////////////////////////////////////////////////////////////////
  178. WriteLn('find suitable queue');
  179. fQueue := TvkuQueue.Create(fDevice.GetQueue(fGraphicsQueueFamilyIndex, 0), fDevice.DeviceCommands);
  180. WriteLn(' handle: ', PtrUInt(fQueue.Handle));
  181. WriteLn(' done');
  182. //////////////////////////////////////////////////////////////////////////////
  183. WriteLn('create surface: ');
  184. SurfaceFactory := TvkuSurfaceFactory.Create(fInstance);
  185. try
  186. SurfaceFactory.AllocHandler := fAllocHandler;
  187. SurfaceFactory.WinControl := RenderPanel;
  188. fSurface := SurfaceFactory.CreateSurface;
  189. WriteLn(' handle: ', PtrUInt(fSurface.Handle));
  190. WriteLn(' find suitable graphics and present queue node index');
  191. fGraphicsQueueNodeIndex := high(fGraphicsQueueNodeIndex);
  192. fPresentQueueNodeIndex := high(fPresentQueueNodeIndex);
  193. QueueFamProps := fPhyDevice.GetQueueFamilyProperties;
  194. for i := low(QueueFamProps) to high(QueueFamProps) do begin
  195. if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then
  196. fGraphicsQueueNodeIndex := i;
  197. if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin
  198. fGraphicsQueueNodeIndex := i;
  199. fPresentQueueNodeIndex := i;
  200. break;
  201. end;
  202. end;
  203. if (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) then begin
  204. for i := low(QueueFamProps) to high(QueueFamProps) do begin
  205. if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin
  206. fPresentQueueNodeIndex := i;
  207. break;
  208. end;
  209. end;
  210. end;
  211. WriteLn(' graphics queue node index: ', fGraphicsQueueNodeIndex);
  212. WriteLn(' present queue node index: ', fPresentQueueNodeIndex);
  213. if (fGraphicsQueueNodeIndex = high(fGraphicsQueueNodeIndex)) or
  214. (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) or
  215. (fPresentQueueNodeIndex <> fGraphicsQueueNodeIndex) then
  216. raise TvkuException.Create('different graphic and present queue node index is not supported yet');
  217. WriteLn(' find suitable image format');
  218. SrfFormats := fPhyDevice.GetSurfaceFormats(fSurface.Handle);
  219. if (Length(SrfFormats) = 0) then
  220. raise TvkuException.Create('no suitable formats found');
  221. if (Length(SrfFormats) = 1) and (SrfFormats[0].format = VK_FORMAT_UNDEFINED) then begin
  222. fSurfaceFormat := VK_FORMAT_R8G8B8A8_UNORM;
  223. fSurfaceColorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR;
  224. end else begin
  225. fSurfaceFormat := SrfFormats[0].format;
  226. fSurfaceColorSpace := SrfFormats[0].colorSpace;
  227. end;
  228. WriteLn(' format: ', fSurfaceFormat);
  229. WriteLn(' color space: ', fSurfaceColorSpace);
  230. WriteLn(' done');
  231. finally
  232. FreeAndNil(SurfaceFactory);
  233. end;
  234. //////////////////////////////////////////////////////////////////////////////
  235. WriteLn('create command pool');
  236. CommandPoolFactory := TvkuCommandPoolFactory.Create(fDevice);
  237. try
  238. CommandPoolFactory.Flags := [ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT ];
  239. CommandPoolFactory.QueueFamilyIndex := fGraphicsQueueNodeIndex;
  240. fCommandPool := CommandPoolFactory.CreateCommandPool;
  241. WriteLn(' handle: ', PtrUInt(fCommandPool.Handle));
  242. WriteLn(' alloc setup command buffer');
  243. SetupCommandBuffer := TvkuCommandBuffer.Create(
  244. fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY),
  245. true, fCommandPool.Handle, fDevice.DeviceCommands);
  246. SetupCommandBuffer.BeginCommand;
  247. WriteLn(' handle: ', PtrUInt(SetupCommandBuffer.Handle));
  248. WriteLn(' done');
  249. finally
  250. FreeAndNil(CommandPoolFactory);
  251. end;
  252. //////////////////////////////////////////////////////////////////////////////
  253. WriteLn('create swap chain');
  254. SwapChainFactory := TvkuSwapChainFactory.Create(fDevice);
  255. try
  256. SwapChainFactory.AllocHandler := fAllocHandler;
  257. SwapChainFactory.Surface := fSurface.Handle;
  258. SwapChainFactory.ImageUsage := [ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ];
  259. SwapChainFactory.ImageArrayLayers := 1;
  260. SwapChainFactory.ImageSharingMode := VK_SHARING_MODE_EXCLUSIVE;
  261. SwapChainFactory.Clipped := true;
  262. SwapChainFactory.ComposideAlpha := [ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR ];
  263. SwapChainFactory.ImageFormat := fSurfaceFormat;
  264. SwapChainFactory.ImageColorSpace := fSurfaceColorSpace;
  265. WriteLn(' get surface capabilities');
  266. SurfaceCapabilities := fPhyDevice.GetSurfaceCapabilities(fSurface.Handle);
  267. if (SurfaceCapabilities.currentExtent.width = High(VkUint32)) then begin
  268. SurfaceCapabilities.currentExtent.width := ClientWidth;
  269. SurfaceCapabilities.currentExtent.height := ClientHeight;
  270. end else begin
  271. ClientWidth := SurfaceCapabilities.currentExtent.width;
  272. ClientHeight := SurfaceCapabilities.currentExtent.height;
  273. end;
  274. WriteLn(' width: ', SurfaceCapabilities.currentExtent.width);
  275. WriteLn(' height: ', SurfaceCapabilities.currentExtent.height);
  276. SwapChainFactory.ImageExtent := SurfaceCapabilities.currentExtent;
  277. Write(' set min image count... ');
  278. SwapChainFactory.MinImageCount := SurfaceCapabilities.minImageCount + 1;
  279. if (SurfaceCapabilities.maxImageCount > 0) and
  280. (SwapChainFactory.MinImageCount > SurfaceCapabilities.maxImageCount) then
  281. SwapChainFactory.MinImageCount := SurfaceCapabilities.maxImageCount;
  282. WriteLn(SwapChainFactory.MinImageCount);
  283. WriteLn(' set pre transform...');
  284. SwapChainFactory.PreTransform := SurfaceCapabilities.currentTransform;
  285. if (VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR in SurfaceCapabilities.supportedTransforms) then
  286. SwapChainFactory.PreTransform := [ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR ];
  287. Write(' find suitable present mode... ');
  288. PresentModes := fPhyDevice.GetSurfacePresentModes(fSurface.Handle);
  289. if (Length(PresentModes) = 0) then
  290. raise TvkuException.Create('unable to get present modes');
  291. for pm in PresentModes do begin
  292. if (pm = VK_PRESENT_MODE_MAILBOX_KHR) then begin
  293. SwapChainFactory.PresentMode := pm;
  294. break;
  295. end;
  296. end;
  297. WriteLn(SwapChainFactory.PresentMode);
  298. fSwapChain := SwapChainFactory.CreateSwapchain;
  299. WriteLn(' handle: ', PtrUInt(fSwapChain.Handle));
  300. WriteLn(' done');
  301. finally
  302. FreeAndNil(SwapChainFactory);
  303. end;
  304. //////////////////////////////////////////////////////////////////////////////
  305. WriteLn('create images and image views');
  306. Images := fSwapChain.GetImages;
  307. SetLength(fImages, Length(Images));
  308. SetLength(fImageViews, Length(Images));
  309. ImageViewFactory := TvkuImageViewFactory.Create(fDevice);
  310. try
  311. ImageViewFactory.AllocHandler := fAllocHandler;
  312. ImageViewFactory.Format := fSurfaceFormat;
  313. ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D;
  314. with ImageViewFactory.SubresourceRange do begin
  315. AspectMask := [ VK_IMAGE_ASPECT_COLOR_BIT ];
  316. BaseMipLevel := 0;
  317. LevelCount := 1;
  318. BaseArrayLayer := 0;
  319. LayerCount := 1;
  320. end;
  321. with ImageViewFactory.Components do begin
  322. r := VK_COMPONENT_SWIZZLE_R;
  323. g := VK_COMPONENT_SWIZZLE_G;
  324. b := VK_COMPONENT_SWIZZLE_B;
  325. a := VK_COMPONENT_SWIZZLE_A;
  326. end;
  327. for i := Low(fImageViews) to High(fImageViews) do begin
  328. fImages[i] := TvkuImage.Create(Images[i], false, fDevice.DeviceCommands, @AllocCallbacks);
  329. WriteLn(' image handle: ', PtrUInt(fImages[i].Handle));
  330. ImageMemoryBarrier := fImages[i].GetMemoryBarrier(
  331. [ VK_IMAGE_ASPECT_COLOR_BIT ],
  332. VK_IMAGE_LAYOUT_UNDEFINED,
  333. VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
  334. SetupCommandBuffer.PipelineBarrier(
  335. [ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ],
  336. [ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ],
  337. [],
  338. [],
  339. [],
  340. [ ImageMemoryBarrier ]);
  341. ImageViewFactory.Image := fImages[i].Handle;
  342. fImageViews[i] := ImageViewFactory.CreateImageView;
  343. WriteLn(' view handle: ', PtrUInt(fImageViews[i].Handle));
  344. end;
  345. WriteLn(' done');
  346. finally
  347. FreeAndNil(ImageViewFactory);
  348. end;
  349. //////////////////////////////////////////////////////////////////////////////
  350. WriteLn('create draw command buffers');
  351. SetLength(fDrawCommandBuffers, Length(fImageViews));
  352. CommandBuffers := fCommandPool.CreateCommandBuffers(
  353. VK_COMMAND_BUFFER_LEVEL_PRIMARY,
  354. Length(fDrawCommandBuffers));
  355. for i := low(CommandBuffers) to high(CommandBuffers) do begin
  356. fDrawCommandBuffers[i] := TvkuCommandBuffer.Create(
  357. CommandBuffers[i],
  358. true,
  359. fCommandPool.Handle,
  360. fDevice.DeviceCommands);
  361. WriteLn(' handle: ', PtrUInt(fDrawCommandBuffers[i].Handle));
  362. end;
  363. WriteLn(' done');
  364. //////////////////////////////////////////////////////////////////////////////
  365. WriteLn('create post present command buffers');
  366. fPostPresentCommandBuffer := TvkuCommandBuffer.Create(
  367. fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY),
  368. true,
  369. fCommandPool.Handle,
  370. fDevice.DeviceCommands);
  371. WriteLn(' handle: ', PtrUInt(fPostPresentCommandBuffer.Handle));
  372. WriteLn(' done');
  373. //////////////////////////////////////////////////////////////////////////////
  374. WriteLn('create depth stencil image and image view');
  375. ImageFactory := TvkuImageFactory.Create(fDevice);
  376. ImageViewFactory := TvkuImageViewFactory.Create(fDevice);
  377. try
  378. ImageFactory.ImageType := VK_IMAGE_TYPE_2D;
  379. ImageFactory.Format := fDepthFormat;
  380. ImageFactory.Extent := vkExtent3D(
  381. SurfaceCapabilities.currentExtent.width,
  382. SurfaceCapabilities.currentExtent.height,
  383. 1);
  384. ImageFactory.MipLevels := 1;
  385. ImageFactory.ArrayLayers := 1;
  386. ImageFactory.Samples := [ VK_SAMPLE_COUNT_1_BIT ];
  387. ImageFactory.Tiling := VK_IMAGE_TILING_OPTIMAL;
  388. ImageFactory.Usage := [ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ];
  389. fDepthStencilImage := ImageFactory.CreateImage;
  390. fDepthStencilImage.AllocateAndBindImageMemory(
  391. fPhyDevice.GetMemoryProperties,
  392. @AllocCallbacks);
  393. WriteLn(' image handle: ', PtrUInt(fDepthStencilImage.Handle));
  394. ImageViewFactory.Image := fDepthStencilImage.Handle;
  395. ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D;
  396. ImageViewFactory.Format := fDepthFormat;
  397. with ImageViewFactory.SubresourceRange do begin
  398. AspectMask := [ VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_STENCIL_BIT ];
  399. BaseMipLevel := 0;
  400. LevelCount := 1;
  401. BaseArrayLayer := 0;
  402. LayerCount := 1;
  403. end;
  404. fDepthStencilImageView := ImageViewFactory.CreateImageView;
  405. WriteLn(' view handle: ', PtrUInt(fDepthStencilImageView.Handle));
  406. WriteLn(' done');
  407. finally
  408. FreeAndNil(ImageViewFactory);
  409. FreeAndNil(ImageFactory);
  410. end;
  411. //////////////////////////////////////////////////////////////////////////////
  412. WriteLn('create render pass');
  413. RenderPassFactory := TvkuRenderPassFactory.Create(fDevice);
  414. try
  415. RenderPassFactory.Attachments.Length := 2;
  416. with RenderPassFactory.Attachments[0] do begin
  417. Format := fSurfaceFormat;
  418. Samples := [ VK_SAMPLE_COUNT_1_BIT ];
  419. LoadOp := VK_ATTACHMENT_LOAD_OP_CLEAR;
  420. StoreOp := VK_ATTACHMENT_STORE_OP_STORE;
  421. StencilLoadOp := VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  422. StencilStoreOp := VK_ATTACHMENT_STORE_OP_DONT_CARE;
  423. InitialLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  424. FinalLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  425. end;
  426. with RenderPassFactory.Attachments[1] do begin
  427. Format := fDepthFormat;
  428. Samples := [ VK_SAMPLE_COUNT_1_BIT ];
  429. LoadOp := VK_ATTACHMENT_LOAD_OP_CLEAR;
  430. StoreOp := VK_ATTACHMENT_STORE_OP_STORE;
  431. StencilLoadOp := VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  432. StencilStoreOp := VK_ATTACHMENT_STORE_OP_DONT_CARE;
  433. InitialLayout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  434. FinalLayout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  435. end;
  436. RenderPassFactory.Subpasses.Length := 1;
  437. with RenderPassFactory.Subpasses[0] do begin
  438. PipelineBindPoint := VK_PIPELINE_BIND_POINT_GRAPHICS;
  439. ColorAttachments.Length := 1;
  440. ColorAttachments[0].Attachment := 0;
  441. ColorAttachments[0].Layout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  442. DepthStencilAttachments.Length := 1;
  443. DepthStencilAttachments[0].Attachment := 1;
  444. DepthStencilAttachments[0].Layout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  445. end;
  446. RenderPassFactory.AllocHandler := fAllocHandler;
  447. fRenderPass := RenderPassFactory.CreateRenderPass;
  448. WriteLn(' handle: ', PtrUInt(fRenderPass.Handle));
  449. WriteLn(' done');
  450. finally
  451. FreeAndNil(RenderPassFactory);
  452. end;
  453. //////////////////////////////////////////////////////////////////////////////
  454. WriteLn('create pipeline cache');
  455. PipelineCacheFactory := TvkuPipelineCacheFactory.Create(fDevice);
  456. try
  457. fPipelineCache := PipelineCacheFactory.CreatePipelineCache;
  458. WriteLn(' handle: ', PtrUInt(fPipelineCache.Handle));
  459. WriteLn(' done');
  460. finally
  461. FreeAndNil(PipelineCacheFactory);
  462. end;
  463. //////////////////////////////////////////////////////////////////////////////
  464. WriteLn('create frame buffers');
  465. FrameBufferFactory := TvkuFrameBufferFactory.Create(fDevice);
  466. try
  467. SetLength(fFrameBuffers, Length(fImageViews));
  468. FrameBufferFactory.AllocHandler := fAllocHandler;
  469. FrameBufferFactory.RenderPass := fRenderPass.Handle;
  470. FrameBufferFactory.Width := SurfaceCapabilities.currentExtent.width;
  471. FrameBufferFactory.Height := SurfaceCapabilities.currentExtent.height;
  472. FrameBufferFactory.Layers := 1;
  473. FrameBufferFactory.Attachments.Length := 2;
  474. FrameBufferFactory.Attachments[1] := fDepthStencilImageView.Handle;
  475. for i := low(fFrameBuffers) to high(fFrameBuffers) do begin
  476. FrameBufferFactory.Attachments[0] := fImageViews[i].Handle;
  477. fFrameBuffers[i] := FrameBufferFactory.CreateFrameBuffer;
  478. WriteLn(' handle: ', PtrUInt(fFrameBuffers[i].Handle));
  479. end;
  480. WriteLn(' done');
  481. finally
  482. FreeAndNil(FrameBufferFactory);
  483. end;
  484. //////////////////////////////////////////////////////////////////////////////
  485. WriteLn('flush setup command buffer');
  486. SetupCommandBuffer.EndCommand;
  487. fQueue.Submit([], [], [ SetupCommandBuffer.Handle ], [], VK_INVALID_NDP_HANDLE);
  488. fQueue.WaitIdle;
  489. FreeAndNil(SetupCommandBuffer);
  490. WriteLn(' done');
  491. //////////////////////////////////////////////////////////////////////////////
  492. WriteLn('create descriptor set layout');
  493. DescSetLayoutFactory := TvkuDescriptorSetLayoutFactory.Create(fDevice);
  494. try
  495. DescSetLayoutFactory.Bindings.Length := 1;
  496. with DescSetLayoutFactory.Bindings[0] do begin
  497. Binding := 0; // binding 0 (Uniform Buffer/Vertex Shader)
  498. DescriptorType := VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  499. DescriptorCount := 1;
  500. StageFlags := [ VK_SHADER_STAGE_VERTEX_BIT ];
  501. end;
  502. DescSetLayoutFactory.AllocHandler := fAllocHandler;
  503. fDescSetLayout := DescSetLayoutFactory.CreateDescriptorSetLayout;
  504. WriteLn(' handle: ', PtrUInt(fDescSetLayout.Handle));
  505. WriteLn(' done');
  506. finally
  507. FreeAndNil(DescSetLayoutFactory);
  508. end;
  509. //////////////////////////////////////////////////////////////////////////////
  510. WriteLn('create pipeline layout');
  511. PipelineLayoutFactory := TvkuPipelineLayoutFactory.Create(fDevice);
  512. try
  513. PipelineLayoutFactory.AllocHandler := fAllocHandler;
  514. PipelineLayoutFactory.SetLayouts.Length := 1;
  515. PipelineLayoutFactory.SetLayouts[0] := fDescSetLayout.Handle;
  516. fPipelineLayout := PipelineLayoutFactory.CreatePipelineLayout;
  517. WriteLn(' handle: ', PtrUInt(fPipelineLayout.Handle));
  518. WriteLn(' done');
  519. finally
  520. FreeAndNil(PipelineLayoutFactory);
  521. end;
  522. //////////////////////////////////////////////////////////////////////////////
  523. WriteLn('create shader modules');
  524. ShaderModuleFactory := TvkuShaderModuleFactory.Create(fDevice);
  525. try
  526. ShaderModuleFactory.AllocHandler := fAllocHandler;
  527. ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.vert', [ VK_SHADER_STAGE_VERTEX_BIT ]);
  528. fVertexShader := ShaderModuleFactory.CreateShaderModule;
  529. WriteLn(' vertex handle: ', PtrUInt(fVertexShader.Handle));
  530. ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag', [ VK_SHADER_STAGE_FRAGMENT_BIT ]);
  531. fFragmentShader := ShaderModuleFactory.CreateShaderModule;
  532. WriteLn(' fragment handle: ', PtrUInt(fFragmentShader.Handle));
  533. WriteLn(' done');
  534. finally
  535. FreeAndNil(ShaderModuleFactory);
  536. end;
  537. //////////////////////////////////////////////////////////////////////////////
  538. WriteLn('create graphics pipeline');
  539. PipelineFactory := TvkuGraphicsPipelineFactory.Create(fDevice);
  540. try
  541. PipelineFactory.AllocHandler := fAllocHandler;
  542. // TODO fPipeline := PipelineFactory.CreateGraphicsPipeline(VK_INVALID_NDP_HANDLE);
  543. finally
  544. FreeAndNil(PipelineFactory);
  545. end;
  546. finally
  547. FreeAndNil(SetupCommandBuffer);
  548. end;
  549. end;
  550. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  551. procedure TMainForm.FormDestroy(Sender: TObject);
  552. procedure FreeAndNilFrameBuffers;
  553. var i: Integer;
  554. begin
  555. for i := Low(fFrameBuffers) to High(fFrameBuffers) do
  556. FreeAndNil(fFrameBuffers[i]);
  557. SetLength(fFrameBuffers, 0);
  558. end;
  559. procedure FreeAndNilImages;
  560. var i: Integer;
  561. begin
  562. for i := low(fImages) to high(fImages) do
  563. FreeAndNil(fImages[i]);
  564. SetLength(fImages, 0);
  565. end;
  566. procedure FreeAndNilImageViews;
  567. var i: Integer;
  568. begin
  569. for i := Low(fImageViews) to High(fImageViews) do
  570. FreeAndNil(fImageViews[i]);
  571. SetLength(fImageViews, 0);
  572. end;
  573. procedure FreeAndNilDrawCommandBuffers;
  574. var i: Integer;
  575. begin
  576. for i := Low(fDrawCommandBuffers) to High(fDrawCommandBuffers) do
  577. FreeAndNil(fDrawCommandBuffers[i]);
  578. SetLength(fDrawCommandBuffers, 0);
  579. end;
  580. begin
  581. FreeAndNil(fPipeline);
  582. FreeAndNil(fFragmentShader);
  583. FreeAndNil(fVertexShader);
  584. FreeAndNil(fPipelineLayout);
  585. FreeAndNil(fDescSetLayout);
  586. FreeAndNilFrameBuffers;
  587. FreeAndNil(fPipelineCache);
  588. FreeAndNil(fRenderPass);
  589. FreeAndNil(fDepthStencilImageView);
  590. FreeAndNil(fDepthStencilImage);
  591. FreeAndNil(fPostPresentCommandBuffer);
  592. FreeAndNilDrawCommandBuffers;
  593. FreeAndNilImageViews;
  594. FreeAndNilImages;
  595. FreeAndNil(fSwapChain);
  596. FreeAndNil(fCommandPool);
  597. FreeAndNil(fSurface);
  598. FreeAndNil(fQueue);
  599. FreeAndNil(fDevice);
  600. FreeAndNil(fPhyDevice);
  601. FreeAndNil(fDebugReporter);
  602. FreeAndNil(fInstance);
  603. FreeAndNil(fAllocHandler);
  604. end;
  605. end.