diff --git a/projects/triangle/triangle.lpi b/projects/triangle/triangle.lpi
index 51e0a78..dd9b78b 100644
--- a/projects/triangle/triangle.lpi
+++ b/projects/triangle/triangle.lpi
@@ -33,7 +33,7 @@
-
+
@@ -233,6 +233,10 @@
+
+
+
+
diff --git a/projects/triangle/triangle.lpr b/projects/triangle/triangle.lpr
index a522bec..cf9d70d 100644
--- a/projects/triangle/triangle.lpr
+++ b/projects/triangle/triangle.lpr
@@ -8,7 +8,7 @@ uses
cthreads,
{$ENDIF}{$ENDIF}
SysUtils, Interfaces, Dialogs, Forms,
- uMainForm, Vulkan, uvkuDescriptorPool, uvkuDescriptorPoolFactory, uvkuDescriptorSet;
+ uMainForm, Vulkan, uvkuDescriptorPool, uvkuDescriptorPoolFactory, uvkuDescriptorSet, uvkuSemaphore;
{$R *.res}
diff --git a/projects/triangle/triangle.lps b/projects/triangle/triangle.lps
index 9d62ba7..564cf7c 100644
--- a/projects/triangle/triangle.lps
+++ b/projects/triangle/triangle.lps
@@ -4,13 +4,13 @@
-
+
-
+
@@ -20,39 +20,41 @@
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
+
+
@@ -60,7 +62,7 @@
-
+
@@ -68,7 +70,7 @@
-
+
@@ -76,23 +78,24 @@
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
@@ -100,7 +103,7 @@
-
+
@@ -108,22 +111,23 @@
-
+
-
+
-
-
-
-
+
+
+
+
+
@@ -131,22 +135,23 @@
-
+
-
+
-
-
-
-
+
+
+
+
+
@@ -154,7 +159,7 @@
-
+
@@ -162,7 +167,7 @@
-
+
@@ -170,7 +175,7 @@
-
+
@@ -178,15 +183,15 @@
-
+
-
-
+
+
@@ -195,7 +200,7 @@
-
+
@@ -203,14 +208,14 @@
-
+
-
+
@@ -218,7 +223,7 @@
-
+
@@ -226,32 +231,33 @@
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
@@ -260,7 +266,7 @@
-
+
@@ -268,7 +274,7 @@
-
+
@@ -276,7 +282,7 @@
-
+
@@ -284,7 +290,7 @@
-
+
@@ -292,7 +298,7 @@
-
+
@@ -300,14 +306,14 @@
-
+
-
+
@@ -315,7 +321,7 @@
-
+
@@ -323,7 +329,7 @@
-
+
@@ -331,7 +337,7 @@
-
+
@@ -339,7 +345,7 @@
-
+
@@ -347,7 +353,7 @@
-
+
@@ -355,13 +361,13 @@
-
+
-
+
@@ -369,7 +375,7 @@
-
+
@@ -377,7 +383,7 @@
-
+
@@ -385,7 +391,7 @@
-
+
@@ -393,7 +399,7 @@
-
+
@@ -401,7 +407,7 @@
-
+
@@ -409,287 +415,291 @@
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
diff --git a/projects/triangle/uMainForm.lfm b/projects/triangle/uMainForm.lfm
index 17e7600..bec341e 100644
--- a/projects/triangle/uMainForm.lfm
+++ b/projects/triangle/uMainForm.lfm
@@ -18,4 +18,9 @@ object MainForm: TMainForm
BevelOuter = bvNone
TabOrder = 0
end
+ object ApplicationProperties: TApplicationProperties
+ OnIdle = ApplicationPropertiesIdle
+ left = 56
+ top = 24
+ end
end
diff --git a/projects/triangle/uMainForm.pas b/projects/triangle/uMainForm.pas
index f3f81e4..5135b91 100644
--- a/projects/triangle/uMainForm.pas
+++ b/projects/triangle/uMainForm.pas
@@ -27,7 +27,9 @@ type
end;
TMainForm = class(TForm)
+ ApplicationProperties: TApplicationProperties;
RenderPanel: TPanel;
+ procedure ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
@@ -77,6 +79,7 @@ type
end;
procedure UpdateUniformBuffers;
+ procedure Render;
end;
var
@@ -179,9 +182,10 @@ var
r2D: TVkRect2D;
begin
try
- fCamera := TglcCamera.Create;
- fAllocHandler := TCustomAllocHandler.Create;
- AllocCallbacks := fAllocHandler.GetStructure;
+ SetupCommandBuffer := nil;
+ fCamera := TglcCamera.Create;
+ fAllocHandler := TCustomAllocHandler.Create;
+ AllocCallbacks := fAllocHandler.GetStructure;
//////////////////////////////////////////////////////////////////////////////
WriteLn('create instance: ');
@@ -237,7 +241,7 @@ begin
DeviceFactory := TvkuDeviceFactory.Create(fInstance);
try
DeviceFactory.AllocHandler := fAllocHandler;
- DeviceFactory.EnabledExtensions.Add('VK_KHR_swapchain');
+ DeviceFactory.EnabledExtensionNames.Add('VK_KHR_swapchain');
DeviceFactory.QueueCreateInfos.Length := 1;
with DeviceFactory.QueueCreateInfos[0] do begin
Flags := 0;
@@ -936,6 +940,9 @@ begin
0,
[ fDescriptorSet.Handle ],
[ ]);
+ BindPipeline(
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ fPipeline.Handle);
BindVertexBuffers(
VERTEX_BUFFER_BIND_ID,
[ fVertex.DataBuffer.Handle ],
@@ -980,6 +987,12 @@ begin
end;
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TMainForm.ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean);
+begin
+ Render;
+end;
+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.FormDestroy(Sender: TObject);
@@ -1069,5 +1082,70 @@ begin
end;
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TMainForm.Render;
+var
+ Semaphore: TvkuSemaphore;
+ AllocCallbacks: TVkAllocationCallbacks;
+ CurrentImage: VkUint32;
+ PostPresentBarrier: TVkImageMemoryBarrier;
+begin
+ fDevice.WaitIdle;
+
+ // present queue
+ AllocCallbacks := fAllocHandler.GetStructure;
+ Semaphore := TvkuSemaphore.Create(
+ VkSemaphoreCreateFlags([ VK_FENCE_CREATE_SIGNALED_BIT ]),
+ fDevice.DeviceCommands,
+ @AllocCallbacks);
+ try
+ CurrentImage := fSwapChain.AcquireNextImage(High(VkUint64), Semaphore.Handle, VK_INVALID_NDP_HANDLE);
+ fQueue.Submit(
+ [ Semaphore.Handle ],
+ [ ],
+ [ fDrawCommandBuffers[CurrentImage].Handle ],
+ [ ],
+ VK_INVALID_NDP_HANDLE);
+ fQueue.Present(
+ [ ],
+ [ fSwapChain.Handle ],
+ [ CurrentImage ]);
+ finally
+ FreeAndNil(Semaphore);
+ end;
+
+ // post present image
+ PostPresentBarrier := fImages[CurrentImage].GetMemoryBarrier(
+ [ VK_IMAGE_ASPECT_COLOR_BIT ],
+ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ PostPresentBarrier.srcAccessMask := [];
+ PostPresentBarrier.dstAccessMask := [ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ];
+
+ fPostPresentCommandBuffer.BeginCommand;
+ try
+ fPostPresentCommandBuffer.PipelineBarrier(
+ [ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT ],
+ [ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ],
+ [ ],
+ [ ],
+ [ ],
+ [ PostPresentBarrier ]);
+ finally
+ fPostPresentCommandBuffer.EndCommand;
+ end;
+
+ // submit queue
+ fQueue.Submit(
+ [ ],
+ [ ],
+ [ fPostPresentCommandBuffer.Handle ],
+ [ ],
+ VK_INVALID_NDP_HANDLE);
+ fQueue.WaitIdle;
+
+ fDevice.WaitIdle;
+end;
+
end.
diff --git a/projects/utils/VulkanUtils.pas b/projects/utils/VulkanUtils.pas
index 105de20..07da1d6 100644
--- a/projects/utils/VulkanUtils.pas
+++ b/projects/utils/VulkanUtils.pas
@@ -21,6 +21,7 @@ uses
uvkuShaderModule, uvkuShaderModuleFactory,
uvkuPipelineLayout, uvkuPipelineLayoutFactory, uvkuPipelineCache, uvkuPipelineCacheFactory, uvkuPipeline, uvkuPipelineFactory,
uvkuDescriptorPool, uvkuDescriptorPoolFactory, uvkuDescriptorSet,
+ uvkuSemaphore,
uvkuUtils;
type
@@ -62,77 +63,80 @@ type
TvkuConsoleDebugReporter = uvkuDebugReporter.TvkuConsoleDebugReporter;
{ Instance }
- TvkuInstance = uvkuInstance.TvkuInstance;
- TvkuInstanceFactory = uvkuInstanceFactory.TvkuInstanceFactory;
+ TvkuInstance = uvkuInstance.TvkuInstance;
+ TvkuInstanceFactory = uvkuInstanceFactory.TvkuInstanceFactory;
{ Device }
- TvkuPhysicalDevice = uvkuPhysicalDevice.TvkuPhysicalDevice;
- TvkuDevice = uvkuDevice.TvkuDevice;
- TvkuDeviceFactory = uvkuDeviceFactory.TvkuDeviceFactory;
- TvkuDeviceMemory = uvkuDeviceMemory.TvkuDeviceMemory;
- TvkuQueue = uvkuQueue.TvkuQueue;
+ TvkuPhysicalDevice = uvkuPhysicalDevice.TvkuPhysicalDevice;
+ TvkuDevice = uvkuDevice.TvkuDevice;
+ TvkuDeviceFactory = uvkuDeviceFactory.TvkuDeviceFactory;
+ TvkuDeviceMemory = uvkuDeviceMemory.TvkuDeviceMemory;
+ TvkuQueue = uvkuQueue.TvkuQueue;
{ Surface }
- TvkuSurface = uvkuSurface.TvkuSurface;
- TvkuSurfaceFactory = uvkuSurfaceFactory.TvkuSurfaceFactory;
+ TvkuSurface = uvkuSurface.TvkuSurface;
+ TvkuSurfaceFactory = uvkuSurfaceFactory.TvkuSurfaceFactory;
{ SwapChain }
- TvkuSwapChain = uvkuSwapChain.TvkuSwapChain;
- TvkuSwapChainFactory = uvkuSwapChainFactory.TvkuSwapChainFactory;
+ TvkuSwapChain = uvkuSwapChain.TvkuSwapChain;
+ TvkuSwapChainFactory = uvkuSwapChainFactory.TvkuSwapChainFactory;
{ Image }
- TvkuImage = uvkuImage.TvkuImage;
- TvkuImageFactory = uvkuImageFactory.TvkuImageFactory;
- TvkuImageView = uvkuImageView.TvkuImageView;
- TvkuImageViewFactory = uvkuImageViewFactory.TvkuImageViewFactory;
+ TvkuImage = uvkuImage.TvkuImage;
+ TvkuImageFactory = uvkuImageFactory.TvkuImageFactory;
+ TvkuImageView = uvkuImageView.TvkuImageView;
+ TvkuImageViewFactory = uvkuImageViewFactory.TvkuImageViewFactory;
{ Buffer }
- TvkuBuffer = uvkuBuffer.TvkuBuffer;
- TvkuBufferFactory = uvkuBufferFactory.TvkuBufferFactory;
- TvkuBufferView = uvkuBufferView.TvkuBufferView;
- TvkuBufferViewFactory = uvkuBufferViewFactory.TvkuBufferViewFactory;
+ TvkuBuffer = uvkuBuffer.TvkuBuffer;
+ TvkuBufferFactory = uvkuBufferFactory.TvkuBufferFactory;
+ TvkuBufferView = uvkuBufferView.TvkuBufferView;
+ TvkuBufferViewFactory = uvkuBufferViewFactory.TvkuBufferViewFactory;
{ Commands }
- TvkuCommandPool = uvkuCommandPool.TvkuCommandPool;
- TvkuCommandPoolFactory = uvkuCommandPoolFactory.TvkuCommandPoolFactory;
- TvkuCommandBuffer = uvkuCommandBuffer.TvkuCommandBuffer;
+ TvkuCommandPool = uvkuCommandPool.TvkuCommandPool;
+ TvkuCommandPoolFactory = uvkuCommandPoolFactory.TvkuCommandPoolFactory;
+ TvkuCommandBuffer = uvkuCommandBuffer.TvkuCommandBuffer;
{ RenderPass }
- TvkuRenderPass = uvkuRenderPass.TvkuRenderPass;
- TvkuRenderPassFactory = uvkuRenderPassFactory.TvkuRenderPassFactory;
+ TvkuRenderPass = uvkuRenderPass.TvkuRenderPass;
+ TvkuRenderPassFactory = uvkuRenderPassFactory.TvkuRenderPassFactory;
{ FrameBuffer }
- TvkuFrameBuffer = uvkuFrameBuffer.TvkuFrameBuffer;
- TvkuFrameBufferFactory = uvkuFrameBufferFactory.TvkuFrameBufferFactory;
+ TvkuFrameBuffer = uvkuFrameBuffer.TvkuFrameBuffer;
+ TvkuFrameBufferFactory = uvkuFrameBufferFactory.TvkuFrameBufferFactory;
{ DescriptorSetLayout }
- TvkuDescriptorSetLayout = uvkuDescriptorSetLayout.TvkuDescriptorSetLayout;
- TvkuDescriptorSetLayoutFactory = uvkuDescriptorSetLayoutFactory.TvkuDescriptorSetLayoutFactory;
+ TvkuDescriptorSetLayout = uvkuDescriptorSetLayout.TvkuDescriptorSetLayout;
+ TvkuDescriptorSetLayoutFactory = uvkuDescriptorSetLayoutFactory.TvkuDescriptorSetLayoutFactory;
{ Shader Modules }
- TvkuShaderModule = uvkuShaderModule.TvkuShaderModule;
- TvkuShaderModuleFactory = uvkuShaderModuleFactory.TvkuShaderModuleFactory;
+ TvkuShaderModule = uvkuShaderModule.TvkuShaderModule;
+ TvkuShaderModuleFactory = uvkuShaderModuleFactory.TvkuShaderModuleFactory;
{ Pipeline }
- TvkuPipelineLayout = uvkuPipelineLayout.TvkuPipelineLayout;
- TvkuPipelineLayoutFactory = uvkuPipelineLayoutFactory.TvkuPipelineLayoutFactory;
- TvkuPipelineCache = uvkuPipelineCache.TvkuPipelineCache;
- TvkuPipelineCacheFactory = uvkuPipelineCacheFactory.TvkuPipelineCacheFactory;
- TvkuPipeline = uvkuPipeline.TvkuPipeline;
- TvkuGraphicsPipeline = uvkuPipeline.TvkuGraphicsPipeline;
- TvkuGraphicsPipelineFactory = uvkuPipelineFactory.TvkuGraphicsPipelineFactory;
- TvkuComputePipeline = uvkuPipeline.TvkuComputePipeline;
- TvkuComputePipelineFactory = uvkuPipelineFactory.TvkuComputePipelineFactory;
+ TvkuPipelineLayout = uvkuPipelineLayout.TvkuPipelineLayout;
+ TvkuPipelineLayoutFactory = uvkuPipelineLayoutFactory.TvkuPipelineLayoutFactory;
+ TvkuPipelineCache = uvkuPipelineCache.TvkuPipelineCache;
+ TvkuPipelineCacheFactory = uvkuPipelineCacheFactory.TvkuPipelineCacheFactory;
+ TvkuPipeline = uvkuPipeline.TvkuPipeline;
+ TvkuGraphicsPipeline = uvkuPipeline.TvkuGraphicsPipeline;
+ TvkuGraphicsPipelineFactory = uvkuPipelineFactory.TvkuGraphicsPipelineFactory;
+ TvkuComputePipeline = uvkuPipeline.TvkuComputePipeline;
+ TvkuComputePipelineFactory = uvkuPipelineFactory.TvkuComputePipelineFactory;
{ DescriptorPool }
- TvkuDescriptorPool = uvkuDescriptorPool.TvkuDescriptorPool;
- TvkuDescriptorPoolFactory = uvkuDescriptorPoolFactory.TvkuDescriptorPoolFactory;
- TvkuDescriptorSet = uvkuDescriptorSet.TvkuDescriptorSet;
+ TvkuDescriptorPool = uvkuDescriptorPool.TvkuDescriptorPool;
+ TvkuDescriptorPoolFactory = uvkuDescriptorPoolFactory.TvkuDescriptorPoolFactory;
+ TvkuDescriptorSet = uvkuDescriptorSet.TvkuDescriptorSet;
+
+ { Semaphore }
+ TvkuSemaphore = uvkuSemaphore.TvkuSemaphore;
{ Utils }
- TvkuException = uvkuUtils.TvkuException;
- TvkuErrorException = uvkuUtils.TvkuErrorException;
- TvkuInvalidFuncPtrException = uvkuUtils.TvkuInvalidFuncPtrException;
+ TvkuException = uvkuUtils.TvkuException;
+ TvkuErrorException = uvkuUtils.TvkuErrorException;
+ TvkuInvalidFuncPtrException = uvkuUtils.TvkuInvalidFuncPtrException;
function vkExtent2D(const X, Y: VkUint32): TVkExtent2D;
function vkExtent3D(const X, Y, Z: VkUint32): TVkExtent3D;
diff --git a/projects/utils/uvkuBuffer.pas b/projects/utils/uvkuBuffer.pas
index b46390e..d8a1ff3 100644
--- a/projects/utils/uvkuBuffer.pas
+++ b/projects/utils/uvkuBuffer.pas
@@ -56,7 +56,7 @@ procedure TvkuBuffer.CreateHandle(const aCreateInfo: TVkBufferCreateInfo);
var err: TVkResult;
begin
err := fDeviceCommands.vkCreateBuffer(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create buffer', err);
end;
@@ -65,7 +65,7 @@ procedure TvkuBuffer.BindMemory(const aMemory: VkDeviceMemory; const aOffset: Vk
var err: TVkResult;
begin
err := fDeviceCommands.vkBindBufferMemory(fDeviceCommands.Device, fHandle, aMemory, aOffset);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to bind buffer memory', err);
fMemory := aMemory;
end;
@@ -102,7 +102,7 @@ begin
if not Assigned(aAllocCallbacks) then
aAllocCallbacks := AllocCallbacks;
err := fDeviceCommands.vkAllocateMemory(fDeviceCommands.Device, @MemAllocInfo, aAllocCallbacks, @Mem);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to allocate buffer memory', err);
fBufferMemory := TvkuDeviceMemory.Create(Mem, true, fDeviceCommands, aAllocCallbacks);
BindMemory(fBufferMemory.Handle, 0);
diff --git a/projects/utils/uvkuBufferView.pas b/projects/utils/uvkuBufferView.pas
index 3c85465..1e4cbd9 100644
--- a/projects/utils/uvkuBufferView.pas
+++ b/projects/utils/uvkuBufferView.pas
@@ -44,7 +44,7 @@ procedure TvkuBufferView.CreateHandle(const aCreateInfo: TVkBufferViewCreateInfo
var err: TVkResult;
begin
err := fDeviceCommands.vkCreateBufferView(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create buffer view', err);
end;
diff --git a/projects/utils/uvkuCommandBuffer.pas b/projects/utils/uvkuCommandBuffer.pas
index d407c3b..687af57 100644
--- a/projects/utils/uvkuCommandBuffer.pas
+++ b/projects/utils/uvkuCommandBuffer.pas
@@ -186,7 +186,7 @@ begin
Info.flags := []; // TODO
Info.pInheritanceInfo := nil; // TODO
err := DeviceCommands.vkBeginCommandBuffer(fHandle, @Info);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to begin command buffer', err);
end;
@@ -195,7 +195,7 @@ procedure TvkuCommandBuffer.EndCommand;
var err: TVkResult;
begin
err := fDeviceCommands.vkEndCommandBuffer(fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to end command buffer', err);
end;
diff --git a/projects/utils/uvkuCommandPool.pas b/projects/utils/uvkuCommandPool.pas
index 43400f9..81f487d 100644
--- a/projects/utils/uvkuCommandPool.pas
+++ b/projects/utils/uvkuCommandPool.pas
@@ -54,7 +54,7 @@ procedure TvkuCommandPool.CreateHandle(const aCreateInfo: TVkCommandPoolCreateIn
var err: TVkResult;
begin
err := fDeviceCommands.vkCreateCommandPool(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create command pool', err);
end;
@@ -78,7 +78,7 @@ begin
AllocInfo.commandBufferCount := aCount;
SetLength(result, aCount);
err := fDeviceCommands.vkAllocateCommandBuffers(fDeviceCommands.Device, @AllocInfo, @result[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create command buffers', err);
end;
diff --git a/projects/utils/uvkuDebugReporter.pas b/projects/utils/uvkuDebugReporter.pas
index 1948fa0..e62b1a7 100644
--- a/projects/utils/uvkuDebugReporter.pas
+++ b/projects/utils/uvkuDebugReporter.pas
@@ -107,7 +107,7 @@ begin
VK_DEBUG_REPORT_DEBUG_BIT_EXT
];
err := fInstanceCommands.vkCreateDebugReportCallbackEXT(fInstanceCommands.Instance, @CreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create debug report handle', err);
end;
diff --git a/projects/utils/uvkuDescriptorPool.pas b/projects/utils/uvkuDescriptorPool.pas
index 5c7bf8b..a94fe84 100644
--- a/projects/utils/uvkuDescriptorPool.pas
+++ b/projects/utils/uvkuDescriptorPool.pas
@@ -55,7 +55,7 @@ begin
if not Assigned(fDeviceCommands.vkCreateDescriptorPool) then
raise TvkuInvalidFuncPtrException.Create('vkCreateDescriptorPool');
err := fDeviceCommands.vkCreateDescriptorPool(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create descriptor pool', err);
end;
@@ -81,7 +81,7 @@ begin
AllocInfo.pSetLayouts := @aDescriptorSetLayouts[0];
SetLength(result, AllocInfo.descriptorSetCount);
err := fDeviceCommands.vkAllocateDescriptorSets(fDeviceCommands.Device, @AllocInfo, @result[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to allocate descriptor sets', err);
end;
@@ -98,7 +98,7 @@ begin
if not Assigned(fDeviceCommands.vkFreeDescriptorSets) then
raise TvkuInvalidFuncPtrException.Create('vkFreeDescriptorSets');
err := fDeviceCommands.vkFreeDescriptorSets(fDeviceCommands.Device, fHandle, Length(aDescriptorSets), @aDescriptorSets[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to free descriptor sets', err);
end;
diff --git a/projects/utils/uvkuDescriptorSetLayout.pas b/projects/utils/uvkuDescriptorSetLayout.pas
index a3b5a52..f811775 100644
--- a/projects/utils/uvkuDescriptorSetLayout.pas
+++ b/projects/utils/uvkuDescriptorSetLayout.pas
@@ -46,7 +46,7 @@ begin
if not Assigned(fDeviceCommands.vkCreateDescriptorSetLayout) then
raise TvkuInvalidFuncPtrException.Create('vkCreateDescriptorSetLayout');
err := fDeviceCommands.vkCreateDescriptorSetLayout(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create descriptor set layout', err);
end;
diff --git a/projects/utils/uvkuDevice.pas b/projects/utils/uvkuDevice.pas
index 7159e33..3f8a072 100644
--- a/projects/utils/uvkuDevice.pas
+++ b/projects/utils/uvkuDevice.pas
@@ -113,6 +113,7 @@ type
procedure FreeMemory(
const aMemory: VkDeviceMemory;
aAllocCallbacks: PVkAllocationCallbacks = nil);
+ procedure WaitIdle;
function UpdateDescriptorSet: TvkuUpdateDescriptorSetHelper;
@@ -333,7 +334,7 @@ begin
if not Assigned(fInstanceCommands.vkCreateDevice) then
raise TvkuInvalidFuncPtrException.Create('vkCreateDevice');
err := fInstanceCommands.vkCreateDevice(aPhyDevice, aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create device', err);
fDeviceCommands := LoadDeviceCommands(fInstanceCommands.Instance, fHandle);
if not Assigned(fDeviceCommands) then
@@ -365,7 +366,7 @@ begin
if not Assigned(aAllocCallbacks) then
aAllocCallbacks := AllocCallbacks;
err := fDeviceCommands.vkAllocateMemory(fHandle, @AllocInfo, aAllocCallbacks, @result);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to allocate device memory', err);
end;
@@ -377,6 +378,15 @@ begin
fDeviceCommands.vkFreeMemory(fHandle, aMemory, aAllocCallbacks);
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuDevice.WaitIdle;
+var err: TVkResult;
+begin
+ err := fDeviceCommands.vkDeviceWaitIdle(fHandle);
+ if (err <> VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to wait for device idle', err);
+end;
+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDevice.UpdateDescriptorSet: TvkuUpdateDescriptorSetHelper;
begin
diff --git a/projects/utils/uvkuDeviceFactory.pas b/projects/utils/uvkuDeviceFactory.pas
index 6d6db35..0152e45 100644
--- a/projects/utils/uvkuDeviceFactory.pas
+++ b/projects/utils/uvkuDeviceFactory.pas
@@ -103,14 +103,14 @@ type
fvkEnabledExtensionNames: array of PVkChar;
fvkQueueCreateInfos: array of TVkDeviceQueueCreateInfo;
- function GetLayers: TStrings;
- function GetExtensions: TStrings;
+ function GetEnabledLayerNames: TStrings;
+ function GetEnabledExtensionNames: 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;
+ property Flags: VkDeviceCreateFlags read fFlags write fFlags;
+ property EnabledLayerNames: TStrings read GetEnabledLayerNames;
+ property EnabledExtensionNames: TStrings read GetEnabledExtensionNames;
+ property EnabledFeatures: TvkuPhysicalDeviceFeatures read fEnabledFeatures;
+ property QueueCreateInfos: TvkuQueueCreateInfoList read fQueueCreateInfos;
function GetStructure: TVkDeviceCreateInfo;
procedure SetStructure(const aData: TVkDeviceCreateInfo);
@@ -288,13 +288,13 @@ end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuDeviceFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuDeviceFactory.GetLayers: TStrings;
+function TvkuDeviceFactory.GetEnabledLayerNames: TStrings;
begin
result := fEnabledLayerNames;
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuDeviceFactory.GetExtensions: TStrings;
+function TvkuDeviceFactory.GetEnabledExtensionNames: TStrings;
begin
result := fEnabledExtensionNames;
end;
diff --git a/projects/utils/uvkuDeviceMemory.pas b/projects/utils/uvkuDeviceMemory.pas
index 7cc6ed3..b3b1a40 100644
--- a/projects/utils/uvkuDeviceMemory.pas
+++ b/projects/utils/uvkuDeviceMemory.pas
@@ -47,7 +47,7 @@ begin
if not Assigned(fDeviceCommands.vkAllocateMemory) then
raise TvkuInvalidFuncPtrException.Create('vkAllocateMemory');
err := fDeviceCommands.vkAllocateMemory(fDeviceCommands.Device, @aAllocInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to allocate device memory', err);
end;
@@ -56,7 +56,7 @@ function TvkuDeviceMemory.Map(const aOffset: VkDeviceSize; aSize: VkDeviceSize;
var err: TVkResult;
begin
err := fDeviceCommands.vkMapMemory(fDeviceCommands.Device, fHandle, aOffset, aSize, aFlags, @result);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to map device memory', err);
end;
diff --git a/projects/utils/uvkuFrameBuffer.pas b/projects/utils/uvkuFrameBuffer.pas
index 3dde8b6..5a779bb 100644
--- a/projects/utils/uvkuFrameBuffer.pas
+++ b/projects/utils/uvkuFrameBuffer.pas
@@ -46,7 +46,7 @@ begin
if not Assigned(fDeviceCommands.vkCreateFramebuffer) then
raise TvkuInvalidFuncPtrException.Create('vkCreateFramebuffer');
err := fDeviceCommands.vkCreateFramebuffer(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create frame buffer', err);
end;
diff --git a/projects/utils/uvkuImage.pas b/projects/utils/uvkuImage.pas
index 37bf80e..fa85e68 100644
--- a/projects/utils/uvkuImage.pas
+++ b/projects/utils/uvkuImage.pas
@@ -60,7 +60,7 @@ procedure TvkuImage.CreateHandle(const aCreateInfo: TVkImageCreateInfo);
var err: TVkResult;
begin
err := fDeviceCommands.vkCreateImage(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
TvkuErrorException.Create('unable to create image', err);
end;
@@ -86,8 +86,8 @@ begin
result.dstAccessMask := [];
result.oldLayout := aOldLayout;
result.newLayout := aNewLayout;
- result.srcQueueFamilyIndex := 0;
- result.dstQueueFamilyIndex := 0;
+ result.srcQueueFamilyIndex := VK_QUEUE_FAMILY_IGNORED;
+ result.dstQueueFamilyIndex := VK_QUEUE_FAMILY_IGNORED;
result.image := fHandle;
result.subresourceRange := range;
@@ -159,7 +159,7 @@ procedure TvkuImage.BindMemory(const aMemory: VkDeviceMemory; const aOffset: VkD
var err: TVkResult;
begin
err := fDeviceCommands.vkBindImageMemory(fDeviceCommands.Device, fHandle, aMemory, aOffset);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
TvkuErrorException.Create('unable to bind image memory', err);
fMemory := aMemory;
end;
@@ -195,7 +195,7 @@ begin
if not Assigned(aAllocCallbacks) then
aAllocCallbacks := AllocCallbacks;
err := fDeviceCommands.vkAllocateMemory(fDeviceCommands.Device, @MemAllocInfo, aAllocCallbacks, @Mem);
- if (err < VK_SUCCESS) then
+ 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);
diff --git a/projects/utils/uvkuImageView.pas b/projects/utils/uvkuImageView.pas
index e4ec45a..c955574 100644
--- a/projects/utils/uvkuImageView.pas
+++ b/projects/utils/uvkuImageView.pas
@@ -46,7 +46,7 @@ begin
if not Assigned(fDeviceCommands.vkCreateImageView) then
raise TvkuInvalidFuncPtrException.Create('vkCreateImageView');
err := fDeviceCommands.vkCreateImageView(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create image view', err);
end;
diff --git a/projects/utils/uvkuInstance.pas b/projects/utils/uvkuInstance.pas
index bb00a81..6c64fed 100644
--- a/projects/utils/uvkuInstance.pas
+++ b/projects/utils/uvkuInstance.pas
@@ -52,12 +52,12 @@ begin
exit;
err := InstanceCommands.vkEnumeratePhysicalDevices(fHandle, @c, nil);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device number', err);
SetLength(fPhysicalDevices, c);
err := InstanceCommands.vkEnumeratePhysicalDevices(fHandle, @c, @fPhysicalDevices[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical devices', err);
end;
@@ -66,7 +66,7 @@ procedure TvkuInstance.CreateHandle(const aCreateInfo: PVkInstanceCreateInfo);
var e: TVkResult;
begin
e := vkCreateInstance(aCreateInfo, AllocCallbacks, @fHandle);
- if (e < VK_SUCCESS) then
+ if (e <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create vulkan instance', e);
fInstanceCommands := LoadInstanceCommands(fHandle);
if not Assigned(InstanceCommands) then
diff --git a/projects/utils/uvkuPhysicalDevice.pas b/projects/utils/uvkuPhysicalDevice.pas
index 33ce6d5..70dd4fb 100644
--- a/projects/utils/uvkuPhysicalDevice.pas
+++ b/projects/utils/uvkuPhysicalDevice.pas
@@ -114,7 +114,7 @@ begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceImageFormatProperties) then
raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceImageFormatProperties');
err := fInstanceCommands.vkGetPhysicalDeviceImageFormatProperties(fHandle, aFormat, aImageType, aTiling, aUsage, aFlags, @result);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device image format properties', err);
end;
@@ -140,7 +140,7 @@ begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfaceSupportKHR) then
raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceSurfaceSupportKHR', 'VK_KHR_surface');
err := fInstanceCommands.vkGetPhysicalDeviceSurfaceSupportKHR(fHandle, aQueueFamilyIndex, aSurface, @b);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device surface support', err);
result := (b <> 0);
end;
@@ -153,7 +153,7 @@ begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfaceCapabilitiesKHR) then
raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceSurfaceCapabilitiesKHR', 'VK_KHR_surface');
err := fInstanceCommands.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(fHandle, aSurface, @result);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device surface capabilities', err);
end;
@@ -179,11 +179,11 @@ begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfacePresentModesKHR) then
raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceSurfacePresentModesKHR', 'VK_KHR_surface');
err := fInstanceCommands.vkGetPhysicalDeviceSurfacePresentModesKHR(fHandle, aSurface, @c, nil);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device surface present mode count', err);
SetLength(result, c);
err := fInstanceCommands.vkGetPhysicalDeviceSurfacePresentModesKHR(fHandle, aSurface, @c, @result[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device surface present modes', err);
end;
@@ -197,11 +197,11 @@ begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceDisplayPropertiesKHR) then
raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceDisplayPropertiesKHR', 'VK_KHR_display');
err := fInstanceCommands.vkGetPhysicalDeviceDisplayPropertiesKHR(fHandle, @c, nil);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device display property count', err);
SetLength(result, c);
err := fInstanceCommands.vkGetPhysicalDeviceDisplayPropertiesKHR(fHandle, @c, @result[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device display properties', err);
end;
@@ -215,11 +215,11 @@ begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceDisplayPlanePropertiesKHR) then
raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceDisplayPlanePropertiesKHR', 'VK_KHR_display');
err := fInstanceCommands.vkGetPhysicalDeviceDisplayPlanePropertiesKHR(fHandle, @c, nil);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device display plane property count', err);
SetLength(result, c);
err := fInstanceCommands.vkGetPhysicalDeviceDisplayPlanePropertiesKHR(fHandle, @c, @result[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device display plane properties', err);
end;
@@ -233,11 +233,11 @@ begin
if not Assigned(fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR) then
raise TvkuInvalidFuncPtrException.Create('vkGetDisplayPlaneSupportedDisplaysKHR', 'VK_KHR_display');
err := fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR(fHandle, aPlaneIndex, @c, nil);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get supported display plane count', err);
SetLength(result, c);
err := fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR(fHandle, aPlaneIndex, @c, @result[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get supported display planes', err);
end;
@@ -251,11 +251,11 @@ begin
if not Assigned(fInstanceCommands.vkGetDisplayModePropertiesKHR) then
raise TvkuInvalidFuncPtrException.Create('vkGetDisplayModePropertiesKHR', 'VK_KHR_display');
err := fInstanceCommands.vkGetDisplayModePropertiesKHR(fHandle, aDisplay, @c, nil);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get display mode property count', err);
SetLength(result, c);
err := fInstanceCommands.vkGetDisplayModePropertiesKHR(fHandle, aDisplay, @c, @result[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get display mode properties', err);
end;
diff --git a/projects/utils/uvkuPipeline.pas b/projects/utils/uvkuPipeline.pas
index af9c186..e83010d 100644
--- a/projects/utils/uvkuPipeline.pas
+++ b/projects/utils/uvkuPipeline.pas
@@ -87,7 +87,7 @@ 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
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create graphics pipeline', err);
end;
@@ -110,7 +110,7 @@ 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
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create compute pipeline', err);
end;
diff --git a/projects/utils/uvkuPipelineCache.pas b/projects/utils/uvkuPipelineCache.pas
index 38bc57c..60f9ef0 100644
--- a/projects/utils/uvkuPipelineCache.pas
+++ b/projects/utils/uvkuPipelineCache.pas
@@ -44,7 +44,7 @@ procedure TvkuPipelineCache.CreateHandle(const aCreateInfo: TVkPipelineCacheCrea
var err: TVkResult;
begin
err := fDeviceCommands.vkCreatePipelineCache(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
TvkuErrorException.Create('unable to create pipeline cache', err);
end;
diff --git a/projects/utils/uvkuPipelineLayout.pas b/projects/utils/uvkuPipelineLayout.pas
index e02aa14..4e9931b 100644
--- a/projects/utils/uvkuPipelineLayout.pas
+++ b/projects/utils/uvkuPipelineLayout.pas
@@ -46,7 +46,7 @@ begin
if not Assigned(fDeviceCommands.vkCreatePipelineLayout) then
raise TvkuInvalidFuncPtrException.Create('vkCreatePipelineLayout');
err := fDeviceCommands.vkCreatePipelineLayout(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create pipeline layout', err);
end;
diff --git a/projects/utils/uvkuQueue.pas b/projects/utils/uvkuQueue.pas
index 0391359..999d343 100644
--- a/projects/utils/uvkuQueue.pas
+++ b/projects/utils/uvkuQueue.pas
@@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils,
- Vulkan, uvkuBase;
+ Vulkan, uvkuBase, uvkuTypes;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -24,6 +24,10 @@ type
const aCommandBuffers: array of VkCommandBuffer;
const aSignalSemaphores: array of VkSemaphore;
const aFence: VkFence);
+ function Present(
+ const aWaitSemaphore: array of VkSemaphore;
+ const aSwapChains: array of VkSwapchainKHR;
+ const aImageIndices: array of VkUint32): TVkResultArr;
procedure WaitIdle;
constructor Create(
@@ -49,8 +53,9 @@ 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');
+ if (Length(aWaitSemaphores) <> Length(aWaitDstStageMask))
+ and (Length(aWaitDstStageMask) <> 0) then
+ raise TvkuException.Create('aWaitDstStageMask must have the same number of elements as aWaitSemaphores or must be empty');
FillByte(SubmitInfo, SizeOf(SubmitInfo), 0);
SubmitInfo.sType := VK_STRUCTURE_TYPE_SUBMIT_INFO;
@@ -63,16 +68,43 @@ begin
SubmitInfo.signalSemaphoreCount := Length(aSignalSemaphores);
SubmitInfo.pSignalSemaphores := @aSignalSemaphores[0];
err := fDeviceCommands.vkQueueSubmit(fHandle, 1, @SubmitInfo, aFence);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to submit queue', err);
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuQueue.Present(
+ const aWaitSemaphore: array of VkSemaphore;
+ const aSwapChains: array of VkSwapchainKHR;
+ const aImageIndices: array of VkUint32): TVkResultArr;
+var
+ info: TVkPresentInfoKHR;
+ err: TVkResult;
+begin
+ if (Length(aSwapChains) <> Length(aImageIndices)) then
+ raise TvkuException.Create('aSwapChains and aImageIndices must have the same number of elements');
+
+ SetLength(result, Length(aSwapChains));
+ FillByte(info, SizeOf(info), 0);
+ info.sType := VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+ info.pNext := nil;
+ info.waitSemaphoreCount := Length(aWaitSemaphore);
+ info.pWaitSemaphores := @aWaitSemaphore[0];
+ info.swapchainCount := Length(aSwapChains);
+ info.pSwapchains := @aSwapChains[0];
+ info.pImageIndices := @aImageIndices[0];
+ info.pResults := @result[0];
+ err := fDeviceCommands.vkQueuePresentKHR(fHandle, @info);
+ if (err <> VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to present queue', err);
+end;
+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuQueue.WaitIdle;
var err: TVkResult;
begin
err := fDeviceCommands.vkQueueWaitIdle(fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('error while waiting for queue', err);
end;
diff --git a/projects/utils/uvkuRenderPass.pas b/projects/utils/uvkuRenderPass.pas
index 861f15e..a5a7ca9 100644
--- a/projects/utils/uvkuRenderPass.pas
+++ b/projects/utils/uvkuRenderPass.pas
@@ -46,7 +46,7 @@ begin
if not Assigned(fDeviceCommands.vkCreateRenderPass) then
raise TvkuInvalidFuncPtrException.Create('vkCreateRenderPass');
err := fDeviceCommands.vkCreateRenderPass(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create render pass', err);
end;
diff --git a/projects/utils/uvkuSemaphore.pas b/projects/utils/uvkuSemaphore.pas
new file mode 100644
index 0000000..db6d43f
--- /dev/null
+++ b/projects/utils/uvkuSemaphore.pas
@@ -0,0 +1,100 @@
+unit uvkuSemaphore;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuSemaphore = class(TvkuAllocHandle)
+ private
+ fHandle: VkSemaphore;
+ fDeviceCommands: TVkDeviceCommands;
+
+ procedure CreateHandle(const aCreateInfo: TVkSemaphoreCreateInfo);
+ public
+ property Handle: VkSemaphore read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ constructor Create(
+ const aFlags: VkSemaphoreCreateFlags;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aCreateInfo: TVkSemaphoreCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aHandle: VkSemaphore;
+ const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuSemaphore//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuSemaphore.CreateHandle(const aCreateInfo: TVkSemaphoreCreateInfo);
+var err: TVkResult;
+begin
+ if not Assigned(fDeviceCommands.vkCreateSemaphore) then
+ raise TvkuInvalidFuncPtrException.Create('vkCreateSemaphore');
+ err := fDeviceCommands.vkCreateSemaphore(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
+ if (err <> VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to create semaphore', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuSemaphore.Create(const aFlags: VkSemaphoreCreateFlags; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
+var CreateInfo: TVkSemaphoreCreateInfo;
+begin
+ FillByte(CreateInfo, SizeOf(CreateInfo), 0);
+ CreateInfo.sType := VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+ CreateInfo.pNext := nil;
+ CreateInfo.flags := aFlags;
+ Create(CreateInfo, aDeviceCommands, aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuSemaphore.Create(const aCreateInfo: TVkSemaphoreCreateInfo; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aCreateInfo);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuSemaphore.Create(const aHandle: VkSemaphore; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuSemaphore.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkDestroySemaphore(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuShaderModule.pas b/projects/utils/uvkuShaderModule.pas
index 0834d11..d5e1f3d 100644
--- a/projects/utils/uvkuShaderModule.pas
+++ b/projects/utils/uvkuShaderModule.pas
@@ -46,7 +46,7 @@ begin
if not Assigned(fDeviceCommands.vkCreateShaderModule) then
raise TvkuInvalidFuncPtrException.Create('vkCreateShaderModule');
err := fDeviceCommands.vkCreateShaderModule(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create shader module', err);
end;
diff --git a/projects/utils/uvkuSurface.pas b/projects/utils/uvkuSurface.pas
index ddb5dd8..b8ac585 100644
--- a/projects/utils/uvkuSurface.pas
+++ b/projects/utils/uvkuSurface.pas
@@ -56,7 +56,7 @@ begin
raise TvkuInvalidFuncPtrException.Create('vkCreateWin32SurfaceKHR', 'VK_KHR_win32_surface');
err := fInstanceCommands.vkCreateWin32SurfaceKHR(fInstanceCommands.Instance, aCreateInfo, AllocCallbacks, @fHandle);
{$ENDIF}
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create surface', err);
end;
diff --git a/projects/utils/uvkuSwapChain.pas b/projects/utils/uvkuSwapChain.pas
index 6d5e2b6..3195e3b 100644
--- a/projects/utils/uvkuSwapChain.pas
+++ b/projects/utils/uvkuSwapChain.pas
@@ -49,7 +49,7 @@ begin
if not Assigned(fDeviceCommands.vkCreateSwapchainKHR) then
raise TvkuException.Create('invalid function pointer: vkCreateSwapchainKHR; did you enabled the VK_KHR_swapchain extension?');
err := fDeviceCommands.vkCreateSwapchainKHR(fDeviceCommands.Device, aCreateInfo, AllocCallbacks, @fHandle);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create swap chain', err);
end;
@@ -62,11 +62,11 @@ begin
if not Assigned(fDeviceCommands.vkGetSwapchainImagesKHR) then
raise TvkuInvalidFuncPtrException.Create('vkGetSwapchainImagesKHR', 'VK_KHR_swapchain');
err := fDeviceCommands.vkGetSwapchainImagesKHR(fDeviceCommands.Device, fHandle, @c, nil);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get swap chain image count', err);
SetLength(result, c);
err := fDeviceCommands.vkGetSwapchainImagesKHR(fDeviceCommands.Device, fHandle, @c, @result[0]);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get swap chain images', err);
end;
@@ -78,7 +78,7 @@ begin
if not Assigned(fDeviceCommands.vkAcquireNextImageKHR) then
raise TvkuInvalidFuncPtrException.Create('vkAcquireNextImageKHR', 'VK_KHR_swapchain');
err := fDeviceCommands.vkAcquireNextImageKHR(fDeviceCommands.Device, fHandle, aTimeout, aSemaphore, aFence, @result);
- if (err < VK_SUCCESS) then
+ if (err <> VK_SUCCESS) then
raise TvkuErrorException.Create('unable to aquire next image', err);
end;
diff --git a/projects/utils/uvkuTypes.pas b/projects/utils/uvkuTypes.pas
index 52aa47c..c6b7231 100644
--- a/projects/utils/uvkuTypes.pas
+++ b/projects/utils/uvkuTypes.pas
@@ -97,6 +97,7 @@ type
TVkDescriptorImageInfoArr = array of TVkDescriptorImageInfo;
TVkDescriptorBufferInfoArr = array of TVkDescriptorBufferInfo;
TVkClearValueArr = array of TVkClearValue;
+ TVkResultArr = array of TVkResult;
TVkUint32List = specialize TvkuList;
TVkFloatList = specialize TvkuList;