|
- unit uMainForm;
-
- {$mode objfpc}{$H+}
-
- interface
-
- uses
- Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
- Vulkan, uvkuAllocationHandler,
- uvkuInstance, uvkuInstanceFactory,
- uvkuPhysicalDevice, uvkuPhysicalDeviceFactory,
- uvkuSurface, uvkuSurfaceFactory,
- uvkuDevice, uvkuDeviceFactory,
- uvkuSwapChain, uvkuSwapChainFactory;
-
- type
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TCustomAllocHandler = class(TvkuAllocationHandler)
- protected
- function AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; override;
- function ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; override;
- procedure FreeMemory(const aMemory: PVkVoid); override;
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TMainForm = class(TForm)
- RenderPanel: TPanel;
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- private
- fAllocHandler: TCustomAllocHandler;
- fInstance: TvkuInstance;
- fPhyDevice: TvkuPhysicalDevice;
- fDevice: TvkuDevice;
- fSurface: TvkuSurface;
- fSwapChain: TvkuSwapChain;
- public
- { public declarations }
- end;
-
- var
- MainForm: TMainForm;
-
- implementation
-
- {$R *.lfm}
- {$I Vulkan.inc}
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TCustomAllocHandler////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TCustomAllocHandler.AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
- begin
- result := inherited AllocateMemory(aSize, aAlignment, aScope);
- WriteLn(Format('%d bytes of memory allocated at %p', [ aSize, result ]));
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TCustomAllocHandler.ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
- var p: PVkVoid;
- begin
- p := aOriginal;
- result := inherited ReallocateMemory(aOriginal, aSize, aAlignment, aScope);
- WriteLn(Format('%d bytes of memory (from %p) reallocated at %p', [ aSize, p, result ]));
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TCustomAllocHandler.FreeMemory(const aMemory: PVkVoid);
- begin
- WriteLn(Format('free memory at %p', [ aMemory ]));
- inherited FreeMemory(aMemory);
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TMainForm//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TMainForm.FormCreate(Sender: TObject);
- var
- PhyDevices: TvkuPhysicalDeviceArr;
- iFactory: TvkuInstanceFactory;
- pdFactory: TvkuPhysicalDeviceFactory;
- dFactory: TvkuDeviceFactory;
- sFactory: TvkuSurfaceFactory;
- scFactory: TvkuSwapChainFactory;
-
- qci: TvkuQueueCreateInfo;
- SrfFormats: TvkuSurfaceFormatArr;
- SurfaceCapabilities: TVkSurfaceCapabilitiesKHR;
- PresentModes: TvkuPresentModeArr;
- pm: TVkPresentModeKHR;
- begin
- fAllocHandler := TCustomAllocHandler.Create;
-
-
- WriteLn('create vulkan instance');
- iFactory := TvkuInstanceFactory.Create;
- try
- iFactory.Extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME);
- iFactory.Extensions.Add(TvkuSurface.GetPlatformSurfaceExtensionName);
- fInstance := iFactory.CreateInstance(fAllocHandler, false);
- finally
- FreeAndNil(iFactory);
- end;
-
-
- WriteLn('check physical devices');
- PhyDevices := fInstance.GetPhysicalDevices;
- if (Length(PhyDevices) <= 0) then
- raise Exception.Create('unable to get physical device');
- pdFactory := TvkuPhysicalDeviceFactory.Create(fInstance);
- try
- fPhyDevice := pdFactory.CreatePhysicalDevice(PhyDevices[0]);
- finally
- FreeAndNil(pdFactory);
- end;
-
-
- WriteLn('create vulkan surface');
- sFactory := TvkuSurfaceFactory.Create(fInstance);
- try
- sFactory.WinControl := RenderPanel;
- fSurface := sFactory.CreateSurface(fAllocHandler, false);
- finally
- FreeAndNil(sFactory);
- end;
-
-
- WriteLn('create vulkan device');
- dFactory := TvkuDeviceFactory.Create(fInstance);
- try
- SetLength(qci.Priorities, 1);
- qci.Priorities[0] := 1.0;
- qci.FamilyIndex := 0;
- qci.Flags := 0;
-
- dFactory.QueueCreateInfoCount := 1;
- dFactory.QueueCreateInfo[0] := qci;
-
- fDevice := dFactory.CreateDevice(fPhyDevice.Handle, fAllocHandler, false);
- finally
- FreeAndNil(dFactory);
- end;
-
- WriteLn('create swap chain');
- scFactory := TvkuSwapChainFactory.Create(fDevice);
- try
- scFactory.Surface := fSurface.Handle;
- scFactory.ImageUsage := [ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ];
- scFactory.ImageArrayLayers := 1;
- scFactory.ImageSharingMode := VK_SHARING_MODE_EXCLUSIVE;
- scFactory.Clipped := true;
- scFactory.ComposideAlpha := [ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR ];
-
- WriteLn(' get surface capabilities');
- SurfaceCapabilities := fPhyDevice.GetSurfaceCapabilities(fSurface.Handle);
- if (SurfaceCapabilities.currentExtent.width = High(VkUint32)) then begin
- SurfaceCapabilities.currentExtent.width := ClientWidth;
- SurfaceCapabilities.currentExtent.height := ClientHeight;
- end else begin
- ClientWidth := SurfaceCapabilities.currentExtent.width;
- ClientHeight := SurfaceCapabilities.currentExtent.height;
- end;
- scFactory.ImageExtent := SurfaceCapabilities.currentExtent;
-
- WriteLn(' set min image count');
- scFactory.MinImageCount := SurfaceCapabilities.minImageCount + 1;
- if (SurfaceCapabilities.maxImageCount > 0) and
- (scFactory.MinImageCount > SurfaceCapabilities.maxImageCount) then
- scFactory.MinImageCount := SurfaceCapabilities.maxImageCount;
-
- WriteLn(' find suitable image format');
- SrfFormats := fPhyDevice.GetSurfaceFormats(fSurface.Handle);
- if (Length(SrfFormats) = 0) then begin
- WriteLn('no suitable formats found');
- halt;
- end;
- if (Length(SrfFormats) = 1) and (SrfFormats[0].format = VK_FORMAT_UNDEFINED) then begin
- scFactory.ImageFormat := VK_FORMAT_R8G8B8A8_UNORM;
- scFactory.ImageColorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR;
- end else begin
- scFactory.ImageFormat := SrfFormats[0].format;
- scFactory.ImageColorSpace := SrfFormats[0].colorSpace;
- end;
-
- WriteLn(' set pre transform');
- scFactory.PreTransform := SurfaceCapabilities.currentTransform;
- if (VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR in SurfaceCapabilities.supportedTransforms) then
- scFactory.PreTransform := scFactory.PreTransform + [ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR ];
-
- WriteLn(' find suitable present mode');
- PresentModes := fPhyDevice.GetSurfacePresentModes(fSurface.Handle);
- if (Length(PresentModes) = 0) then begin
- WriteLn('unable to get present modes');
- halt;
- end;
- for pm in PresentModes do begin
- if (pm = VK_PRESENT_MODE_MAILBOX_KHR) then begin
- scFactory.PresentMode := pm;
- break;
- end;
- end;
-
- fSwapChain := scFactory.CreateSwapchain(fAllocHandler, false);
- finally
- FreeAndNil(scFactory);
- end;
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TMainForm.FormDestroy(Sender: TObject);
- begin
- FreeAndNil(fSwapChain);
- FreeAndNil(fDevice);
- FreeAndNil(fSurface);
- FreeAndNil(fPhyDevice);
- FreeAndNil(fInstance);
- FreeAndNil(fAllocHandler);
- end;
-
- end.
|