diff --git a/com.io7m.jcoronado.api/src/main/java/com/io7m/jcoronado/api/VulkanLogicalDeviceType.java b/com.io7m.jcoronado.api/src/main/java/com/io7m/jcoronado/api/VulkanLogicalDeviceType.java index f7b188e..106b1a6 100644 --- a/com.io7m.jcoronado.api/src/main/java/com/io7m/jcoronado/api/VulkanLogicalDeviceType.java +++ b/com.io7m.jcoronado.api/src/main/java/com/io7m/jcoronado/api/VulkanLogicalDeviceType.java @@ -1016,6 +1016,21 @@ VulkanEventStatus getEventStatus( VulkanEventType event) throws VulkanException; + /** + * Retrieve the current value of a semaphore object. + * + * @param semaphore The semaphore + * + * @return The semaphore value + * + * @throws VulkanException On errors + */ + + @VulkanAPIFunctionType(vulkanFunction = "vkGetSemaphoreCounterValue") + long getSemaphoreCounterValue( + VulkanSemaphoreTimelineType semaphore) + throws VulkanException; + /** * Retrieve the status of a fence object. * @@ -1169,6 +1184,65 @@ default List createComputePipelines( return this.createComputePipelines(Optional.empty(), pipeline_infos); } + /** + * Wait for one or more semaphores to become signaled. + * + * @param semaphores The semaphores upon which to wait + * @param waitAll {@code true} if all semaphores must become signalled to + * stop waiting, {@code false} if any semaphore can become + * signalled + * @param timeoutNanos The timeout period in units of nanoseconds. + * + * @return A value indicating whether waiting succeeded or timed out + * + * @throws VulkanException On errors + */ + + @VulkanAPIFunctionType(vulkanFunction = "vkWaitSemaphores") + VulkanWaitStatus waitForTimelineSemaphores( + List semaphores, + boolean waitAll, + long timeoutNanos) + throws VulkanException; + + /** + * Wait for a semaphore to become signaled. + * + * @param semaphore The semaphores upon which to wait + * @param timeoutNanos The timeout period in units of nanoseconds. + * + * @return A value indicating whether waiting succeeded or timed out + * + * @throws VulkanException On errors + */ + + @VulkanAPIFunctionType(vulkanFunction = "vkWaitSemaphores") + default VulkanWaitStatus waitForTimelineSemaphore( + final VulkanSemaphoreTimelineWait semaphore, + final long timeoutNanos) + throws VulkanException + { + return this.waitForTimelineSemaphores( + List.of(semaphore), + true, + timeoutNanos); + } + + /** + * Signal a timeline semaphore. + * + * @param semaphore The semaphore + * @param value The value + * + * @throws VulkanException On errors + */ + + @VulkanAPIFunctionType(vulkanFunction = "vkSignalSemaphore") + void signalTimelineSemaphore( + VulkanSemaphoreTimelineType semaphore, + long value) + throws VulkanException; + /** * The result of fetching data for a pipeline cache. */ diff --git a/com.io7m.jcoronado.api/src/main/java/com/io7m/jcoronado/api/VulkanSemaphoreTimelineWait.java b/com.io7m.jcoronado.api/src/main/java/com/io7m/jcoronado/api/VulkanSemaphoreTimelineWait.java new file mode 100644 index 0000000..c624705 --- /dev/null +++ b/com.io7m.jcoronado.api/src/main/java/com/io7m/jcoronado/api/VulkanSemaphoreTimelineWait.java @@ -0,0 +1,44 @@ +/* + * Copyright © 2024 Mark Raynsford https://www.io7m.com + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +package com.io7m.jcoronado.api; + +import java.util.Objects; + +/** + * A request to wait until the given semaphore has at least the given value. + * + * @param semaphore The semaphore + * @param value The value + */ + +public record VulkanSemaphoreTimelineWait( + VulkanSemaphoreTimelineType semaphore, + long value) +{ + /** + * A request to wait until the given semaphore has at least the given value. + * + * @param semaphore The semaphore + * @param value The value + */ + + public VulkanSemaphoreTimelineWait + { + Objects.requireNonNull(semaphore, "semaphore"); + } +} diff --git a/com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloVulkan.java b/com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloVulkan.java index 45367ca..857de1e 100644 --- a/com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloVulkan.java +++ b/com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloVulkan.java @@ -67,8 +67,8 @@ import com.io7m.jcoronado.api.VulkanRenderPassCreateInfo; import com.io7m.jcoronado.api.VulkanResourceException; import com.io7m.jcoronado.api.VulkanSemaphoreBinaryCreateInfo; +import com.io7m.jcoronado.api.VulkanSemaphoreBinaryType; import com.io7m.jcoronado.api.VulkanSemaphoreSubmitInfo; -import com.io7m.jcoronado.api.VulkanSemaphoreType; import com.io7m.jcoronado.api.VulkanShaderModuleCreateInfo; import com.io7m.jcoronado.api.VulkanShaderModuleType; import com.io7m.jcoronado.api.VulkanSharingMode; @@ -95,6 +95,11 @@ import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanPresentInfoKHR; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanPresentModeKHR; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainCreateInfo; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainNotReady; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainOK; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainOutOfDate; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainSubOptimal; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainTimedOut; import com.io7m.jcoronado.lwjgl.VulkanLWJGLHostAllocatorJeMalloc; import com.io7m.jcoronado.lwjgl.VulkanLWJGLInstanceProvider; import com.io7m.jcoronado.lwjgl.VulkanLWJGLTemporaryAllocator; @@ -182,8 +187,8 @@ public HelloVulkan() private static void drawFrame( final VulkanExtKHRSwapChainType khrSwapchainExt, final VulkanKHRSwapChainType swapChain, - final VulkanSemaphoreType imageAvailable, - final VulkanSemaphoreType renderFinished, + final VulkanSemaphoreBinaryType imageAvailable, + final VulkanSemaphoreBinaryType renderFinished, final List graphicsCommandBuffers, final VulkanQueueType graphicsQueue, final VulkanQueueType queuePresentation) @@ -200,14 +205,29 @@ private static void drawFrame( 0xffff_ffff_ffff_ffffL, imageAvailable); - final var imageIndexOption = acquisition.imageIndex(); - if (!imageIndexOption.isPresent()) { - LOG.error("could not acquire image"); - return; + final int imageIndex; + switch (acquisition) { + case final VulkanSwapChainOK r -> { + imageIndex = r.imageIndex(); + } + case final VulkanSwapChainNotReady r -> { + LOG.error("Could not acquire image ({})", r); + return; + } + case final VulkanSwapChainOutOfDate r -> { + LOG.error("Could not acquire image ({})", r); + return; + } + case final VulkanSwapChainSubOptimal r -> { + LOG.error("Could not acquire image ({})", r); + return; + } + case final VulkanSwapChainTimedOut r -> { + LOG.error("Could not acquire image ({})", r); + return; + } } - final var imageIndex = - imageIndexOption.getAsInt(); final var graphicsCommandBuffer = graphicsCommandBuffers.get(imageIndex); @@ -516,7 +536,7 @@ private static VulkanSurfaceFormatKHR pickSurfaceFormat( for (final var format : formats) { if (format.format() == VK_FORMAT_B8G8R8A8_UNORM - && format.colorSpace() == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { + && format.colorSpace() == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { return format; } } @@ -950,11 +970,15 @@ public void execute() */ final var graphicsQueue = - device.queue(graphicsQueueProps.queueFamilyIndex(), new VulkanQueueIndex(0)) + device.queue( + graphicsQueueProps.queueFamilyIndex(), + new VulkanQueueIndex(0)) .orElseThrow(() -> new IllegalStateException( "Could not find graphics queue")); final var presentationQueue = - device.queue(presentationQueueProps.queueFamilyIndex(), new VulkanQueueIndex(0)) + device.queue( + presentationQueueProps.queueFamilyIndex(), + new VulkanQueueIndex(0)) .orElseThrow(() -> new IllegalStateException( "Could not find presentation queue")); diff --git a/com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloVulkanWithVMA.java b/com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloVulkanWithVMA.java index 73af55c..80fb107 100644 --- a/com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloVulkanWithVMA.java +++ b/com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloVulkanWithVMA.java @@ -92,6 +92,7 @@ import com.io7m.jcoronado.api.VulkanSamplerCreateInfo; import com.io7m.jcoronado.api.VulkanSamplerType; import com.io7m.jcoronado.api.VulkanSemaphoreBinaryCreateInfo; +import com.io7m.jcoronado.api.VulkanSemaphoreBinaryType; import com.io7m.jcoronado.api.VulkanSemaphoreSubmitInfo; import com.io7m.jcoronado.api.VulkanSemaphoreType; import com.io7m.jcoronado.api.VulkanShaderModuleCreateInfo; @@ -121,6 +122,11 @@ import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanPresentInfoKHR; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanPresentModeKHR; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainCreateInfo; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainNotReady; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainOK; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainOutOfDate; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainSubOptimal; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainTimedOut; import com.io7m.jcoronado.lwjgl.VMALWJGLAllocatorProvider; import com.io7m.jcoronado.lwjgl.VulkanLWJGLHostAllocatorJeMalloc; import com.io7m.jcoronado.lwjgl.VulkanLWJGLInstanceProvider; @@ -628,7 +634,8 @@ private static List createDescriptorSets( LOG.trace( "swap chain has {} images, allocating {} descriptor sets", imageCount, - imageCount); + imageCount + ); final var descriptorPoolUniformBuffer = VulkanDescriptorPoolSize.of( @@ -1126,8 +1133,8 @@ private static ArrayList createUniformBuffers( private static void drawFrame( final VulkanExtKHRSwapChainType khr_swapchain_ext, final VulkanKHRSwapChainType swap_chain, - final VulkanSemaphoreType imageAvailable, - final VulkanSemaphoreType renderFinished, + final VulkanSemaphoreBinaryType imageAvailable, + final VulkanSemaphoreBinaryType renderFinished, final List graphics_command_buffers, final VulkanQueueType graphics_queue, final VulkanQueueType queue_presentation) @@ -1144,16 +1151,31 @@ private static void drawFrame( 0xffff_ffff_ffff_ffffL, imageAvailable); - final var image_index_option = acquisition.imageIndex(); - if (!image_index_option.isPresent()) { - LOG.error("could not acquire image"); - return; + final int imageIndex; + switch (acquisition) { + case final VulkanSwapChainOK r -> { + imageIndex = r.imageIndex(); + } + case final VulkanSwapChainNotReady r -> { + LOG.error("Could not acquire image ({})", r); + return; + } + case final VulkanSwapChainOutOfDate r -> { + LOG.error("Could not acquire image ({})", r); + return; + } + case final VulkanSwapChainSubOptimal r -> { + LOG.error("Could not acquire image ({})", r); + return; + } + case final VulkanSwapChainTimedOut r -> { + LOG.error("Could not acquire image ({})", r); + return; + } } - final var image_index = - image_index_option.getAsInt(); final var graphicsCommandBuffer = - graphics_command_buffers.get(image_index); + graphics_command_buffers.get(imageIndex); /* * Wait until the image is available (via the image available semaphore) before writing @@ -1189,7 +1211,7 @@ private static void drawFrame( final var presentation_info = VulkanPresentInfoKHR.builder() - .addImageIndices(image_index) + .addImageIndices(imageIndex) .addSwapChains(swap_chain) .addWaitSemaphores(renderFinished) .build(); diff --git a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanExtKHRSwapChainType.java b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanExtKHRSwapChainType.java index b400188..d7c4976 100644 --- a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanExtKHRSwapChainType.java +++ b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanExtKHRSwapChainType.java @@ -23,7 +23,7 @@ import com.io7m.jcoronado.api.VulkanImageType; import com.io7m.jcoronado.api.VulkanLogicalDeviceType; import com.io7m.jcoronado.api.VulkanQueueType; -import com.io7m.jcoronado.api.VulkanSemaphoreType; +import com.io7m.jcoronado.api.VulkanSemaphoreBinaryType; import java.util.List; @@ -99,9 +99,9 @@ List images() * @throws VulkanException On errors */ - VulkanSwapChainImageAcquisition acquireImageWithSemaphore( + VulkanSwapChainAcquisitionResultType acquireImageWithSemaphore( long timeout, - VulkanSemaphoreType semaphore) + VulkanSemaphoreBinaryType semaphore) throws VulkanException; /** @@ -117,7 +117,7 @@ VulkanSwapChainImageAcquisition acquireImageWithSemaphore( * @throws VulkanException On errors */ - VulkanSwapChainImageAcquisition acquireImageWithFence( + VulkanSwapChainAcquisitionResultType acquireImageWithFence( long timeout, VulkanFenceType fence) throws VulkanException; @@ -136,9 +136,9 @@ VulkanSwapChainImageAcquisition acquireImageWithFence( * @throws VulkanException On errors */ - VulkanSwapChainImageAcquisition acquireImageWithSemaphoreAndFence( + VulkanSwapChainAcquisitionResultType acquireImageWithSemaphoreAndFence( long timeout, - VulkanSemaphoreType semaphore, + VulkanSemaphoreBinaryType semaphore, VulkanFenceType fence) throws VulkanException; } diff --git a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainAcquisitionResultType.java b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainAcquisitionResultType.java new file mode 100644 index 0000000..57ad3eb --- /dev/null +++ b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainAcquisitionResultType.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2024 Mark Raynsford https://www.io7m.com + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +package com.io7m.jcoronado.extensions.khr_swapchain.api; + +/** + * The result of trying to acquire a swapchain image. + */ + +public sealed interface VulkanSwapChainAcquisitionResultType + permits VulkanSwapChainNotReady, + VulkanSwapChainOK, + VulkanSwapChainOutOfDate, + VulkanSwapChainSubOptimal, + VulkanSwapChainTimedOut +{ + +} diff --git a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainImageAcquisitionType.java b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainImageAcquisitionType.java deleted file mode 100644 index fdfc626..0000000 --- a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainImageAcquisitionType.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2018 Mark Raynsford http://io7m.com - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR - * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package com.io7m.jcoronado.extensions.khr_swapchain.api; - -import com.io7m.immutables.styles.ImmutablesStyleType; -import org.immutables.value.Value; - -import java.util.OptionalInt; - -/** - * The result of an attempt to acquire an image from the swap chain. - */ - -@ImmutablesStyleType -@Value.Immutable -public interface VulkanSwapChainImageAcquisitionType -{ - /** - * @return The index of the acquired image in the swapchain - */ - - @Value.Parameter - OptionalInt imageIndex(); - - /** - * If an image became available, and the swapchain no longer matches the surface properties - * exactly but can still be used to present to the surface successfully, this method will return - * {@code true}. - * - * @return {@code true} if the image is now suboptimal - */ - - @Value.Parameter - boolean subOptimal(); - - /** - * @return {@code true} iff a timeout was specified and no image was available within that time - */ - - @Value.Parameter - boolean timedOut(); -} diff --git a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainNotReady.java b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainNotReady.java new file mode 100644 index 0000000..e2d9563 --- /dev/null +++ b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainNotReady.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2024 Mark Raynsford https://www.io7m.com + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +package com.io7m.jcoronado.extensions.khr_swapchain.api; + +/** + * The swapchain is not ready + */ + +public record VulkanSwapChainNotReady() + implements VulkanSwapChainAcquisitionResultType +{ + +} diff --git a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainOK.java b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainOK.java new file mode 100644 index 0000000..90c8729 --- /dev/null +++ b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainOK.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2024 Mark Raynsford https://www.io7m.com + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +package com.io7m.jcoronado.extensions.khr_swapchain.api; + +/** + * The image at the given swapchain image index was obtained and is a format + * that is still optimal for rendering. + * @param imageIndex The image index + */ + +public record VulkanSwapChainOK( + int imageIndex) + implements VulkanSwapChainAcquisitionResultType +{ + +} diff --git a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainOutOfDate.java b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainOutOfDate.java new file mode 100644 index 0000000..a3ee95c --- /dev/null +++ b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainOutOfDate.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2024 Mark Raynsford https://www.io7m.com + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +package com.io7m.jcoronado.extensions.khr_swapchain.api; + +/** + * The swapchain is out of date and needs recreating. + */ + +public record VulkanSwapChainOutOfDate() + implements VulkanSwapChainAcquisitionResultType +{ + +} diff --git a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainSubOptimal.java b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainSubOptimal.java new file mode 100644 index 0000000..6314002 --- /dev/null +++ b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainSubOptimal.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2024 Mark Raynsford https://www.io7m.com + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +package com.io7m.jcoronado.extensions.khr_swapchain.api; + +/** + * The swapchain images are now suboptimal for rendering. + */ + +public record VulkanSwapChainSubOptimal() + implements VulkanSwapChainAcquisitionResultType +{ + +} diff --git a/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainTimedOut.java b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainTimedOut.java new file mode 100644 index 0000000..0b3e4b6 --- /dev/null +++ b/com.io7m.jcoronado.extensions.khr_surface.api/src/main/java/com/io7m/jcoronado/extensions/khr_swapchain/api/VulkanSwapChainTimedOut.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2024 Mark Raynsford https://www.io7m.com + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +package com.io7m.jcoronado.extensions.khr_swapchain.api; + +/** + * The operation timed out waiting for a swapchain image to become available. + */ + +public record VulkanSwapChainTimedOut() + implements VulkanSwapChainAcquisitionResultType +{ + +} diff --git a/com.io7m.jcoronado.fake/src/main/java/com/io7m/jcoronado/fake/VFakeExtKHRSwapChain.java b/com.io7m.jcoronado.fake/src/main/java/com/io7m/jcoronado/fake/VFakeExtKHRSwapChain.java index 49d44ec..b8930e4 100644 --- a/com.io7m.jcoronado.fake/src/main/java/com/io7m/jcoronado/fake/VFakeExtKHRSwapChain.java +++ b/com.io7m.jcoronado.fake/src/main/java/com/io7m/jcoronado/fake/VFakeExtKHRSwapChain.java @@ -22,15 +22,15 @@ import com.io7m.jcoronado.api.VulkanImageType; import com.io7m.jcoronado.api.VulkanLogicalDeviceType; import com.io7m.jcoronado.api.VulkanQueueType; -import com.io7m.jcoronado.api.VulkanSemaphoreType; +import com.io7m.jcoronado.api.VulkanSemaphoreBinaryType; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanExtKHRSwapChainType; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanPresentInfoKHR; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainAcquisitionResultType; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainCreateInfo; -import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainImageAcquisition; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainTimedOut; import java.util.List; import java.util.Objects; -import java.util.OptionalInt; /** * The surface extension. @@ -117,40 +117,28 @@ public List images() } @Override - public VulkanSwapChainImageAcquisition acquireImageWithSemaphore( + public VulkanSwapChainAcquisitionResultType acquireImageWithSemaphore( final long timeout, - final VulkanSemaphoreType semaphore) + final VulkanSemaphoreBinaryType semaphore) { - return VulkanSwapChainImageAcquisition.of( - OptionalInt.empty(), - false, - true - ); + return new VulkanSwapChainTimedOut(); } @Override - public VulkanSwapChainImageAcquisition acquireImageWithFence( + public VulkanSwapChainAcquisitionResultType acquireImageWithFence( final long timeout, final VulkanFenceType fence) { - return VulkanSwapChainImageAcquisition.of( - OptionalInt.empty(), - false, - true - ); + return new VulkanSwapChainTimedOut(); } @Override - public VulkanSwapChainImageAcquisition acquireImageWithSemaphoreAndFence( + public VulkanSwapChainAcquisitionResultType acquireImageWithSemaphoreAndFence( final long timeout, - final VulkanSemaphoreType semaphore, + final VulkanSemaphoreBinaryType semaphore, final VulkanFenceType fence) { - return VulkanSwapChainImageAcquisition.of( - OptionalInt.empty(), - false, - true - ); + return new VulkanSwapChainTimedOut(); } } } diff --git a/com.io7m.jcoronado.fake/src/main/java/com/io7m/jcoronado/fake/VFakeLogicalDevice.java b/com.io7m.jcoronado.fake/src/main/java/com/io7m/jcoronado/fake/VFakeLogicalDevice.java index 62bc9a4..5ca8cc7 100644 --- a/com.io7m.jcoronado.fake/src/main/java/com/io7m/jcoronado/fake/VFakeLogicalDevice.java +++ b/com.io7m.jcoronado.fake/src/main/java/com/io7m/jcoronado/fake/VFakeLogicalDevice.java @@ -76,6 +76,7 @@ import com.io7m.jcoronado.api.VulkanSemaphoreBinaryType; import com.io7m.jcoronado.api.VulkanSemaphoreTimelineCreateInfo; import com.io7m.jcoronado.api.VulkanSemaphoreTimelineType; +import com.io7m.jcoronado.api.VulkanSemaphoreTimelineWait; import com.io7m.jcoronado.api.VulkanShaderModuleCreateInfo; import com.io7m.jcoronado.api.VulkanShaderModuleType; import com.io7m.jcoronado.api.VulkanSubresourceLayout; @@ -520,6 +521,14 @@ public VulkanEventStatus getEventStatus( throw errorNotImplemented("getEventStatus"); } + @Override + public long getSemaphoreCounterValue( + final VulkanSemaphoreTimelineType semaphore) + throws VulkanException + { + throw errorNotImplemented("getSemaphoreCounterValue"); + } + @Override public VulkanFenceStatus getFenceStatus( final VulkanFenceType fence) @@ -555,4 +564,23 @@ public List createComputePipelines( { throw errorNotImplemented("createComputePipelines"); } + + @Override + public VulkanWaitStatus waitForTimelineSemaphores( + final List semaphores, + final boolean waitAll, + final long timeoutNanos) + throws VulkanException + { + throw errorNotImplemented("waitForSemaphores"); + } + + @Override + public void signalTimelineSemaphore( + final VulkanSemaphoreTimelineType semaphore, + final long value) + throws VulkanException + { + throw errorNotImplemented("signalTimelineSemaphore"); + } } diff --git a/com.io7m.jcoronado.lwjgl/src/main/java/com/io7m/jcoronado/lwjgl/internal/VulkanLWJGLExtKHRSwapChain.java b/com.io7m.jcoronado.lwjgl/src/main/java/com/io7m/jcoronado/lwjgl/internal/VulkanLWJGLExtKHRSwapChain.java index 572b469..d3c1559 100644 --- a/com.io7m.jcoronado.lwjgl/src/main/java/com/io7m/jcoronado/lwjgl/internal/VulkanLWJGLExtKHRSwapChain.java +++ b/com.io7m.jcoronado.lwjgl/src/main/java/com/io7m/jcoronado/lwjgl/internal/VulkanLWJGLExtKHRSwapChain.java @@ -33,8 +33,13 @@ import com.io7m.jcoronado.api.VulkanUncheckedException; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanExtKHRSwapChainType; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanPresentInfoKHR; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainAcquisitionResultType; import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainCreateInfo; -import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainImageAcquisition; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainNotReady; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainOK; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainOutOfDate; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainSubOptimal; +import com.io7m.jcoronado.extensions.khr_swapchain.api.VulkanSwapChainTimedOut; import com.io7m.junreachable.UnreachableCodeException; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.KHRSwapchain; @@ -207,14 +212,14 @@ private List images( .collect(Collectors.toList()); } - private VulkanSwapChainImageAcquisition acquireImage( + private VulkanSwapChainAcquisitionResultType acquireImage( final VulkanLWJGLKHRSwapChain chain, final long timeout, - final VulkanSemaphoreType semaphore, + final VulkanSemaphoreBinaryType semaphore, final VulkanFenceType fence) throws VulkanIncompatibleClassException, VulkanCallFailedException { - final long semaphore_handle = + final long semaphoreHandle = switch (semaphore) { case null -> { yield VK10.VK_NULL_HANDLE; @@ -223,81 +228,63 @@ private VulkanSwapChainImageAcquisition acquireImage( yield checkInstanceOf(b, VulkanLWJGLSemaphoreBinary.class) .handle(); } - case final VulkanSemaphoreTimelineType t -> { - yield checkInstanceOf(t, VulkanLWJGLSemaphoreTimeline.class) - .handle(); - } }; - final long fence_handle; + final long fenceHandle; if (fence != null) { - fence_handle = checkInstanceOf(fence, VulkanLWJGLFence.class) - .handle(); + fenceHandle = checkInstanceOf(fence, VulkanLWJGLFence.class).handle(); } else { - fence_handle = VK10.VK_NULL_HANDLE; + fenceHandle = VK10.VK_NULL_HANDLE; } - final var image_handles = new int[1]; + final var imageHandles = new int[1]; final var result = KHRSwapchain.vkAcquireNextImageKHR( chain.device.device(), chain.chain, timeout, - semaphore_handle, - fence_handle, - image_handles); - - final var image_handle = image_handles[0]; - switch (result) { - case VK10.VK_TIMEOUT: - return VulkanSwapChainImageAcquisition.builder() - .setSubOptimal(false) - .setTimedOut(true) - .build(); - case VK10.VK_NOT_READY: - return VulkanSwapChainImageAcquisition.builder() - .setSubOptimal(false) - .setTimedOut(false) - .build(); - case VK10.VK_SUCCESS: - return VulkanSwapChainImageAcquisition.builder() - .setSubOptimal(false) - .setTimedOut(false) - .setImageIndex(image_handle) - .build(); - case KHRSwapchain.VK_SUBOPTIMAL_KHR: - return VulkanSwapChainImageAcquisition.builder() - .setSubOptimal(true) - .setTimedOut(false) - .setImageIndex(image_handle) - .build(); - default: - VulkanChecks.checkReturnCode(result, "vkAcquireNextImageKHR"); - } + semaphoreHandle, + fenceHandle, + imageHandles + ); - throw new UnreachableCodeException(); + final var imageHandle = imageHandles[0]; + return switch (result) { + case VK10.VK_SUCCESS -> { + yield new VulkanSwapChainOK(imageHandle); + } + case VK10.VK_TIMEOUT -> { + yield new VulkanSwapChainTimedOut(); + } + case VK10.VK_NOT_READY -> { + yield new VulkanSwapChainNotReady(); + } + case KHRSwapchain.VK_SUBOPTIMAL_KHR -> { + yield new VulkanSwapChainSubOptimal(); + } + case KHRSwapchain.VK_ERROR_OUT_OF_DATE_KHR -> { + yield new VulkanSwapChainOutOfDate(); + } + default -> { + VulkanChecks.checkReturnCode(result, "vkAcquireNextImageKHR"); + throw new UnreachableCodeException(); + } + }; } @Override public VulkanKHRSwapChainType swapChainCreate( - final VulkanLogicalDeviceType in_device, + final VulkanLogicalDeviceType inDevice, final VulkanSwapChainCreateInfo info) throws VulkanException { - Objects.requireNonNull(in_device, "in_device"); + Objects.requireNonNull(inDevice, "inDevice"); Objects.requireNonNull(info, "info"); final var device = - checkInstanceOf( - in_device, - VulkanLWJGLLogicalDevice.class); - - Objects.requireNonNull(info, "info"); - + checkInstanceOf(inDevice, VulkanLWJGLLogicalDevice.class); final var surface = - checkInstanceOf( - info.surface(), - VulkanLWJGLExtKHRSurfaceValue.class); + checkInstanceOf(info.surface(), VulkanLWJGLExtKHRSurfaceValue.class); try (var stack = this.stack_initial.push()) { final var vk_info = @@ -343,26 +330,26 @@ public VulkanKHRSwapChainType swapChainCreate( @Override public void queuePresent( - final VulkanQueueType in_queue, - final VulkanPresentInfoKHR present_info) + final VulkanQueueType inQueue, + final VulkanPresentInfoKHR presentInfo) throws VulkanException { final var queue = - checkInstanceOf(in_queue, VulkanLWJGLQueue.class); + checkInstanceOf(inQueue, VulkanLWJGLQueue.class); - Objects.requireNonNull(present_info, "present_info"); + Objects.requireNonNull(presentInfo, "presentInfo"); try (var stack = this.stack_initial.push()) { final var buffer_indices = - packImageIndices(stack, present_info.imageIndices()); + packImageIndices(stack, presentInfo.imageIndices()); - final var swap_chains = present_info.swapChains(); + final var swap_chains = presentInfo.swapChains(); final var swap_chain_count = swap_chains.size(); final var buffer_swapchains = packSwapChains(stack, swap_chains); final var buffer_semaphores = - packSemaphoresX(stack, present_info.waitSemaphores()); + packSemaphoresX(stack, presentInfo.waitSemaphores()); final var vk_info = VkPresentInfoKHR.calloc(stack) @@ -436,9 +423,9 @@ public List images() } @Override - public VulkanSwapChainImageAcquisition acquireImageWithSemaphore( + public VulkanSwapChainAcquisitionResultType acquireImageWithSemaphore( final long timeout, - final VulkanSemaphoreType semaphore) + final VulkanSemaphoreBinaryType semaphore) throws VulkanException { Objects.requireNonNull(semaphore, "semaphore"); @@ -446,7 +433,7 @@ public VulkanSwapChainImageAcquisition acquireImageWithSemaphore( } @Override - public VulkanSwapChainImageAcquisition acquireImageWithFence( + public VulkanSwapChainAcquisitionResultType acquireImageWithFence( final long timeout, final VulkanFenceType fence) throws VulkanException @@ -456,9 +443,9 @@ public VulkanSwapChainImageAcquisition acquireImageWithFence( } @Override - public VulkanSwapChainImageAcquisition acquireImageWithSemaphoreAndFence( + public VulkanSwapChainAcquisitionResultType acquireImageWithSemaphoreAndFence( final long timeout, - final VulkanSemaphoreType semaphore, + final VulkanSemaphoreBinaryType semaphore, final VulkanFenceType fence) throws VulkanException { diff --git a/com.io7m.jcoronado.lwjgl/src/main/java/com/io7m/jcoronado/lwjgl/internal/VulkanLWJGLLogicalDevice.java b/com.io7m.jcoronado.lwjgl/src/main/java/com/io7m/jcoronado/lwjgl/internal/VulkanLWJGLLogicalDevice.java index 30559b5..f27f9bc 100644 --- a/com.io7m.jcoronado.lwjgl/src/main/java/com/io7m/jcoronado/lwjgl/internal/VulkanLWJGLLogicalDevice.java +++ b/com.io7m.jcoronado.lwjgl/src/main/java/com/io7m/jcoronado/lwjgl/internal/VulkanLWJGLLogicalDevice.java @@ -80,6 +80,7 @@ import com.io7m.jcoronado.api.VulkanSemaphoreBinaryType; import com.io7m.jcoronado.api.VulkanSemaphoreTimelineCreateInfo; import com.io7m.jcoronado.api.VulkanSemaphoreTimelineType; +import com.io7m.jcoronado.api.VulkanSemaphoreTimelineWait; import com.io7m.jcoronado.api.VulkanShaderModuleCreateInfo; import com.io7m.jcoronado.api.VulkanShaderModuleType; import com.io7m.jcoronado.api.VulkanSubresourceLayout; @@ -95,7 +96,9 @@ import org.lwjgl.vulkan.VkMemoryRequirements; import org.lwjgl.vulkan.VkQueue; import org.lwjgl.vulkan.VkSemaphoreCreateInfo; +import org.lwjgl.vulkan.VkSemaphoreSignalInfo; import org.lwjgl.vulkan.VkSemaphoreTypeCreateInfo; +import org.lwjgl.vulkan.VkSemaphoreWaitInfo; import org.lwjgl.vulkan.VkSubresourceLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -1596,6 +1599,37 @@ public void mergePipelineCaches( throw VulkanChecks.failed(result, "vkGetEventStatus"); } + @Override + public long getSemaphoreCounterValue( + final VulkanSemaphoreTimelineType semaphore) + throws VulkanException + { + Objects.requireNonNull(semaphore, "semaphore"); + + this.checkNotClosed(); + + final var vkSemaphore = + checkInstanceOf(semaphore, VulkanLWJGLSemaphoreTimeline.class); + + try (var stack = this.stack_initial.push()) { + final var data = + stack.callocLong(1); + + final var result = + VK13.vkGetSemaphoreCounterValue( + this.device, + vkSemaphore.handle(), + data + ); + + if (result == VK_SUCCESS) { + return data.get(0); + } + + throw VulkanChecks.failed(result, "vkGetSemaphoreCounterValue"); + } + } + @Override public @VulkanExternallySynchronizedType VulkanFenceStatus getFenceStatus( final VulkanFenceType fence) @@ -1692,6 +1726,81 @@ public List createComputePipelines( } } + @Override + public VulkanWaitStatus waitForTimelineSemaphores( + final List semaphores, + final boolean waitAll, + final long timeoutNanos) + throws VulkanException + { + Objects.requireNonNull(semaphores, "semaphores"); + + this.checkNotClosed(); + + try (var stack = this.stack_initial.push()) { + final var info = + VkSemaphoreWaitInfo.calloc(stack); + + info.sType(VK13.VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO); + if (!waitAll) { + info.flags(VK13.VK_SEMAPHORE_WAIT_ANY_BIT); + } + info.semaphoreCount(semaphores.size()); + info.pValues( + packLongs(stack, semaphores, VulkanSemaphoreTimelineWait::value) + ); + info.pSemaphores( + packLongs( + stack, + semaphores, + value -> { + return checkInstanceOf( + value.semaphore(), + VulkanLWJGLSemaphoreTimeline.class + ).handle(); + }) + ); + + final var r = + VK13.vkWaitSemaphores(this.device, info, timeoutNanos); + + if (r == VK_SUCCESS) { + return VK_WAIT_SUCCEEDED; + } + if (r == VK_TIMEOUT) { + return VK_WAIT_TIMED_OUT; + } + throw VulkanChecks.failed(r, "vkWaitSemaphores"); + } + } + + @Override + public void signalTimelineSemaphore( + final VulkanSemaphoreTimelineType semaphore, + final long value) + throws VulkanException + { + Objects.requireNonNull(semaphore, "semaphore"); + + this.checkNotClosed(); + + try (var stack = this.stack_initial.push()) { + final var info = + VkSemaphoreSignalInfo.calloc(stack); + info.sType(VK13.VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO); + info.semaphore( + checkInstanceOf(semaphore, VulkanLWJGLSemaphoreTimeline.class) + .handle() + ); + info.value(value); + + VulkanChecks.checkReturnCode( + VK13.vkSignalSemaphore(this.device, info), + "vkSignalSemaphore" + ); + } + } + @Override protected Logger logger() {