Move sampler creation from image to resource manager and cache created samplers

This commit is contained in:
Georg Hagen
2024-07-09 12:31:52 +02:00
parent d48d60441a
commit d9a22236b4
5 changed files with 49 additions and 38 deletions

View File

@@ -8,19 +8,22 @@
namespace OpenVulkano::Vulkan
{
void Image::Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, const vk::MemoryPropertyFlags& memoryPropertyFlags)
void Image::Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, bool allocateMem, const vk::MemoryPropertyFlags& memoryPropertyFlags)
{
this->device = device->device;
image = device->device.createImage(imageCreateInfo);
format = imageCreateInfo.format;
extent = imageCreateInfo.extent;
if (allocateMem)
{
// TODO allocate from resource manager
const vk::MemoryRequirements memRequirements = device->device.getImageMemoryRequirements(image);
size = allocSize = memRequirements.size;
const vk::MemoryAllocateInfo memAllocInfo = { allocSize, device->GetMemoryType(memRequirements.memoryTypeBits, memoryPropertyFlags) };
memory = device->device.allocateMemory(memAllocInfo);
device->device.bindImageMemory(image, memory, 0);
}
imageViewCreateInfo.image = image;
view = device->device.createImageView(imageViewCreateInfo);
@@ -49,32 +52,10 @@ namespace OpenVulkano::Vulkan
imgViewCreateInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
Init(device, imgCreateInfo, imgViewCreateInfo);
CreateSampler();
}
void Image::CreateSampler()
{
vk::SamplerCreateInfo samplerCreateInfo;
samplerCreateInfo.magFilter = vk::Filter::eLinear;
samplerCreateInfo.minFilter = vk::Filter::eLinear;
samplerCreateInfo.mipmapMode = vk::SamplerMipmapMode::eLinear;
samplerCreateInfo.addressModeU = vk::SamplerAddressMode::eClampToEdge;
samplerCreateInfo.addressModeV = vk::SamplerAddressMode::eClampToEdge;
samplerCreateInfo.addressModeW = vk::SamplerAddressMode::eClampToEdge;
samplerCreateInfo.borderColor = vk::BorderColor::eFloatTransparentBlack;
samplerCreateInfo.unnormalizedCoordinates = false;
samplerCreateInfo.compareEnable = false;
sampler = this->device.createSampler(samplerCreateInfo);
}
void Image::Close()
{
if(sampler)
{
device.destroySampler(sampler);
sampler = vk::Sampler();
}
if(view)
{
device.destroyImageView(view);

View File

@@ -27,7 +27,6 @@ namespace OpenVulkano::Vulkan
vk::Image image;
vk::Extent3D extent;
vk::ImageView view;
vk::Sampler sampler;
vk::Format format = vk::Format::eUndefined;
/**
@@ -37,7 +36,7 @@ namespace OpenVulkano::Vulkan
* \param imageViewCreateInfo The image will be set automatically after it's creation
* \param memoryPropertyFlags
*/
void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, bool allocateMem = true, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
void Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution);
@@ -48,8 +47,6 @@ namespace OpenVulkano::Vulkan
SetLayout(cmdBuffer, vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1), newLayout, oldLayout);
}
void CreateSampler();
void Close() override;
operator bool() const { return image.operator bool(); }

View File

@@ -95,6 +95,11 @@ namespace OpenVulkano::Vulkan
toFree.clear();
recycleBuffers.clear();
descriptorSetLayoutCache.clear();
for (auto& sampler : samplerCache)
{
device.destroy(sampler.second);
}
samplerCache.clear();
shaders.clear();
cmdBuffers = nullptr;
cmdPools = nullptr;
@@ -427,4 +432,11 @@ namespace OpenVulkano::Vulkan
vkBuffer->Init(buffer, uBuffer);
return vkBuffer;
}
vk::Sampler ResourceManager::CreateSampler(const vk::SamplerCreateInfo& samplerConfig)
{
auto& sampler = samplerCache[samplerConfig];
if (!sampler) sampler = device.createSampler(samplerConfig);
return sampler;
}
}

View File

@@ -6,6 +6,9 @@
#pragma once
// Workaround for libc++
#define __cpp_lib_three_way_comparison 201907
#include "vulkan/vulkan.hpp"
#include "Base/ICloseable.hpp"
#include "IShaderOwner.hpp"
@@ -62,6 +65,7 @@ namespace OpenVulkano
std::function<void(ManagedBuffer*)> freeFunction;
vk::DescriptorPool descriptorPool;
std::map<DescriptorSetLayoutBinding, vk::DescriptorSetLayout> descriptorSetLayoutCache;
std::map<vk::SamplerCreateInfo, vk::Sampler> samplerCache;
int buffers = -1, currentBuffer = -1;
@@ -108,6 +112,8 @@ namespace OpenVulkano
UniformBuffer* CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId = 2);
vk::Sampler CreateSampler(const vk::SamplerCreateInfo& samplerConfig);
protected: // Allocation management
void DoFreeBuffer(ManagedBuffer* buffer);
@@ -127,9 +133,9 @@ namespace OpenVulkano
MemoryAllocation* GetFreeMemoryAllocation(size_t size, vk::DeviceSize alignment, uint32_t type, bool createIfAllFull = true);
public:
vk::DescriptorSetLayout* GetDescriptorLayoutSet(const DescriptorSetLayoutBinding& descriptorSetLayoutBinding);
public:
VulkanShader* CreateShader(Scene::Shader* shader);
};
}

View File

@@ -19,7 +19,9 @@ namespace OpenVulkano::Vulkan
class VulkanTexture : public IRecordable, public Image
{
public:
static inline vk::SamplerCreateInfo DEFAULT_SAMPLER_CONFIG {};
Scene::Texture* m_texture = nullptr;
vk::Sampler m_sampler;
vk::DescriptorSet m_descriptorSet;
virtual void Init(ResourceManager* resManager, Scene::Texture* texture, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding)
@@ -29,16 +31,29 @@ namespace OpenVulkano::Vulkan
resManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
texture->updated = false;
m_sampler = resManager->CreateSampler(DEFAULT_SAMPLER_CONFIG);
SetDescriptorSet(resManager, descriptorSetLayout, binding);
texture->renderTexture = this;
}
void Close() override
{
Image::Close();
if (m_texture) m_texture->renderTexture = nullptr;
m_texture = nullptr;
}
void SetDescriptorSet(ResourceManager* resManager, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding)
{
// Setup Descriptor set
const vk::DescriptorSetAllocateInfo descSetAllocInfo = { ResourceManager::INSTANCE->descriptorPool, 1, descriptorSetLayout };
m_descriptorSet = resManager->GetContext()->device->device.allocateDescriptorSets(descSetAllocInfo)[0];
vk::DescriptorImageInfo imageInfo = { sampler, view, vk::ImageLayout::eShaderReadOnlyOptimal };
vk::DescriptorImageInfo imageInfo = { m_sampler, view, vk::ImageLayout::eShaderReadOnlyOptimal };
vk::WriteDescriptorSet writeDescriptorSet = { m_descriptorSet, binding.bindingId, 0, 1 };
writeDescriptorSet.descriptorType = static_cast<vk::DescriptorType>(binding.descriptorType);
writeDescriptorSet.pImageInfo = &imageInfo;
resManager->GetContext()->device->device.updateDescriptorSets(1, &writeDescriptorSet, 0, nullptr);
texture->renderTexture = this;
}
void Record(VulkanDrawContext* context) override