unit uvkuPipelineFactory; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuPipeline, uvkuFactoryBase, uvkuTypes; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineShaderStageCreateInfo = class(TvkuStructure) public Flags: VkPipelineShaderStageCreateFlags; Stage: TVkShaderStageFlagBits; Module: VkShaderModule; Name: String; function GetStructure: TVkPipelineShaderStageCreateInfo; procedure SetStructure(const aData: TVkPipelineShaderStageCreateInfo); end; TvkuPipelineShaderStageCreateInfoList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineFactory = class(TvkuDeviceObjFactory) private fFlags: VkPipelineCreateFlags; fLayout: VkPipelineLayout; fBasePipelineHandle: VkPipeline; fBasePipelineIndex: VkInt32; public property Flags: VkPipelineCreateFlags read fFlags write fFlags; property Layout: VkPipelineLayout read fLayout write fLayout; property BasePipelineHandle: VkPipeline read fBasePipelineHandle write fBasePipelineHandle; property BasePipelineIndex: VkInt32 read fBasePipelineIndex write fBasePipelineIndex; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuGraphicsPipelineFactory = class(TvkuPipelineFactory) private fRenderPass: VkRenderPass; fSubPass: VkUint32; fStages: TvkuPipelineShaderStageCreateInfoList; fvkStages: TVkPipelineShaderStageCreateInfoArr; public property RenderPass: VkRenderPass read fRenderPass write fRenderPass; property SubPass: VkUint32 read fSubPass write fSubPass; property Stages: TvkuPipelineShaderStageCreateInfoList read fStages; function GetStructure: TVkGraphicsPipelineCreateInfo; procedure SetStructure(const aData: TVkGraphicsPipelineCreateInfo); function CreateGraphicsPipeline(const aPipelineCache: VkPipelineCache): TvkuGraphicsPipeline; procedure AfterConstruction; override; procedure BeforeDestruction; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuComputePipelineFactory = class(TvkuPipelineFactory) end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineShaderStageCreateInfo////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineShaderStageCreateInfo.GetStructure: TVkPipelineShaderStageCreateInfo; begin FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; result.pNext := nil; result.flags := Flags; result.stage := Stage; result.module := Module; result.pName := PVkChar(Name); result.pSpecializationInfo := nil; // TODO: implement SpecializationInfo end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineShaderStageCreateInfo.SetStructure(const aData: TVkPipelineShaderStageCreateInfo); begin Flags := aData.flags; Stage := aData.stage; Module := aData.module; if Assigned(aData.pName) then Name := aData.pName else Name := ''; // TODO: read SpecializationInfo end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuGraphicsPipelineFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuGraphicsPipelineFactory.GetStructure: TVkGraphicsPipelineCreateInfo; var i: Integer; begin SetLength(fvkStages, fStages.Length); for i := low(fvkStages) to high(fvkStages) do fvkStages[i] := fStages[i].GetStructure; FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; result.pNext := nil; result.flags := fFlags; result.stageCount := Length(fvkStages); result.pStages := @fvkStages[0]; result.pVertexInputState := nil; result.pInputAssemblyState := nil; result.pTessellationState := nil; result.pViewportState := nil; result.pRasterizationState := nil; result.pMultisampleState := nil; result.pDepthStencilState := nil; result.pColorBlendState := nil; result.pDynamicState := nil; result.layout := fLayout; result.renderPass := fRenderPass; result.subpass := fSubPass; result.basePipelineHandle := fBasePipelineHandle; result.basePipelineIndex := fBasePipelineIndex; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuGraphicsPipelineFactory.SetStructure(const aData: TVkGraphicsPipelineCreateInfo); var i: Integer; begin if Assigned(aData.pStages) then begin fStages.Length := aData.stageCount; for i := 0 to aData.stageCount-1 do fStages[i].SetStructure((aData.pStages + i)^); end; fFlags := aData.flags; fLayout := aData.layout; fRenderPass := aData.renderPass; fSubPass := aData.subpass; fBasePipelineHandle := aData.basePipelineHandle; fBasePipelineIndex := aData.basePipelineIndex; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuGraphicsPipelineFactory.CreateGraphicsPipeline(const aPipelineCache: VkPipelineCache): TvkuGraphicsPipeline; begin result := TvkuGraphicsPipeline.Create(GetStructure, aPipelineCache, DeviceCommands, AllocCallbacks); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuGraphicsPipelineFactory.AfterConstruction; begin inherited AfterConstruction; fStages := TvkuPipelineShaderStageCreateInfoList.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuGraphicsPipelineFactory.BeforeDestruction; begin FreeAndNil(fStages); inherited BeforeDestruction; end; end.