浏览代码

* implemented pipeline cache

* created command buffers for rendering
* created depth stencil buffer/image
master
Bergmann89 10 年前
父节点
当前提交
68b70540ae
共有 15 个文件被更改,包括 1079 次插入 和 535 次删除
  1. +9
    -1
      projects/triangle/triangle.lpi
  2. +1
    -1
      projects/triangle/triangle.lpr
  3. +220
    -188
      projects/triangle/triangle.lps
  4. +477
    -336
      projects/triangle/uMainForm.pas
  5. +33
    -1
      projects/utils/VulkanUtils.pas
  6. +2
    -2
      projects/utils/uvkuAllocationHandler.pas
  7. +34
    -1
      projects/utils/uvkuCommandBuffer.pas
  8. +1
    -1
      projects/utils/uvkuDebugReporter.pas
  9. +38
    -2
      projects/utils/uvkuDevice.pas
  10. +1
    -1
      projects/utils/uvkuFactoryBase.pas
  11. +64
    -1
      projects/utils/uvkuImage.pas
  12. +82
    -0
      projects/utils/uvkuPipelineCache.pas
  13. +65
    -0
      projects/utils/uvkuPipelineCacheFactory.pas
  14. +49
    -0
      projects/utils/uvkuQueue.pas
  15. +3
    -0
      projects/utils/uvkuTypes.pas

+ 9
- 1
projects/triangle/triangle.lpi 查看文件

@@ -33,7 +33,7 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="44">
<Units Count="46">
<Unit0>
<Filename Value="triangle.lpr"/>
<IsPartOfProject Value="True"/>
@@ -213,6 +213,14 @@
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
<IsPartOfProject Value="True"/>
</Unit43>
<Unit44>
<Filename Value="..\utils\uvkuPipelineCache.pas"/>
<IsPartOfProject Value="True"/>
</Unit44>
<Unit45>
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/>
<IsPartOfProject Value="True"/>
</Unit45>
</Units>
</ProjectOptions>
<CompilerOptions>


+ 1
- 1
projects/triangle/triangle.lpr 查看文件

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

{$R *.res}



+ 220
- 188
projects/triangle/triangle.lps 查看文件

