unit uvkuDescriptorSetLayoutFactory; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuFactoryBase, uvkuDescriptorSetLayout, uvkuTypes; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuDescriptorSetLayoutBinding = class(TvkuStructure) private fImmutableSamplers: TVkSamplerList; public Binding: VkUint32; DescriptorType: TVkDescriptorType; DescriptorCount: VkUint32; StageFlags: VkShaderStageFlags; property ImmutableSamplers: TVkSamplerList read fImmutableSamplers; function GetStructure: TVkDescriptorSetLayoutBinding; procedure SetStructure(const aData: TVkDescriptorSetLayoutBinding); procedure AfterConstruction; override; procedure BeforeDestruction; override; end; TvkuDescriptorSetLayoutBindingArr = specialize TvkuObjList; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuDescriptorSetLayoutFactory = class(TvkuDeviceObjFactory) private fFlags: VkDescriptorSetLayoutCreateFlags; fBindings: TvkuDescriptorSetLayoutBindingArr; fvkBindings: TVkDescriptorSetLayoutBindingArr; public property Flags: VkDescriptorSetLayoutCreateFlags read fFlags write fFlags; property Bindings: TvkuDescriptorSetLayoutBindingArr read fBindings; function GetStructure: TVkDescriptorSetLayoutCreateInfo; procedure SetStructure(const aData: TVkDescriptorSetLayoutCreateInfo); function CreateDescriptorSetLayout: TvkuDescriptorSetLayout; procedure AfterConstruction; override; procedure BeforeDestruction; override; end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuDescriptorSetLayoutBinding///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuDescriptorSetLayoutBinding.GetStructure: TVkDescriptorSetLayoutBinding; begin FillByte(result, SizeOf(result), 0); result.binding := Binding; result.descriptorType := DescriptorType; result.descriptorCount := DescriptorCount; result.stageFlags := StageFlags; result.pImmutableSamplers := fImmutableSamplers.PData; if (fImmutableSamplers.Length <> 0) and (fImmutableSamplers.Length <> DescriptorCount) then raise TvkuException.Create('''ImmutableSamplers'' must be either empty or contains ''DescriptorCount'' number of elements'); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorSetLayoutBinding.SetStructure(const aData: TVkDescriptorSetLayoutBinding); var i: Integer; begin Binding := aData.binding; DescriptorType := aData.descriptorType; StageFlags := aData.stageFlags; fImmutableSamplers.SetData(aData.pImmutableSamplers, aData.descriptorCount); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorSetLayoutBinding.AfterConstruction; begin inherited AfterConstruction; fImmutableSamplers := TVkSamplerList.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorSetLayoutBinding.BeforeDestruction; begin FreeAndNil(fImmutableSamplers); inherited BeforeDestruction; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuDescriptorSetLayoutFactory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuDescriptorSetLayoutFactory.GetStructure: TVkDescriptorSetLayoutCreateInfo; var i: Integer; begin SetLength(fvkBindings, fBindings.Length); for i := low(fvkBindings) to high(fvkBindings) do fvkBindings[i] := fBindings[i].GetStructure; FillByte(result, SizeOf(result), 0); result.sType := VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; result.pNext := nil; result.flags := fFlags; result.bindingCount := Length(fvkBindings); result.pBindings := @fvkBindings[0]; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorSetLayoutFactory.SetStructure(const aData: TVkDescriptorSetLayoutCreateInfo); var i: Integer; begin fFlags := aData.flags; fBindings.Length := aData.bindingCount; for i := 0 to fBindings.Length do fBindings[i].SetStructure((aData.pBindings + i)^); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuDescriptorSetLayoutFactory.CreateDescriptorSetLayout: TvkuDescriptorSetLayout; begin result := TvkuDescriptorSetLayout.Create(GetStructure, DeviceCommands, AllocCallbacks); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorSetLayoutFactory.AfterConstruction; begin inherited AfterConstruction; fBindings := TvkuDescriptorSetLayoutBindingArr.Create; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorSetLayoutFactory.BeforeDestruction; begin FreeAndNil(fBindings); inherited BeforeDestruction; end; end.