@@ -263,6 +263,26 @@ The UI rendering phase begins with its own command buffer recording, configured
263263 // This is the key difference from scene rendering - we load existing content
264264 colorAttachment.loadOp = vk::AttachmentLoadOp::eLoad; // Preserve scene rendering
265265
266+ // Ensure proper ordering/visibility between scene and UI when using multiple command buffers.
267+ // If you submit scene and UI command buffers separately, synchronize them either by:
268+ // - Submitting both on the same queue with a semaphore (scene signals, UI waits with stage = COLOR_ATTACHMENT_OUTPUT), or
269+ // - Recording a pipeline barrier in the UI command buffer before beginRendering() to make scene color writes visible.
270+ // Example barrier inserted in the UI command buffer:
271+ {
272+ vk::ImageMemoryBarrier2 barrier{
273+ .srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
274+ .srcAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
275+ .dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
276+ .dstAccessMask = vk::AccessFlagBits2::eColorAttachmentRead | vk::AccessFlagBits2::eColorAttachmentWrite,
277+ .oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
278+ .newLayout = vk::ImageLayout::eColorAttachmentOptimal,
279+ .image = *swapChainImages[imageIndex],
280+ .subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 }
281+ };
282+ vk::DependencyInfo depInfo{ .imageMemoryBarrierCount = 1, .pImageMemoryBarriers = &barrier };
283+ imguiCommandBuffer.pipelineBarrier2(depInfo);
284+ }
285+
266286 // UI rendering typically doesn't need depth testing
267287 // Remove depth attachment to optimize UI rendering performance
268288 renderingInfo.pDepthAttachment = nullptr;
@@ -372,24 +392,31 @@ public:
372392 }
373393
374394 void createImGuiDescriptorPool() {
395+ // ImGui typically needs a handful of descriptors (font texture + user UI textures).
396+ // Adjust these values to your app's needs (e.g., expected number of UI textures, buffers).
397+ // As a starting point:
375398 vk::DescriptorPoolSize poolSizes[] =
376399 {
377- { vk::DescriptorType::eSampler, 1000 },
378- { vk::DescriptorType::eCombinedImageSampler, 1000 },
379- { vk::DescriptorType::eSampledImage, 1000 },
380- { vk::DescriptorType::eStorageImage, 1000 },
381- { vk::DescriptorType::eUniformTexelBuffer, 1000 },
382- { vk::DescriptorType::eStorageTexelBuffer, 1000 },
383- { vk::DescriptorType::eUniformBuffer, 1000 },
384- { vk::DescriptorType::eStorageBuffer, 1000 },
385- { vk::DescriptorType::eUniformBufferDynamic, 1000 },
386- { vk::DescriptorType::eStorageBufferDynamic, 1000 },
387- { vk::DescriptorType::eInputAttachment, 1000 }
400+ { vk::DescriptorType::eSampler, 8 },
401+ { vk::DescriptorType::eCombinedImageSampler, 128 }, // font + user-provided textures
402+ { vk::DescriptorType::eSampledImage, 128 },
403+ { vk::DescriptorType::eStorageImage, 8 },
404+ { vk::DescriptorType::eUniformTexelBuffer, 8 },
405+ { vk::DescriptorType::eStorageTexelBuffer, 8 },
406+ { vk::DescriptorType::eUniformBuffer, 32 },
407+ { vk::DescriptorType::eStorageBuffer, 32 },
408+ { vk::DescriptorType::eUniformBufferDynamic, 16 },
409+ { vk::DescriptorType::eStorageBufferDynamic, 16 },
410+ { vk::DescriptorType::eInputAttachment, 8 }
388411 };
389412
413+ // A conservative maxSets equals the sum of descriptor counts.
414+ uint32_t maxSets = 0;
415+ for (const auto& ps : poolSizes) maxSets += ps.descriptorCount;
416+
390417 vk::DescriptorPoolCreateInfo poolInfo{
391418 .flags = vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet,
392- .maxSets = 1000 ,
419+ .maxSets = maxSets ,
393420 .poolSizeCount = static_cast<uint32_t>(std::size(poolSizes)),
394421 .pPoolSizes = poolSizes
395422 };
@@ -890,24 +917,28 @@ void ImGuiUtil::SetInputCallback(std::function<void(ImGuiIO&)> callback) {
890917}
891918
892919void ImGuiUtil::createDescriptorPool() {
920+ // Tune these to match your expected number of UI textures and buffers.
893921 vk::DescriptorPoolSize poolSizes[] =
894922 {
895- { vk::DescriptorType::eSampler, 1000 },
896- { vk::DescriptorType::eCombinedImageSampler, 1000 },
897- { vk::DescriptorType::eSampledImage, 1000 },
898- { vk::DescriptorType::eStorageImage, 1000 },
899- { vk::DescriptorType::eUniformTexelBuffer, 1000 },
900- { vk::DescriptorType::eStorageTexelBuffer, 1000 },
901- { vk::DescriptorType::eUniformBuffer, 1000 },
902- { vk::DescriptorType::eStorageBuffer, 1000 },
903- { vk::DescriptorType::eUniformBufferDynamic, 1000 },
904- { vk::DescriptorType::eStorageBufferDynamic, 1000 },
905- { vk::DescriptorType::eInputAttachment, 1000 }
923+ { vk::DescriptorType::eSampler, 8 },
924+ { vk::DescriptorType::eCombinedImageSampler, 128 },
925+ { vk::DescriptorType::eSampledImage, 128 },
926+ { vk::DescriptorType::eStorageImage, 8 },
927+ { vk::DescriptorType::eUniformTexelBuffer, 8 },
928+ { vk::DescriptorType::eStorageTexelBuffer, 8 },
929+ { vk::DescriptorType::eUniformBuffer, 32 },
930+ { vk::DescriptorType::eStorageBuffer, 32 },
931+ { vk::DescriptorType::eUniformBufferDynamic, 16 },
932+ { vk::DescriptorType::eStorageBufferDynamic, 16 },
933+ { vk::DescriptorType::eInputAttachment, 8 }
906934 };
907935
936+ uint32_t maxSets = 0;
937+ for (const auto& ps : poolSizes) maxSets += ps.descriptorCount;
938+
908939 vk::DescriptorPoolCreateInfo poolInfo{
909940 .flags = vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet,
910- .maxSets = 1000 ,
941+ .maxSets = maxSets ,
911942 .poolSizeCount = static_cast<uint32_t>(std::size(poolSizes)),
912943 .pPoolSizes = poolSizes
913944 };
0 commit comments