@@ -4,13 +4,13 @@
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="64">
<Units Count="66">
<Unit0>
<Filename Value="triangle.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="3" Y="31"/>
<UsageCount Value="98"/>
<UsageCount Value="103"/>
</Unit0>
<Unit1>
<Filename Value="uMainForm.pas"/>
@@ -19,25 +19,33 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="4"/>
<TopLine Value="327"/>
<CursorPos X="35" Y="349"/>
<UsageCount Value="98"/>
<EditorIndex Value="7"/>
<TopLine Value="525"/>
<CursorPos X="21" Y="541"/>
<ExtraEditorCount Value="1"/>
<ExtraEditor1>
<IsVisibleTab Value="True"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
</ExtraEditor1>
<UsageCount Value="103"/>
<Loaded Value="True"/>
</Unit1>
<Unit2>
<Filename Value="..\Vulkan.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="3"/>
<TopLine Value="712"/>
<CursorPos X="17" Y="727"/>
<EditorIndex Value="4"/>
<TopLine Value="1324"/>
<CursorPos X="133" Y="1340"/>
<ExtraEditorCount Value="1"/>
<ExtraEditor1>
<EditorIndex Value="-1"/>
<TopLine Value="3271"/>
<CursorPos X="80" Y="3291"/>
</ExtraEditor1>
<UsageCount Value="98"/>
<UsageCount Value="103"/>
<Loaded Value="True"/>
</Unit2>
<Unit3>
@@ -45,7 +53,7 @@
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="45" Y="16"/>
<UsageCount Value="96"/>
<UsageCount Value="101"/>
</Unit3>
<Unit4>
<Filename Value="..\utils\uvkuInstanceFactory.pas"/>
@@ -53,7 +61,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="13"/>
<CursorPos X="3" Y="29"/>
<UsageCount Value="90"/>
<UsageCount Value="95"/>
</Unit4>
<Unit5>
<Filename Value="..\utils\uvkuPhysicalDevice.pas"/>
@@ -61,23 +69,24 @@
<EditorIndex Value="-1"/>
<TopLine Value="6"/>
<CursorPos X="67" Y="22"/>
<UsageCount Value="90"/>
<UsageCount Value="95"/>
</Unit5>
<Unit6>
<Filename Value="..\utils\uvkuAllocationHandler.pas"/>
<IsPartOfProject Value="True"/>
<TopLine Value="90"/>
<CursorPos X="15" Y="72"/>
<UsageCount Value="80"/>
<TopLine Value="7"/>
<CursorPos X="22" Y="23"/>
<UsageCount Value="85"/>
<Loaded Value="True"/>
</Unit6>
<Unit7>
<Filename Value="..\utils\uvkuDevice.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="62"/>
<CursorPos X="35" Y="67"/>
<UsageCount Value="84"/>
<EditorIndex Value="10"/>
<TopLine Value="28"/>
<CursorPos X="14" Y="29"/>
<UsageCount Value="89"/>
<Loaded Value="True"/>
</Unit7>
<Unit8>
<Filename Value="..\utils\uvkuDeviceFactory.pas"/>
@@ -85,7 +94,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="11"/>
<CursorPos X="10" Y="18"/>
<UsageCount Value="82"/>
<UsageCount Value="87"/>
</Unit8>
<Unit9>
<Filename Value="..\utils\uvkuSurface.pas"/>
@@ -93,7 +102,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="41"/>
<CursorPos X="94" Y="56"/>
<UsageCount Value="77"/>
<UsageCount Value="82"/>
</Unit9>
<Unit10>
<Filename Value="..\utils\uvkuSurfaceFactory.pas"/>
@@ -101,14 +110,14 @@
<EditorIndex Value="-1"/>
<TopLine Value="44"/>
<CursorPos X="33" Y="60"/>
<UsageCount Value="76"/>
<UsageCount Value="81"/>
</Unit10>
<Unit11>
<Filename Value="..\utils\uvkuSwapChainFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="6"/>
<EditorIndex Value="14"/>
<CursorPos X="3" Y="13"/>
<UsageCount Value="67"/>
<UsageCount Value="72"/>
<Loaded Value="True"/>
</Unit11>
<Unit12>
@@ -117,7 +126,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="7"/>
<CursorPos X="36" Y="23"/>
<UsageCount Value="66"/>
<UsageCount Value="71"/>
</Unit12>
<Unit13>
<Filename Value="..\utils\uvkuImageView.pas"/>
@@ -125,7 +134,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="29"/>
<CursorPos X="64" Y="47"/>
<UsageCount Value="63"/>
<UsageCount Value="68"/>
</Unit13>
<Unit14>
<Filename Value="..\utils\uvkuImageViewFactory.pas"/>
@@ -133,32 +142,33 @@
<EditorIndex Value="-1"/>
<TopLine Value="24"/>
<CursorPos X="60" Y="88"/>
<UsageCount Value="63"/>
<UsageCount Value="68"/>
</Unit14>
<Unit15>
<Filename Value="..\utils\uvkuImage.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="48"/>
<CursorPos X="17" Y="64"/>
<UsageCount Value="62"/>
<EditorIndex Value="9"/>
<TopLine Value="208"/>
<CursorPos Y="58"/>
<UsageCount Value="67"/>
<Loaded Value="True"/>
</Unit15>
<Unit16>
<Filename Value="..\utils\uvkuBase.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="2"/>
<TopLine Value="16"/>
<CursorPos X="15" Y="32"/>
<UsageCount Value="61"/>
<EditorIndex Value="3"/>
<TopLine Value="10"/>
<CursorPos X="3" Y="26"/>
<UsageCount Value="66"/>
<Loaded Value="True"/>
</Unit16>
<Unit17>
<Filename Value="..\utils\uvkuDeviceMemory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="33"/>
<CursorPos X="79" Y="44"/>
<UsageCount Value="59"/>
<EditorIndex Value="11"/>
<CursorPos X="35" Y="75"/>
<UsageCount Value="64"/>
<Loaded Value="True"/>
</Unit17>
<Unit18>
<Filename Value="..\utils\uvkuBuffer.pas"/>
@@ -166,23 +176,25 @@
<EditorIndex Value="-1"/>
<TopLine Value="10"/>
<CursorPos X="3" Y="13"/>
<UsageCount Value="58"/>
<UsageCount Value="63"/>
</Unit18>
<Unit19>
<Filename Value="..\utils\uvkuImageFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="20"/>
<CursorPos X="60" Y="74"/>
<UsageCount Value="58"/>
<EditorIndex Value="8"/>
<TopLine Value="32"/>
<CursorPos Y="41"/>
<UsageCount Value="63"/>
<Loaded Value="True"/>
</Unit19>
<Unit20>
<Filename Value="..\utils\uvkuTypes.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="79"/>
<CursorPos Y="95"/>
<UsageCount Value="58"/>
<EditorIndex Value="16"/>
<TopLine Value="63"/>
<CursorPos X="75" Y="77"/>
<UsageCount Value="63"/>
<Loaded Value="True"/>
</Unit20>
<Unit21>
<Filename Value="..\utils\uvkuBufferFactory.pas"/>
@@ -190,7 +202,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="20"/>
<CursorPos X="60" Y="58"/>
<UsageCount Value="57"/>
<UsageCount Value="62"/>
</Unit21>
<Unit22>
<Filename Value="..\utils\uvkuBufferView.pas"/>
@@ -198,57 +210,58 @@
<EditorIndex Value="-1"/>
<TopLine Value="52"/>
<CursorPos X="56" Y="76"/>
<UsageCount Value="57"/>
<UsageCount Value="62"/>
</Unit22>
<Unit23>
<Filename Value="..\utils\uvkuBufferViewFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="31" Y="45"/>
<UsageCount Value="56"/>
<UsageCount Value="61"/>
</Unit23>
<Unit24>
<Filename Value="..\utils\uvkuCommandPool.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="8"/>
<TopLine Value="61"/>
<CursorPos X="39" Y="77"/>
<UsageCount Value="56"/>
<EditorIndex Value="17"/>
<TopLine Value="9"/>
<CursorPos X="50" Y="27"/>
<UsageCount Value="61"/>
<Loaded Value="True"/>
</Unit24>
<Unit25>
<Filename Value="..\utils\uvkuCommandPoolFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="9"/>
<EditorIndex Value="18"/>
<TopLine Value="23"/>
<CursorPos X="3" Y="34"/>
<UsageCount Value="55"/>
<UsageCount Value="60"/>
<Loaded Value="True"/>
</Unit25>
<Unit26>
<Filename Value="..\utils\uvkuCommandBuffer.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="7"/>
<TopLine Value="45"/>
<CursorPos X="91" Y="71"/>
<UsageCount Value="55"/>
<EditorIndex Value="15"/>
<TopLine Value="46"/>
<CursorPos X="74" Y="70"/>
<UsageCount Value="60"/>
<Loaded Value="True"/>
</Unit26>
<Unit27>
<Filename Value="..\utils\uvkuQueue.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="5"/>
<CursorPos Y="12"/>
<UsageCount Value="55"/>
<EditorIndex Value="13"/>
<TopLine Value="55"/>
<CursorPos X="75" Y="76"/>
<UsageCount Value="60"/>
<Loaded Value="True"/>
</Unit27>
<Unit28>
<Filename Value="..\utils\VulkanUtils.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="5"/>
<TopLine Value="50"/>
<CursorPos X="3" Y="66"/>
<UsageCount Value="54"/>
<EditorIndex Value="12"/>
<TopLine Value="65"/>
<CursorPos X="3" Y="72"/>
<UsageCount Value="59"/>
<Loaded Value="True"/>
</Unit28>
<Unit29>
@@ -256,29 +269,30 @@
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="14"/>
<UsageCount Value="71"/>
<UsageCount Value="76"/>
</Unit29>
<Unit30>
<Filename Value="..\utils\uvkuRenderPass.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="3" Y="13"/>
<UsageCount Value="52"/>
<UsageCount Value="57"/>
</Unit30>
<Unit31>
<Filename Value="..\utils\uvkuRenderPassFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="82" Y="11"/>
<UsageCount Value="52"/>
<UsageCount Value="57"/>
</Unit31>
<Unit32>
<Filename Value="..\utils\uvkuFactoryBase.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<EditorIndex Value="1"/>
<TopLine Value="69"/>
<CursorPos X="12" Y="82"/>
<UsageCount Value="52"/>
<CursorPos X="42" Y="88"/>
<UsageCount Value="57"/>
<Loaded Value="True"/>
</Unit32>
<Unit33>
<Filename Value="..\utils\uvkuFrameBuffer.pas"/>
@@ -286,7 +300,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="33"/>
<CursorPos X="150" Y="40"/>
<UsageCount Value="50"/>
<UsageCount Value="55"/>
</Unit33>
<Unit34>
<Filename Value="..\utils\uvkuFrameBufferFactory.pas"/>
@@ -294,14 +308,14 @@
<EditorIndex Value="-1"/>
<TopLine Value="12"/>
<CursorPos X="25" Y="27"/>
<UsageCount Value="50"/>
<UsageCount Value="55"/>
</Unit34>
<Unit35>
<Filename Value="..\utils\uvkuDescriptorSetLayout.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="150" Y="12"/>
<UsageCount Value="50"/>
<UsageCount Value="55"/>
</Unit35>
<Unit36>
<Filename Value="..\utils\uvkuDescriptorSetLayoutFactory.pas"/>
@@ -309,7 +323,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="89"/>
<CursorPos X="3" Y="106"/>
<UsageCount Value="49"/>
<UsageCount Value="54"/>
</Unit36>
<Unit37>
<Filename Value="..\utils\uvkuPipelineLayout.pas"/>
@@ -317,7 +331,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="48"/>
<CursorPos X="150" Y="53"/>
<UsageCount Value="49"/>
<UsageCount Value="54"/>
</Unit37>
<Unit38>
<Filename Value="..\utils\uvkuPipelineLayoutFactory.pas"/>
@@ -325,7 +339,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="10"/>
<CursorPos X="37" Y="112"/>
<UsageCount Value="49"/>
<UsageCount Value="54"/>
</Unit38>
<Unit39>
<Filename Value="..\utils\uvkuShaderModule.pas"/>
@@ -333,7 +347,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="54"/>
<CursorPos X="3" Y="67"/>
<UsageCount Value="47"/>
<UsageCount Value="52"/>
</Unit39>
<Unit40>
<Filename Value="..\utils\uvkuShaderModuleFactory.pas"/>
@@ -341,7 +355,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="117"/>
<CursorPos X="37" Y="127"/>
<UsageCount Value="47"/>
<UsageCount Value="52"/>
</Unit40>
<Unit41>
<Filename Value="..\utils\uvkuPipeline.pas"/>
@@ -349,7 +363,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="7"/>
<CursorPos X="23" Y="92"/>
<UsageCount Value="45"/>
<UsageCount Value="50"/>
</Unit41>
<Unit42>
<Filename Value="..\utils\uvkuPipelineFactory.pas"/>
@@ -357,280 +371,298 @@
<EditorIndex Value="-1"/>
<TopLine Value="7"/>
<CursorPos X="3" Y="23"/>
<UsageCount Value="44"/>
<UsageCount Value="49"/>
</Unit42>
<Unit43>
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="2"/>
<TopLine Value="102"/>
<CursorPos Y="119"/>
<UsageCount Value="27"/>
<Loaded Value="True"/>
</Unit43>
<Unit44>
<Filename Value="..\utils\uvkuPhysicalDeviceFactory.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="5"/>
<CursorPos X="19" Y="17"/>
<UsageCount Value="46"/>
</Unit43>
<Unit44>
</Unit44>
<Unit45>
<Filename Value="..\..\data\Vulkan.tpl"/>
<EditorIndex Value="-1"/>
<TopLine Value="44"/>
<CursorPos X="27" Y="22"/>
<UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit44>
<Unit45>
</Unit45>
<Unit46>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\packages\fcl-base\src\custapp.pp"/>
<UnitName Value="CustApp"/>
<EditorIndex Value="-1"/>
<TopLine Value="13"/>
<CursorPos X="3" Y="30"/>
<UsageCount Value="6"/>
</Unit45>
<Unit46>
</Unit46>
<Unit47>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\inc\objpash.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="181"/>
<CursorPos X="23" Y="197"/>
<UsageCount Value="10"/>
</Unit46>
<Unit47>
</Unit47>
<Unit48>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\customform.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="910"/>
<CursorPos Y="927"/>
<UsageCount Value="10"/>
</Unit47>
<Unit48>
</Unit48>
<Unit49>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\objpas\sysutils\sysstrh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="96"/>
<CursorPos X="10" Y="112"/>
<UsageCount Value="6"/>
</Unit48>
<Unit49>
</Unit49>
<Unit50>
<Filename Value="..\Vulkan_old.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="2195"/>
<CursorPos X="3" Y="2211"/>
<UsageCount Value="6"/>
</Unit49>
<Unit50>
</Unit50>
<Unit51>
<Filename Value="..\Vulkan.inc"/>
<EditorIndex Value="-1"/>
<UsageCount Value="10"/>
</Unit50>
<Unit51>
</Unit51>
<Unit52>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\forms.pp"/>
<UnitName Value="Forms"/>
<EditorIndex Value="-1"/>
<TopLine Value="1249"/>
<CursorPos X="3" Y="1268"/>
<UsageCount Value="6"/>
</Unit51>
<Unit52>
</Unit52>
<Unit53>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\objpas\classes\classesh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="2100"/>
<CursorPos X="38" Y="2125"/>
<UsageCount Value="6"/>
</Unit52>
<Unit53>
</Unit53>
<Unit54>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\extctrls.pp"/>
<UnitName Value="ExtCtrls"/>
<EditorIndex Value="-1"/>
<TopLine Value="1023"/>
<CursorPos X="3" Y="1038"/>
<UsageCount Value="6"/>
</Unit53>
<Unit54>
</Unit54>
<Unit55>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\controls.pp"/>
<UnitName Value="Controls"/>
<EditorIndex Value="-1"/>
<TopLine Value="2240"/>
<CursorPos X="3" Y="2255"/>
<UsageCount Value="6"/>
</Unit54>
<Unit55>
</Unit55>
<Unit56>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\objpas\sysutils\sysutilh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="22"/>
<CursorPos X="4" Y="37"/>
<UsageCount Value="8"/>
</Unit55>
<Unit56>
</Unit56>
<Unit57>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win\sysosh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="7"/>
<CursorPos X="3" Y="22"/>
<UsageCount Value="8"/>
</Unit56>
<Unit57>
</Unit57>
<Unit58>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\inc\systemh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="93"/>
<CursorPos X="19" Y="108"/>
<UsageCount Value="8"/>
</Unit57>
<Unit58>
</Unit58>
<Unit59>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win\wininc\ascdef.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="57"/>
<CursorPos X="10" Y="72"/>
<UsageCount Value="8"/>
</Unit58>
<Unit59>
</Unit59>
<Unit60>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win32\windows.pp"/>
<EditorIndex Value="-1"/>
<UsageCount Value="8"/>
</Unit59>
<Unit60>
</Unit60>
<Unit61>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\3.1.1\source\rtl\win\wininc\base.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="84"/>
<CursorPos X="6" Y="99"/>
<UsageCount Value="8"/>
</Unit60>
<Unit61>
</Unit61>
<Unit62>
<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>
</Unit62>
<Unit63>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\application.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="2148"/>
<CursorPos Y="2163"/>
<UsageCount Value="10"/>
</Unit62>
<Unit63>
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
</Unit63>
<Unit64>
<Filename Value="..\utils\uvkuPipelineCache.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="1"/>
<TopLine Value="102"/>
<CursorPos Y="119"/>
<UsageCount Value="22"/>
<EditorIndex Value="5"/>
<TopLine Value="18"/>
<CursorPos X="13" Y="38"/>
<UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit63>
</Unit64>
<Unit65>
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="6"/>
<TopLine Value="33"/>
<CursorPos X="84" Y="61"/>
<UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit65>
</Units>
<JumpHistory Count="30" HistoryIndex="25">
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="uMainForm.pas"/>
<Caret Line="122" Column="83" TopLine="107"/>
<Filename Value="..\utils\uvkuPipelineCache.pas"/>
<Caret Line="18" Column="67" TopLine="6"/>
</Position1>
<Position2>
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
<Caret Line="109" TopLine="90"/>
<Filename Value="..\utils\uvkuPipelineCache.pas"/>
<Caret Line="72" Column="33" TopLine="40"/>
</Position2>
<Position3>
<Filename Value="uMainForm.pas"/>
<Caret Line="512" Column="22" TopLine="486"/>
<Filename Value="..\utils\uvkuPipelineCache.pas"/>
<Caret Line="15" Column="5"/>
</Position3>
<Position4>
<Filename Value="uMainForm.pas"/>
<Caret Line="33" Column="5" TopLine="16"/>
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/>
<Caret Line="16" Column="53"/>
</Position4>
<Position5>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="47" Column="3" TopLine="31"/>
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/>
<Caret Line="20" Column="72"/>
</Position5>
<Position6>
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
<Caret Line="117" TopLine="102"/>
<Filename Value="..\utils\uvkuPipelineCacheFactory.pas"/>
<Caret Line="43" Column="10" TopLine="21"/>
</Position6>
<Position7>
<Filename Value="uMainForm.pas"/>
<Caret Line="512" TopLine="486"/>
<Filename Value="..\utils\uvkuPipelineCache.pas"/>
<Caret Line="12"/>
</Position7>
<Position8>
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
<Caret Line="117" TopLine="102"/>
<Filename Value="..\utils\uvkuPipelineCache.pas"/>
<Caret Line="38" Column="13" TopLine="29"/>
</Position8>
<Position9>
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
<Caret Line="118" Column="83" TopLine="102"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="340" Column="45" TopLine="327"/>
</Position9>
<Position10>
<Filename Value="uMainForm.pas"/>
<Caret Line="512" TopLine="486"/>
<Caret Line="532" Column="19" TopLine="511"/>
</Position10>
<Position11>
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
<Caret Line="117" TopLine="102"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="51" TopLine="33"/>
</Position11>
<Position12>
<Filename Value="..\utils\uvkuDebugReporter.pas"/>
<Caret Line="118" TopLine="102"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="275" Column="37" TopLine="253"/>
</Position12>
<Position13>
<Filename Value="uMainForm.pas"/>
<Caret Line="253" Column="27" TopLine="242"/>
<Filename Value="..\utils\uvkuCommandBuffer.pas"/>
<Caret Line="24" Column="18" TopLine="7"/>
</Position13>
<Position14>
<Filename Value="uMainForm.pas"/>
<Caret Line="94" Column="3" TopLine="77"/>
<Caret Line="275" Column="37" TopLine="253"/>
</Position14>
<Position15>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="82" Column="3" TopLine="66"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="540" Column="12" TopLine="531"/>
</Position15>
<Position16>
<Filename Value="uMainForm.pas"/>
<Caret Line="261" TopLine="248"/>
<Caret Line="38" Column="5" TopLine="21"/>
</Position16>
<Position17>
<Filename Value="uMainForm.pas"/>
<Caret Line="49" Column="5" TopLine="34"/>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="72" Column="3" TopLine="65"/>
</Position17>
<Position18>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="83" Column="3" TopLine="67"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="21" Column="71" TopLine="3"/>
</Position18>
<Position19>
<Filename Value="..\utils\uvkuCommandBuffer.pas"/>
<Caret Line="23" Column="28" TopLine="4"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="37" Column="14" TopLine="12"/>
</Position19>
<Position20>
<Filename Value="..\utils\uvkuCommandBuffer.pas"/>
<Caret Line="43" Column="22" TopLine="23"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="34" Column="5" TopLine="17"/>
</Position20>
<Position21>
<Filename Value="..\utils\uvkuCommandBuffer.pas"/>
<Caret Line="45" Column="28" TopLine="23"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="49" Column="45" TopLine="21"/>
</Position21>
<Position22>
<Filename Value="uMainForm.pas"/>
<Caret Line="304" Column="42" TopLine="292"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="54" Column="59" TopLine="39"/>
</Position22>
<Position23>
<Filename Value="uMainForm.pas"/>
<Caret Line="259" Column="16" TopLine="244"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="26" Column="30" TopLine="5"/>
</Position23>
<Position24>
<Filename Value="uMainForm.pas"/>
<Caret Line="261" Column="33" TopLine="245"/>
<Caret Line="38" Column="5" TopLine="21"/>
</Position24>
<Position25>
<Filename Value="..\Vulkan.pas"/>
<Caret Line="2887" Column="86" TopLine="2871"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="24" Column="36" TopLine="5"/>
</Position25>
<Position26>
<Filename Value="uMainForm.pas"/>
<Caret Line="315" Column="60" TopLine="300"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="26" Column="52" TopLine="10"/>
</Position26>
<Position27>
<Filename Value="uMainForm.pas"/>
<Caret Line="95" Column="3" TopLine="78"/>
<Caret Line="38" Column="5" TopLine="20"/>
</Position27>
<Position28>
<Filename Value="..\utils\VulkanUtils.pas"/>
<Caret Line="66" Column="3" TopLine="50"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="541" Column="10" TopLine="524"/>
</Position28>
<Position29>
<Filename Value="..\utils\uvkuSwapChainFactory.pas"/>
<Caret Line="13" Column="3"/>
<Filename Value="..\utils\uvkuQueue.pas"/>
<Caret Line="27" Column="24" TopLine="5"/>
</Position29>
<Position30>
<Filename Value="..\utils\uvkuSwapChainFactory.pas"/>
<Caret Line="23" Column="38"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="541" Column="10" TopLine="524"/>
</Position30>
</JumpHistory>
</ProjectSession>


