Skip to content

Vulkan dynamic rendering: PipelineRenderingCreateInfo.pColorAttachmentFormats overwritten for secondary viewports #9143

@Nosfeartu

Description

@Nosfeartu

Version/Branch of Dear ImGui:

Version 1.92.6, Branch: docking

Back-ends:

imgui_impl_glfw.cpp + imgui_impl_vulkan.cpp

Compiler, OS:

Windows 10 + MSVC 2022

Full config/build information:

-Vulkan backend
-Dynamic rendering enabled
-Multi-viewport (ImGuiConfigFlags_ViewportsEnable)
-Reproducible with sRGB swapchain formats

Details:

When using Vulkan dynamic rendering with multi-viewport support, the color attachment formats specified via
ImGui_ImplVulkan_InitInfo::PipelineInfoForViewports.PipelineRenderingCreateInfo.pColorAttachmentFormats are overwritten internally, causing subsequent viewports to ignore the user-provided formats.

This is particularly problematic for sRGB swapchain formats, where the correct format must be preserved.

Details

In imgui_impl_vulkan.cpp, inside:

static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)

the pipeline creation logic for secondary viewports contains the following code:

if (bd->PipelineForViewports == VK_NULL_HANDLE)
{
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
    if (wd->UseDynamicRendering)
    {
        pipeline_info->PipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
        pipeline_info->PipelineRenderingCreateInfo.colorAttachmentCount = 1;
        pipeline_info->PipelineRenderingCreateInfo.pColorAttachmentFormats = &wd->SurfaceFormat.format;
    }
    else
    {
        pipeline_info->RenderPass = wd->RenderPass;
    }
#endif
    bd->PipelineForViewports = ImGui_ImplVulkan_CreatePipeline(
        v->Device, v->Allocator, VK_NULL_HANDLE, &v->PipelineInfoForViewports);
}

This overwrites PipelineRenderingCreateInfo.pColorAttachmentFormats with a pointer to
wd->SurfaceFormat.format.

However, the application may already have initialized PipelineInfoForViewports.PipelineRenderingCreateInfo with its own color attachment format array (e.g. sRGB formats).

Earlier in the same function, those formats are explicitly read:

for (uint32_t n = 0; n < pipeline_info->PipelineRenderingCreateInfo.colorAttachmentCount; n++)
    requestSurfaceImageFormats.push_back(
        pipeline_info->PipelineRenderingCreateInfo.pColorAttachmentFormats[n]);

But later, the pointer is replaced, so for subsequent viewport creation:
-the original format list is lost
-only the first viewport’s surface format is used
-user-specified formats are no longer respected

Impact
-Breaks applications that rely on explicit color formats for dynamic rendering
-Especially problematic for sRGB swapchains
-Behavior differs between first and subsequent viewports
-Makes PipelineInfoForViewports.PipelineRenderingCreateInfo effectively unsafe to pre-initialize

Expected Behavior

If the application provides PipelineRenderingCreateInfo in ImGui_ImplVulkan_InitInfo, ImGui should:
-Respect the provided pColorAttachmentFormats, or
-Avoid overwriting the pointer, or
-Make an internal copy instead of modifying user-owned memory

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions