Procházet zdrojové kódy

* implemented DescriptorSet and DescriptorSetPool

* implemented methods for other classes
* implemented init/render code
master
Bergmann89 před 8 roky
rodič
revize
fe171d19a8
23 změnil soubory, kde provedl 2538 přidání a 395 odebrání
  1. +3
    -0
      .gitmodules
  2. +12
    -12
      projects/Vulkan.pas
  3. +1
    -1
      projects/generator/HeaderGenerator.pas
  4. +50
    -50
      projects/generator/generator.lps
  5. +1
    -0
      projects/lazopenglcore
  6. +16
    -4
      projects/triangle/triangle.lpi
  7. +1
    -1
      projects/triangle/triangle.lpr
  8. +284
    -261
      projects/triangle/triangle.lps
  9. +420
    -22
      projects/triangle/uMainForm.pas
  10. +6
    -0
      projects/utils/VulkanUtils.pas
  11. +62
    -1
      projects/utils/uvkuBuffer.pas
  12. +233
    -0
      projects/utils/uvkuCommandBuffer.pas
  13. +5
    -5
      projects/utils/uvkuCommandPool.pas
  14. +136
    -0
      projects/utils/uvkuDescriptorPool.pas
  15. +115
    -0
      projects/utils/uvkuDescriptorPoolFactory.pas
  16. +56
    -0
      projects/utils/uvkuDescriptorSet.pas
  17. +279
    -1
      projects/utils/uvkuDevice.pas
  18. +1
    -5
      projects/utils/uvkuFactoryBase.pas
  19. +10
    -14
      projects/utils/uvkuImage.pas
  20. +1
    -1
      projects/utils/uvkuImageViewFactory.pas
  21. +797
    -17
      projects/utils/uvkuPipelineFactory.pas
  22. +24
    -0
      projects/utils/uvkuTypes.pas
  23. +25
    -0
      projects/utils/uvkuUtils.pas

+ 3
- 0
.gitmodules Zobrazit soubor

@@ -0,0 +1,3 @@
[submodule "projects/lazopenglcore"]
path = projects/lazopenglcore
url = ../lazopenglcore.git

+ 12
- 12
projects/Vulkan.pas Zobrazit soubor

@@ -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;


+ 1
- 1
projects/generator/HeaderGenerator.pas Zobrazit soubor

@@ -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;


+ 50
- 50
projects/generator/generator.lps Zobrazit soubor

@@ -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>


+ 1
- 0
projects/lazopenglcore

@@ -0,0 +1 @@
Subproject commit f4a09e3657bd0fa4eacfde88a5b19609ad215d92

+ 16
- 4
projects/triangle/triangle.lpi Zobrazit soubor

@@ -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>


+ 1
- 1
projects/triangle/triangle.lpr Zobrazit soubor

@@ -8,7 +8,7 @@ uses
cthreads,
{$ENDIF}{$ENDIF}
SysUtils, Interfaces, Dialogs, Forms,
uMainForm, Vulkan, uvkuDebugReporter, uvkuPipelineCache, uvkuPipelineCacheFactory;
uMainForm, Vulkan, uvkuDescriptorPool, uvkuDescriptorPoolFactory, uvkuDescriptorSet;

{$R *.res}



+ 284
- 261
projects/triangle/triangle.lps Zobrazit soubor

@@ -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"/>


+ 420
- 22
projects/triangle/uMainForm.pas Zobrazit soubor

@@ -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.


+ 6
- 0
projects/utils/VulkanUtils.pas Zobrazit soubor

@@ -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;


+ 62
- 1
projects/utils/uvkuBuffer.pas Zobrazit soubor

@@ -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;



+ 233
- 0
projects/utils/uvkuCommandBuffer.pas Zobrazit soubor

@@ -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);


+ 5
- 5
projects/utils/uvkuCommandPool.pas Zobrazit soubor

@@ -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;


+ 136
- 0
projects/utils/uvkuDescriptorPool.pas Zobrazit soubor

@@ -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.


+ 115
- 0
projects/utils/uvkuDescriptorPoolFactory.pas Zobrazit soubor

@@ -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.


+ 56
- 0
projects/utils/uvkuDescriptorSet.pas Zobrazit soubor

@@ -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.


+ 279
- 1
projects/utils/uvkuDevice.pas Zobrazit soubor

@@ -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);


+ 1
- 5
projects/utils/uvkuFactoryBase.pas Zobrazit soubor

@@ -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


+ 10
- 14
projects/utils/uvkuImage.pas Zobrazit soubor

@@ -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;


+ 1
- 1
projects/utils/uvkuImageViewFactory.pas Zobrazit soubor

@@ -6,7 +6,7 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuImageView, uvkuFactoryBase;
Vulkan, uvkuImageView, uvkuFactoryBase, uvkuTypes;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 797
- 17
projects/utils/uvkuPipelineFactory.pas Zobrazit soubor

@@ -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;


+ 24
- 0
projects/utils/uvkuTypes.pas Zobrazit soubor

@@ -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



+ 25
- 0
projects/utils/uvkuUtils.pas Zobrazit soubor

@@ -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.


Načítá se…
Zrušit
Uložit