From aba74fc701110abb43ed38116fbe94593449270c Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Fri, 28 May 2021 21:45:46 +0200 Subject: [PATCH] [#32] Added sampler handle and sampler manager Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- config/Sources.cmake | 3 + include/vkcv/Core.hpp | 18 +++- include/vkcv/Handles.hpp | 1 + include/vkcv/Sampler.hpp | 22 +++++ projects/first_triangle/src/main.cpp | 7 ++ src/vkcv/BufferManager.cpp | 2 + src/vkcv/Core.cpp | 7 ++ src/vkcv/SamplerManager.cpp | 127 +++++++++++++++++++++++++++ src/vkcv/SamplerManager.hpp | 42 +++++++++ 9 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 include/vkcv/Sampler.hpp create mode 100644 src/vkcv/SamplerManager.cpp create mode 100644 src/vkcv/SamplerManager.hpp diff --git a/config/Sources.cmake b/config/Sources.cmake index cb73f57c..9d1743fa 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -61,4 +61,7 @@ set(vkcv_sources ${vkcv_include}/vkcv/DescriptorConfig.hpp ${vkcv_source}/vkcv/DescriptorConfig.cpp + + ${vkcv_source}/vkcv/SamplerManager.hpp + ${vkcv_source}/vkcv/SamplerManager.cpp ) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index e2fc5c58..ffee796d 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -18,6 +18,7 @@ #include "SyncResources.hpp" #include "Result.hpp" #include "vkcv/DescriptorConfig.hpp" +#include "Sampler.hpp" namespace vkcv { @@ -26,6 +27,7 @@ namespace vkcv class PipelineManager; class DescriptorManager; class BufferManager; + class SamplerManager; struct SubmitInfo { QueueType queueType; @@ -63,6 +65,7 @@ namespace vkcv std::unique_ptr<PipelineManager> m_PipelineManager; std::unique_ptr<DescriptorManager> m_DescriptorManager; std::unique_ptr<BufferManager> m_BufferManager; + std::unique_ptr<SamplerManager> m_SamplerManager; CommandResources m_CommandResources; SyncResources m_SyncResources; @@ -160,7 +163,7 @@ namespace vkcv PassHandle createPass(const PassConfig &config); /** - * Creates a #Buffer with data-type T and @p bufferType + * Creates a #Buffer with data-type T and @p bufferType * @param type Type of Buffer created * @param count Count of elements of type T * @param memoryType Type of Buffers memory @@ -170,6 +173,19 @@ namespace vkcv Buffer<T> createBuffer(vkcv::BufferType type, size_t count, BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL) { return Buffer<T>::create(m_BufferManager.get(), type, count, memoryType); } + + /** + * Creates a Sampler with given attributes. + * + * @param magFilter Magnifying filter + * @param minFilter Minimizing filter + * @param mipmapMode Mipmapping filter + * @param addressMode Address mode + * @return Sampler handle + */ + [[nodiscard]] + SamplerHandle createSampler(SamplerFilterType magFilter, SamplerFilterType minFilter, + SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode); /** TODO: * @param setDescriptions diff --git a/include/vkcv/Handles.hpp b/include/vkcv/Handles.hpp index ad48a1ec..40cfa8e4 100644 --- a/include/vkcv/Handles.hpp +++ b/include/vkcv/Handles.hpp @@ -14,4 +14,5 @@ namespace vkcv struct PassHandle {uint64_t id;}; struct PipelineHandle {uint64_t id;}; struct ResourcesHandle {uint64_t id;}; + struct SamplerHandle {uint64_t id;}; } diff --git a/include/vkcv/Sampler.hpp b/include/vkcv/Sampler.hpp new file mode 100644 index 00000000..007ed5ae --- /dev/null +++ b/include/vkcv/Sampler.hpp @@ -0,0 +1,22 @@ +#pragma once + +namespace vkcv { + + enum class SamplerFilterType { + NEAREST = 1, + LINEAR = 2 + }; + + enum class SamplerMipmapMode { + NEAREST = 1, + LINEAR = 2 + }; + + enum class SamplerAddressMode { + REPEAT = 1, + MIRRORED_REPEAT = 2, + CLAMP_TO_EDGE = 3, + MIRROR_CLAMP_TO_EDGE = 4 + }; + +} diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 07da9506..620fe065 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -53,6 +53,13 @@ int main(int argc, const char** argv) { m[1] = { 0, 0, 0 }; m[2] = { 0, 0, 0 }; buffer.unmap();*/ + + vkcv::SamplerHandle sampler = core.createSampler( + vkcv::SamplerFilterType::NEAREST, + vkcv::SamplerFilterType::NEAREST, + vkcv::SamplerMipmapMode::NEAREST, + vkcv::SamplerAddressMode::REPEAT + ); std::cout << "Physical device: " << physicalDevice.getProperties().deviceName << std::endl; diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp index cb2425a5..a91a0a14 100644 --- a/src/vkcv/BufferManager.cpp +++ b/src/vkcv/BufferManager.cpp @@ -280,10 +280,12 @@ namespace vkcv { if (buffer.m_memory) { device.freeMemory(buffer.m_memory); + buffer.m_memory = nullptr; } if (buffer.m_handle) { device.destroyBuffer(buffer.m_handle); + buffer.m_handle = nullptr; } } diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index fa53b4fa..b328b0cf 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -10,6 +10,7 @@ #include "PassManager.hpp" #include "PipelineManager.hpp" #include "vkcv/BufferManager.hpp" +#include "SamplerManager.hpp" #include "DescriptorManager.hpp" #include "Surface.hpp" #include "ImageLayoutTransitions.hpp" @@ -95,6 +96,7 @@ namespace vkcv m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, m_DescriptorManager(std::make_unique<DescriptorManager>(m_Context.m_Device)), m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager())}, + m_SamplerManager(std::unique_ptr<SamplerManager>(new SamplerManager(m_Context.m_Device))), m_CommandResources(commandResources), m_SyncResources(syncResources) { @@ -253,6 +255,11 @@ namespace vkcv finish(); } } + + SamplerHandle Core::createSampler(SamplerFilterType magFilter, SamplerFilterType minFilter, + SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode) { + return m_SamplerManager->createSampler(magFilter, minFilter, mipmapMode, addressMode); + } ResourcesHandle Core::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets) { diff --git a/src/vkcv/SamplerManager.cpp b/src/vkcv/SamplerManager.cpp new file mode 100644 index 00000000..9ff5481b --- /dev/null +++ b/src/vkcv/SamplerManager.cpp @@ -0,0 +1,127 @@ + +#include "SamplerManager.hpp" +#include "vkcv/Core.hpp" + +namespace vkcv { + + SamplerManager::SamplerManager(const vk::Device& device) noexcept : + m_device(device), m_samplers() + {} + + SamplerManager::~SamplerManager() { + for (uint64_t id = 0; id < m_samplers.size(); id++) { + destroySampler(SamplerHandle{id}); + } + } + + SamplerHandle SamplerManager::createSampler(SamplerFilterType magFilter, + SamplerFilterType minFilter, + SamplerMipmapMode mipmapMode, + SamplerAddressMode addressMode) { + vk::Filter vkMagFilter; + vk::Filter vkMinFilter; + vk::SamplerMipmapMode vkMipmapMode; + vk::SamplerAddressMode vkAddressMode; + + switch (magFilter) { + case SamplerFilterType::NEAREST: + vkMagFilter = vk::Filter::eNearest; + break; + case SamplerFilterType::LINEAR: + vkMagFilter = vk::Filter::eLinear; + break; + default: + return SamplerHandle(); + } + + switch (minFilter) { + case SamplerFilterType::NEAREST: + vkMinFilter = vk::Filter::eNearest; + break; + case SamplerFilterType::LINEAR: + vkMinFilter = vk::Filter::eLinear; + break; + default: + return SamplerHandle(); + } + + switch (mipmapMode) { + case SamplerMipmapMode::NEAREST: + vkMipmapMode = vk::SamplerMipmapMode::eNearest; + break; + case SamplerMipmapMode::LINEAR: + vkMipmapMode = vk::SamplerMipmapMode::eLinear; + break; + default: + return SamplerHandle(); + } + + switch (addressMode) { + case SamplerAddressMode::REPEAT: + vkAddressMode = vk::SamplerAddressMode::eRepeat; + break; + case SamplerAddressMode::MIRRORED_REPEAT: + vkAddressMode = vk::SamplerAddressMode::eMirroredRepeat; + break; + case SamplerAddressMode::CLAMP_TO_EDGE: + vkAddressMode = vk::SamplerAddressMode::eClampToEdge; + break; + case SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: + vkAddressMode = vk::SamplerAddressMode::eMirrorClampToEdge; + break; + default: + return SamplerHandle(); + } + + const vk::SamplerCreateInfo samplerCreateInfo ( + vk::SamplerCreateFlags(), + vkMagFilter, + vkMinFilter, + vkMipmapMode, + vkAddressMode, + vkAddressMode, + vkAddressMode, + 0.0f, + false, + 16.0f, + false, + vk::CompareOp::eAlways, + 0.0f, + 1.0f, + vk::BorderColor::eIntOpaqueBlack, + false + ); + + const vk::Sampler sampler = m_device.createSampler(samplerCreateInfo); + + const uint64_t id = m_samplers.size(); + m_samplers.push_back(sampler); + return SamplerHandle{id}; + } + + vk::Sampler SamplerManager::getVulkanSampler(const SamplerHandle &handle) const { + const uint64_t id = handle.id; + + if (id >= m_samplers.size()) { + return nullptr; + } + + return m_samplers[id]; + } + + void SamplerManager::destroySampler(const SamplerHandle &handle) { + const uint64_t id = handle.id; + + if (id >= m_samplers.size()) { + return; + } + + auto& sampler = m_samplers[id]; + + if (sampler) { + m_device.destroySampler(sampler); + sampler = nullptr; + } + } + +} diff --git a/src/vkcv/SamplerManager.hpp b/src/vkcv/SamplerManager.hpp new file mode 100644 index 00000000..41f58b2f --- /dev/null +++ b/src/vkcv/SamplerManager.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include <vector> +#include <vulkan/vulkan.hpp> + +#include "vkcv/Handles.hpp" +#include "vkcv/Sampler.hpp" + +namespace vkcv { + + class Core; + + class SamplerManager { + friend class Core; + private: + vk::Device m_device; + std::vector<vk::Sampler> m_samplers; + + explicit SamplerManager(const vk::Device& device) noexcept; + + public: + ~SamplerManager(); + + SamplerManager(const SamplerManager& other) = delete; + SamplerManager(SamplerManager&& other) = delete; + + SamplerManager& operator=(const SamplerManager& other) = delete; + SamplerManager& operator=(SamplerManager&& other) = delete; + + SamplerHandle createSampler(SamplerFilterType magFilter, + SamplerFilterType minFilter, + SamplerMipmapMode mipmapMode, + SamplerAddressMode addressMode); + + [[nodiscard]] + vk::Sampler getVulkanSampler(const SamplerHandle& handle) const; + + void destroySampler(const SamplerHandle& handle); + + }; + +} -- GitLab