@@ -100,7 +100,8 @@ bool VulkanRenderer::initialize()
100100 if (!m_vulkanResources.createBackgroundVertexBuffer (m_vulkanDevice))
101101 return false ;
102102
103- if (!m_vulkanResources.createSyncObjects (m_vulkanDevice.getDevice ()))
103+ if (!m_vulkanResources.createSyncObjects (m_vulkanDevice.getDevice (),
104+ static_cast <uint32_t >(m_vulkanSwapchain.getImages ().size ())))
104105 return false ;
105106
106107 if (!createCommandBuffers ())
@@ -325,6 +326,13 @@ void VulkanRenderer::resize(uint32_t width, uint32_t height)
325326 m_imagesInFlight.clear ();
326327 m_imagesInFlight.resize (m_vulkanSwapchain.getImages ().size (), VK_NULL_HANDLE);
327328
329+ if (!m_vulkanResources.recreateRenderFinishedSemaphores (m_vulkanDevice.getDevice (),
330+ static_cast <uint32_t >(m_vulkanSwapchain.getImages ().size ())))
331+ {
332+ Logger::error (" VK: Failed to recreate render-finished semaphores after resize" );
333+ return ;
334+ }
335+
328336 if (!createCommandBuffers ())
329337 {
330338 Logger::error (" VK: Failed to recreate command buffers" );
@@ -431,6 +439,44 @@ void VulkanRenderer::prepareVertexData()
431439 Logger::debug (" VK: Vertex buffer created (host-visible) for animation updates" );
432440}
433441
442+ void VulkanRenderer::writeDescriptorSets ()
443+ {
444+ if (m_descriptorSet == VK_NULL_HANDLE || m_uniformBuffer == VK_NULL_HANDLE || m_textureView == VK_NULL_HANDLE)
445+ return ;
446+
447+ VkDevice device = m_vulkanDevice.getDevice ();
448+ const VkDeviceSize uboSize = 320 ;
449+
450+ VkDescriptorBufferInfo bufferDescInfo{};
451+ bufferDescInfo.buffer = m_uniformBuffer;
452+ bufferDescInfo.offset = 0 ;
453+ bufferDescInfo.range = uboSize;
454+
455+ VkDescriptorImageInfo imageDescInfo{};
456+ imageDescInfo.sampler = m_textureSampler;
457+ imageDescInfo.imageView = m_textureView;
458+ imageDescInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
459+
460+ VkWriteDescriptorSet descriptorWrites[2 ]{};
461+ descriptorWrites[0 ].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
462+ descriptorWrites[0 ].dstSet = m_descriptorSet;
463+ descriptorWrites[0 ].dstBinding = 0 ;
464+ descriptorWrites[0 ].dstArrayElement = 0 ;
465+ descriptorWrites[0 ].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
466+ descriptorWrites[0 ].descriptorCount = 1 ;
467+ descriptorWrites[0 ].pBufferInfo = &bufferDescInfo;
468+
469+ descriptorWrites[1 ].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
470+ descriptorWrites[1 ].dstSet = m_descriptorSet;
471+ descriptorWrites[1 ].dstBinding = 1 ;
472+ descriptorWrites[1 ].dstArrayElement = 0 ;
473+ descriptorWrites[1 ].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
474+ descriptorWrites[1 ].descriptorCount = 1 ;
475+ descriptorWrites[1 ].pImageInfo = &imageDescInfo;
476+
477+ vkUpdateDescriptorSets (device, 2 , descriptorWrites, 0 , nullptr );
478+ }
479+
434480void VulkanRenderer::updateUniformBuffer ()
435481{
436482 VkDevice device = m_vulkanDevice.getDevice ();
@@ -603,38 +649,7 @@ void VulkanRenderer::updateUniformBuffer()
603649 descriptorWrites[1 ].descriptorCount = 1 ;
604650 descriptorWrites[1 ].pImageInfo = &imageDescInfo;
605651
606- vkUpdateDescriptorSets (device, 2 , descriptorWrites, 0 , nullptr );
607- }
608- else if (m_descriptorSet != VK_NULL_HANDLE && m_textureView != VK_NULL_HANDLE)
609- {
610- VkDescriptorBufferInfo bufferDescInfo{};
611- bufferDescInfo.buffer = m_uniformBuffer;
612- bufferDescInfo.offset = 0 ;
613- bufferDescInfo.range = uboSize;
614-
615- VkDescriptorImageInfo imageDescInfo{};
616- imageDescInfo.sampler = m_textureSampler;
617- imageDescInfo.imageView = m_textureView;
618- imageDescInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
619-
620- VkWriteDescriptorSet descriptorWrites[2 ]{};
621- descriptorWrites[0 ].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
622- descriptorWrites[0 ].dstSet = m_descriptorSet;
623- descriptorWrites[0 ].dstBinding = 0 ;
624- descriptorWrites[0 ].dstArrayElement = 0 ;
625- descriptorWrites[0 ].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
626- descriptorWrites[0 ].descriptorCount = 1 ;
627- descriptorWrites[0 ].pBufferInfo = &bufferDescInfo;
628-
629- descriptorWrites[1 ].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
630- descriptorWrites[1 ].dstSet = m_descriptorSet;
631- descriptorWrites[1 ].dstBinding = 1 ;
632- descriptorWrites[1 ].dstArrayElement = 0 ;
633- descriptorWrites[1 ].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
634- descriptorWrites[1 ].descriptorCount = 1 ;
635- descriptorWrites[1 ].pImageInfo = &imageDescInfo;
636-
637- vkUpdateDescriptorSets (device, 2 , descriptorWrites, 0 , nullptr );
652+ writeDescriptorSets ();
638653 }
639654
640655 void * data;
@@ -773,6 +788,7 @@ bool VulkanRenderer::uploadTexture()
773788 }
774789 Logger::debug (" VK: Texture image view created, calling updateUniformBuffer" );
775790
791+ writeDescriptorSets ();
776792 updateUniformBuffer ();
777793
778794 vkDestroyBuffer (device, stagingBuffer, nullptr );
@@ -874,7 +890,10 @@ bool VulkanRenderer::createCommandBuffers()
874890 renderPassInfo.clearValueCount = static_cast <uint32_t >(clearValues.size ());
875891 renderPassInfo.pClearValues = clearValues.data ();
876892
877- vkCmdBeginRenderPass (m_commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
893+ VkSubpassBeginInfo subpassBegin{};
894+ subpassBegin.sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO;
895+ subpassBegin.contents = VK_SUBPASS_CONTENTS_INLINE;
896+ vkCmdBeginRenderPass2 (m_commandBuffers[i], &renderPassInfo, &subpassBegin);
878897
879898 VkBuffer bgBuffer = m_vulkanResources.getBackgroundVertexBuffer ();
880899 if (m_background.shouldRender && m_vulkanPipeline.getBackgroundPipeline () != VK_NULL_HANDLE && bgBuffer != VK_NULL_HANDLE)
@@ -919,7 +938,9 @@ bool VulkanRenderer::createCommandBuffers()
919938 vkCmdDraw (m_commandBuffers[i], m_vertexCount, 1 , 0 , 0 );
920939 }
921940
922- vkCmdEndRenderPass (m_commandBuffers[i]);
941+ VkSubpassEndInfo subpassEnd{};
942+ subpassEnd.sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO;
943+ vkCmdEndRenderPass2 (m_commandBuffers[i], &subpassEnd);
923944
924945 if (vkEndCommandBuffer (m_commandBuffers[i]) != VK_SUCCESS)
925946 {
@@ -948,7 +969,6 @@ void VulkanRenderer::submitFrame()
948969
949970 VkFence fence = m_vulkanResources.getInFlightFence (m_currentFrame);
950971 VkSemaphore imageAvailable = m_vulkanResources.getImageAvailableSemaphore (m_currentFrame);
951- VkSemaphore renderFinished = m_vulkanResources.getRenderFinishedSemaphore (m_currentFrame);
952972 vkWaitForFences (device, 1 , &fence, VK_TRUE, UINT64_MAX);
953973
954974 uint32_t imageIndex;
@@ -966,6 +986,8 @@ void VulkanRenderer::submitFrame()
966986 return ;
967987 }
968988
989+ VkSemaphore renderFinished = m_vulkanResources.getRenderFinishedSemaphore (imageIndex);
990+
969991 if (m_imagesInFlight[imageIndex] != VK_NULL_HANDLE)
970992 {
971993 vkWaitForFences (device, 1 , &m_imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
@@ -1023,13 +1045,31 @@ void VulkanRenderer::submitFrame()
10231045
10241046void VulkanRenderer::setVSync (bool enabled)
10251047{
1026- if (m_vulkanDevice.getDevice () != VK_NULL_HANDLE)
1027- {
1028- m_vulkanSwapchain.setVSync (m_vulkanDevice, enabled);
1048+ if (m_vulkanDevice.getDevice () == VK_NULL_HANDLE || !m_initialized)
1049+ return ;
10291050
1030- if (m_config)
1051+ VkDevice device = m_vulkanDevice.getDevice ();
1052+ if (m_vulkanSwapchain.setVSync (m_vulkanDevice, enabled))
1053+ {
1054+ vkDeviceWaitIdle (device);
1055+ m_imagesInFlight.clear ();
1056+ m_imagesInFlight.resize (m_vulkanSwapchain.getImages ().size (), VK_NULL_HANDLE);
1057+ if (!m_vulkanResources.recreateRenderFinishedSemaphores (device,
1058+ static_cast <uint32_t >(m_vulkanSwapchain.getImages ().size ())))
10311059 {
1032- m_config-> setVSync (enabled );
1060+ Logger::error ( " VK: Failed to recreate render-finished semaphores after VSync change " );
10331061 }
1062+ if (!m_commandBuffers.empty ())
1063+ {
1064+ vkFreeCommandBuffers (device, m_vulkanResources.getCommandPool (),
1065+ static_cast <uint32_t >(m_commandBuffers.size ()), m_commandBuffers.data ());
1066+ m_commandBuffers.clear ();
1067+ }
1068+ if (!createCommandBuffers ())
1069+ Logger::error (" VK: Failed to recreate command buffers after VSync change" );
1070+ m_iconChanged = true ;
10341071 }
1072+
1073+ if (m_config)
1074+ m_config->setVSync (enabled);
10351075}
0 commit comments