ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
60.65k stars 10.24k forks source link

ImGui::RenderPlatformWindowsDefault Sample Error with Vulkan backend #4182

Open rohfel opened 3 years ago

rohfel commented 3 years ago

Version: 1.83 Branch: docking

Back-ends: imgui_impl_glfw.cpp + imgui_impl_vulkan.cpp Compiler: LLVM/Clang Operating System: Windows 10 20H2

Hello! So, I recently want to integrating docking to my application. I take a look at docking branch and the example for GLFW and Vulkan. I follow that example and build it successfully. When I run it, Vulkan give me this validation layer error when i called ImGui::RenderPlatformWindowsDefault:

ValidationLayer

This is my ImGui implementation:

static VkDescriptorPool s_ImguiDescriptorPool;

VulkanImGuiManager::VulkanImGuiManager()
{
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGui::StyleColorsDark();

    SetDarkTheme();

    ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
    ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
    ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

    ImGui::GetIO().DisplaySize             = ImVec2(VulkanStorage::GetInstance()->SwapChainExtent.width,
                                            VulkanStorage::GetInstance()->SwapChainExtent.height);
    ImGui::GetIO().DisplayFramebufferScale = ImVec2(1.0f, 1.0f);

    // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
    if(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
    {
        ImGui::GetStyle().WindowRounding = 0.0F;
        ImGui::GetStyle().Colors[ImGuiCol_WindowBg].w = 1.0F;
    }

    ImGui_ImplGlfw_InitForVulkan(static_cast<GLFWwindow*>(WindowProperty::GetInstance().Window), true);

    // This is descriptor pool for ImGui.
    VkDescriptorPoolSize poolSize = {};
    poolSize.type                 = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
    poolSize.descriptorCount      = 1;

    VkDescriptorPoolCreateInfo descriptorPoolInformation = {};
    descriptorPoolInformation.sType                      = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
    descriptorPoolInformation.poolSizeCount              = 1;
    descriptorPoolInformation.pPoolSizes                 = &poolSize;
    descriptorPoolInformation.maxSets                    = 1;

    PUYU_ASSERT(vkCreateDescriptorPool(VulkanStorage::GetInstance()->Device, &descriptorPoolInformation, nullptr,
                                           &s_ImguiDescriptorPool) == VK_SUCCESS,
                    "Failed to create a ImGui descriptor pool!")

    ImGui_ImplVulkan_InitInfo initializationVulkanInformation = {};
    initializationVulkanInformation.Instance                  = VulkanStorage::GetInstance()->Instance;
    initializationVulkanInformation.PhysicalDevice            = VulkanStorage::GetInstance()->PhysicalDevice;
    initializationVulkanInformation.Device                    = VulkanStorage::GetInstance()->Device;
    initializationVulkanInformation.QueueFamily = QueueFamilyIndices::FindQueueFamilies(VulkanStorage::GetInstance()->PhysicalDevice).GraphicsFamily.value();
    initializationVulkanInformation.Queue           = VulkanStorage::GetInstance()->GraphicsQueue;
    initializationVulkanInformation.DescriptorPool  = s_ImguiDescriptorPool;
    initializationVulkanInformation.MinImageCount   = VulkanStorage::GetInstance()->MinimumImageCount;
    initializationVulkanInformation.ImageCount      = VulkanStorage::GetInstance()->ImageCount;
    initializationVulkanInformation.MSAASamples     = VulkanStorage::GetInstance()->MSAASample;
    initializationVulkanInformation.CheckVkResultFn = [](const VkResult result)
    {
        if(!result) return;

        PUYU_ASSERT(false, "Vulkan ImGui error: %d", result);
    };
    ImGui_ImplVulkan_Init(&initializationVulkanInformation, VulkanStorage::GetInstance()->RenderPass);

    VkCommandBuffer commandBuffer = VulkanRendererUtility::BeginSingleTimeCommand();
    ImGui_ImplVulkan_CreateFontsTexture(commandBuffer);
    VulkanRendererUtility::EndSingleTimeCommand(commandBuffer);
    ImGui_ImplVulkan_DestroyFontUploadObjects();
}

VulkanImGuiManager::~VulkanImGuiManager()
{
    ImGui_ImplVulkan_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

    vkDestroyDescriptorPool(VulkanStorage::GetInstance()->Device, s_ImguiDescriptorPool, nullptr);
}

void VulkanImGuiManager::Begin() const
{
    if(VulkanStorage::GetInstance()->IsFrameBufferResized)
        ImGui_ImplVulkan_SetMinImageCount(VulkanStorage::GetInstance()->MinimumImageCount);

    ImGui_ImplVulkan_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();
}

void VulkanImGuiManager::End() const
{
    ImGui::Render();
}

It seems that I have different MSAA samples. But, can I explicitly tell ImGui to use custom MSAA samples when rendering?

Thanks!

ocornut commented 3 years ago

It seems that I have different MSAA samples. But, can I explicitly tell ImGui to use custom MSAA samples when rendering?

I am not sure how to help you. We're missing quite some context: You are not saying which Vulkan function triggers this, if it happens with main/single viewport or secondary viewport, how you setup the MSAASamples function, how to setup your context.

I suggest you dig into the the mismatching state, first try to find a change/fix in imgui_impl_vulkan.cpp and then if it is work we can design of a change in the ImGui_ImplVulkan_InitInfo structure to make it possible to use the backend with those different settings you have.