Files
Seele/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp
T

193 lines
6.8 KiB
C++
Raw Normal View History

2020-03-09 12:30:07 +01:00
#include "VulkanGraphicsResources.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanGraphics.h"
#include "VulkanInitializer.h"
using namespace Seele;
using namespace Seele::Vulkan;
DescriptorLayout::~DescriptorLayout()
2020-03-09 12:30:07 +01:00
{
if (layoutHandle != VK_NULL_HANDLE)
{
vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr);
}
}
void DescriptorLayout::create()
2020-03-09 12:30:07 +01:00
{
if (layoutHandle != VK_NULL_HANDLE)
{
return;
}
bindings.resize(descriptorBindings.size());
for (size_t i = 0; i < descriptorBindings.size(); ++i)
{
VkDescriptorSetLayoutBinding& binding = bindings[i];
const Gfx::DescriptorBinding& rhiBinding = descriptorBindings[i];
2020-03-09 12:30:07 +01:00
binding.binding = rhiBinding.binding;
binding.descriptorCount = rhiBinding.descriptorCount;
binding.descriptorType = cast(rhiBinding.descriptorType);
binding.stageFlags = rhiBinding.shaderStages;
binding.pImmutableSamplers = nullptr;
}
VkDescriptorSetLayoutCreateInfo createInfo =
init::DescriptorSetLayoutCreateInfo(bindings.data(), bindings.size());
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
allocator = new DescriptorAllocator(graphics, *this);
2020-03-09 12:30:07 +01:00
}
PipelineLayout::~PipelineLayout()
2020-03-13 12:44:33 +01:00
{
if (layoutHandle != VK_NULL_HANDLE)
{
vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
}
}
void PipelineLayout::create()
2020-03-09 12:30:07 +01:00
{
vulkanDescriptorLayouts.resize(descriptorSetLayouts.size());
for (size_t i = 0; i < descriptorSetLayouts.size(); ++i)
{
PDescriptorLayout layout = descriptorSetLayouts[i].cast<DescriptorLayout>();
2020-03-09 19:22:21 +01:00
layout->create();
vulkanDescriptorLayouts[i] = layout->getHandle();
2020-03-09 12:30:07 +01:00
}
2020-03-09 19:22:21 +01:00
VkPipelineLayoutCreateInfo createInfo =
init::PipelineLayoutCreateInfo(vulkanDescriptorLayouts.data(), vulkanDescriptorLayouts.size());
Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
for (size_t i = 0; i < pushConstants.size(); i++)
{
vkPushConstants[i].offset = pushConstants[i].offset;
vkPushConstants[i].size = pushConstants[i].size;
2020-03-13 12:44:33 +01:00
vkPushConstants[i].stageFlags = cast((VkShaderStageFlagBits)pushConstants[i].stageFlags);
2020-03-09 19:22:21 +01:00
}
createInfo.pushConstantRangeCount = vkPushConstants.size();
createInfo.pPushConstantRanges = vkPushConstants.data();
2020-03-13 12:44:33 +01:00
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
layoutHash = memCrc32(&createInfo, sizeof(VkPipelineLayoutCreateInfo), 0);
}
DescriptorSet::~DescriptorSet()
2020-03-13 12:44:33 +01:00
{
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
2020-03-13 12:44:33 +01:00
{
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
2020-03-13 12:44:33 +01:00
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
// bufferInfos.add(bufferInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor);
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer)
2020-03-13 12:44:33 +01:00
{
PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>();
2020-03-13 12:44:33 +01:00
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
// bufferInfos.add(bufferInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor);
}
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState)
2020-03-13 12:44:33 +01:00
{
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
2020-03-13 12:44:33 +01:00
VkDescriptorImageInfo imageInfo =
init::DescriptorImageInfo(
vulkanSampler->sampler,
VK_NULL_HANDLE,
VK_IMAGE_LAYOUT_BEGIN_RANGE);
imageInfos.add(imageInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back());
writeDescriptors.add(writeDescriptor);
}
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
2020-03-13 12:44:33 +01:00
{
// VulkanTextureBase* vulkanTexture = VulkanTextureBase::cast(texture);
//It is assumed that the image is in the correct layout
// VkDescriptorImageInfo imageInfo =
// init::DescriptorImageInfo(
// VK_NULL_HANDLE,
// vulkanTexture->defaultView.view,
// graphics->getRHIDevice().findLayout(vulkanTexture->surface.image));
if (samplerState != nullptr)
{
// PVulkanSamplerState vulkanSampler = samplerState.cast<VulkanSamplerState>();
// imageInfo.sampler = vulkanSampler->sampler;
}
// imageInfos.add(imageInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, binding, &imageInfos.back());
// if (vulkanTexture->surface.usageFlags & TexCreate_UAV)
{
// writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
writeDescriptors.add(writeDescriptor);
}
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
2020-03-13 12:44:33 +01:00
{
PDescriptorSet otherSet = other.cast<DescriptorSet>();
2020-03-13 12:44:33 +01:00
return setHandle < otherSet->setHandle;
}
void DescriptorSet::writeChanges()
2020-03-13 12:44:33 +01:00
{
if (writeDescriptors.size() > 0)
{
vkUpdateDescriptorSets(graphics->getDevice(), writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
writeDescriptors.clear();
imageInfos.clear();
bufferInfos.clear();
}
}
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout)
2020-03-13 12:44:33 +01:00
: layout(layout)
, graphics(graphics)
{
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_END_RANGE];
std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
for (int i = 0; i < layout.getBindings().size(); ++i)
{
auto& binding = layout.getBindings()[i];
int typeIndex = binding.descriptorType;
perTypeSizes[typeIndex] += 256;
}
Array<VkDescriptorPoolSize> poolSizes;
for (int i = 0; i < VK_DESCRIPTOR_TYPE_END_RANGE; ++i)
{
if (perTypeSizes[i] > 0)
{
VkDescriptorPoolSize size;
size.descriptorCount = perTypeSizes[i];
size.type = (VkDescriptorType)i;
poolSizes.add(size);
}
}
VkDescriptorPoolCreateInfo createInfo = init::DescriptorPoolCreateInfo(poolSizes.size(), poolSizes.data(), maxSets);
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
}
DescriptorAllocator::~DescriptorAllocator()
2020-03-13 12:44:33 +01:00
{
vkDestroyDescriptorPool(graphics->getDevice(), poolHandle, nullptr);
}
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet& descriptorSet)
2020-03-13 12:44:33 +01:00
{
descriptorSet = new DescriptorSet(graphics, this);
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
2020-03-13 12:44:33 +01:00
VkDescriptorSetLayout layoutHandle = layout.getHandle();
VkDescriptorSetAllocateInfo allocInfo =
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &vulkanSet->setHandle));
}