+ 477
- 336
projects/triangle/uMainForm.pas 查看文件

@@ -28,6 +28,7 @@ type
fPresentQueueNodeIndex: VkUint32;
fSurfaceFormat: TVkFormat;
fSurfaceColorSpace: TVkColorSpaceKHR;
fDepthFormat: TVkFormat;

fAllocHandler: TCustomAllocHandler;
fDebugReporter: TvkuConsoleDebugReporter;
@@ -37,6 +38,7 @@ type
fQueue: TvkuQueue;
fSurface: TvkuSurface;
fSwapChain: TvkuSwapChain;
fImages: array of TvkuImage;
fImageViews: array of TvkuImageView;
fRenderPass: TvkuRenderPass;
fFrameBuffers: array of TvkuFrameBuffer;
@@ -46,7 +48,11 @@ type
fFragmentShader: TvkuShaderModule;
fPipeline: TvkuGraphicsPipeline;
fCommandPool: TvkuCommandPool;
fCommandBuffer: TvkuCommandBuffer;
fDrawCommandBuffers: array of TvkuCommandBuffer;
fPostPresentCommandBuffer: TvkuCommandBuffer;
fDepthStencilImage: TvkuImage;
fDepthStencilImageView: TvkuImageView;
fPipelineCache: TvkuPipelineCache;
end;

var
@@ -93,6 +99,7 @@ var
SurfaceFactory: TvkuSurfaceFactory;
CommandPoolFactory: TvkuCommandPoolFactory;
SwapChainFactory: TvkuSwapChainFactory;
ImageFactory: TvkuImageFactory;
ImageViewFactory: TvkuImageViewFactory;
RenderPassFactory: TvkuRenderPassFactory;
FrameBufferFactory: TvkuFrameBufferFactory;
@@ -100,9 +107,10 @@ var
PipelineLayoutFactory: TvkuPipelineLayoutFactory;
ShaderModuleFactory: TvkuShaderModuleFactory;
PipelineFactory: TvkuGraphicsPipelineFactory;
PipelineCacheFactory: TvkuPipelineCacheFactory;

SetupCommandBuffer: TvkuCommandBuffer;
QueueFamProps: TVkQueueFamilyPropertiesArr;
DepthFormat: TVkFormat;
f: TVkFormat;
i: Integer;
SrfFormats: TVkSurfaceFormatArr;
@@ -110,385 +118,495 @@ var
PresentModes: TVkPresentModeArr;
pm: TVkPresentModeKHR;
Images: TVkImageArr;
ComponentMapping: TVkComponentMapping;
AllocCallbacks: TVkAllocationCallbacks;
ImageMemoryBarrier: TVkImageMemoryBarrier;
CommandBuffers: TVkCommandBufferArr;
begin
fAllocHandler := TCustomAllocHandler.Create;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create instance: ');
InstanceFactory := TvkuInstanceFactory.Create;
try
InstanceFactory.AllocHandler := fAllocHandler;
InstanceFactory.EnabledExtensionNames.Add(VK_KHR_SURFACE_EXTENSION_NAME);
InstanceFactory.EnabledExtensionNames.Add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
InstanceFactory.EnabledExtensionNames.Add(TvkuSurface.GetPlatformSurfaceExtensionName);
fInstance := InstanceFactory.CreateInstance;
WriteLn(' handle: ', PtrUInt(fInstance.Handle));
WriteLn(' done');
finally
FreeAndNil(InstanceFactory);
end;

fDebugReporter := TvkuConsoleDebugReporter.Create(fInstance.InstanceCommands, fAllocHandler);

//////////////////////////////////////////////////////////////////////////////
WriteLn('find suitable physical device');
PhyDevices := fInstance.GetPhysicalDevices;
if (Length(PhyDevices) <= 0) then
raise TvkuException.Create('unable to get physical device');
fPhyDevice := TvkuPhysicalDevice.Create(PhyDevices[0], fInstance.InstanceCommands);
WriteLn(' handle: ', PtrUInt(fPhyDevice.Handle));

