From da6e22a74c96e002c4dd7e7ee9be95f400a1644b Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Wed, 30 Mar 2016 20:28:05 +0200 Subject: [PATCH] * refactored Vulkan initialization * implemented DebugReporter --- projects/triangle/triangle.lpi | 6 +- projects/triangle/triangle.lpr | 2 +- projects/triangle/triangle.lps | 309 +++++++++++----------- projects/triangle/uMainForm.pas | 194 +++++++++++--- projects/utils/VulkanUtils.pas | 5 +- projects/utils/uvkuAllocationHandler.pas | 31 ++- projects/utils/uvkuCommandBuffer.pas | 21 ++ projects/utils/uvkuCommandPoolFactory.pas | 3 + projects/utils/uvkuDebugReporter.pas | 134 ++++++++++ 9 files changed, 504 insertions(+), 201 deletions(-) create mode 100644 projects/utils/uvkuDebugReporter.pas diff --git a/projects/triangle/triangle.lpi b/projects/triangle/triangle.lpi index e65fc77..8a68b03 100644 --- a/projects/triangle/triangle.lpi +++ b/projects/triangle/triangle.lpi @@ -33,7 +33,7 @@ - + @@ -209,6 +209,10 @@ + + + + diff --git a/projects/triangle/triangle.lpr b/projects/triangle/triangle.lpr index 291da12..49b8a7b 100644 --- a/projects/triangle/triangle.lpr +++ b/projects/triangle/triangle.lpr @@ -8,7 +8,7 @@ uses cthreads, {$ENDIF}{$ENDIF} SysUtils, Interfaces, Dialogs, Forms, - uMainForm, Vulkan; + uMainForm, Vulkan, uvkuDebugReporter; {$R *.res} diff --git a/projects/triangle/triangle.lps b/projects/triangle/triangle.lps index f810685..6596f79 100644 --- a/projects/triangle/triangle.lps +++ b/projects/triangle/triangle.lps @@ -4,14 +4,13 @@ - + - + - - + @@ -20,25 +19,25 @@ - - - + + + + - - - - + + + - - + + - + @@ -46,49 +45,47 @@ - + - + - - + - - - - - + + + + - - - + + + - - - + + + - - - + + + @@ -96,7 +93,7 @@ - + @@ -104,15 +101,15 @@ - + - - - - + + + + @@ -120,7 +117,7 @@ - + @@ -128,7 +125,7 @@ - + @@ -136,7 +133,7 @@ - + @@ -144,15 +141,16 @@ - + - - - - + + + + + @@ -160,7 +158,7 @@ - + @@ -168,7 +166,7 @@ - + @@ -176,7 +174,7 @@ - + @@ -184,7 +182,7 @@ - + @@ -192,7 +190,7 @@ - + @@ -200,52 +198,57 @@ - + - + - - - - + + + + + - - - + + + + + - - - + + + + + - - - + + + - - - - + + + + @@ -253,30 +256,29 @@ - + - + - + - + - - + @@ -284,7 +286,7 @@ - + @@ -292,14 +294,14 @@ - + - + @@ -307,7 +309,7 @@ - + @@ -315,7 +317,7 @@ - + @@ -323,7 +325,7 @@ - + @@ -331,7 +333,7 @@ - + @@ -339,15 +341,15 @@ - + - - - + + + @@ -355,7 +357,7 @@ - + @@ -412,8 +414,7 @@ - - + @@ -500,126 +501,136 @@ + + + + + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/projects/triangle/uMainForm.pas b/projects/triangle/uMainForm.pas index 573e0d3..dc5ded3 100644 --- a/projects/triangle/uMainForm.pas +++ b/projects/triangle/uMainForm.pas @@ -23,7 +23,14 @@ type procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private + fGraphicsQueueFamilyIndex: VkUint32; + fGraphicsQueueNodeIndex: VkUint32; + fPresentQueueNodeIndex: VkUint32; + fSurfaceFormat: TVkFormat; + fSurfaceColorSpace: TVkColorSpaceKHR; + fAllocHandler: TCustomAllocHandler; + fDebugReporter: TvkuConsoleDebugReporter; fInstance: TvkuInstance; fPhyDevice: TvkuPhysicalDevice; fDevice: TvkuDevice; @@ -38,6 +45,8 @@ type fVertexShader: TvkuShaderModule; fFragmentShader: TvkuShaderModule; fPipeline: TvkuGraphicsPipeline; + fCommandPool: TvkuCommandPool; + fCommandBuffer: TvkuCommandBuffer; end; var @@ -54,7 +63,7 @@ implementation 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 ])); + WriteLn(Format(' MEM - %d bytes of memory allocated at %p', [ aSize, result ])); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -63,13 +72,13 @@ 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 ])); + WriteLn(Format(' MEM - %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 ])); + WriteLn(Format(' MEM - free memory at %p', [ aMemory ])); inherited FreeMemory(aMemory); end; @@ -82,6 +91,7 @@ var InstanceFactory: TvkuInstanceFactory; DeviceFactory: TvkuDeviceFactory; SurfaceFactory: TvkuSurfaceFactory; + CommandPoolFactory: TvkuCommandPoolFactory; SwapChainFactory: TvkuSwapChainFactory; ImageViewFactory: TvkuImageViewFactory; RenderPassFactory: TvkuRenderPassFactory; @@ -91,9 +101,9 @@ var ShaderModuleFactory: TvkuShaderModuleFactory; PipelineFactory: TvkuGraphicsPipelineFactory; + QueueFamProps: TVkQueueFamilyPropertiesArr; DepthFormat: TVkFormat; f: TVkFormat; - SurcafeFormat: TVkSurfaceFormatKHR; i: Integer; SrfFormats: TVkSurfaceFormatArr; SurfaceCapabilities: TVkSurfaceCapabilitiesKHR; @@ -105,23 +115,44 @@ begin fAllocHandler := TCustomAllocHandler.Create; ////////////////////////////////////////////////////////////////////////////// - WriteLn('create instance'); + WriteLn('create instance: '); InstanceFactory := TvkuInstanceFactory.Create; try InstanceFactory.AllocHandler := fAllocHandler; InstanceFactory.EnabledExtensionNames.Add(VK_KHR_SURFACE_EXTENSION_NAME); + InstanceFactory.EnabledExtensionNames.Add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); InstanceFactory.EnabledExtensionNames.Add(TvkuSurface.GetPlatformSurfaceExtensionName); fInstance := InstanceFactory.CreateInstance; + WriteLn(' handle: ', PtrUInt(fInstance.Handle)); + WriteLn(' done'); finally FreeAndNil(InstanceFactory); end; + fDebugReporter := TvkuConsoleDebugReporter.Create(fInstance.InstanceCommands, fAllocHandler); + ////////////////////////////////////////////////////////////////////////////// WriteLn('find suitable physical device'); PhyDevices := fInstance.GetPhysicalDevices; if (Length(PhyDevices) <= 0) then - raise Exception.Create('unable to get physical device'); + raise TvkuException.Create('unable to get physical device'); fPhyDevice := TvkuPhysicalDevice.Create(PhyDevices[0], fInstance.InstanceCommands); + WriteLn(' handle: ', PtrUInt(fPhyDevice.Handle)); + + Write(' find suitable graphics queue index... '); + QueueFamProps := fPhyDevice.GetQueueFamilyProperties; + fGraphicsQueueFamilyIndex := high(fGraphicsQueueFamilyIndex); + for i := low(QueueFamProps) to high(QueueFamProps) do begin + if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then begin + fGraphicsQueueFamilyIndex := i; + WriteLn(fGraphicsQueueFamilyIndex); + break; + end; + end; + if (fGraphicsQueueFamilyIndex = high(fGraphicsQueueFamilyIndex)) then + raise TvkuException.Create('unable to find graphics queue index'); + + Write(' find suitable depth format... '); f := VK_FORMAT_UNDEFINED; for f in [ VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM ] do begin if (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT in fPhyDevice.GetFormatProperties(f).optimalTilingFeatures) then begin @@ -129,39 +160,111 @@ begin break; end; end; + WriteLn(DepthFormat); + WriteLn(' done'); ////////////////////////////////////////////////////////////////////////////// WriteLn('create device'); DeviceFactory := TvkuDeviceFactory.Create(fInstance); try DeviceFactory.AllocHandler := fAllocHandler; + DeviceFactory.EnabledExtensions.Add('VK_KHR_swapchain'); DeviceFactory.QueueCreateInfos.Length := 1; with DeviceFactory.QueueCreateInfos[0] do begin Flags := 0; - QueueFamilyIndex := 0; + QueueFamilyIndex := fGraphicsQueueFamilyIndex; QueuePriorities.Length := 1; QueuePriorities[0] := 1.0; end; fDevice := DeviceFactory.CreateDevice(fPhyDevice.Handle); + WriteLn(' handle: ', PtrUInt(fDevice.Handle)); + WriteLn(' done'); finally FreeAndNil(DeviceFactory); end; ////////////////////////////////////////////////////////////////////////////// WriteLn('find suitable queue'); - fQueue := TvkuQueue.Create(fDevice.GetQueue(0, 0), fDevice.DeviceCommands); + fQueue := TvkuQueue.Create(fDevice.GetQueue(fGraphicsQueueFamilyIndex, 0), fDevice.DeviceCommands); + WriteLn(' handle: ', PtrUInt(fQueue.Handle)); + WriteLn(' done'); ////////////////////////////////////////////////////////////////////////////// - WriteLn('create surface'); + WriteLn('create surface: '); SurfaceFactory := TvkuSurfaceFactory.Create(fInstance); try SurfaceFactory.AllocHandler := fAllocHandler; SurfaceFactory.WinControl := RenderPanel; fSurface := SurfaceFactory.CreateSurface; + WriteLn(' handle: ', PtrUInt(fSurface.Handle)); + + WriteLn(' find suitable graphics and present queue node index'); + fGraphicsQueueNodeIndex := high(fGraphicsQueueNodeIndex); + fPresentQueueNodeIndex := high(fPresentQueueNodeIndex); + QueueFamProps := fPhyDevice.GetQueueFamilyProperties; + for i := low(QueueFamProps) to high(QueueFamProps) do begin + if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then + fGraphicsQueueNodeIndex := i; + + if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin + fGraphicsQueueNodeIndex := i; + fPresentQueueNodeIndex := i; + break; + end; + end; + if (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) then begin + for i := low(QueueFamProps) to high(QueueFamProps) do begin + if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin + fPresentQueueNodeIndex := i; + break; + end; + end; + end; + WriteLn(' graphics queue node index: ', fGraphicsQueueNodeIndex); + WriteLn(' present queue node index: ', fPresentQueueNodeIndex); + if (fGraphicsQueueNodeIndex = high(fGraphicsQueueNodeIndex)) or + (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) or + (fPresentQueueNodeIndex <> fGraphicsQueueNodeIndex) then + raise TvkuException.Create('different graphic and present queue node index is not supported yet'); + + WriteLn(' find suitable image format'); + SrfFormats := fPhyDevice.GetSurfaceFormats(fSurface.Handle); + if (Length(SrfFormats) = 0) then + raise TvkuException.Create('no suitable formats found'); + if (Length(SrfFormats) = 1) and (SrfFormats[0].format = VK_FORMAT_UNDEFINED) then begin + fSurfaceFormat := VK_FORMAT_R8G8B8A8_UNORM; + fSurfaceColorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR; + end else begin + fSurfaceFormat := SrfFormats[0].format; + fSurfaceColorSpace := SrfFormats[0].colorSpace; + end; + WriteLn(' format: ', fSurfaceFormat); + WriteLn(' color space: ', fSurfaceColorSpace); + + WriteLn(' done'); finally FreeAndNil(SurfaceFactory); end; + ////////////////////////////////////////////////////////////////////////////// + WriteLn('create command pool'); + CommandPoolFactory := TvkuCommandPoolFactory.Create(fDevice); + try + CommandPoolFactory.Flags := [ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT ]; + CommandPoolFactory.QueueFamilyIndex := fGraphicsQueueNodeIndex; + fCommandPool := CommandPoolFactory.CreateCommandPool; + WriteLn(' handle: ', PtrUInt(fCommandPool.Handle)); + + WriteLn(' alloc command buffer'); + fCommandBuffer := TvkuCommandBuffer.Create( + fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY), + true, fCommandPool.Handle, fDevice.DeviceCommands); + WriteLn(' handle: ', PtrUInt(fCommandBuffer.Handle)); + WriteLn(' done'); + finally + FreeAndNil(CommandPoolFactory); + end; + ////////////////////////////////////////////////////////////////////////////// WriteLn('create swap chain'); SwapChainFactory := TvkuSwapChainFactory.Create(fDevice); @@ -173,6 +276,8 @@ begin SwapChainFactory.ImageSharingMode := VK_SHARING_MODE_EXCLUSIVE; SwapChainFactory.Clipped := true; SwapChainFactory.ComposideAlpha := [ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR ]; + SwapChainFactory.ImageFormat := fSurfaceFormat; + SwapChainFactory.ImageColorSpace := fSurfaceColorSpace; WriteLn(' get surface capabilities'); SurfaceCapabilities := fPhyDevice.GetSurfaceCapabilities(fSurface.Handle); @@ -183,50 +288,37 @@ begin ClientWidth := SurfaceCapabilities.currentExtent.width; ClientHeight := SurfaceCapabilities.currentExtent.height; end; + WriteLn(' width: ', SurfaceCapabilities.currentExtent.width); + WriteLn(' height: ', SurfaceCapabilities.currentExtent.height); SwapChainFactory.ImageExtent := SurfaceCapabilities.currentExtent; - WriteLn(' set min image count'); + Write(' set min image count... '); SwapChainFactory.MinImageCount := SurfaceCapabilities.minImageCount + 1; if (SurfaceCapabilities.maxImageCount > 0) and (SwapChainFactory.MinImageCount > SurfaceCapabilities.maxImageCount) then SwapChainFactory.MinImageCount := SurfaceCapabilities.maxImageCount; + WriteLn(SwapChainFactory.MinImageCount); - 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 - SurcafeFormat.format := VK_FORMAT_R8G8B8A8_UNORM; - SurcafeFormat.colorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR; - end else begin - SurcafeFormat.format := SrfFormats[0].format; - SurcafeFormat.colorSpace := SrfFormats[0].colorSpace; - end; - SwapChainFactory.ImageFormat := SurcafeFormat.format; - SwapChainFactory.ImageColorSpace := SurcafeFormat.colorSpace; - - - WriteLn(' set pre transform'); + WriteLn(' set pre transform...'); SwapChainFactory.PreTransform := SurfaceCapabilities.currentTransform; if (VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR in SurfaceCapabilities.supportedTransforms) then - SwapChainFactory.PreTransform := SwapChainFactory.PreTransform + [ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR ]; + SwapChainFactory.PreTransform := [ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR ]; - WriteLn(' find suitable present mode'); + Write(' find suitable present mode... '); PresentModes := fPhyDevice.GetSurfacePresentModes(fSurface.Handle); - if (Length(PresentModes) = 0) then begin - WriteLn('unable to get present modes'); - halt; - end; + if (Length(PresentModes) = 0) then + raise TvkuException.Create('unable to get present modes'); for pm in PresentModes do begin if (pm = VK_PRESENT_MODE_MAILBOX_KHR) then begin SwapChainFactory.PresentMode := pm; break; end; end; + WriteLn(SwapChainFactory.PresentMode); fSwapChain := SwapChainFactory.CreateSwapchain; + WriteLn(' handle: ', PtrUInt(fSwapChain.Handle)); + WriteLn(' done'); finally FreeAndNil(SwapChainFactory); end; @@ -237,14 +329,8 @@ begin SetLength(fImageViews, Length(Images)); ImageViewFactory := TvkuImageViewFactory.Create(fDevice); try - ComponentMapping.r := VK_COMPONENT_SWIZZLE_R; - ComponentMapping.g := VK_COMPONENT_SWIZZLE_G; - ComponentMapping.b := VK_COMPONENT_SWIZZLE_B; - ComponentMapping.a := VK_COMPONENT_SWIZZLE_A; - ImageViewFactory.AllocHandler := fAllocHandler; - ImageViewFactory.Format := SurcafeFormat.format; - ImageViewFactory.Components := ComponentMapping; + ImageViewFactory.Format := fSurfaceFormat; ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D; with ImageViewFactory.SubresourceRange do begin AspectMask := [ VK_IMAGE_ASPECT_COLOR_BIT ]; @@ -253,10 +339,19 @@ begin BaseArrayLayer := 0; LayerCount := 1; end; + with ImageViewFactory.Components do begin + r := VK_COMPONENT_SWIZZLE_R; + g := VK_COMPONENT_SWIZZLE_G; + b := VK_COMPONENT_SWIZZLE_B; + a := VK_COMPONENT_SWIZZLE_A; + end; for i := Low(fImageViews) to High(fImageViews) do begin + // TODO create image barrier ImageViewFactory.Image := Images[i]; fImageViews[i] := ImageViewFactory.CreateImageView; + WriteLn(' handle: ', PtrUInt(fImageViews[i].Handle)); end; + WriteLn(' done'); finally FreeAndNil(ImageViewFactory); end; @@ -267,7 +362,7 @@ begin try RenderPassFactory.Attachments.Length := 2; with RenderPassFactory.Attachments[0] do begin - Format := SurcafeFormat.format; + Format := fSurfaceFormat; Samples := [ VK_SAMPLE_COUNT_1_BIT ]; LoadOp := VK_ATTACHMENT_LOAD_OP_CLEAR; StoreOp := VK_ATTACHMENT_STORE_OP_STORE; @@ -303,6 +398,9 @@ begin RenderPassFactory.AllocHandler := fAllocHandler; fRenderPass := RenderPassFactory.CreateRenderPass; + + WriteLn(' handle: ', PtrUInt(fRenderPass.Handle)); + WriteLn(' done'); finally FreeAndNil(RenderPassFactory); end; @@ -323,7 +421,9 @@ begin for i := low(fFrameBuffers) to high(fFrameBuffers) do begin FrameBufferFactory.Attachments[0] := fImageViews[i].Handle; fFrameBuffers[i] := FrameBufferFactory.CreateFrameBuffer; + WriteLn(' handle: ', PtrUInt(fFrameBuffers[i].Handle)); end; + WriteLn(' done'); finally FreeAndNil(FrameBufferFactory); end; @@ -343,6 +443,8 @@ begin DescSetLayoutFactory.AllocHandler := fAllocHandler; fDescSetLayout := DescSetLayoutFactory.CreateDescriptorSetLayout; + WriteLn(' handle: ', PtrUInt(fDescSetLayout.Handle)); + WriteLn(' done'); finally FreeAndNil(DescSetLayoutFactory); end; @@ -355,6 +457,8 @@ begin PipelineLayoutFactory.SetLayouts.Length := 1; PipelineLayoutFactory.SetLayouts[0] := fDescSetLayout.Handle; fPipelineLayout := PipelineLayoutFactory.CreatePipelineLayout; + WriteLn(' handle: ', PtrUInt(fPipelineLayout.Handle)); + WriteLn(' done'); finally FreeAndNil(PipelineLayoutFactory); end; @@ -367,9 +471,12 @@ begin ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.vert', [ VK_SHADER_STAGE_VERTEX_BIT ]); fVertexShader := ShaderModuleFactory.CreateShaderModule; + WriteLn(' vertex handle: ', PtrUInt(fVertexShader.Handle)); ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag', [ VK_SHADER_STAGE_FRAGMENT_BIT ]); fFragmentShader := ShaderModuleFactory.CreateShaderModule; + WriteLn(' fragment handle: ', PtrUInt(fFragmentShader.Handle)); + WriteLn(' done'); finally FreeAndNil(ShaderModuleFactory); end; @@ -379,7 +486,7 @@ begin PipelineFactory := TvkuGraphicsPipelineFactory.Create(fDevice); try PipelineFactory.AllocHandler := fAllocHandler; - fPipeline := PipelineFactory.CreateGraphicsPipeline(VK_INVALID_NDP_HANDLE); + // TODO fPipeline := PipelineFactory.CreateGraphicsPipeline(VK_INVALID_NDP_HANDLE); finally FreeAndNil(PipelineFactory); end; @@ -418,6 +525,7 @@ begin FreeAndNil(fQueue); FreeAndNil(fDevice); FreeAndNil(fPhyDevice); + FreeAndNil(fDebugReporter); FreeAndNil(fInstance); FreeAndNil(fAllocHandler); end; diff --git a/projects/utils/VulkanUtils.pas b/projects/utils/VulkanUtils.pas index c405f02..7142ce1 100644 --- a/projects/utils/VulkanUtils.pas +++ b/projects/utils/VulkanUtils.pas @@ -6,7 +6,7 @@ interface uses Classes, SysUtils, - uvkuTypes, uvkuAllocationHandler, + uvkuTypes, uvkuAllocationHandler, uvkuDebugReporter, uvkuInstance, uvkuInstanceFactory, uvkuPhysicalDevice, uvkuDevice, uvkuDeviceFactory, uvkuDeviceMemory, uvkuQueue, uvkuSurface, uvkuSurfaceFactory, @@ -43,6 +43,9 @@ type TvkuAllocationHandler = uvkuAllocationHandler.TvkuAllocationHandler; + TvkuDebugReporter = uvkuDebugReporter.TvkuDebugReporter; + TvkuConsoleDebugReporter = uvkuDebugReporter.TvkuConsoleDebugReporter; + { Instance } TvkuInstance = uvkuInstance.TvkuInstance; TvkuInstanceFactory = uvkuInstanceFactory.TvkuInstanceFactory; diff --git a/projects/utils/uvkuAllocationHandler.pas b/projects/utils/uvkuAllocationHandler.pas index c66cc21..7e1512f 100644 --- a/projects/utils/uvkuAllocationHandler.pas +++ b/projects/utils/uvkuAllocationHandler.pas @@ -1,6 +1,7 @@ unit uvkuAllocationHandler; {$mode objfpc}{$H+} +{$I Vulkan.inc} interface @@ -25,32 +26,50 @@ type implementation ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function AllocateMemoryCallback(aUserData: PVkVoid; aSize: VkSize; aAlignment: VkSize; aScope: TVkSystemAllocationScope): PVkVoid; stdcall; +function AllocateMemoryCallback( + aUserData: PVkVoid; + aSize: VkSize; + aAlignment: VkSize; + aScope: TVkSystemAllocationScope): PVkVoid; {$IFDEF VK_CDECL}cdecl{$ELSE}stdcall{$ENDIF}; begin result := TvkuAllocationHandler(aUserData).AllocateMemory(aSize, aAlignment, aScope); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ReallocateMemoryCallback(aUserData: PVkVoid; aOriginal: PVkVoid; aSize: VkSize; - aAlignment: VkSize; aScope: TVkSystemAllocationScope): PVkVoid; stdcall; +function ReallocateMemoryCallback( + aUserData: PVkVoid; + aOriginal: PVkVoid; + aSize: VkSize; + aAlignment: VkSize; + aScope: TVkSystemAllocationScope): PVkVoid; {$IFDEF VK_CDECL}cdecl{$ELSE}stdcall{$ENDIF}; begin result := TvkuAllocationHandler(aUserData).ReallocateMemory(aOriginal, aSize, aAlignment, aScope); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure FreeMemoryCallback(aUserData: PVkVoid; aMemory: PVkVoid); stdcall; +procedure FreeMemoryCallback( + aUserData: PVkVoid; + aMemory: PVkVoid); {$IFDEF VK_CDECL}cdecl{$ELSE}stdcall{$ENDIF}; begin TvkuAllocationHandler(aUserData).FreeMemory(aMemory); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure InternalAllocationCallback(aUserData: PVkVoid; aSize: VkSize; aType: TVkInternalAllocationType; aScope: TVkSystemAllocationScope); stdcall; +procedure InternalAllocationCallback( + aUserData: PVkVoid; + aSize: VkSize; + aType: TVkInternalAllocationType; + aScope: TVkSystemAllocationScope); {$IFDEF VK_CDECL}cdecl{$ELSE}stdcall{$ENDIF}; begin TvkuAllocationHandler(aUserData).InternalAllocationNotification(aSize, aType, aScope); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure InternalFreeCallback(aUserData: PVkVoid; aSize: VkSize; aType: TVkInternalAllocationType; aScope: TVkSystemAllocationScope); stdcall; +procedure InternalFreeCallback( + aUserData: PVkVoid; + aSize: VkSize; + aType: TVkInternalAllocationType; + aScope: TVkSystemAllocationScope); {$IFDEF VK_CDECL}cdecl{$ELSE}stdcall{$ENDIF}; begin TvkuAllocationHandler(aUserData).InternalFreeNotification(aSize, aType, aScope); end; diff --git a/projects/utils/uvkuCommandBuffer.pas b/projects/utils/uvkuCommandBuffer.pas index 64aad9b..73f9138 100644 --- a/projects/utils/uvkuCommandBuffer.pas +++ b/projects/utils/uvkuCommandBuffer.pas @@ -20,6 +20,8 @@ type property CommandPool: VkCommandPool read fCommandPool; property DeviceCommands: TVkDeviceCommands read fDeviceCommands; + procedure BeginCommand; + constructor Create( const aHandle: VkCommandBuffer; const aOwnsHandle: Boolean; @@ -30,8 +32,27 @@ type implementation +uses + uvkuUtils; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuCommandBuffer////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuCommandBuffer.BeginCommand; +var + Info: TVkCommandBufferBeginInfo; + err: TVkResult; +begin + FillByte(Info, SizeOf(Info), 0); + Info.sType := VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + Info.pNext := nil; + Info.flags := []; // TODO + Info.pInheritanceInfo := nil; // TODO + err := DeviceCommands.vkBeginCommandBuffer(fHandle, @Info); + if (err < VK_SUCCESS) then + raise TvkuErrorException.Create('unable to begin command buffer', err); +end; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuCommandBuffer.Create(const aHandle: VkCommandBuffer; const aOwnsHandle: Boolean; const aCommandPool: VkCommandPool; const aDeviceCommands: TVkDeviceCommands); diff --git a/projects/utils/uvkuCommandPoolFactory.pas b/projects/utils/uvkuCommandPoolFactory.pas index 1aabfd0..4229ab8 100644 --- a/projects/utils/uvkuCommandPoolFactory.pas +++ b/projects/utils/uvkuCommandPoolFactory.pas @@ -15,6 +15,9 @@ type fFlags: VkCommandPoolCreateFlags; fQueueFamilyIndex: VkUint32; public + property Flags: VkCommandPoolCreateFlags read fFlags write fFlags; + property QueueFamilyIndex: VkUint32 read fQueueFamilyIndex write fQueueFamilyIndex; + function GetStructure: TVkCommandPoolCreateInfo; procedure SetStructure(const aData: TVkCommandPoolCreateInfo); diff --git a/projects/utils/uvkuDebugReporter.pas b/projects/utils/uvkuDebugReporter.pas new file mode 100644 index 0000000..498cc00 --- /dev/null +++ b/projects/utils/uvkuDebugReporter.pas @@ -0,0 +1,134 @@ +unit uvkuDebugReporter; + +{$mode objfpc}{$H+} +{$I Vulkan.inc} + +interface + +uses + Classes, SysUtils, + Vulkan, uvkuBase, uvkuAllocationHandler; + +type +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TvkuDebugReporter = class(TvkuAllocHandle) + private + fHandle: VkDebugReportCallbackEXT; + fInstanceCommands: TVkInstanceCommands; + protected + function DebugMessage( + aFlags: VkDebugReportFlagsEXT; + aObjectType: TVkDebugReportObjectTypeEXT; + aObject: VkUint64; + aLocation: VkSize; + aMessageCode: VkInt32; + aLayerPrefix: String; + aMessage: String): Boolean; virtual; + public + property Handle: VkDebugReportCallbackEXT read fHandle; + + constructor Create( + const aInstanceCommands: TVkInstanceCommands; + const aAllocHandler: TvkuAllocationHandler = nil); + destructor Destroy; override; + end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TvkuConsoleDebugReporter = class(TvkuDebugReporter) + protected + function DebugMessage(aFlags: VkDebugReportFlagsEXT; aObjectType: TVkDebugReportObjectTypeEXT; aObject: VkUint64; + aLocation: VkSize; aMessageCode: VkInt32; aLayerPrefix: String; aMessage: String): Boolean; override; + end; + +implementation + +uses + uvkuUtils; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function DebugReportCallback( + flags: VkDebugReportFlagsEXT; + objectType: TVkDebugReportObjectTypeEXT; + uObject: VkUint64; + location: VkSize; + messageCode: VkInt32; + pLayerPrefix: PVkChar; + pMessage: PVkChar; + pUserData: PVkVoid): VkBool32; {$IFDEF VK_CDECL}cdecl{$ELSE}stdcall{$ENDIF}; +var ret: Boolean; +begin + ret := TvkuDebugReporter(pUserData).DebugMessage( + flags, + objectType, + uObject, + location, + messageCode, + String(pLayerPrefix), + String(pMessage)); + if ret + then result := VK_TRUE + else result := VK_FALSE; +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TvkuDebugReporter////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TvkuDebugReporter.DebugMessage(aFlags: VkDebugReportFlagsEXT; aObjectType: TVkDebugReportObjectTypeEXT; + aObject: VkUint64; aLocation: VkSize; aMessageCode: VkInt32; aLayerPrefix: String; aMessage: String): Boolean; +begin + result := true; +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TvkuDebugReporter.Create( + const aInstanceCommands: TVkInstanceCommands; + const aAllocHandler: TvkuAllocationHandler); +var + CreateInfo: TVkDebugReportCallbackCreateInfoEXT; + err: TVkResult; +begin + inherited Create; + if Assigned(aAllocHandler) then + SetAllocCallbacks(aAllocHandler.MakeStructure); + fInstanceCommands := aInstanceCommands; + + FillByte(CreateInfo, SizeOf(CreateInfo), 0); + CreateInfo.sType := VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + CreateInfo.pNext := nil; + CreateInfo.pfnCallback := @DebugReportCallback; + CreateInfo.pUserData := self; + CreateInfo.flags := [ + VK_DEBUG_REPORT_INFORMATION_BIT_EXT, + VK_DEBUG_REPORT_WARNING_BIT_EXT, + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, + VK_DEBUG_REPORT_ERROR_BIT_EXT, + VK_DEBUG_REPORT_DEBUG_BIT_EXT + ]; + err := fInstanceCommands.vkCreateDebugReportCallbackEXT(fInstanceCommands.Instance, @CreateInfo, AllocCallbacks, @fHandle); + if (err < VK_SUCCESS) then + raise TvkuErrorException.Create('unable to create debug report handle', err); +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +destructor TvkuDebugReporter.Destroy; +begin + if (fHandle <> VK_INVALID_NDP_HANDLE) then + fInstanceCommands.vkDestroyDebugReportCallbackEXT(fInstanceCommands.Instance, fHandle, AllocCallbacks); + fHandle := VK_INVALID_NDP_HANDLE; + inherited Destroy; +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TvkuConsoleDebugReporter/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TvkuConsoleDebugReporter.DebugMessage( + aFlags: VkDebugReportFlagsEXT; aObjectType: TVkDebugReportObjectTypeEXT; + aObject: VkUint64; aLocation: VkSize; aMessageCode: VkInt32; aLayerPrefix: String; aMessage: String): Boolean; +begin + WriteLn(Format(' DBG - [%03d] %10s: %s', [ Integer(aFlags), aLayerPrefix, aMessage ])); +end; + +end. +