Description
Version/Branch of Dear ImGui:
Version 1.92.6, Branch: docking
Back-ends:
imgui_impl_Vulkan.cpp + imgui_impl_win32.cpp
Compiler, OS:
Windows 11 + MSVC 2022
Full config/build information:
Dear ImGui 1.92.6 WIP (19259)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _WIN64
define: _MSC_VER=1939
define: _MSVC_LANG=201703
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
IM_ASSERT: runs expression: OK. expand size: OK
--------------------------------
io.BackendPlatformName: imgui_impl_win32
io.BackendRendererName: imgui_impl_vulkan
io.ConfigFlags: 0x00000483
NavEnableKeyboard
NavEnableGamepad
DockingEnable
ViewportsEnable
io.ConfigDpiScaleFonts
io.ConfigDpiScaleViewports
io.ConfigViewportsNoDecoration
io.ConfigViewportsNoDefaultParent
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00003C1E
HasMouseCursors
HasSetMousePos
PlatformHasViewports
HasMouseHoveredViewport
HasParentViewport
RendererHasVtxOffset
RendererHasTextures
RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,128
io.Fonts->FontLoaderName: stb_truetype
io.DisplaySize: 1898.00,1144.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 12.00,12.00
style.WindowBorderSize: 1.00
style.FramePadding: 6.00,4.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 12.00,6.00
style.ItemInnerSpacing: 6.00,6.00
Details:
Using Dynamic Rendering feature with Docking/MultiViewports, starting from the second call to FrameRender() leads to errors:
[vulkan] Debug report from ObjectType: 6 Message: vkCmdDrawIndexed(): subpassCount is incompatible between VkRenderPass 0x70000000007 (from VkCommandBuffer 0x220135cc4b0) and VkRenderPass 0x0 (from VkPipeline 0x1d000000001d), 1 != 0. The Vulkan spec states: The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS (https://docs.vulkan.org/spec/latest/chapters/drawing.html#VUID-vkCmdDrawIndexed-renderPass-02684)
[vulkan] Debug report from ObjectType: 6 Message: vkCmdDrawIndexed(): dependencyCount is incompatible between VkRenderPass 0x70000000007 (from VkCommandBuffer 0x220135cc4b0) and VkRenderPass 0x0 (from VkPipeline 0x1d000000001d), 1 != 0. The Vulkan spec states: The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS (https://docs.vulkan.org/spec/latest/chapters/drawing.html#VUID-vkCmdDrawIndexed-renderPass-02684)
I've traced the error to
// Draw
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
in
// Render function
void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline)
invoked as
ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer);
Screenshots/Video:
No response
Minimal, Complete and Verifiable Example code:
Modify main.cpp of example_win32_vulkan as:
// Main code int main(int, char**)
ImGui_ImplVulkan_InitInfo init_info = {};
//init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version.
init_info.Instance = g_Instance;
init_info.PhysicalDevice = g_PhysicalDevice;
init_info.Device = g_Device;
init_info.QueueFamily = g_QueueFamily;
init_info.Queue = g_Queue;
//init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool;
init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount;
init_info.Allocator = g_Allocator;
//init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
//init_info.PipelineInfoMain.Subpass = 0;
//init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.UseDynamicRendering = true;
VkFormat colorFormat{ VK_FORMAT_B8G8R8A8_UNORM };
VkPipelineRenderingCreateInfo pipelineInfoMain{};
pipelineInfoMain.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
pipelineInfoMain.pNext = nullptr;
pipelineInfoMain.colorAttachmentCount = 1u;
pipelineInfoMain.pColorAttachmentFormats = &colorFormat;
init_info.PipelineInfoMain.PipelineRenderingCreateInfo = pipelineInfoMain;
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineRenderingCreateInfo pipelineInfoViewport{};
pipelineInfoViewport.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
pipelineInfoViewport.pNext = nullptr;
pipelineInfoViewport.colorAttachmentCount = 1u;
pipelineInfoViewport.pColorAttachmentFormats = &colorFormat;
init_info.PipelineInfoForViewports.PipelineRenderingCreateInfo = pipelineInfoViewport;
init_info.PipelineInfoForViewports.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info);
static void SetupVulkan(ImVector<const char*> instance_extensions)
// Create Logical Device (with 1 queue)
{
ImVector<const char*> device_extensions;
device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
device_extensions.push_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
device_extensions.push_back(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME);
device_extensions.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
device_extensions.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
device_extensions.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
// Enumerate physical device extension
uint32_t properties_count;
ImVector<VkExtensionProperties> properties;
vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, nullptr);
properties.resize(properties_count);
vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, properties.Data);
#ifdef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME
if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME))
device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
#endif
const float queue_priority[] = { 1.0f };
VkDeviceQueueCreateInfo queue_info[1] = {};
queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_info[0].queueFamilyIndex = g_QueueFamily;
queue_info[0].queueCount = 1;
queue_info[0].pQueuePriorities = queue_priority;
//Dynamic Rendering
VkPhysicalDeviceDynamicRenderingFeaturesKHR physicalDeviceDynamicRenderingFeaturesKHR{};
physicalDeviceDynamicRenderingFeaturesKHR.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR;
physicalDeviceDynamicRenderingFeaturesKHR.pNext = nullptr;
physicalDeviceDynamicRenderingFeaturesKHR.dynamicRendering = VK_TRUE;
VkDeviceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
create_info.pNext = &physicalDeviceDynamicRenderingFeaturesKHR;
create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]);
create_info.pQueueCreateInfos = queue_info;
create_info.enabledExtensionCount = (uint32_t)device_extensions.Size;
create_info.ppEnabledExtensionNames = device_extensions.Data;
err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device);
check_vk_result(err);
vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);
}