Write(' find suitable graphics queue index... ');
QueueFamProps := fPhyDevice.GetQueueFamilyProperties;
fGraphicsQueueFamilyIndex := high(fGraphicsQueueFamilyIndex);
for i := low(QueueFamProps) to high(QueueFamProps) do begin
if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then begin
fGraphicsQueueFamilyIndex := i;
WriteLn(fGraphicsQueueFamilyIndex);
break;
end;
end;
if (fGraphicsQueueFamilyIndex = high(fGraphicsQueueFamilyIndex)) then
raise TvkuException.Create('unable to find graphics queue index');

Write(' find suitable depth format... ');
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;
fAllocHandler := TCustomAllocHandler.Create;
AllocCallbacks := fAllocHandler.GetStructure;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create instance: ');
InstanceFactory := TvkuInstanceFactory.Create;
try
InstanceFactory.AllocHandler := fAllocHandler;
InstanceFactory.EnabledExtensionNames.Add(VK_KHR_SURFACE_EXTENSION_NAME);
InstanceFactory.EnabledExtensionNames.Add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
InstanceFactory.EnabledExtensionNames.Add(TvkuSurface.GetPlatformSurfaceExtensionName);
fInstance := InstanceFactory.CreateInstance;
WriteLn(' handle: ', PtrUInt(fInstance.Handle));
WriteLn(' done');
finally
FreeAndNil(InstanceFactory);
end;
end;
WriteLn(DepthFormat);
WriteLn(' done');

//////////////////////////////////////////////////////////////////////////////
WriteLn('create device');
DeviceFactory := TvkuDeviceFactory.Create(fInstance);
try
DeviceFactory.AllocHandler := fAllocHandler;
DeviceFactory.EnabledExtensions.Add('VK_KHR_swapchain');
DeviceFactory.QueueCreateInfos.Length := 1;
with DeviceFactory.QueueCreateInfos[0] do begin
Flags := 0;
QueueFamilyIndex := fGraphicsQueueFamilyIndex;
QueuePriorities.Length := 1;
QueuePriorities[0] := 1.0;
end;
fDevice := DeviceFactory.CreateDevice(fPhyDevice.Handle);
WriteLn(' handle: ', PtrUInt(fDevice.Handle));
WriteLn(' done');
finally
FreeAndNil(DeviceFactory);
end;
fDebugReporter := TvkuConsoleDebugReporter.Create(fInstance.InstanceCommands, fAllocHandler);

//////////////////////////////////////////////////////////////////////////////
WriteLn('find suitable queue');
fQueue := TvkuQueue.Create(fDevice.GetQueue(fGraphicsQueueFamilyIndex, 0), fDevice.DeviceCommands);
WriteLn(' handle: ', PtrUInt(fQueue.Handle));
WriteLn(' done');
//////////////////////////////////////////////////////////////////////////////
WriteLn('find suitable physical device');
PhyDevices := fInstance.GetPhysicalDevices;
if (Length(PhyDevices) <= 0) then
raise TvkuException.Create('unable to get physical device');
fPhyDevice := TvkuPhysicalDevice.Create(PhyDevices[0], fInstance.InstanceCommands);
WriteLn(' handle: ', PtrUInt(fPhyDevice.Handle));

//////////////////////////////////////////////////////////////////////////////
WriteLn('create surface: ');
SurfaceFactory := TvkuSurfaceFactory.Create(fInstance);
try
SurfaceFactory.AllocHandler := fAllocHandler;
SurfaceFactory.WinControl := RenderPanel;
fSurface := SurfaceFactory.CreateSurface;
WriteLn(' handle: ', PtrUInt(fSurface.Handle));

WriteLn(' find suitable graphics and present queue node index');
fGraphicsQueueNodeIndex := high(fGraphicsQueueNodeIndex);
fPresentQueueNodeIndex := high(fPresentQueueNodeIndex);
QueueFamProps := fPhyDevice.GetQueueFamilyProperties;
Write(' find suitable graphics queue index... ');
QueueFamProps := fPhyDevice.GetQueueFamilyProperties;
fGraphicsQueueFamilyIndex := high(fGraphicsQueueFamilyIndex);
for i := low(QueueFamProps) to high(QueueFamProps) do begin
if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then
fGraphicsQueueNodeIndex := i;

if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin
fGraphicsQueueNodeIndex := i;
fPresentQueueNodeIndex := i;
if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then begin
fGraphicsQueueFamilyIndex := i;
WriteLn(fGraphicsQueueFamilyIndex);
break;
end;
end;
if (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) then begin
for i := low(QueueFamProps) to high(QueueFamProps) do begin
if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin
fPresentQueueNodeIndex := i;
break;
end;
if (fGraphicsQueueFamilyIndex = high(fGraphicsQueueFamilyIndex)) then
raise TvkuException.Create('unable to find graphics queue index');

Write(' find suitable depth format... ');
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
fDepthFormat := f;
break;
end;
end;
WriteLn(' graphics queue node index: ', fGraphicsQueueNodeIndex);
WriteLn(' present queue node index: ', fPresentQueueNodeIndex);
if (fGraphicsQueueNodeIndex = high(fGraphicsQueueNodeIndex)) or
(fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) or
(fPresentQueueNodeIndex <> fGraphicsQueueNodeIndex) then
raise TvkuException.Create('different graphic and present queue node index is not supported yet');

WriteLn(' find suitable image format');
SrfFormats := fPhyDevice.GetSurfaceFormats(fSurface.Handle);
if (Length(SrfFormats) = 0) then
raise TvkuException.Create('no suitable formats found');
if (Length(SrfFormats) = 1) and (SrfFormats[0].format = VK_FORMAT_UNDEFINED) then begin
fSurfaceFormat := VK_FORMAT_R8G8B8A8_UNORM;
fSurfaceColorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR;
end else begin
fSurfaceFormat := SrfFormats[0].format;
fSurfaceColorSpace := SrfFormats[0].colorSpace;
WriteLn(fDepthFormat);
WriteLn(' done');

//////////////////////////////////////////////////////////////////////////////
WriteLn('create device');
DeviceFactory := TvkuDeviceFactory.Create(fInstance);
try
DeviceFactory.AllocHandler := fAllocHandler;
DeviceFactory.EnabledExtensions.Add('VK_KHR_swapchain');
DeviceFactory.QueueCreateInfos.Length := 1;
with DeviceFactory.QueueCreateInfos[0] do begin
Flags := 0;
QueueFamilyIndex := fGraphicsQueueFamilyIndex;
QueuePriorities.Length := 1;
QueuePriorities[0] := 1.0;
end;
fDevice := DeviceFactory.CreateDevice(fPhyDevice.Handle);
WriteLn(' handle: ', PtrUInt(fDevice.Handle));
WriteLn(' done');
finally
FreeAndNil(DeviceFactory);
end;
WriteLn(' format: ', fSurfaceFormat);
WriteLn(' color space: ', fSurfaceColorSpace);

//////////////////////////////////////////////////////////////////////////////
WriteLn('find suitable queue');
fQueue := TvkuQueue.Create(fDevice.GetQueue(fGraphicsQueueFamilyIndex, 0), fDevice.DeviceCommands);
WriteLn(' handle: ', PtrUInt(fQueue.Handle));
WriteLn(' done');
finally
FreeAndNil(SurfaceFactory);
end;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create command pool');
CommandPoolFactory := TvkuCommandPoolFactory.Create(fDevice);
try
CommandPoolFactory.Flags := [ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT ];
CommandPoolFactory.QueueFamilyIndex := fGraphicsQueueNodeIndex;
fCommandPool := CommandPoolFactory.CreateCommandPool;
WriteLn(' handle: ', PtrUInt(fCommandPool.Handle));
//////////////////////////////////////////////////////////////////////////////
WriteLn('create surface: ');
SurfaceFactory := TvkuSurfaceFactory.Create(fInstance);
try
SurfaceFactory.AllocHandler := fAllocHandler;
SurfaceFactory.WinControl := RenderPanel;
fSurface := SurfaceFactory.CreateSurface;
WriteLn(' handle: ', PtrUInt(fSurface.Handle));

WriteLn(' find suitable graphics and present queue node index');
fGraphicsQueueNodeIndex := high(fGraphicsQueueNodeIndex);
fPresentQueueNodeIndex := high(fPresentQueueNodeIndex);
QueueFamProps := fPhyDevice.GetQueueFamilyProperties;
for i := low(QueueFamProps) to high(QueueFamProps) do begin
if (VK_QUEUE_GRAPHICS_BIT in QueueFamProps[i].queueFlags) then
fGraphicsQueueNodeIndex := i;

WriteLn(' alloc command buffer');
fCommandBuffer := TvkuCommandBuffer.Create(
fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY),
true, fCommandPool.Handle, fDevice.DeviceCommands);
WriteLn(' handle: ', PtrUInt(fCommandBuffer.Handle));
WriteLn(' done');
finally
FreeAndNil(CommandPoolFactory);
end;
if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin
fGraphicsQueueNodeIndex := i;
fPresentQueueNodeIndex := i;
break;
end;
end;
if (fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) then begin
for i := low(QueueFamProps) to high(QueueFamProps) do begin
if fPhyDevice.GetSurfaceSupport(i, fSurface.Handle) then begin
fPresentQueueNodeIndex := i;
break;
end;
end;
end;
WriteLn(' graphics queue node index: ', fGraphicsQueueNodeIndex);
WriteLn(' present queue node index: ', fPresentQueueNodeIndex);
if (fGraphicsQueueNodeIndex = high(fGraphicsQueueNodeIndex)) or
(fPresentQueueNodeIndex = high(fPresentQueueNodeIndex)) or
(fPresentQueueNodeIndex <> fGraphicsQueueNodeIndex) then
raise TvkuException.Create('different graphic and present queue node index is not supported yet');

WriteLn(' find suitable image format');
SrfFormats := fPhyDevice.GetSurfaceFormats(fSurface.Handle);
if (Length(SrfFormats) = 0) then
raise TvkuException.Create('no suitable formats found');
if (Length(SrfFormats) = 1) and (SrfFormats[0].format = VK_FORMAT_UNDEFINED) then begin
fSurfaceFormat := VK_FORMAT_R8G8B8A8_UNORM;
fSurfaceColorSpace := VK_COLORSPACE_SRGB_NONLINEAR_KHR;
end else begin
fSurfaceFormat := SrfFormats[0].format;
fSurfaceColorSpace := SrfFormats[0].colorSpace;
end;
WriteLn(' format: ', fSurfaceFormat);
WriteLn(' color space: ', fSurfaceColorSpace);

//////////////////////////////////////////////////////////////////////////////
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;
SwapChainFactory.ImageSharingMode := VK_SHARING_MODE_EXCLUSIVE;
SwapChainFactory.Clipped := true;
SwapChainFactory.ComposideAlpha := [ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR ];
SwapChainFactory.ImageFormat := fSurfaceFormat;
SwapChainFactory.ImageColorSpace := fSurfaceColorSpace;

WriteLn(' get surface capabilities');
SurfaceCapabilities := fPhyDevice.GetSurfaceCapabilities(fSurface.Handle);
if (SurfaceCapabilities.currentExtent.width = High(VkUint32)) then begin
SurfaceCapabilities.currentExtent.width := ClientWidth;
SurfaceCapabilities.currentExtent.height := ClientHeight;
end else begin
ClientWidth := SurfaceCapabilities.currentExtent.width;
ClientHeight := SurfaceCapabilities.currentExtent.height;
WriteLn(' done');
finally
FreeAndNil(SurfaceFactory);
end;
WriteLn(' width: ', SurfaceCapabilities.currentExtent.width);
WriteLn(' height: ', SurfaceCapabilities.currentExtent.height);
SwapChainFactory.ImageExtent := SurfaceCapabilities.currentExtent;

Write(' set min image count... ');
SwapChainFactory.MinImageCount := SurfaceCapabilities.minImageCount + 1;
if (SurfaceCapabilities.maxImageCount > 0) and
(SwapChainFactory.MinImageCount > SurfaceCapabilities.maxImageCount) then
SwapChainFactory.MinImageCount := SurfaceCapabilities.maxImageCount;
WriteLn(SwapChainFactory.MinImageCount);

WriteLn(' set pre transform...');
SwapChainFactory.PreTransform := SurfaceCapabilities.currentTransform;
if (VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR in SurfaceCapabilities.supportedTransforms) then
SwapChainFactory.PreTransform := [ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR ];

Write(' find suitable present mode... ');
PresentModes := fPhyDevice.GetSurfacePresentModes(fSurface.Handle);
if (Length(PresentModes) = 0) then
raise TvkuException.Create('unable to get present modes');
for pm in PresentModes do begin
if (pm = VK_PRESENT_MODE_MAILBOX_KHR) then begin
SwapChainFactory.PresentMode := pm;
break;
end;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create command pool');
CommandPoolFactory := TvkuCommandPoolFactory.Create(fDevice);
try
CommandPoolFactory.Flags := [ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT ];
CommandPoolFactory.QueueFamilyIndex := fGraphicsQueueNodeIndex;
fCommandPool := CommandPoolFactory.CreateCommandPool;
WriteLn(' handle: ', PtrUInt(fCommandPool.Handle));

WriteLn(' alloc setup command buffer');
SetupCommandBuffer := TvkuCommandBuffer.Create(
fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY),
true, fCommandPool.Handle, fDevice.DeviceCommands);
SetupCommandBuffer.BeginCommand;
WriteLn(' handle: ', PtrUInt(SetupCommandBuffer.Handle));
WriteLn(' done');
finally
FreeAndNil(CommandPoolFactory);
end;
WriteLn(SwapChainFactory.PresentMode);

fSwapChain := SwapChainFactory.CreateSwapchain;
WriteLn(' handle: ', PtrUInt(fSwapChain.Handle));
WriteLn(' done');
finally
FreeAndNil(SwapChainFactory);
end;
//////////////////////////////////////////////////////////////////////////////
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;
SwapChainFactory.ImageSharingMode := VK_SHARING_MODE_EXCLUSIVE;
SwapChainFactory.Clipped := true;
SwapChainFactory.ComposideAlpha := [ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR ];
SwapChainFactory.ImageFormat := fSurfaceFormat;
SwapChainFactory.ImageColorSpace := fSurfaceColorSpace;

WriteLn(' get surface capabilities');
SurfaceCapabilities := fPhyDevice.GetSurfaceCapabilities(fSurface.Handle);
if (SurfaceCapabilities.currentExtent.width = High(VkUint32)) then begin
SurfaceCapabilities.currentExtent.width := ClientWidth;
SurfaceCapabilities.currentExtent.height := ClientHeight;
end else begin
ClientWidth := SurfaceCapabilities.currentExtent.width;
ClientHeight := SurfaceCapabilities.currentExtent.height;
end;
WriteLn(' width: ', SurfaceCapabilities.currentExtent.width);
WriteLn(' height: ', SurfaceCapabilities.currentExtent.height);
SwapChainFactory.ImageExtent := SurfaceCapabilities.currentExtent;

Write(' set min image count... ');
SwapChainFactory.MinImageCount := SurfaceCapabilities.minImageCount + 1;
if (SurfaceCapabilities.maxImageCount > 0) and
(SwapChainFactory.MinImageCount > SurfaceCapabilities.maxImageCount) then
SwapChainFactory.MinImageCount := SurfaceCapabilities.maxImageCount;
WriteLn(SwapChainFactory.MinImageCount);

WriteLn(' set pre transform...');
SwapChainFactory.PreTransform := SurfaceCapabilities.currentTransform;
if (VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR in SurfaceCapabilities.supportedTransforms) then
SwapChainFactory.PreTransform := [ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR ];

Write(' find suitable present mode... ');
PresentModes := fPhyDevice.GetSurfacePresentModes(fSurface.Handle);
if (Length(PresentModes) = 0) then
raise TvkuException.Create('unable to get present modes');
for pm in PresentModes do begin
if (pm = VK_PRESENT_MODE_MAILBOX_KHR) then begin
SwapChainFactory.PresentMode := pm;
break;
end;
end;
WriteLn(SwapChainFactory.PresentMode);

//////////////////////////////////////////////////////////////////////////////
WriteLn('create image views');
Images := fSwapChain.GetImages;
SetLength(fImageViews, Length(Images));
ImageViewFactory := TvkuImageViewFactory.Create(fDevice);
try
ImageViewFactory.AllocHandler := fAllocHandler;
ImageViewFactory.Format := fSurfaceFormat;
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;
fSwapChain := SwapChainFactory.CreateSwapchain;
WriteLn(' handle: ', PtrUInt(fSwapChain.Handle));
WriteLn(' done');
finally
FreeAndNil(SwapChainFactory);
end;
with ImageViewFactory.Components do begin
r := VK_COMPONENT_SWIZZLE_R;
g := VK_COMPONENT_SWIZZLE_G;
b := VK_COMPONENT_SWIZZLE_B;
a := VK_COMPONENT_SWIZZLE_A;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create images and image views');
Images := fSwapChain.GetImages;
SetLength(fImages, Length(Images));
SetLength(fImageViews, Length(Images));
ImageViewFactory := TvkuImageViewFactory.Create(fDevice);
try
ImageViewFactory.AllocHandler := fAllocHandler;
ImageViewFactory.Format := fSurfaceFormat;
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;
with ImageViewFactory.Components do begin
r := VK_COMPONENT_SWIZZLE_R;
g := VK_COMPONENT_SWIZZLE_G;
b := VK_COMPONENT_SWIZZLE_B;
a := VK_COMPONENT_SWIZZLE_A;
end;
for i := Low(fImageViews) to High(fImageViews) do begin
fImages[i] := TvkuImage.Create(Images[i], false, fDevice.DeviceCommands, @AllocCallbacks);
WriteLn(' image handle: ', PtrUInt(fImages[i].Handle));
ImageMemoryBarrier := fImages[i].GetMemoryBarrier(
[ VK_IMAGE_ASPECT_COLOR_BIT ],
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
SetupCommandBuffer.PipelineBarrier(
[ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ],
[ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ],
[],
[],
[],
[ ImageMemoryBarrier ]);

ImageViewFactory.Image := fImages[i].Handle;
fImageViews[i] := ImageViewFactory.CreateImageView;
WriteLn(' view handle: ', PtrUInt(fImageViews[i].Handle));
end;
WriteLn(' done');
finally
FreeAndNil(ImageViewFactory);
end;
for i := Low(fImageViews) to High(fImageViews) do begin
// TODO create image barrier
ImageViewFactory.Image := Images[i];
fImageViews[i] := ImageViewFactory.CreateImageView;
WriteLn(' handle: ', PtrUInt(fImageViews[i].Handle));

//////////////////////////////////////////////////////////////////////////////
WriteLn('create draw command buffers');
SetLength(fDrawCommandBuffers, Length(fImageViews));
CommandBuffers := fCommandPool.CreateCommandBuffers(
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
Length(fDrawCommandBuffers));
for i := low(CommandBuffers) to high(CommandBuffers) do begin
fDrawCommandBuffers[i] := TvkuCommandBuffer.Create(
CommandBuffers[i],
true,
fCommandPool.Handle,
fDevice.DeviceCommands);
WriteLn(' handle: ', PtrUInt(fDrawCommandBuffers[i].Handle));
end;
WriteLn(' done');
finally
FreeAndNil(ImageViewFactory);
end;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create render pass');
RenderPassFactory := TvkuRenderPassFactory.Create(fDevice);
try
RenderPassFactory.Attachments.Length := 2;
with RenderPassFactory.Attachments[0] do begin
Format := fSurfaceFormat;
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;
//////////////////////////////////////////////////////////////////////////////
WriteLn('create post present command buffers');
fPostPresentCommandBuffer := TvkuCommandBuffer.Create(
fCommandPool.CreateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY),
true,
fCommandPool.Handle,
fDevice.DeviceCommands);
WriteLn(' handle: ', PtrUInt(fPostPresentCommandBuffer.Handle));
WriteLn(' done');

