diff --git a/openVulkanoCpp/Vulkan/Image.cpp b/openVulkanoCpp/Vulkan/Image.cpp index 22c024d..21e738f 100644 --- a/openVulkanoCpp/Vulkan/Image.cpp +++ b/openVulkanoCpp/Vulkan/Image.cpp @@ -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; - // 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); + 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); @@ -87,4 +68,4 @@ namespace OpenVulkano::Vulkan } Buffer::Close(); } -} \ No newline at end of file +} diff --git a/openVulkanoCpp/Vulkan/Image.hpp b/openVulkanoCpp/Vulkan/Image.hpp index 0b10a24..ee684bb 100644 --- a/openVulkanoCpp/Vulkan/Image.hpp +++ b/openVulkanoCpp/Vulkan/Image.hpp @@ -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(); } diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index 3e50a4b..326d2aa 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -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; + } } diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp index 8b2852f..0286d57 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp @@ -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 freeFunction; vk::DescriptorPool descriptorPool; std::map descriptorSetLayoutCache; + std::map 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); }; } diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp index 48d4d93..c41c2dc 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp @@ -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(binding.descriptorType); writeDescriptorSet.pImageInfo = &imageInfo; resManager->GetContext()->device->device.updateDescriptorSets(1, &writeDescriptorSet, 0, nullptr); - - texture->renderTexture = this; } void Record(VulkanDrawContext* context) override