I’m creating a GUI for a Vulkan application using ImGui and loading 13 textures there for buttons, background, etc. Here is the code to create the descriptor pool:
vk::DescriptorPoolSize poolSize;
poolSize.type = vk::DescriptorType::eCombinedImageSampler;
poolSize.descriptorCount = 1;
vk::DescriptorPoolCreateInfo poolInfo;
poolInfo.flags = vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet;
poolInfo.maxSets = 13;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;
Normally I have descriptorCount equal to the number of textures, and maxSets = 1 so I create 13 descriptors and 1 descriptor set, but ImGui refuses to work in this case. ImGui works only if maxSets is equal to the number of textures and descriptorCount = 1. ImGui creates for EVERY texture a separate descriptorSet with 1 texture(descriptor) for each texture?
When dealing with descriptors, you need to start with the shader. If your pool has a maximum of 1 set and 13 descriptors, that means that it could only allocate a single set with 13 individual image descriptors within it.
Does your shader declare a set with up to 13 image descriptors in it? Because if not, then there’s a mismatch of expectations.
I don’t know whether it is your shader or ImGUI’s shader, but the two of you seem to be confused as to what the shader is actually doing.
In any case, there are only two ways I could imagine a shader with 1 set and 13 descriptors for images could work. One way is for the shader to declare 1 set and one descriptor, with each texture being assigned a different descriptor index and the shader being written to use a specific index. That is, the shader would have to know which image it is being used with.
The alternative is to use an array of images, alongside dynamic indexing of that array. The latter is probably the best way to go about it, but this requires that the shader is given an index for the particular texture it wants to use.
Maybe ImGUI wants to work that way, but maybe it doesn’t. It seems to me though if ImGUI requires that external code hands it a descriptor pool to allocate from, that there would be some documentation on ImGUI’s expectations on how to construct that pool.
Thank you for your response. However, ImGui only works with different Descriptorsets for each texture. And I want to know if ImGui really uses different Descriptorsets for each texture or if the code contains a error?
Didn’t you just answer your own question? If ImGUI says that it “only works with different Descriptorsets for each texture”, then that’s what it works with.
1 Like
ImGui is api agnostic. How it works with Vulkan is totally up to you. It could be as little as one texture atlas and as many as your application requires.
1 Like
Thank you for your reply. I think I have found what the problem is. Here is the code from imgui.cpp that I use to create the texture:
VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout)
{
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
// Create Descriptor Set:
VkDescriptorSet descriptor_set;
{
VkDescriptorSetAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.descriptorPool = v->DescriptorPool;
alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &bd->DescriptorSetLayout;
VkResult err = vkAllocateDescriptorSets(v->Device, &alloc_info, &descriptor_set);
check_vk_result(err);
}
...
//some code
...
return descriptor_set;
}
As I understand it, this function allocates one separate DescriptorSet for one texture. That’s why Imgui didn’t work when maxSets = 1, because it created several DescriptorSets (for each texture). Please correct me if I’ve got it wrong. Thank you all for your help.
Yes, that code allocates one descriptor set per texture. But tbh. ImGui’s default Vulkan implementation is IMO very sub optimal and nothing people should blindly copy. You can do much better by integrating Vulkan directly into your application instead of using the implementation provided by ImGui itself.
1 Like
Thanks. Do I understand correctly that VulkanUIOverlay.cpp in your VulkanExamples is an example of how to independently integrate ImGui into a Vulkan application?
Yes, it’s an example of how to integrate ImGui in a different and probably more optimal way. But in the end you should tailor it to your use case.
1 Like