//////////////////////////////////////////////////////////////////////////////
WriteLn('create depth stencil image and image view');
ImageFactory := TvkuImageFactory.Create(fDevice);
ImageViewFactory := TvkuImageViewFactory.Create(fDevice);
try
ImageFactory.ImageType := VK_IMAGE_TYPE_2D;
ImageFactory.Format := fDepthFormat;
ImageFactory.Extent := vkExtent3D(
SurfaceCapabilities.currentExtent.width,
SurfaceCapabilities.currentExtent.height,
1);
ImageFactory.MipLevels := 1;
ImageFactory.ArrayLayers := 1;
ImageFactory.Samples := [ VK_SAMPLE_COUNT_1_BIT ];
ImageFactory.Tiling := VK_IMAGE_TILING_OPTIMAL;
ImageFactory.Usage := [ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ];
fDepthStencilImage := ImageFactory.CreateImage;
fDepthStencilImage.AllocateAndBindImageMemory(
fPhyDevice.GetMemoryProperties,
@AllocCallbacks);
WriteLn(' image handle: ', PtrUInt(fDepthStencilImage.Handle));

ImageViewFactory.Image := fDepthStencilImage.Handle;
ImageViewFactory.ViewType := VK_IMAGE_VIEW_TYPE_2D;
ImageViewFactory.Format := fDepthFormat;
with ImageViewFactory.SubresourceRange do begin
AspectMask := [ VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_STENCIL_BIT ];
BaseMipLevel := 0;
LevelCount := 1;
BaseArrayLayer := 0;
LayerCount := 1;
end;
fDepthStencilImageView := ImageViewFactory.CreateImageView;
WriteLn(' view handle: ', PtrUInt(fDepthStencilImageView.Handle));

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;
WriteLn(' done');
finally
FreeAndNil(ImageViewFactory);
FreeAndNil(ImageFactory);
end;

RenderPassFactory.Subpasses.Length := 1;
with RenderPassFactory.Subpasses[0] do begin
PipelineBindPoint := VK_PIPELINE_BIND_POINT_GRAPHICS;
//////////////////////////////////////////////////////////////////////////////
WriteLn('create render pass');
RenderPassFactory := TvkuRenderPassFactory.Create(fDevice);
try
RenderPassFactory.Attachments.Length := 2;
with RenderPassFactory.Attachments[0] do begin
Format := fSurfaceFormat;
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 := fDepthFormat;
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;

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

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

RenderPassFactory.AllocHandler := fAllocHandler;
fRenderPass := RenderPassFactory.CreateRenderPass;
DepthStencilAttachments.Length := 1;
DepthStencilAttachments[0].Attachment := 1;
DepthStencilAttachments[0].Layout := VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
end;

WriteLn(' handle: ', PtrUInt(fRenderPass.Handle));
WriteLn(' done');
finally
FreeAndNil(RenderPassFactory);
end;
RenderPassFactory.AllocHandler := fAllocHandler;
fRenderPass := RenderPassFactory.CreateRenderPass;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create frame buffers');
FrameBufferFactory := TvkuFrameBufferFactory.Create(fDevice);
try
SetLength(fFrameBuffers, Length(fImageViews));

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;
WriteLn(' handle: ', PtrUInt(fFrameBuffers[i].Handle));
WriteLn(' handle: ', PtrUInt(fRenderPass.Handle));
WriteLn(' done');
finally
FreeAndNil(RenderPassFactory);
end;
WriteLn(' done');
finally
FreeAndNil(FrameBufferFactory);
end;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create descriptor set layout');
DescSetLayoutFactory := TvkuDescriptorSetLayoutFactory.Create(fDevice);
try
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 ];
//////////////////////////////////////////////////////////////////////////////
WriteLn('create pipeline cache');
PipelineCacheFactory := TvkuPipelineCacheFactory.Create(fDevice);
try
fPipelineCache := PipelineCacheFactory.CreatePipelineCache;
WriteLn(' handle: ', PtrUInt(fPipelineCache.Handle));
WriteLn(' done');
finally
FreeAndNil(PipelineCacheFactory);
end;

DescSetLayoutFactory.AllocHandler := fAllocHandler;
//////////////////////////////////////////////////////////////////////////////
WriteLn('create frame buffers');
FrameBufferFactory := TvkuFrameBufferFactory.Create(fDevice);
try
SetLength(fFrameBuffers, Length(fImageViews));

FrameBufferFactory.AllocHandler := fAllocHandler;
FrameBufferFactory.RenderPass := fRenderPass.Handle;
FrameBufferFactory.Width := SurfaceCapabilities.currentExtent.width;
FrameBufferFactory.Height := SurfaceCapabilities.currentExtent.height;
FrameBufferFactory.Layers := 1;
FrameBufferFactory.Attachments.Length := 2;
FrameBufferFactory.Attachments[1] := fDepthStencilImageView.Handle;

for i := low(fFrameBuffers) to high(fFrameBuffers) do begin
FrameBufferFactory.Attachments[0] := fImageViews[i].Handle;
fFrameBuffers[i] := FrameBufferFactory.CreateFrameBuffer;
WriteLn(' handle: ', PtrUInt(fFrameBuffers[i].Handle));
end;
WriteLn(' done');
finally
FreeAndNil(FrameBufferFactory);
end;

fDescSetLayout := DescSetLayoutFactory.CreateDescriptorSetLayout;
WriteLn(' handle: ', PtrUInt(fDescSetLayout.Handle));
//////////////////////////////////////////////////////////////////////////////
WriteLn('flush setup command buffer');
SetupCommandBuffer.EndCommand;
fQueue.Submit([], [], [ SetupCommandBuffer.Handle ], [], VK_INVALID_NDP_HANDLE);
fQueue.WaitIdle;
FreeAndNil(SetupCommandBuffer);
WriteLn(' done');
finally
FreeAndNil(DescSetLayoutFactory);
end;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create pipeline layout');
PipelineLayoutFactory := TvkuPipelineLayoutFactory.Create(fDevice);
try
PipelineLayoutFactory.AllocHandler := fAllocHandler;
PipelineLayoutFactory.SetLayouts.Length := 1;
PipelineLayoutFactory.SetLayouts[0] := fDescSetLayout.Handle;
fPipelineLayout := PipelineLayoutFactory.CreatePipelineLayout;
WriteLn(' handle: ', PtrUInt(fPipelineLayout.Handle));
WriteLn(' done');
finally
FreeAndNil(PipelineLayoutFactory);
end;
//////////////////////////////////////////////////////////////////////////////
WriteLn('create descriptor set layout');
DescSetLayoutFactory := TvkuDescriptorSetLayoutFactory.Create(fDevice);
try
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;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create shader modules');
ShaderModuleFactory := TvkuShaderModuleFactory.Create(fDevice);
try
ShaderModuleFactory.AllocHandler := fAllocHandler;
DescSetLayoutFactory.AllocHandler := fAllocHandler;

ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.vert', [ VK_SHADER_STAGE_VERTEX_BIT ]);
fVertexShader := ShaderModuleFactory.CreateShaderModule;
WriteLn(' vertex handle: ', PtrUInt(fVertexShader.Handle));
fDescSetLayout := DescSetLayoutFactory.CreateDescriptorSetLayout;
WriteLn(' handle: ', PtrUInt(fDescSetLayout.Handle));
WriteLn(' done');
finally
FreeAndNil(DescSetLayoutFactory);
end;

ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag', [ VK_SHADER_STAGE_FRAGMENT_BIT ]);
fFragmentShader := ShaderModuleFactory.CreateShaderModule;
WriteLn(' fragment handle: ', PtrUInt(fFragmentShader.Handle));
WriteLn(' done');
finally
FreeAndNil(ShaderModuleFactory);
end;
//////////////////////////////////////////////////////////////////////////////
WriteLn('create pipeline layout');
PipelineLayoutFactory := TvkuPipelineLayoutFactory.Create(fDevice);
try
PipelineLayoutFactory.AllocHandler := fAllocHandler;
PipelineLayoutFactory.SetLayouts.Length := 1;
PipelineLayoutFactory.SetLayouts[0] := fDescSetLayout.Handle;
fPipelineLayout := PipelineLayoutFactory.CreatePipelineLayout;
WriteLn(' handle: ', PtrUInt(fPipelineLayout.Handle));
WriteLn(' done');
finally
FreeAndNil(PipelineLayoutFactory);
end;

//////////////////////////////////////////////////////////////////////////////
WriteLn('create shader modules');
ShaderModuleFactory := TvkuShaderModuleFactory.Create(fDevice);
try
ShaderModuleFactory.AllocHandler := fAllocHandler;

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

ShaderModuleFactory.LoadGlslCode(ExtractFilePath(Application.ExeName) + '../../data/shaders/triangle.frag', [ VK_SHADER_STAGE_FRAGMENT_BIT ]);
fFragmentShader := ShaderModuleFactory.CreateShaderModule;
WriteLn(' fragment handle: ', PtrUInt(fFragmentShader.Handle));
WriteLn(' done');
finally
FreeAndNil(ShaderModuleFactory);
end;

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

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

@@ -503,12 +621,28 @@ procedure TMainForm.FormDestroy(Sender: TObject);
SetLength(fFrameBuffers, 0);
end;

procedure FreeAndNilImages;
var i: Integer;
begin
for i := low(fImages) to high(fImages) do
FreeAndNil(fImages[i]);
SetLength(fImages, 0);
end;

procedure FreeAndNilImageViews;
var i: Integer;
begin
for i := Low(fImageViews) to High(fImageViews) do
FreeAndNil(fImageViews[i]);
SetLength(fImageViews, 0);
FreeAndNil(fImageViews[i]);
SetLength(fImageViews, 0);
end;

procedure FreeAndNilDrawCommandBuffers;
var i: Integer;
begin
for i := Low(fDrawCommandBuffers) to High(fDrawCommandBuffers) do
FreeAndNil(fDrawCommandBuffers[i]);
SetLength(fDrawCommandBuffers, 0);
end;

