Browse Source

* refactored factories

master
Bergmann89 8 years ago
parent
commit
296c5fbb40
29 changed files with 2278 additions and 1637 deletions
  1. +1
    -0
      .gitignore
  2. +13
    -1
      projects/triangle/triangle.lpi
  3. +10
    -2
      projects/triangle/triangle.lpr
  4. +284
    -267
      projects/triangle/triangle.lps
  5. +130
    -100
      projects/triangle/uMainForm.pas
  6. +29
    -37
      projects/utils/VulkanUtils.pas
  7. +9
    -42
      projects/utils/uvkuAllocationHandler.pas
  8. +40
    -73
      projects/utils/uvkuBufferFactory.pas
  9. +23
    -45
      projects/utils/uvkuBufferViewFactory.pas
  10. +5
    -5
      projects/utils/uvkuCommandPool.pas
  11. +17
    -40
      projects/utils/uvkuCommandPoolFactory.pas
  12. +85
    -57
      projects/utils/uvkuDescriptorSetLayoutFactory.pas
  13. +296
    -125
      projects/utils/uvkuDeviceFactory.pas
  14. +61
    -2
      projects/utils/uvkuFactoryBase.pas
  15. +36
    -72
      projects/utils/uvkuFrameBufferFactory.pas
  16. +62
    -87
      projects/utils/uvkuImageFactory.pas
  17. +74
    -41
      projects/utils/uvkuImageViewFactory.pas
  18. +4
    -4
      projects/utils/uvkuInstance.pas
  19. +99
    -99
      projects/utils/uvkuInstanceFactory.pas
  20. +17
    -17
      projects/utils/uvkuPhysicalDevice.pas
  21. +127
    -0
      projects/utils/uvkuPipeline.pas
  22. +169
    -0
      projects/utils/uvkuPipelineFactory.pas
  23. +63
    -97
      projects/utils/uvkuPipelineLayoutFactory.pas
  24. +267
    -106
      projects/utils/uvkuRenderPassFactory.pas
  25. +83
    -38
      projects/utils/uvkuShaderModuleFactory.pas
  26. +26
    -146
      projects/utils/uvkuSurfaceFactory.pas
  27. +2
    -2
      projects/utils/uvkuSwapChain.pas
  28. +68
    -99
      projects/utils/uvkuSwapChainFactory.pas
  29. +178
    -33
      projects/utils/uvkuTypes.pas

+ 1
- 0
.gitignore View File

@@ -1,4 +1,5 @@
*.exe
*.dbg
*.log
*.heaptrc
**/lib/

+ 13
- 1
projects/triangle/triangle.lpi View File

@@ -33,7 +33,7 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="41">
<Units Count="43">
<Unit0>
<Filename Value="triangle.lpr"/>
<IsPartOfProject Value="True"/>
@@ -201,6 +201,14 @@
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<IsPartOfProject Value="True"/>
</Unit40>
<Unit41>
<Filename Value="..\utils\uvkuPipeline.pas"/>
<IsPartOfProject Value="True"/>
</Unit41>
<Unit42>
<Filename Value="..\utils\uvkuPipelineFactory.pas"/>
<IsPartOfProject Value="True"/>
</Unit42>
</Units>
</ProjectOptions>
<CompilerOptions>
@@ -214,6 +222,10 @@
<OtherUnitFiles Value="..;..\utils"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<CodeGeneration>
<TargetCPU Value="x86_64"/>
<TargetOS Value="win64"/>
</CodeGeneration>
<Linking>
<Debugging>
<UseHeaptrc Value="True"/>


+ 10
- 2
projects/triangle/triangle.lpr View File

@@ -7,17 +7,25 @@ uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, Dialogs, Forms, uMainForm, Vulkan, uvkuPipelineLayout, uvkuPipelineLayoutFactory, uvkuShaderModule,
uvkuShaderModuleFactory;
SysUtils, Interfaces, Dialogs, Forms,
uMainForm, Vulkan;

{$R *.res}

var
heaptrcFile: String;

begin
if not InitializeVulkan then begin
MessageDlg('Error', 'unable to initialize vulkan api', mtError, [mbOK], 0);
halt;
end;

heaptrcFile := ChangeFileExt(Application.ExeName, '.heaptrc');
if (FileExists(heaptrcFile)) then
DeleteFile(heaptrcFile);
SetHeapTraceOutput(heaptrcFile);

RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);


+ 284
- 267
projects/triangle/triangle.lps View File

@@ -4,13 +4,13 @@
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="59">
<Units Count="63">
<Unit0>
<Filename Value="triangle.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="8"/>
<CursorPos X="22" Y="12"/>
<UsageCount Value="72"/>
<EditorIndex Value="5"/>
<CursorPos X="3" Y="31"/>
<UsageCount Value="93"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
@@ -20,74 +20,75 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="3"/>
<TopLine Value="335"/>
<CursorPos X="45" Y="361"/>
<UsageCount Value="72"/>
<TopLine Value="104"/>
<CursorPos Y="118"/>
<UsageCount Value="93"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
<Unit2>
<Filename Value="..\Vulkan.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="14"/>
<TopLine Value="2350"/>
<CursorPos X="70" Y="2370"/>
<EditorIndex Value="7"/>
<TopLine Value="4295"/>
<CursorPos X="41" Y="4316"/>
<ExtraEditorCount Value="1"/>
<ExtraEditor1>
<EditorIndex Value="-1"/>
<TopLine Value="2785"/>
<CursorPos X="3" Y="2800"/>
<TopLine Value="1857"/>
<CursorPos X="75" Y="1873"/>
</ExtraEditor1>
<UsageCount Value="72"/>
<UsageCount Value="93"/>
<Loaded Value="True"/>
</Unit2>
<Unit3>
<Filename Value="..\utils\uvkuInstance.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="30" Y="9"/>
<UsageCount Value="70"/>
<CursorPos X="45" Y="16"/>
<UsageCount Value="91"/>
</Unit3>
<Unit4>
<Filename Value="..\utils\uvkuInstanceFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="19"/>
<CursorPos X="3" Y="161"/>
<UsageCount Value="64"/>
<EditorIndex Value="2"/>
<TopLine Value="13"/>
<CursorPos X="3" Y="29"/>
<UsageCount Value="85"/>
<Loaded Value="True"/>
</Unit4>
<Unit5>
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="245"/>
<CursorPos X="38" Y="252"/>
<UsageCount Value="64"/>
<EditorIndex Value="6"/>
<TopLine Value="159"/>
<CursorPos X="16" Y="210"/>
<UsageCount Value="85"/>
<Loaded Value="True"/>
</Unit5>
<Unit6>
<Filename Value="..\utils\uvkuAllocationHandler.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="91"/>
<CursorPos X="39" Y="99"/>
<UsageCount Value="54"/>
<EditorIndex Value="4"/>
<CursorPos X="3" Y="93"/>
<UsageCount Value="75"/>
<Loaded Value="True"/>
</Unit6>
<Unit7>
<Filename Value="..\utils\uvkuDevice.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="51"/>
<CursorPos X="63" Y="66"/>
<UsageCount Value="58"/>
<TopLine Value="54"/>
<CursorPos Y="81"/>
<UsageCount Value="79"/>
</Unit7>
<Unit8>
<Filename Value="..\utils\uvkuDeviceFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="16"/>
<CursorPos X="11" Y="9"/>
<UsageCount Value="56"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="353"/>
<CursorPos Y="377"/>
<UsageCount Value="77"/>
</Unit8>
<Unit9>
<Filename Value="..\utils\uvkuSurface.pas"/>
@@ -95,32 +96,31 @@
<EditorIndex Value="-1"/>
<TopLine Value="41"/>
<CursorPos X="94" Y="56"/>
<UsageCount Value="51"/>
<UsageCount Value="72"/>
</Unit9>
<Unit10>
<Filename Value="..\utils\uvkuSurfaceFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="17"/>
<CursorPos X="11" Y="10"/>
<UsageCount Value="50"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="44"/>
<CursorPos X="33" Y="60"/>
<UsageCount Value="71"/>
</Unit10>
<Unit11>
<Filename Value="..\utils\uvkuSwapChainFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="18"/>
<TopLine Value="34"/>
<CursorPos X="14" Y="48"/>
<UsageCount Value="41"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="64"/>
<CursorPos X="63" Y="51"/>
<UsageCount Value="62"/>
</Unit11>
<Unit12>
<Filename Value="..\utils\uvkuSwapChain.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="62"/>
<CursorPos X="35" Y="78"/>
<UsageCount Value="40"/>
<TopLine Value="7"/>
<CursorPos X="36" Y="23"/>
<UsageCount Value="61"/>
</Unit12>
<Unit13>
<Filename Value="..\utils\uvkuImageView.pas"/>
@@ -128,32 +128,31 @@
<EditorIndex Value="-1"/>
<TopLine Value="29"/>
<CursorPos X="64" Y="47"/>
<UsageCount Value="37"/>
<UsageCount Value="58"/>
</Unit13>
<Unit14>
<Filename Value="..\utils\uvkuImageViewFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="20"/>
<TopLine Value="21"/>
<CursorPos X="14" Y="36"/>
<UsageCount Value="37"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="24"/>
<CursorPos X="60" Y="88"/>
<UsageCount Value="58"/>
</Unit14>
<Unit15>
<Filename Value="..\utils\uvkuImage.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="36"/>
<CursorPos X="102" Y="51"/>
<UsageCount Value="36"/>
<TopLine Value="48"/>
<CursorPos X="17" Y="64"/>
<UsageCount Value="57"/>
</Unit15>
<Unit16>
<Filename Value="..\utils\uvkuBase.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="26"/>
<CursorPos X="5" Y="39"/>
<UsageCount Value="35"/>
<TopLine Value="21"/>
<CursorPos Y="82"/>
<UsageCount Value="56"/>
</Unit16>
<Unit17>
<Filename Value="..\utils\uvkuDeviceMemory.pas"/>
@@ -161,7 +160,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="33"/>
<CursorPos X="79" Y="44"/>
<UsageCount Value="33"/>
<UsageCount Value="54"/>
</Unit17>
<Unit18>
<Filename Value="..\utils\uvkuBuffer.pas"/>
@@ -169,32 +168,31 @@
<EditorIndex Value="-1"/>
<TopLine Value="10"/>
<CursorPos X="3" Y="13"/>
<UsageCount Value="32"/>
<UsageCount Value="53"/>
</Unit18>
<Unit19>
<Filename Value="..\utils\uvkuImageFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="19"/>
<CursorPos X="22" Y="9"/>
<UsageCount Value="32"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="20"/>
<CursorPos X="60" Y="74"/>
<UsageCount Value="53"/>
</Unit19>
<Unit20>
<Filename Value="..\utils\uvkuTypes.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="15"/>
<TopLine Value="3"/>
<CursorPos X="3" Y="18"/>
<UsageCount Value="32"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="79"/>
<CursorPos Y="95"/>
<UsageCount Value="53"/>
</Unit20>
<Unit21>
<Filename Value="..\utils\uvkuBufferFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="21"/>
<CursorPos X="23" Y="9"/>
<UsageCount Value="31"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="20"/>
<CursorPos X="60" Y="58"/>
<UsageCount Value="52"/>
</Unit21>
<Unit22>
<Filename Value="..\utils\uvkuBufferView.pas"/>
@@ -202,39 +200,36 @@
<EditorIndex Value="-1"/>
<TopLine Value="52"/>
<CursorPos X="56" Y="76"/>
<UsageCount Value="31"/>
<UsageCount Value="52"/>
</Unit22>
<Unit23>
<Filename Value="..\utils\uvkuBufferViewFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="22"/>
<CursorPos X="50" Y="9"/>
<UsageCount Value="30"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="31" Y="45"/>
<UsageCount Value="51"/>
</Unit23>
<Unit24>
<Filename Value="..\utils\uvkuCommandPool.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="23"/>
<TopLine Value="58"/>
<CursorPos X="34" Y="78"/>
<UsageCount Value="30"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="57"/>
<CursorPos X="21" Y="73"/>
<UsageCount Value="51"/>
</Unit24>
<Unit25>
<Filename Value="..\utils\uvkuCommandPoolFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="24"/>
<CursorPos X="28" Y="9"/>
<UsageCount Value="29"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="46" Y="42"/>
<UsageCount Value="50"/>
</Unit25>
<Unit26>
<Filename Value="..\utils\uvkuCommandBuffer.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="39" Y="13"/>
<UsageCount Value="29"/>
<UsageCount Value="50"/>
</Unit26>
<Unit27>
<Filename Value="..\utils\uvkuQueue.pas"/>
@@ -242,378 +237,400 @@
<EditorIndex Value="-1"/>
<TopLine Value="7"/>
<CursorPos X="22" Y="23"/>
<UsageCount Value="29"/>
<UsageCount Value="50"/>
</Unit27>
<Unit28>
<Filename Value="..\utils\VulkanUtils.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="2"/>
<TopLine Value="39"/>
<CursorPos X="45" Y="21"/>
<UsageCount Value="28"/>
<EditorIndex Value="1"/>
<TopLine Value="32"/>
<CursorPos X="3" Y="48"/>
<UsageCount Value="49"/>
<Loaded Value="True"/>
</Unit28>
<Unit29>
<Filename Value="..\utils\uvkuUtils.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="12"/>
<TopLine Value="17"/>
<CursorPos X="28" Y="29"/>
<UsageCount Value="45"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="14"/>
<UsageCount Value="66"/>
</Unit29>
<Unit30>
<Filename Value="..\utils\uvkuRenderPass.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="1"/>
<TopLine Value="8"/>
<CursorPos X="150" Y="12"/>
<UsageCount Value="26"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="3" Y="13"/>
<UsageCount Value="47"/>
</Unit30>
<Unit31>
<Filename Value="..\utils\uvkuRenderPassFactory.pas"/>
<IsPartOfProject Value="True"/>
<TopLine Value="35"/>
<CursorPos X="22" Y="56"/>
<UsageCount Value="26"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="82" Y="11"/>
<UsageCount Value="47"/>
</Unit31>
<Unit32>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="7"/>
<UsageCount Value="26"/>
<EditorIndex Value="3"/>
<TopLine Value="69"/>
<CursorPos X="12" Y="82"/>
<UsageCount Value="47"/>
<Loaded Value="True"/>
</Unit32>
<Unit33>
<Filename Value="..\utils\uvkuFrameBuffer.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="11"/>
<EditorIndex Value="-1"/>
<TopLine Value="33"/>
<CursorPos X="150" Y="40"/>
<UsageCount Value="24"/>
<Loaded Value="True"/>
<UsageCount Value="45"/>
</Unit33>
<Unit34>
<Filename Value="..\utils\uvkuFrameBufferFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="13"/>
<TopLine Value="98"/>
<CursorPos X="39" Y="111"/>
<UsageCount Value="24"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="12"/>
<CursorPos X="25" Y="27"/>
<UsageCount Value="45"/>
</Unit34>
<Unit35>
<Filename Value="..\utils\uvkuDescriptorSetLayout.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="6"/>
<EditorIndex Value="-1"/>
<CursorPos X="150" Y="12"/>
<UsageCount Value="24"/>
<Loaded Value="True"/>
<UsageCount Value="45"/>
</Unit35>
<Unit36>
<Filename Value="..\utils\uvkuDescriptorSetLayoutFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="7"/>
<TopLine Value="64"/>
<CursorPos Y="77"/>
<UsageCount Value="23"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="89"/>
<CursorPos X="3" Y="106"/>
<UsageCount Value="44"/>
</Unit36>
<Unit37>
<Filename Value="..\utils\uvkuPipelineLayout.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="9"/>
<EditorIndex Value="-1"/>
<TopLine Value="48"/>
<CursorPos X="150" Y="53"/>
<UsageCount Value="23"/>
<Loaded Value="True"/>
<UsageCount Value="44"/>
</Unit37>
<Unit38>
<Filename Value="..\utils\uvkuPipelineLayoutFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="10"/>
<TopLine Value="17"/>
<CursorPos X="14" Y="147"/>
<UsageCount Value="23"/>
<Loaded Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="10"/>
<CursorPos X="37" Y="112"/>
<UsageCount Value="44"/>
</Unit38>
<Unit39>
<Filename Value="..\utils\uvkuShaderModule.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="54"/>
<CursorPos X="3" Y="67"/>
<UsageCount Value="42"/>
</Unit39>
<Unit40>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="117"/>
<CursorPos X="37" Y="127"/>
<UsageCount Value="42"/>
</Unit40>
<Unit41>
<Filename Value="..\utils\uvkuPipeline.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="79"/>
<CursorPos X="17" Y="91"/>
<UsageCount Value="40"/>
</Unit41>
<Unit42>
<Filename Value="..\utils\uvkuPipelineFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="7"/>
<CursorPos X="3" Y="23"/>
<UsageCount Value="39"/>
</Unit42>
<Unit43>
<Filename Value="..\utils\uvkuPhysicalDeviceFactory.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="5"/>
<CursorPos X="19" Y="17"/>
<UsageCount Value="49"/>
</Unit39>
<Unit40>
<UsageCount Value="46"/>
</Unit43>
<Unit44>
<Filename Value="..\..\data\Vulkan.tpl"/>
<EditorIndex Value="-1"/>
<TopLine Value="44"/>
<CursorPos X="27" Y="22"/>
<UsageCount Value="13"/>
<UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit40>
<Unit41>
</Unit44>
<Unit45>
<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="9"/>
</Unit41>
<Unit42>
<UsageCount Value="6"/>
</Unit45>
<Unit46>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\inc\objpash.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="181"/>
<CursorPos X="21" Y="223"/>
<CursorPos X="23" Y="197"/>
<UsageCount Value="10"/>
</Unit42>
<Unit43>
</Unit46>
<Unit47>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\customform.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="138"/>
<CursorPos Y="154"/>
<UsageCount Value="8"/>
</Unit43>
<Unit44>
<TopLine Value="910"/>
<CursorPos Y="927"/>
<UsageCount Value="10"/>
</Unit47>
<Unit48>
<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="9"/>
</Unit44>
<Unit45>
<UsageCount Value="6"/>
</Unit48>
<Unit49>
<Filename Value="..\Vulkan_old.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="2195"/>
<CursorPos X="3" Y="2211"/>
<UsageCount Value="9"/>
</Unit45>
<Unit46>
<UsageCount Value="6"/>
</Unit49>
<Unit50>
<Filename Value="..\Vulkan.inc"/>
<EditorIndex Value="-1"/>
<CursorPos X="9" Y="5"/>
<UsageCount Value="10"/>
</Unit46>
<Unit47>
<UsageCount Value="7"/>
</Unit50>
<Unit51>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\forms.pp"/>
<UnitName Value="Forms"/>
<EditorIndex Value="-1"/>
<TopLine Value="1249"/>
<CursorPos X="3" Y="1268"/>
<UsageCount Value="9"/>
</Unit47>
<Unit48>
<UsageCount Value="6"/>
</Unit51>
<Unit52>
<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="9"/>
</Unit48>
<Unit49>
<UsageCount Value="6"/>
</Unit52>
<Unit53>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\extctrls.pp"/>
<UnitName Value="ExtCtrls"/>
<EditorIndex Value="-1"/>
<TopLine Value="1023"/>
<CursorPos X="3" Y="1038"/>
<UsageCount Value="9"/>
</Unit49>
<Unit50>
<UsageCount Value="6"/>
</Unit53>
<Unit54>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\controls.pp"/>
<UnitName Value="Controls"/>
<EditorIndex Value="-1"/>
<TopLine Value="2240"/>
<CursorPos X="3" Y="2255"/>
<UsageCount Value="9"/>
</Unit50>
<Unit51>
<UsageCount Value="6"/>
</Unit54>
<Unit55>
<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="11"/>
</Unit51>
<Unit52>
<UsageCount Value="8"/>
</Unit55>
<Unit56>
<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="11"/>
</Unit52>
<Unit53>
<UsageCount Value="8"/>
</Unit56>
<Unit57>
<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="11"/>
</Unit53>
<Unit54>
<UsageCount Value="8"/>
</Unit57>
<Unit58>
<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="11"/>
</Unit54>
<Unit55>
<UsageCount Value="8"/>
</Unit58>
<Unit59>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win32\windows.pp"/>
<EditorIndex Value="-1"/>
<UsageCount Value="11"/>
</Unit55>
<Unit56>
<UsageCount Value="8"/>
</Unit59>
<Unit60>
<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="11"/>
</Unit56>
<Unit57>
<Filename Value="..\utils\uvkuShaderModule.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="4"/>
<CursorPos X="36" Y="79"/>
<UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit57>
<Unit58>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="5"/>
<TopLine Value="85"/>
<CursorPos X="46" Y="93"/>
<UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit58>
<UsageCount Value="8"/>
</Unit60>
<Unit61>
<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"/>
</Unit61>
<Unit62>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\application.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="2148"/>
<CursorPos Y="2163"/>
<UsageCount Value="10"/>
</Unit62>
</Units>
<JumpHistory Count="30" HistoryIndex="28">
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="uMainForm.pas"/>
<Caret Line="248" Column="23" TopLine="231"/>
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/>
<Caret Line="47" Column="97" TopLine="32"/>
</Position1>
<Position2>
<Filename Value="uMainForm.pas"/>
<Caret Line="267" Column="13" TopLine="241"/>
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/>
<Caret Line="260" Column="23" TopLine="241"/>
</Position2>
<Position3>
<Filename Value="uMainForm.pas"/>
<Caret Line="278" Column="12" TopLine="254"/>
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/>
<Caret Line="257" Column="83" TopLine="241"/>
</Position3>
<Position4>
<Filename Value="uMainForm.pas"/>
<Caret Line="293" Column="5" TopLine="282"/>
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/>
<Caret Line="245" Column="60" TopLine="229"/>
</Position4>
<Position5>
<Filename Value="uMainForm.pas"/>
<Caret Line="292" Column="13" TopLine="282"/>
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/>
<Caret Line="257" Column="83" TopLine="241"/>
</Position5>
<Position6>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="96" Column="3" TopLine="81"/>
<Filename Value="..\Vulkan.pas"/>
<Caret Line="4540" Column="93" TopLine="4525"/>
</Position6>
<Position7>
<Filename Value="..\utils\uvkuFrameBufferFactory.pas"/>
<Caret Line="45" Column="19" TopLine="27"/>
<Filename Value="..\Vulkan.pas"/>
</Position7>
<Position8>
<Filename Value="uMainForm.pas"/>
<Caret Line="292" Column="13" TopLine="282"/>
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/>
<Caret Line="257" Column="83" TopLine="241"/>
</Position8>
<Position9>
<Filename Value="uMainForm.pas"/>
<Caret Line="295" Column="29" TopLine="267"/>
<Caret Line="106" Column="10" TopLine="88"/>
</Position9>
<Position10>
<Filename Value="uMainForm.pas"/>
<Caret Line="331" Column="24" TopLine="301"/>
<Caret Line="13" Column="3"/>
</Position10>
<Position11>
<Filename Value="uMainForm.pas"/>
<Caret Line="36" Column="29"/>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="44" Column="3" TopLine="28"/>
</Position11>
<Position12>
<Filename Value="uMainForm.pas"/>
<Caret Line="318" Column="42" TopLine="305"/>
<Caret Line="117" Column="21" TopLine="104"/>
</Position12>
<Position13>
<Filename Value="uMainForm.pas"/>
<Caret Line="332" Column="27" TopLine="319"/>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="48" Column="3" TopLine="32"/>
</Position13>
<Position14>
<Filename Value="uMainForm.pas"/>
<Caret Line="37" Column="41" TopLine="20"/>
<Filename Value="..\utils\uvkuInstanceFactory.pas"/>
<Caret Line="163" Column="27" TopLine="144"/>
</Position14>
<Position15>
<Filename Value="uMainForm.pas"/>
<Caret Line="335" Column="36" TopLine="317"/>
<Filename Value="..\utils\uvkuInstanceFactory.pas"/>
<Caret Line="29" Column="3" TopLine="13"/>
</Position15>
<Position16>
<Filename Value="uMainForm.pas"/>
<Caret Line="320" Column="78" TopLine="305"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="74" TopLine="66"/>
</Position16>
<Position17>
<Filename Value="..\utils\uvkuShaderModule.pas"/>
<Caret Line="17" Column="74" TopLine="5"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="82" TopLine="66"/>
</Position17>
<Position18>
<Filename Value="..\utils\uvkuShaderModule.pas"/>
<Caret Line="78" Column="25" TopLine="48"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="111" TopLine="104"/>
</Position18>
<Position19>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="17" Column="34"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="82" TopLine="66"/>
</Position19>
<Position20>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="25" Column="29" TopLine="4"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="66" TopLine="50"/>
</Position20>
<Position21>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="32" Column="20" TopLine="19"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="68" TopLine="50"/>
</Position21>
<Position22>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="75" Column="3" TopLine="45"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="69" TopLine="50"/>
</Position22>
<Position23>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="77" Column="33" TopLine="53"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="83" TopLine="67"/>
</Position23>
<Position24>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="31" Column="54" TopLine="19"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="77" Column="26" TopLine="69"/>
</Position24>
<Position25>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="28" Column="54" TopLine="11"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="83" TopLine="69"/>
</Position25>
<Position26>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="41" Column="43" TopLine="22"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="84" TopLine="69"/>
</Position26>
<Position27>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
<Caret Line="32" Column="71" TopLine="17"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="85" TopLine="69"/>
</Position27>
<Position28>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="110" Column="9" TopLine="87"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="86" TopLine="69"/>
</Position28>
<Position29>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="21" Column="45" TopLine="6"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="87" TopLine="69"/>
</Position29>
<Position30>
<Filename Value="uMainForm.pas"/>
<Caret Line="39" Column="14" TopLine="21"/>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<Caret Line="88" TopLine="69"/>
</Position30>
</JumpHistory>
</ProjectSession>
<Debugging>
<Watches Count="1">
<Watches Count="2">
<Item1>
<Expression Value="self"/>
</Item1>
<Item2>
<Expression Value="fDeviceCommands"/>
</Item2>
</Watches>
</Debugging>
</CONFIG>

