unit uvkuPipelineLayoutFactory; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuFactoryBase, uvkuPipelineLayout, uvkuAllocationHandler, uvkuTypes; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineLayoutEx = class(TvkuPipelineLayout) private fAllocHandler: TvkuAllocationHandler; fOwnsHandler: Boolean; public destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPipelineLayoutFactory = class(TvkuDeviceObjFactory) private fFlags: VkPipelineLayoutCreateFlags; fSetLayouts: TvkuDescriptorSetLayoutArr; fPushConstantRanges: TvkuPushConstantRangeArr; function GetPushConstantRange(const aIndex: Integer): TVkPushConstantRange; function GetPushConstantRangeCount: Integer; function GetSetLayout(const aIndex: Integer): VkDescriptorSetLayout; function GetSetLayoutCount: Integer; procedure SetPushConstantRange(const aIndex: Integer; aValue: TVkPushConstantRange); procedure SetPushConstantRangeCount(aValue: Integer); procedure SetSetLayout(const aIndex: Integer; aValue: VkDescriptorSetLayout); procedure SetSetLayoutCount(aValue: Integer); public property Flags: VkPipelineLayoutCreateFlags read fFlags write fFlags; property SetLayouts: TvkuDescriptorSetLayoutArr read fSetLayouts write fSetLayouts; property SetLayoutCount: Integer read GetSetLayoutCount write SetSetLayoutCount; property SetLayout[const aIndex: Integer]: VkDescriptorSetLayout read GetSetLayout write SetSetLayout; property PushConstantRanges: TvkuPushConstantRangeArr read fPushConstantRanges write fPushConstantRanges; property PushConstantRangeCount: Integer read GetPushConstantRangeCount write SetPushConstantRangeCount; property PushConstantRange[const aIndex: Integer]: TVkPushConstantRange read GetPushConstantRange write SetPushConstantRange; function CreatePipelineLayout: TvkuPipelineLayoutEx; function CreatePipelineLayout( const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuPipelineLayoutEx; end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineLayoutEx/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuPipelineLayoutEx.Destroy; begin inherited Destroy; if fOwnsHandler then FreeAndNil(fAllocHandler); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPipelineLayoutFactory////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineLayoutFactory.GetPushConstantRange(const aIndex: Integer): TVkPushConstantRange; begin if (aIndex < low(fPushConstantRanges)) or (aIndex > high(fPushConstantRanges)) then raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fPushConstantRanges), High(fPushConstantRanges)]); result := fPushConstantRanges[aIndex]; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineLayoutFactory.GetPushConstantRangeCount: Integer; begin result := Length(fPushConstantRanges); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineLayoutFactory.GetSetLayout(const aIndex: Integer): VkDescriptorSetLayout; begin if (aIndex < low(fSetLayouts)) or (aIndex > high(fSetLayouts)) then raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fSetLayouts), High(fSetLayouts)]); result := fSetLayouts[aIndex]; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineLayoutFactory.GetSetLayoutCount: Integer; begin result := Length(fSetLayouts); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineLayoutFactory.SetPushConstantRange(const aIndex: Integer; aValue: TVkPushConstantRange); begin if (aIndex < low(fPushConstantRanges)) or (aIndex > high(fPushConstantRanges)) then raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fPushConstantRanges), High(fPushConstantRanges)]); fPushConstantRanges[aIndex] := aValue; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineLayoutFactory.SetPushConstantRangeCount(aValue: Integer); begin SetLength(fPushConstantRanges, aValue); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineLayoutFactory.SetSetLayout(const aIndex: Integer; aValue: VkDescriptorSetLayout); begin if (aIndex < low(fSetLayouts)) or (aIndex > high(fSetLayouts)) then raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fSetLayouts), High(fSetLayouts)]); fSetLayouts[aIndex] := aValue; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuPipelineLayoutFactory.SetSetLayoutCount(aValue: Integer); begin SetLength(fSetLayouts, aValue); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineLayoutFactory.CreatePipelineLayout: TvkuPipelineLayoutEx; begin result := CreatePipelineLayout(nil, false); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPipelineLayoutFactory.CreatePipelineLayout(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuPipelineLayoutEx; var CreateInfo: TVkPipelineLayoutCreateInfo; begin FillByte(CreateInfo, SizeOf(CreateInfo), 0); CreateInfo.sType := VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; CreateInfo.pNext := nil; CreateInfo.flags := fFlags; CreateInfo.setLayoutCount := Length(fSetLayouts); CreateInfo.pSetLayouts := @fSetLayouts[0]; CreateInfo.pushConstantRangeCount := Length(fPushConstantRanges); CreateInfo.pPushConstantRanges := @fPushConstantRanges[0]; if Assigned(aAllocHandler) then result := TvkuPipelineLayoutEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr) else result := TvkuPipelineLayoutEx.Create(CreateInfo, DeviceCommands); try TvkuPipelineLayoutEx(result).fAllocHandler := aAllocHandler; TvkuPipelineLayoutEx(result).fOwnsHandler := aOwnsHandler; except FreeAndNil(result); raise; end; end; end.