begin
@@ -518,9 +652,16 @@ begin
FreeAndNil(fPipelineLayout);
FreeAndNil(fDescSetLayout);
FreeAndNilFrameBuffers;
FreeAndNil(fPipelineCache);
FreeAndNil(fRenderPass);
FreeAndNil(fDepthStencilImageView);
FreeAndNil(fDepthStencilImage);
FreeAndNil(fPostPresentCommandBuffer);
FreeAndNilDrawCommandBuffers;
FreeAndNilImageViews;
FreeAndNilImages;
FreeAndNil(fSwapChain);
FreeAndNil(fCommandPool);
FreeAndNil(fSurface);
FreeAndNil(fQueue);
FreeAndNil(fDevice);


+ 33
- 1
projects/utils/VulkanUtils.pas 查看文件

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

uses
Classes, SysUtils,
Vulkan,
uvkuTypes, uvkuAllocationHandler, uvkuDebugReporter,
uvkuInstance, uvkuInstanceFactory,
uvkuPhysicalDevice, uvkuDevice, uvkuDeviceFactory, uvkuDeviceMemory, uvkuQueue,
@@ -18,7 +19,7 @@ uses
uvkuFrameBuffer, uvkuFrameBufferFactory,
uvkuDescriptorSetLayout, uvkuDescriptorSetLayoutFactory,
uvkuShaderModule, uvkuShaderModuleFactory,
uvkuPipelineLayout, uvkuPipelineLayoutFactory, uvkuPipeline, uvkuPipelineFactory,
uvkuPipelineLayout, uvkuPipelineLayoutFactory, uvkuPipelineCache, uvkuPipelineCacheFactory, uvkuPipeline, uvkuPipelineFactory,
uvkuUtils;

type
@@ -40,6 +41,19 @@ type
TVkPushConstantRangeArr = uvkuTypes.TVkPushConstantRangeArr;
TVkPipelineShaderStageCreateInfoArr = uvkuTypes.TVkPipelineShaderStageCreateInfoArr;
TVkPipelineVertexInputStateCreateInfoArr = uvkuTypes.TVkPipelineVertexInputStateCreateInfoArr;
TVkAttachmentDescriptionArr = uvkuTypes.TVkAttachmentDescriptionArr;
TVkSubpassDescriptionArr = uvkuTypes.TVkSubpassDescriptionArr;
TVkSubpassDependencyArr = uvkuTypes.TVkSubpassDependencyArr;
TVkAttachmentReferenceArr = uvkuTypes.TVkAttachmentReferenceArr;
TVkMemoryBarrierArr = uvkuTypes.TVkMemoryBarrierArr;
TVkBufferMemoryBarrierArr = uvkuTypes.TVkBufferMemoryBarrierArr;
TVkImageMemoryBarrierArr = uvkuTypes.TVkImageMemoryBarrierArr;

TVkUint32List = uvkuTypes.TVkUint32List;
TVkFloatList = uvkuTypes.TVkFloatList;
TVkImageViewList = uvkuTypes.TVkImageViewList;
TVkSamplerList = uvkuTypes.TVkSamplerList;
TVkDescriptorSetLayoutList = uvkuTypes.TVkDescriptorSetLayoutList;

TvkuAllocationHandler = uvkuAllocationHandler.TvkuAllocationHandler;

@@ -101,6 +115,8 @@ type
{ Pipeline }
TvkuPipelineLayout = uvkuPipelineLayout.TvkuPipelineLayout;
TvkuPipelineLayoutFactory = uvkuPipelineLayoutFactory.TvkuPipelineLayoutFactory;
TvkuPipelineCache = uvkuPipelineCache.TvkuPipelineCache;
TvkuPipelineCacheFactory = uvkuPipelineCacheFactory.TvkuPipelineCacheFactory;
TvkuPipeline = uvkuPipeline.TvkuPipeline;
TvkuGraphicsPipeline = uvkuPipeline.TvkuGraphicsPipeline;
TvkuGraphicsPipelineFactory = uvkuPipelineFactory.TvkuGraphicsPipelineFactory;
@@ -112,7 +128,23 @@ type
TvkuErrorException = uvkuUtils.TvkuErrorException;
TvkuInvalidFuncPtrException = uvkuUtils.TvkuInvalidFuncPtrException;

function vkExtent2D(const X, Y: VkUint32): TVkExtent2D;
function vkExtent3D(const X, Y, Z: VkUint32): TVkExtent3D;

implementation

function vkExtent2D(const X, Y: VkUint32): TVkExtent2D;
begin
result.width := x;
result.height := y;
end;

function vkExtent3D(const X, Y, Z: VkUint32): TVkExtent3D;
begin
result.width := x;
result.height := y;
result.depth := z;
end;

end.


+ 2
- 2
projects/utils/uvkuAllocationHandler.pas 查看文件

@@ -20,7 +20,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 MakeStructure: TVkAllocationCallbacks;
function GetStructure: TVkAllocationCallbacks;
end;

implementation
@@ -107,7 +107,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuAllocationHandler.MakeStructure: TVkAllocationCallbacks;
function TvkuAllocationHandler.GetStructure: TVkAllocationCallbacks;
begin
FillByte(result, SizeOf(result), 0);
result.pUserData := self;


+ 34
- 1
projects/utils/uvkuCommandBuffer.pas 查看文件

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

uses
Classes, SysUtils,
Vulkan, uvkuBase;
Vulkan, uvkuBase, uvkuTypes;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -21,6 +21,14 @@ type
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;

procedure BeginCommand;
procedure EndCommand;
procedure PipelineBarrier(
const aSrcStageMask: VkPipelineStageFlags;
const aDstStageMask: VkPipelineStageFlags;
const aDependencyFlags: VkDependencyFlags;
const aMemoryBarriers: array of TVkMemoryBarrier;
const aBufferMemoryBarriers: array of TVkBufferMemoryBarrier;
const aImageMemoryBarriers: array of TVkImageMemoryBarrier);

constructor Create(
const aHandle: VkCommandBuffer;
@@ -53,6 +61,31 @@ begin
raise TvkuErrorException.Create('unable to begin command buffer', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuCommandBuffer.EndCommand;
var err: TVkResult;
begin
err := fDeviceCommands.vkEndCommandBuffer(fHandle);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to end command buffer', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuCommandBuffer.PipelineBarrier(const aSrcStageMask: VkPipelineStageFlags;
const aDstStageMask: VkPipelineStageFlags; const aDependencyFlags: VkDependencyFlags;
const aMemoryBarriers: array of TVkMemoryBarrier; const aBufferMemoryBarriers: array of TVkBufferMemoryBarrier;
const aImageMemoryBarriers: array of TVkImageMemoryBarrier);
begin
DeviceCommands.vkCmdPipelineBarrier(
fHandle,
aSrcStageMask,
aDstStageMask,
aDependencyFlags,
Length(aMemoryBarriers), @aMemoryBarriers[0],
Length(aBufferMemoryBarriers), @aBufferMemoryBarriers[0],
Length(aImageMemoryBarriers), @aImageMemoryBarriers[0]);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuCommandBuffer.Create(const aHandle: VkCommandBuffer; const aOwnsHandle: Boolean;
const aCommandPool: VkCommandPool; const aDeviceCommands: TVkDeviceCommands);


+ 1
- 1
projects/utils/uvkuDebugReporter.pas 查看文件

@@ -91,7 +91,7 @@ var
begin
inherited Create;
if Assigned(aAllocHandler) then
SetAllocCallbacks(aAllocHandler.MakeStructure);
SetAllocCallbacks(aAllocHandler.GetStructure);
fInstanceCommands := aInstanceCommands;

FillByte(CreateInfo, SizeOf(CreateInfo), 0);


+ 38
- 2
projects/utils/uvkuDevice.pas 查看文件

@@ -23,7 +23,16 @@ type
property Handle: VkDevice read fHandle;
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;

function GetQueue(const aQueueFamilyIndex, aQueueIndex: VkUint32): VkQueue;
function GetQueue(
const aQueueFamilyIndex: VkUint32;
const aQueueIndex: VkUint32): VkQueue;
function AllocateMemory(
const aSize: VkUint32;
const aMemoryTypeIndex: VkUint32;
aAllocCallbacks: PVkAllocationCallbacks = nil): VkDeviceMemory;
procedure FreeMemory(
const aMemory: VkDeviceMemory;
aAllocCallbacks: PVkAllocationCallbacks = nil);

constructor Create(
const aPhysicalDevice: VkPhysicalDevice;
@@ -60,7 +69,7 @@ begin
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDevice.GetQueue(const aQueueFamilyIndex, aQueueIndex: VkUint32): VkQueue;
function TvkuDevice.GetQueue(const aQueueFamilyIndex: VkUint32; const aQueueIndex: VkUint32): VkQueue;
begin
if not Assigned(fDeviceCommands.vkGetDeviceQueue) then
raise TvkuInvalidFuncPtrException.Create('vkGetDeviceQueue');
@@ -69,6 +78,33 @@ begin
raise TvkuException.Create('unable to get device queue');
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDevice.AllocateMemory(const aSize: VkUint32; const aMemoryTypeIndex: VkUint32;
aAllocCallbacks: PVkAllocationCallbacks): VkDeviceMemory;
var
AllocInfo: TVkMemoryAllocateInfo;
err: TVkResult;
begin
FillByte(AllocInfo, SizeOf(AllocInfo), 0);
AllocInfo.sType := VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
AllocInfo.pNext := nil;
AllocInfo.allocationSize := aSize;
AllocInfo.memoryTypeIndex := aMemoryTypeIndex;
if not Assigned(aAllocCallbacks) then
aAllocCallbacks := AllocCallbacks;
err := fDeviceCommands.vkAllocateMemory(fHandle, @AllocInfo, aAllocCallbacks, @result);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to allocate device memory', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuDevice.FreeMemory(const aMemory: VkDeviceMemory; aAllocCallbacks: PVkAllocationCallbacks);
begin
if not Assigned(aAllocCallbacks) then
aAllocCallbacks := AllocCallbacks;
fDeviceCommands.vkFreeMemory(fHandle, aMemory, aAllocCallbacks);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo;
const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: PVkAllocationCallbacks);


+ 1
- 1
projects/utils/uvkuFactoryBase.pas 查看文件

@@ -85,7 +85,7 @@ begin
if Assigned(fAllocHandler) then begin
new(fAllocCallbacks);
fOwnsAllocCallbacks := true;
fAllocCallbacks^ := fAllocHandler.MakeStructure;
fAllocCallbacks^ := fAllocHandler.GetStructure;
end;
end;



+ 64
- 1
projects/utils/uvkuImage.pas 查看文件

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

uses
Classes, SysUtils,
Vulkan, uvkuBase;
Vulkan, uvkuBase, uvkuDeviceMemory;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -14,6 +14,7 @@ type
private
fHandle: VkImage;
fDeviceCommands: TVkDeviceCommands;
fImageMemory: TvkuDeviceMemory;

procedure CreateHandle(const aCreateInfo: TVkImageCreateInfo);
public
@@ -24,6 +25,14 @@ type
const aAspectMask: VkImageAspectFlags;
const aOldLayout: TVkImageLayout;
const aNewLayout: TVkImageLayout): TVkImageMemoryBarrier;
procedure BindMemory(
const aMemory: VkDeviceMemory;
const aOffset: VkDeviceSize);
function GetMemoryRequirements: TVkMemoryRequirements;

