[WIP] Continue working on pipeline

This commit is contained in:
Piotr Krygier committed 2025-06-20 13:44:33 +02:00
1 parent f8eb98ddf4
commit daed76f02f
28 files changed
+467 -2156

No files matched your search

+187 -86
View File
@@ -22,18 +22,25 @@
#include "vulkan/vulkan_core.h"
#include "vulkan_errors.h"
RSE_LINKED_LIST_DEFINE(descriptor_set_layout_list_t,
VkDescriptorSetLayoutBinding);
RSE_LINKED_LIST_DEFINE(descriptor_set_layout_list_t, VkDescriptorSetLayoutBinding);
struct descriptor_t
{
uint32_t binding;
VkDescriptorType type;
uint32_t descriptors_count;
uint32_t descriptor_count;
VkShaderStageFlags shader_stages;
VkSampler immutable_sampler;
};
RSE_LINKED_LIST_DEFINE(descriptors_list_t, struct descriptor_t);
RSE_LINKED_LIST_DEFINE(descriptor_set_list_t, struct descriptor_t);
struct descriptor_set_handle_t
{
VkDescriptorSet descriptor_sets;
VkDescriptorPool descriptor_pool;
VkDescriptorSetLayout descriptor_sets_layout;
};
/* FIXME: When new descriptors are introduced to Vulkan, this enum has to be
* updated */
@@ -59,40 +66,37 @@ enum descriptor_type_id_t
DESCRIPTOR_TYPE_ID_MAX_ENUM,
};
struct descriptors_data_t
rse_err_t descriptor_add_set(struct descriptor_set_list_t* descriptor_set_list, uint32_t binding, VkDescriptorType type,
uint32_t descriptor_count, VkShaderStageFlags shader_stages, VkSampler sampler)
{
VkDescriptorPool pool;
VkDescriptorSet set;
struct descriptor_set_layout_list_t layouts_list;
};
struct descriptor_t descriptor_sets = {.binding = binding,
.type = type,
.descriptor_count = descriptor_count,
.shader_stages = shader_stages,
.immutable_sampler = sampler};
rse_err_t descriptor_add(struct descriptors_list_t* descriptors_list,
uint32_t binding, VkDescriptorType type,
uint32_t descriptors_count,
VkShaderStageFlags shader_stages, VkSampler sampler)
{
struct descriptor_t descriptor = {.binding = binding,
.type = type,
.descriptors_count = descriptors_count,
.shader_stages = shader_stages,
.immutable_sampler = sampler};
RSE_LINKED_LIST_PUSH_BACK(descriptors_list, descriptor);
RSE_LINKED_LIST_PUSH_BACK(descriptor_set_list, descriptor_sets);
return RSE_ERROR_NO_ERROR;
}
rse_err_t descriptors_build(struct graphics_context_t* context,
struct descriptors_list_t* descriptors)
rse_err_t descriptors_build(struct graphics_context_t* context, struct descriptor_set_list_t* descriptors,
struct descriptor_set_handle_t* descriptor_set_handle)
{
VkDescriptorPoolCreateInfo pool_create_info = {};
VkDescriptorPoolCreateFlags pool_create_flags = 0U;
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
VkDescriptorPoolSize pool_sizes[DESCRIPTOR_TYPE_ID_MAX_ENUM] = {};
VkDescriptorPoolSize requested_pool_sizes[DESCRIPTOR_TYPE_ID_MAX_ENUM] = {};
uint32_t pool_max_sets = 0;
size_t pool_size_count = 0U;
size_t iterator = 0U;
size_t pool_size_count = 0U;
uint32_t pool_max_sets = 0U;
uint32_t sets_per_type = 0U;
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
VkDescriptorPoolCreateInfo pool_create_info = {0};
VkDescriptorPoolCreateFlags pool_create_flags = 0U; // TODO: Flags not set anywhere
VkDescriptorPoolSize pool_sizes[DESCRIPTOR_TYPE_ID_MAX_ENUM] = {0};
VkDescriptorPoolSize requested_pool_sizes[DESCRIPTOR_TYPE_ID_MAX_ENUM] = {0};
VkDescriptorSetAllocateInfo alloc_info = {0};
VkDescriptorSetLayoutBinding layout_bindings[DESCRIPTOR_TYPE_ID_MAX_ENUM] = {0};
VkDescriptorSetLayoutCreateInfo layout_create_info = {0};
VkDescriptorSetLayout set_layout = VK_NULL_HANDLE;
VkDescriptorSet descriptor_sets = VK_NULL_HANDLE;
if (NULL == context) {
LOGF(_("Provided NULL context\n"));
@@ -100,118 +104,193 @@ rse_err_t descriptors_build(struct graphics_context_t* context,
return RSE_ERROR_NULL_POINTER;
}
iterator = 0U;
RSE_LINKED_LIST_FOREACH(descriptors, descriptor)
{
switch (descriptor->data.type) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
pool_sizes[DESCRIPTOR_TYPE_SAMPLER_ID].type =
VK_DESCRIPTOR_TYPE_SAMPLER;
pool_sizes[DESCRIPTOR_TYPE_SAMPLER_ID].type = VK_DESCRIPTOR_TYPE_SAMPLER;
pool_sizes[DESCRIPTOR_TYPE_SAMPLER_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
pool_sizes[DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_ID].type =
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
pool_sizes[DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_ID].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
pool_sizes[DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
pool_sizes[DESCRIPTOR_TYPE_SAMPLED_IMAGE_ID].type =
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
pool_sizes[DESCRIPTOR_TYPE_SAMPLED_IMAGE_ID].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
pool_sizes[DESCRIPTOR_TYPE_SAMPLED_IMAGE_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
pool_sizes[DESCRIPTOR_TYPE_STORAGE_IMAGE_ID].type =
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_IMAGE_ID].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_IMAGE_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER_ID].type =
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER_ID].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
pool_sizes[DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER_ID].type =
VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER_ID].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_ID].type =
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_ID].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_ID].type =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_ID].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC_ID].type =
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC_ID].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC_ID].type =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC_ID].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
pool_sizes[DESCRIPTOR_TYPE_INPUT_ATTACHMENT_ID].type =
VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
pool_sizes[DESCRIPTOR_TYPE_INPUT_ATTACHMENT_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_INPUT_ATTACHMENT_ID].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
pool_sizes[DESCRIPTOR_TYPE_INPUT_ATTACHMENT_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
pool_sizes[DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_ID].type =
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK;
pool_sizes[DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_ID].type = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK;
pool_sizes[DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
pool_sizes[DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR_ID].type =
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
pool_sizes[DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:
pool_sizes[DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV_ID].type =
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV;
pool_sizes[DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM:
pool_sizes[DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM_ID].type =
VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM;
pool_sizes[DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM:
pool_sizes[DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM_ID].type =
VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM;
pool_sizes[DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM_ID]
.descriptorCount++;
pool_sizes[DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM_ID].type = VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM;
pool_sizes[DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM_ID].descriptorCount++;
break;
case VK_DESCRIPTOR_TYPE_MUTABLE_EXT:
pool_sizes[DESCRIPTOR_TYPE_MUTABLE_EXT_ID].type =
VK_DESCRIPTOR_TYPE_MUTABLE_EXT;
pool_sizes[DESCRIPTOR_TYPE_MUTABLE_EXT_ID].type = VK_DESCRIPTOR_TYPE_MUTABLE_EXT;
pool_sizes[DESCRIPTOR_TYPE_MUTABLE_EXT_ID].descriptorCount++;
break;
default:
LOGF(_("Invalid descriptor type provided\n"));
return VULKAN_ERROR_UNKNOWN_DESCRIPTOR_TYPE;
}
layout_bindings[iterator].binding = descriptor->data.binding;
layout_bindings[iterator].descriptorCount = descriptor->data.descriptor_count;
layout_bindings[iterator].descriptorType = descriptor->data.type;
layout_bindings[iterator].pImmutableSamplers = descriptor->data.immutable_sampler;
layout_bindings[iterator].stageFlags = descriptor->data.shader_stages;
iterator++;
}
layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layout_create_info.bindingCount = iterator;
layout_create_info.pBindings = layout_bindings;
if (VK_SUCCESS != vkCreateDescriptorSetLayout(context->device, &layout_create_info, NULL, &set_layout)) {
LOGF(_("Failed to create descriptor sets layout\n"));
return VULKAN_ERROR_DESCRIPTOR_SET_LAYOUT_CREATION_FAILED;
}
/* Another loop. Seems bit too many? TODO: Optimize this later.
* What I'm doing here is calculating minimum viable number of pool max sets. This is a bit tricky, as
* (unintuitively) we have to select the MINIMUM number of sets, not maximum. This makes sense, but is difficult to
* wrap headr around */
RSE_LINKED_LIST_FOREACH(descriptors, descriptor)
{
switch (descriptor->data.type) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
sets_per_type =
pool_sizes[DESCRIPTOR_TYPE_SAMPLER_ID].descriptorCount / descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
sets_per_type =
pool_sizes[DESCRIPTOR_TYPE_SAMPLED_IMAGE_ID].descriptorCount / descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
sets_per_type =
pool_sizes[DESCRIPTOR_TYPE_STORAGE_IMAGE_ID].descriptorCount / descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
sets_per_type =
pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_ID].descriptorCount / descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
sets_per_type =
pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_ID].descriptorCount / descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
sets_per_type =
pool_sizes[DESCRIPTOR_TYPE_INPUT_ATTACHMENT_ID].descriptorCount / descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM:
sets_per_type = pool_sizes[DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM_ID].descriptorCount /
descriptor->data.descriptor_count;
break;
case VK_DESCRIPTOR_TYPE_MUTABLE_EXT:
sets_per_type =
pool_sizes[DESCRIPTOR_TYPE_MUTABLE_EXT_ID].descriptorCount / descriptor->data.descriptor_count;
break;
default:
LOGF(_("Invalid descriptor type provided\n"));
return VULKAN_ERROR_UNKNOWN_DESCRIPTOR_TYPE;
}
if (pool_max_sets == 0 || pool_max_sets > sets_per_type) {
pool_max_sets = sets_per_type;
}
}
/* Allocate pool based on layout */
/* create array of required descriptors */
for (iterator = 0U; iterator < DESCRIPTOR_TYPE_ID_MAX_ENUM; ++iterator) {
if (pool_sizes[iterator].descriptorCount > 0) {
requested_pool_sizes[pool_size_count].type =
pool_sizes[iterator].type;
requested_pool_sizes[pool_size_count].descriptorCount =
pool_sizes[iterator].descriptorCount;
requested_pool_sizes[pool_size_count].type = pool_sizes[iterator].type;
requested_pool_sizes[pool_size_count].descriptorCount = pool_sizes[iterator].descriptorCount;
pool_size_count++;
}
}
@@ -219,10 +298,32 @@ rse_err_t descriptors_build(struct graphics_context_t* context,
pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_create_info.pNext = NULL;
pool_create_info.flags = pool_create_flags;
pool_create_info.maxSets =
0; // FIXME: Calculate number of sets based on layout
pool_create_info.maxSets = pool_max_sets;
pool_create_info.poolSizeCount = pool_size_count;
pool_create_info.pPoolSizes = requested_pool_sizes;
if (VK_SUCCESS != vkCreateDescriptorPool(context->device, &pool_create_info, NULL, &descriptor_pool)) {
LOGF(_("Failed to create descriptor pool\n"));
return VULKAN_ERROR_DESCRIPTOR_POOL_CREATION_FAILED;
}
/* Allocate descriptors from the pool */
alloc_info.descriptorPool = &descriptor_pool;
alloc_info.descriptorSetCount =
pool_max_sets; /* TODO: Always allocating maximum number of sets? This might get weird */
alloc_info.pSetLayouts = set_layout;
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
if (VK_SUCCESS != vkAllocateDescriptorSets(context->device, &alloc_info, &descriptor_sets)) {
LOGF(_("Failed to create descriptor sets\n"));
return VULKAN_ERROR_DESCRIPTOR_SET_CREATION_FAILED;
}
descriptor_set_handle->descriptor_pool = descriptor_pool;
descriptor_set_handle->descriptor_sets = descriptor_sets;
descriptor_set_handle->descriptor_sets_layout = set_layout;
return RSE_ERROR_NO_ERROR;
}
rse_err_t descriptor_get_layouts()