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

459 lines
17 KiB
C++
Raw Normal View History

2023-11-15 17:42:57 +01:00
#include "Descriptor.h"
#include "Buffer.h"
2024-06-09 12:20:04 +02:00
#include "CRC.h"
2023-12-02 10:55:00 +01:00
#include "Command.h"
2024-04-13 23:51:38 +02:00
#include "Graphics.h"
2024-07-10 21:07:10 +02:00
#include "RayTracing.h"
2024-08-13 22:44:04 +02:00
#include "Texture.h"
2020-03-09 12:30:07 +01:00
using namespace Seele;
using namespace Seele::Vulkan;
2021-05-06 17:02:10 +02:00
DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name)
2024-04-13 23:51:38 +02:00
: Gfx::DescriptorLayout(name), graphics(graphics), layoutHandle(VK_NULL_HANDLE) {}
DescriptorLayout::~DescriptorLayout() {
2024-05-15 15:27:13 +02:00
graphics->getDestructionManager()->queueResourceForDestruction(std::move(pool));
2024-05-29 10:40:35 +02:00
if (layoutHandle != VK_NULL_HANDLE) {
vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr);
}
2020-03-09 12:30:07 +01:00
}
2024-04-13 23:51:38 +02:00
void DescriptorLayout::create() {
2024-05-29 10:40:35 +02:00
if (layoutHandle != VK_NULL_HANDLE) {
return;
}
bindings.resize(descriptorBindings.size());
Array<VkDescriptorBindingFlags> bindingFlags(descriptorBindings.size());
for (size_t i = 0; i < descriptorBindings.size(); ++i) {
const Gfx::DescriptorBinding& gfxBinding = descriptorBindings[i];
bindings[i] = {
.binding = gfxBinding.binding,
.descriptorType = cast(gfxBinding.descriptorType),
.descriptorCount = gfxBinding.descriptorCount,
.stageFlags = gfxBinding.shaderStages,
.pImmutableSamplers = nullptr,
};
bindingFlags[i] = gfxBinding.bindingFlags;
}
VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.pNext = nullptr,
.bindingCount = static_cast<uint32>(bindingFlags.size()),
.pBindingFlags = bindingFlags.data(),
2023-11-10 22:26:47 +01:00
};
2024-05-29 10:40:35 +02:00
VkDescriptorSetLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = &bindingFlagsInfo,
2024-06-19 10:44:11 +02:00
.flags = 0,
2024-05-29 10:40:35 +02:00
.bindingCount = (uint32)bindings.size(),
.pBindings = bindings.data(),
};
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
2020-03-09 12:30:07 +01:00
2024-05-29 10:40:35 +02:00
pool = new DescriptorPool(graphics, this);
2020-10-03 11:00:10 +02:00
2024-05-29 10:40:35 +02:00
hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32());
2020-03-09 12:30:07 +01:00
}
2024-05-29 10:40:35 +02:00
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
2024-08-07 21:19:33 +02:00
: CommandBoundResource(graphics, layout->getName()), graphics(graphics), layout(layout) {
2024-05-29 10:40:35 +02:00
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
cachedHandles[i] = nullptr;
2021-12-27 15:04:53 +01:00
}
2024-05-29 10:40:35 +02:00
2024-07-10 21:07:10 +02:00
Map<Gfx::SeDescriptorType, uint32> perTypeSizes;
2024-05-29 10:40:35 +02:00
for (uint32 i = 0; i < layout->getBindings().size(); ++i) {
auto& binding = layout->getBindings()[i];
2024-07-10 21:07:10 +02:00
perTypeSizes[binding.descriptorType] += 512;
2024-05-29 10:40:35 +02:00
}
Array<VkDescriptorPoolSize> poolSizes;
2024-07-10 21:07:10 +02:00
for (const auto [type, num] : perTypeSizes) {
VkDescriptorPoolSize size;
size.descriptorCount = num;
size.type = cast(type);
poolSizes.add(size);
2024-05-29 10:40:35 +02:00
}
VkDescriptorPoolCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr,
2024-06-19 10:44:11 +02:00
.flags = 0,
2024-05-29 10:40:35 +02:00
.maxSets = maxSets * Gfx::numFramesBuffered,
.poolSizeCount = (uint32)poolSizes.size(),
.pPoolSizes = poolSizes.data(),
};
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
2020-03-13 12:44:33 +01:00
}
2024-04-13 23:51:38 +02:00
DescriptorPool::~DescriptorPool() {
2024-06-09 12:20:04 +02:00
for (size_t i = 0; i < maxSets; ++i) {
if (cachedHandles[i] != nullptr) {
2024-10-14 18:14:08 +02:00
graphics->getDestructionManager()->queueResourceForDestruction(std::move(cachedHandles[i]));
2024-05-15 15:27:13 +02:00
}
}
vkDestroyDescriptorPool(graphics->getDevice(), poolHandle, nullptr);
if (nextAlloc) {
delete nextAlloc;
}
2020-06-02 11:46:18 +02:00
}
2024-04-13 23:51:38 +02:00
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
2024-05-29 10:40:35 +02:00
VkDescriptorSetLayout layoutHandle = layout->getHandle();
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorSetCount = 1,
};
VkDescriptorSetAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorPool = poolHandle,
.descriptorSetCount = 1,
.pSetLayouts = &layoutHandle,
};
uint32 counts = 0;
for (const auto& binding : layout->bindings) {
if (binding.descriptorCount > 0) {
counts = binding.descriptorCount;
}
2021-12-27 15:04:53 +01:00
}
2024-05-29 10:40:35 +02:00
if (layout->bindings.size() > 0) {
setCounts.pDescriptorCounts = &counts;
allocInfo.pNext = &setCounts;
2024-04-13 23:51:38 +02:00
}
2024-05-29 10:40:35 +02:00
for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) {
if (cachedHandles[setIndex] == nullptr) {
cachedHandles[setIndex] = new DescriptorSet(graphics, this);
}
2024-07-18 11:45:56 +02:00
if (cachedHandles[setIndex]->isCurrentlyBound()) {
2024-05-29 10:40:35 +02:00
// Currently in use, skip
continue;
}
if (cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) {
// If it hasnt been initialized, allocate it
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
}
2020-03-13 12:44:33 +01:00
2024-05-29 10:40:35 +02:00
PDescriptorSet vulkanSet = cachedHandles[setIndex];
2020-10-03 11:00:10 +02:00
2024-05-29 10:40:35 +02:00
// Found set, stop searching
return vulkanSet;
}
if (nextAlloc == nullptr) {
nextAlloc = new DescriptorPool(graphics, layout);
}
// std::cout << "Out of descriptors, forwarding" << std::endl;
return nextAlloc->allocateDescriptorSet();
// throw std::logic_error("Out of descriptor sets");
2020-03-13 12:44:33 +01:00
}
2024-04-13 23:51:38 +02:00
void DescriptorPool::reset() {
2024-05-29 10:40:35 +02:00
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
if (cachedHandles[i] == nullptr) {
return;
}
}
if (nextAlloc != nullptr) {
nextAlloc->reset();
2021-12-27 15:04:53 +01:00
}
2020-03-13 12:44:33 +01:00
}
2024-04-13 23:51:38 +02:00
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
2024-08-13 22:44:04 +02:00
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics, owner->getLayout()->getName()), setHandle(VK_NULL_HANDLE),
graphics(graphics), owner(owner) {
boundResources.resize(owner->getLayout()->getBindings().size());
2024-08-13 22:44:04 +02:00
for (uint32 i = 0; i < boundResources.size(); ++i) {
2024-09-27 15:57:37 +02:00
boundResources[i].resize(owner->getLayout()->getBindings()[i].descriptorCount);
2024-06-20 21:57:26 +02:00
}
}
2024-04-23 08:11:44 +02:00
DescriptorSet::~DescriptorSet() {}
2024-04-13 23:51:38 +02:00
2024-09-27 15:57:37 +02:00
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PUniformBuffer uniformBuffer) {
2024-05-29 10:40:35 +02:00
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
2025-01-12 11:26:52 +01:00
if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) {
2024-05-29 10:40:35 +02:00
return;
}
2024-04-13 23:51:38 +02:00
2024-05-29 10:40:35 +02:00
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
2024-06-09 12:20:04 +02:00
});
2024-04-13 23:51:38 +02:00
2024-05-29 10:40:35 +02:00
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
2024-09-27 15:57:37 +02:00
.dstArrayElement = index,
2024-05-29 10:40:35 +02:00
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
.pBufferInfo = &bufferInfos.back(),
2024-06-09 12:20:04 +02:00
});
2024-05-29 10:40:35 +02:00
2024-09-27 15:57:37 +02:00
boundResources[binding][index] = vulkanBuffer->getAlloc();
2024-04-13 23:51:38 +02:00
}
2024-09-27 15:57:37 +02:00
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
2024-05-29 10:40:35 +02:00
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
2025-01-12 11:26:52 +01:00
if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) {
2024-05-29 10:40:35 +02:00
return;
}
2024-04-13 23:51:38 +02:00
2024-05-29 10:40:35 +02:00
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
2024-06-09 12:20:04 +02:00
});
2024-05-29 10:40:35 +02:00
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
2024-09-27 15:57:37 +02:00
.dstArrayElement = index,
2024-05-29 10:40:35 +02:00
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
2024-10-07 20:14:00 +02:00
.pBufferInfo = &bufferInfos.back(),
});
boundResources[binding][index] = vulkanBuffer->getAlloc();
}
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PVertexBuffer indexBuffer) {
PVertexBuffer vulkanBuffer = indexBuffer.cast<VertexBuffer>();
2025-01-12 11:26:52 +01:00
if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) {
2024-10-07 20:14:00 +02:00
return;
}
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = index,
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
2024-05-29 10:40:35 +02:00
.pBufferInfo = &bufferInfos.back(),
2024-06-09 12:20:04 +02:00
});
2024-04-13 23:51:38 +02:00
2024-09-27 15:57:37 +02:00
boundResources[binding][index] = vulkanBuffer->getAlloc();
2024-04-13 23:51:38 +02:00
}
2024-09-27 15:57:37 +02:00
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PIndexBuffer indexBuffer) {
2024-07-10 21:07:10 +02:00
PIndexBuffer vulkanBuffer = indexBuffer.cast<IndexBuffer>();
2025-01-12 11:26:52 +01:00
if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) {
2024-07-10 21:07:10 +02:00
return;
}
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
2024-09-27 15:57:37 +02:00
.dstArrayElement = index,
2024-07-10 21:07:10 +02:00
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
.pBufferInfo = &bufferInfos.back(),
});
2024-09-27 15:57:37 +02:00
boundResources[binding][index] = vulkanBuffer->getAlloc();
2024-05-06 18:36:16 +02:00
}
2024-09-27 15:57:37 +02:00
void DescriptorSet::updateSampler(uint32_t binding, uint32 index, Gfx::PSampler samplerState) {
2024-05-29 10:40:35 +02:00
PSampler vulkanSampler = samplerState.cast<Sampler>();
2024-09-27 15:57:37 +02:00
if (boundResources[binding][index] == vulkanSampler->getHandle()) {
2024-05-29 10:40:35 +02:00
return;
2022-04-15 11:19:30 +02:00
}
2024-05-29 10:40:35 +02:00
imageInfos.add(VkDescriptorImageInfo{
.sampler = vulkanSampler->getSampler(),
.imageView = VK_NULL_HANDLE,
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
2024-06-09 12:20:04 +02:00
});
2024-05-29 10:40:35 +02:00
2023-11-15 17:42:57 +01:00
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
2024-09-27 15:57:37 +02:00
.dstArrayElement = index,
2024-05-29 10:40:35 +02:00
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.pImageInfo = &imageInfos.back(),
2024-06-09 12:20:04 +02:00
});
2024-05-29 10:40:35 +02:00
2024-09-27 15:57:37 +02:00
boundResources[binding][index] = vulkanSampler->getHandle();
2024-06-18 19:19:05 +02:00
}
2024-09-27 15:57:37 +02:00
void DescriptorSet::updateTexture(uint32_t binding, uint32 index, Gfx::PTexture2D texture) {
2024-05-29 10:40:35 +02:00
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
2024-09-27 15:57:37 +02:00
if (boundResources[binding][index] == vulkanTexture->getHandle()) {
2024-05-29 10:40:35 +02:00
return;
}
// It is assumed that the image is in the correct layout
imageInfos.add(VkDescriptorImageInfo{
2024-09-27 15:57:37 +02:00
.sampler = VK_NULL_HANDLE,
2024-05-29 10:40:35 +02:00
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
2024-06-09 12:20:04 +02:00
});
2024-05-29 10:40:35 +02:00
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
2024-09-27 15:57:37 +02:00
.dstArrayElement = index,
2023-11-15 17:42:57 +01:00
.descriptorCount = 1,
2024-08-13 22:44:04 +02:00
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
2023-11-15 17:42:57 +01:00
.pImageInfo = &imageInfos.back(),
2024-06-09 12:20:04 +02:00
});
2024-05-29 10:40:35 +02:00
2024-09-27 15:57:37 +02:00
boundResources[binding][index] = vulkanTexture->getHandle();
2024-06-18 19:19:05 +02:00
}
2024-09-27 15:57:37 +02:00
void DescriptorSet::updateTexture(uint32_t binding, uint32 index, Gfx::PTexture3D texture) {
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
if (boundResources[binding][index] == vulkanTexture->getHandle()) {
return;
2024-05-29 10:40:35 +02:00
}
2024-09-27 15:57:37 +02:00
// It is assumed that the image is in the correct layout
imageInfos.add(VkDescriptorImageInfo{
.sampler = VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = index,
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
.pImageInfo = &imageInfos.back(),
});
boundResources[binding][index] = vulkanTexture->getHandle();
2022-04-15 11:19:30 +02:00
}
2020-03-13 12:44:33 +01:00
2024-09-27 15:57:37 +02:00
void DescriptorSet::updateTexture(uint32_t binding, uint32 index, Gfx::PTextureCube texture) {
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
if (boundResources[binding][index] == vulkanTexture->getHandle()) {
return;
2024-06-20 21:57:26 +02:00
}
2024-09-27 15:57:37 +02:00
// It is assumed that the image is in the correct layout
imageInfos.add(VkDescriptorImageInfo{
.sampler = VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = index,
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
.pImageInfo = &imageInfos.back(),
});
boundResources[binding][index] = vulkanTexture->getHandle();
2024-06-20 21:57:26 +02:00
}
2024-09-27 15:57:37 +02:00
void DescriptorSet::updateAccelerationStructure(uint32 binding, uint32 index, Gfx::PTopLevelAS as) {
2024-07-10 21:07:10 +02:00
auto tlas = as.cast<TopLevelAS>();
accelerationInfos.add(VkWriteDescriptorSetAccelerationStructureKHR{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
.pNext = nullptr,
.accelerationStructureCount = 1,
2024-07-12 13:33:52 +02:00
.pAccelerationStructures = &tlas->handle,
2024-07-10 21:07:10 +02:00
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = &accelerationInfos.back(),
.dstSet = setHandle,
.dstBinding = binding,
2024-09-27 15:57:37 +02:00
.dstArrayElement = index,
2024-07-10 21:07:10 +02:00
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
});
}
2024-06-20 21:57:26 +02:00
2024-04-13 23:51:38 +02:00
void DescriptorSet::writeChanges() {
2024-05-29 10:40:35 +02:00
if (writeDescriptors.size() > 0) {
if (isCurrentlyBound()) {
std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl;
assert(!isCurrentlyBound());
}
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
writeDescriptors.clear();
imageInfos.clear();
bufferInfos.clear();
2024-04-13 23:51:38 +02:00
}
2020-03-13 12:44:33 +01:00
}
2024-04-23 08:11:44 +02:00
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout)
: Gfx::PipelineLayout(name, baseLayout), graphics(graphics), layoutHandle(VK_NULL_HANDLE) {}
2021-04-13 23:09:16 +02:00
2024-04-13 23:51:38 +02:00
PipelineLayout::~PipelineLayout() {}
2020-03-13 12:44:33 +01:00
std::mutex layoutLock;
2024-04-13 23:51:38 +02:00
Map<uint32, VkPipelineLayout> cachedLayouts;
2020-10-03 11:00:10 +02:00
2024-04-13 23:51:38 +02:00
void PipelineLayout::create() {
2024-05-29 10:40:35 +02:00
for (auto [name, desc] : descriptorSetLayouts) {
PDescriptorLayout layout = desc.cast<DescriptorLayout>();
layout->create();
uint32 parameterIndex = parameterMapping[layout->getName()];
2024-06-09 12:20:04 +02:00
if (parameterIndex >= vulkanDescriptorLayouts.size()) {
2024-05-29 10:40:35 +02:00
vulkanDescriptorLayouts.resize(parameterIndex + 1);
}
vulkanDescriptorLayouts[parameterIndex] = layout->getHandle();
2024-04-23 23:21:30 +02:00
}
2020-03-13 12:44:33 +01:00
2024-05-29 10:40:35 +02:00
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;
vkPushConstants[i].stageFlags = pushConstants[i].stageFlags;
}
2020-03-13 12:44:33 +01:00
2024-05-29 10:40:35 +02:00
VkPipelineLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.setLayoutCount = (uint32)vulkanDescriptorLayouts.size(),
.pSetLayouts = vulkanDescriptorLayouts.data(),
.pushConstantRangeCount = (uint32)vkPushConstants.size(),
.pPushConstantRanges = vkPushConstants.data(),
};
2020-10-03 11:00:10 +02:00
2024-06-09 12:20:04 +02:00
layoutHash =
CRC::Calculate(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
layoutHash =
CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, CRC::CRC_32(), layoutHash);
2024-04-13 23:51:38 +02:00
2024-05-29 10:40:35 +02:00
std::unique_lock l(layoutLock);
if (cachedLayouts.contains(layoutHash)) {
// std::cout << "New Layout" << std::endl;
layoutHandle = cachedLayouts[layoutHash];
return;
}
2024-04-13 23:51:38 +02:00
2024-05-29 10:40:35 +02:00
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
cachedLayouts[layoutHash] = layoutHandle;
2020-10-03 11:00:10 +02:00
}