X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Fsampler_backend.cpp;h=134be91b018ea052601aab04d14adeafae13053e;hp=f4162ed0b2c7eb714f3a8da428b86c96a458802c;hb=a16145549dc87c3b12671f797bd77b14bcc7786b;hpb=bbdf52425b736a59d01dda215458c3a1c9bdb320 diff --git a/source/backends/vulkan/sampler_backend.cpp b/source/backends/vulkan/sampler_backend.cpp index f4162ed0..134be91b 100644 --- a/source/backends/vulkan/sampler_backend.cpp +++ b/source/backends/vulkan/sampler_backend.cpp @@ -1,30 +1,128 @@ +#include "destroyqueue.h" +#include "device.h" #include "sampler.h" #include "sampler_backend.h" +#include "vulkan.h" using namespace std; namespace Msp { namespace GL { -VulkanSampler::VulkanSampler() -{ - throw logic_error("VulkanSampler is unimplemented"); -} +VulkanSampler::VulkanSampler(): + device(Device::get_current()) +{ } VulkanSampler::VulkanSampler(VulkanSampler &&other): - handle(other.handle) + device(other.device), + handle(other.handle), + debug_name(move(other.debug_name)) { other.handle = 0; } VulkanSampler::~VulkanSampler() -{ } +{ + if(handle) + device.get_destroy_queue().destroy(handle); +} void VulkanSampler::update(unsigned) const -{ } +{ + const Sampler &self = *static_cast(this); + const VulkanFunctions &vk = device.get_functions(); -void VulkanSampler::set_debug_name(const string &) -{ } + if(handle) + device.get_destroy_queue().destroy(handle); + + VkSamplerCreateInfo sampler_info = { }; + sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + sampler_info.magFilter = static_cast(get_vulkan_filter(self.mag_filter)); + sampler_info.minFilter = static_cast(get_vulkan_filter(self.min_filter)); + sampler_info.mipmapMode = static_cast(get_vulkan_mipmap_mode(self.min_filter)); + sampler_info.addressModeU = static_cast(get_vulkan_address_mode(self.wrap_s)); + sampler_info.addressModeV = static_cast(get_vulkan_address_mode(self.wrap_t)); + sampler_info.addressModeW = static_cast(get_vulkan_address_mode(self.wrap_r)); + sampler_info.anisotropyEnable = (self.max_anisotropy>1.0f); + sampler_info.maxAnisotropy = self.max_anisotropy; + sampler_info.compareEnable = self.compare; + sampler_info.compareOp = static_cast(get_vulkan_predicate(self.cmp_func)); + sampler_info.maxLod = VK_LOD_CLAMP_NONE; + // TODO Vulkan does not allow arbitrary border colors + + vk.CreateSampler(sampler_info, handle); + +#ifdef DEBUG + if(!debug_name.empty()) + set_vulkan_object_name(); +#endif +} + +void VulkanSampler::set_debug_name(const string &name) +{ +#ifdef DEBUG + debug_name = name; + if(handle) + set_vulkan_object_name(); +#else + (void)name; +#endif +} + +void VulkanSampler::set_vulkan_object_name() const +{ +#ifdef DEBUG + const VulkanFunctions &vk = device.get_functions(); + + VkDebugUtilsObjectNameInfoEXT name_info = { }; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.objectType = VK_OBJECT_TYPE_SAMPLER; + name_info.objectHandle = reinterpret_cast(handle); + name_info.pObjectName = debug_name.c_str(); + vk.SetDebugUtilsObjectName(name_info); +#endif +} + + +unsigned get_vulkan_filter(unsigned filter) +{ + switch(filter) + { + case NEAREST: + case NEAREST_MIPMAP_NEAREST: + case NEAREST_MIPMAP_LINEAR: return VK_FILTER_NEAREST; + case LINEAR: + case LINEAR_MIPMAP_NEAREST: + case LINEAR_MIPMAP_LINEAR: return VK_FILTER_LINEAR; + default: throw invalid_argument("get_vulkan_filter"); + } +} + +unsigned get_vulkan_mipmap_mode(unsigned filter) +{ + switch(filter) + { + case NEAREST: + case LINEAR: return VK_SAMPLER_MIPMAP_MODE_NEAREST; + case NEAREST_MIPMAP_NEAREST: + case NEAREST_MIPMAP_LINEAR: + case LINEAR_MIPMAP_NEAREST: + case LINEAR_MIPMAP_LINEAR: return VK_SAMPLER_MIPMAP_MODE_LINEAR; + default: throw invalid_argument("get_vulkan_mipmap_mode"); + } +} + +unsigned get_vulkan_address_mode(unsigned wrap) +{ + switch(wrap) + { + case REPEAT: return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + case MIRRORED_REPEAT: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + default: throw invalid_argument("get_vulkan_address_mode"); + } +} } // namespace GL } // namespace Msp