Program Listing for File descriptorSetLayoutWrapper.cpp
↰ Return to documentation for file (PrismEngine/src/descriptorSetLayoutWrapper.cpp)
#include "descriptorSetLayoutWrapper.h"
void prism::PGC::L3::DescriptorSetLayoutWrapper::createDescriptorSetLayout(utils::Context* context, utils::Settings* settings)
{
std::vector<VkDescriptorSetLayoutBinding> bindings;
for (int i = 0; i < settings->descriptorSetLayout.bindings.size(); i++) {
utils::BindingConfig targetBinding = settings->descriptorSetLayout.bindings[i];
bindings.push_back(createDescriptorSetLayoutBinding(targetBinding));
}
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
layoutInfo.pBindings = bindings.data();
if (vkCreateDescriptorSetLayout(context->device, &layoutInfo, nullptr, &context->descriptorSetLayout) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor set layout!");
}
}
VkDescriptorSetLayoutBinding prism::PGC::L3::DescriptorSetLayoutWrapper::createDescriptorSetLayoutBinding(utils::BindingConfig targetBinding) {
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = targetBinding.binding;
uboLayoutBinding.descriptorCount = targetBinding.descriptorCount;
uboLayoutBinding.descriptorType = targetBinding.descriptorType;
uboLayoutBinding.pImmutableSamplers = targetBinding.immutableSamplers;
uboLayoutBinding.stageFlags = targetBinding.stageFlags;
return uboLayoutBinding;
}
void prism::PGC::L3::DescriptorSetLayoutWrapper::createDescriptorSet(utils::Context* context) {
std::vector<VkDescriptorSetLayout> layouts(context->MAX_FRAMES_IN_FLIGHT, context->descriptorSetLayout);
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = context->descriptorPool;
allocInfo.descriptorSetCount = static_cast<uint32_t>(context->MAX_FRAMES_IN_FLIGHT);
allocInfo.pSetLayouts = layouts.data();
context->descriptorSets.resize(context->MAX_FRAMES_IN_FLIGHT);
if (vkAllocateDescriptorSets(context->device, &allocInfo, context->descriptorSets.data()) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate descriptor sets!");
}
for (size_t i = 0; i < context->MAX_FRAMES_IN_FLIGHT; i++) {
// CameraUBO (статический)
VkDescriptorBufferInfo cameraBufferInfo{};
cameraBufferInfo.buffer = context->uniformBuffers[i].camera;
cameraBufferInfo.offset = 0;
cameraBufferInfo.range = sizeof(CameraUBO);
// ObjectSSBO
VkDescriptorBufferInfo objectsBufferInfo{};
objectsBufferInfo.buffer = context->storageBuffers[i].object;
objectsBufferInfo.offset = 0;
objectsBufferInfo.range = VK_WHOLE_SIZE;
VkDescriptorBufferInfo pointLightsBufferInfo{};
pointLightsBufferInfo.buffer = context->storageBuffers[i].pointLights;
pointLightsBufferInfo.offset = 0;
pointLightsBufferInfo.range = VK_WHOLE_SIZE;
VkDescriptorBufferInfo dirLightsBufferInfo{};
dirLightsBufferInfo.buffer = context->storageBuffers[i].directionalLights;
dirLightsBufferInfo.offset = 0;
dirLightsBufferInfo.range = VK_WHOLE_SIZE;
std::array<VkWriteDescriptorSet, 4> descriptorWrites{};
// Camera UBO (binding 0) - статический
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = context->descriptorSets[i];
descriptorWrites[0].dstBinding = 0;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrites[0].descriptorCount = 1;
descriptorWrites[0].pBufferInfo = &cameraBufferInfo;
// Object SSBO (binding 1)
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[1].dstSet = context->descriptorSets[i];
descriptorWrites[1].dstBinding = 1;
descriptorWrites[1].dstArrayElement = 0;
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptorWrites[1].descriptorCount = 1;
descriptorWrites[1].pBufferInfo = &objectsBufferInfo;
// PointLights SSBO (binding 2)
descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[2].dstSet = context->descriptorSets[i];
descriptorWrites[2].dstBinding = 2;
descriptorWrites[2].dstArrayElement = 0;
descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptorWrites[2].descriptorCount = 1;
descriptorWrites[2].pBufferInfo = &pointLightsBufferInfo;
// DirectionLights SSBO (binding 3)
descriptorWrites[3].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[3].dstSet = context->descriptorSets[i];
descriptorWrites[3].dstBinding = 3;
descriptorWrites[3].dstArrayElement = 0;
descriptorWrites[3].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptorWrites[3].descriptorCount = 1;
descriptorWrites[3].pBufferInfo = &dirLightsBufferInfo;
vkUpdateDescriptorSets(context->device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
}
}
void prism::PGC::L3::DescriptorSetLayoutWrapper::cleanupDescriptorSetLayout(utils::Context* context)
{
vkDestroyDescriptorSetLayout(context->device, context->descriptorSetLayout, nullptr);
}
void prism::PGC::L3::DescriptorSetLayoutWrapper::createTextureDescriptorSetLayout(utils::Context* context, utils::Settings* settings) {
VkDescriptorSetLayoutBinding binding{};
binding.binding = 0;
binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
binding.descriptorCount = settings->MAX_TEXTURES;
binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorBindingFlagsEXT bindingFlags = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT;
VkDescriptorSetLayoutBindingFlagsCreateInfoEXT flagsInfo{};
flagsInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT;
flagsInfo.bindingCount = 1;
flagsInfo.pBindingFlags = &bindingFlags;
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.pNext = &flagsInfo;
layoutInfo.bindingCount = 1;
layoutInfo.pBindings = &binding;
layoutInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
if (vkCreateDescriptorSetLayout(context->device, &layoutInfo, nullptr, &context->textureDescriptorSetLayout) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture descriptor set layout!");
}
}
void prism::PGC::L3::DescriptorSetLayoutWrapper::createTextureDescriptorSet(utils::Context* context) {
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = context->textureDescriptorPool;
allocInfo.descriptorSetCount = 1;
allocInfo.pSetLayouts = &context->textureDescriptorSetLayout;
if (vkAllocateDescriptorSets(context->device, &allocInfo, &context->textureDescriptorSet) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate texture descriptor set!");
}
}
void prism::PGC::L3::DescriptorSetLayoutWrapper::createDescriptorPool(utils::Context* context, utils::Settings* settings)
{
// Пул для буферов
{
std::array<VkDescriptorPoolSize, 2> poolSizes{};
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSizes[0].descriptorCount = static_cast<uint32_t>(context->MAX_FRAMES_IN_FLIGHT);
poolSizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
poolSizes[1].descriptorCount = static_cast<uint32_t>(context->MAX_FRAMES_IN_FLIGHT * 3);
VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
poolInfo.pPoolSizes = poolSizes.data();
poolInfo.maxSets = static_cast<uint32_t>(context->MAX_FRAMES_IN_FLIGHT);
if (vkCreateDescriptorPool(context->device, &poolInfo, nullptr, &context->descriptorPool) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor pool!");
}
}
// Пул для bindless текстур
{
VkDescriptorPoolSize poolSize{};
poolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
poolSize.descriptorCount = settings->MAX_TEXTURES;
VkDescriptorPoolCreateInfo poolInfo = {};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;
poolInfo.maxSets = 1;
if (vkCreateDescriptorPool(context->device, &poolInfo, nullptr, &context->textureDescriptorPool) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture descriptor pool!");
}
}
}