* implemented methods for other classes * implemented init/render codemaster
@@ -0,0 +1,3 @@ | |||
[submodule "projects/lazopenglcore"] | |||
path = projects/lazopenglcore | |||
url = ../lazopenglcore.git |
@@ -1947,9 +1947,9 @@ type { structures } | |||
maxFragmentDualSrcAttachments: VkUint32; | |||
maxFragmentCombinedOutputResources: VkUint32; | |||
maxComputeSharedMemorySize: VkUint32; | |||
maxComputeWorkGroupCount: array[0..3] of VkUint32; | |||
maxComputeWorkGroupCount: array[0..2] of VkUint32; | |||
maxComputeWorkGroupInvocations: VkUint32; | |||
maxComputeWorkGroupSize: array[0..3] of VkUint32; | |||
maxComputeWorkGroupSize: array[0..2] of VkUint32; | |||
subPixelPrecisionBits: VkUint32; | |||
subTexelPrecisionBits: VkUint32; | |||
mipmapPrecisionBits: VkUint32; | |||
@@ -1958,8 +1958,8 @@ type { structures } | |||
maxSamplerLodBias: VkFloat; | |||
maxSamplerAnisotropy: VkFloat; | |||
maxViewports: VkUint32; | |||
maxViewportDimensions: array[0..2] of VkUint32; | |||
viewportBoundsRange: array[0..2] of VkFloat; | |||
maxViewportDimensions: array[0..1] of VkUint32; | |||
viewportBoundsRange: array[0..1] of VkFloat; | |||
viewportSubPixelBits: VkUint32; | |||
minMemoryMapAlignment: VkSize; | |||
minTexelBufferOffsetAlignment: VkDeviceSize; | |||
@@ -1992,8 +1992,8 @@ type { structures } | |||
maxCullDistances: VkUint32; | |||
maxCombinedClipAndCullDistances: VkUint32; | |||
discreteQueuePriorities: VkUint32; | |||
pointSizeRange: array[0..2] of VkFloat; | |||
lineWidthRange: array[0..2] of VkFloat; | |||
pointSizeRange: array[0..1] of VkFloat; | |||
lineWidthRange: array[0..1] of VkFloat; | |||
pointSizeGranularity: VkFloat; | |||
lineWidthGranularity: VkFloat; | |||
strictLines: VkBool32; | |||
@@ -2585,7 +2585,7 @@ type { structures } | |||
logicOp: TVkLogicOp; | |||
attachmentCount: VkUint32; | |||
pAttachments: PVkPipelineColorBlendAttachmentState; | |||
blendConstants: array[0..4] of VkFloat; | |||
blendConstants: array[0..3] of VkFloat; | |||
end; | |||
PVkPipelineColorBlendStateCreateInfo = ^TVkPipelineColorBlendStateCreateInfo; | |||
PPVkPipelineColorBlendStateCreateInfo = ^PVkPipelineColorBlendStateCreateInfo; | |||
@@ -2918,9 +2918,9 @@ type { structures } | |||
TVkImageBlit = record | |||
srcSubresource: TVkImageSubresourceLayers; | |||
srcOffsets: array[0..2] of TVkOffset3D; | |||
srcOffsets: array[0..1] of TVkOffset3D; | |||
dstSubresource: TVkImageSubresourceLayers; | |||
dstOffsets: array[0..2] of TVkOffset3D; | |||
dstOffsets: array[0..1] of TVkOffset3D; | |||
end; | |||
PVkImageBlit = ^TVkImageBlit; | |||
PPVkImageBlit = ^PVkImageBlit; | |||
@@ -2938,9 +2938,9 @@ type { structures } | |||
TVkClearColorValue = record | |||
case Integer of | |||
000: (float32: array[0..4] of VkFloat); | |||
001: (int32: array[0..4] of VkInt32); | |||
002: (uint32: array[0..4] of VkUint32); | |||
000: (float32: array[0..3] of VkFloat); | |||
001: (int32: array[0..3] of VkInt32); | |||
002: (uint32: array[0..3] of VkUint32); | |||
end; | |||
PVkClearColorValue = ^TVkClearColorValue; | |||
PPVkClearColorValue = ^PVkClearColorValue; | |||
@@ -675,7 +675,7 @@ begin | |||
raise Exception.Create('void can not be used as type'); | |||
if (aArrSize <> '') then begin | |||
if TryStrToInt(String(aArrSize), i) | |||
then aName := WideString(Format('array[0..%d] of %s', [i, aName])) | |||
then aName := WideString(Format('array[0..%d] of %s', [i-1, aName])) | |||
else aName := WideString(Format('array[0..%s-1] of %s', [aArrSize, aName])); | |||
end; | |||
end; | |||
@@ -17,8 +17,8 @@ | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="1"/> | |||
<TopLine Value="1494"/> | |||
<CursorPos X="78" Y="1518"/> | |||
<TopLine Value="228"/> | |||
<CursorPos X="58" Y="241"/> | |||
<UsageCount Value="23"/> | |||
<Loaded Value="True"/> | |||
</Unit1> | |||
@@ -34,8 +34,8 @@ | |||
<Filename Value="..\Vulkan.pas"/> | |||
<IsVisibleTab Value="True"/> | |||
<EditorIndex Value="2"/> | |||
<TopLine Value="666"/> | |||
<CursorPos X="41" Y="691"/> | |||
<TopLine Value="2914"/> | |||
<CursorPos X="65" Y="2941"/> | |||
<UsageCount Value="11"/> | |||
<Loaded Value="True"/> | |||
</Unit3> | |||
@@ -50,123 +50,123 @@ | |||
<JumpHistory Count="30" HistoryIndex="29"> | |||
<Position1> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1446" TopLine="1432"/> | |||
<Caret Line="1446" Column="19" TopLine="1432"/> | |||
</Position1> | |||
<Position2> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1450" TopLine="1432"/> | |||
<Caret Line="215" Column="27" TopLine="205"/> | |||
</Position2> | |||
<Position3> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1446" TopLine="1432"/> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="528" Column="31" TopLine="503"/> | |||
</Position3> | |||
<Position4> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1450" TopLine="1432"/> | |||
<Caret Line="1447" Column="20" TopLine="1432"/> | |||
</Position4> | |||
<Position5> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1446" Column="19" TopLine="1432"/> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="1186" Column="75" TopLine="1175"/> | |||
</Position5> | |||
<Position6> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="215" Column="27" TopLine="205"/> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="215" Column="70" TopLine="200"/> | |||
</Position6> | |||
<Position7> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret TopLine="69"/> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1447" TopLine="1431"/> | |||
</Position7> | |||
<Position8> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="528" Column="31" TopLine="503"/> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1518" Column="89" TopLine="1504"/> | |||
</Position8> | |||
<Position9> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1447" Column="20" TopLine="1432"/> | |||
<Caret Line="1449" Column="49" TopLine="1431"/> | |||
</Position9> | |||
<Position10> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="1186" Column="75" TopLine="1175"/> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1448" TopLine="1431"/> | |||
</Position10> | |||
<Position11> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="215" Column="70" TopLine="200"/> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1452" TopLine="1431"/> | |||
</Position11> | |||
<Position12> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1447" TopLine="1431"/> | |||
<Caret Line="1446" TopLine="1431"/> | |||
</Position12> | |||
<Position13> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1518" Column="89" TopLine="1504"/> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="527" Column="31" TopLine="504"/> | |||
</Position13> | |||
<Position14> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1449" Column="49" TopLine="1431"/> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="557" Column="28" TopLine="532"/> | |||
</Position14> | |||
<Position15> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1448" TopLine="1431"/> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="567" Column="29" TopLine="542"/> | |||
</Position15> | |||
<Position16> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1452" TopLine="1431"/> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="579" Column="29" TopLine="554"/> | |||
</Position16> | |||
<Position17> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1446" TopLine="1431"/> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="599" Column="22" TopLine="574"/> | |||
</Position17> | |||
<Position18> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="527" Column="31" TopLine="504"/> | |||
<Caret Line="609" Column="32" TopLine="584"/> | |||
</Position18> | |||
<Position19> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="557" Column="28" TopLine="532"/> | |||
<Caret Line="615" Column="44" TopLine="590"/> | |||
</Position19> | |||
<Position20> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="567" Column="29" TopLine="542"/> | |||
<Caret Line="637" Column="31" TopLine="612"/> | |||
</Position20> | |||
<Position21> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="579" Column="29" TopLine="554"/> | |||
<Caret Line="646" Column="29" TopLine="621"/> | |||
</Position21> | |||
<Position22> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="599" Column="22" TopLine="574"/> | |||
<Caret Line="654" Column="36" TopLine="629"/> | |||
</Position22> | |||
<Position23> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="609" Column="32" TopLine="584"/> | |||
<Caret Line="660" Column="47" TopLine="635"/> | |||
</Position23> | |||
<Position24> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="615" Column="44" TopLine="590"/> | |||
<Caret Line="666" Column="41" TopLine="641"/> | |||
</Position24> | |||
<Position25> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="637" Column="31" TopLine="612"/> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1446" TopLine="1431"/> | |||
</Position25> | |||
<Position26> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="646" Column="29" TopLine="621"/> | |||
<Caret Line="691" Column="41" TopLine="578"/> | |||
</Position26> | |||
<Position27> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="654" Column="36" TopLine="629"/> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1518" Column="78" TopLine="1486"/> | |||
</Position27> | |||
<Position28> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="660" Column="47" TopLine="635"/> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="243" Column="62" TopLine="228"/> | |||
</Position28> | |||
<Position29> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<Caret Line="666" Column="41" TopLine="641"/> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="678" Column="65" TopLine="651"/> | |||
</Position29> | |||
<Position30> | |||
<Filename Value="HeaderGenerator.pas"/> | |||
<Caret Line="1446" TopLine="1431"/> | |||
<Caret Line="679" Column="49" TopLine="652"/> | |||
</Position30> | |||
</JumpHistory> | |||
</ProjectSession> | |||
@@ -0,0 +1 @@ | |||
Subproject commit f4a09e3657bd0fa4eacfde88a5b19609ad215d92 |
@@ -33,7 +33,7 @@ | |||
<PackageName Value="LCL"/> | |||
</Item1> | |||
</RequiredPackages> | |||
<Units Count="46"> | |||
<Units Count="49"> | |||
<Unit0> | |||
<Filename Value="triangle.lpr"/> | |||
<IsPartOfProject Value="True"/> | |||
@@ -221,6 +221,18 @@ | |||
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
</Unit45> | |||
<Unit46> | |||
<Filename Value="..\utils\uvkuDescriptorPool.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
</Unit46> | |||
<Unit47> | |||
<Filename Value="..\utils\uvkuDescriptorPoolFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
</Unit47> | |||
<Unit48> | |||
<Filename Value="..\utils\uvkuDescriptorSet.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
</Unit48> | |||
</Units> | |||
</ProjectOptions> | |||
<CompilerOptions> | |||
@@ -231,12 +243,12 @@ | |||
</Target> | |||
<SearchPaths> | |||
<IncludeFiles Value="$(ProjOutDir);.."/> | |||
<OtherUnitFiles Value="..;..\utils"/> | |||
<OtherUnitFiles Value="..;..\utils;..\lazopenglcore"/> | |||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> | |||
</SearchPaths> | |||
<CodeGeneration> | |||
<TargetCPU Value="x86_64"/> | |||
<TargetOS Value="win64"/> | |||
<TargetCPU Value="i386"/> | |||
<TargetOS Value="win32"/> | |||
</CodeGeneration> | |||
<Linking> | |||
<Debugging> | |||
@@ -8,7 +8,7 @@ uses | |||
cthreads, | |||
{$ENDIF}{$ENDIF} | |||
SysUtils, Interfaces, Dialogs, Forms, | |||
uMainForm, Vulkan, uvkuDebugReporter, uvkuPipelineCache, uvkuPipelineCacheFactory; | |||
uMainForm, Vulkan, uvkuDescriptorPool, uvkuDescriptorPoolFactory, uvkuDescriptorSet; | |||
{$R *.res} | |||
@@ -4,13 +4,13 @@ | |||
<PathDelim Value="\"/> | |||
<Version Value="9"/> | |||
<BuildModes Active="Default"/> | |||
<Units Count="66"> | |||
<Units Count="70"> | |||
<Unit0> | |||
<Filename Value="triangle.lpr"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<CursorPos X="3" Y="31"/> | |||
<UsageCount Value="103"/> | |||
<CursorPos X="20" Y="11"/> | |||
<UsageCount Value="124"/> | |||
</Unit0> | |||
<Unit1> | |||
<Filename Value="uMainForm.pas"/> | |||
@@ -19,33 +19,32 @@ | |||
<HasResources Value="True"/> | |||
<ResourceBaseClass Value="Form"/> | |||
<IsVisibleTab Value="True"/> | |||
<EditorIndex Value="7"/> | |||
<TopLine Value="525"/> | |||
<CursorPos X="21" Y="541"/> | |||
<EditorIndex Value="2"/> | |||
<TopLine Value="115"/> | |||
<CursorPos X="3" Y="131"/> | |||
<ExtraEditorCount Value="1"/> | |||
<ExtraEditor1> | |||
<IsVisibleTab Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<WindowIndex Value="1"/> | |||
<TopLine Value="-1"/> | |||
<CursorPos X="-1" Y="-1"/> | |||
<TopLine Value="29"/> | |||
<CursorPos X="5" Y="46"/> | |||
</ExtraEditor1> | |||
<UsageCount Value="103"/> | |||
<UsageCount Value="124"/> | |||
<Loaded Value="True"/> | |||
<LoadedDesigner Value="True"/> | |||
</Unit1> | |||
<Unit2> | |||
<Filename Value="..\Vulkan.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="4"/> | |||
<TopLine Value="1324"/> | |||
<CursorPos X="133" Y="1340"/> | |||
<EditorIndex Value="5"/> | |||
<TopLine Value="3006"/> | |||
<CursorPos X="79" Y="3022"/> | |||
<ExtraEditorCount Value="1"/> | |||
<ExtraEditor1> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="3271"/> | |||
<CursorPos X="80" Y="3291"/> | |||
<TopLine Value="2730"/> | |||
<CursorPos Y="2754"/> | |||
</ExtraEditor1> | |||
<UsageCount Value="103"/> | |||
<UsageCount Value="124"/> | |||
<Loaded Value="True"/> | |||
</Unit2> | |||
<Unit3> | |||
@@ -53,7 +52,7 @@ | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<CursorPos X="45" Y="16"/> | |||
<UsageCount Value="101"/> | |||
<UsageCount Value="122"/> | |||
</Unit3> | |||
<Unit4> | |||
<Filename Value="..\utils\uvkuInstanceFactory.pas"/> | |||
@@ -61,31 +60,30 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="13"/> | |||
<CursorPos X="3" Y="29"/> | |||
<UsageCount Value="95"/> | |||
<UsageCount Value="116"/> | |||
</Unit4> | |||
<Unit5> | |||
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="6"/> | |||
<CursorPos X="67" Y="22"/> | |||
<UsageCount Value="95"/> | |||
<TopLine Value="68"/> | |||
<CursorPos Y="87"/> | |||
<UsageCount Value="116"/> | |||
</Unit5> | |||
<Unit6> | |||
<Filename Value="..\utils\uvkuAllocationHandler.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<TopLine Value="7"/> | |||
<CursorPos X="22" Y="23"/> | |||
<UsageCount Value="85"/> | |||
<Loaded Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="11"/> | |||
<CursorPos Y="36"/> | |||
<UsageCount Value="106"/> | |||
</Unit6> | |||
<Unit7> | |||
<Filename Value="..\utils\uvkuDevice.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="10"/> | |||
<TopLine Value="28"/> | |||
<CursorPos X="14" Y="29"/> | |||
<UsageCount Value="89"/> | |||
<TopLine Value="135"/> | |||
<CursorPos X="9" Y="62"/> | |||
<UsageCount Value="110"/> | |||
<Loaded Value="True"/> | |||
</Unit7> | |||
<Unit8> | |||
@@ -94,7 +92,7 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="11"/> | |||
<CursorPos X="10" Y="18"/> | |||
<UsageCount Value="87"/> | |||
<UsageCount Value="108"/> | |||
</Unit8> | |||
<Unit9> | |||
<Filename Value="..\utils\uvkuSurface.pas"/> | |||
@@ -102,7 +100,7 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="41"/> | |||
<CursorPos X="94" Y="56"/> | |||
<UsageCount Value="82"/> | |||
<UsageCount Value="103"/> | |||
</Unit9> | |||
<Unit10> | |||
<Filename Value="..\utils\uvkuSurfaceFactory.pas"/> | |||
@@ -110,15 +108,14 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="44"/> | |||
<CursorPos X="33" Y="60"/> | |||
<UsageCount Value="81"/> | |||
<UsageCount Value="102"/> | |||
</Unit10> | |||
<Unit11> | |||
<Filename Value="..\utils\uvkuSwapChainFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="14"/> | |||
<EditorIndex Value="-1"/> | |||
<CursorPos X="3" Y="13"/> | |||
<UsageCount Value="72"/> | |||
<Loaded Value="True"/> | |||
<UsageCount Value="93"/> | |||
</Unit11> | |||
<Unit12> | |||
<Filename Value="..\utils\uvkuSwapChain.pas"/> | |||
@@ -126,83 +123,79 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="7"/> | |||
<CursorPos X="36" Y="23"/> | |||
<UsageCount Value="71"/> | |||
<UsageCount Value="92"/> | |||
</Unit12> | |||
<Unit13> | |||
<Filename Value="..\utils\uvkuImageView.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="29"/> | |||
<CursorPos X="64" Y="47"/> | |||
<UsageCount Value="68"/> | |||
<TopLine Value="40"/> | |||
<CursorPos Y="48"/> | |||
<UsageCount Value="89"/> | |||
</Unit13> | |||
<Unit14> | |||
<Filename Value="..\utils\uvkuImageViewFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="24"/> | |||
<CursorPos X="60" Y="88"/> | |||
<UsageCount Value="68"/> | |||
<CursorPos X="43" Y="9"/> | |||
<UsageCount Value="89"/> | |||
</Unit14> | |||
<Unit15> | |||
<Filename Value="..\utils\uvkuImage.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="9"/> | |||
<TopLine Value="208"/> | |||
<CursorPos Y="58"/> | |||
<UsageCount Value="67"/> | |||
<Loaded Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="173"/> | |||
<CursorPos X="36" Y="195"/> | |||
<UsageCount Value="88"/> | |||
</Unit15> | |||
<Unit16> | |||
<Filename Value="..\utils\uvkuBase.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="3"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="10"/> | |||
<CursorPos X="3" Y="26"/> | |||
<UsageCount Value="66"/> | |||
<Loaded Value="True"/> | |||
<UsageCount Value="87"/> | |||
</Unit16> | |||
<Unit17> | |||
<Filename Value="..\utils\uvkuDeviceMemory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="11"/> | |||
<CursorPos X="35" Y="75"/> | |||
<UsageCount Value="64"/> | |||
<Loaded Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="10"/> | |||
<CursorPos X="17" Y="23"/> | |||
<UsageCount Value="85"/> | |||
</Unit17> | |||
<Unit18> | |||
<Filename Value="..\utils\uvkuBuffer.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="10"/> | |||
<CursorPos X="3" Y="13"/> | |||
<UsageCount Value="63"/> | |||
<TopLine Value="85"/> | |||
<CursorPos X="42" Y="100"/> | |||
<UsageCount Value="84"/> | |||
</Unit18> | |||
<Unit19> | |||
<Filename Value="..\utils\uvkuImageFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="8"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="32"/> | |||
<CursorPos Y="41"/> | |||
<UsageCount Value="63"/> | |||
<Loaded Value="True"/> | |||
<UsageCount Value="84"/> | |||
</Unit19> | |||
<Unit20> | |||
<Filename Value="..\utils\uvkuTypes.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="16"/> | |||
<TopLine Value="63"/> | |||
<CursorPos X="75" Y="77"/> | |||
<UsageCount Value="63"/> | |||
<EditorIndex Value="1"/> | |||
<TopLine Value="93"/> | |||
<CursorPos X="3" Y="109"/> | |||
<UsageCount Value="84"/> | |||
<Loaded Value="True"/> | |||
</Unit20> | |||
<Unit21> | |||
<Filename Value="..\utils\uvkuBufferFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="20"/> | |||
<CursorPos X="60" Y="58"/> | |||
<UsageCount Value="62"/> | |||
<TopLine Value="18"/> | |||
<CursorPos Y="27"/> | |||
<UsageCount Value="83"/> | |||
</Unit21> | |||
<Unit22> | |||
<Filename Value="..\utils\uvkuBufferView.pas"/> | |||
@@ -210,89 +203,88 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="52"/> | |||
<CursorPos X="56" Y="76"/> | |||
<UsageCount Value="62"/> | |||
<UsageCount Value="83"/> | |||
</Unit22> | |||
<Unit23> | |||
<Filename Value="..\utils\uvkuBufferViewFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<CursorPos X="31" Y="45"/> | |||
<UsageCount Value="61"/> | |||
<UsageCount Value="82"/> | |||
</Unit23> | |||
<Unit24> | |||
<Filename Value="..\utils\uvkuCommandPool.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="17"/> | |||
<TopLine Value="9"/> | |||
<CursorPos X="50" Y="27"/> | |||
<UsageCount Value="61"/> | |||
<Loaded Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="61"/> | |||
<CursorPos X="3" Y="64"/> | |||
<UsageCount Value="82"/> | |||
</Unit24> | |||
<Unit25> | |||
<Filename Value="..\utils\uvkuCommandPoolFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="18"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="23"/> | |||
<CursorPos X="3" Y="34"/> | |||
<UsageCount Value="60"/> | |||
<Loaded Value="True"/> | |||
<UsageCount Value="81"/> | |||
</Unit25> | |||
<Unit26> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="15"/> | |||
<TopLine Value="46"/> | |||
<CursorPos X="74" Y="70"/> | |||
<UsageCount Value="60"/> | |||
<EditorIndex Value="4"/> | |||
<TopLine Value="311"/> | |||
<CursorPos X="16" Y="267"/> | |||
<UsageCount Value="81"/> | |||
<Loaded Value="True"/> | |||
</Unit26> | |||
<Unit27> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="13"/> | |||
<TopLine Value="55"/> | |||
<CursorPos X="75" Y="76"/> | |||
<UsageCount Value="60"/> | |||
<Loaded Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="5"/> | |||
<CursorPos X="7" Y="22"/> | |||
<UsageCount Value="81"/> | |||
</Unit27> | |||
<Unit28> | |||
<Filename Value="..\utils\VulkanUtils.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="12"/> | |||
<TopLine Value="65"/> | |||
<CursorPos X="3" Y="72"/> | |||
<UsageCount Value="59"/> | |||
<EditorIndex Value="3"/> | |||
<TopLine Value="75"/> | |||
<CursorPos X="3" Y="90"/> | |||
<UsageCount Value="80"/> | |||
<Loaded Value="True"/> | |||
</Unit28> | |||
<Unit29> | |||
<Filename Value="..\utils\uvkuUtils.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="14"/> | |||
<UsageCount Value="76"/> | |||
<TopLine Value="472"/> | |||
<CursorPos Y="492"/> | |||
<UsageCount Value="97"/> | |||
</Unit29> | |||
<Unit30> | |||
<Filename Value="..\utils\uvkuRenderPass.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<CursorPos X="3" Y="13"/> | |||
<UsageCount Value="57"/> | |||
<TopLine Value="52"/> | |||
<CursorPos Y="77"/> | |||
<UsageCount Value="78"/> | |||
</Unit30> | |||
<Unit31> | |||
<Filename Value="..\utils\uvkuRenderPassFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<CursorPos X="82" Y="11"/> | |||
<UsageCount Value="57"/> | |||
<TopLine Value="286"/> | |||
<CursorPos X="39" Y="304"/> | |||
<UsageCount Value="78"/> | |||
</Unit31> | |||
<Unit32> | |||
<Filename Value="..\utils\uvkuFactoryBase.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="1"/> | |||
<TopLine Value="69"/> | |||
<CursorPos X="42" Y="88"/> | |||
<UsageCount Value="57"/> | |||
<Loaded Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="7"/> | |||
<CursorPos X="69" Y="9"/> | |||
<UsageCount Value="78"/> | |||
</Unit32> | |||
<Unit33> | |||
<Filename Value="..\utils\uvkuFrameBuffer.pas"/> | |||
@@ -300,7 +292,7 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="33"/> | |||
<CursorPos X="150" Y="40"/> | |||
<UsageCount Value="55"/> | |||
<UsageCount Value="76"/> | |||
</Unit33> | |||
<Unit34> | |||
<Filename Value="..\utils\uvkuFrameBufferFactory.pas"/> | |||
@@ -308,14 +300,14 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="12"/> | |||
<CursorPos X="25" Y="27"/> | |||
<UsageCount Value="55"/> | |||
<UsageCount Value="76"/> | |||
</Unit34> | |||
<Unit35> | |||
<Filename Value="..\utils\uvkuDescriptorSetLayout.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<CursorPos X="150" Y="12"/> | |||
<UsageCount Value="55"/> | |||
<UsageCount Value="76"/> | |||
</Unit35> | |||
<Unit36> | |||
<Filename Value="..\utils\uvkuDescriptorSetLayoutFactory.pas"/> | |||
@@ -323,7 +315,7 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="89"/> | |||
<CursorPos X="3" Y="106"/> | |||
<UsageCount Value="54"/> | |||
<UsageCount Value="75"/> | |||
</Unit36> | |||
<Unit37> | |||
<Filename Value="..\utils\uvkuPipelineLayout.pas"/> | |||
@@ -331,7 +323,7 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="48"/> | |||
<CursorPos X="150" Y="53"/> | |||
<UsageCount Value="54"/> | |||
<UsageCount Value="75"/> | |||
</Unit37> | |||
<Unit38> | |||
<Filename Value="..\utils\uvkuPipelineLayoutFactory.pas"/> | |||
@@ -339,334 +331,365 @@ | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="10"/> | |||
<CursorPos X="37" Y="112"/> | |||
<UsageCount Value="54"/> | |||
<UsageCount Value="75"/> | |||
</Unit38> | |||
<Unit39> | |||
<Filename Value="..\utils\uvkuShaderModule.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="54"/> | |||
<CursorPos X="3" Y="67"/> | |||
<UsageCount Value="52"/> | |||
<TopLine Value="39"/> | |||
<CursorPos Y="61"/> | |||
<UsageCount Value="73"/> | |||
</Unit39> | |||
<Unit40> | |||
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="117"/> | |||
<CursorPos X="37" Y="127"/> | |||
<UsageCount Value="52"/> | |||
<TopLine Value="136"/> | |||
<CursorPos Y="159"/> | |||
<UsageCount Value="73"/> | |||
</Unit40> | |||
<Unit41> | |||
<Filename Value="..\utils\uvkuPipeline.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="7"/> | |||
<CursorPos X="23" Y="92"/> | |||
<UsageCount Value="50"/> | |||
<TopLine Value="9"/> | |||
<CursorPos Y="12"/> | |||
<UsageCount Value="71"/> | |||
</Unit41> | |||
<Unit42> | |||
<Filename Value="..\utils\uvkuPipelineFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="7"/> | |||
<CursorPos X="3" Y="23"/> | |||
<UsageCount Value="49"/> | |||
<UsageCount Value="70"/> | |||
</Unit42> | |||
<Unit43> | |||
<Filename Value="..\utils\uvkuDebugReporter.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="2"/> | |||
<TopLine Value="102"/> | |||
<CursorPos Y="119"/> | |||
<UsageCount Value="27"/> | |||
<Loaded Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="84"/> | |||
<CursorPos X="32" Y="103"/> | |||
<UsageCount Value="48"/> | |||
</Unit43> | |||
<Unit44> | |||
<Filename Value="..\utils\uvkuPipelineCache.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="18"/> | |||
<CursorPos X="13" Y="38"/> | |||
<UsageCount Value="42"/> | |||
</Unit44> | |||
<Unit45> | |||
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="33"/> | |||
<CursorPos X="84" Y="61"/> | |||
<UsageCount Value="42"/> | |||
</Unit45> | |||
<Unit46> | |||
<Filename Value="..\utils\uvkuDescriptorPool.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="16"/> | |||
<CursorPos X="5" Y="16"/> | |||
<UsageCount Value="29"/> | |||
</Unit46> | |||
<Unit47> | |||
<Filename Value="..\utils\uvkuDescriptorPoolFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="7"/> | |||
<CursorPos X="68" Y="31"/> | |||
<UsageCount Value="29"/> | |||
</Unit47> | |||
<Unit48> | |||
<Filename Value="..\utils\uvkuDescriptorSet.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="11"/> | |||
<CursorPos Y="51"/> | |||
<UsageCount Value="28"/> | |||
</Unit48> | |||
<Unit49> | |||
<Filename Value="..\utils\uvkuPhysicalDeviceFactory.pas"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="5"/> | |||
<CursorPos X="19" Y="17"/> | |||
<UsageCount Value="46"/> | |||
</Unit44> | |||
<Unit45> | |||
<UsageCount Value="44"/> | |||
</Unit49> | |||
<Unit50> | |||
<Filename Value="..\..\data\Vulkan.tpl"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="44"/> | |||
<CursorPos X="27" Y="22"/> | |||
<UsageCount Value="10"/> | |||
<UsageCount Value="8"/> | |||
<DefaultSyntaxHighlighter Value="None"/> | |||
</Unit45> | |||
<Unit46> | |||
</Unit50> | |||
<Unit51> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\packages\fcl-base\src\custapp.pp"/> | |||
<UnitName Value="CustApp"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="13"/> | |||
<CursorPos X="3" Y="30"/> | |||
<UsageCount Value="6"/> | |||
</Unit46> | |||
<Unit47> | |||
<UsageCount Value="4"/> | |||
</Unit51> | |||
<Unit52> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\inc\objpash.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="181"/> | |||
<CursorPos X="23" Y="197"/> | |||
<UsageCount Value="10"/> | |||
</Unit47> | |||
<Unit48> | |||
<UsageCount Value="8"/> | |||
</Unit52> | |||
<Unit53> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\customform.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="910"/> | |||
<CursorPos Y="927"/> | |||
<UsageCount Value="10"/> | |||
</Unit48> | |||
<Unit49> | |||
<UsageCount Value="8"/> | |||
</Unit53> | |||
<Unit54> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\objpas\sysutils\sysstrh.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="96"/> | |||
<CursorPos X="10" Y="112"/> | |||
<UsageCount Value="6"/> | |||
</Unit49> | |||
<Unit50> | |||
<UsageCount Value="4"/> | |||
</Unit54> | |||
<Unit55> | |||
<Filename Value="..\Vulkan_old.pas"/> | |||
<EditorIndex Value="-1"/> | |||
<WindowIndex Value="-1"/> | |||
<TopLine Value="2195"/> | |||
<CursorPos X="3" Y="2211"/> | |||
<UsageCount Value="6"/> | |||
</Unit50> | |||
<Unit51> | |||
<UsageCount Value="4"/> | |||
</Unit55> | |||
<Unit56> | |||
<Filename Value="..\Vulkan.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<UsageCount Value="10"/> | |||
</Unit51> | |||
<Unit52> | |||
<UsageCount Value="8"/> | |||
</Unit56> | |||
<Unit57> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\forms.pp"/> | |||
<UnitName Value="Forms"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="1249"/> | |||
<CursorPos X="3" Y="1268"/> | |||
<UsageCount Value="6"/> | |||
</Unit52> | |||
<Unit53> | |||
<UsageCount Value="4"/> | |||
</Unit57> | |||
<Unit58> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\objpas\classes\classesh.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="2100"/> | |||
<CursorPos X="38" Y="2125"/> | |||
<UsageCount Value="6"/> | |||
</Unit53> | |||
<Unit54> | |||
<UsageCount Value="4"/> | |||
</Unit58> | |||
<Unit59> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\extctrls.pp"/> | |||
<UnitName Value="ExtCtrls"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="1023"/> | |||
<CursorPos X="3" Y="1038"/> | |||
<UsageCount Value="6"/> | |||
</Unit54> | |||
<Unit55> | |||
<UsageCount Value="4"/> | |||
</Unit59> | |||
<Unit60> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\controls.pp"/> | |||
<UnitName Value="Controls"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="2240"/> | |||
<CursorPos X="3" Y="2255"/> | |||
<UsageCount Value="6"/> | |||
</Unit55> | |||
<Unit56> | |||
<UsageCount Value="4"/> | |||
</Unit60> | |||
<Unit61> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\objpas\sysutils\sysutilh.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="22"/> | |||
<CursorPos X="4" Y="37"/> | |||
<UsageCount Value="8"/> | |||
</Unit56> | |||
<Unit57> | |||
<UsageCount Value="6"/> | |||
</Unit61> | |||
<Unit62> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win\sysosh.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="7"/> | |||
<CursorPos X="3" Y="22"/> | |||
<UsageCount Value="8"/> | |||
</Unit57> | |||
<Unit58> | |||
<UsageCount Value="6"/> | |||
</Unit62> | |||
<Unit63> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\inc\systemh.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="93"/> | |||
<CursorPos X="19" Y="108"/> | |||
<UsageCount Value="8"/> | |||
</Unit58> | |||
<Unit59> | |||
<UsageCount Value="6"/> | |||
</Unit63> | |||
<Unit64> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win\wininc\ascdef.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="57"/> | |||
<CursorPos X="10" Y="72"/> | |||
<UsageCount Value="8"/> | |||
</Unit59> | |||
<Unit60> | |||
<UsageCount Value="6"/> | |||
</Unit64> | |||
<Unit65> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win32\windows.pp"/> | |||
<EditorIndex Value="-1"/> | |||
<UsageCount Value="8"/> | |||
</Unit60> | |||
<Unit61> | |||
<UsageCount Value="6"/> | |||
</Unit65> | |||
<Unit66> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win\wininc\base.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="84"/> | |||
<CursorPos X="6" Y="99"/> | |||
<UsageCount Value="8"/> | |||
</Unit61> | |||
<Unit62> | |||
<UsageCount Value="6"/> | |||
</Unit66> | |||
<Unit67> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\objpas\typinfo.pp"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="97"/> | |||
<CursorPos X="7" Y="113"/> | |||
<UsageCount Value="9"/> | |||
</Unit62> | |||
<Unit63> | |||
<UsageCount Value="7"/> | |||
</Unit67> | |||
<Unit68> | |||
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\application.inc"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="2148"/> | |||
<CursorPos Y="2163"/> | |||
<UsageCount Value="10"/> | |||
</Unit63> | |||
<Unit64> | |||
<Filename Value="..\utils\uvkuPipelineCache.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="5"/> | |||
<TopLine Value="18"/> | |||
<CursorPos X="13" Y="38"/> | |||
<UsageCount Value="21"/> | |||
<Loaded Value="True"/> | |||
</Unit64> | |||
<Unit65> | |||
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/> | |||
<IsPartOfProject Value="True"/> | |||
<EditorIndex Value="6"/> | |||
<TopLine Value="33"/> | |||
<CursorPos X="84" Y="61"/> | |||
<UsageCount Value="21"/> | |||
<Loaded Value="True"/> | |||
</Unit65> | |||
<UsageCount Value="8"/> | |||
</Unit68> | |||
<Unit69> | |||
<Filename Value="..\lazopenglcore\uglcCamera.pas"/> | |||
<EditorIndex Value="-1"/> | |||
<TopLine Value="31"/> | |||
<CursorPos X="21" Y="66"/> | |||
<UsageCount Value="8"/> | |||
</Unit69> | |||
</Units> | |||
<JumpHistory Count="30" HistoryIndex="29"> | |||
<JumpHistory Count="29" HistoryIndex="28"> | |||
<Position1> | |||
<Filename Value="..\utils\uvkuPipelineCache.pas"/> | |||
<Caret Line="18" Column="67" TopLine="6"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="931" TopLine="920"/> | |||
</Position1> | |||
<Position2> | |||
<Filename Value="..\utils\uvkuPipelineCache.pas"/> | |||
<Caret Line="72" Column="33" TopLine="40"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="932" TopLine="920"/> | |||
</Position2> | |||
<Position3> | |||
<Filename Value="..\utils\uvkuPipelineCache.pas"/> | |||
<Caret Line="15" Column="5"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="935" TopLine="920"/> | |||
</Position3> | |||
<Position4> | |||
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/> | |||
<Caret Line="16" Column="53"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="937" TopLine="920"/> | |||
</Position4> | |||
<Position5> | |||
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/> | |||
<Caret Line="20" Column="72"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="939" TopLine="920"/> | |||
</Position5> | |||
<Position6> | |||
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/> | |||
<Caret Line="43" Column="10" TopLine="21"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="942" TopLine="920"/> | |||
</Position6> | |||
<Position7> | |||
<Filename Value="..\utils\uvkuPipelineCache.pas"/> | |||
<Caret Line="12"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="941" TopLine="920"/> | |||
</Position7> | |||
<Position8> | |||
<Filename Value="..\utils\uvkuPipelineCache.pas"/> | |||
<Caret Line="38" Column="13" TopLine="29"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="944" TopLine="920"/> | |||
</Position8> | |||
<Position9> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="340" Column="45" TopLine="327"/> | |||
<Caret Line="947" TopLine="921"/> | |||
</Position9> | |||
<Position10> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="532" Column="19" TopLine="511"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="305" Column="24" TopLine="284"/> | |||
</Position10> | |||
<Position11> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="51" TopLine="33"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="301" TopLine="284"/> | |||
</Position11> | |||
<Position12> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="275" Column="37" TopLine="253"/> | |||
<Caret Line="933" TopLine="916"/> | |||
</Position12> | |||
<Position13> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="24" Column="18" TopLine="7"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="935" TopLine="916"/> | |||
</Position13> | |||
<Position14> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="275" Column="37" TopLine="253"/> | |||
<Caret Line="937" TopLine="916"/> | |||
</Position14> | |||
<Position15> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="540" Column="12" TopLine="531"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="262" TopLine="246"/> | |||
</Position15> | |||
<Position16> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="38" Column="5" TopLine="21"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="261" TopLine="246"/> | |||
</Position16> | |||
<Position17> | |||
<Filename Value="..\utils\VulkanUtils.pas"/> | |||
<Caret Line="72" Column="3" TopLine="65"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="260" TopLine="246"/> | |||
</Position17> | |||
<Position18> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="21" Column="71" TopLine="3"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="259" TopLine="246"/> | |||
</Position18> | |||
<Position19> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="37" Column="14" TopLine="12"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="255" TopLine="246"/> | |||
</Position19> | |||
<Position20> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="34" Column="5" TopLine="17"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="937" TopLine="916"/> | |||
</Position20> | |||
<Position21> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="49" Column="45" TopLine="21"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="263" TopLine="246"/> | |||
</Position21> | |||
<Position22> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="54" Column="59" TopLine="39"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="939" TopLine="916"/> | |||
</Position22> | |||
<Position23> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="26" Column="30" TopLine="5"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="930" Column="46" TopLine="916"/> | |||
</Position23> | |||
<Position24> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="38" Column="5" TopLine="21"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="254" TopLine="250"/> | |||
</Position24> | |||
<Position25> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="24" Column="36" TopLine="5"/> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="935" TopLine="916"/> | |||
</Position25> | |||
<Position26> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="26" Column="52" TopLine="10"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="258" Column="27" TopLine="249"/> | |||
</Position26> | |||
<Position27> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="38" Column="5" TopLine="20"/> | |||
<Filename Value="..\utils\uvkuCommandBuffer.pas"/> | |||
<Caret Line="267" Column="16" TopLine="311"/> | |||
</Position27> | |||
<Position28> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="541" Column="10" TopLine="524"/> | |||
<Caret Line="946" Column="22" TopLine="667"/> | |||
</Position28> | |||
<Position29> | |||
<Filename Value="..\utils\uvkuQueue.pas"/> | |||
<Caret Line="27" Column="24" TopLine="5"/> | |||
</Position29> | |||
<Position30> | |||
<Filename Value="uMainForm.pas"/> | |||
<Caret Line="541" Column="10" TopLine="524"/> | |||
</Position30> | |||
<Caret Line="141" Column="3" TopLine="124"/> | |||
</Position29> | |||
</JumpHistory> | |||
</ProjectSession> | |||
<Debugging> | |||
<BreakPoints Count="1"> | |||
<Item1> | |||
<Kind Value="bpkSource"/> | |||
<WatchScope Value="wpsLocal"/> | |||
<WatchKind Value="wpkWrite"/> | |||
<Source Value="uMainForm.pas"/> | |||
<Line Value="947"/> | |||
</Item1> | |||
</BreakPoints> | |||
<Watches Count="2"> | |||
<Item1> | |||
<Expression Value="self"/> | |||
@@ -6,7 +6,8 @@ interface | |||
uses | |||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, | |||
Vulkan, VulkanUtils; | |||
Vulkan, VulkanUtils, | |||
ugluVector, ugluMatrix, uglcCamera; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -18,6 +19,13 @@ type | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
type | |||
TUniforms = packed record | |||
ProjectionMat: TgluMatrix4f; | |||
ModelMatrix: TgluMatrix4f; | |||
ViewMatrix: TgluMatrix4f; | |||
end; | |||
TMainForm = class(TForm) | |||
RenderPanel: TPanel; | |||
procedure FormCreate(Sender: TObject); | |||
@@ -26,10 +34,11 @@ type | |||
fGraphicsQueueFamilyIndex: VkUint32; | |||
fGraphicsQueueNodeIndex: VkUint32; | |||
fPresentQueueNodeIndex: VkUint32; | |||
fSurfaceFormat: TVkFormat; | |||
fColorFormat: TVkFormat; | |||
fSurfaceColorSpace: TVkColorSpaceKHR; | |||
fDepthFormat: TVkFormat; | |||
fCamera: TglcCamera; | |||
fAllocHandler: TCustomAllocHandler; | |||
fDebugReporter: TvkuConsoleDebugReporter; | |||
fInstance: TvkuInstance; | |||
@@ -53,6 +62,21 @@ type | |||
fDepthStencilImage: TvkuImage; | |||
fDepthStencilImageView: TvkuImageView; | |||
fPipelineCache: TvkuPipelineCache; | |||
fDescriptorPool: TvkuDescriptorPool; | |||
fDescriptorSet: TvkuDescriptorSet; | |||
fVertex: packed record | |||
DataMemory: TvkuDeviceMemory; | |||
DataBuffer: TvkuBuffer; | |||
IndexMemory: TvkuDeviceMemory; | |||
IndexBuffer: TvkuBuffer; | |||
end; | |||
fUniform: packed record | |||
Values: TUniforms; | |||
Memory: TvkuDeviceMemory; | |||
Buffer: TvkuBuffer; | |||
end; | |||
procedure UpdateUniformBuffers; | |||
end; | |||
var | |||
@@ -63,6 +87,12 @@ implementation | |||
{$R *.lfm} | |||
{$I Vulkan.inc} | |||
uses | |||
uvkuUtils; | |||
const | |||
VERTEX_BUFFER_BIND_ID = 0; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TCustomAllocHandler//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -92,6 +122,26 @@ end; | |||
//TMainForm////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TMainForm.FormCreate(Sender: TObject); | |||
type | |||
TVertex = packed record | |||
position: array[0..2] of VkFloat; | |||
color: array[0..2] of VkFloat; | |||
end; | |||
TVertexData = array[0..2] of TVertex; | |||
TIndexData = array[0..2] of VkUint32; | |||
const | |||
ClearColor: TVkClearValue = ( color: ( float32: ( 0.0, 0.0, 0.0, 1.0 ) ) ); | |||
ClearDepthStencil: TVkClearValue = ( depthStencil: ( depth: 1.0; stencil: 0 ) ); | |||
VertexData: TVertexData = ( | |||
( position: ( 1.0, 1.0, 0.0 ); color: ( 1.0, 0.0, 0.0 ) ), | |||
( position: (-1.0, 1.0, 0.0 ); color: ( 0.0, 1.0, 0.0 ) ), | |||
( position: ( 0.0,-1.0, 0.0 ); color: ( 0.0, 0.0, 1.0 ) ) | |||
); | |||
IndexData: TIndexData = ( | |||
0, 1, 2 | |||
); | |||
var | |||
PhyDevices: TVkPhysicalDeviceArr; | |||
InstanceFactory: TvkuInstanceFactory; | |||
@@ -108,11 +158,14 @@ var | |||
ShaderModuleFactory: TvkuShaderModuleFactory; | |||
PipelineFactory: TvkuGraphicsPipelineFactory; | |||
PipelineCacheFactory: TvkuPipelineCacheFactory; | |||
BufferFactory: TvkuBufferFactory; | |||
DescriptorPoolFactory: TvkuDescriptorPoolFactory; | |||
SetupCommandBuffer: TvkuCommandBuffer; | |||
QueueFamProps: TVkQueueFamilyPropertiesArr; | |||
f: TVkFormat; | |||
i: Integer; | |||
p: PVkVoid; | |||
SrfFormats: TVkSurfaceFormatArr; | |||
SurfaceCapabilities: TVkSurfaceCapabilitiesKHR; | |||
PresentModes: TVkPresentModeArr; | |||
@@ -121,9 +174,13 @@ var | |||
AllocCallbacks: TVkAllocationCallbacks; | |||
ImageMemoryBarrier: TVkImageMemoryBarrier; | |||
CommandBuffers: TVkCommandBufferArr; | |||
MemReq: TVkMemoryRequirements; | |||
vp: TVkViewport; | |||
r2D: TVkRect2D; | |||
begin | |||
try | |||
fAllocHandler := TCustomAllocHandler.Create; | |||
fCamera := TglcCamera.Create; | |||
fAllocHandler := TCustomAllocHandler.Create; | |||
AllocCallbacks := fAllocHandler.GetStructure; | |||
////////////////////////////////////////////////////////////////////////////// | |||
@@ -215,13 +272,15 @@ begin | |||
fPresentQueueNodeIndex := high(fPresentQueueNodeIndex); | |||
QueueFamProps := fPhyDevice.GetQueueFamilyProperties; | |||
for i := low(QueueFamProps) to high(QueueFamProps) do begin | |||
if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then | |||
fGraphicsQueueNodeIndex := i; | |||
if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then begin | |||
if (fGraphicsQueueNodeIndex = high(fGraphicsQueueNodeIndex)) then | |||
fGraphicsQueueNodeIndex := i; | |||
if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin | |||
fGraphicsQueueNodeIndex := i; | |||
fPresentQueueNodeIndex := i; | |||
break; | |||
if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin | |||
fGraphicsQueueNodeIndex := i; | |||
fPresentQueueNodeIndex := i; | |||
break; | |||
end; | |||
end; | |||
end; | |||
if (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) then begin | |||
@@ -244,13 +303,13 @@ begin | |||
if (Length(SrfFormats) = 0) then | |||
raise TvkuException.Create('no suitable formats found'); | |||
if (Length(SrfFormats) = 1) and (SrfFormats[0].format = VK_FORMAT_UNDEFINED) then begin | |||
fSurfaceFormat := VK_FORMAT_R8G8B8A8_UNORM; | |||
fColorFormat := VK_FORMAT_B8G8R8A8_UNORM; | |||
fSurfaceColorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR; | |||
end else begin | |||
fSurfaceFormat := SrfFormats[0].format; | |||
fColorFormat := SrfFormats[0].format; | |||
fSurfaceColorSpace := SrfFormats[0].colorSpace; | |||
end; | |||
WriteLn(' format: ', fSurfaceFormat); | |||
WriteLn(' format: ', fColorFormat); | |||
WriteLn(' color space: ', fSurfaceColorSpace); | |||
WriteLn(' done'); | |||
@@ -269,7 +328,7 @@ begin | |||
WriteLn(' alloc setup command buffer'); | |||
SetupCommandBuffer := TvkuCommandBuffer.Create( | |||
fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY), | |||
fCommandPool.AllocateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY), | |||
true, fCommandPool.Handle, fDevice.DeviceCommands); | |||
SetupCommandBuffer.BeginCommand; | |||
WriteLn(' handle: ', PtrUInt(SetupCommandBuffer.Handle)); | |||
@@ -289,7 +348,7 @@ begin | |||
SwapChainFactory.ImageSharingMode := VK_SHARING_MODE_EXCLUSIVE; | |||
SwapChainFactory.Clipped := true; | |||
SwapChainFactory.ComposideAlpha := [ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR ]; | |||
SwapChainFactory.ImageFormat := fSurfaceFormat; | |||
SwapChainFactory.ImageFormat := fColorFormat; | |||
SwapChainFactory.ImageColorSpace := fSurfaceColorSpace; | |||
WriteLn(' get surface capabilities'); | |||
@@ -326,6 +385,10 @@ begin | |||
SwapChainFactory.PresentMode := pm; | |||
break; | |||
end; | |||
if (SwapChainFactory.PresentMode <> VK_PRESENT_MODE_MAILBOX_KHR) | |||
and (pm = VK_PRESENT_MODE_IMMEDIATE_KHR) | |||
then | |||
SwapChainFactory.PresentMode := pm; | |||
end; | |||
WriteLn(SwapChainFactory.PresentMode); | |||
@@ -344,7 +407,7 @@ begin | |||
ImageViewFactory := TvkuImageViewFactory.Create(fDevice); | |||
try | |||
ImageViewFactory.AllocHandler := fAllocHandler; | |||
ImageViewFactory.Format := fSurfaceFormat; | |||
ImageViewFactory.Format := fColorFormat; | |||
ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D; | |||
with ImageViewFactory.SubresourceRange do begin | |||
AspectMask := [ VK_IMAGE_ASPECT_COLOR_BIT ]; | |||
@@ -386,7 +449,7 @@ begin | |||
////////////////////////////////////////////////////////////////////////////// | |||
WriteLn('create draw command buffers'); | |||
SetLength(fDrawCommandBuffers, Length(fImageViews)); | |||
CommandBuffers := fCommandPool.CreateCommandBuffers( | |||
CommandBuffers := fCommandPool.AllocateCommandBuffers( | |||
VK_COMMAND_BUFFER_LEVEL_PRIMARY, | |||
Length(fDrawCommandBuffers)); | |||
for i := low(CommandBuffers) to high(CommandBuffers) do begin | |||
@@ -402,7 +465,7 @@ begin | |||
////////////////////////////////////////////////////////////////////////////// | |||
WriteLn('create post present command buffers'); | |||
fPostPresentCommandBuffer := TvkuCommandBuffer.Create( | |||
fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY), | |||
fCommandPool.AllocateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY), | |||
true, | |||
fCommandPool.Handle, | |||
fDevice.DeviceCommands); | |||
@@ -424,13 +487,28 @@ begin | |||
ImageFactory.ArrayLayers := 1; | |||
ImageFactory.Samples := [ VK_SAMPLE_COUNT_1_BIT ]; | |||
ImageFactory.Tiling := VK_IMAGE_TILING_OPTIMAL; | |||
ImageFactory.Usage := [ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ]; | |||
ImageFactory.Usage := [ | |||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, | |||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT ]; | |||
fDepthStencilImage := ImageFactory.CreateImage; | |||
fDepthStencilImage.AllocateAndBindImageMemory( | |||
fPhyDevice.GetMemoryProperties, | |||
@AllocCallbacks); | |||
WriteLn(' image handle: ', PtrUInt(fDepthStencilImage.Handle)); | |||
WriteLn(' create image memory barrier'); | |||
ImageMemoryBarrier := fImages[i].GetMemoryBarrier( | |||
[ VK_IMAGE_ASPECT_DEPTH_BIT ], | |||
VK_IMAGE_LAYOUT_UNDEFINED, | |||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); | |||
SetupCommandBuffer.PipelineBarrier( | |||
[ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ], | |||
[ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ], | |||
[], | |||
[], | |||
[], | |||
[ ImageMemoryBarrier ]); | |||
ImageViewFactory.Image := fDepthStencilImage.Handle; | |||
ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D; | |||
ImageViewFactory.Format := fDepthFormat; | |||
@@ -456,7 +534,7 @@ begin | |||
try | |||
RenderPassFactory.Attachments.Length := 2; | |||
with RenderPassFactory.Attachments[0] do begin | |||
Format := fSurfaceFormat; | |||
Format := fColorFormat; | |||
Samples := [ VK_SAMPLE_COUNT_1_BIT ]; | |||
LoadOp := VK_ATTACHMENT_LOAD_OP_CLEAR; | |||
StoreOp := VK_ATTACHMENT_STORE_OP_STORE; | |||
@@ -542,6 +620,100 @@ begin | |||
FreeAndNil(SetupCommandBuffer); | |||
WriteLn(' done'); | |||
////////////////////////////////////////////////////////////////////////////// | |||
WriteLn('recreate setup command buffer'); | |||
SetupCommandBuffer := TvkuCommandBuffer.Create( | |||
fCommandPool.AllocateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY), | |||
true, fCommandPool.Handle, fDevice.DeviceCommands); | |||
SetupCommandBuffer.BeginCommand; | |||
WriteLn(' handle: ', PtrUInt(SetupCommandBuffer.Handle)); | |||
WriteLn(' done'); | |||
////////////////////////////////////////////////////////////////////////////// | |||
BufferFactory := TvkuBufferFactory.Create(fDevice); | |||
try | |||
WriteLn('create vertex data buffer'); | |||
BufferFactory.Size := SizeOf(VertexData); | |||
BufferFactory.Usage := [ VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ]; | |||
fVertex.DataBuffer := BufferFactory.CreateBuffer; | |||
WriteLn(' buffer handle: ', PtrUInt(fVertex.DataBuffer.Handle)); | |||
MemReq := fVertex.DataBuffer.GetMemoryRequirements; | |||
fVertex.DataMemory := TvkuDeviceMemory.Create( | |||
fDevice.AllocateMemory( | |||
MemReq.size, | |||
vkuGetMemoryTypeIndex( | |||
fPhyDevice.GetMemoryProperties, | |||
MemReq.memoryTypeBits, | |||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT), | |||
@AllocCallbacks), | |||
true, | |||
fDevice.DeviceCommands, | |||
@AllocCallbacks); | |||
WriteLn(' memory handle: ', PtrUInt(fVertex.DataMemory.Handle)); | |||
p := fVertex.DataMemory.Map(0, MemReq.size, 0); | |||
try | |||
Move(VertexData, p^, SizeOf(VertexData)); | |||
finally | |||
fVertex.DataMemory.Unmap; | |||
end; | |||
fVertex.DataBuffer.BindMemory(fVertex.DataMemory.Handle, 0); | |||
WriteLn(' done'); | |||
WriteLn('create vertex index buffer'); | |||
BufferFactory.Size := SizeOf(IndexData); | |||
BufferFactory.Usage := [ VK_BUFFER_USAGE_INDEX_BUFFER_BIT ]; | |||
fVertex.IndexBuffer := BufferFactory.CreateBuffer; | |||
WriteLn(' buffer handle: ', PtrUInt(fVertex.IndexBuffer.Handle)); | |||
MemReq := fVertex.IndexBuffer.GetMemoryRequirements; | |||
fVertex.IndexMemory := TvkuDeviceMemory.Create( | |||
fDevice.AllocateMemory( | |||
MemReq.size, | |||
vkuGetMemoryTypeIndex( | |||
fPhyDevice.GetMemoryProperties, | |||
MemReq.memoryTypeBits, | |||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT), | |||
@AllocCallbacks), | |||
true, | |||
fDevice.DeviceCommands, | |||
@AllocCallbacks); | |||
WriteLn(' memory handle: ', PtrUInt(fVertex.IndexMemory.Handle)); | |||
p := fVertex.IndexMemory.Map(0, MemReq.size, 0); | |||
try | |||
Move(IndexData, p^, SizeOf(IndexData)); | |||
finally | |||
fVertex.IndexMemory.Unmap; | |||
end; | |||
fVertex.IndexBuffer.BindMemory(fVertex.IndexMemory.Handle, 0); | |||
WriteLn(' done'); | |||
WriteLn('create uniform buffer'); | |||
BufferFactory.Size := SizeOf(IndexData); | |||
BufferFactory.Usage := [ VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ]; | |||
fUniform.Buffer := BufferFactory.CreateBuffer; | |||
WriteLn(' buffer handle: ', PtrUInt(fUniform.Buffer.Handle)); | |||
MemReq := fUniform.Buffer.GetMemoryRequirements; | |||
fUniform.Memory := TvkuDeviceMemory.Create( | |||
fDevice.AllocateMemory( | |||
MemReq.size, | |||
vkuGetMemoryTypeIndex( | |||
fPhyDevice.GetMemoryProperties, | |||
MemReq.memoryTypeBits, | |||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT), | |||
@AllocCallbacks), | |||
true, | |||
fDevice.DeviceCommands, | |||
@AllocCallbacks); | |||
WriteLn(' memory handle: ', PtrUInt(fUniform.Memory.Handle)); | |||
fUniform.Buffer.BindMemory(fUniform.Memory.Handle, 0); | |||
UpdateUniformBuffers; | |||
WriteLn(' done'); | |||
finally | |||
FreeAndNil(BufferFactory); | |||
end; | |||
////////////////////////////////////////////////////////////////////////////// | |||
WriteLn('create descriptor set layout'); | |||
DescSetLayoutFactory := TvkuDescriptorSetLayoutFactory.Create(fDevice); | |||
@@ -583,11 +755,11 @@ begin | |||
try | |||
ShaderModuleFactory.AllocHandler := fAllocHandler; | |||
ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.vert', [ VK_SHADER_STAGE_VERTEX_BIT ]); | |||
ShaderModuleFactory.LoadSpvCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.vert.spv'); | |||
fVertexShader := ShaderModuleFactory.CreateShaderModule; | |||
WriteLn(' vertex handle: ', PtrUInt(fVertexShader.Handle)); | |||
ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag', [ VK_SHADER_STAGE_FRAGMENT_BIT ]); | |||
ShaderModuleFactory.LoadSpvCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag.spv'); | |||
fFragmentShader := ShaderModuleFactory.CreateShaderModule; | |||
WriteLn(' fragment handle: ', PtrUInt(fFragmentShader.Handle)); | |||
WriteLn(' done'); | |||
@@ -600,11 +772,209 @@ begin | |||
PipelineFactory := TvkuGraphicsPipelineFactory.Create(fDevice); | |||
try | |||
PipelineFactory.AllocHandler := fAllocHandler; | |||
// TODO fPipeline := PipelineFactory.CreateGraphicsPipeline(VK_INVALID_NDP_HANDLE); | |||
PipelineFactory.Stages.Length := 2; | |||
with PipelineFactory.Stages[0] do begin | |||
Stage := [ VK_SHADER_STAGE_VERTEX_BIT ]; | |||
Module := fVertexShader.Handle; | |||
Name := 'main'; | |||
end; | |||
with PipelineFactory.Stages[1] do begin | |||
Stage := [ VK_SHADER_STAGE_FRAGMENT_BIT ]; | |||
Module := fFragmentShader.Handle; | |||
Name := 'main'; | |||
end; | |||
with PipelineFactory.VertexInputState do begin | |||
VertexBindingDescriptions.Length := 1; | |||
VertexBindingDescriptions[0].Binding := VERTEX_BUFFER_BIND_ID; | |||
VertexBindingDescriptions[0].Stride := SizeOf(TVertex); | |||
VertexBindingDescriptions[0].InputRate := VK_VERTEX_INPUT_RATE_VERTEX; | |||
VertexAttributeDescriptions.Length := 2; | |||
// Location 0: Position | |||
VertexAttributeDescriptions[0].Binding := VERTEX_BUFFER_BIND_ID; | |||
VertexAttributeDescriptions[0].Location := 0; | |||
VertexAttributeDescriptions[0].Format := VK_FORMAT_R32G32B32_SFLOAT; | |||
VertexAttributeDescriptions[0].Offset := 0; | |||
VertexAttributeDescriptions[0].Binding := 0; | |||
// Location 1: Color | |||
VertexAttributeDescriptions[1].Binding := VERTEX_BUFFER_BIND_ID; | |||
VertexAttributeDescriptions[1].Location := 1; | |||
VertexAttributeDescriptions[1].Format := VK_FORMAT_R32G32B32_SFLOAT; | |||
VertexAttributeDescriptions[1].Offset := 3 * SizeOf(VkFloat); | |||
VertexAttributeDescriptions[1].Binding := 0; | |||
end; | |||
with PipelineFactory.InputAssemblyState do begin | |||
Topology := VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; | |||
end; | |||
with PipelineFactory.RasterizationState do begin | |||
PolygonMode := VK_POLYGON_MODE_FILL; | |||
CullMode := VK_CULL_MODE_NONE; | |||
FrontFace := VK_FRONT_FACE_COUNTER_CLOCKWISE; | |||
DepthClampEnable := false; | |||
RasterizerDiscardEnable := false; | |||
DepthBiasEnable := false; | |||
end; | |||
with PipelineFactory.ColorBlendState do begin | |||
Attachments.Length := 1; | |||
Attachments[0].ColorWriteMask := [ | |||
VK_COLOR_COMPONENT_R_BIT, | |||
VK_COLOR_COMPONENT_G_BIT, | |||
VK_COLOR_COMPONENT_B_BIT, | |||
VK_COLOR_COMPONENT_A_BIT]; | |||
Attachments[0].BlendEnable := false; | |||
end; | |||
with PipelineFactory.ViewportState do begin | |||
Viewports.Length := 1; | |||
Scissors.Length := 1; | |||
end; | |||
with PipelineFactory.DynamicState do begin | |||
DynamicStates.Length := 2; | |||
DynamicStates[0] := VK_DYNAMIC_STATE_VIEWPORT; | |||
DynamicStates[1] := VK_DYNAMIC_STATE_SCISSOR; | |||
end; | |||
with PipelineFactory.DepthStencilState do begin | |||
DepthTestEnable := true; | |||
DepthWriteEnable := true; | |||
DepthCompareOp := VK_COMPARE_OP_LESS_OR_EQUAL; | |||
DepthBoundsTestEnable := false; | |||
StencilTestEnable := false; | |||
Back.failOp := VK_STENCIL_OP_KEEP; | |||
Back.passOp := VK_STENCIL_OP_KEEP; | |||
Back.compareOp := VK_COMPARE_OP_ALWAYS; | |||
Front := Back; | |||
end; | |||
with PipelineFactory.MultiSampleState do begin | |||
RasterizationSamples := [ VK_SAMPLE_COUNT_1_BIT ]; | |||
end; | |||
PipelineFactory.Layout := fPipelineLayout.Handle; | |||
PipelineFactory.RenderPass := fRenderPass.Handle; | |||
PipelineFactory.SubPass := 0; | |||
fPipeline := PipelineFactory.CreateGraphicsPipeline(VK_INVALID_NDP_HANDLE); | |||
WriteLn(' handle: ', PtrUInt(fPipeline.Handle)); | |||
WriteLn(' done'); | |||
finally | |||
FreeAndNil(PipelineFactory); | |||
end; | |||
////////////////////////////////////////////////////////////////////////////// | |||
WriteLn('create descriptor pool'); | |||
DescriptorPoolFactory := TvkuDescriptorPoolFactory.Create(fDevice.DeviceCommands); | |||
try | |||
DescriptorPoolFactory.MaxSets := 1; | |||
DescriptorPoolFactory.PoolSizes.Length := 1; | |||
DescriptorPoolFactory.PoolSizes[0].DescriptorType := VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; | |||
DescriptorPoolFactory.PoolSizes[0].DescriptorCount := 1; | |||
fDescriptorPool := DescriptorPoolFactory.CreateDescriptorPool; | |||
WriteLn(' handle: ', PtrUInt(fDescriptorPool.Handle)); | |||
WriteLn(' done'); | |||
finally | |||
FreeAndNil(DescriptorPoolFactory); | |||
end; | |||
////////////////////////////////////////////////////////////////////////////// | |||
WriteLn('setup/update descriptor sets'); | |||
fDescriptorSet := TvkuDescriptorSet.Create( | |||
fDescriptorPool.AllocateDescriptorSet(fDescSetLayout.Handle), | |||
true, | |||
fDescriptorPool.Handle, | |||
fDevice.DeviceCommands); | |||
WriteLn(' handle: ', PtrUInt(fDescriptorSet.Handle)); | |||
WriteLn(' update descriptor set'); | |||
with fDevice.UpdateDescriptorSet do | |||
try | |||
WriteDescriptorSets.Length := 1; | |||
WriteDescriptorSets[0].DstSet := fDescriptorSet.Handle; | |||
WriteDescriptorSets[0].DstBinding := 0; | |||
WriteDescriptorSets[0].DescriptorType := VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; | |||
WriteDescriptorSets[0].BufferInfos.Length := 1; | |||
WriteDescriptorSets[0].BufferInfos[0].Buffer := fUniform.Buffer.Handle; | |||
WriteDescriptorSets[0].BufferInfos[0].Offset := 0; | |||
WriteDescriptorSets[0].BufferInfos[0].Range := SizeOf(fUniform.Values); | |||
Execute; | |||
finally | |||
Free; | |||
end; | |||
WriteLn(' done'); | |||
////////////////////////////////////////////////////////////////////////////// | |||
WriteLn('build command buffers'); | |||
for i := low(fDrawCommandBuffers) to high(fDrawCommandBuffers) do begin | |||
WriteLn(' command buffer: ', PtrUInt(fDrawCommandBuffers[i].Handle)); | |||
with fDrawCommandBuffers[i] do begin | |||
BeginCommand; | |||
with BeginRenderPass do | |||
try | |||
RenderPassBeginInfo.RenderPass := fRenderPass.Handle; | |||
RenderPassBeginInfo.Framebuffer := fFrameBuffers[i].Handle; | |||
RenderPassBeginInfo.RenderArea.offset.x := 0; | |||
RenderPassBeginInfo.RenderArea.offset.y := 0; | |||
RenderPassBeginInfo.RenderArea.extent.width := ClientWidth; | |||
RenderPassBeginInfo.RenderArea.extent.height := ClientHeight; | |||
RenderPassBeginInfo.ClearValues.Length := 2; | |||
RenderPassBeginInfo.ClearValues[0] := ClearColor; | |||
RenderPassBeginInfo.ClearValues[1] := ClearDepthStencil; | |||
Execute(VK_SUBPASS_CONTENTS_INLINE); | |||
finally | |||
Free; | |||
end; | |||
FillByte(vp, SizeOf(vp), 0); | |||
vp.height := ClientHeight; | |||
vp.width := ClientWidth; | |||
vp.minDepth := 0.0; | |||
vp.maxDepth := 1.0; | |||
SetViewport(0, [ vp ]); | |||
FillByte(r2D, SizeOf(r2D), 0); | |||
r2D.extent.width := ClientWidth; | |||
r2D.extent.height := ClientHeight; | |||
r2D.offset.x := 0; | |||
r2D.offset.y := 0; | |||
SetScissors(1, [ r2D ]); | |||
BindDescriptorSet( | |||
VK_PIPELINE_BIND_POINT_GRAPHICS, | |||
fPipelineLayout.Handle, | |||
0, | |||
[ fDescriptorSet.Handle ], | |||
[ ]); | |||
BindVertexBuffers( | |||
VERTEX_BUFFER_BIND_ID, | |||
[ fVertex.DataBuffer.Handle ], | |||
[ 0 ]); | |||
BindIndexBuffers( | |||
fVertex.IndexBuffer.Handle, | |||
0, | |||
VK_INDEX_TYPE_UINT32); | |||
DrawIndexed( | |||
3, 1, 0, 0, 1); | |||
FillByte(ImageMemoryBarrier, SizeOf(ImageMemoryBarrier), 0); | |||
with ImageMemoryBarrier do begin | |||
sType := VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; | |||
pNext := nil; | |||
srcAccessMask := [ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ]; | |||
dstAccessMask := [ ]; | |||
oldLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | |||
newLayout := VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; | |||
srcQueueFamilyIndex := VK_QUEUE_FAMILY_IGNORED; | |||
dstQueueFamilyIndex := VK_QUEUE_FAMILY_IGNORED; | |||
subresourceRange.aspectMask := [ VK_IMAGE_ASPECT_COLOR_BIT ]; | |||
subresourceRange.baseMipLevel := 0; | |||
subresourceRange.levelCount := 1; | |||
subresourceRange.baseArrayLayer := 0; | |||
subresourceRange.layerCount := 1; | |||
end; | |||
PipelineBarrier( | |||
[ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT ], | |||
[ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ], | |||
[], | |||
[], | |||
[], | |||
[ ImageMemoryBarrier ]); | |||
EndCommand; | |||
end; | |||
end; | |||
WriteLn(' done'); | |||
finally | |||
FreeAndNil(SetupCommandBuffer); | |||
end; | |||
@@ -646,11 +1016,19 @@ procedure TMainForm.FormDestroy(Sender: TObject); | |||
end; | |||
begin | |||
FreeAndNil(fDescriptorSet); | |||
FreeAndNil(fDescriptorPool); | |||
FreeAndNil(fPipeline); | |||
FreeAndNil(fFragmentShader); | |||
FreeAndNil(fVertexShader); | |||
FreeAndNil(fPipelineLayout); | |||
FreeAndNil(fDescSetLayout); | |||
FreeAndNil(fUniform.Buffer); | |||
FreeAndNil(fUniform.Memory); | |||
FreeAndNil(fVertex.DataBuffer); | |||
FreeAndNil(fVertex.DataMemory); | |||
FreeAndNil(fVertex.IndexBuffer); | |||
FreeAndNil(fVertex.IndexMemory); | |||
FreeAndNilFrameBuffers; | |||
FreeAndNil(fPipelineCache); | |||
FreeAndNil(fRenderPass); | |||
@@ -669,6 +1047,26 @@ begin | |||
FreeAndNil(fDebugReporter); | |||
FreeAndNil(fInstance); | |||
FreeAndNil(fAllocHandler); | |||
FreeAndNil(fCamera); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TMainForm.UpdateUniformBuffers; | |||
var p: PVkVoid; | |||
begin | |||
fCamera.Perspective(45, ClientWidth/ClientHeight, 0.001, 1000); | |||
fCamera.Position := gluMatrixIdentity * gluMatrixTranslate(gluVector3f(0, 0, -5)); | |||
fUniform.Values.ProjectionMat := fCamera.ProjMatrix; | |||
fUniform.Values.ModelMatrix := fCamera.Position; | |||
fUniform.Values.ViewMatrix := gluMatrixIdentity; | |||
p := fUniform.Memory.Map(0, SizeOf(fUniform.Values), 0); | |||
try | |||
move(fUniform.Values, p^, SizeOf(fUniform.Values)); | |||
finally | |||
fUniform.Memory.Unmap; | |||
end; | |||
end; | |||
end. | |||
@@ -20,6 +20,7 @@ uses | |||
uvkuDescriptorSetLayout, uvkuDescriptorSetLayoutFactory, | |||
uvkuShaderModule, uvkuShaderModuleFactory, | |||
uvkuPipelineLayout, uvkuPipelineLayoutFactory, uvkuPipelineCache, uvkuPipelineCacheFactory, uvkuPipeline, uvkuPipelineFactory, | |||
uvkuDescriptorPool, uvkuDescriptorPoolFactory, uvkuDescriptorSet, | |||
uvkuUtils; | |||
type | |||
@@ -123,6 +124,11 @@ type | |||
TvkuComputePipeline = uvkuPipeline.TvkuComputePipeline; | |||
TvkuComputePipelineFactory = uvkuPipelineFactory.TvkuComputePipelineFactory; | |||
{ DescriptorPool } | |||
TvkuDescriptorPool = uvkuDescriptorPool.TvkuDescriptorPool; | |||
TvkuDescriptorPoolFactory = uvkuDescriptorPoolFactory.TvkuDescriptorPoolFactory; | |||
TvkuDescriptorSet = uvkuDescriptorSet.TvkuDescriptorSet; | |||
{ Utils } | |||
TvkuException = uvkuUtils.TvkuException; | |||
TvkuErrorException = uvkuUtils.TvkuErrorException; | |||
@@ -6,7 +6,7 @@ interface | |||
uses | |||
Classes, SysUtils, | |||
Vulkan, uvkuBase; | |||
Vulkan, uvkuBase, uvkuDeviceMemory; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -14,11 +14,23 @@ type | |||
private | |||
fHandle: VkBuffer; | |||
fDeviceCommands: TVkDeviceCommands; | |||
fMemory: VkDeviceMemory; | |||
fBufferMemory: TvkuDeviceMemory; | |||
procedure CreateHandle(const aCreateInfo: TVkBufferCreateInfo); | |||
public | |||
property Handle: VkBuffer read fHandle; | |||
property DeviceCommands: TVkDeviceCommands read fDeviceCommands; | |||
property Memory: VkDeviceMemory read fMemory; | |||
procedure BindMemory( | |||
const aMemory: VkDeviceMemory; | |||
const aOffset: VkDeviceSize); | |||
function GetMemoryRequirements: TVkMemoryRequirements; | |||
procedure AllocateAndBindBufferMemory( | |||
const aMemoryProperties: TVkPhysicalDeviceMemoryProperties; | |||
aAllocCallbacks: PVkAllocationCallbacks = nil); | |||
constructor Create( | |||
const aCreateInfo: TVkBufferCreateInfo; | |||
@@ -48,6 +60,54 @@ begin | |||
raise TvkuErrorException.Create('unable to create buffer', err); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuBuffer.BindMemory(const aMemory: VkDeviceMemory; const aOffset: VkDeviceSize); | |||
var err: TVkResult; | |||
begin | |||
err := fDeviceCommands.vkBindBufferMemory(fDeviceCommands.Device, fHandle, aMemory, aOffset); | |||
if (err < VK_SUCCESS) then | |||
raise TvkuErrorException.Create('unable to bind buffer memory', err); | |||
fMemory := aMemory; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuBuffer.GetMemoryRequirements: TVkMemoryRequirements; | |||
begin | |||
fDeviceCommands.vkGetBufferMemoryRequirements(fDeviceCommands.Device, fHandle, @result); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuBuffer.AllocateAndBindBufferMemory( | |||
const aMemoryProperties: TVkPhysicalDeviceMemoryProperties; | |||
aAllocCallbacks: PVkAllocationCallbacks); | |||
var | |||
i: Integer; | |||
bits: VkUint32; | |||
MemReq: TVkMemoryRequirements; | |||
Mem: VkDeviceMemory; | |||
MemAllocInfo: TVkMemoryAllocateInfo; | |||
err: TVkResult; | |||
begin | |||
MemReq := GetMemoryRequirements; | |||
FillByte(MemAllocInfo, SizeOf(MemAllocInfo), 0); | |||
MemAllocInfo.sType := VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; | |||
MemAllocInfo.pNext := nil; | |||
MemAllocInfo.allocationSize := MemReq.size; | |||
MemAllocInfo.memoryTypeIndex := vkuGetMemoryTypeIndex( | |||
aMemoryProperties, | |||
MemReq.memoryTypeBits, | |||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); | |||
if not Assigned(aAllocCallbacks) then | |||
aAllocCallbacks := AllocCallbacks; | |||
err := fDeviceCommands.vkAllocateMemory(fDeviceCommands.Device, @MemAllocInfo, aAllocCallbacks, @Mem); | |||
if (err < VK_SUCCESS) then | |||
raise TvkuErrorException.Create('unable to allocate buffer memory', err); | |||
fBufferMemory := TvkuDeviceMemory.Create(Mem, true, fDeviceCommands, aAllocCallbacks); | |||
BindMemory(fBufferMemory.Handle, 0); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuBuffer.Create(const aCreateInfo: TVkBufferCreateInfo; const aDeviceCommands: TVkDeviceCommands; | |||
const aAllocCallbacks: PVkAllocationCallbacks); | |||
@@ -75,6 +135,7 @@ begin | |||
if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then | |||
fDeviceCommands.vkDestroyBuffer(fDeviceCommands.Device, fHandle, AllocCallbacks); | |||
fHandle := VK_INVALID_NDP_HANDLE; | |||
FreeAndNil(fBufferMemory); | |||
inherited Destroy; | |||
end; | |||
@@ -9,6 +9,39 @@ uses | |||
Vulkan, uvkuBase, uvkuTypes; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuRenderPassBeginInfo = class(TvkuStructure) | |||
private | |||
fClearValues: TVkClearValueList; | |||
public | |||
RenderPass: VkRenderPass; | |||
Framebuffer: VkFramebuffer; | |||
RenderArea: TVkRect2D; | |||
property ClearValues: TVkClearValueList read fClearValues; | |||
function GetStructure: TVkRenderPassBeginInfo; | |||
procedure SetStructure(const aData: TVkRenderPassBeginInfo); | |||
constructor Create; | |||
destructor Destroy; override; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuBeginRenderPassHelper = class(TvkuCommandHelper) | |||
private | |||
fRenderPassBeginInfo: TvkuRenderPassBeginInfo; | |||
fDeviceCommands: TVkDeviceCommands; | |||
fCommandBuffer: VkCommandBuffer; | |||
public | |||
property RenderPassBeginInfo: TvkuRenderPassBeginInfo read fRenderPassBeginInfo; | |||
procedure Execute(const aContents: TVkSubpassContents); | |||
constructor Create(const aCommandBuffer: VkCommandBuffer; const aDeviceCommands: TVkDeviceCommands); | |||
destructor Destroy; override; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuCommandBuffer = class(TvkuHandle) | |||
private | |||
@@ -30,6 +63,38 @@ type | |||
const aBufferMemoryBarriers: array of TVkBufferMemoryBarrier; | |||
const aImageMemoryBarriers: array of TVkImageMemoryBarrier); | |||
function BeginRenderPass: TvkuBeginRenderPassHelper; | |||
procedure EndRenderPass; | |||
procedure SetViewport( | |||
const aFirstViewport: VkUint32; | |||
const aViewports: array of TVkViewport); | |||
procedure SetScissors( | |||
const aFirstScissor: VkUint32; | |||
const aScissorss: array of TVkRect2D); | |||
procedure BindDescriptorSet( | |||
const aBindPoint: TVkPipelineBindPoint; | |||
const aLayout: VkPipelineLayout; | |||
const aFirstSet: VkUint32; | |||
const aDescriptorSets: array of VkDescriptorSet; | |||
const aDynamicOffsets: array of VkUint32); | |||
procedure BindPipeline( | |||
const aBindPoint: TVkPipelineBindPoint; | |||
const aPipeline: VkPipeline); | |||
procedure BindVertexBuffers( | |||
const aFirstBinding: VkUint32; | |||
const aBuffers: array of VkBuffer; | |||
const aOffsets: array of VkDeviceSize); | |||
procedure BindIndexBuffers( | |||
const aBuffer: VkBuffer; | |||
const aOffset: VkDeviceSize; | |||
const aIndexType: TVkIndexType); | |||
procedure DrawIndexed( | |||
const aIndexCount: VkUint32; | |||
const aInstanceCount: VkUint32; | |||
const aFirstIndex: VkUint32; | |||
const aVertexOffset: VkInt32; | |||
const aFirstInstance: VkUint32); | |||
constructor Create( | |||
const aHandle: VkCommandBuffer; | |||
const aOwnsHandle: Boolean; | |||
@@ -43,6 +108,70 @@ implementation | |||
uses | |||
uvkuUtils; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuRenderPassBeginInfo//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuRenderPassBeginInfo.GetStructure: TVkRenderPassBeginInfo; | |||
begin | |||
FillByte(result, SizeOf(result), 0); | |||
result.sType := VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; | |||
result.pNext := nil; | |||
result.renderPass := RenderPass; | |||
result.framebuffer := Framebuffer; | |||
result.renderArea := RenderArea; | |||
result.clearValueCount := fClearValues.Length; | |||
result.pClearValues := fClearValues.PData; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuRenderPassBeginInfo.SetStructure(const aData: TVkRenderPassBeginInfo); | |||
begin | |||
RenderPass := aData.renderPass; | |||
Framebuffer := aData.framebuffer; | |||
RenderArea := aData.renderArea; | |||
ClearValues.SetData(aData.pClearValues, aData.clearValueCount); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuRenderPassBeginInfo.Create; | |||
begin | |||
inherited Create; | |||
fClearValues := TVkClearValueList.Create; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
destructor TvkuRenderPassBeginInfo.Destroy; | |||
begin | |||
FreeAndNil(fClearValues); | |||
inherited Destroy; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuBeginRenderPassHelper////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuBeginRenderPassHelper.Execute(const aContents: TVkSubpassContents); | |||
var info: TVkRenderPassBeginInfo; | |||
begin | |||
info := fRenderPassBeginInfo.GetStructure; | |||
fDeviceCommands.vkCmdBeginRenderPass(fCommandBuffer, @info, aContents); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuBeginRenderPassHelper.Create(const aCommandBuffer: VkCommandBuffer; const aDeviceCommands: TVkDeviceCommands); | |||
begin | |||
inherited Create; | |||
fCommandBuffer := aCommandBuffer; | |||
fDeviceCommands := aDeviceCommands; | |||
fRenderPassBeginInfo := TvkuRenderPassBeginInfo.Create; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
destructor TvkuBeginRenderPassHelper.Destroy; | |||
begin | |||
FreeAndNil(fRenderPassBeginInfo); | |||
inherited Destroy; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuCommandBuffer////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -86,6 +215,110 @@ begin | |||
Length(aImageMemoryBarriers), @aImageMemoryBarriers[0]); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuCommandBuffer.BeginRenderPass: TvkuBeginRenderPassHelper; | |||
begin | |||
result := TvkuBeginRenderPassHelper.Create(fHandle, fDeviceCommands); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCommandBuffer.EndRenderPass; | |||
begin | |||
fDeviceCommands.vkCmdEndRenderPass(fHandle); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCommandBuffer.SetViewport(const aFirstViewport: VkUint32; const aViewports: array of TVkViewport); | |||
begin | |||
fDeviceCommands.vkCmdSetViewport( | |||
fHandle, | |||
aFirstViewport, | |||
Length(aViewports), | |||
@aViewports[0]); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCommandBuffer.SetScissors(const aFirstScissor: VkUint32; const aScissorss: array of TVkRect2D); | |||
begin | |||
fDeviceCommands.vkCmdSetScissor( | |||
fHandle, | |||
aFirstScissor, | |||
Length(aScissorss), | |||
@aScissorss[0]); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCommandBuffer.BindDescriptorSet(const aBindPoint: TVkPipelineBindPoint; const aLayout: VkPipelineLayout; | |||
const aFirstSet: VkUint32; const aDescriptorSets: array of VkDescriptorSet; const aDynamicOffsets: array of VkUint32); | |||
var | |||
DescSetCount, DynOffsetCount: Integer; | |||
DescSets: PVkDescriptorSet; | |||
DynOffsets: PVkUint32; | |||
begin | |||
DescSetCount := Length(aDescriptorSets); | |||
DynOffsetCount := Length(aDynamicOffsets); | |||
if (DescSetCount > 0) | |||
then DescSets := @aDescriptorSets[0] | |||
else DescSets := nil; | |||
if (DynOffsetCount > 0) | |||
then DynOffsets := @aDynamicOffsets[0] | |||
else DynOffsets := nil; | |||
fDeviceCommands.vkCmdBindDescriptorSets( | |||
fHandle, | |||
aBindPoint, | |||
aLayout, | |||
aFirstSet, | |||
DescSetCount, | |||
DescSets, | |||
DynOffsetCount, | |||
DynOffsets); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCommandBuffer.BindPipeline(const aBindPoint: TVkPipelineBindPoint; const aPipeline: VkPipeline); | |||
begin | |||
fDeviceCommands.vkCmdBindPipeline(fHandle, aBindPoint, aPipeline); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCommandBuffer.BindVertexBuffers(const aFirstBinding: VkUint32; const aBuffers: array of VkBuffer; | |||
const aOffsets: array of VkDeviceSize); | |||
begin | |||
if (Length(aBuffers) <> Length(aOffsets)) then | |||
raise TvkuException.Create('aBuffers and aOffsets must have the same number of elements'); | |||
fDeviceCommands.vkCmdBindVertexBuffers( | |||
fHandle, | |||
aFirstBinding, | |||
Length(aBuffers), | |||
@aBuffers[0], | |||
@aOffsets[0]); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCommandBuffer.BindIndexBuffers(const aBuffer: VkBuffer; const aOffset: VkDeviceSize; | |||
const aIndexType: TVkIndexType); | |||
begin | |||
fDeviceCommands.vkCmdBindIndexBuffer( | |||
fHandle, | |||
aBuffer, | |||
aOffset, | |||
aIndexType); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCommandBuffer.DrawIndexed(const aIndexCount: VkUint32; const aInstanceCount: VkUint32; | |||
const aFirstIndex: VkUint32; const aVertexOffset: VkInt32; const aFirstInstance: VkUint32); | |||
begin | |||
fDeviceCommands.vkCmdDrawIndexed( | |||
fHandle, | |||
aIndexCount, | |||
aInstanceCount, | |||
aFirstIndex, | |||
aVertexOffset, | |||
aFirstInstance); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuCommandBuffer.Create(const aHandle: VkCommandBuffer; const aOwnsHandle: Boolean; | |||
const aCommandPool: VkCommandPool; const aDeviceCommands: TVkDeviceCommands); | |||
@@ -20,9 +20,9 @@ type | |||
property Handle: VkCommandPool read fHandle; | |||
property DeviceCommands: TVkDeviceCommands read fDeviceCommands; | |||
function CreateCommandBuffer( | |||
function AllocateCommandBuffer( | |||
const aLevel: TVkCommandBufferLevel): VkCommandBuffer; | |||
function CreateCommandBuffers( | |||
function AllocateCommandBuffers( | |||
const aLevel: TVkCommandBufferLevel; | |||
const aCount: Integer): TVkCommandBufferArr; | |||
procedure FreeCommandBuffer( | |||
@@ -59,13 +59,13 @@ begin | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuCommandPool.CreateCommandBuffer(const aLevel: TVkCommandBufferLevel): VkCommandBuffer; | |||
function TvkuCommandPool.AllocateCommandBuffer(const aLevel: TVkCommandBufferLevel): VkCommandBuffer; | |||
begin | |||
result := CreateCommandBuffers(aLevel, 1)[0]; | |||
result := AllocateCommandBuffers(aLevel, 1)[0]; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuCommandPool.CreateCommandBuffers(const aLevel: TVkCommandBufferLevel; const aCount: Integer): TVkCommandBufferArr; | |||
function TvkuCommandPool.AllocateCommandBuffers(const aLevel: TVkCommandBufferLevel; const aCount: Integer): TVkCommandBufferArr; | |||
var | |||
AllocInfo: TVkCommandBufferAllocateInfo; | |||
err: TVkResult; | |||
@@ -0,0 +1,136 @@ | |||
unit uvkuDescriptorPool; | |||
{$mode objfpc}{$H+} | |||
interface | |||
uses | |||
Classes, SysUtils, | |||
Vulkan, uvkuBase, uvkuTypes; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuDescriptorPool = class(TvkuAllocHandle) | |||
private | |||
fHandle: VkDescriptorPool; | |||
fDeviceCommands: TVkDeviceCommands; | |||
procedure CreateHandle(const aCreateInfo: TVkDescriptorPoolCreateInfo); | |||
public | |||
property Handle: VkDescriptorPool read fHandle; | |||
property DeviceCommands: TVkDeviceCommands read fDeviceCommands; | |||
function AllocateDescriptorSet( | |||
const aDescriptorSetLayout: VkDescriptorSetLayout): VkDescriptorSet; | |||
function AllocateDescriptorSets( | |||
const aDescriptorSetLayouts: array of VkDescriptorSetLayout): TVkDescriptorSetArr; | |||
procedure FreeDescriptorSet( | |||
const aDescriptorSet: VkDescriptorSet); | |||
procedure FreeDescriptorSets( | |||
const aDescriptorSets: TVkDescriptorSetArr); | |||
constructor Create( | |||
const aCreateInfo: TVkDescriptorPoolCreateInfo; | |||
const aDeviceCommands: TVkDeviceCommands; | |||
const aAllocCallbacks: PVkAllocationCallbacks = nil); | |||
constructor Create( | |||
const aHandle: VkDescriptorPool; | |||
const aOwnsHandle: Boolean; | |||
const aDeviceCommands: TVkDeviceCommands; | |||
const aAllocCallbacks: PVkAllocationCallbacks = nil); | |||
destructor Destroy; override; | |||
end; | |||
implementation | |||
uses | |||
uvkuUtils; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuDescriptorPool///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorPool.CreateHandle(const aCreateInfo: TVkDescriptorPoolCreateInfo); | |||
var err: TVkResult; | |||
begin | |||
if not Assigned(fDeviceCommands.vkCreateDescriptorPool) then | |||
raise TvkuInvalidFuncPtrException.Create('vkCreateDescriptorPool'); | |||
err := fDeviceCommands.vkCreateDescriptorPool(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle); | |||
if (err < VK_SUCCESS) then | |||
raise TvkuErrorException.Create('unable to create descriptor pool', err); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuDescriptorPool.AllocateDescriptorSet(const aDescriptorSetLayout: VkDescriptorSetLayout): VkDescriptorSet; | |||
begin | |||
result := AllocateDescriptorSets([ aDescriptorSetLayout ])[0]; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuDescriptorPool.AllocateDescriptorSets(const aDescriptorSetLayouts: array of VkDescriptorSetLayout): TVkDescriptorSetArr; | |||
var | |||
AllocInfo: TVkDescriptorSetAllocateInfo; | |||
err: TVkResult; | |||
begin | |||
if not Assigned(fDeviceCommands.vkAllocateDescriptorSets) then | |||
raise TvkuInvalidFuncPtrException.Create('vkAllocateDescriptorSets'); | |||
FillByte(AllocInfo, SizeOf(AllocInfo), 0); | |||
AllocInfo.sType := VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | |||
AllocInfo.pNext := nil; | |||
AllocInfo.descriptorPool := fHandle; | |||
AllocInfo.descriptorSetCount := Length(aDescriptorSetLayouts); | |||
AllocInfo.pSetLayouts := @aDescriptorSetLayouts[0]; | |||
SetLength(result, AllocInfo.descriptorSetCount); | |||
err := fDeviceCommands.vkAllocateDescriptorSets(fDeviceCommands.Device, @AllocInfo, @result[0]); | |||
if (err < VK_SUCCESS) then | |||
raise TvkuErrorException.Create('unable to allocate descriptor sets', err); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorPool.FreeDescriptorSet(const aDescriptorSet: VkDescriptorSet); | |||
begin | |||
FreeDescriptorSets(TVkDescriptorSetArr.Create(aDescriptorSet)); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorPool.FreeDescriptorSets(const aDescriptorSets: TVkDescriptorSetArr); | |||
var err: TVkResult; | |||
begin | |||
if not Assigned(fDeviceCommands.vkFreeDescriptorSets) then | |||
raise TvkuInvalidFuncPtrException.Create('vkFreeDescriptorSets'); | |||
err := fDeviceCommands.vkFreeDescriptorSets(fDeviceCommands.Device, fHandle, Length(aDescriptorSets), @aDescriptorSets[0]); | |||
if (err < VK_SUCCESS) then | |||
raise TvkuErrorException.Create('unable to free descriptor sets', err); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuDescriptorPool.Create(const aCreateInfo: TVkDescriptorPoolCreateInfo; | |||
const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks); | |||
begin | |||
inherited Create; | |||
fDeviceCommands := aDeviceCommands; | |||
SetAllocCallbacks(aAllocCallbacks); | |||
CreateHandle(aCreateInfo); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuDescriptorPool.Create(const aHandle: VkDescriptorPool; const aOwnsHandle: Boolean; | |||
const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks); | |||
begin | |||
inherited Create; | |||
fHandle := aHandle; | |||
fDeviceCommands := aDeviceCommands; | |||
OwnsHandle := aOwnsHandle; | |||
SetAllocCallbacks(aAllocCallbacks); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
destructor TvkuDescriptorPool.Destroy; | |||
begin | |||
if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then | |||
fDeviceCommands.vkDestroyDescriptorPool(fDeviceCommands.Device, fHandle, AllocCallbacks); | |||
fHandle := VK_INVALID_NDP_HANDLE; | |||
inherited Destroy; | |||
end; | |||
end. | |||
@@ -0,0 +1,115 @@ | |||
unit uvkuDescriptorPoolFactory; | |||
{$mode objfpc}{$H+} | |||
interface | |||
uses | |||
Classes, SysUtils, | |||
Vulkan, uvkuFactoryBase, uvkuDescriptorPool, uvkuTypes; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuDescriptorPoolSize = class(TvkuStructure) | |||
DescriptorType: TVkDescriptorType; | |||
DescriptorCount: VkUint32; | |||
function GetStructure: TVkDescriptorPoolSize; | |||
procedure SetStructure(const aData: TVkDescriptorPoolSize); | |||
end; | |||
TvkuDescriptorPoolSizeList = specialize TvkuObjList<TvkuDescriptorPoolSize>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuDescriptorPoolFactory = class(TvkuDeviceObjFactory) | |||
private | |||
fPoolSizes: TvkuDescriptorPoolSizeList; | |||
fvkPoolSizes: TVkDescriptorPoolSizeArr; | |||
public | |||
Flags: VkDescriptorPoolCreateFlags; | |||
MaxSets: VkUint32; | |||
property PoolSizes: TvkuDescriptorPoolSizeList read fPoolSizes; | |||
function GetStructure: TVkDescriptorPoolCreateInfo; | |||
procedure SetStructure(const aData: TVkDescriptorPoolCreateInfo); | |||
function CreateDescriptorPool: TvkuDescriptorPool; | |||
procedure AfterConstruction; override; | |||
procedure BeforeDestruction; override; | |||
end; | |||
implementation | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuDescriptorPoolSize///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuDescriptorPoolSize.GetStructure: TVkDescriptorPoolSize; | |||
begin | |||
FillByte(result, SizeOf(result), 0); | |||
result.dType := DescriptorType; | |||
result.descriptorCount := DescriptorCount; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorPoolSize.SetStructure(const aData: TVkDescriptorPoolSize); | |||
begin | |||
DescriptorType := aData.dType; | |||
DescriptorCount := aData.descriptorCount; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuDescriptorPoolFactory////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuDescriptorPoolFactory.GetStructure: TVkDescriptorPoolCreateInfo; | |||
var i: Integer; | |||
begin | |||
SetLength(fvkPoolSizes, fPoolSizes.Length); | |||
for i := low(fvkPoolSizes) to high(fvkPoolSizes) do | |||
fvkPoolSizes[i] := fPoolSizes[i].GetStructure; | |||
FillByte(result, SizeOf(result), 0); | |||
result.sType := VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; | |||
result.pNext := nil; | |||
result.flags := Flags; | |||
result.maxSets := MaxSets; | |||
result.poolSizeCount := Length(fvkPoolSizes); | |||
result.pPoolSizes := @fvkPoolSizes[0]; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorPoolFactory.SetStructure(const aData: TVkDescriptorPoolCreateInfo); | |||
var i: Integer; | |||
begin | |||
if Assigned(aData.pPoolSizes) then begin | |||
fPoolSizes.Length := aData.poolSizeCount; | |||
for i := 0 to fPoolSizes.Length-1 do | |||
fPoolSizes[i].SetStructure((aData.pPoolSizes + i)^); | |||
end; | |||
Flags := aData.flags; | |||
MaxSets := aData.maxSets; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuDescriptorPoolFactory.CreateDescriptorPool: TvkuDescriptorPool; | |||
begin | |||
result := TvkuDescriptorPool.Create(GetStructure, DeviceCommands, AllocCallbacks); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorPoolFactory.AfterConstruction; | |||
begin | |||
inherited AfterConstruction; | |||
fPoolSizes := TvkuDescriptorPoolSizeList.Create; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorPoolFactory.BeforeDestruction; | |||
begin | |||
FreeAndNil(fPoolSizes); | |||
inherited BeforeDestruction; | |||
end; | |||
end. | |||
@@ -0,0 +1,56 @@ | |||
unit uvkuDescriptorSet; | |||
{$mode objfpc}{$H+} | |||
interface | |||
uses | |||
Classes, SysUtils, | |||
Vulkan, uvkuBase; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuDescriptorSet = class(TvkuHandle) | |||
private | |||
fHandle: VkDescriptorSet; | |||
fDescriptorPool: VkDescriptorPool; | |||
fDeviceCommands: TVkDeviceCommands; | |||
public | |||
property Handle: VkDescriptorSet read fHandle; | |||
property DescriptorPool: VkDescriptorPool read fDescriptorPool; | |||
property DeviceCommands: TVkDeviceCommands read fDeviceCommands; | |||
constructor Create( | |||
const aHandle: VkDescriptorSet; | |||
const aOwnsHandle: Boolean; | |||
const aDescriptorPool: VkDescriptorPool; | |||
const aDeviceCommands: TVkDeviceCommands); | |||
destructor Destroy; override; | |||
end; | |||
implementation | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuDescriptorSet////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuDescriptorSet.Create(const aHandle: VkDescriptorSet; const aOwnsHandle: Boolean; | |||
const aDescriptorPool: VkDescriptorPool; const aDeviceCommands: TVkDeviceCommands); | |||
begin | |||
inherited Create; | |||
fHandle := aHandle; | |||
OwnsHandle := aOwnsHandle; | |||
fDescriptorPool := aDescriptorPool; | |||
fDeviceCommands := aDeviceCommands; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
destructor TvkuDescriptorSet.Destroy; | |||
begin | |||
if (fHandle <> VK_INVALID_NDP_HANDLE) and OwnsHandle then | |||
fDeviceCommands.vkFreeDescriptorSets(fDeviceCommands.Device, fDescriptorPool, 1, @fHandle); | |||
fHandle := VK_INVALID_NDP_HANDLE; | |||
inherited Destroy; | |||
end; | |||
end. | |||
@@ -6,9 +6,89 @@ interface | |||
uses | |||
Classes, SysUtils, | |||
Vulkan, uvkuBase; | |||
Vulkan, uvkuBase, uvkuTypes; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuDescriptorImageInfo = class(TvkuStructure) | |||
Sampler: VkSampler; | |||
ImageView: VkImageView; | |||
ImageLayout: TVkImageLayout; | |||
function GetStructure: TVkDescriptorImageInfo; | |||
procedure SetStructure(const aData: TVkDescriptorImageInfo); | |||
end; | |||
TvkuDescriptorImageInfoList = specialize TvkuObjList<TvkuDescriptorImageInfo>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuDescriptorBufferInfo = class(TvkuStructure) | |||
Buffer: VkBuffer; | |||
Offset: VkDeviceSize; | |||
Range: VkDeviceSize; | |||
function GetStructure: TVkDescriptorBufferInfo; | |||
procedure SetStructure(const aData: TVkDescriptorBufferInfo); | |||
end; | |||
TvkuDescriptorBufferInfoList = specialize TvkuObjList<TvkuDescriptorBufferInfo>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuWriteDescriptorSet = class(TvkuStructure) | |||
private | |||
fImageInfos: TvkuDescriptorImageInfoList; | |||
fBufferInfos: TvkuDescriptorBufferInfoList; | |||
fTexelBufferViews: TVkBufferViewList; | |||
fvkImageInfos: TVkDescriptorImageInfoArr; | |||
fvkBufferInfos: TVkDescriptorBufferInfoArr; | |||
public | |||
DstSet: VkDescriptorSet; | |||
DstBinding: VkUint32; | |||
DstArrayElement: VkUint32; | |||
DescriptorType: TVkDescriptorType; | |||
property ImageInfos: TvkuDescriptorImageInfoList read fImageInfos; | |||
property BufferInfos: TvkuDescriptorBufferInfoList read fBufferInfos; | |||
function GetStructure: TVkWriteDescriptorSet; | |||
procedure SetStructure(const aData: TVkWriteDescriptorSet); | |||
procedure AfterConstruction; override; | |||
procedure BeforeDestruction; override; | |||
end; | |||
TvkuWriteDescriptorSetList = specialize TvkuObjList<TvkuWriteDescriptorSet>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuCopyDescriptorSet = class(TvkuStructure) | |||
public | |||
SrcSet: VkDescriptorSet; | |||
SrcBinding: VkUint32; | |||
SrcArrayElement: VkUint32; | |||
DstSet: VkDescriptorSet; | |||
DstBinding: VkUint32; | |||
DstArrayElement: VkUint32; | |||
DescriptorCount: VkUint32; | |||
function GetStructure: TVkCopyDescriptorSet; | |||
procedure SetStructure(const aData: TVkCopyDescriptorSet); | |||
end; | |||
TvkuCopyDescriptorSetList = specialize TvkuObjList<TvkuCopyDescriptorSet>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuUpdateDescriptorSetHelper = class(TvkuCommandHelper) | |||
private | |||
fDeviceCommands: TVkDeviceCommands; | |||
fWriteDescriptorSets: TvkuWriteDescriptorSetList; | |||
fCopyDescriptorSets: TvkuCopyDescriptorSetList; | |||
public | |||
property WriteDescriptorSets: TvkuWriteDescriptorSetList read fWriteDescriptorSets; | |||
property CopyDescriptorSets: TvkuCopyDescriptorSetList read fCopyDescriptorSets; | |||
procedure Execute; | |||
constructor Create(const aDeviceCommands: TVkDeviceCommands); | |||
destructor Destroy; override; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuDevice = class(TvkuAllocHandle) | |||
private | |||
@@ -34,6 +114,8 @@ type | |||
const aMemory: VkDeviceMemory; | |||
aAllocCallbacks: PVkAllocationCallbacks = nil); | |||
function UpdateDescriptorSet: TvkuUpdateDescriptorSetHelper; | |||
constructor Create( | |||
const aPhysicalDevice: VkPhysicalDevice; | |||
const aCreateInfo: TVkDeviceCreateInfo; | |||
@@ -52,6 +134,196 @@ implementation | |||
uses | |||
uvkuUtils; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuDescriptorImageInfo//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuDescriptorImageInfo.GetStructure: TVkDescriptorImageInfo; | |||
begin | |||
FillByte(result, SizeOf(result), 0); | |||
result.sampler := Sampler; | |||
result.imageView := ImageView; | |||
result.imageLayout := ImageLayout; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorImageInfo.SetStructure(const aData: TVkDescriptorImageInfo); | |||
begin | |||
Sampler := aData.sampler; | |||
ImageView := aData.imageView; | |||
ImageLayout := aData.imageLayout; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuDescriptorBufferInfo/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuDescriptorBufferInfo.GetStructure: TVkDescriptorBufferInfo; | |||
begin | |||
FillByte(result, SizeOf(result), 0); | |||
result.buffer := Buffer; | |||
result.offset := Offset; | |||
result.range := Range; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuDescriptorBufferInfo.SetStructure(const aData: TVkDescriptorBufferInfo); | |||
begin | |||
Buffer := aData.buffer; | |||
Offset := aData.offset; | |||
Range := aData.range; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuWriteDescriptorSet///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuWriteDescriptorSet.GetStructure: TVkWriteDescriptorSet; | |||
var c, i: Integer; | |||
begin | |||
c := fImageInfos.Length; | |||
if (c < fBufferInfos.Length) then | |||
c := fBufferInfos.Length; | |||
if (c < fTexelBufferViews.Length) then | |||
c := fTexelBufferViews.Length; | |||
SetLength(fvkImageInfos, fImageInfos.Length); | |||
if (fImageInfos.Length <> 0) and (fImageInfos.Length <> c) then | |||
raise TvkuException.Create('ImageInfos, BufferInfos and TexelBufferViews must be empty or must have the same size!'); | |||
for i := low(fvkImageInfos) to high(fvkImageInfos) do | |||
fvkImageInfos[i] := fImageInfos[i].GetStructure; | |||
SetLength(fvkBufferInfos, fBufferInfos.Length); | |||
if (fBufferInfos.Length <> 0) and (fBufferInfos.Length <> c) then | |||
raise TvkuException.Create('ImageInfos, BufferInfos and TexelBufferViews must be empty or must have the same size!'); | |||
for i := low(fvkBufferInfos) to high(fvkBufferInfos) do | |||
fvkBufferInfos[i] := fBufferInfos[i].GetStructure; | |||
if (fTexelBufferViews.Length <> 0) and (fTexelBufferViews.Length <> c) then | |||
raise TvkuException.Create('ImageInfos, BufferInfos and TexelBufferViews must be empty or must have the same size!'); | |||
FillByte(result, SizeOf(result), 0); | |||
result.sType := VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; | |||
result.pNext := nil; | |||
result.dstSet := DstSet; | |||
result.dstBinding := DstBinding; | |||
result.dstArrayElement := DstArrayElement; | |||
result.descriptorCount := c; | |||
result.descriptorType := DescriptorType; | |||
result.pImageInfo := @fvkImageInfos[0]; | |||
result.pBufferInfo := @fvkBufferInfos[0]; | |||
result.pTexelBufferView := fTexelBufferViews.PData; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuWriteDescriptorSet.SetStructure(const aData: TVkWriteDescriptorSet); | |||
var i: Integer; | |||
begin | |||
if Assigned(aData.pImageInfo) then begin | |||
fImageInfos.Length := aData.descriptorCount; | |||
for i := 0 to fImageInfos.Length-1 do | |||
fImageInfos[i].SetStructure((aData.pImageInfo + i)^); | |||
end; | |||
if Assigned(aData.pBufferInfo) then begin | |||
fBufferInfos.Length := aData.descriptorCount; | |||
for i := 0 to fBufferInfos.Length-1 do | |||
fBufferInfos[i].SetStructure((aData.pBufferInfo + i)^); | |||
end; | |||
fTexelBufferViews.SetData(aData.pTexelBufferView, aData.descriptorCount); | |||
DstSet := aData.dstSet; | |||
DstBinding := aData.dstBinding; | |||
DstArrayElement := aData.dstArrayElement; | |||
DescriptorType := aData.descriptorType; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuWriteDescriptorSet.AfterConstruction; | |||
begin | |||
inherited AfterConstruction; | |||
fImageInfos := TvkuDescriptorImageInfoList.Create; | |||
fBufferInfos := TvkuDescriptorBufferInfoList.Create; | |||
fTexelBufferViews := TVkBufferViewList.Create; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuWriteDescriptorSet.BeforeDestruction; | |||
begin | |||
FreeAndNil(fImageInfos); | |||
FreeAndNil(fBufferInfos); | |||
FreeAndNil(fTexelBufferViews); | |||
inherited BeforeDestruction; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuCopyDescriptorSet////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuCopyDescriptorSet.GetStructure: TVkCopyDescriptorSet; | |||
begin | |||
result.sType := VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; | |||
result.pNext := nil; | |||
result.srcSet := SrcSet; | |||
result.srcBinding := SrcBinding; | |||
result.srcArrayElement := SrcArrayElement; | |||
result.dstSet := DstSet; | |||
result.dstBinding := DstBinding; | |||
result.dstArrayElement := DstArrayElement; | |||
result.descriptorCount := DescriptorCount; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuCopyDescriptorSet.SetStructure(const aData: TVkCopyDescriptorSet); | |||
begin | |||
SrcSet := aData.srcSet; | |||
SrcBinding := aData.srcBinding; | |||
SrcArrayElement := aData.srcArrayElement; | |||
DstSet := aData.dstSet; | |||
DstBinding := aData.dstBinding; | |||
DstArrayElement := aData.dstArrayElement; | |||
DescriptorCount := aData.descriptorCount; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuUpdateDescriptorSetHelper////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
procedure TvkuUpdateDescriptorSetHelper.Execute; | |||
var | |||
i: Integer; | |||
vkWriteDescriptorSets: array of TVkWriteDescriptorSet; | |||
vkCopyDescriptorSets: array of TVkCopyDescriptorSet; | |||
begin | |||
SetLength(vkWriteDescriptorSets, fWriteDescriptorSets.Length); | |||
for i := low(vkWriteDescriptorSets) to high(vkWriteDescriptorSets) do | |||
vkWriteDescriptorSets[i] := fWriteDescriptorSets[i].GetStructure; | |||
SetLength(vkCopyDescriptorSets, fCopyDescriptorSets.Length); | |||
for i := low(vkCopyDescriptorSets) to high(vkCopyDescriptorSets) do | |||
vkCopyDescriptorSets[i] := fCopyDescriptorSets[i].GetStructure; | |||
fDeviceCommands.vkUpdateDescriptorSets( | |||
fDeviceCommands.Device, | |||
Length(vkWriteDescriptorSets), | |||
@vkWriteDescriptorSets[0], | |||
Length(vkCopyDescriptorSets), | |||
@vkCopyDescriptorSets[0]); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuUpdateDescriptorSetHelper.Create(const aDeviceCommands: TVkDeviceCommands); | |||
begin | |||
inherited Create; | |||
fDeviceCommands := aDeviceCommands; | |||
fWriteDescriptorSets := TvkuWriteDescriptorSetList.Create; | |||
fCopyDescriptorSets := TvkuCopyDescriptorSetList.Create; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
destructor TvkuUpdateDescriptorSetHelper.Destroy; | |||
begin | |||
FreeAndNil(fCopyDescriptorSets); | |||
FreeAndNil(fWriteDescriptorSets); | |||
inherited Destroy; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
//TvkuDevice///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -105,6 +377,12 @@ begin | |||
fDeviceCommands.vkFreeMemory(fHandle, aMemory, aAllocCallbacks); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function TvkuDevice.UpdateDescriptorSet: TvkuUpdateDescriptorSetHelper; | |||
begin | |||
result := TvkuUpdateDescriptorSetHelper.Create(fDeviceCommands); | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo; | |||
const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: PVkAllocationCallbacks); | |||
@@ -6,13 +6,9 @@ interface | |||
uses | |||
Classes, SysUtils, | |||
Vulkan, uvkuInstance, uvkuDevice, uvkuAllocationHandler; | |||
Vulkan, uvkuInstance, uvkuDevice, uvkuAllocationHandler, uvkuTypes; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuStructure = class | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuFactory = class(TvkuStructure) | |||
private | |||
@@ -14,12 +14,14 @@ type | |||
private | |||
fHandle: VkImage; | |||
fDeviceCommands: TVkDeviceCommands; | |||
fMemory: VkDeviceMemory; | |||
fImageMemory: TvkuDeviceMemory; | |||
procedure CreateHandle(const aCreateInfo: TVkImageCreateInfo); | |||
public | |||
property Handle: VkImage read fHandle; | |||
property DeviceCommands: TVkDeviceCommands read fDeviceCommands; | |||
property Memory: VkDeviceMemory read fMemory; | |||
function GetMemoryBarrier( | |||
const aAspectMask: VkImageAspectFlags; | |||
@@ -159,6 +161,7 @@ begin | |||
err := fDeviceCommands.vkBindImageMemory(fDeviceCommands.Device, fHandle, aMemory, aOffset); | |||
if (err < VK_SUCCESS) then | |||
TvkuErrorException.Create('unable to bind image memory', err); | |||
fMemory := aMemory; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -181,20 +184,13 @@ begin | |||
MemReq := GetMemoryRequirements; | |||
FillByte(MemAllocInfo, SizeOf(MemAllocInfo), 0); | |||
MemAllocInfo.sType := VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; | |||
MemAllocInfo.pNext := nil; | |||
MemAllocInfo.allocationSize := MemReq.size; | |||
bits := MemReq.memoryTypeBits; | |||
for i := 0 to VK_MAX_MEMORY_TYPES-1 do begin | |||
if ((bits and 1) = 1) and | |||
(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT in aMemoryProperties.memoryTypes[i].propertyFlags) then | |||
begin | |||
MemAllocInfo.memoryTypeIndex := i; | |||
break; | |||
end; | |||
bits := bits shr 1; | |||
end; | |||
MemAllocInfo.sType := VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; | |||
MemAllocInfo.pNext := nil; | |||
MemAllocInfo.allocationSize := MemReq.size; | |||
MemAllocInfo.memoryTypeIndex := vkuGetMemoryTypeIndex( | |||
aMemoryProperties, | |||
MemReq.memoryTypeBits, | |||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);; | |||
if not Assigned(aAllocCallbacks) then | |||
aAllocCallbacks := AllocCallbacks; | |||
@@ -6,7 +6,7 @@ interface | |||
uses | |||
Classes, SysUtils, | |||
Vulkan, uvkuImageView, uvkuFactoryBase; | |||
Vulkan, uvkuImageView, uvkuFactoryBase, uvkuTypes; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -22,6 +22,228 @@ type | |||
end; | |||
TvkuPipelineShaderStageCreateInfoList = specialize TvkuObjList<TvkuPipelineShaderStageCreateInfo>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuVertexInputBindingDescription = class(TvkuStructure) | |||
public | |||
Binding: VkUint32; | |||
Stride: VkUint32; | |||
InputRate: TVkVertexInputRate; | |||
function GetStructure: TVkVertexInputBindingDescription; | |||
procedure SetStructure(const aData: TVkVertexInputBindingDescription); | |||
end; | |||
TvkuVertexInputBindingDescriptionList = specialize TvkuObjList<TvkuVertexInputBindingDescription>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuVertexInputAttributeDescription = class(TvkuStructure) | |||
public | |||
Location: VkUint32; | |||
Binding: VkUint32; | |||
Format: TVkFormat; | |||
Offset: VkUint32; | |||
function GetStructure: TVkVertexInputAttributeDescription; | |||
procedure SetStructure(const aData: TVkVertexInputAttributeDescription); | |||
end; | |||
TvkuVertexInputAttributeDescriptionList = specialize TvkuObjList<TvkuVertexInputAttributeDescription>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
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<TvkuViewport>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuRect2D = class(TvkuStructure) | |||
Offset: TVkOffset2D; | |||
Extent: TVkExtent2D; | |||
function GetStructure: TVkRect2D; | |||
procedure SetStructure(const aData: TVkRect2D); | |||
end; | |||
TvkuRect2DList = specialize TvkuObjList<TvkuRect2D>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
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<TvkuPipelineColorBlendAttachmentState>; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
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 | |||
@@ -39,16 +261,44 @@ type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuGraphicsPipelineFactory = class(TvkuPipelineFactory) | |||
private | |||
fRenderPass: VkRenderPass; | |||
fSubPass: VkUint32; | |||
fStages: TvkuPipelineShaderStageCreateInfoList; | |||
fRenderPass: VkRenderPass; | |||
fSubpass: VkUint32; | |||
fvkStages: TVkPipelineShaderStageCreateInfoArr; | |||
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 RenderPass: VkRenderPass read fRenderPass write fRenderPass; | |||
property SubPass: VkUint32 read fSubPass write fSubPass; | |||
property Stages: TvkuPipelineShaderStageCreateInfoList read fStages; | |||
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); | |||
@@ -95,6 +345,508 @@ begin | |||
// 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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -105,21 +857,31 @@ begin | |||
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 := 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.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; | |||
@@ -155,12 +917,30 @@ end; | |||
procedure TvkuGraphicsPipelineFactory.AfterConstruction; | |||
begin | |||
inherited AfterConstruction; | |||
fStages := TvkuPipelineShaderStageCreateInfoList.Create; | |||
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; | |||
@@ -9,6 +9,14 @@ uses | |||
Vulkan, uvkuUtils; | |||
type | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuStructure = class | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
TvkuCommandHelper = class | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
generic TvkuListBase<T> = class(TObject) | |||
private type | |||
@@ -77,12 +85,28 @@ type | |||
TVkMemoryBarrierArr = array of TVkMemoryBarrier; | |||
TVkBufferMemoryBarrierArr = array of TVkBufferMemoryBarrier; | |||
TVkImageMemoryBarrierArr = array of TVkImageMemoryBarrier; | |||
TVkViewportArr = array of TVkViewport; | |||
TVkRect2DArr = array of TVkRect2D; | |||
TVkSampleMaskArr = array of VkSampleMask; | |||
TVkVertexInputBindingDescriptionArr = array of TVkVertexInputBindingDescription; | |||
TVkVertexInputAttributeDescriptionArr = array of TVkVertexInputAttributeDescription; | |||
TVkPipelineColorBlendAttachmentStateArr = array of TVkPipelineColorBlendAttachmentState; | |||
TVkDynamicStateArr = array of TVkDynamicState; | |||
TVkDescriptorPoolSizeArr = array of TVkDescriptorPoolSize; | |||
TVkDescriptorSetArr = array of VkDescriptorSet; | |||
TVkDescriptorImageInfoArr = array of TVkDescriptorImageInfo; | |||
TVkDescriptorBufferInfoArr = array of TVkDescriptorBufferInfo; | |||
TVkClearValueArr = array of TVkClearValue; | |||
TVkUint32List = specialize TvkuList<VkUint32>; | |||
TVkFloatList = specialize TvkuList<VkFloat>; | |||
TVkImageViewList = specialize TvkuList<VkImageView>; | |||
TVkSamplerList = specialize TvkuList<VkSampler>; | |||
TVkDescriptorSetLayoutList = specialize TvkuList<VkDescriptorSetLayout>; | |||
TVkSampleMaskList = specialize TvkuList<VkSampleMask>; | |||
TVkDynamicStateList = specialize TvkuList<TVkDynamicState>; | |||
TVkBufferViewList = specialize TvkuList<VkBufferView>; | |||
TVkClearValueList = specialize TvkuList<TVkClearValue>; | |||
implementation | |||
@@ -36,6 +36,11 @@ function vkuMakeString(const aFeatures: TVkPhysicalDeviceFeatures; const aSepera | |||
function vkuMakeString(const aProperties: TVkPhysicalDeviceProperties; const aPrintLimits, aPrintSparseProps: Boolean): String; | |||
function vkuMakeString(const aMemoryProperties: TVkPhysicalDeviceMemoryProperties): String; | |||
function vkuGetMemoryTypeIndex( | |||
const aMemoryProperties: TVkPhysicalDeviceMemoryProperties; | |||
aMemoryTypeBits: VkUint32; | |||
const aProperty: TVkMemoryPropertyFlagBit): VkUint32; | |||
implementation | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -475,6 +480,26 @@ begin | |||
end; | |||
end; | |||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
function vkuGetMemoryTypeIndex( | |||
const aMemoryProperties: TVkPhysicalDeviceMemoryProperties; | |||
aMemoryTypeBits: VkUint32; | |||
const aProperty: TVkMemoryPropertyFlagBit): VkUint32; | |||
var | |||
i: Integer; | |||
begin | |||
result := 0; | |||
for i := 0 to VK_MAX_MEMORY_TYPES-1 do begin | |||
if ((aMemoryTypeBits and 1) = 1) and | |||
(aProperty in aMemoryProperties.memoryTypes[i].propertyFlags) then | |||
begin | |||
result := i; | |||
break; | |||
end; | |||
aMemoryTypeBits := aMemoryTypeBits shr 1; | |||
end; | |||
end; | |||
end. | |||