procedure AllocateAndBindImageMemory(
const aMemoryProperties: TVkPhysicalDeviceMemoryProperties;
aAllocCallbacks: PVkAllocationCallbacks = nil);

constructor Create(
const aCreateInfo: TVkImageCreateInfo;
@@ -143,6 +152,59 @@ begin
end;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuImage.BindMemory(const aMemory: VkDeviceMemory; const aOffset: VkDeviceSize);
var err: TVkResult;
begin
err := fDeviceCommands.vkBindImageMemory(fDeviceCommands.Device, fHandle, aMemory, aOffset);
if (err < VK_SUCCESS) then
TvkuErrorException.Create('unable to bind image memory', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuImage.GetMemoryRequirements: TVkMemoryRequirements;
begin
fDeviceCommands.vkGetImageMemoryRequirements(fDeviceCommands.Device, fHandle, @result);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuImage.AllocateAndBindImageMemory(const aMemoryProperties: TVkPhysicalDeviceMemoryProperties;
aAllocCallbacks: PVkAllocationCallbacks);
var
i: Integer;
bits: VkUint32;
MemReq: TVkMemoryRequirements;
Mem: VkDeviceMemory;
MemAllocInfo: TVkMemoryAllocateInfo;
err: TVkResult;
begin
MemReq := GetMemoryRequirements;

FillByte(MemAllocInfo, SizeOf(MemAllocInfo), 0);
MemAllocInfo.sType := VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
MemAllocInfo.pNext := nil;
MemAllocInfo.allocationSize := MemReq.size;

bits := MemReq.memoryTypeBits;
for i := 0 to VK_MAX_MEMORY_TYPES-1 do begin
if ((bits and 1) = 1) and
(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT in aMemoryProperties.memoryTypes[i].propertyFlags) then
begin
MemAllocInfo.memoryTypeIndex := i;
break;
end;
bits := bits shr 1;
end;

if not Assigned(aAllocCallbacks) then
aAllocCallbacks := AllocCallbacks;
err := fDeviceCommands.vkAllocateMemory(fDeviceCommands.Device, @MemAllocInfo, aAllocCallbacks, @Mem);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to allocate image memory', err);
fImageMemory := TvkuDeviceMemory.Create(Mem, true, fDeviceCommands, aAllocCallbacks);
BindMemory(fImageMemory.Handle, 0);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuImage.Create(const aCreateInfo: TVkImageCreateInfo; const aDeviceCommands: TVkDeviceCommands;
const aAllocCallbacks: PVkAllocationCallbacks);
@@ -170,6 +232,7 @@ begin
if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
fDeviceCommands.vkDestroyImage(fDeviceCommands.Device, fHandle, AllocCallbacks);
fHandle := VK_INVALID_NDP_HANDLE;
FreeAndNil(fImageMemory);
inherited Destroy;
end;



+ 82
- 0
projects/utils/uvkuPipelineCache.pas 查看文件

@@ -0,0 +1,82 @@
unit uvkuPipelineCache;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils,
Vulkan, uvkuBase;

type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuPipelineCache = class(TvkuAllocHandle)
private
fHandle: VkPipelineCache;
fDeviceCommands: TVkDeviceCommands;

procedure CreateHandle(const aCreateInfo: TVkPipelineCacheCreateInfo);
public
property Handle: VkPipelineCache read fHandle;
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;

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

implementation

uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuPipelineCache//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuPipelineCache.CreateHandle(const aCreateInfo: TVkPipelineCacheCreateInfo);
var err: TVkResult;
begin
err := fDeviceCommands.vkCreatePipelineCache(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
if (err < VK_SUCCESS) then
TvkuErrorException.Create('unable to create pipeline cache', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuPipelineCache.Create(const aCreateInfo: TVkPipelineCacheCreateInfo;
const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create;
fDeviceCommands := aDeviceCommands;
SetAllocCallbacks(aAllocCallbacks);
CreateHandle(aCreateInfo);
end;

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

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

end.


+ 65
- 0
projects/utils/uvkuPipelineCacheFactory.pas 查看文件

@@ -0,0 +1,65 @@
unit uvkuPipelineCacheFactory;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils,
Vulkan, uvkuFactoryBase, uvkuPipelineCache;

type
TvkuPipelineCacheFactory = class(TvkuDeviceObjFactory)
private
fFlags: VkPipelineCacheCreateFlags;
fInitialDataSize: VkSize;
fInitialData: PVkVoid;
public
property Flags: VkPipelineCacheCreateFlags read fFlags write fFlags;

procedure SetInitalData(const aData: PVkVoid; const aSize: VkSize);

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

function CreatePipelineCache: TvkuPipelineCache;
end;

implementation

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuPipelineCacheFactory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuPipelineCacheFactory.SetInitalData(const aData: PVkVoid; const aSize: VkSize);
begin
fInitialData := aData;
fInitialDataSize := aSize;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineCacheFactory.GetStructure: TVkPipelineCacheCreateInfo;
begin
FillByte(result, SizeOf(result), 0);
result.sType := VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
result.pNext := nil;
result.flags := fFlags;
result.initialDataSize := fInitialDataSize;
result.pInitialData := fInitialData;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuPipelineCacheFactory.SetStructure(const aData: TVkPipelineCacheCreateInfo);
begin
fFlags := aData.flags;
fInitialDataSize := aData.initialDataSize;
fInitialData := aData.pInitialData;
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPipelineCacheFactory.CreatePipelineCache: TvkuPipelineCache;
begin
result := TvkuPipelineCache.Create(GetStructure, DeviceCommands, AllocCallbacks);
end;

end.


+ 49
- 0
projects/utils/uvkuQueue.pas 查看文件

@@ -18,6 +18,14 @@ type
property Handle: VkQueue read fHandle;
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;

procedure Submit(
const aWaitSemaphores: array of VkSemaphore;
const aWaitDstStageMask: array of VkSemaphore;
const aCommandBuffers: array of VkCommandBuffer;
const aSignalSemaphores: array of VkSemaphore;
const aFence: VkFence);
procedure WaitIdle;

constructor Create(
const aHandle: VkQueue;
const aDeviceCommands: TVkDeviceCommands);
@@ -25,8 +33,49 @@ type

implementation

uses
uvkuUtils;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuQueue//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuQueue.Submit(
const aWaitSemaphores: array of VkSemaphore;
const aWaitDstStageMask: array of VkSemaphore;
const aCommandBuffers: array of VkCommandBuffer;
const aSignalSemaphores: array of VkSemaphore;
const aFence: VkFence);
var
SubmitInfo: TVkSubmitInfo;
err: TVkResult;
begin
if Length(aWaitSemaphores) <> Length(aWaitDstStageMask) then
raise TvkuException.Create('aWaitSemaphores and aWaitDstStageMask must have the same number of elements');

FillByte(SubmitInfo, SizeOf(SubmitInfo), 0);
SubmitInfo.sType := VK_STRUCTURE_TYPE_SUBMIT_INFO;
SubmitInfo.pNext := nil;
SubmitInfo.waitSemaphoreCount := Length(aWaitSemaphores);
SubmitInfo.pWaitSemaphores := @aWaitSemaphores[0];
SubmitInfo.pWaitDstStageMask := @aWaitDstStageMask[0];
SubmitInfo.commandBufferCount := Length(aCommandBuffers);
SubmitInfo.pCommandBuffers := @aCommandBuffers[0];
SubmitInfo.signalSemaphoreCount := Length(aSignalSemaphores);
SubmitInfo.pSignalSemaphores := @aSignalSemaphores[0];
err := fDeviceCommands.vkQueueSubmit(fHandle, 1, @SubmitInfo, aFence);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to submit queue', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuQueue.WaitIdle;
var err: TVkResult;
begin
err := fDeviceCommands.vkQueueWaitIdle(fHandle);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('error while waiting for queue', err);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuQueue.Create(const aHandle: VkQueue; const aDeviceCommands: TVkDeviceCommands);
begin


+ 3
- 0
projects/utils/uvkuTypes.pas 查看文件

@@ -74,6 +74,9 @@ type
TVkSubpassDescriptionArr = array of TVkSubpassDescription;
TVkSubpassDependencyArr = array of TVkSubpassDependency;
TVkAttachmentReferenceArr = array of TVkAttachmentReference;
TVkMemoryBarrierArr = array of TVkMemoryBarrier;
TVkBufferMemoryBarrierArr = array of TVkBufferMemoryBarrier;
TVkImageMemoryBarrierArr = array of TVkImageMemoryBarrier;

TVkUint32List = specialize TvkuList<VkUint32>;
TVkFloatList = specialize TvkuList<VkFloat>;


正在加载...
取消
保存