Cleanup for objects destruction and process termination. This is still work in progress, I don't like the way it's handled right now.
452 lines
20 KiB
C
452 lines
20 KiB
C
/**
|
|
* @file descriptor_builder.c
|
|
* @author Piotr Krygier (everyonecancode@gmail.com)
|
|
* @brief
|
|
* @version 0.1
|
|
* @date 2025-03-14
|
|
*
|
|
* @copyright Copyright (c) 2025
|
|
*
|
|
*/
|
|
|
|
#include "descriptor_builder.h"
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include "src/graphics_context.h"
|
|
#include "src/vulkan_commons.h"
|
|
#include "utilities/commons.h"
|
|
#include "utilities/errors_common.h"
|
|
#include "utilities/linked_list.h"
|
|
#include "utilities/localization.h"
|
|
#include "utilities/logger.h"
|
|
#include "vulkan/vulkan_core.h"
|
|
#include "vulkan_errors.h"
|
|
|
|
RSE_LINKED_LIST_DEFINE(descriptor_set_layout_list_t, VkDescriptorSetLayoutBinding);
|
|
|
|
struct descriptor_t
|
|
{
|
|
uint32_t binding;
|
|
VkDescriptorType type;
|
|
uint32_t descriptor_count;
|
|
VkShaderStageFlags shader_stages;
|
|
VkSampler* immutable_sampler;
|
|
};
|
|
|
|
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;
|
|
struct descriptor_set_list_t* descriptor_set_list;
|
|
};
|
|
|
|
/* FIXME: When new descriptors are introduced to Vulkan, this enum has to be
|
|
* updated */
|
|
enum descriptor_type_id_t
|
|
{
|
|
DESCRIPTOR_TYPE_SAMPLER_ID,
|
|
DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_ID,
|
|
DESCRIPTOR_TYPE_SAMPLED_IMAGE_ID,
|
|
DESCRIPTOR_TYPE_STORAGE_IMAGE_ID,
|
|
DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER_ID,
|
|
DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER_ID,
|
|
DESCRIPTOR_TYPE_UNIFORM_BUFFER_ID,
|
|
DESCRIPTOR_TYPE_STORAGE_BUFFER_ID,
|
|
DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC_ID,
|
|
DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC_ID,
|
|
DESCRIPTOR_TYPE_INPUT_ATTACHMENT_ID,
|
|
DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_ID,
|
|
DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR_ID,
|
|
DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV_ID,
|
|
DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM_ID,
|
|
DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM_ID,
|
|
DESCRIPTOR_TYPE_MUTABLE_EXT_ID,
|
|
DESCRIPTOR_TYPE_ID_MAX_ENUM,
|
|
};
|
|
|
|
rse_err_t descriptor_initialize_handle(struct descriptor_set_handle_t **descriptor_set_handle)
|
|
{
|
|
if (NULL != *descriptor_set_handle) {
|
|
LOGE(_("Desciptor already initialized\n"));
|
|
|
|
return RSE_ERROR_INVALID_PARAM;
|
|
}
|
|
|
|
rse_malloc(*descriptor_set_handle, sizeof(struct descriptor_set_handle_t));
|
|
(*descriptor_set_handle)->descriptor_set_list = NULL;
|
|
|
|
return RSE_ERROR_NO_ERROR;
|
|
}
|
|
|
|
rse_err_t descriptor_free_handle(struct descriptor_set_handle_t **descriptor_set_handle)
|
|
{
|
|
if (NULL == *descriptor_set_handle) {
|
|
LOGE(_("Provided NULL handle\n"));
|
|
|
|
return RSE_ERROR_INVALID_PARAM;
|
|
}
|
|
|
|
RSE_LINKED_LIST_CLEAR((*descriptor_set_handle)->descriptor_set_list);
|
|
rse_free(*descriptor_set_handle);
|
|
|
|
*descriptor_set_handle = NULL;
|
|
|
|
return RSE_ERROR_NO_ERROR;
|
|
}
|
|
|
|
rse_err_t descriptor_add_set(struct descriptor_set_handle_t* descriptor_set_handle, uint32_t binding, VkDescriptorType type,
|
|
uint32_t descriptor_count, VkShaderStageFlags shader_stages, VkSampler* sampler)
|
|
{
|
|
struct descriptor_t descriptor_sets = {.binding = binding,
|
|
.type = type,
|
|
.descriptor_count = descriptor_count,
|
|
.shader_stages = shader_stages,
|
|
.immutable_sampler = sampler};
|
|
|
|
RSE_LINKED_LIST_PUSH_BACK(descriptor_set_handle->descriptor_set_list, descriptor_sets);
|
|
|
|
return RSE_ERROR_NO_ERROR;
|
|
}
|
|
|
|
rse_err_t descriptors_build(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle)
|
|
{
|
|
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"));
|
|
|
|
return RSE_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
if (NULL == descriptor_set_handle) {
|
|
LOGF(_("Descriptor set handle is null.\n"));
|
|
|
|
return RSE_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
if (RSE_LINKED_LIST_IS_EMPTY(descriptor_set_handle->descriptor_set_list)) {
|
|
LOGF(_("Provided empty descriptors list\n"));
|
|
|
|
return RSE_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
iterator = 0U;
|
|
RSE_LINKED_LIST_FOREACH(descriptor_set_handle->descriptor_set_list, 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].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++;
|
|
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].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].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++;
|
|
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++;
|
|
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].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].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++;
|
|
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++;
|
|
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++;
|
|
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++;
|
|
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++;
|
|
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++;
|
|
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++;
|
|
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++;
|
|
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].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(descriptor_set_handle->descriptor_set_list, 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;
|
|
pool_size_count++;
|
|
}
|
|
}
|
|
|
|
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 = 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;
|
|
|
|
context->descriptor_sets = descriptor_set_handle;
|
|
|
|
return RSE_ERROR_NO_ERROR;
|
|
}
|
|
|
|
rse_err_t descriptor_get_layout(struct descriptor_set_handle_t* descriptor_set_handle,
|
|
VkDescriptorSetLayout* descriptor_sets_layout)
|
|
{
|
|
if (NULL == descriptor_set_handle->descriptor_sets_layout) {
|
|
LOGF(_("Requested descriptor set layout is NULL\n"));
|
|
|
|
return RSE_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
*descriptor_sets_layout = descriptor_set_handle->descriptor_sets_layout;
|
|
|
|
return RSE_ERROR_NO_ERROR;
|
|
}
|
|
|
|
rse_err_t descriptor_get_vkhandle(struct descriptor_set_handle_t* descriptor_set_handle, VkDescriptorSet* descriptor_set)
|
|
{
|
|
if (NULL == descriptor_set_handle) {
|
|
LOGF(_("Provided handle is NULL\n"));
|
|
|
|
return RSE_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
*descriptor_set = descriptor_set_handle->descriptor_sets;
|
|
|
|
return RSE_ERROR_NO_ERROR;
|
|
}
|
|
|
|
rse_err_t descriptor_attach_image(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle, uint16_t texture_id, VkSampler sampler, uint32_t binding)
|
|
{
|
|
VkDescriptorImageInfo image_info = {0};
|
|
VkWriteDescriptorSet write_set = {0};
|
|
|
|
image_info.sampler = sampler;
|
|
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
image_info.imageView = context->texture_images[texture_id].image_view;
|
|
|
|
write_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
write_set.pImageInfo = &image_info;
|
|
write_set.dstSet = descriptor_set_handle->descriptor_sets;
|
|
write_set.dstBinding = binding;
|
|
write_set.dstArrayElement = 0U;
|
|
write_set.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; //TODO: Maybe not only samplers?
|
|
write_set.descriptorCount = 1;
|
|
|
|
vkUpdateDescriptorSets(context->device, 1U, &write_set, 0, NULL);
|
|
|
|
return RSE_ERROR_NO_ERROR;
|
|
}
|
|
|
|
rse_err_t descriptor_attach_buffer(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle, struct vulkan_buffer_t* buffer, uint32_t binding, VkDescriptorType type)
|
|
{
|
|
VkDescriptorBufferInfo buffer_info = {0};
|
|
VkWriteDescriptorSet write_set = {0};
|
|
|
|
buffer_info.buffer = buffer->buffer;
|
|
buffer_info.offset = 0U;
|
|
buffer_info.range = buffer->allocated_size;
|
|
|
|
write_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
write_set.pBufferInfo = &buffer_info;
|
|
write_set.dstSet = descriptor_set_handle->descriptor_sets;
|
|
write_set.dstBinding = binding;
|
|
write_set.dstArrayElement = 0U;
|
|
write_set.descriptorType = type;
|
|
write_set.descriptorCount = 1;
|
|
|
|
vkUpdateDescriptorSets(context->device, 1U, &write_set, 0, NULL);
|
|
|
|
return RSE_ERROR_NO_ERROR;
|
|
}
|
|
|
|
void destroy_descriptors(struct graphics_context_t* context)
|
|
{
|
|
vkDestroyDescriptorSetLayout(context->device, context->descriptor_sets->descriptor_sets_layout, NULL);
|
|
vkDestroyDescriptorPool(context->device, context->descriptor_sets->descriptor_pool, NULL);
|
|
}
|