+ 130
- 100
projects/triangle/uMainForm.pas View File

@@ -37,6 +37,7 @@ type
fPipelineLayout: TvkuPipelineLayout;
fVertexShader: TvkuShaderModule;
fFragmentShader: TvkuShaderModule;
fPipeline: TvkuGraphicsPipeline;
end;

var
@@ -53,7 +54,7 @@ implementation
function TCustomAllocHandler.AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
begin
result := inherited AllocateMemory(aSize, aAlignment, aScope);
WriteLn(Format('%d bytes of memory allocated at %p', [ aSize, result ]));
WriteLn(Format(' %d bytes of memory allocated at %p', [ aSize, result ]));
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -62,13 +63,13 @@ var p: PVkVoid;
begin
p := aOriginal;
result := inherited ReallocateMemory(aOriginal, aSize, aAlignment, aScope);
WriteLn(Format('%d bytes of memory (from %p) reallocated at %p', [ aSize, p, result ]));
WriteLn(Format(' %d bytes of memory (from %p) reallocated at %p', [ aSize, p, result ]));
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TCustomAllocHandler.FreeMemory(const aMemory: PVkVoid);
begin
WriteLn(Format('free memory at %p', [ aMemory ]));
WriteLn(Format(' free memory at %p', [ aMemory ]));
inherited FreeMemory(aMemory);
end;

@@ -77,7 +78,7 @@ end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.FormCreate(Sender: TObject);
var
PhyDevices: TvkuPhysicalDeviceArr;
PhyDevices: TVkPhysicalDeviceArr;
InstanceFactory: TvkuInstanceFactory;
DeviceFactory: TvkuDeviceFactory;
SurfaceFactory: TvkuSurfaceFactory;
@@ -88,21 +89,18 @@ var
DescSetLayoutFactory: TvkuDescriptorSetLayoutFactory;
PipelineLayoutFactory: TvkuPipelineLayoutFactory;
ShaderModuleFactory: TvkuShaderModuleFactory;
PipelineFactory: TvkuGraphicsPipelineFactory;

Format: TVkSurfaceFormatKHR;
SubResourceRange: TVkImageSubresourceRange;
DepthFormat: TVkFormat;
f: TVkFormat;
SurcafeFormat: TVkSurfaceFormatKHR;
i: Integer;
qci: TvkuQueueCreateInfo;
SrfFormats: TvkuSurfaceFormatArr;
SrfFormats: TVkSurfaceFormatArr;
SurfaceCapabilities: TVkSurfaceCapabilitiesKHR;
PresentModes: TvkuPresentModeArr;
PresentModes: TVkPresentModeArr;
pm: TVkPresentModeKHR;
Images: TvkuImageArr;
Images: TVkImageArr;
ComponentMapping: TVkComponentMapping;
AttDesc: TVkAttachmentDescription;
AttRef: TVkAttachmentReference;
Subpass: TVkSubpassDescription;
DescSetLayoutBinding: TVkDescriptorSetLayoutBinding;
begin
fAllocHandler := TCustomAllocHandler.Create;

@@ -110,9 +108,10 @@ begin
WriteLn('create instance');
InstanceFactory := TvkuInstanceFactory.Create;
try
InstanceFactory.Extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME);
InstanceFactory.Extensions.Add(TvkuSurface.GetPlatformSurfaceExtensionName);
fInstance := InstanceFactory.CreateInstance(fAllocHandler, false);
InstanceFactory.AllocHandler := fAllocHandler;
InstanceFactory.EnabledExtensionNames.Add(VK_KHR_SURFACE_EXTENSION_NAME);
InstanceFactory.EnabledExtensionNames.Add(TvkuSurface.GetPlatformSurfaceExtensionName);
fInstance := InstanceFactory.CreateInstance;
finally
FreeAndNil(InstanceFactory);
end;
@@ -123,20 +122,27 @@ begin
if (Length(PhyDevices) <= 0) then
raise Exception.Create('unable to get physical device');
fPhyDevice := TvkuPhysicalDevice.Create(PhyDevices[0], fInstance.InstanceCommands);
f := VK_FORMAT_UNDEFINED;
for f in [ VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM ] do begin
if (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT in fPhyDevice.GetFormatProperties(f).optimalTilingFeatures) then begin
DepthFormat := f;
break;
end;
end;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create device');
DeviceFactory := TvkuDeviceFactory.Create(fInstance);
try
SetLength(qci.Priorities, 1);
qci.Priorities[0] := 1.0;
qci.FamilyIndex := 0;
qci.Flags := 0;
DeviceFactory.QueueCreateInfoCount := 1;
DeviceFactory.QueueCreateInfo[0] := qci;
fDevice := DeviceFactory.CreateDevice(fPhyDevice.Handle, fAllocHandler, false);
DeviceFactory.AllocHandler := fAllocHandler;
DeviceFactory.QueueCreateInfos.Length := 1;
with DeviceFactory.QueueCreateInfos[0] do begin
Flags := 0;
QueueFamilyIndex := 0;
QueuePriorities.Length := 1;
QueuePriorities[0] := 1.0;
end;
fDevice := DeviceFactory.CreateDevice(fPhyDevice.Handle);
finally
FreeAndNil(DeviceFactory);
end;
@@ -149,8 +155,9 @@ begin
WriteLn('create surface');
SurfaceFactory := TvkuSurfaceFactory.Create(fInstance);
try
SurfaceFactory.WinControl := RenderPanel;
fSurface := SurfaceFactory.CreateSurface(fAllocHandler, false);
SurfaceFactory.AllocHandler := fAllocHandler;
SurfaceFactory.WinControl := RenderPanel;
fSurface := SurfaceFactory.CreateSurface;
finally
FreeAndNil(SurfaceFactory);
end;
@@ -159,6 +166,7 @@ begin
WriteLn('create swap chain');
SwapChainFactory := TvkuSwapChainFactory.Create(fDevice);
try
SwapChainFactory.AllocHandler := fAllocHandler;
SwapChainFactory.Surface := fSurface.Handle;
SwapChainFactory.ImageUsage := [ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ];
SwapChainFactory.ImageArrayLayers := 1;
@@ -190,14 +198,14 @@ begin
halt;
end;
if (Length(SrfFormats) = 1) and (SrfFormats[0].format = VK_FORMAT_UNDEFINED) then begin
Format.format := VK_FORMAT_R8G8B8A8_UNORM;
Format.colorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR;
SurcafeFormat.format := VK_FORMAT_R8G8B8A8_UNORM;
SurcafeFormat.colorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR;
end else begin
Format.format := SrfFormats[0].format;
Format.colorSpace := SrfFormats[0].colorSpace;
SurcafeFormat.format := SrfFormats[0].format;
SurcafeFormat.colorSpace := SrfFormats[0].colorSpace;
end;
SwapChainFactory.ImageFormat := Format.format;
SwapChainFactory.ImageColorSpace := format.colorSpace;
SwapChainFactory.ImageFormat := SurcafeFormat.format;
SwapChainFactory.ImageColorSpace := SurcafeFormat.colorSpace;


WriteLn(' set pre transform');
@@ -218,7 +226,7 @@ begin
end;
end;

fSwapChain := SwapChainFactory.CreateSwapchain(fAllocHandler, false);
fSwapChain := SwapChainFactory.CreateSwapchain;
finally
FreeAndNil(SwapChainFactory);
end;
@@ -234,19 +242,20 @@ begin
ComponentMapping.b := VK_COMPONENT_SWIZZLE_B;
ComponentMapping.a := VK_COMPONENT_SWIZZLE_A;

SubResourceRange.aspectMask := [ VK_IMAGE_ASPECT_COLOR_BIT ];
SubResourceRange.baseMipLevel := 0;
SubResourceRange.levelCount := 1;
SubResourceRange.baseArrayLayer := 0;
SubResourceRange.layerCount := 1;

ImageViewFactory.Format := Format.format;
ImageViewFactory.Components := ComponentMapping;
ImageViewFactory.SubresourceRange := SubResourceRange;
ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D;
ImageViewFactory.AllocHandler := fAllocHandler;
ImageViewFactory.Format := SurcafeFormat.format;
ImageViewFactory.Components := ComponentMapping;
ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D;
with ImageViewFactory.SubresourceRange do begin
AspectMask := [ VK_IMAGE_ASPECT_COLOR_BIT ];
BaseMipLevel := 0;
LevelCount := 1;
BaseArrayLayer := 0;
LayerCount := 1;
end;
for i := Low(fImageViews) to High(fImageViews) do begin
ImageViewFactory.Image := Images[i];
fImageViews[i] := ImageViewFactory.CreateImageView(fAllocHandler, false);
fImageViews[i] := ImageViewFactory.CreateImageView;
end;
finally
FreeAndNil(ImageViewFactory);
@@ -256,38 +265,44 @@ begin
WriteLn('create render pass');
RenderPassFactory := TvkuRenderPassFactory.Create(fDevice);
try
FillByte(AttDesc, SizeOf(AttDesc), 0);
AttDesc.format := Format.format;
AttDesc.samples := [ VK_SAMPLE_COUNT_1_BIT ];
AttDesc.loadOp := VK_ATTACHMENT_LOAD_OP_CLEAR;
AttDesc.storeOp := VK_ATTACHMENT_STORE_OP_STORE;
AttDesc.stencilLoadOp := VK_ATTACHMENT_LOAD_OP_DONT_CARE;
AttDesc.stencilStoreOp := VK_ATTACHMENT_STORE_OP_DONT_CARE;
AttDesc.initialLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
AttDesc.finalLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

FillByte(AttRef, SizeOf(AttRef), 0);
AttRef.attachment := 0;
AttRef.layout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

FillByte(Subpass, SizeOf(Subpass), 0);
Subpass.pipelineBindPoint := VK_PIPELINE_BIND_POINT_GRAPHICS;
Subpass.flags := 0;
Subpass.inputAttachmentCount := 0;
Subpass.pInputAttachments := nil;
Subpass.colorAttachmentCount := 1;
Subpass.pColorAttachments := @AttRef;
Subpass.pResolveAttachments := nil;
Subpass.pDepthStencilAttachment := nil;
Subpass.preserveAttachmentCount := 0;
Subpass.pPreserveAttachments := nil;

RenderPassFactory.AttachmentCount := 1;
RenderPassFactory.Attachment[0] := AttDesc;
RenderPassFactory.SubpassCount := 1;
RenderPassFactory.Subpass[0] := Subpass;

fRenderPass := RenderPassFactory.CreateRenderPass(fAllocHandler, false);
RenderPassFactory.Attachments.Length := 2;
with RenderPassFactory.Attachments[0] do begin
Format := SurcafeFormat.format;
Samples := [ VK_SAMPLE_COUNT_1_BIT ];
LoadOp := VK_ATTACHMENT_LOAD_OP_CLEAR;
StoreOp := VK_ATTACHMENT_STORE_OP_STORE;
StencilLoadOp := VK_ATTACHMENT_LOAD_OP_DONT_CARE;
StencilStoreOp := VK_ATTACHMENT_STORE_OP_DONT_CARE;
InitialLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
FinalLayout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
end;

with RenderPassFactory.Attachments[1] do begin
Format := DepthFormat;
Samples := [ VK_SAMPLE_COUNT_1_BIT ];
LoadOp := VK_ATTACHMENT_LOAD_OP_CLEAR;
StoreOp := VK_ATTACHMENT_STORE_OP_STORE;
StencilLoadOp := VK_ATTACHMENT_LOAD_OP_DONT_CARE;
StencilStoreOp := VK_ATTACHMENT_STORE_OP_DONT_CARE;
InitialLayout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
FinalLayout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
end;

RenderPassFactory.Subpasses.Length := 1;
with RenderPassFactory.Subpasses[0] do begin
PipelineBindPoint := VK_PIPELINE_BIND_POINT_GRAPHICS;

ColorAttachments.Length := 1;
ColorAttachments[0].Attachment := 0;
ColorAttachments[0].Layout := VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

DepthStencilAttachments.Length := 1;
DepthStencilAttachments[0].Attachment := 1;
DepthStencilAttachments[0].Layout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
end;

RenderPassFactory.AllocHandler := fAllocHandler;
fRenderPass := RenderPassFactory.CreateRenderPass;
finally
FreeAndNil(RenderPassFactory);
end;
@@ -298,15 +313,16 @@ begin
try
SetLength(fFrameBuffers, Length(fImageViews));

FrameBufferFactory.RenderPass := fRenderPass.Handle;
FrameBufferFactory.AttachmentCount := 1;
FrameBufferFactory.width := SurfaceCapabilities.currentExtent.width;
FrameBufferFactory.height := SurfaceCapabilities.currentExtent.height;
FrameBufferFactory.layers := 1;
FrameBufferFactory.AllocHandler := fAllocHandler;
FrameBufferFactory.RenderPass := fRenderPass.Handle;
FrameBufferFactory.Width := SurfaceCapabilities.currentExtent.width;
FrameBufferFactory.Height := SurfaceCapabilities.currentExtent.height;
FrameBufferFactory.Layers := 1;
FrameBufferFactory.Attachments.Length := 1;

for i := low(fFrameBuffers) to high(fFrameBuffers) do begin
FrameBufferFactory.Attachments[0] := fImageViews[i].Handle;
fFrameBuffers[i] := FrameBufferFactory.CreateFrameBuffer(fAllocHandler, false);
fFrameBuffers[i] := FrameBufferFactory.CreateFrameBuffer;
end;
finally
FreeAndNil(FrameBufferFactory);
@@ -316,17 +332,17 @@ begin
WriteLn('create descriptor set layout');
DescSetLayoutFactory := TvkuDescriptorSetLayoutFactory.Create(fDevice);
try
FillByte(DescSetLayoutBinding, SizeOf(DescSetLayoutBinding), 0);
DescSetLayoutBinding.binding := 0; // binding 0 (Uniform Buffer/Vertex Shader)
DescSetLayoutBinding.descriptorType := VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
DescSetLayoutBinding.descriptorCount := 1;
DescSetLayoutBinding.stageFlags := [ VK_SHADER_STAGE_VERTEX_BIT ];
DescSetLayoutBinding.pImmutableSamplers := nil;
DescSetLayoutFactory.Bindings.Length := 1;
with DescSetLayoutFactory.Bindings[0] do begin
Binding := 0; // binding 0 (Uniform Buffer/Vertex Shader)
DescriptorType := VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
DescriptorCount := 1;
StageFlags := [ VK_SHADER_STAGE_VERTEX_BIT ];
end;

DescSetLayoutFactory.BindingCount := 1;
DescSetLayoutFactory.Binding[0] := DescSetLayoutBinding;
DescSetLayoutFactory.AllocHandler := fAllocHandler;

fDescSetLayout := DescSetLayoutFactory.CreateDescriptorSetLayout(fAllocHandler, false);
fDescSetLayout := DescSetLayoutFactory.CreateDescriptorSetLayout;
finally
FreeAndNil(DescSetLayoutFactory);
end;
@@ -335,9 +351,10 @@ begin
WriteLn('create pipeline layout');
PipelineLayoutFactory := TvkuPipelineLayoutFactory.Create(fDevice);
try
PipelineLayoutFactory.SetLayoutCount := 1;
PipelineLayoutFactory.SetLayout[0] := fDescSetLayout.Handle;
fPipelineLayout := PipelineLayoutFactory.CreatePipelineLayout(fAllocHandler, false);
PipelineLayoutFactory.AllocHandler := fAllocHandler;
PipelineLayoutFactory.SetLayouts.Length := 1;
PipelineLayoutFactory.SetLayouts[0] := fDescSetLayout.Handle;
fPipelineLayout := PipelineLayoutFactory.CreatePipelineLayout;
finally
FreeAndNil(PipelineLayoutFactory);
end;
@@ -346,14 +363,26 @@ begin
WriteLn('create shader modules');
ShaderModuleFactory := TvkuShaderModuleFactory.Create(fDevice);
try
ShaderModuleFactory.SetShaderCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.vert.spv');
fVertexShader := ShaderModuleFactory.CreateShaderModule(fAllocHandler, false);
ShaderModuleFactory.AllocHandler := fAllocHandler;

ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.vert', [ VK_SHADER_STAGE_VERTEX_BIT ]);
fVertexShader := ShaderModuleFactory.CreateShaderModule;

ShaderModuleFactory.SetShaderCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag.spv');
fFragmentShader := ShaderModuleFactory.CreateShaderModule(fAllocHandler, false);
ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag', [ VK_SHADER_STAGE_FRAGMENT_BIT ]);
fFragmentShader := ShaderModuleFactory.CreateShaderModule;
finally
FreeAndNil(ShaderModuleFactory);
end;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create graphics pipeline');
PipelineFactory := TvkuGraphicsPipelineFactory.Create(fDevice);
try
PipelineFactory.AllocHandler := fAllocHandler;
fPipeline := PipelineFactory.CreateGraphicsPipeline(VK_INVALID_NDP_HANDLE);
finally
FreeAndNil(PipelineFactory);
end;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -376,6 +405,7 @@ procedure TMainForm.FormDestroy(Sender: TObject);
end;

begin
FreeAndNil(fPipeline);
FreeAndNil(fFragmentShader);
FreeAndNil(fVertexShader);
FreeAndNil(fPipelineLayout);


+ 29
- 37
projects/utils/VulkanUtils.pas View File

@@ -17,101 +17,93 @@ uses
uvkuRenderPass, uvkuRenderPassFactory,
uvkuFrameBuffer, uvkuFrameBufferFactory,
uvkuDescriptorSetLayout, uvkuDescriptorSetLayoutFactory,
uvkuPipelineLayout, uvkuPipelineLayoutFactory,
uvkuShaderModule, uvkuShaderModuleFactory,
uvkuPipelineLayout, uvkuPipelineLayoutFactory, uvkuPipeline, uvkuPipelineFactory,
uvkuUtils;

type
{ Types }
TvkuFloatArr = uvkuTypes.TvkuFloatArr;
TvkuUint32Arr = uvkuTypes.TvkuUint32Arr;
TvkuImageArr = uvkuTypes.TvkuImageArr;
TvkuPhysicalDeviceArr = uvkuTypes.TvkuPhysicalDeviceArr;
TvkuQueueFamilyPropertiesArr = uvkuTypes.TvkuQueueFamilyPropertiesArr;
TvkuSparseImageFormatPropertiesArr = uvkuTypes.TvkuSparseImageFormatPropertiesArr;
TvkuSurfaceFormatArr = uvkuTypes.TvkuSurfaceFormatArr;
TvkuPresentModeArr = uvkuTypes.TvkuPresentModeArr;
TvkuDisplayPropertiesArr = uvkuTypes.TvkuDisplayPropertiesArr;
TvkuDisplayPlanePropertiesArr = uvkuTypes.TvkuDisplayPlanePropertiesArr;
TvkuDisplayArr = uvkuTypes.TvkuDisplayArr;
TvkuDisplayModePropertiesArr = uvkuTypes.TvkuDisplayModePropertiesArr;
TvkuCommandBufferArr = uvkuTypes.TvkuCommandBufferArr;
TvkuApplicationInfo = uvkuTypes.TvkuApplicationInfo;
TvkuQueueCreateInfo = uvkuTypes.TvkuQueueCreateInfo;
TvkuQueueCreateInfoArr = uvkuTypes.TvkuQueueCreateInfoArr;

TvkuAllocationHandler = uvkuAllocationHandler.TvkuAllocationHandler;
PVkCharArr = uvkuTypes.PVkCharArr;
TVkPhysicalDeviceArr = uvkuTypes.TVkPhysicalDeviceArr;
TVkQueueFamilyPropertiesArr = uvkuTypes.TVkQueueFamilyPropertiesArr;
TVkSparseImageFormatPropertiesArr = uvkuTypes.TVkSparseImageFormatPropertiesArr;
TVkSurfaceFormatArr = uvkuTypes.TVkSurfaceFormatArr;
TVkPresentModeArr = uvkuTypes.TVkPresentModeArr;
TVkDisplayPropertiesArr = uvkuTypes.TVkDisplayPropertiesArr;
TVkDisplayPlanePropertiesArr = uvkuTypes.TVkDisplayPlanePropertiesArr;
TVkDisplayArr = uvkuTypes.TVkDisplayArr;
TVkDisplayModePropertiesArr = uvkuTypes.TVkDisplayModePropertiesArr;
TVkImageArr = uvkuTypes.TVkImageArr;
TVkCommandBufferArr = uvkuTypes.TVkCommandBufferArr;
TVkDescriptorSetLayoutBindingArr = uvkuTypes.TVkDescriptorSetLayoutBindingArr;
TVkDescriptorSetLayoutArr = uvkuTypes.TVkDescriptorSetLayoutArr;
TVkPushConstantRangeArr = uvkuTypes.TVkPushConstantRangeArr;
TVkPipelineShaderStageCreateInfoArr = uvkuTypes.TVkPipelineShaderStageCreateInfoArr;
TVkPipelineVertexInputStateCreateInfoArr = uvkuTypes.TVkPipelineVertexInputStateCreateInfoArr;

