2121import org .lwjgl .glfw .GLFWVulkan ;
2222import org .lwjgl .system .MemoryStack ;
2323import org .lwjgl .system .MemoryUtil ;
24- import org .lwjgl .vulkan .KHRSurface ;
25- import org .lwjgl .vulkan .KHRSwapchain ;
26- import org .lwjgl .vulkan .VK10 ;
27- import org .lwjgl .vulkan .VkCommandBuffer ;
28- import org .lwjgl .vulkan .VkExtent2D ;
29- import org .lwjgl .vulkan .VkImageBlit ;
30- import org .lwjgl .vulkan .VkImageMemoryBarrier ;
31- import org .lwjgl .vulkan .VkImageSubresourceLayers ;
32- import org .lwjgl .vulkan .VkImageSubresourceRange ;
33- import org .lwjgl .vulkan .VkMemoryBarrier ;
34- import org .lwjgl .vulkan .VkOffset3D ;
35- import org .lwjgl .vulkan .VkPresentInfoKHR ;
36- import org .lwjgl .vulkan .VkQueue ;
37- import org .lwjgl .vulkan .VkSurfaceCapabilitiesKHR ;
38- import org .lwjgl .vulkan .VkSurfaceFormatKHR ;
39- import org .lwjgl .vulkan .VkSwapchainCreateInfoKHR ;
24+ import org .lwjgl .vulkan .*;
4025import org .lwjgl .vulkan .VkSurfaceFormatKHR .Buffer ;
4126
4227@ Environment (EnvType .CLIENT )
@@ -50,6 +35,9 @@ public class Vk11GpuSurface implements GpuSurfaceBackend {
5035 private int swapchainWidth ;
5136 private int swapchainHeight ;
5237 private final LongList swapchainImages = new LongArrayList ();
38+ private long [] acquireSemaphores = null ;
39+ private long [] presentSemaphores = null ;
40+ private int currentAcquireSemaphore = 0 ;
5341 private int currentImageIndex = NO_CURRENT_IMAGE ;
5442 private @ Nullable SurfaceException eatenException = null ;
5543 private boolean swapchainSuboptimal ;
@@ -143,6 +131,8 @@ private void destroySwapchain() {
143131 if (this .swapchain != 0L ) {
144132 this .device .graphicsQueue ().waitIdle ();
145133 KHRSwapchain .vkDestroySwapchainKHR (this .device .vkDevice (), this .swapchain , null );
134+ destroySemaphores (presentSemaphores );
135+ destroySemaphores (acquireSemaphores );
146136 this .swapchain = 0L ;
147137 }
148138 }
@@ -204,6 +194,12 @@ public void configure(final GpuSurface.Configuration config) throws SurfaceExcep
204194 this .swapchainImages .add (swapchainImagesPtr .get (i ));
205195 }
206196
197+ acquireSemaphores = new long [swapchainImages .size ()];
198+ createSemaphores (acquireSemaphores );
199+
200+ presentSemaphores = new long [swapchainImages .size ()];
201+ createSemaphores (presentSemaphores );
202+
207203 this .swapchainSuboptimal = false ;
208204 this .swapchainOutOfDate = false ;
209205 this .swapchainWidth = config .width ();
@@ -235,8 +231,8 @@ public void acquireNextTexture() throws SurfaceException {
235231 try (MemoryStack stack = MemoryStack .stackPush ()) {
236232 IntBuffer frameIndexPtr = stack .callocInt (1 );
237233 frameIndexPtr .put (0 , NO_CURRENT_IMAGE );
238- Vk11CommandEncoder commandEncoder = this . device . createCommandEncoder () ;
239- long acquireSemaphore = commandEncoder . acquireSemaphore () ;
234+ currentAcquireSemaphore = ( currentAcquireSemaphore + 1 ) % acquireSemaphores . length ;
235+ long acquireSemaphore = acquireSemaphores [ currentAcquireSemaphore ] ;
240236 int result = KHRSwapchain .vkAcquireNextImageKHR (this .device .vkDevice (), this .swapchain , 50000000000L , acquireSemaphore , 0L , frameIndexPtr );
241237 if (result == VK10 .VK_TIMEOUT ) {
242238 throw new IllegalStateException ("GPU timeout attempting to acquire next frame" );
@@ -358,8 +354,8 @@ public void blitFromTexture(final @NotNull CommandEncoderBackend commandEncoder,
358354 );
359355 }
360356
361- vk11CommandEncoder .waitSemaphore (vk11CommandEncoder . acquireSemaphore () , 0L , VK10 .VK_PIPELINE_STAGE_ALL_COMMANDS_BIT );
362- vk11CommandEncoder .signalSemaphore (vk11CommandEncoder . presentSemaphore () , 0L , VK10 .VK_PIPELINE_STAGE_TRANSFER_BIT );
357+ vk11CommandEncoder .waitSemaphore (acquireSemaphores [ currentAcquireSemaphore ] , 0L , VK10 .VK_PIPELINE_STAGE_ALL_COMMANDS_BIT );
358+ vk11CommandEncoder .signalSemaphore (presentSemaphores [ currentImageIndex ] , 0L , VK10 .VK_PIPELINE_STAGE_TRANSFER_BIT );
363359 }
364360
365361 @ Override
@@ -370,7 +366,7 @@ public void present() {
370366
371367 try (MemoryStack stack = MemoryStack .stackPush ()) {
372368 VkPresentInfoKHR presentInfo = VkPresentInfoKHR .calloc (stack ).sType$Default ();
373- presentInfo .pWaitSemaphores (stack .longs (this .device . createCommandEncoder (). submittedPresentSemaphore () ));
369+ presentInfo .pWaitSemaphores (stack .longs (this .presentSemaphores [ this . currentImageIndex ] ));
374370 presentInfo .swapchainCount (1 );
375371 presentInfo .pSwapchains (stack .longs (this .swapchain ));
376372 presentInfo .pImageIndices (stack .ints (this .currentImageIndex ));
@@ -387,4 +383,19 @@ public void present() {
387383 }
388384 }
389385 }
386+
387+ private void createSemaphores ( long [] semaphores ) {
388+ try (MemoryStack stack = MemoryStack .stackPush ()) {
389+ VkSemaphoreCreateInfo createInfo = VkSemaphoreCreateInfo .calloc (stack ).sType$Default ();
390+ LongBuffer ptr = stack .callocLong (1 );
391+ for (int i = 0 ; i < semaphores .length ; i ++) {
392+ Vk11Utils .crashIfFailure (VK10 .vkCreateSemaphore (device .vkDevice (), createInfo , null , ptr ), "Failed to create semaphore" );
393+ semaphores [i ] = ptr .get (0 );
394+ }
395+ }
396+ }
397+
398+ private void destroySemaphores (long [] semaphores ) {
399+ for (long s : semaphores ) VK10 .vkDestroySemaphore (device .vkDevice (), s , null );
400+ }
390401}
0 commit comments