From 26ab32164172285bf911a8248c1183529961a3aa Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sat, 20 Jun 2026 21:00:19 +0100 Subject: [PATCH] Add descriptors --- main.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/main.cpp b/main.cpp index 5f0e01d..e4145e9 100644 --- a/main.cpp +++ b/main.cpp @@ -135,6 +135,9 @@ wapp_intern VkCommandPool command_pool = VK_NULL_HANDLE; wapp_intern VkCommandBufferArray command_buffers; wapp_intern TextureArray textures; wapp_intern VkDescriptorImageInfoArray tex_descriptors; +wapp_intern VkDescriptorSetLayout desc_set_layout_tex = VK_NULL_HANDLE; +wapp_intern VkDescriptorPool desc_pool = VK_NULL_HANDLE; +wapp_intern VkDescriptorSet desc_set_tex = VK_NULL_HANDLE; // }}} int main() { @@ -807,6 +810,92 @@ int main() { ktxTexture_Destroy(texture); // }}} } + + // {{{ Descriptor Indexing + // A descriptor is a handle that describes a shader resource. + // + // Descriptors are added into Descriptor Sets which are allocated from a Descriptor Pool. + // A descriptor set object is an opaque object containing storage for a set of descriptors, + // where the types and number of descriptors is defined by a descriptor set layout. + // + // Each descriptor set has a layout. A descriptor set layout object is defined by an array of + // zero or more descriptor bindings. Each individual descriptor binding is specified by + // a descriptor type, a count (array size) of the number of descriptors in the binding, a set + // of shader stages that can access the binding, and (if using immutable samplers) an array of + // sampler descriptors. + + // {{{ Create Descriptor Set Layout + // Create a single binding with variable number of descriptors + u32 texture_count = (u32)wapp_array_count(textures); + + VkDescriptorBindingFlags desc_variable_flag = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT; + + VkDescriptorSetLayoutBindingFlagsCreateInfo desc_binding_flags = {}; + desc_binding_flags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO; + desc_binding_flags.bindingCount = 1; + desc_binding_flags.pBindingFlags = &desc_variable_flag; + + VkDescriptorSetLayoutBinding desc_layout_binding_tex = {}; + // We combine texture images and samplers, so the binding's type needs to be + // VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER + desc_layout_binding_tex.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + desc_layout_binding_tex.descriptorCount = texture_count; + // We only need to access this from the fragment shader, so we set stageFlags to + // VK_SHADER_STAGE_FRAGMENT_BIT + desc_layout_binding_tex.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + + VkDescriptorSetLayoutCreateInfo desc_set_layout_create_info = {}; + desc_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + desc_set_layout_create_info.pNext = &desc_binding_flags; + desc_set_layout_create_info.bindingCount = 1; + desc_set_layout_create_info.pBindings = &desc_layout_binding_tex; + + check(vkCreateDescriptorSetLayout(device, &desc_set_layout_create_info, NULL, &desc_set_layout_tex)); + // }}} + + // {{{ Create Descriptor Pool To Allocate Descriptors + VkDescriptorPoolSize desc_pool_size = {}; + desc_pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + desc_pool_size.descriptorCount = texture_count; + + VkDescriptorPoolCreateInfo desc_pool_create_info = {}; + desc_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + desc_pool_create_info.maxSets = 1; + desc_pool_create_info.poolSizeCount = 1; + desc_pool_create_info.pPoolSizes = &desc_pool_size; + + check(vkCreateDescriptorPool(device, &desc_pool_create_info, NULL, &desc_pool)); + // }}} + + // {{{ Allocate Descriptor Sets + // Descriptor indexing allocate info + VkDescriptorSetVariableDescriptorCountAllocateInfo var_desc_count_alloc_info = {}; + var_desc_count_alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO; + var_desc_count_alloc_info.descriptorSetCount = 1; + var_desc_count_alloc_info.pDescriptorCounts = &texture_count; + + VkDescriptorSetAllocateInfo tex_desc_set_alloc_info = {}; + tex_desc_set_alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + tex_desc_set_alloc_info.pNext = &var_desc_count_alloc_info; + tex_desc_set_alloc_info.descriptorPool = desc_pool; + tex_desc_set_alloc_info.descriptorSetCount = 1; + tex_desc_set_alloc_info.pSetLayouts = &desc_set_layout_tex; + + check(vkAllocateDescriptorSets(device, &tex_desc_set_alloc_info, &desc_set_tex)); + // }}} + + // {{{ Write Descriptor Set Data + VkWriteDescriptorSet write_desc_set_tex = {}; + write_desc_set_tex.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_desc_set_tex.dstSet = desc_set_tex; + write_desc_set_tex.dstBinding = 0; + write_desc_set_tex.descriptorCount = (u32)wapp_array_count(tex_descriptors); + write_desc_set_tex.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write_desc_set_tex.pImageInfo = tex_descriptors; + + vkUpdateDescriptorSets(device, 1, &write_desc_set_tex, 0, NULL); + // }}} + // }}} // }}} wapp_mem_arena_allocator_temp_end(&arena); @@ -830,6 +919,8 @@ int main() { // }}} // {{{ Cleanup + vkDestroyDescriptorPool(device, desc_pool, NULL); + vkDestroyDescriptorSetLayout(device, desc_set_layout_tex, NULL); for (u32 i = 0; i < wapp_array_count(textures); ++i) { vkDestroySampler(device, textures[i].sampler, NULL); vkDestroyImageView(device, textures[i].view, NULL);