TvkuAllocationHandler = uvkuAllocationHandler.TvkuAllocationHandler;

{ Instance }
TvkuInstance = uvkuInstance.TvkuInstance;
TvkuInstanceEx = uvkuInstanceFactory.TvkuInstanceEx;
TvkuInstanceFactory = uvkuInstanceFactory.TvkuInstanceFactory;

{ Device }
TvkuPhysicalDevice = uvkuPhysicalDevice.TvkuPhysicalDevice;
TvkuDevice = uvkuDevice.TvkuDevice;
TvkuDeviceEx = uvkuDeviceFactory.TvkuDeviceEx;
TvkuDeviceFactory = uvkuDeviceFactory.TvkuDeviceFactory;
TvkuDeviceMemory = uvkuDeviceMemory.TvkuDeviceMemory;
TvkuQueue = uvkuQueue.TvkuQueue;

{ Surface }
TvkuSurface = uvkuSurface.TvkuSurface;
TvkuSurfaceEx = uvkuSurfaceFactory.TvkuSurfaceEx;
TvkuSurfaceFactory = uvkuSurfaceFactory.TvkuSurfaceFactory;

{ SwapChain }
TvkuSwapChain = uvkuSwapChain.TvkuSwapChain;
TvkuSwapChainEx = uvkuSwapChainFactory.TvkuSwapChainEx;
TvkuSwapChainFactory = uvkuSwapChainFactory.TvkuSwapChainFactory;

{ Image }
TvkuImage = uvkuImage.TvkuImage;
TvkuImageEx = uvkuImageFactory.TvkuImageEx;
TvkuImageFactory = uvkuImageFactory.TvkuImageFactory;
TvkuImageView = uvkuImageView.TvkuImageView;
TvkuImageViewEx = uvkuImageViewFactory.TvkuImageViewEx;
TvkuImageViewFactory = uvkuImageViewFactory.TvkuImageViewFactory;

{ Buffer }
TvkuBuffer = uvkuBuffer.TvkuBuffer;
TvkuBufferEx = uvkuBufferFactory.TvkuBufferEx;
TvkuBufferFactory = uvkuBufferFactory.TvkuBufferFactory;
TvkuBufferView = uvkuBufferView.TvkuBufferView;
TvkuBufferViewEx = uvkuBufferViewFactory.TvkuBufferViewEx;
TvkuBufferViewFactory = uvkuBufferViewFactory.TvkuBufferViewFactory;

{ Commands }
TvkuCommandPool = uvkuCommandPool.TvkuCommandPool;
TvkuCommandPoolEx = uvkuCommandPoolFactory.TvkuCommandPoolEx;
TvkuCommandPoolFactory = uvkuCommandPoolFactory.TvkuCommandPoolFactory;
TvkuCommandBuffer = uvkuCommandBuffer.TvkuCommandBuffer;

{ RenderPass }
TvkuRenderPass = uvkuRenderPass.TvkuRenderPass;
TvkuRenderPassEx = uvkuRenderPassFactory.TvkuRenderPassEx;
TvkuRenderPassFactory = uvkuRenderPassFactory.TvkuRenderPassFactory;

{ FrameBuffer }
TvkuFrameBuffer = uvkuFrameBuffer.TvkuFrameBuffer;
TvkuFrameBufferEx = uvkuFrameBufferFactory.TvkuFrameBufferEx;
TvkuFrameBufferFactory = uvkuFrameBufferFactory.TvkuFrameBufferFactory;

{ DescriptorSetLayout }
TvkuDescriptorSetLayout = uvkuDescriptorSetLayout.TvkuDescriptorSetLayout;
TvkuDescriptorSetLayoutEx = uvkuDescriptorSetLayoutFactory.TvkuDescriptorSetLayoutEx;
TvkuDescriptorSetLayoutFactory = uvkuDescriptorSetLayoutFactory.TvkuDescriptorSetLayoutFactory;

{ Pipeline }
TvkuPipelineLayout = uvkuPipelineLayout.TvkuPipelineLayout;
TvkuPipelineLayoutEx = uvkuPipelineLayoutFactory.TvkuPipelineLayoutEx;
TvkuPipelineLayoutFactory = uvkuPipelineLayoutFactory.TvkuPipelineLayoutFactory;

{ Shader Modules }
TvkuShaderModule = uvkuShaderModule.TvkuShaderModule;
TvkuShaderModuleEx = uvkuShaderModuleFactory.TvkuShaderModuleEx;
TvkuShaderModuleFactory = uvkuShaderModuleFactory.TvkuShaderModuleFactory;

{ Pipeline }
TvkuPipelineLayout = uvkuPipelineLayout.TvkuPipelineLayout;
TvkuPipelineLayoutFactory = uvkuPipelineLayoutFactory.TvkuPipelineLayoutFactory;
TvkuPipeline = uvkuPipeline.TvkuPipeline;
TvkuGraphicsPipeline = uvkuPipeline.TvkuGraphicsPipeline;
TvkuGraphicsPipelineFactory = uvkuPipelineFactory.TvkuGraphicsPipelineFactory;
TvkuComputePipeline = uvkuPipeline.TvkuComputePipeline;
TvkuComputePipelineFactory = uvkuPipelineFactory.TvkuComputePipelineFactory;

{ Utils }
TvkuException = uvkuUtils.TvkuException;
TvkuErrorException = uvkuUtils.TvkuErrorException;


+ 9
- 42
projects/utils/uvkuAllocationHandler.pas View File

@@ -11,8 +11,6 @@ uses
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuAllocationHandler = class(TObject)
private
fAllocCallbacks: PVkAllocationCallbacks;
protected
function AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; virtual;
function ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; virtual;
@@ -21,11 +19,7 @@ type
procedure InternalAllocationNotification(const aSize: VkSize; const aType: TVkInternalAllocationType; const aScope: TVkSystemAllocationScope);
procedure InternalFreeNotification(const aSize: VkSize; const aType: TVkInternalAllocationType; const aScope: TVkSystemAllocationScope);
public
function GetAllocationCallbacks: TVkAllocationCallbacks;
function GetAllocationCallbacksPtr: PVkAllocationCallbacks;

constructor Create;
destructor Destroy; override;
function MakeStructure: TVkAllocationCallbacks;
end;

implementation
@@ -94,42 +88,15 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuAllocationHandler.GetAllocationCallbacks: TVkAllocationCallbacks;
begin
result := GetAllocationCallbacksPtr^;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuAllocationHandler.GetAllocationCallbacksPtr: PVkAllocationCallbacks;
function TvkuAllocationHandler.MakeStructure: TVkAllocationCallbacks;
begin
if not Assigned(fAllocCallbacks) then begin
new(fAllocCallbacks);
FillByte(fAllocCallbacks^, SizeOf(result), 0);
fAllocCallbacks^.pUserData := self;
fAllocCallbacks^.pfnAllocation := @AllocateMemoryCallback;
fAllocCallbacks^.pfnReallocation := @ReallocateMemoryCallback;
fAllocCallbacks^.pfnFree := @FreeMemoryCallback;
fAllocCallbacks^.pfnInternalAllocation := @InternalAllocationCallback;
fAllocCallbacks^.pfnInternalFree := @InternalFreeCallback;
end;
result := fAllocCallbacks;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuAllocationHandler.Create;
begin
inherited Create;
fAllocCallbacks := nil;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuAllocationHandler.Destroy;
begin
if Assigned(fAllocCallbacks) then begin
Dispose(fAllocCallbacks);
fAllocCallbacks := nil;
end;
inherited Destroy;
FillByte(result, SizeOf(result), 0);
result.pUserData := self;
result.pfnAllocation := @AllocateMemoryCallback;
result.pfnReallocation := @ReallocateMemoryCallback;
result.pfnFree := @FreeMemoryCallback;
result.pfnInternalAllocation := @InternalAllocationCallback;
result.pfnInternalFree := @InternalFreeCallback;
end;

end.


+ 40
- 73
projects/utils/uvkuBufferFactory.pas View File

@@ -6,18 +6,9 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuBuffer, uvkuAllocationHandler, uvkuTypes, uvkuFactoryBase;
Vulkan, uvkuBuffer, uvkuTypes, uvkuFactoryBase;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuBufferEx = class(TvkuBuffer)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandle: Boolean;
public
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuBufferFactory = class(TvkuDeviceObjFactory)
private
@@ -25,25 +16,21 @@ type
fSize: VkDeviceSize;
fUsage: VkBufferUsageFlags;
fSharingMode: TVkSharingMode;
fQueueFamilyIndices: TvkuUint32Arr;

function GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
function GetQueueFamilyIndexCount: Integer;
procedure SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
fQueueFamilyIndices: TVkUint32List;
public
property Flags: VkBufferCreateFlags read fFlags write fFlags;
property Size: VkDeviceSize read fSize write fSize;
property Usage: VkBufferUsageFlags read fUsage write fUsage;
property SharingMode: TVkSharingMode read fSharingMode write fSharingMode;
property QueueFamilyIndices: TvkuUint32Arr read fQueueFamilyIndices;
property QueueFamilyIndexCount: Integer read GetQueueFamilyIndexCount;
property QueueFamilyIndex[const aIndex: Integer]: VkUint32 read GetQueueFamilyIndex write SetQueueFamilyIndex;
function CreateBuffer: TvkuBufferEx;
function CreateBuffer(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuBufferEx;
property Flags: VkBufferCreateFlags read fFlags write fFlags;
property Size: VkDeviceSize read fSize write fSize;
property Usage: VkBufferUsageFlags read fUsage write fUsage;
property SharingMode: TVkSharingMode read fSharingMode write fSharingMode;
property QueueFamilyIndices: TVkUint32List read fQueueFamilyIndices;
function GetStructure: TVkBufferCreateInfo;
procedure SetStructure(const aData: TVkBufferCreateInfo);
function CreateBuffer: TvkuBuffer;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

implementation
@@ -51,71 +38,51 @@ implementation
uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuBufferEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuBufferEx.Destroy;
begin
inherited Destroy;
if fOwnsHandle then
FreeAndNil(fAllocHandler);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuBufferFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuBufferFactory.GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
function TvkuBufferFactory.GetStructure: TVkBufferCreateInfo;
begin
if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
result := fQueueFamilyIndices[aIndex];
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.size := fSize;
result.usage := fUsage;
result.sharingMode := fSharingMode;
result.queueFamilyIndexCount := fQueueFamilyIndices.Length;
result.pQueueFamilyIndices := fQueueFamilyIndices.PData;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuBufferFactory.GetQueueFamilyIndexCount: Integer;
procedure TvkuBufferFactory.SetStructure(const aData: TVkBufferCreateInfo);
var i: Integer;
begin
result := Length(fQueueFamilyIndices);
fFlags := aData.flags;
fSize := aData.size;
fUsage := aData.usage;
fSharingMode := aData.sharingMode;
fQueueFamilyIndices.SetData(aData.pQueueFamilyIndices, aData.queueFamilyIndexCount);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuBufferFactory.SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
function TvkuBufferFactory.CreateBuffer: TvkuBuffer;
begin
if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
fQueueFamilyIndices[aIndex] := aValue;
result := TvkuBuffer.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuBufferFactory.CreateBuffer: TvkuBufferEx;
procedure TvkuBufferFactory.AfterConstruction;
begin
result := CreateBuffer(nil, false);
inherited AfterConstruction;
fQueueFamilyIndices := TVkUint32List.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuBufferFactory.CreateBuffer(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuBufferEx;
var
CreateInfo: TVkBufferCreateInfo;
procedure TvkuBufferFactory.BeforeDestruction;
begin
FillByte(CreateInfo, 0, SizeOf(CreateInfo));
CreateInfo.sType := VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.size := fSize;
CreateInfo.usage := fUsage;
CreateInfo.sharingMode := fSharingMode;
CreateInfo.queueFamilyIndexCount := Length(fQueueFamilyIndices);
CreateInfo.pQueueFamilyIndices := @fQueueFamilyIndices[0];

if Assigned(aAllocHandler)
then result := TvkuBufferEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuBufferEx.Create(CreateInfo, DeviceCommands);
try
TvkuBufferEx(result).fAllocHandler := aAllocHandler;
TvkuBufferEx(result).fOwnsHandle := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
FreeAndNil(fQueueFamilyIndices);
inherited BeforeDestruction;
end;

end.


+ 23
- 45
projects/utils/uvkuBufferViewFactory.pas View File

@@ -6,18 +6,9 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuBufferView, uvkuAllocationHandler, uvkuFactoryBase;
Vulkan, uvkuBufferView, uvkuFactoryBase;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuBufferViewEx = class(TvkuBufferView)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
public
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuBufferViewFactory = class(TvkuDeviceObjFactory)
private
@@ -33,56 +24,43 @@ type
property Offset: VkDeviceSize read fOffset write fOffset;
property Range: VkDeviceSize read fRange write fRange;

function CreateBufferView: TvkuBufferViewEx;
function CreateBufferView(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuBufferViewEx;
function GetStructure: TVkBufferViewCreateInfo;
procedure SetStructure(const aData: TVkBufferViewCreateInfo);
function CreateBufferView: TvkuBufferView;
end;

implementation

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuBufferViewEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuBufferViewFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuBufferViewEx.Destroy;
function TvkuBufferViewFactory.GetStructure: TVkBufferViewCreateInfo;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.buffer := fBuffer;
result.format := fFormat;
result.offset := fOffset;
result.range := fRange;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuBufferViewFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuBufferViewFactory.CreateBufferView: TvkuBufferViewEx;
procedure TvkuBufferViewFactory.SetStructure(const aData: TVkBufferViewCreateInfo);
begin
result := CreateBufferView(nil, false);
fFlags := aData.flags;
fBuffer := aData.buffer;
fFormat := aData.format;
fOffset := aData.offset;
fRange := aData.range;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuBufferViewFactory.CreateBufferView(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuBufferViewEx;
var
CreateInfo: TVkBufferViewCreateInfo;
function TvkuBufferViewFactory.CreateBufferView: TvkuBufferView;
begin
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.buffer := fBuffer;
CreateInfo.format := fFormat;
CreateInfo.offset := fOffset;
CreateInfo.range := fRange;

if Assigned(aAllocHandler)
then result := TvkuBufferViewEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuBufferViewEx.Create(CreateInfo, DeviceCommands);
try
TvkuBufferViewEx(result).fAllocHandler := aAllocHandler;
TvkuBufferViewEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
result := TvkuBufferView.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

end.


+ 5
- 5
projects/utils/uvkuCommandPool.pas View File

@@ -24,11 +24,11 @@ type
const aLevel: TVkCommandBufferLevel): VkCommandBuffer;
function CreateCommandBuffers(
const aLevel: TVkCommandBufferLevel;
const aCount: Integer): TvkuCommandBufferArr;
const aCount: Integer): TVkCommandBufferArr;
procedure FreeCommandBuffer(
const aBuffer: VkCommandBuffer);
procedure FreeCommandBuffers(
const aBuffers: TvkuCommandBufferArr);
const aBuffers: TVkCommandBufferArr);

constructor Create(
const aCreateInfo: TVkCommandPoolCreateInfo;
@@ -65,7 +65,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuCommandPool.CreateCommandBuffers(const aLevel: TVkCommandBufferLevel; const aCount: Integer): TvkuCommandBufferArr;
function TvkuCommandPool.CreateCommandBuffers(const aLevel: TVkCommandBufferLevel; const aCount: Integer): TVkCommandBufferArr;
var
AllocInfo: TVkCommandBufferAllocateInfo;
err: TVkResult;
@@ -85,11 +85,11 @@ end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuCommandPool.FreeCommandBuffer(const aBuffer: VkCommandBuffer);
begin
FreeCommandBuffers(TvkuCommandBufferArr.Create(aBuffer));
FreeCommandBuffers(TVkCommandBufferArr.Create(aBuffer));
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuCommandPool.FreeCommandBuffers(const aBuffers: TvkuCommandBufferArr);
procedure TvkuCommandPool.FreeCommandBuffers(const aBuffers: TVkCommandBufferArr);
begin
fDeviceCommands.vkFreeCommandBuffers(fDeviceCommands.Device, fHandle, Length(aBuffers), @aBuffers[0]);
end;


+ 17
- 40
projects/utils/uvkuCommandPoolFactory.pas View File

@@ -6,69 +6,46 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuCommandPool, uvkuAllocationHandler, uvkuFactoryBase;
Vulkan, uvkuCommandPool, uvkuFactoryBase;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuCommandPoolEx = class(TvkuCommandPool)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
public
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuCommandPoolFactory = class(TvkuDeviceObjFactory)
private
fFlags: VkCommandPoolCreateFlags;
fQueueFamilyIndex: VkUint32;
public
function CreateCommandPool: TvkuCommandPoolEx;
function CreateCommandPool(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuCommandPoolEx;
function GetStructure: TVkCommandPoolCreateInfo;
procedure SetStructure(const aData: TVkCommandPoolCreateInfo);

function CreateCommandPool: TvkuCommandPool;
end;

implementation

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuCommandPoolEx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuCommandPoolFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuCommandPoolEx.Destroy;
function TvkuCommandPoolFactory.GetStructure: TVkCommandPoolCreateInfo;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.queueFamilyIndex := fQueueFamilyIndex;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuCommandPoolFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuCommandPoolFactory.CreateCommandPool: TvkuCommandPoolEx;
procedure TvkuCommandPoolFactory.SetStructure(const aData: TVkCommandPoolCreateInfo);
begin
result := CreateCommandPool(nil, false);
fFlags := aData.flags;
fQueueFamilyIndex := aData.queueFamilyIndex;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuCommandPoolFactory.CreateCommandPool(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuCommandPoolEx;
var CreateInfo: TVkCommandPoolCreateInfo;
function TvkuCommandPoolFactory.CreateCommandPool: TvkuCommandPool;
begin
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.queueFamilyIndex := fQueueFamilyIndex;
if Assigned(aAllocHandler)
then result := TvkuCommandPoolEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuCommandPoolEx.Create(CreateInfo, DeviceCommands);
try
TvkuCommandPoolEx(result).fAllocHandler := aAllocHandler;
TvkuCommandPoolEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
result := TvkuCommandPool.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

end.


+ 85
- 57
projects/utils/uvkuDescriptorSetLayoutFactory.pas View File

@@ -6,38 +6,47 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuFactoryBase, uvkuDescriptorSetLayout, uvkuAllocationHandler, uvkuTypes;
Vulkan, uvkuFactoryBase, uvkuDescriptorSetLayout, uvkuTypes;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuDescriptorSetLayoutEx = class(TvkuDescriptorSetLayout)
TvkuDescriptorSetLayoutBinding = class(TvkuStructure)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
fImmutableSamplers: TVkSamplerList;
public
destructor Destroy; override;
Binding: VkUint32;
DescriptorType: TVkDescriptorType;
DescriptorCount: VkUint32;
StageFlags: VkShaderStageFlags;

property ImmutableSamplers: TVkSamplerList read fImmutableSamplers;

function GetStructure: TVkDescriptorSetLayoutBinding;
procedure SetStructure(const aData: TVkDescriptorSetLayoutBinding);

procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
TvkuDescriptorSetLayoutBindingArr = specialize TvkuObjList<TvkuDescriptorSetLayoutBinding>;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuDescriptorSetLayoutFactory = class(TvkuDeviceObjFactory)
private
fFlags: VkDescriptorSetLayoutCreateFlags;
fBindings: TvkuDescriptorSetLayoutBindingArr;
function GetBinding(const aIndex: Integer): TVkDescriptorSetLayoutBinding;
function GetBindingCount: Integer;
procedure SetBinding(const aIndex: Integer; aValue: TVkDescriptorSetLayoutBinding);
procedure SetBindingCount(aValue: Integer);

fvkBindings: TVkDescriptorSetLayoutBindingArr;
public
property Flags: VkDescriptorSetLayoutCreateFlags read fFlags write fFlags;
property Flags: VkDescriptorSetLayoutCreateFlags read fFlags write fFlags;
property Bindings: TvkuDescriptorSetLayoutBindingArr read fBindings;

property Bindings: TvkuDescriptorSetLayoutBindingArr read fBindings write fBindings;
property BindingCount: Integer read GetBindingCount write SetBindingCount;
property Binding[const aIndex: Integer]: TVkDescriptorSetLayoutBinding read GetBinding write SetBinding;
function GetStructure: TVkDescriptorSetLayoutCreateInfo;
procedure SetStructure(const aData: TVkDescriptorSetLayoutCreateInfo);

function CreateDescriptorSetLayout: TvkuDescriptorSetLayoutEx;
function CreateDescriptorSetLayout(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuDescriptorSetLayoutEx;
function CreateDescriptorSetLayout: TvkuDescriptorSetLayout;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

implementation
@@ -46,73 +55,92 @@ uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuDescriptorSetLayoutEx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuDescriptorSetLayoutBinding/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuDescriptorSetLayoutEx.Destroy;
function TvkuDescriptorSetLayoutBinding.GetStructure: TVkDescriptorSetLayoutBinding;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
FillByte(result, SizeOf(result), 0);
result.binding := Binding;
result.descriptorType := DescriptorType;
result.descriptorCount := DescriptorCount;
result.stageFlags := StageFlags;
result.pImmutableSamplers := fImmutableSamplers.PData;

if (fImmutableSamplers.Length <> 0) and
(fImmutableSamplers.Length <> DescriptorCount) then
raise TvkuException.Create('''ImmutableSamplers'' must be either empty or contains ''DescriptorCount'' number of elements');
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuDescriptorSetLayoutFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDescriptorSetLayoutBinding.SetStructure(const aData: TVkDescriptorSetLayoutBinding);
var i: Integer;
begin
Binding := aData.binding;
DescriptorType := aData.descriptorType;
StageFlags := aData.stageFlags;
fImmutableSamplers.SetData(aData.pImmutableSamplers, aData.descriptorCount);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDescriptorSetLayoutFactory.GetBinding(const aIndex: Integer): TVkDescriptorSetLayoutBinding;
procedure TvkuDescriptorSetLayoutBinding.AfterConstruction;
begin
if (aIndex < low(fBindings)) or (aIndex > high(fBindings)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fBindings), High(fBindings)]);
result := fBindings[aIndex];
inherited AfterConstruction;
fImmutableSamplers := TVkSamplerList.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDescriptorSetLayoutFactory.GetBindingCount: Integer;
procedure TvkuDescriptorSetLayoutBinding.BeforeDestruction;
begin
result := Length(fBindings);
FreeAndNil(fImmutableSamplers);
inherited BeforeDestruction;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDescriptorSetLayoutFactory.SetBinding(const aIndex: Integer; aValue: TVkDescriptorSetLayoutBinding);
//TvkuDescriptorSetLayoutFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDescriptorSetLayoutFactory.GetStructure: TVkDescriptorSetLayoutCreateInfo;
var i: Integer;
begin
if (aIndex < low(fBindings)) or (aIndex > high(fBindings)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fBindings), High(fBindings)]);
fBindings[aIndex] := aValue;
SetLength(fvkBindings, fBindings.Length);
for i := low(fvkBindings) to high(fvkBindings) do
fvkBindings[i] := fBindings[i].GetStructure;

FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.bindingCount := Length(fvkBindings);
result.pBindings := @fvkBindings[0];
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDescriptorSetLayoutFactory.SetBindingCount(aValue: Integer);
procedure TvkuDescriptorSetLayoutFactory.SetStructure(const aData: TVkDescriptorSetLayoutCreateInfo);
var i: Integer;
begin
SetLength(fBindings, aValue);
fFlags := aData.flags;
fBindings.Length := aData.bindingCount;
for i := 0 to fBindings.Length do
fBindings[i].SetStructure((aData.pBindings + i)^);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDescriptorSetLayoutFactory.CreateDescriptorSetLayout: TvkuDescriptorSetLayoutEx;
function TvkuDescriptorSetLayoutFactory.CreateDescriptorSetLayout: TvkuDescriptorSetLayout;
begin
result := CreateDescriptorSetLayout(nil, false);
result := TvkuDescriptorSetLayout.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDescriptorSetLayoutFactory.CreateDescriptorSetLayout(const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuDescriptorSetLayoutEx;
var
CreateInfo: TVkDescriptorSetLayoutCreateInfo;
procedure TvkuDescriptorSetLayoutFactory.AfterConstruction;
begin
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.bindingCount := Length(fBindings);
CreateInfo.pBindings := @fBindings[0];
if Assigned(aAllocHandler)
then result := TvkuDescriptorSetLayoutEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuDescriptorSetLayoutEx.Create(CreateInfo, DeviceCommands);
try
TvkuDescriptorSetLayoutEx(result).fAllocHandler := aAllocHandler;
TvkuDescriptorSetLayoutEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
inherited AfterConstruction;
fBindings := TvkuDescriptorSetLayoutBindingArr.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDescriptorSetLayoutFactory.BeforeDestruction;
begin
FreeAndNil(fBindings);
inherited BeforeDestruction;
end;

end.


+ 296
- 125
projects/utils/uvkuDeviceFactory.pas View File

@@ -6,53 +6,116 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuDevice, uvkuAllocationHandler, uvkuTypes, uvkuFactoryBase;
Vulkan, uvkuDevice, uvkuTypes, uvkuFactoryBase, uvkuUtils;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuDeviceEx = class(TvkuDevice)
TvkuQueueCreateInfo = class(TvkuStructure)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
fQueuePriorities: TVkFloatList;
public
destructor Destroy; override;
Flags: VkDeviceQueueCreateFlags;
QueueFamilyIndex: VkUint32;

property QueuePriorities: TVkFloatList read fQueuePriorities;

function GetStructure: TVkDeviceQueueCreateInfo;
procedure SetStructure(const aData: TVkDeviceQueueCreateInfo);

procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
TvkuQueueCreateInfoList = specialize TvkuObjList<TvkuQueueCreateInfo>;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuPhysicalDeviceFeatures = class(TvkuStructure)
RobustBufferAccess: VkBool32;
FullDrawIndexUint32: VkBool32;
ImageCubeArray: VkBool32;
IndependentBlend: VkBool32;
GeometryShader: VkBool32;
TessellationShader: VkBool32;
SampleRateShading: VkBool32;
DualSrcBlend: VkBool32;
LogicOp: VkBool32;
MultiDrawIndirect: VkBool32;
DrawIndirectFirstInstance: VkBool32;
DepthClamp: VkBool32;
DepthBiasClamp: VkBool32;
FillModeNonSolid: VkBool32;
DepthBounds: VkBool32;
WideLines: VkBool32;
LargePoints: VkBool32;
AlphaToOne: VkBool32;
MultiViewport: VkBool32;
SamplerAnisotropy: VkBool32;
TextureCompressionETC2: VkBool32;
TextureCompressionASTC_LDR: VkBool32;
TextureCompressionBC: VkBool32;
OcclusionQueryPrecise: VkBool32;
PipelineStatisticsQuery: VkBool32;
VertexPipelineStoresAndAtomics: VkBool32;
FragmentStoresAndAtomics: VkBool32;
ShaderTessellationAndGeometryPointSize: VkBool32;
ShaderImageGatherExtended: VkBool32;
ShaderStorageImageExtendedFormats: VkBool32;
ShaderStorageImageMultisample: VkBool32;
ShaderStorageImageReadWithoutFormat: VkBool32;
ShaderStorageImageWriteWithoutFormat: VkBool32;
ShaderUniformBufferArrayDynamicIndexing: VkBool32;
ShaderSampledImageArrayDynamicIndexing: VkBool32;
ShaderStorageBufferArrayDynamicIndexing: VkBool32;
ShaderStorageImageArrayDynamicIndexing: VkBool32;
ShaderClipDistance: VkBool32;
ShaderCullDistance: VkBool32;
ShaderFloat64: VkBool32;
ShaderInt64: VkBool32;
ShaderInt16: VkBool32;
ShaderResourceResidency: VkBool32;
ShaderResourceMinLod: VkBool32;
SparseBinding: VkBool32;
SparseResidencyBuffer: VkBool32;
SparseResidencyImage2D: VkBool32;
SparseResidencyImage3D: VkBool32;
SparseResidency2Samples: VkBool32;
SparseResidency4Samples: VkBool32;
SparseResidency8Samples: VkBool32;
SparseResidency16Samples: VkBool32;
SparseResidencyAliased: VkBool32;
VariableMultisampleRate: VkBool32;
InheritedQueries: VkBool32;

function GetStructure: TVkPhysicalDeviceFeatures;
procedure SetStructure(const aData: TVkPhysicalDeviceFeatures);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuDeviceFactory = class(TvkuInstanceObjFactory)
private
fFeatures: TVkPhysicalDeviceFeatures;
fFlags: VkDeviceCreateFlags;
fLayers: TStringList;
fExtensions: TStringList;
fQueueCreateInfos: TvkuQueueCreateInfoArr;
fEnabledFeatures: TvkuPhysicalDeviceFeatures;
fFlags: VkDeviceCreateFlags;
fEnabledLayerNames: TStringList;
fEnabledExtensionNames: TStringList;
fQueueCreateInfos: TvkuQueueCreateInfoList;

fvkEnabledFeatures: TVkPhysicalDeviceFeatures;
fvkEnabledLayerNames: array of PVkChar;
fvkEnabledExtensionNames: array of PVkChar;
fvkQueueCreateInfos: array of TVkDeviceQueueCreateInfo;

function GetLayers: TStrings;
function GetExtensions: TStrings;
public
property Flags: VkDeviceCreateFlags read fFlags write fFlags;
property EnabledLayers: TStrings read GetLayers;
property EnabledExtensions: TStrings read GetExtensions;
property EnabledFeatures: TvkuPhysicalDeviceFeatures read fEnabledFeatures;
property QueueCreateInfos: TvkuQueueCreateInfoList read fQueueCreateInfos;

function GetQueueCreateInfoCount: Integer;
function GetQueueCreateInfo(const aIndex: Integer): TvkuQueueCreateInfo;
function GetQueueCreateInfos: TvkuQueueCreateInfoArr;
function GetStructure: TVkDeviceCreateInfo;
procedure SetStructure(const aData: TVkDeviceCreateInfo);

procedure SetQueueCreateInfoCount(aValue: Integer);
procedure SetQueueCreateInfo(const aIndex: Integer; aValue: TvkuQueueCreateInfo);
procedure SetQueueCreateInfos(aValue: TvkuQueueCreateInfoArr);
public
property Flags: VkDeviceCreateFlags read fFlags write fFlags;
property EnabledLayers: TStrings read GetLayers;
property EnabledExtensions: TStrings read GetExtensions;
property EnabledFeatures: TVkPhysicalDeviceFeatures read fFeatures;

property QueueCreateInfos: TvkuQueueCreateInfoArr read GetQueueCreateInfos write SetQueueCreateInfos;
property QueueCreateInfoCount: Integer read GetQueueCreateInfoCount write SetQueueCreateInfoCount;
property QueueCreateInfo[const aIndex: Integer]: TvkuQueueCreateInfo read GetQueueCreateInfo write SetQueueCreateInfo;

function CreateDevice(
const aPhysicalDevice: VkPhysicalDevice): TvkuDeviceEx;
function CreateDevice(
const aPhysicalDevice: VkPhysicalDevice;
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuDeviceEx;
function CreateDevice(const aPhysicalDevice: VkPhysicalDevice): TvkuDevice;

procedure AfterConstruction; override;
procedure BeforeDestruction; override;
@@ -60,153 +123,261 @@ type

implementation

uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuDeviceEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuQueueCreateInfo////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuDeviceEx.Destroy;
function TvkuQueueCreateInfo.GetStructure: TVkDeviceQueueCreateInfo;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
result.pNext := nil;
result.flags := Flags;
result.queueFamilyIndex := QueueFamilyIndex;
result.queueCount := fQueuePriorities.Length;
result.pQueuePriorities := fQueuePriorities.PData;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuDeviceFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.GetLayers: TStrings;
procedure TvkuQueueCreateInfo.SetStructure(const aData: TVkDeviceQueueCreateInfo);
var i: Integer;
begin
result := fLayers;
Flags := aData.flags;
QueueFamilyIndex := aData.queueFamilyIndex;
fQueuePriorities.Length := aData.queueCount;
for i := 0 to fQueuePriorities.Length-1 do
fQueuePriorities[i] := (aData.pQueuePriorities + i)^;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.GetExtensions: TStrings;
procedure TvkuQueueCreateInfo.AfterConstruction;
begin
result := fExtensions;
inherited AfterConstruction;
fQueuePriorities := TVkFloatList.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.GetQueueCreateInfoCount: Integer;
procedure TvkuQueueCreateInfo.BeforeDestruction;
begin
result := Length(fQueueCreateInfos);
FreeAndNil(fQueuePriorities);
inherited BeforeDestruction;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.GetQueueCreateInfo(const aIndex: Integer): TvkuQueueCreateInfo;
//TvkuPhysicalDeviceFeatures/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDeviceFeatures.GetStructure: TVkPhysicalDeviceFeatures;
begin
if (aIndex < low(fQueueCreateInfos)) or (aIndex > high(fQueueCreateInfos)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueCreateInfos), High(fQueueCreateInfos)]);
result := fQueueCreateInfos[aIndex];
FillByte(result, SizeOf(result), 0);
result.robustBufferAccess := RobustBufferAccess;
result.fullDrawIndexUint32 := FullDrawIndexUint32;
result.imageCubeArray := ImageCubeArray;
result.independentBlend := IndependentBlend;
result.geometryShader := GeometryShader;
result.tessellationShader := TessellationShader;
result.sampleRateShading := SampleRateShading;
result.dualSrcBlend := DualSrcBlend;
result.logicOp := LogicOp;
result.multiDrawIndirect := MultiDrawIndirect;
result.drawIndirectFirstInstance := DrawIndirectFirstInstance;
result.depthClamp := DepthClamp;
result.depthBiasClamp := DepthBiasClamp;
result.fillModeNonSolid := FillModeNonSolid;
result.depthBounds := DepthBounds;
result.wideLines := WideLines;
result.largePoints := LargePoints;
result.alphaToOne := AlphaToOne;
result.multiViewport := MultiViewport;
result.samplerAnisotropy := SamplerAnisotropy;
result.textureCompressionETC2 := TextureCompressionETC2;
result.textureCompressionASTC_LDR := TextureCompressionASTC_LDR;
result.textureCompressionBC := TextureCompressionBC;
result.occlusionQueryPrecise := OcclusionQueryPrecise;
result.pipelineStatisticsQuery := PipelineStatisticsQuery;
result.vertexPipelineStoresAndAtomics := VertexPipelineStoresAndAtomics;
result.fragmentStoresAndAtomics := FragmentStoresAndAtomics;
result.shaderTessellationAndGeometryPointSize := ShaderTessellationAndGeometryPointSize;
result.shaderImageGatherExtended := ShaderImageGatherExtended;
result.shaderStorageImageExtendedFormats := ShaderStorageImageExtendedFormats;
result.shaderStorageImageMultisample := ShaderStorageImageMultisample;
result.shaderStorageImageReadWithoutFormat := ShaderStorageImageReadWithoutFormat;
result.shaderStorageImageWriteWithoutFormat := ShaderStorageImageWriteWithoutFormat;
result.shaderUniformBufferArrayDynamicIndexing := ShaderUniformBufferArrayDynamicIndexing;
result.shaderSampledImageArrayDynamicIndexing := ShaderSampledImageArrayDynamicIndexing;
result.shaderStorageBufferArrayDynamicIndexing := ShaderStorageBufferArrayDynamicIndexing;
result.shaderStorageImageArrayDynamicIndexing := ShaderStorageImageArrayDynamicIndexing;
result.shaderClipDistance := ShaderClipDistance;
result.shaderCullDistance := ShaderCullDistance;
result.shaderFloat64 := ShaderFloat64;
result.shaderInt64 := ShaderInt64;
result.shaderInt16 := ShaderInt16;
result.shaderResourceResidency := ShaderResourceResidency;
result.shaderResourceMinLod := ShaderResourceMinLod;
result.sparseBinding := SparseBinding;
result.sparseResidencyBuffer := SparseResidencyBuffer;
result.sparseResidencyImage2D := SparseResidencyImage2D;
result.sparseResidencyImage3D := SparseResidencyImage3D;
result.sparseResidency2Samples := SparseResidency2Samples;
result.sparseResidency4Samples := SparseResidency4Samples;
result.sparseResidency8Samples := SparseResidency8Samples;
result.sparseResidency16Samples := SparseResidency16Samples;
result.sparseResidencyAliased := SparseResidencyAliased;
result.variableMultisampleRate := VariableMultisampleRate;
result.inheritedQueries := InheritedQueries;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.GetQueueCreateInfos: TvkuQueueCreateInfoArr;
procedure TvkuPhysicalDeviceFeatures.SetStructure(const aData: TVkPhysicalDeviceFeatures);
begin
result := fQueueCreateInfos;
RobustBufferAccess := aData.robustBufferAccess;
FullDrawIndexUint32 := aData.fullDrawIndexUint32;
ImageCubeArray := aData.imageCubeArray;
IndependentBlend := aData.independentBlend;
GeometryShader := aData.geometryShader;
TessellationShader := aData.tessellationShader;
SampleRateShading := aData.sampleRateShading;
DualSrcBlend := aData.dualSrcBlend;
LogicOp := aData.logicOp;
MultiDrawIndirect := aData.multiDrawIndirect;
DrawIndirectFirstInstance := aData.drawIndirectFirstInstance;
DepthClamp := aData.depthClamp;
DepthBiasClamp := aData.depthBiasClamp;
FillModeNonSolid := aData.fillModeNonSolid;
DepthBounds := aData.depthBounds;
WideLines := aData.wideLines;
LargePoints := aData.largePoints;
AlphaToOne := aData.alphaToOne;
MultiViewport := aData.multiViewport;
SamplerAnisotropy := aData.samplerAnisotropy;
TextureCompressionETC2 := aData.textureCompressionETC2;
TextureCompressionASTC_LDR := aData.textureCompressionASTC_LDR;
TextureCompressionBC := aData.textureCompressionBC;
OcclusionQueryPrecise := aData.occlusionQueryPrecise;
PipelineStatisticsQuery := aData.pipelineStatisticsQuery;
VertexPipelineStoresAndAtomics := aData.vertexPipelineStoresAndAtomics;
FragmentStoresAndAtomics := aData.fragmentStoresAndAtomics;
ShaderTessellationAndGeometryPointSize := aData.shaderTessellationAndGeometryPointSize;
ShaderImageGatherExtended := aData.shaderImageGatherExtended;
ShaderStorageImageExtendedFormats := aData.shaderStorageImageExtendedFormats;
ShaderStorageImageMultisample := aData.shaderStorageImageMultisample;
ShaderStorageImageReadWithoutFormat := aData.shaderStorageImageReadWithoutFormat;
ShaderStorageImageWriteWithoutFormat := aData.shaderStorageImageWriteWithoutFormat;
ShaderUniformBufferArrayDynamicIndexing := aData.shaderUniformBufferArrayDynamicIndexing;
ShaderSampledImageArrayDynamicIndexing := aData.shaderSampledImageArrayDynamicIndexing;
ShaderStorageBufferArrayDynamicIndexing := aData.shaderStorageBufferArrayDynamicIndexing;
ShaderStorageImageArrayDynamicIndexing := aData.shaderStorageImageArrayDynamicIndexing;
ShaderClipDistance := aData.shaderClipDistance;
ShaderCullDistance := aData.shaderCullDistance;
ShaderFloat64 := aData.shaderFloat64;
ShaderInt64 := aData.shaderInt64;
ShaderInt16 := aData.shaderInt16;
ShaderResourceResidency := aData.shaderResourceResidency;
ShaderResourceMinLod := aData.shaderResourceMinLod;
SparseBinding := aData.sparseBinding;
SparseResidencyBuffer := aData.sparseResidencyBuffer;
SparseResidencyImage2D := aData.sparseResidencyImage2D;
SparseResidencyImage3D := aData.sparseResidencyImage3D;
SparseResidency2Samples := aData.sparseResidency2Samples;
SparseResidency4Samples := aData.sparseResidency4Samples;
SparseResidency8Samples := aData.sparseResidency8Samples;
SparseResidency16Samples := aData.sparseResidency16Samples;
SparseResidencyAliased := aData.sparseResidencyAliased;
VariableMultisampleRate := aData.variableMultisampleRate;
InheritedQueries := aData.inheritedQueries;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDeviceFactory.SetQueueCreateInfoCount(aValue: Integer);
//TvkuDeviceFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.GetLayers: TStrings;
begin
if (aValue < 0) then
aValue := 0;
SetLength(fQueueCreateInfos, aValue);
result := fEnabledLayerNames;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDeviceFactory.SetQueueCreateInfo(const aIndex: Integer; aValue: TvkuQueueCreateInfo);
function TvkuDeviceFactory.GetExtensions: TStrings;
begin
if (aIndex < low(fQueueCreateInfos)) or (aIndex > high(fQueueCreateInfos)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueCreateInfos), High(fQueueCreateInfos)]);
fQueueCreateInfos[aIndex] := aValue;
result := fEnabledExtensionNames;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDeviceFactory.SetQueueCreateInfos(aValue: TvkuQueueCreateInfoArr);
function TvkuDeviceFactory.GetStructure: TVkDeviceCreateInfo;
var i: Integer;
begin
fQueueCreateInfos := aValue;
if (fQueueCreateInfos.Length <= 0) then
raise TvkuException.Create('no queue create infos assigned');

fvkEnabledFeatures := fEnabledFeatures.GetStructure;

SetLength(fvkEnabledLayerNames, fEnabledLayerNames.Count);
for i := 0 to fEnabledLayerNames.Count-1 do
fvkEnabledLayerNames[i] := PVkChar(fEnabledLayerNames[i]);

SetLength(fvkEnabledExtensionNames, fEnabledExtensionNames.Count);
for i := 0 to fEnabledExtensionNames.Count-1 do
fvkEnabledExtensionNames[i] := PVkChar(fEnabledExtensionNames[i]);

SetLength(fvkQueueCreateInfos, fQueueCreateInfos.Length);
for i := low(fvkQueueCreateInfos) to high(fvkQueueCreateInfos) do
fvkQueueCreateInfos[i] := fQueueCreateInfos[i].GetStructure;

FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.queueCreateInfoCount := Length(fvkQueueCreateInfos);
result.pQueueCreateInfos := @fvkQueueCreateInfos[0];
result.enabledLayerCount := Length(fvkEnabledLayerNames);
result.ppEnabledLayerNames := @fvkEnabledLayerNames[0];
result.enabledExtensionCount := Length(fvkEnabledExtensionNames);
result.ppEnabledExtensionNames := @fvkEnabledExtensionNames[0];
result.pEnabledFeatures := @fvkEnabledFeatures;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice): TvkuDeviceEx;
procedure TvkuDeviceFactory.SetStructure(const aData: TVkDeviceCreateInfo);
var i: Integer;
begin
result := CreateDevice(aPhysicalDevice, nil, false);
if Assigned(aData.pEnabledFeatures) then
fEnabledFeatures.SetStructure(aData.pEnabledFeatures^);

fEnabledLayerNames.Clear;
for i := 0 to aData.enabledLayerCount-1 do
fEnabledLayerNames.Add(aData.ppEnabledLayerNames[i]);

fEnabledExtensionNames.Clear;
for i := 0 to aData.enabledExtensionCount-1 do
fEnabledExtensionNames.Add(aData.ppEnabledExtensionNames[i]);

fQueueCreateInfos.Length := aData.queueCreateInfoCount;
for i := 0 to fQueueCreateInfos.Length-1 do
fQueueCreateInfos[i].SetStructure((aData.pQueueCreateInfos + i)^);

fFlags := aData.flags;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice;
const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuDeviceEx;
var
CreateInfo: TVkDeviceCreateInfo;
QueueInfos: array of TVkDeviceQueueCreateInfo;
lay: array of PVkChar;
ext: array of PVkChar;
i: Integer;
function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice): TvkuDevice;
begin
if (Length(fQueueCreateInfos) <= 0) then
raise TvkuException.Create('no queue create infos assigned');

SetLength(lay, fLayers.Count);
for i := 0 to fLayers.Count-1 do
lay[i] := PVkChar(fLayers[i]);

SetLength(ext, fExtensions.Count);
for i := 0 to fExtensions.Count-1 do
ext[i] := PVkChar(fExtensions[i]);

SetLength(QueueInfos, Length(fQueueCreateInfos));
for i := 0 to high(fQueueCreateInfos) do begin
FillByte(QueueInfos[i], SizeOf(QueueInfos[0]), 0);
QueueInfos[i].sType := VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
QueueInfos[i].pNext := nil;
QueueInfos[i].flags := fQueueCreateInfos[i].Flags;
QueueInfos[i].queueFamilyIndex := fQueueCreateInfos[i].FamilyIndex;
QueueInfos[i].queueCount := Length(fQueueCreateInfos[i].Priorities);
if (QueueInfos[i].queueCount > 0)
then QueueInfos[i].pQueuePriorities := @fQueueCreateInfos[i].Priorities[0]
else QueueInfos[i].pQueuePriorities := nil;
end;

FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.queueCreateInfoCount := Length(QueueInfos);
CreateInfo.pQueueCreateInfos := @QueueInfos[0];
CreateInfo.enabledLayerCount := Length(lay);
CreateInfo.ppEnabledLayerNames := @lay[0];
CreateInfo.enabledExtensionCount := Length(ext);
CreateInfo.ppEnabledExtensionNames := @ext[0];
CreateInfo.pEnabledFeatures := @fFeatures;

if Assigned(aAllocHandler)
then result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, InstanceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, InstanceCommands);
try
TvkuDeviceEx(result).fAllocHandler := aAllocHandler;
TvkuDeviceEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
result := TvkuDevice.Create(aPhysicalDevice, GetStructure, InstanceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDeviceFactory.AfterConstruction;
begin
inherited AfterConstruction;
FillByte(fFeatures, SizeOf(fFeatures), 0);
fLayers := TStringList.Create;
fExtensions := TStringList.Create;
fEnabledFeatures := TvkuPhysicalDeviceFeatures.Create;
fEnabledLayerNames := TStringList.Create;
fEnabledExtensionNames := TStringList.Create;
fQueueCreateInfos := TvkuQueueCreateInfoList.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDeviceFactory.BeforeDestruction;
begin
FreeAndNil(fLayers);
FreeAndNil(fExtensions);
FreeAndNil(fQueueCreateInfos);
FreeAndNil(fEnabledLayerNames);
FreeAndNil(fEnabledExtensionNames);
FreeAndNil(fEnabledFeatures);
inherited BeforeDestruction;
end;



+ 61
- 2
projects/utils/uvkuFactoryBase.pas View File

@@ -6,11 +6,29 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuInstance, uvkuDevice;
Vulkan, uvkuInstance, uvkuDevice, uvkuAllocationHandler;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuFactory = class(TObject)
TvkuStructure = class
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuFactory = class(TvkuStructure)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsAllocCallbacks: Boolean;
fAllocCallbacks: PVkAllocationCallbacks;

procedure FreeAllocCallbacks;

procedure SetAllocCallbacks(aValue: PVkAllocationCallbacks);
procedure SetAllocHandler(aValue: TvkuAllocationHandler);
public
property AllocHandler: TvkuAllocationHandler read fAllocHandler write SetAllocHandler;
property AllocCallbacks: PVkAllocationCallbacks read fAllocCallbacks write SetAllocCallbacks;

destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -37,6 +55,47 @@ type

implementation

uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuFactory////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuFactory.FreeAllocCallbacks;
begin
if Assigned(fAllocCallbacks) and fOwnsAllocCallbacks then
Dispose(fAllocCallbacks);
fAllocCallbacks := nil;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuFactory.SetAllocCallbacks(aValue: PVkAllocationCallbacks);
begin
fAllocHandler := nil;
FreeAllocCallbacks;
fAllocCallbacks := aValue;
fOwnsAllocCallbacks := false;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuFactory.SetAllocHandler(aValue: TvkuAllocationHandler);
begin
FreeAllocCallbacks;
fAllocHandler := aValue;
if Assigned(fAllocHandler) then begin
new(fAllocCallbacks);
fOwnsAllocCallbacks := true;
fAllocCallbacks^ := fAllocHandler.MakeStructure;
end;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuFactory.Destroy;
begin
FreeAllocCallbacks;
inherited Destroy;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuInstanceObjFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 36
- 72
projects/utils/uvkuFrameBufferFactory.pas View File

@@ -6,18 +6,9 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuFrameBuffer, uvkuFactoryBase, uvkuAllocationHandler, uvkuTypes;
Vulkan, uvkuFrameBuffer, uvkuFactoryBase, uvkuTypes;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuFrameBufferEx = class(TvkuFrameBuffer)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
public
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuFrameBufferFactory = class(TvkuDeviceObjFactory)
private
@@ -26,26 +17,22 @@ type
fWidth: VkUint32;
fHeight: VkUint32;
fLayers: VkUint32;
fAttachments: TvkuImageViewArr;
function GetAttachment(const aIndex: Integer): VkImageView;
function GetAttachmentCount: Integer;
procedure SetAttachment(const aIndex: Integer; aValue: VkImageView);
procedure SetAttachmentCount(aValue: Integer);
fAttachments: TVkImageViewList;
public
property Flags: VkFramebufferCreateFlags read fFlags write fFlags;
property RenderPass: VkRenderPass read fRenderPass write fRenderPass;
property Width: VkUint32 read fWidth write fWidth;
property Height: VkUint32 read fHeight write fHeight;
property Layers: VkUint32 read fLayers write fLayers;
property Attachments: TVkImageViewList read fAttachments;

function GetStructure: TVkFramebufferCreateInfo;
procedure SetStructure(const aData: TVkFramebufferCreateInfo);

property Attachments: TvkuImageViewArr read fAttachments write fAttachments;
property AttachmentCount: Integer read GetAttachmentCount write SetAttachmentCount;
property Attachment[const aIndex: Integer]: VkImageView read GetAttachment write SetAttachment;
function CreateFrameBuffer: TvkuFrameBuffer;

function CreateFrameBuffer: TvkuFrameBufferEx;
function CreateFrameBuffer(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuFrameBufferEx;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

implementation
@@ -53,77 +40,54 @@ implementation
uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuFrameBufferEx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuFrameBufferEx.Destroy;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuFrameBufferFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuFrameBufferFactory.GetAttachment(const aIndex: Integer): VkImageView;
begin
if (aIndex < low(fAttachments)) or (aIndex > high(fAttachments)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fAttachments), High(fAttachments)]);
result := fAttachments[aIndex];
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuFrameBufferFactory.GetAttachmentCount: Integer;
function TvkuFrameBufferFactory.GetStructure: TVkFramebufferCreateInfo;
begin
result := Length(fAttachments);
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.renderPass := fRenderPass;
result.attachmentCount := fAttachments.Length;
result.pAttachments := fAttachments.PData;
result.width := fWidth;
result.height := fHeight;
result.layers := fLayers;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuFrameBufferFactory.SetAttachment(const aIndex: Integer; aValue: VkImageView);
procedure TvkuFrameBufferFactory.SetStructure(const aData: TVkFramebufferCreateInfo);
var i: Integer;
begin
if (aIndex < low(fAttachments)) or (aIndex > high(fAttachments)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fAttachments), High(fAttachments)]);
fAttachments[aIndex] := aValue;
fFlags := aData.flags;
fRenderPass := aData.renderPass;
fWidth := aData.width;
fHeight := aData.height;
fLayers := aData.layers;
fAttachments.SetData(aData.pAttachments, aData.attachmentCount);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuFrameBufferFactory.SetAttachmentCount(aValue: Integer);
function TvkuFrameBufferFactory.CreateFrameBuffer: TvkuFrameBuffer;
begin
SetLength(fAttachments, aValue);
result := TvkuFrameBuffer.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuFrameBufferFactory.CreateFrameBuffer: TvkuFrameBufferEx;
procedure TvkuFrameBufferFactory.AfterConstruction;
begin
result := CreateFrameBuffer(nil, false);
inherited AfterConstruction;
fAttachments := TVkImageViewList.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuFrameBufferFactory.CreateFrameBuffer(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuFrameBufferEx;
var
CreateInfo: TVkFramebufferCreateInfo;
procedure TvkuFrameBufferFactory.BeforeDestruction;
begin
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.renderPass := fRenderPass;
CreateInfo.attachmentCount := Length(fAttachments);
CreateInfo.pAttachments := @fAttachments[0];
CreateInfo.width := fWidth;
CreateInfo.height := fHeight;
CreateInfo.layers := fLayers;
if Assigned(aAllocHandler)
then result := TvkuFrameBufferEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuFrameBufferEx.Create(CreateInfo, DeviceCommands);
try
TvkuFrameBufferEx(result).fAllocHandler := aAllocHandler;
TvkuFrameBufferEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
FreeAndNil(fAttachments);
inherited BeforeDestruction;
end;

end.


+ 62
- 87
projects/utils/uvkuImageFactory.pas View File

@@ -6,18 +6,9 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuImage, uvkuAllocationHandler, uvkuTypes, uvkuFactoryBase;
Vulkan, uvkuImage, uvkuTypes, uvkuFactoryBase;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuImageEx = class(TvkuImage)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandle: Boolean;
public
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuImageFactory = class(TvkuDeviceObjFactory)
private
@@ -31,33 +22,29 @@ type
fTiling: TVkImageTiling;
fUsage: VkImageUsageFlags;
fSharingMode: TVkSharingMode;
fQueueFamilyIndices: TvkuUint32Arr;
fQueueFamilyIndices: TVkUint32List;
fInitialLayout: TVkImageLayout;

function GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
function GetQueueFamilyIndexCount: Integer;
procedure SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
public
property Flags: VkImageCreateFlags read fFlags write fFlags;
property ImageType: TVkImageType read fImageType write fImageType;
property Format: TVkFormat read fFormat write fFormat;
property Extent: TVkExtent3D read fExtent write fExtent;
property MipLevels: VkUint32 read fMipLevels write fMipLevels;
property ArrayLayers: VkUint32 read fArrayLayers write fArrayLayers;
property Samples: TVkSampleCountFlagBits read fSamples write fSamples;
property Tiling: TVkImageTiling read fTiling write fTiling;
property Usage: VkImageUsageFlags read fUsage write fUsage;
property SharingMode: TVkSharingMode read fSharingMode write fSharingMode;
property InitialLayout: TVkImageLayout read fInitialLayout write fInitialLayout;
property QueueFamilyIndices: TvkuUint32Arr read fQueueFamilyIndices;
property QueueFamilyIndexCount: Integer read GetQueueFamilyIndexCount;
property QueueFamilyIndex[const aIndex: Integer]: VkUint32 read GetQueueFamilyIndex write SetQueueFamilyIndex;
function CreateImage: TvkuImageEx;
function CreateImage(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuImageEx;
property Flags: VkImageCreateFlags read fFlags write fFlags;
property ImageType: TVkImageType read fImageType write fImageType;
property Format: TVkFormat read fFormat write fFormat;
property Extent: TVkExtent3D read fExtent write fExtent;
property MipLevels: VkUint32 read fMipLevels write fMipLevels;
property ArrayLayers: VkUint32 read fArrayLayers write fArrayLayers;
property Samples: TVkSampleCountFlagBits read fSamples write fSamples;
property Tiling: TVkImageTiling read fTiling write fTiling;
property Usage: VkImageUsageFlags read fUsage write fUsage;
property SharingMode: TVkSharingMode read fSharingMode write fSharingMode;
property InitialLayout: TVkImageLayout read fInitialLayout write fInitialLayout;
property QueueFamilyIndices: TVkUint32List read fQueueFamilyIndices;
function GetStructure: TVkImageCreateInfo;
procedure SetStructure(const aData: TVkImageCreateInfo);
function CreateImage: TvkuImage;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

implementation
@@ -65,78 +52,66 @@ implementation
uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuImageEx////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuImageEx.Destroy;
begin
inherited Destroy;
if fOwnsHandle then
FreeAndNil(fAllocHandler);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuImageFactory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuImageFactory.GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
function TvkuImageFactory.GetStructure: TVkImageCreateInfo;
begin
if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
result := fQueueFamilyIndices[aIndex];
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.imageType := fImageType;
result.format := fFormat;
result.extent := fExtent;
result.mipLevels := fMipLevels;
result.arrayLayers := fArrayLayers;
result.samples := fSamples;
result.tiling := fTiling;
result.usage := fUsage;
result.sharingMode := fSharingMode;
result.queueFamilyIndexCount := fQueueFamilyIndices.Length;
result.pQueueFamilyIndices := fQueueFamilyIndices.PData;
result.initialLayout := fInitialLayout;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuImageFactory.GetQueueFamilyIndexCount: Integer;
procedure TvkuImageFactory.SetStructure(const aData: TVkImageCreateInfo);
var i: Integer;
begin
result := Length(fQueueFamilyIndices);
fFlags := aData.flags;
fImageType := aData.imageType;
fFormat := aData.format;
fExtent := aData.extent;
fMipLevels := aData.mipLevels;
fArrayLayers := aData.arrayLayers;
fSamples := aData.samples;
fTiling := aData.tiling;
fUsage := aData.usage;
fSharingMode := aData.sharingMode;
fInitialLayout := aData.initialLayout;

fQueueFamilyIndices.SetData(aData.pQueueFamilyIndices, aData.queueFamilyIndexCount);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuImageFactory.SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
function TvkuImageFactory.CreateImage: TvkuImage;
begin
if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
fQueueFamilyIndices[aIndex] := aValue;
result := TvkuImage.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuImageFactory.CreateImage: TvkuImageEx;
procedure TvkuImageFactory.AfterConstruction;
begin
result := CreateImage(nil, false);
inherited AfterConstruction;
fQueueFamilyIndices := TVkUint32List.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuImageFactory.CreateImage(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuImageEx;
var
CreateInfo: TVkImageCreateInfo;
procedure TvkuImageFactory.BeforeDestruction;
begin
FillByte(CreateInfo, 0, SizeOf(CreateInfo));
CreateInfo.sType := VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.imageType := fImageType;
CreateInfo.format := fFormat;
CreateInfo.extent := fExtent;
CreateInfo.mipLevels := fMipLevels;
CreateInfo.arrayLayers := fArrayLayers;
CreateInfo.samples := fSamples;
CreateInfo.tiling := fTiling;
CreateInfo.usage := fUsage;
CreateInfo.sharingMode := fSharingMode;
CreateInfo.queueFamilyIndexCount := Length(fQueueFamilyIndices);
CreateInfo.pQueueFamilyIndices := @fQueueFamilyIndices[0];
CreateInfo.initialLayout := fInitialLayout;

if Assigned(aAllocHandler)
then result := TvkuImageEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuImageEx.Create(CreateInfo, DeviceCommands);
try
TvkuImageEx(result).fAllocHandler := aAllocHandler;
TvkuImageEx(result).fOwnsHandle := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
FreeAndNil(fQueueFamilyIndices);
inherited BeforeDestruction;
end;

end.


+ 74
- 41
projects/utils/uvkuImageViewFactory.pas View File

@@ -6,16 +6,19 @@ interface

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

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuImageViewEx = class(TvkuImageView)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
public
destructor Destroy; override;
TvkuImageSubresourceRange = class(TvkuStructure)
AspectMask: VkImageAspectFlags;
BaseMipLevel: VkUint32;
LevelCount: VkUint32;
BaseArrayLayer: VkUint32;
LayerCount: VkUint32;

function GetStructure: TVkImageSubresourceRange;
procedure SetStructure(const aData: TVkImageSubresourceRange);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -26,64 +29,94 @@ type
fViewType: TVkImageViewType;
fFormat: TVkFormat;
fComponents: TVkComponentMapping;
fSubresourceRange: TVkImageSubresourceRange;
fSubresourceRange: TvkuImageSubresourceRange;
public
property Flags: VkImageViewCreateFlags read fFlags write fFlags;
property Image: VkImage read fImage write fImage;
property ViewType: TVkImageViewType read fViewType write fViewType;
property Format: TVkFormat read fFormat write fFormat;
property Components: TVkComponentMapping read fComponents write fComponents;
property SubresourceRange: TVkImageSubresourceRange read fSubresourceRange write fSubresourceRange;
property SubresourceRange: TvkuImageSubresourceRange read fSubresourceRange;

function CreateImageView: TvkuImageViewEx;
function CreateImageView(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuImageViewEx;
function GetStructure: TVkImageViewCreateInfo;
procedure SetStructure(const aData: TVkImageViewCreateInfo);

function CreateImageView: TvkuImageView;

procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

implementation

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuImageViewEx////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuImageSubresourceRange//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuImageViewEx.Destroy;
function TvkuImageSubresourceRange.GetStructure: TVkImageSubresourceRange;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
FillByte(result, SizeOf(result), 0);
result.aspectMask := AspectMask;
result.baseMipLevel := BaseMipLevel;
result.levelCount := LevelCount;
result.baseArrayLayer := BaseArrayLayer;
result.layerCount := LayerCount;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuImageSubresourceRange.SetStructure(const aData: TVkImageSubresourceRange);
begin
AspectMask := aData.aspectMask;
BaseMipLevel := aData.baseMipLevel;
LevelCount := aData.levelCount;
BaseArrayLayer := aData.baseArrayLayer;
LayerCount := aData.layerCount;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuImageViewFactory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuImageViewFactory.CreateImageView: TvkuImageViewEx;
function TvkuImageViewFactory.GetStructure: TVkImageViewCreateInfo;
begin
result := CreateImageView(nil, false);
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.image := fImage;
result.viewType := fViewType;
result.format := fFormat;
result.components := fComponents;
result.subresourceRange := fSubresourceRange.GetStructure;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuImageViewFactory.CreateImageView(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuImageViewEx;
var CreateInfo: TVkImageViewCreateInfo;
procedure TvkuImageViewFactory.SetStructure(const aData: TVkImageViewCreateInfo);
begin
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.image := fImage;
CreateInfo.viewType := fViewType;
CreateInfo.format := fFormat;
CreateInfo.components := fComponents;
CreateInfo.subresourceRange := fSubresourceRange;
if Assigned(aAllocHandler)
then result := TvkuImageViewEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuImageViewEx.Create(CreateInfo, DeviceCommands);
try
TvkuImageViewEx(result).fAllocHandler := aAllocHandler;
TvkuImageViewEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
fFlags := aData.flags;
fImage := aData.image;
fViewType := aData.viewType;
fFormat := aData.format;
fComponents := aData.components;
fSubresourceRange.SetStructure(aData.subresourceRange);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuImageViewFactory.CreateImageView: TvkuImageView;
begin
result := TvkuImageView.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuImageViewFactory.AfterConstruction;
begin
inherited AfterConstruction;
fSubresourceRange := TvkuImageSubresourceRange.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuImageViewFactory.BeforeDestruction;
begin
FreeAndNil(fSubresourceRange);
inherited BeforeDestruction;
end;

end.


+ 4
- 4
projects/utils/uvkuInstance.pas View File

@@ -13,7 +13,7 @@ type
TvkuInstance = class(TvkuAllocHandle)
private
fHandle: VkInstance;
fPhysicalDevices: TvkuPhysicalDeviceArr;
fPhysicalDevices: TVkPhysicalDeviceArr;
fInstanceCommands: TVkInstanceCommands;

procedure UpdatePhysicalDevices;
@@ -23,7 +23,7 @@ type
property Handle: VkInstance read fHandle;
property InstanceCommands: TVkInstanceCommands read fInstanceCommands;

function GetPhysicalDevices: TvkuPhysicalDeviceArr;
function GetPhysicalDevices: TVkPhysicalDeviceArr;

constructor Create(
const aCreateInfo: TVkInstanceCreateInfo;
@@ -48,7 +48,7 @@ var
c: VkUint32;
err: TVkResult;
begin
if (Length(fPhysicalDevices) > 0) then
if (fPhysicalDevices <> nil) then
exit;

err := InstanceCommands.vkEnumeratePhysicalDevices(fHandle, @c, nil);
@@ -74,7 +74,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuInstance.GetPhysicalDevices: TvkuPhysicalDeviceArr;
function TvkuInstance.GetPhysicalDevices: TVkPhysicalDeviceArr;
begin
UpdatePhysicalDevices;
result := fPhysicalDevices;


+ 99
- 99
projects/utils/uvkuInstanceFactory.pas View File

@@ -7,83 +7,88 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuInstance, uvkuAllocationHandler, uvkuTypes, uvkuFactoryBase;
Vulkan, uvkuInstance, uvkuFactoryBase, uvkuTypes;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuInstanceEx = class(TvkuInstance)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
TvkuApplicationInfo = class(TObject)
public
destructor Destroy; override;
AppName: String;
AppVersion: VkVersion;
EngineName: String;
EngineVersion: VkVersion;
ApiVersion: VkVersion;

function GetStructure: TVkApplicationInfo;
procedure SetStructure(const aData: TVkApplicationInfo);

constructor Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuInstanceFactory = class(TvkuFactory)
private
fFlags: VkInstanceCreateFlags;
fApplicationInfo: TvkuApplicationInfo;
fFlags: VkInstanceCreateFlags;
fApplicationInfo: TvkuApplicationInfo;
fEnabledLayerNames: TStringList;
fEnabledExtensionNames: TStringList;

fLayers: TStringList;
fExtensions: TStringList;
fvkApplicationInfo: TVkApplicationInfo;
fvkEnabledLayerNames: PVkCharArr;
fvkEnabledExtensionNames: PVkCharArr;

function GetLayers: TStrings;
function GetExtensions: TStrings;
public
property Flags: VkInstanceCreateFlags read fFlags;
property ApplicationInfo: TvkuApplicationInfo read fApplicationInfo;
property Layers: TStrings read GetLayers;
property Extensions: TStrings read GetExtensions;
property Flags: VkInstanceCreateFlags read fFlags;
property ApplicationInfo: TvkuApplicationInfo read fApplicationInfo;
property EnabledLayerNames: TStrings read GetLayers;
property EnabledExtensionNames: TStrings read GetExtensions;

function CreateInstance: TvkuInstanceEx;
function CreateInstance(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuInstanceEx;
function GetStructure: TVkInstanceCreateInfo;
procedure SetStructure(const aData: TVkInstanceCreateInfo);
function CreateInstance: TvkuInstance;

constructor Create;
destructor Destroy; override;
end;

function vkuApplicationInfo: TvkuApplicationInfo;
function vkuApplicationInfo(
aAppName: String;
aAppVersion: VkVersion;
aEngineName: String;
aEngineVersion: VkVersion;
aApiVersion: VkVersion = VK_API_VERSION): TvkuApplicationInfo;

implementation

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function vkuApplicationInfo: TvkuApplicationInfo;
//TvkuApplicationInfo////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuApplicationInfo.GetStructure: TVkApplicationInfo;
begin
result.AppName := ExtractFileName(ParamStr(0));
result.AppVersion := 0;
result.EngineName := ExtractFileName(ParamStr(0));
result.EngineVersion := 0;
result.ApiVersion := VK_API_VERSION;
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_APPLICATION_INFO;
result.pNext := nil;
result.pApplicationName := PVkChar(AppName);
result.applicationVersion := AppVersion;
result.pEngineName := PVkChar(EngineName);
result.engineVersion := EngineVersion;
result.apiVersion := ApiVersion;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function vkuApplicationInfo(aAppName: String; aAppVersion: VkVersion; aEngineName: String; aEngineVersion: VkVersion; aApiVersion: VkVersion): TvkuApplicationInfo;
procedure TvkuApplicationInfo.SetStructure(const aData: TVkApplicationInfo);
begin
result := vkuApplicationInfo();
result.AppName := aAppName;
result.AppVersion := aAppVersion;
result.EngineName := aEngineName;
result.EngineVersion := aEngineVersion;
result.ApiVersion := aApiVersion;
AppName := aData.pApplicationName;
AppVersion := aData.applicationVersion;
EngineName := aData.pEngineName;
EngineVersion := aData.engineVersion;
ApiVersion := aData.apiVersion;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuInstanceEx/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuInstanceEx.Destroy;
constructor TvkuApplicationInfo.Create;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
AppName := ExtractFileName(ParamStr(0));
AppVersion := 0;
EngineName := ExtractFileName(ParamStr(0));
EngineVersion := 0;
ApiVersion := VK_API_VERSION;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -91,84 +96,79 @@ end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuInstanceFactory.GetLayers: TStrings;
begin
result := fLayers;
result := fEnabledLayerNames;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuInstanceFactory.GetExtensions: TStrings;
begin
result := fExtensions;
result := fEnabledExtensionNames;
end;

function TvkuInstanceFactory.GetStructure: TVkInstanceCreateInfo;
var i: Integer;
begin
SetLength(fvkEnabledLayerNames, fEnabledLayerNames.Count);
for i := low(fvkEnabledLayerNames) to high(fvkEnabledLayerNames) do
fvkEnabledLayerNames[i] := PVkChar(fEnabledLayerNames[i]);

SetLength(fvkEnabledExtensionNames, fEnabledExtensionNames.Count);
for i := low(fvkEnabledExtensionNames) to high(fvkEnabledExtensionNames) do
fvkEnabledExtensionNames[i] := PVkChar(fEnabledExtensionNames[i]);

fvkApplicationInfo := fApplicationInfo.GetStructure;

FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.pApplicationInfo := @fvkApplicationInfo;
result.enabledLayerCount := Length(fvkEnabledLayerNames);
result.ppEnabledLayerNames := @fvkEnabledLayerNames[0];
result.enabledExtensionCount := Length(fvkEnabledExtensionNames);
result.ppEnabledExtensionNames := @fvkEnabledExtensionNames[0];
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuInstanceFactory.CreateInstance: TvkuInstanceEx;
procedure TvkuInstanceFactory.SetStructure(const aData: TVkInstanceCreateInfo);
var i: Integer;
begin
result := CreateInstance(nil, false);
fFlags := aData.flags;

if Assigned(aData.pApplicationInfo) then
fApplicationInfo.SetStructure(aData.pApplicationInfo^);

fEnabledLayerNames.Clear;
for i := 0 to aData.enabledLayerCount-1 do
fEnabledLayerNames.Add(aData.ppEnabledLayerNames[i]);

fEnabledExtensionNames.Clear;
for i := 0 to aData.enabledExtensionCount-1 do
fEnabledExtensionNames.Add(aData.ppEnabledExtensionNames[i]);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuInstanceFactory.CreateInstance(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuInstanceEx;
var
CreateInfo: TVkInstanceCreateInfo;
AppInfo: TVkApplicationInfo;
i: Integer;
lay: array of PVkChar;
ext: array of PVkChar;
function TvkuInstanceFactory.CreateInstance: TvkuInstance;
begin
FillByte(AppInfo{%H-}, SizeOf(AppInfo), 0);
AppInfo.sType := VK_STRUCTURE_TYPE_APPLICATION_INFO;
AppInfo.pNext := nil;
AppInfo.pApplicationName := PVkChar(fApplicationInfo.AppName);
AppInfo.applicationVersion := fApplicationInfo.AppVersion;
AppInfo.pEngineName := PVkChar(fApplicationInfo.EngineName);
AppInfo.engineVersion := fApplicationInfo.EngineVersion;
AppInfo.apiVersion := fApplicationInfo.ApiVersion;

SetLength(lay, fLayers.Count);
for i := 0 to fLayers.Count-1 do
lay[i] := PVkChar(fLayers[i]);

SetLength(ext, fExtensions.Count);
for i := 0 to fExtensions.Count-1 do
ext[i] := PVkChar(fExtensions[i]);

FillByte(CreateInfo{%H-}, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.pApplicationInfo := @AppInfo;
CreateInfo.enabledLayerCount := Length(lay);
CreateInfo.ppEnabledLayerNames := @lay[0];
CreateInfo.enabledExtensionCount := Length(ext);
CreateInfo.ppEnabledExtensionNames := @ext[0];

if Assigned(aAllocHandler)
then result := TvkuInstanceEx.Create(CreateInfo, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuInstanceEx.Create(CreateInfo);
try
TvkuInstanceEx(result).fAllocHandler := aAllocHandler;
TvkuInstanceEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
result := TvkuInstance.Create(GetStructure, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuInstanceFactory.Create;
begin
inherited Create;
fLayers := TStringList.Create;
fExtensions := TStringList.Create;
fApplicationInfo := vkuApplicationInfo;
fFlags := 0;
fEnabledLayerNames := TStringList.Create;
fEnabledExtensionNames := TStringList.Create;
fApplicationInfo := TvkuApplicationInfo.Create;
fFlags := 0;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuInstanceFactory.Destroy;
begin
FreeAndNil(fLayers);
FreeAndNil(fExtensions);
FreeAndNil(fApplicationInfo);
FreeAndNil(fEnabledLayerNames);
FreeAndNil(fEnabledExtensionNames);
inherited Destroy;
end;



+ 17
- 17
projects/utils/uvkuPhysicalDevice.pas View File

@@ -19,7 +19,7 @@ type
function GetFeatures: TVkPhysicalDeviceFeatures;
function GetProperties: TVkPhysicalDeviceProperties;
function GetMemoryProperties: TVkPhysicalDeviceMemoryProperties;
function GetQueueFamilyProperties: TvkuQueueFamilyPropertiesArr;
function GetQueueFamilyProperties: TVkQueueFamilyPropertiesArr;
function GetFormatProperties(const aFormat: TVkFormat): TVkFormatProperties;
function GetImageFormatProperties(
const aFormat: TVkFormat;
@@ -32,19 +32,19 @@ type
const aImageType: TVkImageType;
const aSamples: TVkSampleCountFlagBits;
const aUsage: VkImageUsageFlags;
const aTiling: TVkImageTiling): TvkuSparseImageFormatPropertiesArr;
const aTiling: TVkImageTiling): TVkSparseImageFormatPropertiesArr;

public { VK_KHR_surface }
function GetSurfaceSupport(const aQueueFamilyIndex: VkUint32; const aSurface: VkSurfaceKHR): Boolean;
function GetSurfaceCapabilities(const aSurface: VkSurfaceKHR): TVkSurfaceCapabilitiesKHR;
function GetSurfaceFormats(const aSurface: VkSurfaceKHR): TvkuSurfaceFormatArr;
function GetSurfacePresentModes(const aSurface: VkSurfaceKHR): TvkuPresentModeArr;
function GetSurfaceFormats(const aSurface: VkSurfaceKHR): TVkSurfaceFormatArr;
function GetSurfacePresentModes(const aSurface: VkSurfaceKHR): TVkPresentModeArr;

public { VK_KHR_display }
function GetDisplayProperties: TvkuDisplayPropertiesArr;
function GetDisplayPlaneProperties: TvkuDisplayPlanePropertiesArr;
function GetDisplayPlaneSupportedDisplays(const aPlaneIndex: VkUint32): TvkuDisplayArr;
function GetDisplayModeProperties(const aDisplay: VkDisplayKHR): TvkuDisplayModePropertiesArr;
function GetDisplayProperties: TVkDisplayPropertiesArr;
function GetDisplayPlaneProperties: TVkDisplayPlanePropertiesArr;
function GetDisplayPlaneSupportedDisplays(const aPlaneIndex: VkUint32): TVkDisplayArr;
function GetDisplayModeProperties(const aDisplay: VkDisplayKHR): TVkDisplayModePropertiesArr;

public
property Handle: VkPhysicalDevice read fHandle;
@@ -87,7 +87,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetQueueFamilyProperties: TvkuQueueFamilyPropertiesArr;
function TvkuPhysicalDevice.GetQueueFamilyProperties: TVkQueueFamilyPropertiesArr;
var c: VkUint32;
begin
result := nil;
@@ -120,7 +120,7 @@ end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetSparseImageFormatProperties(const aFormat: TVkFormat; const aImageType: TVkImageType;
const aSamples: TVkSampleCountFlagBits; const aUsage: VkImageUsageFlags; const aTiling: TVkImageTiling): TvkuSparseImageFormatPropertiesArr;
const aSamples: TVkSampleCountFlagBits; const aUsage: VkImageUsageFlags; const aTiling: TVkImageTiling): TVkSparseImageFormatPropertiesArr;
var c: VkUint32;
begin
result := nil;
@@ -158,7 +158,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetSurfaceFormats(const aSurface: VkSurfaceKHR): TvkuSurfaceFormatArr;
function TvkuPhysicalDevice.GetSurfaceFormats(const aSurface: VkSurfaceKHR): TVkSurfaceFormatArr;
var c: VkUint32;
begin
result := nil;
@@ -170,7 +170,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetSurfacePresentModes(const aSurface: VkSurfaceKHR): TvkuPresentModeArr;
function TvkuPhysicalDevice.GetSurfacePresentModes(const aSurface: VkSurfaceKHR): TVkPresentModeArr;
var
c: VkUint32;
err: TVkResult;
@@ -188,7 +188,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetDisplayProperties: TvkuDisplayPropertiesArr;
function TvkuPhysicalDevice.GetDisplayProperties: TVkDisplayPropertiesArr;
var
err: TVkResult;
c: VkUint32;
@@ -206,7 +206,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetDisplayPlaneProperties: TvkuDisplayPlanePropertiesArr;
function TvkuPhysicalDevice.GetDisplayPlaneProperties: TVkDisplayPlanePropertiesArr;
var
err: TVkResult;
c: VkUint32;
@@ -224,7 +224,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetDisplayPlaneSupportedDisplays(const aPlaneIndex: VkUint32): TvkuDisplayArr;
function TvkuPhysicalDevice.GetDisplayPlaneSupportedDisplays(const aPlaneIndex: VkUint32): TVkDisplayArr;
var
err: TVkResult;
c: VkUint32;
@@ -242,7 +242,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetDisplayModeProperties(const aDisplay: VkDisplayKHR): TvkuDisplayModePropertiesArr;
function TvkuPhysicalDevice.GetDisplayModeProperties(const aDisplay: VkDisplayKHR): TVkDisplayModePropertiesArr;
var
err: TVkResult;
c: VkUint32;
@@ -254,7 +254,7 @@ begin
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get display mode property count', err);
SetLength(result, c);
err := fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR(fHandle, aDisplay, @c, @result[0]);
err := fInstanceCommands.vkGetDisplayModePropertiesKHR(fHandle, aDisplay, @c, @result[0]);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get display mode properties', err);
end;


+ 127
- 0
projects/utils/uvkuPipeline.pas View File

@@ -0,0 +1,127 @@
unit uvkuPipeline;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils,
Vulkan, uvkuBase;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuPipeline = class(TvkuAllocHandle)
private
fHandle: VkPipeline;
fDeviceCommands: TVkDeviceCommands;
public
property Handle: VkPipeline read fHandle;
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;

constructor Create(
const aHandle: VkPipeline;
const aOwnsHandle: Boolean;
const aDeviceCommands: TVkDeviceCommands;
const aAllocCallbacks: PVkAllocationCallbacks = nil);
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuGraphicsPipeline = class(TvkuPipeline)
private
procedure CreateHandle(const aCreateInfo: TVkGraphicsPipelineCreateInfo; const aPipelineCache: VkPipelineCache);
public
constructor Create(
const aCreateInfo: TVkGraphicsPipelineCreateInfo;
const aPipelineCache: VkPipelineCache;
const aDeviceCommands: TVkDeviceCommands;
const aAllocCallbacks: PVkAllocationCallbacks = nil);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuComputePipeline = class(TvkuPipeline)
private
procedure CreateHandle(const aCreateInfo: TVkComputePipelineCreateInfo; const aPipelineCache: VkPipelineCache);
public
constructor Create(
const aCreateInfo: TVkComputePipelineCreateInfo;
const aPipelineCache: VkPipelineCache;
const aDeviceCommands: TVkDeviceCommands;
const aAllocCallbacks: PVkAllocationCallbacks = nil);
end;

implementation

uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuPipeline///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuPipeline.Create(const aHandle: VkPipeline; const aOwnsHandle: Boolean;
const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create;
fHandle := aHandle;
fDeviceCommands := aDeviceCommands;
OwnsHandle := aOwnsHandle;
SetAllocCallbacks(aAllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuPipeline.Destroy;
begin
if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
fDeviceCommands.vkDestroyPipeline(fDeviceCommands.Device, fHandle, AllocCallbacks);
fHandle := VK_INVALID_NDP_HANDLE;
inherited Destroy;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuGraphicsPipeline///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuGraphicsPipeline.CreateHandle(const aCreateInfo: TVkGraphicsPipelineCreateInfo;
const aPipelineCache: VkPipelineCache);
var err: TVkResult;
begin
if not Assigned(fDeviceCommands.vkCreateGraphicsPipelines) then
raise TvkuInvalidFuncPtrException.Create('vkCreateGraphicsPipelines');
err := fDeviceCommands.vkCreateGraphicsPipelines(fDeviceCommands.Device, aPipelineCache, 1, @aCreateInfo, AllocCallbacks, @fHandle);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create graphics pipeline', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuGraphicsPipeline.Create(const aCreateInfo: TVkGraphicsPipelineCreateInfo;
const aPipelineCache: VkPipelineCache; const aDeviceCommands: TVkDeviceCommands;
const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create(VK_INVALID_NDP_HANDLE, true, aDeviceCommands, aAllocCallbacks);
CreateHandle(aCreateInfo, aPipelineCache);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuComputePipeline////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuComputePipeline.CreateHandle(const aCreateInfo: TVkComputePipelineCreateInfo;
const aPipelineCache: VkPipelineCache);
var err: TVkResult;
begin
if not Assigned(fDeviceCommands.vkCreateComputePipelines) then
raise TvkuInvalidFuncPtrException.Create('vkCreateComputePipelines');
err := fDeviceCommands.vkCreateComputePipelines(fDeviceCommands.Device, aPipelineCache, 1, @aCreateInfo, AllocCallbacks, @fHandle);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create compute pipeline', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuComputePipeline.Create(const aCreateInfo: TVkComputePipelineCreateInfo;
const aPipelineCache: VkPipelineCache; const aDeviceCommands: TVkDeviceCommands;
const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create(VK_INVALID_NDP_HANDLE, true, aDeviceCommands, aAllocCallbacks);
CreateHandle(aCreateInfo, aPipelineCache);
end;

end.


+ 169
- 0
projects/utils/uvkuPipelineFactory.pas View File

@@ -0,0 +1,169 @@
unit uvkuPipelineFactory;

{$mode objfpc}{$H+}

interface

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

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuPipelineShaderStageCreateInfo = class(TvkuStructure)
public
Flags: VkPipelineShaderStageCreateFlags;
Stage: TVkShaderStageFlagBits;
Module: VkShaderModule;
Name: String;

function GetStructure: TVkPipelineShaderStageCreateInfo;
procedure SetStructure(const aData: TVkPipelineShaderStageCreateInfo);
end;
TvkuPipelineShaderStageCreateInfoList = specialize TvkuObjList<TvkuPipelineShaderStageCreateInfo>;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuPipelineFactory = class(TvkuDeviceObjFactory)
private
fFlags: VkPipelineCreateFlags;
fLayout: VkPipelineLayout;
fBasePipelineHandle: VkPipeline;
fBasePipelineIndex: VkInt32;
public
property Flags: VkPipelineCreateFlags read fFlags write fFlags;
property Layout: VkPipelineLayout read fLayout write fLayout;
property BasePipelineHandle: VkPipeline read fBasePipelineHandle write fBasePipelineHandle;
property BasePipelineIndex: VkInt32 read fBasePipelineIndex write fBasePipelineIndex;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuGraphicsPipelineFactory = class(TvkuPipelineFactory)
private
fRenderPass: VkRenderPass;
fSubPass: VkUint32;
fStages: TvkuPipelineShaderStageCreateInfoList;

fvkStages: TVkPipelineShaderStageCreateInfoArr;
public
property RenderPass: VkRenderPass read fRenderPass write fRenderPass;
property SubPass: VkUint32 read fSubPass write fSubPass;

property Stages: TvkuPipelineShaderStageCreateInfoList read fStages;

function GetStructure: TVkGraphicsPipelineCreateInfo;
procedure SetStructure(const aData: TVkGraphicsPipelineCreateInfo);

function CreateGraphicsPipeline(const aPipelineCache: VkPipelineCache): TvkuGraphicsPipeline;

procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuComputePipelineFactory = class(TvkuPipelineFactory)
end;

implementation

uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuPipelineShaderStageCreateInfo//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineShaderStageCreateInfo.GetStructure: TVkPipelineShaderStageCreateInfo;
begin
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
result.pNext := nil;
result.flags := Flags;
result.stage := Stage;
result.module := Module;
result.pName := PVkChar(Name);
result.pSpecializationInfo := nil; // TODO: implement SpecializationInfo
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuPipelineShaderStageCreateInfo.SetStructure(const aData: TVkPipelineShaderStageCreateInfo);
begin
Flags := aData.flags;
Stage := aData.stage;
Module := aData.module;
if Assigned(aData.pName)
then Name := aData.pName
else Name := '';
// TODO: read SpecializationInfo
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuGraphicsPipelineFactory////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuGraphicsPipelineFactory.GetStructure: TVkGraphicsPipelineCreateInfo;
var i: Integer;
begin
SetLength(fvkStages, fStages.Length);
for i := low(fvkStages) to high(fvkStages) do
fvkStages[i] := fStages[i].GetStructure;

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.layout := fLayout;
result.renderPass := fRenderPass;
result.subpass := fSubPass;
result.basePipelineHandle := fBasePipelineHandle;
result.basePipelineIndex := fBasePipelineIndex;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuGraphicsPipelineFactory.SetStructure(const aData: TVkGraphicsPipelineCreateInfo);
var i: Integer;
begin
if Assigned(aData.pStages) then begin
fStages.Length := aData.stageCount;
for i := 0 to aData.stageCount-1 do
fStages[i].SetStructure((aData.pStages + i)^);
end;

fFlags := aData.flags;
fLayout := aData.layout;
fRenderPass := aData.renderPass;
fSubPass := aData.subpass;
fBasePipelineHandle := aData.basePipelineHandle;
fBasePipelineIndex := aData.basePipelineIndex;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuGraphicsPipelineFactory.CreateGraphicsPipeline(const aPipelineCache: VkPipelineCache): TvkuGraphicsPipeline;
begin
result := TvkuGraphicsPipeline.Create(GetStructure, aPipelineCache, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuGraphicsPipelineFactory.AfterConstruction;
begin
inherited AfterConstruction;
fStages := TvkuPipelineShaderStageCreateInfoList.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuGraphicsPipelineFactory.BeforeDestruction;
begin
FreeAndNil(fStages);
inherited BeforeDestruction;
end;

end.


+ 63
- 97
projects/utils/uvkuPipelineLayoutFactory.pas View File

@@ -6,48 +6,41 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuFactoryBase, uvkuPipelineLayout, uvkuAllocationHandler, uvkuTypes;
Vulkan, uvkuFactoryBase, uvkuPipelineLayout, uvkuTypes;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuPipelineLayoutEx = class(TvkuPipelineLayout)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
TvkuPushConstantRange = class(TvkuStructure)
public
destructor Destroy; override;
StageFlags: VkShaderStageFlags;
Offset: VkUint32;
Size: VkUint32;

function GetStructure: TVkPushConstantRange;
procedure SetStructure(const aData: TVkPushConstantRange);
end;
TvkuPushConstantRangeList = specialize TvkuObjList<TvkuPushConstantRange>;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuPipelineLayoutFactory = class(TvkuDeviceObjFactory)
private
fFlags: VkPipelineLayoutCreateFlags;
fSetLayouts: TvkuDescriptorSetLayoutArr;
fPushConstantRanges: TvkuPushConstantRangeArr;

function GetPushConstantRange(const aIndex: Integer): TVkPushConstantRange;
function GetPushConstantRangeCount: Integer;
function GetSetLayout(const aIndex: Integer): VkDescriptorSetLayout;
function GetSetLayoutCount: Integer;
procedure SetPushConstantRange(const aIndex: Integer; aValue: TVkPushConstantRange);
procedure SetPushConstantRangeCount(aValue: Integer);
procedure SetSetLayout(const aIndex: Integer; aValue: VkDescriptorSetLayout);
procedure SetSetLayoutCount(aValue: Integer);
fSetLayouts: TVkDescriptorSetLayoutList;
fPushConstantRanges: TvkuPushConstantRangeList;

fvkPushConstantRanges: TVkPushConstantRangeArr;
public
property Flags: VkPipelineLayoutCreateFlags read fFlags write fFlags;
property Flags: VkPipelineLayoutCreateFlags read fFlags write fFlags;
property SetLayouts: TVkDescriptorSetLayoutList read fSetLayouts;
property PushConstantRanges: TvkuPushConstantRangeList read fPushConstantRanges;

property SetLayouts: TvkuDescriptorSetLayoutArr read fSetLayouts write fSetLayouts;
property SetLayoutCount: Integer read GetSetLayoutCount write SetSetLayoutCount;
property SetLayout[const aIndex: Integer]: VkDescriptorSetLayout read GetSetLayout write SetSetLayout;
function GetStructure: TVkPipelineLayoutCreateInfo;
procedure SetStructure(const aData: TVkPipelineLayoutCreateInfo);

property PushConstantRanges: TvkuPushConstantRangeArr read fPushConstantRanges write fPushConstantRanges;
property PushConstantRangeCount: Integer read GetPushConstantRangeCount write SetPushConstantRangeCount;
property PushConstantRange[const aIndex: Integer]: TVkPushConstantRange read GetPushConstantRange write SetPushConstantRange;
function CreatePipelineLayout: TvkuPipelineLayout;

function CreatePipelineLayout: TvkuPipelineLayoutEx;
function CreatePipelineLayout(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuPipelineLayoutEx;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

implementation
@@ -56,102 +49,75 @@ uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuPipelineLayoutEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuPipelineLayoutEx.Destroy;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuPipelineLayoutFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineLayoutFactory.GetPushConstantRange(const aIndex: Integer): TVkPushConstantRange;
begin
if (aIndex < low(fPushConstantRanges)) or (aIndex > high(fPushConstantRanges)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fPushConstantRanges), High(fPushConstantRanges)]);
result := fPushConstantRanges[aIndex];
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineLayoutFactory.GetPushConstantRangeCount: Integer;
begin
result := Length(fPushConstantRanges);
end;

//TvkuPushConstantRange//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineLayoutFactory.GetSetLayout(const aIndex: Integer): VkDescriptorSetLayout;
function TvkuPushConstantRange.GetStructure: TVkPushConstantRange;
begin
if (aIndex < low(fSetLayouts)) or (aIndex > high(fSetLayouts)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fSetLayouts), High(fSetLayouts)]);
result := fSetLayouts[aIndex];
FillByte(result, SizeOf(result), 0);
result.stageFlags := StageFlags;
result.offset := Offset;
result.size := Size;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineLayoutFactory.GetSetLayoutCount: Integer;
procedure TvkuPushConstantRange.SetStructure(const aData: TVkPushConstantRange);
begin
result := Length(fSetLayouts);
StageFlags := aData.stageFlags;
Offset := aData.offset;
Size := aData.size;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuPipelineLayoutFactory.SetPushConstantRange(const aIndex: Integer; aValue: TVkPushConstantRange);
begin
if (aIndex < low(fPushConstantRanges)) or (aIndex > high(fPushConstantRanges)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fPushConstantRanges), High(fPushConstantRanges)]);
fPushConstantRanges[aIndex] := aValue;
end;

//TvkuPipelineLayoutFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuPipelineLayoutFactory.SetPushConstantRangeCount(aValue: Integer);
function TvkuPipelineLayoutFactory.GetStructure: TVkPipelineLayoutCreateInfo;
var i: Integer;
begin
SetLength(fPushConstantRanges, aValue);
SetLength(fvkPushConstantRanges, fPushConstantRanges.Length);
for i := low(fvkPushConstantRanges) to high(fvkPushConstantRanges) do
fvkPushConstantRanges[i] := fPushConstantRanges[i].GetStructure;

FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.setLayoutCount := fSetLayouts.Length;
result.pSetLayouts := fSetLayouts.PData;
result.pushConstantRangeCount := Length(fvkPushConstantRanges);
result.pPushConstantRanges := @fvkPushConstantRanges[0];
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuPipelineLayoutFactory.SetSetLayout(const aIndex: Integer; aValue: VkDescriptorSetLayout);
procedure TvkuPipelineLayoutFactory.SetStructure(const aData: TVkPipelineLayoutCreateInfo);
var i: Integer;
begin
if (aIndex < low(fSetLayouts)) or (aIndex > high(fSetLayouts)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fSetLayouts), High(fSetLayouts)]);
fSetLayouts[aIndex] := aValue;
fFlags := aData.flags;
fSetLayouts.SetData(aData.pSetLayouts, aData.setLayoutCount);
fPushConstantRanges.Length := aData.pushConstantRangeCount;
for i := 0 to fPushConstantRanges.Length-1 do
fPushConstantRanges[i].SetStructure((aData.pPushConstantRanges + i)^);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuPipelineLayoutFactory.SetSetLayoutCount(aValue: Integer);
function TvkuPipelineLayoutFactory.CreatePipelineLayout: TvkuPipelineLayout;
begin
SetLength(fSetLayouts, aValue);
result := TvkuPipelineLayout.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineLayoutFactory.CreatePipelineLayout: TvkuPipelineLayoutEx;
procedure TvkuPipelineLayoutFactory.AfterConstruction;
begin
result := CreatePipelineLayout(nil, false);
inherited AfterConstruction;
fSetLayouts := TVkDescriptorSetLayoutList.Create;
fPushConstantRanges := TvkuPushConstantRangeList.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineLayoutFactory.CreatePipelineLayout(const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuPipelineLayoutEx;
var CreateInfo: TVkPipelineLayoutCreateInfo;
procedure TvkuPipelineLayoutFactory.BeforeDestruction;
begin
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.setLayoutCount := Length(fSetLayouts);
CreateInfo.pSetLayouts := @fSetLayouts[0];
CreateInfo.pushConstantRangeCount := Length(fPushConstantRanges);
CreateInfo.pPushConstantRanges := @fPushConstantRanges[0];
if Assigned(aAllocHandler)
then result := TvkuPipelineLayoutEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuPipelineLayoutEx.Create(CreateInfo, DeviceCommands);
try
TvkuPipelineLayoutEx(result).fAllocHandler := aAllocHandler;
TvkuPipelineLayoutEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
FreeAndNil(fPushConstantRanges);
FreeAndNil(fSetLayouts);
inherited BeforeDestruction;
end;

end.


+ 267
- 106
projects/utils/uvkuRenderPassFactory.pas View File

@@ -6,58 +6,109 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuFactoryBase, uvkuRenderPass, uvkuAllocationHandler, uvkuTypes;
Vulkan, uvkuFactoryBase, uvkuRenderPass, uvkuTypes;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuRenderPassEx = class(TvkuRenderPass)
TvkuAttachmentDescription = class(TvkuStructure)
public
Flags: VkAttachmentDescriptionFlags;
Format: TVkFormat;
Samples: TVkSampleCountFlagBits;
LoadOp: TVkAttachmentLoadOp;
StoreOp: TVkAttachmentStoreOp;
StencilLoadOp: TVkAttachmentLoadOp;
StencilStoreOp: TVkAttachmentStoreOp;
InitialLayout: TVkImageLayout;
FinalLayout: TVkImageLayout;

function GetStructure: TVkAttachmentDescription;
procedure SetStructure(const aData: TVkAttachmentDescription);
end;
TvkuAttachmentDescriptionList = specialize TvkuObjList<TvkuAttachmentDescription>;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuAttachmentReference = class(TvkuStructure)
public
Attachment: VkUint32;
Layout: TVkImageLayout;

function GetStructure: TVkAttachmentReference;
procedure SetStructure(const aData: TVkAttachmentReference);
end;
TvkuAttachmentReferenceList = specialize TvkuObjList<TvkuAttachmentReference>;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuSubpassDescription = class(TvkuStructure)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
fInputAttachments: TvkuAttachmentReferenceList;
fColorAttachments: TvkuAttachmentReferenceList;
fResolveAttachments: TvkuAttachmentReferenceList;
fDepthStencilAttachments: TvkuAttachmentReferenceList;
fPreserveAttachments: TVkUint32List;

fvkInputAttachments: TVkAttachmentReferenceArr;
fvkColorAttachments: TVkAttachmentReferenceArr;
fvkResolveAttachments: TVkAttachmentReferenceArr;
fvkDepthStencilAttachments: TVkAttachmentReferenceArr;
public
destructor Destroy; override;
Flags: VkSubpassDescriptionFlags;
PipelineBindPoint: TVkPipelineBindPoint;

property InputAttachments: TvkuAttachmentReferenceList read fInputAttachments;
property ColorAttachments: TvkuAttachmentReferenceList read fColorAttachments;
property ResolveAttachments: TvkuAttachmentReferenceList read fResolveAttachments;
property DepthStencilAttachments: TvkuAttachmentReferenceList read fDepthStencilAttachments;
property PreserveAttachments: TVkUint32List read fPreserveAttachments;

function GetStructure: TVkSubpassDescription;
procedure SetStructure(const aData: TVkSubpassDescription);

procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
TvkuSubpassDescriptionList = specialize TvkuObjList<TvkuSubpassDescription>;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuSubpassDependency = class(TvkuStructure)
public
SrcSubpass: VkUint32;
DstSubpass: VkUint32;
SrcStageMask: VkPipelineStageFlags;
DstStageMask: VkPipelineStageFlags;
SrcAccessMask: VkAccessFlags;
DstAccessMask: VkAccessFlags;
DependencyFlags: VkDependencyFlags;

function GetStructure: TVkSubpassDependency;
procedure SetStructure(const aData: TVkSubpassDependency);
end;
TvkuSubpassDependencyList = specialize TvkuObjList<TvkuSubpassDependency>;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuRenderPassFactory = class(TvkuDeviceObjFactory)
private
fFlags: VkRenderPassCreateFlags;
fAttachments: TvkuAttachmentDescriptionArr;
fSubpasses: TvkuSubpassDescriptionArr;
fDependencies: TvkuSubpassDependencyArr;

function GetAttachment(const aIndex: Integer): TVkAttachmentDescription;
function GetAttachmentCount: Integer;
function GetDependency(const aIndex: Integer): TVkSubpassDependency;
function GetDependencyCount: Integer;
function GetSubpass(const aIndex: Integer): TVkSubpassDescription;
function GetSubpassCount: Integer;

procedure SetAttachment(const aIndex: Integer; aValue: TVkAttachmentDescription);
procedure SetAttachmentCount(aValue: Integer);
procedure SetDependency(const aIndex: Integer; aValue: TVkSubpassDependency);
procedure SetDependencyCount(aValue: Integer);
procedure SetSubpass(const aIndex: Integer; aValue: TVkSubpassDescription);
procedure SetSubpassCount(aValue: Integer);
public
property Flags: VkRenderPassCreateFlags read fFlags write fFlags;
fAttachments: TvkuAttachmentDescriptionList;
fSubpasses: TvkuSubpassDescriptionList;
fDependencies: TvkuSubpassDependencyList;

property Attachments: TvkuAttachmentDescriptionArr read fAttachments write fAttachments;
property AttachmentCount: Integer read GetAttachmentCount write SetAttachmentCount;
property Attachment[const aIndex: Integer]: TVkAttachmentDescription read GetAttachment write SetAttachment;
fvkAttachments: TVkAttachmentDescriptionArr;
fvkSubpasses: TVkSubpassDescriptionArr;
fvkDependencies: TVkSubpassDependencyArr;
public
property Flags: VkRenderPassCreateFlags read fFlags write fFlags;
property Attachments: TvkuAttachmentDescriptionList read fAttachments;
property Subpasses: TvkuSubpassDescriptionList read fSubpasses;
property Dependencies: TvkuSubpassDependencyList read fDependencies;

property Subpasses: TvkuSubpassDescriptionArr read fSubpasses write fSubpasses;
property SubpassCount: Integer read GetSubpassCount write SetSubpassCount;
property Subpass[const aIndex: Integer]: TVkSubpassDescription read GetSubpass write SetSubpass;
function GetStructure: TVkRenderPassCreateInfo;
procedure SetStructure(const aData: TVkRenderPassCreateInfo);

property Dependencies: TvkuSubpassDependencyArr read fDependencies write fDependencies;
property DependencyCount: Integer read GetDependencyCount write SetDependencyCount;
property Dependency[const aIndex: Integer]: TVkSubpassDependency read GetDependency write SetDependency;
function CreateRenderPass: TvkuRenderPass;

function CreateRenderPass: TvkuRenderPassEx;
function CreateRenderPass(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuRenderPassEx;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

implementation
@@ -66,133 +117,243 @@ uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuRenderPassEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuAttachmentDescription//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuRenderPassEx.Destroy;
function TvkuAttachmentDescription.GetStructure: TVkAttachmentDescription;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
result.flags := Flags;
result.format := Format;
result.samples := Samples;
result.loadOp := LoadOp;
result.storeOp := StoreOp;
result.stencilLoadOp := StencilLoadOp;
result.stencilStoreOp := StencilStoreOp;
result.initialLayout := InitialLayout;
result.finalLayout := FinalLayout;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuRenderPassFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.GetAttachment(const aIndex: Integer): TVkAttachmentDescription;
procedure TvkuAttachmentDescription.SetStructure(const aData: TVkAttachmentDescription);
begin
if (aIndex < low(fAttachments)) or (aIndex > high(fAttachments)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fAttachments), High(fAttachments)]);
result := fAttachments[aIndex];
Flags := aData.flags;
Format := aData.format;
Samples := aData.samples;
LoadOp := aData.loadOp;
StoreOp := aData.storeOp;
StencilLoadOp := aData.stencilLoadOp;
StencilStoreOp := aData.stencilStoreOp;
InitialLayout := aData.initialLayout;
FinalLayout := aData.finalLayout;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.GetAttachmentCount: Integer;
//TvkuAttachmentReference////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuAttachmentReference.GetStructure: TVkAttachmentReference;
begin
result := Length(fAttachments);
FillByte(result, SizeOf(result), 0);
result.attachment := Attachment;
result.layout := Layout;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.GetDependency(const aIndex: Integer): TVkSubpassDependency;
procedure TvkuAttachmentReference.SetStructure(const aData: TVkAttachmentReference);
begin
if (aIndex < low(fDependencies)) or (aIndex > high(fDependencies)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fDependencies), High(fDependencies)]);
result := fDependencies[aIndex];
Attachment := aData.attachment;
Layout := aData.layout;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.GetDependencyCount: Integer;
//TvkuSubpassDescription/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSubpassDescription.GetStructure: TVkSubpassDescription;
var i: Integer;
begin
result := Length(fDependencies);
if (fResolveAttachments.Length <> 0) and
(fResolveAttachments.Length <> fColorAttachments.Length) then
raise TvkuException.Create('''ResolveAttachments'' must be empty or have the same size as ''ColorAttachments''');

if (fDepthStencilAttachments.Length <> fColorAttachments.Length) then
raise TvkuException.Create('''DepthStencilAttachments'' must have the same size as ''ColorAttachments''');

SetLength(fvkInputAttachments, fInputAttachments.Length);
for i := low(fvkInputAttachments) to high(fvkInputAttachments) do
fvkInputAttachments[i] := fInputAttachments[i].GetStructure;

SetLength(fvkColorAttachments, fColorAttachments.Length);
for i := low(fvkColorAttachments) to high(fvkColorAttachments) do
fvkColorAttachments[i] := fColorAttachments[i].GetStructure;

SetLength(fvkResolveAttachments, fResolveAttachments.Length);
for i := low(fvkResolveAttachments) to high(fvkResolveAttachments) do
fvkResolveAttachments[i] := fResolveAttachments[i].GetStructure;

SetLength(fvkDepthStencilAttachments, fDepthStencilAttachments.Length);
for i := low(fvkDepthStencilAttachments) to high(fvkDepthStencilAttachments) do
fvkDepthStencilAttachments[i] := fDepthStencilAttachments[i].GetStructure;

result.flags := Flags;
result.pipelineBindPoint := PipelineBindPoint;
result.inputAttachmentCount := Length(fvkInputAttachments);
result.pInputAttachments := @fvkInputAttachments[0];
result.colorAttachmentCount := Length(fvkColorAttachments);
result.pColorAttachments := @fvkColorAttachments[0];
result.pResolveAttachments := @fvkResolveAttachments[0];
result.pDepthStencilAttachment := @fvkDepthStencilAttachments[0];
result.preserveAttachmentCount := fPreserveAttachments.Length;
result.pPreserveAttachments := fPreserveAttachments.PData;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.GetSubpass(const aIndex: Integer): TVkSubpassDescription;
procedure TvkuSubpassDescription.SetStructure(const aData: TVkSubpassDescription);
var i: Integer;
begin
if (aIndex < low(fSubpasses)) or (aIndex > high(fSubpasses)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fSubpasses), High(fSubpasses)]);
result := fSubpasses[aIndex];
Flags := aData.flags;
PipelineBindPoint := aData.pipelineBindPoint;

if Assigned(aData.pInputAttachments) then begin
fInputAttachments.Length := aData.inputAttachmentCount;
for i := 0 to aData.inputAttachmentCount-1 do
fInputAttachments[i].SetStructure((aData.pInputAttachments + i)^);
end else
fInputAttachments.Length := 0;

if Assigned(aData.pResolveAttachments) then begin
fResolveAttachments.Length := aData.colorAttachmentCount;
for i := 0 to aData.colorAttachmentCount-1 do
fResolveAttachments[i].SetStructure((aData.pResolveAttachments + i)^);
end else
fResolveAttachments.Length := 0;

if Assigned(aData.pDepthStencilAttachment) then begin
fDepthStencilAttachments.Length := aData.colorAttachmentCount;
for i := 0 to aData.colorAttachmentCount-1 do
fDepthStencilAttachments[i].SetStructure((aData.pDepthStencilAttachment + i)^);
end else
fDepthStencilAttachments.Length := 0;

fPreserveAttachments.SetData(aData.pPreserveAttachments, aData.preserveAttachmentCount);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.GetSubpassCount: Integer;
procedure TvkuSubpassDescription.AfterConstruction;
begin
result := Length(fSubpasses);
inherited AfterConstruction;
fInputAttachments := TvkuAttachmentReferenceList.Create;
fColorAttachments := TvkuAttachmentReferenceList.Create;
fResolveAttachments := TvkuAttachmentReferenceList.Create;
fDepthStencilAttachments := TvkuAttachmentReferenceList.Create;
fPreserveAttachments := TVkUint32List.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuRenderPassFactory.SetAttachment(const aIndex: Integer; aValue: TVkAttachmentDescription);
procedure TvkuSubpassDescription.BeforeDestruction;
begin
if (aIndex < low(fAttachments)) or (aIndex > high(fAttachments)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fAttachments), High(fAttachments)]);
fAttachments[aIndex] := aValue;
FreeAndNil(fPreserveAttachments);
FreeAndNil(fDepthStencilAttachments);
FreeAndNil(fResolveAttachments);
FreeAndNil(fColorAttachments);
FreeAndNil(fInputAttachments);
inherited BeforeDestruction;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuRenderPassFactory.SetAttachmentCount(aValue: Integer);
//TvkuSubpassDependency//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSubpassDependency.GetStructure: TVkSubpassDependency;
begin
SetLength(fAttachments, aValue);
result.srcSubpass := SrcSubpass;
result.dstSubpass := DstSubpass;
result.srcStageMask := SrcStageMask;
result.dstStageMask := DstStageMask;
result.srcAccessMask := SrcAccessMask;
result.dstAccessMask := DstAccessMask;
result.dependencyFlags := DependencyFlags;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuRenderPassFactory.SetDependency(const aIndex: Integer; aValue: TVkSubpassDependency);
procedure TvkuSubpassDependency.SetStructure(const aData: TVkSubpassDependency);
begin
if (aIndex < low(fDependencies)) or (aIndex > high(fDependencies)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fDependencies), High(fDependencies)]);
fDependencies[aIndex] := aValue;
SrcSubpass := aData.srcSubpass;
DstSubpass := aData.dstSubpass;
SrcStageMask := aData.srcStageMask;
DstStageMask := aData.dstStageMask;
SrcAccessMask := aData.srcAccessMask;
DstAccessMask := aData.dstAccessMask;
DependencyFlags := aData.dependencyFlags;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuRenderPassFactory.SetDependencyCount(aValue: Integer);
//TvkuRenderPassFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.GetStructure: TVkRenderPassCreateInfo;
var i: Integer;
begin
SetLength(fDependencies, aValue);
SetLength(fvkAttachments, fAttachments.Length);
for i := low(fvkAttachments) to high(fvkAttachments) do
fvkAttachments[i] := fAttachments[i].GetStructure;

SetLength(fvkSubpasses, fSubpasses.Length);
for i := low(fvkSubpasses) to high(fvkSubpasses) do
fvkSubpasses[i] := fSubpasses[i].GetStructure;

SetLength(fvkDependencies, fDependencies.Length);
for i := low(fvkDependencies) to high(fvkDependencies) do
fvkDependencies[i] := fDependencies[i].GetStructure;

FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.attachmentCount := Length(fvkAttachments);
result.pAttachments := @fvkAttachments[0];
result.subpassCount := Length(fvkSubpasses);
result.pSubpasses := @fvkSubpasses[0];
result.dependencyCount := Length(fvkDependencies);
result.pDependencies := @fvkDependencies[0];
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuRenderPassFactory.SetSubpass(const aIndex: Integer; aValue: TVkSubpassDescription);
procedure TvkuRenderPassFactory.SetStructure(const aData: TVkRenderPassCreateInfo);
var i: Integer;
begin
if (aIndex < low(fSubpasses)) or (aIndex > high(fSubpasses)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fSubpasses), High(fSubpasses)]);
fSubpasses[aIndex] := aValue;
fFlags := aData.flags;

fAttachments.Length := aData.attachmentCount;
for i := 0 to fAttachments.Length-1 do
fAttachments[i].SetStructure((aData.pAttachments + i)^);

fSubpasses.Length := aData.subpassCount;
for i := 0 to fSubpasses.Length-1 do
fSubpasses[i].SetStructure((aData.pSubpasses + i)^);

fDependencies.Length := aData.dependencyCount;
for i := 0 to fDependencies.Length-1 do
fDependencies[i].SetStructure((aData.pDependencies + i)^);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuRenderPassFactory.SetSubpassCount(aValue: Integer);
function TvkuRenderPassFactory.CreateRenderPass: TvkuRenderPass;
begin
SetLength(fSubpasses, aValue);
result := TvkuRenderPass.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.CreateRenderPass: TvkuRenderPassEx;
procedure TvkuRenderPassFactory.AfterConstruction;
begin
result := CreateRenderPass(nil, false);
inherited AfterConstruction;
fAttachments := TvkuAttachmentDescriptionList.Create;
fSubpasses := TvkuSubpassDescriptionList.Create;
fDependencies := TvkuSubpassDependencyList.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuRenderPassFactory.CreateRenderPass(const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuRenderPassEx;
var
CreateInfo: TVkRenderPassCreateInfo;
procedure TvkuRenderPassFactory.BeforeDestruction;
begin
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.attachmentCount := Length(fAttachments);
CreateInfo.pAttachments := @fAttachments[0];
CreateInfo.subpassCount := Length(fSubpasses);
CreateInfo.pSubpasses := @fSubpasses[0];
CreateInfo.dependencyCount := Length(fDependencies);
CreateInfo.pDependencies := @fDependencies[0];
if Assigned(aAllocHandler)
then result := TvkuRenderPassEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuRenderPassEx.Create(CreateInfo, DeviceCommands);
try
TvkuRenderPassEx(result).fAllocHandler := aAllocHandler;
TvkuRenderPassEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
FreeAndNil(fDependencies);
FreeAndNil(fSubpasses);
FreeAndNil(fAttachments);
inherited BeforeDestruction;
end;




+ 83
- 38
projects/utils/uvkuShaderModuleFactory.pas View File

@@ -6,18 +6,9 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuFactoryBase, uvkuAllocationHandler, uvkuShaderModule;
Vulkan, uvkuFactoryBase, uvkuShaderModule;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuShaderModuleEx = class(TvkuShaderModule)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
public
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuShaderModuleFactory = class(TvkuDeviceObjFactory)
private
@@ -26,33 +17,29 @@ type
fShaderCodeSize: VkSize;

procedure ReallocShaderCode(const aSize: VkSize);
procedure SetGlslCode(const aCode: PVkVoid; const aSize: VkSize; const aStage: VkShaderStageFlags);
public
property Flags: VkShaderModuleCreateFlags read fFlags write fFlags;

procedure SetShaderCode(const aStream: TStream; aSize: VkSize = 0);
procedure SetShaderCode(const aFilename: String);
procedure SetShaderCode(const aMem: PVkVoid; const aSize: VkSize);
procedure SetShaderCode(const aCode: PVkVoid; const aSize: VkSize);

procedure LoadSpvCode(const aStream: TStream; aSize: VkSize = 0);
procedure LoadSpvCode(const aFilename: String);

function CreateShaderModule: TvkuShaderModuleEx;
function CreateShaderModule(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuShaderModuleEx;
procedure SetGlslCode(const aCode: String; const aStage: VkShaderStageFlags);
procedure LoadGlslCode(const aStream: TStream; const aStage: VkShaderStageFlags; aSize: VkSize = 0);
procedure LoadGlslCode(const aFilename: String; const aStage: VkShaderStageFlags);

function GetStructure: TVkShaderModuleCreateInfo;
procedure SetStructure(const aData: TVkShaderModuleCreateInfo);

function CreateShaderModule: TvkuShaderModule;

procedure BeforeDestruction; override;
end;

implementation

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuShaderModuleEx/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuShaderModuleEx.Destroy;
begin
if fOwnsHandler then
FreeAndNil(fAllocHandler);
inherited Destroy;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuShaderModuleFactory////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -66,42 +53,99 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuShaderModuleFactory.SetShaderCode(const aStream: TStream; aSize: VkSize);
procedure TvkuShaderModuleFactory.SetGlslCode(const aCode: PVkVoid; const aSize: VkSize; const aStage: VkShaderStageFlags);
var p: PVkUint32;
begin
ReallocShaderCode(3 * SizeOf(VkUint32) + aSize + 1);
p := fShaderCode;
(p + 0)^ := $07230203;
(p + 1)^ := 0;
(p + 2)^ := VkUint32(aStage);
Move(aCode^, (p + 3)^, aSize);
PByte(fShaderCode + 3 * SizeOf(VkUint32) + aSize)^ := 0;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuShaderModuleFactory.SetShaderCode(const aCode: PVkVoid; const aSize: VkSize);
begin
ReallocShaderCode(aSize);
Move(aCode^, fShaderCode^, fShaderCodeSize);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuShaderModuleFactory.LoadSpvCode(const aStream: TStream; aSize: VkSize);
begin
if (aSize = 0) then
aSize := aStream.Size - aStream.Position;
ReallocShaderCode(aSize);
aStream.Read(fShaderCode^, fShaderCodeSize);
aStream.Read(fShaderCode^, aSize);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuShaderModuleFactory.SetShaderCode(const aFilename: String);
procedure TvkuShaderModuleFactory.LoadSpvCode(const aFilename: String);
var fs: TFileStream;
begin
fs := TFileStream.Create(aFilename, fmOpenRead);
try
SetShaderCode(fs);
LoadSpvCode(fs);
finally
FreeAndNil(fs);
end;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuShaderModuleFactory.SetShaderCode(const aMem: PVkVoid; const aSize: VkSize);
procedure TvkuShaderModuleFactory.SetGlslCode(const aCode: String; const aStage: VkShaderStageFlags);
begin
ReallocShaderCode(aSize);
Move(aMem^, fShaderCode^, fShaderCodeSize);
SetGlslCode(PVkVoid(PAnsiChar(aCode)), Length(aCode), aStage);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuShaderModuleFactory.LoadGlslCode(const aStream: TStream; const aStage: VkShaderStageFlags; aSize: VkSize);
var mem: PVkVoid;
begin
if (aSize = 0) then
aSize := aStream.Size - aStream.Position;
mem := GetMemory(aSize);
try
aStream.Read(mem^, aSize);
SetGlslCode(mem, aSize, aStage);
finally
FreeMemory(mem);
end;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuShaderModuleFactory.LoadGlslCode(const aFilename: String; const aStage: VkShaderStageFlags);
var fs: TFileStream;
begin
fs := TFileStream.Create(aFilename, fmOpenRead);
try
LoadGlslCode(fs, aStage);
finally
FreeAndNil(fs);
end;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuShaderModuleFactory.GetStructure: TVkShaderModuleCreateInfo;
begin
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.codeSize := fShaderCodeSize;
result.pCode := fShaderCode;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuShaderModuleFactory.CreateShaderModule: TvkuShaderModuleEx;
procedure TvkuShaderModuleFactory.SetStructure(const aData: TVkShaderModuleCreateInfo);
begin
result := CreateShaderModule(nil, false);
fFlags := aData.flags;
SetShaderCode(aData.pCode, aData.codeSize);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuShaderModuleFactory.CreateShaderModule(const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuShaderModuleEx;
function TvkuShaderModuleFactory.CreateShaderModule: TvkuShaderModule;
var
CreateInfo: TVkShaderModuleCreateInfo;
begin
@@ -111,6 +155,7 @@ begin
CreateInfo.flags := fFlags;
CreateInfo.codeSize := fShaderCodeSize;
CreateInfo.pCode := fShaderCode;
result := TvkuShaderModule.Create(CreateInfo, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 26
- 146
projects/utils/uvkuSurfaceFactory.pas View File

@@ -7,18 +7,9 @@ interface

uses
Classes, SysUtils, Controls,
Vulkan, uvkuSurface, uvkuAllocationHandler, uvkuFactoryBase;
Vulkan, uvkuSurface, uvkuFactoryBase;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuSurfaceEx = class(TvkuSurface)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
public
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuSurfaceFactory = class(TvkuInstanceObjFactory)
{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
@@ -29,6 +20,9 @@ type
public
property HInstance: Vulkan.HINSTANCE read fHInstance write fHInstance;
property Hwnd: Vulkan.HWND read fHwnd write SetHwnd;

function GetStructure: TVkWin32SurfaceCreateInfoKHR;
procedure SetStructure(const aData: TVkWin32SurfaceCreateInfoKHR);
{$ENDIF}

private
@@ -39,10 +33,7 @@ type
property WinControl: TWinControl read fWinControl write SetWinControl;
property Flags: VkFlags read fFlags write fFlags;

function CreateSurface: TvkuSurfaceEx;
function CreateSurface(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuSurfaceEx;
function CreateSurface: TvkuSurface;

procedure AfterConstruction; override;
end;
@@ -53,79 +44,33 @@ implementation
uses Windows;
{$ENDIF}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuSurfaceEx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuSurfaceEx.Destroy;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuSurfaceFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)}
{$ERROR 'TODO: implement'}
procedure TvkuSurfaceFactory.SetDisplay(const aValue: TDisplay);
begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetWindow(const aValue: TWindow);
begin
end;

{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)}
{$ERROR 'TODO: implement'}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetConnection(const aValue: xcb_connection_t);
begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetWindow(const aValue: xcb_window_t);
begin
end;

{$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)}
{$ERROR 'TODO: implement'}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetDisplay(const aValue: wl_display);
begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetSurface(const aValue: wl_surface);
begin
end;

{$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)}
{$ERROR 'TODO: implement'}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetConnection(const aValue: MirConnection);
begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetSurface(const aValue: MirSurface);
{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
procedure TvkuSurfaceFactory.SetHwnd(const aValue: Vulkan.HWND);
begin
SetWinControl(nil);
fHwnd := aValue;
end;

{$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)}
{$ERROR 'TODO: implement'}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetWindow(const aValue: ANativeWindow);
function TvkuSurfaceFactory.GetStructure: TVkWin32SurfaceCreateInfoKHR;
begin
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
result.pNext := nil;
result.flags := fFlags;
result.hinstance := fHInstance;
result.hwnd := fHwnd;
end;

{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.SetHwnd(const aValue: Vulkan.HWND);
procedure TvkuSurfaceFactory.SetStructure(const aData: TVkWin32SurfaceCreateInfoKHR);
begin
SetWinControl(nil);
fHwnd := aValue;
fFlags := aData.flags;
fHInstance := aData.hinstance;
fHwnd := aData.hwnd;
end;
{$ENDIF}

@@ -135,89 +80,24 @@ begin
if fWinControl = aValue then
exit;
fWinControl := aValue;
{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
fHwnd := Vulkan.HWND(fWinControl.Handle);
{$ELSE}
{$ERROR 'unknown or unsupported system'}
{$ENDIF}
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSurfaceFactory.CreateSurface: TvkuSurfaceEx;
function TvkuSurfaceFactory.CreateSurface: TvkuSurface;
begin
result := CreateSurface(nil, false);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSurfaceFactory.CreateSurface(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuSurfaceEx;
{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
var CreateInfo: TVkWin32SurfaceCreateInfoKHR;
{$ENDIF}
var srf: TvkuSurfaceEx;
begin
{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.hinstance := fHInstance;
CreateInfo.hwnd := fHwnd;
{$ENDIF}
if Assigned(aAllocHandler)
then srf := TvkuSurfaceEx.Create(CreateInfo, InstanceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else srf := TvkuSurfaceEx.Create(CreateInfo, InstanceCommands);
try
srf.fAllocHandler := aAllocHandler;
srf.fOwnsHandler := aOwnsHandler;
except
FreeAndNil(srf);
end;
result := srf;
result := TvkuSurface.Create(GetStructure, InstanceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSurfaceFactory.AfterConstruction;
begin
inherited AfterConstruction;
{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
fHInstance := Vulkan.HINSTANCE(GetModuleHandle(nil));
{$ENDIF}
fFlags := 0;


+ 2
- 2
projects/utils/uvkuSwapChain.pas View File

@@ -20,7 +20,7 @@ type
property Handle: VkSwapchainKHR read fHandle;
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;

function GetImages: TvkuImageArr;
function GetImages: TVkImageArr;
function AcquireNextImage(const aTimeout: VkUint64; const aSemaphore: VkSemaphore; const aFence: VkFence): VkUint32;

constructor Create(
@@ -54,7 +54,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSwapChain.GetImages: TvkuImageArr;
function TvkuSwapChain.GetImages: TVkImageArr;
var
c: VkUint32;
err: TVkResult;


+ 68
- 99
projects/utils/uvkuSwapChainFactory.pas View File

@@ -6,18 +6,9 @@ interface

uses
Classes, SysUtils,
Vulkan, uvkuSwapChain, uvkuTypes, uvkuAllocationHandler, uvkuFactoryBase;
Vulkan, uvkuSwapChain, uvkuTypes, uvkuFactoryBase;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuSwapChainEx = class(TvkuSwapChain)
private
fAllocHandler: TvkuAllocationHandler;
fOwnsHandler: Boolean;
public
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuSwapChainFactory = class(TvkuDeviceObjFactory)
private
@@ -30,42 +21,36 @@ type
fImageArrayLayers: VkUint32;
fImageUsage: VkImageUsageFlags;
fImageSharingMode: TVkSharingMode;
fQueueFamilyIndices: TvkuUint32Arr;
fQueueFamilyIndices: TVkUint32List;
fPreTransform: TVkSurfaceTransformFlagBitsKHR;
fComposideAlpha: TVkCompositeAlphaFlagBitsKHR;
fPresentMode: TVkPresentModeKHR;
fClipped: Boolean;
fOldSwapChain: VkSwapchainKHR;

function GetQueueFamilyIndexCount: Integer;
function GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
procedure SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
public
property Flags: VkSwapchainCreateFlagsKHR read fFlags write fFlags;
property Surface: VkSurfaceKHR read fSurface write fSurface;
property MinImageCount: VkUint32 read fMinImageCount write fMinImageCount;
property ImageFormat: TVkFormat read fImageFormat write fImageFormat;
property ImageColorSpace: TVkColorSpaceKHR read fImageColorSpace write fImageColorSpace;
property ImageExtent: TVkExtent2D read fImageExtent write fImageExtent;
property ImageArrayLayers: VkUint32 read fImageArrayLayers write fImageArrayLayers;
property ImageUsage: VkImageUsageFlags read fImageUsage write fImageUsage;
property ImageSharingMode: TVkSharingMode read fImageSharingMode write fImageSharingMode;
property PreTransform: TVkSurfaceTransformFlagBitsKHR read fPreTransform write fPreTransform;
property ComposideAlpha: TVkCompositeAlphaFlagBitsKHR read fComposideAlpha write fComposideAlpha;
property PresentMode: TVkPresentModeKHR read fPresentMode write fPresentMode;
property Clipped: Boolean read fClipped write fClipped;
property OldSwapChain: VkSwapchainKHR read fOldSwapChain write fOldSwapChain;
property QueueFamilyIndices: TvkuUint32Arr read fQueueFamilyIndices write fQueueFamilyIndices;
property QueueFamilyIndexCount: Integer read GetQueueFamilyIndexCount;
property QueueFamilyIndex[const aIndex: Integer]: VkUint32 read GetQueueFamilyIndex write SetQueueFamilyIndex;
property Flags: VkSwapchainCreateFlagsKHR read fFlags write fFlags;
property Surface: VkSurfaceKHR read fSurface write fSurface;
property MinImageCount: VkUint32 read fMinImageCount write fMinImageCount;
property ImageFormat: TVkFormat read fImageFormat write fImageFormat;
property ImageColorSpace: TVkColorSpaceKHR read fImageColorSpace write fImageColorSpace;
property ImageExtent: TVkExtent2D read fImageExtent write fImageExtent;
property ImageArrayLayers: VkUint32 read fImageArrayLayers write fImageArrayLayers;
property ImageUsage: VkImageUsageFlags read fImageUsage write fImageUsage;
property ImageSharingMode: TVkSharingMode read fImageSharingMode write fImageSharingMode;
property PreTransform: TVkSurfaceTransformFlagBitsKHR read fPreTransform write fPreTransform;
property ComposideAlpha: TVkCompositeAlphaFlagBitsKHR read fComposideAlpha write fComposideAlpha;
property PresentMode: TVkPresentModeKHR read fPresentMode write fPresentMode;
property Clipped: Boolean read fClipped write fClipped;
property OldSwapChain: VkSwapchainKHR read fOldSwapChain write fOldSwapChain;
property QueueFamilyIndices: TVkUint32List read fQueueFamilyIndices;
function GetStructure: TVkSwapchainCreateInfoKHR;
procedure SetStructure(const aData: TVkSwapchainCreateInfoKHR);

function CreateSwapchain: TvkuSwapChain;
function CreateSwapchain(
const aAllocHandler: TvkuAllocationHandler;
const aOwnsHandler: Boolean): TvkuSwapChain;

procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

implementation
@@ -73,90 +58,74 @@ implementation
uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuSwapChainEx////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuSwapChainEx.Destroy;
begin
inherited Destroy;
if fOwnsHandler then
FreeAndNil(fAllocHandler);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuSwapChainFactory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSwapChainFactory.GetQueueFamilyIndexCount: Integer;
function TvkuSwapChainFactory.GetStructure: TVkSwapchainCreateInfoKHR;
begin
result := Length(fQueueFamilyIndices);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSwapChainFactory.GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
begin
if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
result := fQueueFamilyIndices[aIndex];
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
result.pNext := nil;
result.flags := fFlags;
result.surface := fSurface;
result.minImageCount := fMinImageCount;
result.imageFormat := fImageFormat;
result.imageColorSpace := fImageColorSpace;
result.imageExtent := fImageExtent;
result.imageArrayLayers := fImageArrayLayers;
result.imageUsage := fImageUsage;
result.imageSharingMode := fImageSharingMode;
result.queueFamilyIndexCount := fQueueFamilyIndices.Length;
result.pQueueFamilyIndices := fQueueFamilyIndices.PData;
result.preTransform := fPreTransform;
result.compositeAlpha := fComposideAlpha;
result.presentMode := fPresentMode;
result.oldSwapchain := fOldSwapChain;
if fClipped
then result.clipped := VK_TRUE
else result.clipped := VK_FALSE;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSwapChainFactory.SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
procedure TvkuSwapChainFactory.SetStructure(const aData: TVkSwapchainCreateInfoKHR);
begin
if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
fQueueFamilyIndices[aIndex] := aValue;
fFlags := aData.flags;
fSurface := aData.surface;
fMinImageCount := aData.minImageCount;
fImageFormat := aData.imageFormat;
fImageColorSpace := aData.imageColorSpace;
fImageExtent := aData.imageExtent;
fImageArrayLayers := aData.imageArrayLayers;
fImageUsage := aData.imageUsage;
fImageSharingMode := aData.imageSharingMode;
fPreTransform := aData.preTransform;
fComposideAlpha := aData.compositeAlpha;
fPresentMode := aData.presentMode;
fOldSwapChain := aData.oldSwapchain;
fClipped := (aData.clipped <> 0);

fQueueFamilyIndices.SetData(aData.pQueueFamilyIndices, aData.queueFamilyIndexCount);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSwapChainFactory.CreateSwapchain: TvkuSwapChain;
begin
result := CreateSwapchain(nil, false);
result := TvkuSwapChain.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSwapChainFactory.CreateSwapchain(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuSwapChain;
var
CreateInfo: TVkSwapchainCreateInfoKHR;
procedure TvkuSwapChainFactory.AfterConstruction;
begin
FillByte(CreateInfo, SizeOf(CreateInfo), 0);
CreateInfo.sType := VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
CreateInfo.pNext := nil;
CreateInfo.flags := fFlags;
CreateInfo.surface := fSurface;
CreateInfo.minImageCount := fMinImageCount;
CreateInfo.imageFormat := fImageFormat;
CreateInfo.imageColorSpace := fImageColorSpace;
CreateInfo.imageExtent := fImageExtent;
CreateInfo.imageArrayLayers := fImageArrayLayers;
CreateInfo.imageUsage := fImageUsage;
CreateInfo.imageSharingMode := fImageSharingMode;
CreateInfo.queueFamilyIndexCount := Length(fQueueFamilyIndices);
CreateInfo.pQueueFamilyIndices := @fQueueFamilyIndices[0];
CreateInfo.preTransform := fPreTransform;
CreateInfo.compositeAlpha := fComposideAlpha;
CreateInfo.presentMode := fPresentMode;
CreateInfo.oldSwapchain := fOldSwapChain;
if fClipped
then CreateInfo.clipped := VK_TRUE
else CreateInfo.clipped := VK_FALSE;

if Assigned(aAllocHandler)
then result := TvkuSwapChainEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuSwapChainEx.Create(CreateInfo, DeviceCommands);
try
TvkuSwapChainEx(result).fAllocHandler := aAllocHandler;
TvkuSwapChainEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
raise;
end;
inherited AfterConstruction;
fPresentMode := VK_PRESENT_MODE_FIFO_KHR;
fQueueFamilyIndices := TVkUint32List.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuSwapChainFactory.AfterConstruction;
procedure TvkuSwapChainFactory.BeforeDestruction;
begin
inherited AfterConstruction;
fPresentMode := VK_PRESENT_MODE_FIFO_KHR;
FreeAndNil(fQueueFamilyIndices);
inherited BeforeDestruction;
end;

end.


+ 178
- 33
projects/utils/uvkuTypes.pas View File

@@ -6,46 +6,191 @@ interface

uses
Classes, SysUtils,
Vulkan;
Vulkan, uvkuUtils;

type
TvkuFloatArr = array of VkFloat;
TvkuUint32Arr = array of VkUint32;
TvkuImageArr = array of VkImage;
TvkuPhysicalDeviceArr = array of VkPhysicalDevice;
TvkuQueueFamilyPropertiesArr = array of TVkQueueFamilyProperties;
TvkuSparseImageFormatPropertiesArr = array of TVkSparseImageFormatProperties;
TvkuSurfaceFormatArr = array of TVkSurfaceFormatKHR;
TvkuPresentModeArr = array of TVkPresentModeKHR;
TvkuDisplayPropertiesArr = array of TVkDisplayPropertiesKHR;
TvkuDisplayPlanePropertiesArr = array of TVkDisplayPlanePropertiesKHR;
TvkuDisplayArr = array of VkDisplayKHR;
TvkuDisplayModePropertiesArr = array of TVkDisplayModePropertiesKHR;
TvkuCommandBufferArr = array of VkCommandBuffer;
TvkuAttachmentDescriptionArr = array of TVkAttachmentDescription;
TvkuSubpassDescriptionArr = array of TVkSubpassDescription;
TvkuSubpassDependencyArr = array of TVkSubpassDependency;
TvkuImageViewArr = array of VkImageView;
TvkuDescriptorSetLayoutBindingArr = array of TVkDescriptorSetLayoutBinding;
TvkuDescriptorSetLayoutArr = array of VkDescriptorSetLayout;
TvkuPushConstantRangeArr = array of TVkPushConstantRange;

TvkuApplicationInfo = packed record
AppName: String;
AppVersion: VkVersion;
EngineName: String;
EngineVersion: VkVersion;
ApiVersion: VkVersion;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
generic TvkuListBase<T> = class(TObject)
private type
TPointerType = ^T;
TArrayType = array of T;
private
fItems: TArrayType;
function GetData: TPointerType;
function GetItem(const aIndex: Integer): T;
function GetLength: Integer;
procedure SetLength(aValue: Integer);
protected
procedure InitItem(var aItem: T); virtual;
procedure FreeItem(var aItem: T); virtual;
public
property Length: Integer read GetLength write SetLength;
property Count: Integer read GetLength write SetLength;
property Size: Integer read GetLength write SetLength;
property PData: TPointerType read GetData;
property Data: TArrayType read fItems;
property Items[const aIndex: Integer]: T read GetItem; default;

constructor Create;
destructor Destroy; override;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
generic TvkuList<T> = class(specialize TvkuListBase<T>)
private
procedure SetItem(const aIndex: Integer; aValue: T);
public
property Items[const aIndex: Integer]: T read GetItem write SetItem; default;
property Data: TArrayType read fItems write fItems;

procedure SetData(const aData: TPointerType; const aCount: Integer);
end;

TvkuQueueCreateInfo = packed record
Flags: VkDeviceQueueCreateFlags;
FamilyIndex: VkUint32;
Priorities: TvkuFloatArr;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
generic TvkuObjList<T> = class(specialize TvkuListBase<T>)
protected
procedure InitItem(var aItem: T); override;
procedure FreeItem(var aItem: T); override;
end;
TvkuQueueCreateInfoArr = array of TvkuQueueCreateInfo;

PVkCharArr = array of PVkChar;
TVkPhysicalDeviceArr = array of VkPhysicalDevice;
TVkQueueFamilyPropertiesArr = array of TVkQueueFamilyProperties;
TVkSparseImageFormatPropertiesArr = array of TVkSparseImageFormatProperties;
TVkSurfaceFormatArr = array of TVkSurfaceFormatKHR;
TVkPresentModeArr = array of TVkPresentModeKHR;
TVkDisplayPropertiesArr = array of TVkDisplayPropertiesKHR;
TVkDisplayPlanePropertiesArr = array of TVkDisplayPlanePropertiesKHR;
TVkDisplayArr = array of VkDisplayKHR;
TVkDisplayModePropertiesArr = array of TVkDisplayModePropertiesKHR;
TVkImageArr = array of VkImage;
TVkCommandBufferArr = array of VkCommandBuffer;
TVkDescriptorSetLayoutBindingArr = array of TVkDescriptorSetLayoutBinding;
TVkDescriptorSetLayoutArr = array of VkDescriptorSetLayout;
TVkPushConstantRangeArr = array of TVkPushConstantRange;
TVkPipelineShaderStageCreateInfoArr = array of TVkPipelineShaderStageCreateInfo;
TVkPipelineVertexInputStateCreateInfoArr = array of TVkPipelineVertexInputStateCreateInfo;
TVkAttachmentDescriptionArr = array of TVkAttachmentDescription;
TVkSubpassDescriptionArr = array of TVkSubpassDescription;
TVkSubpassDependencyArr = array of TVkSubpassDependency;
TVkAttachmentReferenceArr = array of TVkAttachmentReference;

TVkUint32List = specialize TvkuList<VkUint32>;
TVkFloatList = specialize TvkuList<VkFloat>;
TVkImageViewList = specialize TvkuList<VkImageView>;
TVkSamplerList = specialize TvkuList<VkSampler>;
TVkDescriptorSetLayoutList = specialize TvkuList<VkDescriptorSetLayout>;

implementation

uses
typinfo;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuCreateInfoArr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuListBase.GetItem(const aIndex: Integer): T;
begin
if (aIndex < low(fItems)) or (aIndex > high(fItems)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fItems), High(fItems)]);
result := fItems[aIndex];
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuListBase.GetData: TPointerType;
begin
result := @fItems[0];
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuListBase.GetLength: Integer;
begin
result := System.Length(fItems);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuListBase.SetLength(aValue: Integer);
var i: Integer;
begin
if (aValue < 0) then
aValue := 0;
i := System.Length(fItems);
while (i > aValue) do begin
FreeItem(fItems[i-1]);
dec(i);
end;
i := System.Length(fItems) + 1;
System.SetLength(fItems, aValue);
while (i <= aValue) do begin
InitItem(fItems[i-1]);
inc(i);
end;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuListBase.InitItem(var aItem: T);
begin
FillByte(aItem, SizeOf(aItem), 0);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuListBase.FreeItem(var aItem: T);
begin
// DUMMY
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuListBase.Create;
begin
inherited Create;
System.SetLength(fItems, 0);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuListBase.Destroy;
begin
SetLength(0);
inherited Destroy;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuList///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuList.SetItem(const aIndex: Integer; aValue: T);
begin
if (aIndex < low(fItems)) or (aIndex > high(fItems)) then
raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fItems), High(fItems)]);
fItems[aIndex] := aValue;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuList.SetData(const aData: TPointerType; const aCount: Integer);
var i: Integer;
begin
if Assigned(aData) then begin
SetLength(aCount);
for i := low(fItems) to high(fItems) do
fItems[i] := (aData + i)^;
end else
SetLength(0);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuObjList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuObjList.InitItem(var aItem: T);
begin
inherited InitItem(aItem);
aItem := T.Create;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuObjList.FreeItem(var aItem: T);
begin
FreeAndNil(aItem);
inherited FreeItem(aItem);
end;


end.


Loading…
Cancel
Save