unit uvkuRenderPassFactory; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuFactoryBase, uvkuRenderPass, uvkuTypes; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuAttachmentDescription = class(TvkuStructure) public Flags: VkAttachmentDescriptionFlags; Format: TVkFormat; Samples: TVkSampleCountFlagBits; LoadOp: TVkAttachmentLoadOp; StoreOp: TVkAttachmentStoreOp; StencilLoadOp: TVkAttachmentLoadOp; StencilStoreOp: TVkAttachmentStoreOp; InitialLayout: TVkImageLayout; FinalLayout: TVkImageLayout; function GetStructure: TVkAttachmentDescription; procedure SetStructure(const aData: TVkAttachmentDescription); end; TvkuAttachmentDescriptionList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuAttachmentReference = class(TvkuStructure) public Attachment: VkUint32; Layout: TVkImageLayout; function GetStructure: TVkAttachmentReference; procedure SetStructure(const aData: TVkAttachmentReference); end; TvkuAttachmentReferenceList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuSubpassDescription = class(TvkuStructure) private fInputAttachments: TvkuAttachmentReferenceList; fColorAttachments: TvkuAttachmentReferenceList; fResolveAttachments: TvkuAttachmentReferenceList; fDepthStencilAttachments: TvkuAttachmentReferenceList; fPreserveAttachments: TVkUint32List; fvkInputAttachments: TVkAttachmentReferenceArr; fvkColorAttachments: TVkAttachmentReferenceArr; fvkResolveAttachments: TVkAttachmentReferenceArr; fvkDepthStencilAttachments: TVkAttachmentReferenceArr; public Flags: VkSubpassDescriptionFlags; PipelineBindPoint: TVkPipelineBindPoint; property InputAttachments: TvkuAttachmentReferenceList read fInputAttachments; property ColorAttachments: TvkuAttachmentReferenceList read fColorAttachments; property ResolveAttachments: TvkuAttachmentReferenceList read fResolveAttachments; property DepthStencilAttachments: TvkuAttachmentReferenceList read fDepthStencilAttachments; property PreserveAttachments: TVkUint32List read fPreserveAttachments; function GetStructure: TVkSubpassDescription; procedure SetStructure(const aData: TVkSubpassDescription); procedure AfterConstruction; override; procedure BeforeDestruction; override; end; TvkuSubpassDescriptionList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuSubpassDependency = class(TvkuStructure) public SrcSubpass: VkUint32; DstSubpass: VkUint32; SrcStageMask: VkPipelineStageFlags; DstStageMask: VkPipelineStageFlags; SrcAccessMask: VkAccessFlags; DstAccessMask: VkAccessFlags; DependencyFlags: VkDependencyFlags; function GetStructure: TVkSubpassDependency; procedure SetStructure(const aData: TVkSubpassDependency); end; TvkuSubpassDependencyList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuRenderPassFactory = class(TvkuDeviceObjFactory) private fFlags: VkRenderPassCreateFlags; fAttachments: TvkuAttachmentDescriptionList; fSubpasses: TvkuSubpassDescriptionList; fDependencies: TvkuSubpassDependencyList; fvkAttachments: TVkAttachmentDescriptionArr; fvkSubpasses: TVkSubpassDescriptionArr; fvkDependencies: TVkSubpassDependencyArr; public property Flags: VkRenderPassCreateFlags read fFlags write fFlags; property Attachments: TvkuAttachmentDescriptionList read fAttachments; property Subpasses: TvkuSubpassDescriptionList read fSubpasses; property Dependencies: TvkuSubpassDependencyList read fDependencies; function GetStructure: TVkRenderPassCreateInfo; procedure SetStructure(const aData: TVkRenderPassCreateInfo); function CreateRenderPass: TvkuRenderPass; procedure AfterConstruction; override; procedure BeforeDestruction; override; end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuAttachmentDescription////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuAttachmentDescription.GetStructure: TVkAttachmentDescription; begin result.flags := Flags; result.format := Format; result.samples := Samples; result.loadOp := LoadOp; result.storeOp := StoreOp; result.stencilLoadOp := StencilLoadOp; result.stencilStoreOp := StencilStoreOp; result.initialLayout := InitialLayout; result.finalLayout := FinalLayout; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuAttachmentDescription.SetStructure(const aData: TVkAttachmentDescription); begin Flags := aData.flags; Format := aData.format; Samples := aData.samples; LoadOp := aData.loadOp; StoreOp := aData.storeOp; StencilLoadOp := aData.stencilLoadOp; StencilStoreOp := aData.stencilStoreOp; InitialLayout := aData.initialLayout; FinalLayout := aData.finalLayout; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuAttachmentReference//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuAttachmentReference.GetStructure: TVkAttachmentReference; begin FillByte(result, SizeOf(result), 0); result.attachment := Attachment; result.layout := Layout; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuAttachmentReference.SetStructure(const aData: TVkAttachmentReference); begin Attachment := aData.attachment; Layout := aData.layout; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuSubpassDescription///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuSubpassDescription.GetStructure: TVkSubpassDescription; var i: Integer; begin if (fResolveAttachments.Length <> 0) and (fResolveAttachments.Length <> fColorAttachments.Length) then raise TvkuException.Create('''ResolveAttachments'' must be empty or have the same size as ''ColorAttachments'''); if (fDepthStencilAttachments.Length <> fColorAttachments.Length) then raise TvkuException.Create('''DepthStencilAttachments'' must have the same size as ''ColorAttachments'''); SetLength(fvkInputAttachments, fInputAttachments.Length); for i := low(fvkInputAttachments) to high(fvkInputAttachments) do fvkInputAttachments[i] := fInputAttachments[i].GetStructure; SetLength(fvkColorAttachments, fColorAttachments.Length); for i := low(fvkColorAttachments) to high(fvkColorAttachments) do fvkColorAttachments[i] := fColorAttachments[i].GetStructure; SetLength(fvkResolveAttachments, fResolveAttachments.Length); for i := low(fvkResolveAttachments) to high(fvkResolveAttachments) do fvkResolveAttachments[i] := fResolveAttachments[i].GetStructure; SetLength(fvkDepthStencilAttachments, fDepthStencilAttachments.Length); for i := low(fvkDepthStencilAttachments) to high(fvkDepthStencilAttachments) do fvkDepthStencilAttachments[i] := fDepthStencilAttachments[i].GetStructure; result.flags := Flags; result.pipelineBindPoint := PipelineBindPoint; result.inputAttachmentCount := Length(fvkInputAttachments); result.pInputAttachments := @fvkInputAttachments[0]; result.colorAttachmentCount := Length(fvkColorAttachments); result.pColorAttachments := @fvkColorAttachments[0]; result.pResolveAttachments := @fvkResolveAttachments[0]; result.pDepthStencilAttachment := @fvkDepthStencilAttachments[0]; result.preserveAttachmentCount := fPreserveAttachments.Length; result.pPreserveAttachments := fPreserveAttachments.PData; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuSubpassDescription.SetStructure(const aData: TVkSubpassDescription); var i: Integer; begin Flags := aData.flags; PipelineBindPoint := aData.pipelineBindPoint; if Assigned(aData.pInputAttachments) then begin fInputAttachments.Length := aData.inputAttachmentCount; for i := 0 to aData.inputAttachmentCount-1 do fInputAttachments[i].SetStructure((aData.pInputAttachments + i)^); end else fInputAttachments.Length := 0; if Assigned(aData.pResolveAttachments) then begin fResolveAttachments.Length := aData.colorAttachmentCount; for i := 0 to aData.colorAttachmentCount-1 do fResolveAttachments[i].SetStructure((aData.pResolveAttachments + i)^); end else fResolveAttachments.Length := 0; if Assigned(aData.pDepthStencilAttachment) then begin fDepthStencilAttachments.Length := aData.colorAttachmentCount; for i := 0 to aData.colorAttachmentCount-1 do fDepthStencilAttachments[i].SetStructure((aData.pDepthStencilAttachment + i)^); end else fDepthStencilAttachments.Length := 0; fPreserveAttachments.SetData(aData.pPreserveAttachments, aData.preserveAttachmentCount); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuSubpassDescription.AfterConstruction; begin inherited AfterConstruction; fInputAttachments := TvkuAttachmentReferenceList.Create; fColorAttachments := TvkuAttachmentReferenceList.Create; fResolveAttachments := TvkuAttachmentReferenceList.Create; fDepthStencilAttachments := TvkuAttachmentReferenceList.Create; fPreserveAttachments := TVkUint32List.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuSubpassDescription.BeforeDestruction; begin FreeAndNil(fPreserveAttachments); FreeAndNil(fDepthStencilAttachments); FreeAndNil(fResolveAttachments); FreeAndNil(fColorAttachments); FreeAndNil(fInputAttachments); inherited BeforeDestruction; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuSubpassDependency////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuSubpassDependency.GetStructure: TVkSubpassDependency; begin result.srcSubpass := SrcSubpass; result.dstSubpass := DstSubpass; result.srcStageMask := SrcStageMask; result.dstStageMask := DstStageMask; result.srcAccessMask := SrcAccessMask; result.dstAccessMask := DstAccessMask; result.dependencyFlags := DependencyFlags; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuSubpassDependency.SetStructure(const aData: TVkSubpassDependency); begin SrcSubpass := aData.srcSubpass; DstSubpass := aData.dstSubpass; SrcStageMask := aData.srcStageMask; DstStageMask := aData.dstStageMask; SrcAccessMask := aData.srcAccessMask; DstAccessMask := aData.dstAccessMask; DependencyFlags := aData.dependencyFlags; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuRenderPassFactory////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuRenderPassFactory.GetStructure: TVkRenderPassCreateInfo; var i: Integer; begin SetLength(fvkAttachments, fAttachments.Length); for i := low(fvkAttachments) to high(fvkAttachments) do fvkAttachments[i] := fAttachments[i].GetStructure; SetLength(fvkSubpasses, fSubpasses.Length); for i := low(fvkSubpasses) to high(fvkSubpasses) do fvkSubpasses[i] := fSubpasses[i].GetStructure; SetLength(fvkDependencies, fDependencies.Length); for i := low(fvkDependencies) to high(fvkDependencies) do fvkDependencies[i] := fDependencies[i].GetStructure; FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; result.pNext := nil; result.flags := fFlags; result.attachmentCount := Length(fvkAttachments); result.pAttachments := @fvkAttachments[0]; result.subpassCount := Length(fvkSubpasses); result.pSubpasses := @fvkSubpasses[0]; result.dependencyCount := Length(fvkDependencies); result.pDependencies := @fvkDependencies[0]; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuRenderPassFactory.SetStructure(const aData: TVkRenderPassCreateInfo); var i: Integer; begin fFlags := aData.flags; fAttachments.Length := aData.attachmentCount; for i := 0 to fAttachments.Length-1 do fAttachments[i].SetStructure((aData.pAttachments + i)^); fSubpasses.Length := aData.subpassCount; for i := 0 to fSubpasses.Length-1 do fSubpasses[i].SetStructure((aData.pSubpasses + i)^); fDependencies.Length := aData.dependencyCount; for i := 0 to fDependencies.Length-1 do fDependencies[i].SetStructure((aData.pDependencies + i)^); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuRenderPassFactory.CreateRenderPass: TvkuRenderPass; begin result := TvkuRenderPass.Create(GetStructure, DeviceCommands, AllocCallbacks); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuRenderPassFactory.AfterConstruction; begin inherited AfterConstruction; fAttachments := TvkuAttachmentDescriptionList.Create; fSubpasses := TvkuSubpassDescriptionList.Create; fDependencies := TvkuSubpassDependencyList.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuRenderPassFactory.BeforeDestruction; begin FreeAndNil(fDependencies); FreeAndNil(fSubpasses); FreeAndNil(fAttachments); inherited BeforeDestruction; end; end.