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; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuVertexInputBindingDescription = class(TvkuStructure) public Binding: VkUint32; Stride: VkUint32; InputRate: TVkVertexInputRate; function GetStructure: TVkVertexInputBindingDescription; procedure SetStructure(const aData: TVkVertexInputBindingDescription); end; TvkuVertexInputBindingDescriptionList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuVertexInputAttributeDescription = class(TvkuStructure) public Location: VkUint32; Binding: VkUint32; Format: TVkFormat; Offset: VkUint32; function GetStructure: TVkVertexInputAttributeDescription; procedure SetStructure(const aData: TVkVertexInputAttributeDescription); end; TvkuVertexInputAttributeDescriptionList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineVertexInputStateCreateInfo = class(TvkuStructure) private fFlags: VkPipelineVertexInputStateCreateFlags; fVertexBindingDescriptions: TvkuVertexInputBindingDescriptionList; fVertexAttributeDescriptions: TvkuVertexInputAttributeDescriptionList; fvkVertexBindingDescriptions: TVkVertexInputBindingDescriptionArr; fvkVertexAttributeDescriptions: TVkVertexInputAttributeDescriptionArr; public property Flags: VkPipelineVertexInputStateCreateFlags read fFlags write fFlags; property VertexBindingDescriptions: TvkuVertexInputBindingDescriptionList read fVertexBindingDescriptions; property VertexAttributeDescriptions: TvkuVertexInputAttributeDescriptionList read fVertexAttributeDescriptions; function GetStructure: TVkPipelineVertexInputStateCreateInfo; procedure SetStructure(const aData: TVkPipelineVertexInputStateCreateInfo); constructor Create; destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineInputAssemblyStateCreateInfo = class(TvkuStructure) Flags: VkPipelineInputAssemblyStateCreateFlags; Topology: TVkPrimitiveTopology; PrimitiveRestartEnable: Boolean; function GetStructure: TVkPipelineInputAssemblyStateCreateInfo; procedure SetStructure(const aData: TVkPipelineInputAssemblyStateCreateInfo); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineTessellationStateCreateInfo = class(TvkuStructure) public Flags: VkPipelineTessellationStateCreateFlags; PatchControlPoints: VkUint32; function GetStructure: TVkPipelineTessellationStateCreateInfo; procedure SetStructure(const aData: TVkPipelineTessellationStateCreateInfo); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuViewport = class(TvkuStructure) x: VkFloat; y: VkFloat; Width: VkFloat; Height: VkFloat; MinDepth: VkFloat; MaxDepth: VkFloat; function GetStructure: TVkViewport; procedure SetStructure(const aData: TVkViewport); end; TvkuViewportList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuRect2D = class(TvkuStructure) Offset: TVkOffset2D; Extent: TVkExtent2D; function GetStructure: TVkRect2D; procedure SetStructure(const aData: TVkRect2D); end; TvkuRect2DList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineViewportStateCreateInfo = class(TvkuStructure) private fFlags: VkPipelineViewportStateCreateFlags; fViewports: TvkuViewportList; fScissors: TvkuRect2DList; fvkViewports: TVkViewportArr; fvkScissors: TVkRect2DArr; public property Flags: VkPipelineViewportStateCreateFlags read fFlags write fFlags; property Viewports: TvkuViewportList read fViewports; property Scissors: TvkuRect2DList read fScissors; function GetStructure: TVkPipelineViewportStateCreateInfo; procedure SetStructure(const aData: TVkPipelineViewportStateCreateInfo); constructor Create; destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineRasterizationStateCreateInfo = class(TvkuStructure) Flags: VkPipelineRasterizationStateCreateFlags; DepthClampEnable: Boolean; RasterizerDiscardEnable: Boolean; PolygonMode: TVkPolygonMode; CullMode: VkCullModeFlags; FrontFace: TVkFrontFace; DepthBiasEnable: Boolean; DepthBiasConstantFactor: VkFloat; DepthBiasClamp: VkFloat; DepthBiasSlopeFactor: VkFloat; LineWidth: VkFloat; function GetStructure: TVkPipelineRasterizationStateCreateInfo; procedure SetStructure(const aData: TVkPipelineRasterizationStateCreateInfo); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineMultisampleStateCreateInfo = class(TvkuStructure) private fSampleMask: TVkSampleMaskList; public Flags: VkPipelineMultisampleStateCreateFlags; RasterizationSamples: TVkSampleCountFlagBits; SampleShadingEnable: Boolean; MinSampleShading: VkFloat; AlphaToCoverageEnable: Boolean; AlphaToOneEnable: Boolean; property SampleMask: TVkSampleMaskList read fSampleMask; function GetStructure: TVkPipelineMultisampleStateCreateInfo; procedure SetStructure(const aData: TVkPipelineMultisampleStateCreateInfo); constructor Create; destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineDepthStencilStateCreateInfo = class(TvkuStructure) public Flags: VkPipelineDepthStencilStateCreateFlags; DepthTestEnable: Boolean; DepthWriteEnable: Boolean; DepthCompareOp: TVkCompareOp; DepthBoundsTestEnable: Boolean; StencilTestEnable: Boolean; Front: TVkStencilOpState; Back: TVkStencilOpState; MinDepthBounds: VkFloat; MaxDepthBounds: VkFloat; function GetStructure: TVkPipelineDepthStencilStateCreateInfo; procedure SetStructure(const aData: TVkPipelineDepthStencilStateCreateInfo); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineColorBlendAttachmentState = class(TvkuStructure) public BlendEnable: Boolean; SrcColorBlendFactor: TVkBlendFactor; DstColorBlendFactor: TVkBlendFactor; ColorBlendOp: TVkBlendOp; SrcAlphaBlendFactor: TVkBlendFactor; DstAlphaBlendFactor: TVkBlendFactor; AlphaBlendOp: TVkBlendOp; ColorWriteMask: VkColorComponentFlags; function GetStructure: TVkPipelineColorBlendAttachmentState; procedure SetStructure(const aData: TVkPipelineColorBlendAttachmentState); end; TvkuPipelineColorBlendAttachmentStateList = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineColorBlendStateCreateInfo = class(TvkuStructure) private fAttachments: TvkuPipelineColorBlendAttachmentStateList; fvkAttachments: TVkPipelineColorBlendAttachmentStateArr; public Flags: VkPipelineColorBlendStateCreateFlags; LogicOpEnable: Boolean; LogicOp: TVkLogicOp; BlendConstants: array[0..3] of VkFloat; property Attachments: TvkuPipelineColorBlendAttachmentStateList read fAttachments; function GetStructure: TVkPipelineColorBlendStateCreateInfo; procedure SetStructure(const aData: TVkPipelineColorBlendStateCreateInfo); constructor Create; destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineDynamicStateCreateInfo = class(TvkuStructure) private fDynamicStates: TVkDynamicStateList; fvkDynamicStates: TVkDynamicStateArr; public Flags: VkPipelineDynamicStateCreateFlags; property DynamicStates: TVkDynamicStateList read fDynamicStates; function GetStructure: TVkPipelineDynamicStateCreateInfo; procedure SetStructure(const aData: TVkPipelineDynamicStateCreateInfo); constructor Create; destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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; fVertexInputState: TvkuPipelineVertexInputStateCreateInfo; fInputAssemblyState: TvkuPipelineInputAssemblyStateCreateInfo; fTessellationState: TvkuPipelineTessellationStateCreateInfo; fViewportState: TvkuPipelineViewportStateCreateInfo; fRasterizationState: TvkuPipelineRasterizationStateCreateInfo; fMultisampleState: TvkuPipelineMultisampleStateCreateInfo; fDepthStencilState: TvkuPipelineDepthStencilStateCreateInfo; fColorBlendState: TvkuPipelineColorBlendStateCreateInfo; fDynamicState: TvkuPipelineDynamicStateCreateInfo; fvkStages: TVkPipelineShaderStageCreateInfoArr; fvkVertexInputState: TVkPipelineVertexInputStateCreateInfo; fvkInputAssemblyState: TVkPipelineInputAssemblyStateCreateInfo; fvkTessellationState: TVkPipelineTessellationStateCreateInfo; fvkRasterizationState: TVkPipelineRasterizationStateCreateInfo; fvkColorBlendState: TVkPipelineColorBlendStateCreateInfo; fvkMultisampleState: TVkPipelineMultisampleStateCreateInfo; fvkViewportState: TVkPipelineViewportStateCreateInfo; fvkDepthStencilState: TVkPipelineDepthStencilStateCreateInfo; fvkDynamicState: TVkPipelineDynamicStateCreateInfo; public property RenderPass: VkRenderPass read fRenderPass write fRenderPass; property SubPass: VkUint32 read fSubPass write fSubPass; property Stages: TvkuPipelineShaderStageCreateInfoList read fStages; property VertexInputState: TvkuPipelineVertexInputStateCreateInfo read fVertexInputState; property InputAssemblyState: TvkuPipelineInputAssemblyStateCreateInfo read fInputAssemblyState; property TessellationState: TvkuPipelineTessellationStateCreateInfo read fTessellationState; property ViewportState: TvkuPipelineViewportStateCreateInfo read fViewportState; property RasterizationState: TvkuPipelineRasterizationStateCreateInfo read fRasterizationState; property MultiSampleState: TvkuPipelineMultisampleStateCreateInfo read fMultiSampleState; property DepthStencilState: TvkuPipelineDepthStencilStateCreateInfo read fDepthStencilState; property ColorBlendState: TvkuPipelineColorBlendStateCreateInfo read fColorBlendState; property DynamicState: TvkuPipelineDynamicStateCreateInfo read fDynamicState; 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; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuVertexInputBindingDescription////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuVertexInputBindingDescription.GetStructure: TVkVertexInputBindingDescription; begin FillByte(result, SizeOf(result), 0); result.binding := Binding; result.stride := Stride; result.inputRate := InputRate; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuVertexInputBindingDescription.SetStructure(const aData: TVkVertexInputBindingDescription); begin Binding := aData.binding; Stride := aData.stride; InputRate := aData.inputRate; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuVertexInputAttributeDescription//////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuVertexInputAttributeDescription.GetStructure: TVkVertexInputAttributeDescription; begin FillByte(result, SizeOf(result), 0); result.location := Location; result.binding := Binding; result.format := Format; result.offset := Offset; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuVertexInputAttributeDescription.SetStructure(const aData: TVkVertexInputAttributeDescription); begin Location := aData.location; Binding := aData.binding; Format := aData.format; Offset := aData.offset; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineVertexInputStateCreateInfo///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineVertexInputStateCreateInfo.GetStructure: TVkPipelineVertexInputStateCreateInfo; var i: Integer; begin SetLength(fvkVertexBindingDescriptions, fVertexBindingDescriptions.Length); for i := low(fvkVertexBindingDescriptions) to high(fvkVertexBindingDescriptions) do fvkVertexBindingDescriptions[i] := fVertexBindingDescriptions[i].GetStructure; SetLength(fvkVertexAttributeDescriptions, fVertexAttributeDescriptions.Length); for i := low(fvkVertexAttributeDescriptions) to high(fvkVertexAttributeDescriptions) do fvkVertexAttributeDescriptions[i] := fVertexAttributeDescriptions[i].GetStructure; FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; result.pNext := nil; result.flags := fFlags; result.vertexBindingDescriptionCount := Length(fvkVertexBindingDescriptions); result.pVertexBindingDescriptions := @fvkVertexBindingDescriptions[0]; result.vertexAttributeDescriptionCount := Length(fvkVertexAttributeDescriptions); result.pVertexAttributeDescriptions := @fvkVertexAttributeDescriptions[0]; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineVertexInputStateCreateInfo.SetStructure(const aData: TVkPipelineVertexInputStateCreateInfo); var i: Integer; begin if Assigned(aData.pVertexAttributeDescriptions) then begin fVertexAttributeDescriptions.Length := aData.vertexAttributeDescriptionCount; for i := 0 to fVertexAttributeDescriptions.Length-1 do fVertexAttributeDescriptions[i].SetStructure((aData.pVertexAttributeDescriptions + i)^); end; if Assigned(aData.pVertexBindingDescriptions) then begin fVertexBindingDescriptions.Length := aData.vertexBindingDescriptionCount; for i := 0 to fVertexBindingDescriptions.Length-1 do fVertexBindingDescriptions[i].SetStructure((aData.pVertexBindingDescriptions + i)^); end; fFlags := aData.flags; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuPipelineVertexInputStateCreateInfo.Create; begin inherited Create; fVertexAttributeDescriptions := TvkuVertexInputAttributeDescriptionList.Create; fVertexBindingDescriptions := TvkuVertexInputBindingDescriptionList.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuPipelineVertexInputStateCreateInfo.Destroy; begin FreeAndNil(fVertexBindingDescriptions); FreeAndNil(fVertexAttributeDescriptions); inherited Destroy; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineInputAssemblyStateCreateInfo/////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineInputAssemblyStateCreateInfo.GetStructure: TVkPipelineInputAssemblyStateCreateInfo; begin FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; result.pNext := nil; result.flags := Flags; result.topology := Topology; if PrimitiveRestartEnable then result.primitiveRestartEnable := VK_TRUE else result.primitiveRestartEnable := VK_FALSE; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineInputAssemblyStateCreateInfo.SetStructure(const aData: TVkPipelineInputAssemblyStateCreateInfo); begin Flags := aData.flags; Topology := aData.topology; PrimitiveRestartEnable := (aData.primitiveRestartEnable <> 0); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineTessellationStateCreateInfo//////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineTessellationStateCreateInfo.GetStructure: TVkPipelineTessellationStateCreateInfo; begin FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; result.pNext := nil; result.flags := Flags; result.patchControlPoints := PatchControlPoints; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineTessellationStateCreateInfo.SetStructure(const aData: TVkPipelineTessellationStateCreateInfo); begin Flags := aData.flags; PatchControlPoints := aData.patchControlPoints; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuViewport/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuViewport.GetStructure: TVkViewport; begin FillByte(result, SizeOf(result), 0); result.x := x; result.y := y; result.width := Width; result.height := Height; result.minDepth := MinDepth; result.maxDepth := MaxDepth; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuViewport.SetStructure(const aData: TVkViewport); begin x := aData.x; y := aData.y; Width := aData.width; Height := aData.height; MinDepth := aData.minDepth; MaxDepth := aData.maxDepth; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuRect2D///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuRect2D.GetStructure: TVkRect2D; begin FillByte(result, SizeOf(result), 0); result.offset := Offset; result.extent := Extent; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuRect2D.SetStructure(const aData: TVkRect2D); begin Offset := aData.offset; Extent := aData.extent; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineViewportStateCreateInfo//////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineViewportStateCreateInfo.GetStructure: TVkPipelineViewportStateCreateInfo; var i: Integer; begin SetLength(fvkViewports, fViewports.Length); for i := low(fvkViewports) to high(fvkViewports) do fvkViewports[i] := fViewports[i].GetStructure; SetLength(fvkScissors, fScissors.Length); for i := low(fvkScissors) to high(fvkScissors) do fvkScissors[i] := fScissors[i].GetStructure; FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; result.pNext := nil; result.flags := fFlags; result.viewportCount := Length(fvkViewports); result.pViewports := @fvkViewports[0]; result.scissorCount := Length(fvkScissors); result.pScissors := @fvkScissors[0]; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineViewportStateCreateInfo.SetStructure(const aData: TVkPipelineViewportStateCreateInfo); var i: Integer; begin if Assigned(aData.pViewports) then begin fViewports.Length := aData.viewportCount; for i := 0 to fViewports.Length-1 do fViewports[i].SetStructure((aData.pViewports + i)^); end; if Assigned(aData.pScissors) then begin fScissors.Length := aData.scissorCount; for i := 0 to fScissors.Length-1 do fScissors[i].SetStructure((aData.pScissors + i)^); end; fFlags := aData.flags; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuPipelineViewportStateCreateInfo.Create; begin inherited Create; fViewports := TvkuViewportList.Create; fScissors := TvkuRect2DList.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuPipelineViewportStateCreateInfo.Destroy; begin FreeAndNil(fViewports); FreeAndNil(fScissors); inherited Destroy; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineRasterizationStateCreateInfo/////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineRasterizationStateCreateInfo.GetStructure: TVkPipelineRasterizationStateCreateInfo; begin FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; result.pNext := nil; result.flags := Flags; result.polygonMode := PolygonMode; result.cullMode := CullMode; result.frontFace := FrontFace; result.depthBiasConstantFactor := DepthBiasConstantFactor; result.depthBiasClamp := DepthBiasClamp; result.depthBiasSlopeFactor := DepthBiasSlopeFactor; result.lineWidth := LineWidth; if DepthClampEnable then result.depthClampEnable := VK_TRUE else result.depthClampEnable := VK_FALSE; if RasterizerDiscardEnable then result.rasterizerDiscardEnable := VK_TRUE else result.rasterizerDiscardEnable := VK_FALSE; if DepthBiasEnable then result.depthBiasEnable := VK_TRUE else result.depthBiasEnable := VK_FALSE; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineRasterizationStateCreateInfo.SetStructure(const aData: TVkPipelineRasterizationStateCreateInfo); begin Flags := aData.flags; DepthClampEnable := (aData.depthClampEnable <> 0); RasterizerDiscardEnable := (aData.rasterizerDiscardEnable <> 0); PolygonMode := aData.polygonMode; CullMode := aData.cullMode; FrontFace := aData.frontFace; DepthBiasEnable := (aData.depthBiasEnable <> 0); DepthBiasConstantFactor := aData.depthBiasConstantFactor; DepthBiasClamp := aData.depthBiasClamp; DepthBiasSlopeFactor := aData.depthBiasSlopeFactor; LineWidth := aData.lineWidth; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineMultisampleStateCreateInfo///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineMultisampleStateCreateInfo.GetStructure: TVkPipelineMultisampleStateCreateInfo; var i: Integer; begin if (fSampleMask.Length <> 0) then fSampleMask.Length := 32; FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; result.pNext := nil; result.flags := Flags; result.rasterizationSamples := RasterizationSamples; result.minSampleShading := MinSampleShading; result.pSampleMask := fSampleMask.PData; if SampleShadingEnable then result.sampleShadingEnable := VK_TRUE else result.sampleShadingEnable := VK_FALSE; if AlphaToCoverageEnable then result.alphaToCoverageEnable := VK_TRUE else result.alphaToCoverageEnable := VK_FALSE; if AlphaToOneEnable then result.alphaToOneEnable := VK_TRUE else result.alphaToOneEnable := VK_FALSE; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineMultisampleStateCreateInfo.SetStructure(const aData: TVkPipelineMultisampleStateCreateInfo); begin fSampleMask.SetData(aData.pSampleMask, 32); Flags := aData.flags; RasterizationSamples := aData.rasterizationSamples; SampleShadingEnable := (aData.sampleShadingEnable <> 0); MinSampleShading := aData.minSampleShading; AlphaToCoverageEnable := (aData.alphaToCoverageEnable <> 0); AlphaToOneEnable := (aData.alphaToOneEnable <> 0); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuPipelineMultisampleStateCreateInfo.Create; begin inherited Create; fSampleMask := TVkSampleMaskList.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuPipelineMultisampleStateCreateInfo.Destroy; begin FreeAndNil(fSampleMask); inherited Destroy; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineDepthStencilStateCreateInfo.GetStructure: TVkPipelineDepthStencilStateCreateInfo; begin FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; result.pNext := nil; result.flags := Flags; result.depthCompareOp := DepthCompareOp; result.front := Front; result.back := Back; result.minDepthBounds := MinDepthBounds; result.maxDepthBounds := MaxDepthBounds; if DepthTestEnable then result.depthTestEnable := VK_TRUE else result.depthTestEnable := VK_FALSE; if DepthWriteEnable then result.depthWriteEnable := VK_TRUE else result.depthWriteEnable := VK_FALSE; if DepthBoundsTestEnable then result.depthBoundsTestEnable := VK_TRUE else result.depthBoundsTestEnable := VK_FALSE; if StencilTestEnable then result.stencilTestEnable := VK_TRUE else result.stencilTestEnable := VK_FALSE; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineDepthStencilStateCreateInfo.SetStructure(const aData: TVkPipelineDepthStencilStateCreateInfo); begin Flags := aData.flags; DepthTestEnable := (aData.depthTestEnable <> 0); DepthWriteEnable := (aData.depthWriteEnable <> 0); DepthCompareOp := aData.depthCompareOp; DepthBoundsTestEnable := (aData.depthBoundsTestEnable <> 0); StencilTestEnable := (aData.stencilTestEnable <> 0); Front := aData.front; Back := aData.back; MinDepthBounds := aData.minDepthBounds; MaxDepthBounds := aData.maxDepthBounds; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineColorBlendAttachmentState////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineColorBlendAttachmentState.GetStructure: TVkPipelineColorBlendAttachmentState; begin FillByte(result, SizeOf(result), 0); if BlendEnable then result.blendEnable := VK_TRUE else result.blendEnable := VK_FALSE; result.srcColorBlendFactor := SrcColorBlendFactor; result.dstColorBlendFactor := DstColorBlendFactor; result.colorBlendOp := ColorBlendOp; result.srcAlphaBlendFactor := SrcAlphaBlendFactor; result.dstAlphaBlendFactor := DstAlphaBlendFactor; result.alphaBlendOp := AlphaBlendOp; result.colorWriteMask := ColorWriteMask; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineColorBlendAttachmentState.SetStructure(const aData: TVkPipelineColorBlendAttachmentState); begin BlendEnable := (aData.blendEnable <> 0); SrcColorBlendFactor := aData.srcColorBlendFactor; DstColorBlendFactor := aData.dstColorBlendFactor; ColorBlendOp := aData.colorBlendOp; SrcAlphaBlendFactor := aData.srcAlphaBlendFactor; DstAlphaBlendFactor := aData.dstAlphaBlendFactor; AlphaBlendOp := aData.alphaBlendOp; ColorWriteMask := aData.colorWriteMask; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineColorBlendStateCreateInfo////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineColorBlendStateCreateInfo.GetStructure: TVkPipelineColorBlendStateCreateInfo; var i: Integer; begin SetLength(fvkAttachments, fAttachments.Length); for i := low(fvkAttachments) to high(fvkAttachments) do fvkAttachments[i] := fAttachments[i].GetStructure; FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; result.pNext := nil; result.flags := Flags; result.logicOp := LogicOp; result.attachmentCount := Length(fvkAttachments); result.pAttachments := @fvkAttachments[0]; result.blendConstants := BlendConstants; if LogicOpEnable then result.logicOpEnable := VK_TRUE else result.logicOpEnable := VK_FALSE; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineColorBlendStateCreateInfo.SetStructure(const aData: TVkPipelineColorBlendStateCreateInfo); var i: Integer; begin if Assigned(aData.pAttachments) then begin fAttachments.Length := aData.attachmentCount; for i := 0 to fAttachments.Length-1 do fAttachments[i].SetStructure((aData.pAttachments + i)^); end; Flags := aData.flags; LogicOp := aData.logicOp; LogicOpEnable := (aData.logicOpEnable <> 0); BlendConstants := aData.blendConstants; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuPipelineColorBlendStateCreateInfo.Create; begin inherited Create; fAttachments := TvkuPipelineColorBlendAttachmentStateList.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuPipelineColorBlendStateCreateInfo.Destroy; begin FreeAndNil(fAttachments); inherited Destroy; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineDynamicStateCreateInfo///////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineDynamicStateCreateInfo.GetStructure: TVkPipelineDynamicStateCreateInfo; begin FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; result.pNext := nil; result.flags := Flags; result.dynamicStateCount := fDynamicStates.Length; result.pDynamicStates := fDynamicStates.PData; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineDynamicStateCreateInfo.SetStructure(const aData: TVkPipelineDynamicStateCreateInfo); begin fDynamicStates.SetData(aData.pDynamicStates, aData.dynamicStateCount); Flags := aData.flags; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuPipelineDynamicStateCreateInfo.Create; begin inherited Create; fDynamicStates := TVkDynamicStateList.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuPipelineDynamicStateCreateInfo.Destroy; begin FreeAndNil(fDynamicStates); inherited Destroy; 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; fvkVertexInputState := fVertexInputState.GetStructure; fvkInputAssemblyState := fInputAssemblyState.GetStructure; fvkTessellationState := fTessellationState.GetStructure; fvkViewportState := fViewportState.GetStructure; fvkRasterizationState := fRasterizationState.GetStructure; fvkMultisampleState := fMultisampleState.GetStructure; fvkDepthStencilState := fDepthStencilState.GetStructure; fvkColorBlendState := fColorBlendState.GetStructure; fvkDynamicState := fDynamicState.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 := @fvkVertexInputState; result.pInputAssemblyState := @fvkInputAssemblyState; result.pTessellationState := @fvkTessellationState; result.pViewportState := @fvkViewportState; result.pRasterizationState := @fvkRasterizationState; result.pMultisampleState := @fvkMultisampleState; result.pDepthStencilState := @fvkDepthStencilState; result.pColorBlendState := @fvkColorBlendState; result.pDynamicState := @fvkDynamicState; 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; fVertexInputState := TvkuPipelineVertexInputStateCreateInfo.Create; fInputAssemblyState := TvkuPipelineInputAssemblyStateCreateInfo.Create; fTessellationState := TvkuPipelineTessellationStateCreateInfo.Create; fViewportState := TvkuPipelineViewportStateCreateInfo.Create; fRasterizationState := TvkuPipelineRasterizationStateCreateInfo.Create; fMultisampleState := TvkuPipelineMultisampleStateCreateInfo.Create; fDepthStencilState := TvkuPipelineDepthStencilStateCreateInfo.Create; fColorBlendState := TvkuPipelineColorBlendStateCreateInfo.Create; fDynamicState := TvkuPipelineDynamicStateCreateInfo.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuGraphicsPipelineFactory.BeforeDestruction; begin FreeAndNil(fDynamicState); FreeAndNil(fColorBlendState); FreeAndNil(fDepthStencilState); FreeAndNil(fMultisampleState); FreeAndNil(fRasterizationState); FreeAndNil(fViewportState); FreeAndNil(fTessellationState); FreeAndNil(fInputAssemblyState); FreeAndNil(fVertexInputState); FreeAndNil(fStages); inherited BeforeDestruction; end; end.