mirror of https://github.com/mosra/magnum.git
Browse Source
Together with SamplerFilter, SamplerMipmap and SamplerWrapping enums convertible from the generic versions, which finally deprecate the last remaining vk*() conversion functions in Enums.h and thus the whole header as well. The EnumsTest executable is also no more, as the rest of it now resides inside SamplerTest.pull/504/head
14 changed files with 1206 additions and 283 deletions
@ -0,0 +1,242 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Sampler.h" |
||||||
|
#include "SamplerCreateInfo.h" |
||||||
|
|
||||||
|
#include <Corrade/Containers/ArrayView.h> |
||||||
|
|
||||||
|
#include "Magnum/Sampler.h" |
||||||
|
#include "Magnum/Math/Vector3.h" |
||||||
|
#include "Magnum/Vk/Assert.h" |
||||||
|
#include "Magnum/Vk/Device.h" |
||||||
|
#include "Magnum/Vk/Result.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Vk { |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
constexpr SamplerFilter FilterMapping[]{ |
||||||
|
SamplerFilter::Nearest, |
||||||
|
SamplerFilter::Linear |
||||||
|
}; |
||||||
|
|
||||||
|
constexpr SamplerMipmap SamplerMipmapMapping[]{ |
||||||
|
SamplerMipmap::Nearest, /* See samplerMipmap() for details */ |
||||||
|
SamplerMipmap::Nearest, |
||||||
|
SamplerMipmap::Linear |
||||||
|
}; |
||||||
|
|
||||||
|
constexpr SamplerWrapping SamplerWrappingMapping[]{ |
||||||
|
SamplerWrapping::Repeat, |
||||||
|
SamplerWrapping::MirroredRepeat, |
||||||
|
SamplerWrapping::ClampToEdge, |
||||||
|
SamplerWrapping::ClampToBorder, |
||||||
|
SamplerWrapping::MirrorClampToEdge |
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
SamplerFilter samplerFilter(const Magnum::SamplerFilter filter) { |
||||||
|
CORRADE_ASSERT(UnsignedInt(filter) < Containers::arraySize(FilterMapping), |
||||||
|
"Vk::samplerFilter(): invalid filter" << filter, {}); |
||||||
|
return FilterMapping[UnsignedInt(filter)]; |
||||||
|
} |
||||||
|
|
||||||
|
SamplerMipmap samplerMipmap(const Magnum::SamplerMipmap mipmap) { |
||||||
|
CORRADE_ASSERT(UnsignedInt(mipmap) < Containers::arraySize(SamplerMipmapMapping), |
||||||
|
"Vk::samplerMipmap(): invalid mode" << mipmap, {}); |
||||||
|
return SamplerMipmapMapping[UnsignedInt(mipmap)]; |
||||||
|
} |
||||||
|
|
||||||
|
SamplerWrapping samplerWrapping(const Magnum::SamplerWrapping wrapping) { |
||||||
|
CORRADE_ASSERT(UnsignedInt(wrapping) < Containers::arraySize(SamplerWrappingMapping), |
||||||
|
"Vk::samplerWrapping(): invalid wrapping" << wrapping, {}); |
||||||
|
return SamplerWrappingMapping[UnsignedInt(wrapping)]; |
||||||
|
} |
||||||
|
|
||||||
|
template<std::size_t dimensions> Math::Vector<dimensions, SamplerWrapping> samplerWrapping(const Math::Vector<dimensions, Magnum::SamplerWrapping>& wrapping) { |
||||||
|
Math::Vector<dimensions, SamplerWrapping> out{NoInit}; |
||||||
|
for(std::size_t i = 0; i != dimensions; ++i) |
||||||
|
out[i] = samplerWrapping(wrapping[i]); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
/* Export needed by MSVC, for others it's enough to have on the declaration in
|
||||||
|
the header */ |
||||||
|
template MAGNUM_VK_EXPORT Math::Vector<1, SamplerWrapping> samplerWrapping(const Math::Vector<1, Magnum::SamplerWrapping>&); |
||||||
|
template MAGNUM_VK_EXPORT Math::Vector<2, SamplerWrapping> samplerWrapping(const Math::Vector<2, Magnum::SamplerWrapping>&); |
||||||
|
template MAGNUM_VK_EXPORT Math::Vector<3, SamplerWrapping> samplerWrapping(const Math::Vector<3, Magnum::SamplerWrapping>&); |
||||||
|
|
||||||
|
Debug& operator<<(Debug& debug, const SamplerFilter value) { |
||||||
|
debug << "Vk::SamplerFilter" << Debug::nospace; |
||||||
|
|
||||||
|
switch(value) { |
||||||
|
/* LCOV_EXCL_START */ |
||||||
|
#define _c(value) case Vk::SamplerFilter::value: return debug << "::" << Debug::nospace << #value; |
||||||
|
_c(Nearest) |
||||||
|
_c(Linear) |
||||||
|
#undef _c |
||||||
|
/* LCOV_EXCL_STOP */ |
||||||
|
} |
||||||
|
|
||||||
|
/* Vulkan docs have the values in decimal, so not converting to hex */ |
||||||
|
return debug << "(" << Debug::nospace << Int(value) << Debug::nospace << ")"; |
||||||
|
} |
||||||
|
|
||||||
|
Debug& operator<<(Debug& debug, const SamplerMipmap value) { |
||||||
|
debug << "Vk::SamplerMipmap" << Debug::nospace; |
||||||
|
|
||||||
|
switch(value) { |
||||||
|
/* LCOV_EXCL_START */ |
||||||
|
#define _c(value) case Vk::SamplerMipmap::value: return debug << "::" << Debug::nospace << #value; |
||||||
|
_c(Nearest) |
||||||
|
_c(Linear) |
||||||
|
#undef _c |
||||||
|
/* LCOV_EXCL_STOP */ |
||||||
|
} |
||||||
|
|
||||||
|
/* Vulkan docs have the values in decimal, so not converting to hex */ |
||||||
|
return debug << "(" << Debug::nospace << Int(value) << Debug::nospace << ")"; |
||||||
|
} |
||||||
|
|
||||||
|
Debug& operator<<(Debug& debug, const SamplerWrapping value) { |
||||||
|
debug << "Vk::SamplerWrapping" << Debug::nospace; |
||||||
|
|
||||||
|
switch(value) { |
||||||
|
/* LCOV_EXCL_START */ |
||||||
|
#define _c(value) case Vk::SamplerWrapping::value: return debug << "::" << Debug::nospace << #value; |
||||||
|
_c(Repeat) |
||||||
|
_c(MirroredRepeat) |
||||||
|
_c(ClampToEdge) |
||||||
|
_c(ClampToBorder) |
||||||
|
_c(MirrorClampToEdge) |
||||||
|
#undef _c |
||||||
|
/* LCOV_EXCL_STOP */ |
||||||
|
} |
||||||
|
|
||||||
|
/* Vulkan docs have the values in decimal, so not converting to hex */ |
||||||
|
return debug << "(" << Debug::nospace << Int(value) << Debug::nospace << ")"; |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo::SamplerCreateInfo(const Flags flags): _info{} { |
||||||
|
_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; |
||||||
|
_info.flags = VkDescriptorSetLayoutCreateFlags(flags); |
||||||
|
_info.minFilter = VkFilter(SamplerFilter::Nearest); |
||||||
|
_info.magFilter = VkFilter(SamplerFilter::Nearest); |
||||||
|
/* These are 0, which makes them the obvious candidates, however it's also
|
||||||
|
helpful in case the texture coordinates are completely off -- with |
||||||
|
ClampToEdge (that I wanted to use at first) it would make debugging much |
||||||
|
harder as the output could be just a single color in worst cases */ |
||||||
|
_info.addressModeU = VkSamplerAddressMode(SamplerWrapping::Repeat); |
||||||
|
_info.addressModeV = VkSamplerAddressMode(SamplerWrapping::Repeat); |
||||||
|
_info.addressModeW = VkSamplerAddressMode(SamplerWrapping::Repeat); |
||||||
|
_info.minLod = -1000.0f; |
||||||
|
_info.maxLod = 1000.0f; |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo::SamplerCreateInfo(NoInitT) noexcept {} |
||||||
|
|
||||||
|
SamplerCreateInfo::SamplerCreateInfo(const VkSamplerCreateInfo& info): |
||||||
|
/* Can't use {} with GCC 4.8 here because it tries to initialize the first
|
||||||
|
member instead of doing a copy */ |
||||||
|
_info(info) {} |
||||||
|
|
||||||
|
SamplerCreateInfo& SamplerCreateInfo::setMinificationFilter(const SamplerFilter filter, const SamplerMipmap mipmap) { |
||||||
|
_info.minFilter = VkFilter(filter); |
||||||
|
_info.mipmapMode = VkSamplerMipmapMode(mipmap); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo& SamplerCreateInfo::setMinificationFilter(const Magnum::SamplerFilter filter, const Magnum::SamplerMipmap mipmap) { |
||||||
|
return setMinificationFilter(samplerFilter(filter), samplerMipmap(mipmap)); |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo& SamplerCreateInfo::setMagnificationFilter(const SamplerFilter filter) { |
||||||
|
_info.magFilter = VkFilter(filter); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo& SamplerCreateInfo::setMagnificationFilter(const Magnum::SamplerFilter filter) { |
||||||
|
return setMagnificationFilter(samplerFilter(filter)); |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo& SamplerCreateInfo::setWrapping(const Math::Vector3<SamplerWrapping>& wrapping) { |
||||||
|
_info.addressModeU = VkSamplerAddressMode(wrapping.x()); |
||||||
|
_info.addressModeV = VkSamplerAddressMode(wrapping.y()); |
||||||
|
_info.addressModeW = VkSamplerAddressMode(wrapping.z()); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo& SamplerCreateInfo::setWrapping(const Math::Vector3<Magnum::SamplerWrapping>& wrapping) { |
||||||
|
return setWrapping(samplerWrapping(wrapping)); |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo& SamplerCreateInfo::setWrapping(const SamplerWrapping wrapping) { |
||||||
|
return setWrapping(Math::Vector3<SamplerWrapping>{wrapping}); |
||||||
|
} |
||||||
|
|
||||||
|
SamplerCreateInfo& SamplerCreateInfo::setWrapping(const Magnum::SamplerWrapping wrapping) { |
||||||
|
return setWrapping(Math::Vector3<Magnum::SamplerWrapping>{wrapping}); |
||||||
|
} |
||||||
|
|
||||||
|
Sampler Sampler::wrap(Device& device, const VkSampler handle, const HandleFlags flags) { |
||||||
|
Sampler out{NoCreate}; |
||||||
|
out._device = &device; |
||||||
|
out._handle = handle; |
||||||
|
out._flags = flags; |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
Sampler::Sampler(Device& device, const SamplerCreateInfo& info): _device{&device}, _flags{HandleFlag::DestroyOnDestruction} { |
||||||
|
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreateSampler(device, info, nullptr, &_handle)); |
||||||
|
} |
||||||
|
|
||||||
|
Sampler::Sampler(NoCreateT): _device{}, _handle{} {} |
||||||
|
|
||||||
|
Sampler::Sampler(Sampler&& other) noexcept: _device{other._device}, _handle{other._handle}, _flags{other._flags} { |
||||||
|
other._handle = {}; |
||||||
|
} |
||||||
|
|
||||||
|
Sampler::~Sampler() { |
||||||
|
if(_handle && (_flags & HandleFlag::DestroyOnDestruction)) |
||||||
|
(**_device).DestroySampler(*_device, _handle, nullptr); |
||||||
|
} |
||||||
|
|
||||||
|
Sampler& Sampler::operator=(Sampler&& other) noexcept { |
||||||
|
using std::swap; |
||||||
|
swap(other._device, _device); |
||||||
|
swap(other._handle, _handle); |
||||||
|
swap(other._flags, _flags); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
VkSampler Sampler::release() { |
||||||
|
const VkSampler handle = _handle; |
||||||
|
_handle = {}; |
||||||
|
return handle; |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,145 @@ |
|||||||
|
#ifndef Magnum_Vk_Sampler_h |
||||||
|
#define Magnum_Vk_Sampler_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class @ref Magnum::Vk::Sampler |
||||||
|
* @m_since_latest |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Magnum/Tags.h" |
||||||
|
#include "Magnum/Vk/Handle.h" |
||||||
|
#include "Magnum/Vk/visibility.h" |
||||||
|
#include "Magnum/Vk/Vk.h" |
||||||
|
#include "Magnum/Vk/Vulkan.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Vk { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Sampler |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
Wraps a @type_vk_keyword{Sampler}. |
||||||
|
|
||||||
|
@section Vk-Sampler-creation Sampler creation |
||||||
|
|
||||||
|
The default-constructed @ref SamplerCreateInfo uses a conservative setup with |
||||||
|
nearest neighbor filtering and will produce valid results with no need to set |
||||||
|
up anything else: |
||||||
|
|
||||||
|
@snippet MagnumVk.cpp Sampler-creation |
||||||
|
|
||||||
|
Usually, however, you'll want to set up filtering and mip level selection at |
||||||
|
least, along with other properties: |
||||||
|
|
||||||
|
@snippet MagnumVk.cpp Sampler-creation-linear |
||||||
|
|
||||||
|
*/ |
||||||
|
class MAGNUM_VK_EXPORT Sampler { |
||||||
|
public: |
||||||
|
/**
|
||||||
|
* @brief Wrap existing Vulkan handle |
||||||
|
* @param device Vulkan device the sampler is created on |
||||||
|
* @param handle The @type_vk{Sampler} handle |
||||||
|
* @param flags Handle flags |
||||||
|
* |
||||||
|
* The @p handle is expected to be originating from @p device. Unlike |
||||||
|
* a sampler created using a constructor, the Vulkan sampler is by |
||||||
|
* default not deleted on destruction, use @p flags for different |
||||||
|
* behavior. |
||||||
|
* @see @ref release() |
||||||
|
*/ |
||||||
|
static Sampler wrap(Device& device, VkSampler handle, HandleFlags flags = {}); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor |
||||||
|
* @param device Vulkan device to create the sampler on |
||||||
|
* @param info Sampler creation info |
||||||
|
* |
||||||
|
* @see @fn_vk_keyword{CreateSampler} |
||||||
|
*/ |
||||||
|
explicit Sampler(Device& device, const SamplerCreateInfo& info); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct without creating the sampler |
||||||
|
* |
||||||
|
* The constructed instance is equivalent to moved-from state. Useful |
||||||
|
* in cases where you will overwrite the instance later anyway. Move |
||||||
|
* another object over it to make it useful. |
||||||
|
*/ |
||||||
|
explicit Sampler(NoCreateT); |
||||||
|
|
||||||
|
/** @brief Copying is not allowed */ |
||||||
|
Sampler(const Sampler&) = delete; |
||||||
|
|
||||||
|
/** @brief Move constructor */ |
||||||
|
Sampler(Sampler&& other) noexcept; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor |
||||||
|
* |
||||||
|
* Destroys associated @type_vk{Sampler} handle, unless the instance |
||||||
|
* was created using @ref wrap() without |
||||||
|
* @ref HandleFlag::DestroyOnDestruction specified. |
||||||
|
* @see @fn_vk_keyword{DestroySampler}, @ref release() |
||||||
|
*/ |
||||||
|
~Sampler(); |
||||||
|
|
||||||
|
/** @brief Copying is not allowed */ |
||||||
|
Sampler& operator=(const Sampler&) = delete; |
||||||
|
|
||||||
|
/** @brief Move assignment */ |
||||||
|
Sampler& operator=(Sampler&& other) noexcept; |
||||||
|
|
||||||
|
/** @brief Underlying @type_vk{Sampler} handle */ |
||||||
|
VkSampler handle() { return _handle; } |
||||||
|
/** @overload */ |
||||||
|
operator VkSampler() { return _handle; } |
||||||
|
|
||||||
|
/** @brief Handle flags */ |
||||||
|
HandleFlags handleFlags() const { return _flags; } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Release the underlying Vulkan sampler |
||||||
|
* |
||||||
|
* Releases ownership of the Vulkan sampler and returns its handle so |
||||||
|
* @fn_vk{DestroySampler} is not called on destruction. The internal |
||||||
|
* state is then equivalent to moved-from state. |
||||||
|
* @see @ref wrap() |
||||||
|
*/ |
||||||
|
VkSampler release(); |
||||||
|
|
||||||
|
private: |
||||||
|
/* Can't be a reference because of the NoCreate constructor */ |
||||||
|
Device* _device; |
||||||
|
|
||||||
|
VkSampler _handle; |
||||||
|
HandleFlags _flags; |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,308 @@ |
|||||||
|
#ifndef Magnum_Vk_SamplerCreateInfo_h |
||||||
|
#define Magnum_Vk_SamplerCreateInfo_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class @ref Magnum::Vk::SamplerCreateInfo, enum @ref Magnum::Vk::SamplerFilter, @ref Magnum::Vk::SamplerMipmap, @ref Magnum::Vk::SamplerWrapping, function @ref Magnum::Vk::samplerFilter(), @ref Magnum::Vk::samplerMipmap(), @ref Magnum::Vk::samplerWrapping() |
||||||
|
* @m_since_latest |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Corrade/Containers/EnumSet.h> |
||||||
|
|
||||||
|
#include "Magnum/Tags.h" |
||||||
|
#include "Magnum/Vk/visibility.h" |
||||||
|
#include "Magnum/Vk/Vk.h" |
||||||
|
#include "Magnum/Vk/Vulkan.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Vk { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Texture sampler filtering |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
Wraps a @type_vk_keyword{Filter}. |
||||||
|
@see @ref Magnum::SamplerFilter, @ref samplerFilter(), |
||||||
|
@ref SamplerCreateInfo::setMinificationFilter(), |
||||||
|
@ref SamplerCreateInfo::setMagnificationFilter() |
||||||
|
*/ |
||||||
|
enum class SamplerFilter: Int { |
||||||
|
/** Nearest neighbor filtering */ |
||||||
|
Nearest = VK_FILTER_NEAREST, |
||||||
|
|
||||||
|
/** Linear interpolation filtering */ |
||||||
|
Linear = VK_FILTER_LINEAR |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
@debugoperatorenum{SamplerFilter} |
||||||
|
@m_since_latest |
||||||
|
*/ |
||||||
|
MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, SamplerFilter value); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Convert a generic sampler filter to Vulkan sampler filter |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@see @ref samplerMipmap(), @ref samplerWrapping() |
||||||
|
*/ |
||||||
|
MAGNUM_VK_EXPORT SamplerFilter samplerFilter(Magnum::SamplerFilter filter); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Texture sampler mip level selection |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
Wraps a @type_vk_keyword{SamplerMipmapMode}. |
||||||
|
@see @ref Magnum::SamplerMipmap, @ref samplerMipmap(), |
||||||
|
@ref SamplerCreateInfo::setMinificationFilter() |
||||||
|
*/ |
||||||
|
enum class SamplerMipmap: Int { |
||||||
|
/** Select nearest mip level */ |
||||||
|
Nearest = VK_SAMPLER_MIPMAP_MODE_NEAREST, |
||||||
|
|
||||||
|
/** Linear interpolation of nearest mip levels */ |
||||||
|
Linear = VK_SAMPLER_MIPMAP_MODE_LINEAR |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
@debugoperatorenum{SamplerWrapping} |
||||||
|
@m_since_latest |
||||||
|
*/ |
||||||
|
MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, SamplerWrapping value); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Convert a generic sampler mipmap mode to Vulkan sampler mipmap mode |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
Vulkan doesn't support the @ref Magnum::SamplerMipmap::Base value directly, |
||||||
|
instead @ref SamplerMipmap::Nearest is used and you have to configure the |
||||||
|
sampler to use just a single mipmap level. |
||||||
|
@see @ref samplerFilter(), @ref samplerWrapping() |
||||||
|
*/ |
||||||
|
MAGNUM_VK_EXPORT SamplerMipmap samplerMipmap(Magnum::SamplerMipmap mipmap); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Texture sampler wrapping |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@see @ref Magnum::SamplerWrapping, @ref samplerWrapping(), |
||||||
|
@ref SamplerCreateInfo::setWrapping() |
||||||
|
*/ |
||||||
|
enum class SamplerWrapping: Int { |
||||||
|
/** Repeat the texture */ |
||||||
|
Repeat = VK_SAMPLER_ADDRESS_MODE_REPEAT, |
||||||
|
|
||||||
|
/** Repeat a mirrored texture */ |
||||||
|
MirroredRepeat = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, |
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamp to edge. Coordinates out of range will be clamped to the first / |
||||||
|
* last column / row / layer in given direction. |
||||||
|
*/ |
||||||
|
ClampToEdge = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, |
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamp to border color. Coordinates of out range will be clamped to the |
||||||
|
* border color. |
||||||
|
*/ |
||||||
|
ClampToBorder = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, |
||||||
|
|
||||||
|
/**
|
||||||
|
* Mirror the texture once in negative coordinates and clamp to edge after |
||||||
|
* that. |
||||||
|
* @requires_vk12 Extension @vk_extension{KHR,sampler_mirror_clamp_to_edge} |
||||||
|
* @todoc The extension mentions something about vanilla 1.2 not having |
||||||
|
* this unless the extension is also listed (wtf??) |
||||||
|
*/ |
||||||
|
MirrorClampToEdge = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
@debugoperatorenum{SamplerMipmap} |
||||||
|
@m_since_latest |
||||||
|
*/ |
||||||
|
MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, SamplerMipmap value); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Convert a generic sampler wrapping mode to Vulkan sampler wrapping mode |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@see @ref samplerFilter(), @ref samplerMipmap() |
||||||
|
*/ |
||||||
|
MAGNUM_VK_EXPORT SamplerWrapping samplerWrapping(Magnum::SamplerWrapping wrapping); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief @copybrief samplerWrapping() |
||||||
|
* @m_deprecated_since_latest Use @ref samplerWrapping() instead. |
||||||
|
*/ |
||||||
|
template<std::size_t dimensions> MAGNUM_VK_EXPORT Math::Vector<dimensions, SamplerWrapping> samplerWrapping(const Math::Vector<dimensions, Magnum::SamplerWrapping>& wrapping); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Sampler creation info |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
Wraps a @type_vk_keyword{SamplerCreateInfo}. See |
||||||
|
@ref Vk-Sampler-creation "Sampler creation" for usage information. |
||||||
|
@todo @type_vk{SamplerReductionMode}, anisotropy |
||||||
|
*/ |
||||||
|
class MAGNUM_VK_EXPORT SamplerCreateInfo { |
||||||
|
public: |
||||||
|
/**
|
||||||
|
* @brief Sampler creation flag |
||||||
|
* |
||||||
|
* Wraps @type_vk_keyword{SamplerCreateFlagBits}. |
||||||
|
* @see @ref Flags, @ref SamplerCreateInfo(Flags) |
||||||
|
* @m_enum_values_as_keywords |
||||||
|
*/ |
||||||
|
enum class Flag: UnsignedInt { |
||||||
|
/** @todo all the flags from extensions */ |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sampler creation flags |
||||||
|
* |
||||||
|
* Type-safe wrapper for @type_vk_keyword{SamplerCreateFlags}. |
||||||
|
* @see @ref SamplerCreateInfo(Flags) |
||||||
|
*/ |
||||||
|
typedef Containers::EnumSet<Flag> Flags; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor |
||||||
|
* @param flags Sampler creation flags |
||||||
|
* |
||||||
|
* The following @type_vk{SamplerCreateInfo} fields are pre-filled in |
||||||
|
* addition to `sType`, everything else is zero-filled: |
||||||
|
* |
||||||
|
* - `flags` |
||||||
|
* - `minFilter` and `magFilter` to @ref SamplerFilter::Nearest |
||||||
|
* - `mipmapMode` to @ref SamplerMipmap::Nearest |
||||||
|
* - `addressModeU`, `addressModeV` and `addressModeW` to |
||||||
|
* @ref SamplerWrapping::Repeat |
||||||
|
* - `minLod` to @cpp -1000.0f @ce |
||||||
|
* - `maxLod` to @cpp 1000.0f @ce |
||||||
|
* |
||||||
|
* The min/max LOD defaults are chosen to be the same as OpenGL |
||||||
|
* defaults. |
||||||
|
* @see @ref setMinificationFilter(), @ref setMagnificationFilter(), |
||||||
|
* @ref setWrapping() |
||||||
|
*/ |
||||||
|
explicit SamplerCreateInfo(Flags flags = {}); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct without initializing the contents |
||||||
|
* |
||||||
|
* Note that not even the `sType` field is set --- the structure has to |
||||||
|
* be fully initialized afterwards in order to be usable. |
||||||
|
*/ |
||||||
|
explicit SamplerCreateInfo(NoInitT) noexcept; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct from existing data |
||||||
|
* |
||||||
|
* Copies the existing values verbatim, pointers are kept unchanged |
||||||
|
* without taking over the ownership. Modifying the newly created |
||||||
|
* instance will not modify the original data nor the pointed-to data. |
||||||
|
*/ |
||||||
|
explicit SamplerCreateInfo(const VkSamplerCreateInfo& info); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set minification filter |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Sets the following @type_vk{SamplerCreateInfo} fields: |
||||||
|
* |
||||||
|
* - `minFilter` to @p filter |
||||||
|
* - `mipmapMode` to @p mipmap |
||||||
|
* |
||||||
|
* @see @ref setMagnificationFilter(), @ref setWrapping() |
||||||
|
*/ |
||||||
|
SamplerCreateInfo& setMinificationFilter(SamplerFilter filter, SamplerMipmap mipmap); |
||||||
|
/** @overload */ |
||||||
|
SamplerCreateInfo& setMinificationFilter(Magnum::SamplerFilter filter, Magnum::SamplerMipmap mipmap); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set magnification filter |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Sets the following @type_vk{SamplerCreateInfo} fields: |
||||||
|
* |
||||||
|
* - `magFilter` to @p filter |
||||||
|
* |
||||||
|
* @see @ref setMinificationFilter(), @ref setWrapping() |
||||||
|
*/ |
||||||
|
SamplerCreateInfo& setMagnificationFilter(SamplerFilter filter); |
||||||
|
/** @overload */ |
||||||
|
SamplerCreateInfo& setMagnificationFilter(Magnum::SamplerFilter filter); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set wrapping |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Sets the following @type_vk{SamplerCreateInfo} fields: |
||||||
|
* |
||||||
|
* - `addressModeU`, `addressModeV` and `addressModeW` to |
||||||
|
* the respective components of @p wrapping |
||||||
|
* |
||||||
|
* @see @ref setMinificationFilter(), @ref setMagnificationFilter() |
||||||
|
*/ |
||||||
|
SamplerCreateInfo& setWrapping(const Math::Vector3<SamplerWrapping>& wrapping); |
||||||
|
/** @overload */ |
||||||
|
SamplerCreateInfo& setWrapping(const Math::Vector3<Magnum::SamplerWrapping>& wrapping); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set wrapping for all dimensions at once |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Same as calling @ref setWrapping(const Math::Vector3<SamplerWrapping>&) |
||||||
|
* with @p wrapping set for all components. |
||||||
|
*/ |
||||||
|
SamplerCreateInfo& setWrapping(SamplerWrapping wrapping); |
||||||
|
/** @overload */ |
||||||
|
SamplerCreateInfo& setWrapping(Magnum::SamplerWrapping wrapping); |
||||||
|
|
||||||
|
/** @brief Underlying @type_vk{SamplerCreateInfo} structure */ |
||||||
|
VkSamplerCreateInfo& operator*() { return _info; } |
||||||
|
/** @overload */ |
||||||
|
const VkSamplerCreateInfo& operator*() const { return _info; } |
||||||
|
/** @overload */ |
||||||
|
VkSamplerCreateInfo* operator->() { return &_info; } |
||||||
|
/** @overload */ |
||||||
|
const VkSamplerCreateInfo* operator->() const { return &_info; } |
||||||
|
/** @overload */ |
||||||
|
operator const VkSamplerCreateInfo*() const { return &_info; } |
||||||
|
|
||||||
|
private: |
||||||
|
VkSamplerCreateInfo _info; |
||||||
|
}; |
||||||
|
|
||||||
|
CORRADE_ENUMSET_OPERATORS(SamplerCreateInfo::Flags) |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
/* Make the definition complete -- it doesn't make sense to have a CreateInfo
|
||||||
|
without the corresponding object anyway. */ |
||||||
|
#include "Magnum/Vk/Sampler.h" |
||||||
|
|
||||||
|
#endif |
||||||
@ -1,153 +0,0 @@ |
|||||||
/*
|
|
||||||
This file is part of Magnum. |
|
||||||
|
|
||||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
|
||||||
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a |
|
||||||
copy of this software and associated documentation files (the "Software"), |
|
||||||
to deal in the Software without restriction, including without limitation |
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
||||||
and/or sell copies of the Software, and to permit persons to whom the |
|
||||||
Software is furnished to do so, subject to the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included |
|
||||||
in all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
||||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
||||||
DEALINGS IN THE SOFTWARE. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <sstream> |
|
||||||
#include <Corrade/TestSuite/Tester.h> |
|
||||||
#include <Corrade/Utility/DebugStl.h> |
|
||||||
|
|
||||||
#include "Magnum/Mesh.h" |
|
||||||
#include "Magnum/PixelFormat.h" |
|
||||||
#include "Magnum/Sampler.h" |
|
||||||
#include "Magnum/VertexFormat.h" |
|
||||||
#include "Magnum/Vk/Enums.h" |
|
||||||
|
|
||||||
namespace Magnum { namespace Vk { namespace Test { namespace { |
|
||||||
|
|
||||||
struct EnumsTest: TestSuite::Tester { |
|
||||||
explicit EnumsTest(); |
|
||||||
|
|
||||||
void mapVkFilter(); |
|
||||||
void mapVkFilterInvalid(); |
|
||||||
|
|
||||||
void mapVkSamplerMipmapMode(); |
|
||||||
void mapVkSamplerMipmapModeInvalid(); |
|
||||||
|
|
||||||
void mapVkSamplerAddressMode(); |
|
||||||
void mapVkSamplerAddressModeArray(); |
|
||||||
void mapVkSamplerAddressModeUnsupported(); |
|
||||||
void mapVkSamplerAddressModeInvalid(); |
|
||||||
}; |
|
||||||
|
|
||||||
EnumsTest::EnumsTest() { |
|
||||||
addTests({&EnumsTest::mapVkFilter, |
|
||||||
&EnumsTest::mapVkFilterInvalid, |
|
||||||
|
|
||||||
&EnumsTest::mapVkSamplerMipmapMode, |
|
||||||
&EnumsTest::mapVkSamplerMipmapModeInvalid, |
|
||||||
|
|
||||||
&EnumsTest::mapVkSamplerAddressMode, |
|
||||||
&EnumsTest::mapVkSamplerAddressModeArray, |
|
||||||
&EnumsTest::mapVkSamplerAddressModeUnsupported, |
|
||||||
&EnumsTest::mapVkSamplerAddressModeInvalid}); |
|
||||||
} |
|
||||||
|
|
||||||
void EnumsTest::mapVkFilter() { |
|
||||||
CORRADE_COMPARE(vkFilter(SamplerFilter::Nearest), VK_FILTER_NEAREST); |
|
||||||
CORRADE_COMPARE(vkFilter(SamplerFilter::Linear), VK_FILTER_LINEAR); |
|
||||||
} |
|
||||||
|
|
||||||
void EnumsTest::mapVkFilterInvalid() { |
|
||||||
#ifdef CORRADE_NO_ASSERT |
|
||||||
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); |
|
||||||
#endif |
|
||||||
|
|
||||||
std::ostringstream out; |
|
||||||
Error redirectError{&out}; |
|
||||||
|
|
||||||
vkFilter(Magnum::SamplerFilter(0x123)); |
|
||||||
CORRADE_COMPARE(out.str(), |
|
||||||
"Vk::vkFilter(): invalid filter SamplerFilter(0x123)\n"); |
|
||||||
} |
|
||||||
|
|
||||||
void EnumsTest::mapVkSamplerMipmapMode() { |
|
||||||
CORRADE_COMPARE(vkSamplerMipmapMode(SamplerMipmap::Base), VK_SAMPLER_MIPMAP_MODE_NEAREST); /* deliberate */ |
|
||||||
CORRADE_COMPARE(vkSamplerMipmapMode(SamplerMipmap::Nearest), VK_SAMPLER_MIPMAP_MODE_NEAREST); |
|
||||||
CORRADE_COMPARE(vkSamplerMipmapMode(SamplerMipmap::Linear), VK_SAMPLER_MIPMAP_MODE_LINEAR); |
|
||||||
} |
|
||||||
|
|
||||||
void EnumsTest::mapVkSamplerMipmapModeInvalid() { |
|
||||||
#ifdef CORRADE_NO_ASSERT |
|
||||||
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); |
|
||||||
#endif |
|
||||||
|
|
||||||
std::ostringstream out; |
|
||||||
Error redirectError{&out}; |
|
||||||
|
|
||||||
vkSamplerMipmapMode(Magnum::SamplerMipmap(0x123)); |
|
||||||
CORRADE_COMPARE(out.str(), |
|
||||||
"Vk::vkSamplerMipmapMode(): invalid mode SamplerMipmap(0x123)\n"); |
|
||||||
} |
|
||||||
|
|
||||||
void EnumsTest::mapVkSamplerAddressMode() { |
|
||||||
CORRADE_VERIFY(hasVkSamplerAddressMode(SamplerWrapping::Repeat)); |
|
||||||
CORRADE_COMPARE(vkSamplerAddressMode(SamplerWrapping::Repeat), VK_SAMPLER_ADDRESS_MODE_REPEAT); |
|
||||||
|
|
||||||
CORRADE_VERIFY(hasVkSamplerAddressMode(SamplerWrapping::MirroredRepeat)); |
|
||||||
CORRADE_COMPARE(vkSamplerAddressMode(SamplerWrapping::MirroredRepeat), VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT); |
|
||||||
|
|
||||||
CORRADE_VERIFY(hasVkSamplerAddressMode(SamplerWrapping::ClampToEdge)); |
|
||||||
CORRADE_COMPARE(vkSamplerAddressMode(SamplerWrapping::ClampToEdge), VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); |
|
||||||
|
|
||||||
CORRADE_VERIFY(hasVkSamplerAddressMode(SamplerWrapping::ClampToBorder)); |
|
||||||
CORRADE_COMPARE(vkSamplerAddressMode(SamplerWrapping::ClampToBorder), VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); |
|
||||||
} |
|
||||||
|
|
||||||
void EnumsTest::mapVkSamplerAddressModeArray() { |
|
||||||
CORRADE_COMPARE(vkSamplerAddressMode<2>({SamplerWrapping::Repeat, SamplerWrapping::ClampToBorder}), (Math::Vector2<VkSamplerAddressMode>{VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER})); |
|
||||||
} |
|
||||||
|
|
||||||
void EnumsTest::mapVkSamplerAddressModeUnsupported() { |
|
||||||
#ifdef CORRADE_NO_ASSERT |
|
||||||
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); |
|
||||||
#endif |
|
||||||
|
|
||||||
#if 1 |
|
||||||
CORRADE_SKIP("All sampler address modes are supported."); |
|
||||||
#else |
|
||||||
CORRADE_VERIFY(!hasVkSamplerAddressMode(Magnum::SamplerWrapping::MirrorClampToEdge)); |
|
||||||
std::ostringstream out; |
|
||||||
Error redirectError{&out}; |
|
||||||
vkSamplerAddressMode(Magnum::SamplerWrapping::MirrorClampToEdge); |
|
||||||
CORRADE_COMPARE(out.str(), |
|
||||||
"Vk::vkSamplerAddressMode(): unsupported wrapping SamplerWrapping::MirrorClampToEdge\n"); |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
void EnumsTest::mapVkSamplerAddressModeInvalid() { |
|
||||||
#ifdef CORRADE_NO_ASSERT |
|
||||||
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); |
|
||||||
#endif |
|
||||||
|
|
||||||
std::ostringstream out; |
|
||||||
Error redirectError{&out}; |
|
||||||
|
|
||||||
vkSamplerAddressMode(Magnum::SamplerWrapping(0x123)); |
|
||||||
CORRADE_COMPARE(out.str(), |
|
||||||
"Vk::vkSamplerAddressMode(): invalid wrapping SamplerWrapping(0x123)\n"); |
|
||||||
} |
|
||||||
|
|
||||||
}}}} |
|
||||||
|
|
||||||
CORRADE_TEST_MAIN(Magnum::Vk::Test::EnumsTest) |
|
||||||
@ -0,0 +1,289 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <sstream> |
||||||
|
#include <Corrade/TestSuite/Tester.h> |
||||||
|
#include <Corrade/Utility/DebugStl.h> |
||||||
|
|
||||||
|
#include "Magnum/Sampler.h" |
||||||
|
#include "Magnum/Math/Vector3.h" |
||||||
|
#include "Magnum/Vk/SamplerCreateInfo.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Vk { namespace Test { namespace { |
||||||
|
|
||||||
|
struct SamplerTest: TestSuite::Tester { |
||||||
|
explicit SamplerTest(); |
||||||
|
|
||||||
|
void mapFilter(); |
||||||
|
void mapFilterInvalid(); |
||||||
|
|
||||||
|
void mapMipmap(); |
||||||
|
void mapMipmapInvalid(); |
||||||
|
|
||||||
|
void mapWrapping(); |
||||||
|
void mapWrappingVector(); |
||||||
|
void mapWrappingInvalid(); |
||||||
|
|
||||||
|
void createInfoConstruct(); |
||||||
|
void createInfoConstructNoInit(); |
||||||
|
void createInfoConstructFromVk(); |
||||||
|
template<class T> void createInfoSetFilter(); |
||||||
|
template<class T> void createInfoSetMipmap(); |
||||||
|
template<class T> void createInfoSetWrapping(); |
||||||
|
template<class T> void createInfoSetWrappingSingleValue(); |
||||||
|
|
||||||
|
void constructNoCreate(); |
||||||
|
void constructCopy(); |
||||||
|
|
||||||
|
void debugFilter(); |
||||||
|
void debugMipmap(); |
||||||
|
void debugWrapping(); |
||||||
|
}; |
||||||
|
|
||||||
|
SamplerTest::SamplerTest() { |
||||||
|
addTests({&SamplerTest::mapFilter, |
||||||
|
&SamplerTest::mapFilterInvalid, |
||||||
|
|
||||||
|
&SamplerTest::mapMipmap, |
||||||
|
&SamplerTest::mapMipmapInvalid, |
||||||
|
|
||||||
|
&SamplerTest::mapWrapping, |
||||||
|
&SamplerTest::mapWrappingVector, |
||||||
|
&SamplerTest::mapWrappingInvalid, |
||||||
|
|
||||||
|
&SamplerTest::createInfoConstruct, |
||||||
|
&SamplerTest::createInfoConstructNoInit, |
||||||
|
&SamplerTest::createInfoConstructFromVk, |
||||||
|
&SamplerTest::createInfoSetFilter<SamplerFilter>, |
||||||
|
&SamplerTest::createInfoSetFilter<Magnum::SamplerFilter>, |
||||||
|
&SamplerTest::createInfoSetMipmap<SamplerMipmap>, |
||||||
|
&SamplerTest::createInfoSetMipmap<Magnum::SamplerMipmap>, |
||||||
|
&SamplerTest::createInfoSetWrapping<SamplerWrapping>, |
||||||
|
&SamplerTest::createInfoSetWrapping<Magnum::SamplerWrapping>, |
||||||
|
&SamplerTest::createInfoSetWrappingSingleValue<SamplerWrapping>, |
||||||
|
&SamplerTest::createInfoSetWrappingSingleValue<Magnum::SamplerWrapping>, |
||||||
|
|
||||||
|
&SamplerTest::constructNoCreate, |
||||||
|
&SamplerTest::constructCopy, |
||||||
|
|
||||||
|
&SamplerTest::debugFilter, |
||||||
|
&SamplerTest::debugMipmap, |
||||||
|
&SamplerTest::debugWrapping}); |
||||||
|
} |
||||||
|
|
||||||
|
template<class> struct SamplerTypeTraits; |
||||||
|
template<> struct SamplerTypeTraits<SamplerFilter> { |
||||||
|
static const char* name() { return "SamplerFilter"; } |
||||||
|
}; |
||||||
|
template<> struct SamplerTypeTraits<Magnum::SamplerFilter> { |
||||||
|
static const char* name() { return "Magnum::SamplerFilter"; } |
||||||
|
}; |
||||||
|
template<> struct SamplerTypeTraits<SamplerMipmap> { |
||||||
|
static const char* name() { return "SamplerMipmap"; } |
||||||
|
}; |
||||||
|
template<> struct SamplerTypeTraits<Magnum::SamplerMipmap> { |
||||||
|
static const char* name() { return "Magnum::SamplerMipmap"; } |
||||||
|
}; |
||||||
|
template<> struct SamplerTypeTraits<SamplerWrapping> { |
||||||
|
static const char* name() { return "SamplerWrapping"; } |
||||||
|
}; |
||||||
|
template<> struct SamplerTypeTraits<Magnum::SamplerWrapping> { |
||||||
|
static const char* name() { return "Magnum::SamplerWrapping"; } |
||||||
|
}; |
||||||
|
|
||||||
|
void SamplerTest::mapFilter() { |
||||||
|
CORRADE_COMPARE(samplerFilter(Magnum::SamplerFilter::Nearest), SamplerFilter::Nearest); |
||||||
|
CORRADE_COMPARE(samplerFilter(Magnum::SamplerFilter::Linear), SamplerFilter::Linear); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::mapFilterInvalid() { |
||||||
|
#ifdef CORRADE_NO_ASSERT |
||||||
|
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); |
||||||
|
#endif |
||||||
|
|
||||||
|
std::ostringstream out; |
||||||
|
Error redirectError{&out}; |
||||||
|
|
||||||
|
samplerFilter(Magnum::SamplerFilter(0x123)); |
||||||
|
CORRADE_COMPARE(out.str(), |
||||||
|
"Vk::samplerFilter(): invalid filter SamplerFilter(0x123)\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::mapMipmap() { |
||||||
|
CORRADE_COMPARE(samplerMipmap(Magnum::SamplerMipmap::Base), SamplerMipmap::Nearest); /* deliberate */ |
||||||
|
CORRADE_COMPARE(samplerMipmap(Magnum::SamplerMipmap::Nearest), SamplerMipmap::Nearest); |
||||||
|
CORRADE_COMPARE(samplerMipmap(Magnum::SamplerMipmap::Linear), SamplerMipmap::Linear); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::mapMipmapInvalid() { |
||||||
|
#ifdef CORRADE_NO_ASSERT |
||||||
|
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); |
||||||
|
#endif |
||||||
|
|
||||||
|
std::ostringstream out; |
||||||
|
Error redirectError{&out}; |
||||||
|
|
||||||
|
samplerMipmap(Magnum::SamplerMipmap(0x123)); |
||||||
|
CORRADE_COMPARE(out.str(), |
||||||
|
"Vk::samplerMipmap(): invalid mode SamplerMipmap(0x123)\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::mapWrapping() { |
||||||
|
CORRADE_COMPARE(samplerWrapping(Magnum::SamplerWrapping::Repeat), SamplerWrapping::Repeat); |
||||||
|
|
||||||
|
CORRADE_COMPARE(samplerWrapping(Magnum::SamplerWrapping::MirroredRepeat), SamplerWrapping::MirroredRepeat); |
||||||
|
|
||||||
|
CORRADE_COMPARE(samplerWrapping(Magnum::SamplerWrapping::ClampToEdge), SamplerWrapping::ClampToEdge); |
||||||
|
|
||||||
|
CORRADE_COMPARE(samplerWrapping(Magnum::SamplerWrapping::ClampToBorder), SamplerWrapping::ClampToBorder); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::mapWrappingVector() { |
||||||
|
CORRADE_COMPARE(samplerWrapping<2>({Magnum::SamplerWrapping::Repeat, Magnum::SamplerWrapping::ClampToBorder}), (Math::Vector2<SamplerWrapping>{SamplerWrapping::Repeat, SamplerWrapping::ClampToBorder})); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::mapWrappingInvalid() { |
||||||
|
#ifdef CORRADE_NO_ASSERT |
||||||
|
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); |
||||||
|
#endif |
||||||
|
|
||||||
|
std::ostringstream out; |
||||||
|
Error redirectError{&out}; |
||||||
|
|
||||||
|
samplerWrapping(Magnum::SamplerWrapping(0x123)); |
||||||
|
CORRADE_COMPARE(out.str(), |
||||||
|
"Vk::samplerWrapping(): invalid wrapping SamplerWrapping(0x123)\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::createInfoConstruct() { |
||||||
|
/** @todo use a real flag once it exists */ |
||||||
|
SamplerCreateInfo info{SamplerCreateInfo::Flag(1237)}; |
||||||
|
CORRADE_COMPARE(info->flags, 1237); |
||||||
|
CORRADE_COMPARE(info->minFilter, VK_FILTER_NEAREST); |
||||||
|
CORRADE_COMPARE(info->magFilter, VK_FILTER_NEAREST); |
||||||
|
CORRADE_COMPARE(info->mipmapMode, VK_SAMPLER_MIPMAP_MODE_NEAREST); |
||||||
|
CORRADE_COMPARE(info->addressModeU, VK_SAMPLER_ADDRESS_MODE_REPEAT); |
||||||
|
CORRADE_COMPARE(info->addressModeV, VK_SAMPLER_ADDRESS_MODE_REPEAT); |
||||||
|
CORRADE_COMPARE(info->addressModeW, VK_SAMPLER_ADDRESS_MODE_REPEAT); |
||||||
|
CORRADE_COMPARE(info->minLod, -1000.0f); |
||||||
|
CORRADE_COMPARE(info->maxLod, 1000.0f); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::createInfoConstructNoInit() { |
||||||
|
SamplerCreateInfo info{NoInit}; |
||||||
|
info->sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; |
||||||
|
new(&info) SamplerCreateInfo{NoInit}; |
||||||
|
CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); |
||||||
|
|
||||||
|
CORRADE_VERIFY(std::is_nothrow_constructible<SamplerCreateInfo, NoInitT>::value); |
||||||
|
|
||||||
|
/* Implicit construction is not allowed */ |
||||||
|
CORRADE_VERIFY(!std::is_convertible<NoInitT, SamplerCreateInfo>::value); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::createInfoConstructFromVk() { |
||||||
|
VkSamplerCreateInfo vkInfo; |
||||||
|
vkInfo.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; |
||||||
|
|
||||||
|
SamplerCreateInfo info{vkInfo}; |
||||||
|
CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); |
||||||
|
} |
||||||
|
|
||||||
|
template<class T> void SamplerTest::createInfoSetFilter() { |
||||||
|
setTestCaseTemplateName(SamplerTypeTraits<T>::name()); |
||||||
|
|
||||||
|
SamplerCreateInfo info; |
||||||
|
info.setMinificationFilter(T::Linear, {}) |
||||||
|
.setMagnificationFilter(T::Linear); |
||||||
|
CORRADE_COMPARE(info->minFilter, VK_FILTER_LINEAR); |
||||||
|
CORRADE_COMPARE(info->mipmapMode, 0); |
||||||
|
CORRADE_COMPARE(info->magFilter, VK_FILTER_LINEAR); |
||||||
|
} |
||||||
|
|
||||||
|
template<class T> void SamplerTest::createInfoSetMipmap() { |
||||||
|
setTestCaseTemplateName(SamplerTypeTraits<T>::name()); |
||||||
|
|
||||||
|
SamplerCreateInfo info; |
||||||
|
info.setMinificationFilter({}, T::Linear); |
||||||
|
CORRADE_COMPARE(info->minFilter, 0); |
||||||
|
CORRADE_COMPARE(info->mipmapMode, VK_SAMPLER_MIPMAP_MODE_LINEAR); |
||||||
|
} |
||||||
|
|
||||||
|
template<class T> void SamplerTest::createInfoSetWrapping() { |
||||||
|
setTestCaseTemplateName(SamplerTypeTraits<T>::name()); |
||||||
|
|
||||||
|
SamplerCreateInfo info; |
||||||
|
info.setWrapping({T::MirroredRepeat, T::ClampToEdge, T::MirrorClampToEdge}); |
||||||
|
CORRADE_COMPARE(info->addressModeU, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT); |
||||||
|
CORRADE_COMPARE(info->addressModeV, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); |
||||||
|
CORRADE_COMPARE(info->addressModeW, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE); |
||||||
|
} |
||||||
|
|
||||||
|
template<class T> void SamplerTest::createInfoSetWrappingSingleValue() { |
||||||
|
setTestCaseTemplateName(SamplerTypeTraits<T>::name()); |
||||||
|
|
||||||
|
SamplerCreateInfo info; |
||||||
|
info.setWrapping(T::ClampToBorder); |
||||||
|
CORRADE_COMPARE(info->addressModeU, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); |
||||||
|
CORRADE_COMPARE(info->addressModeV, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); |
||||||
|
CORRADE_COMPARE(info->addressModeW, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::constructNoCreate() { |
||||||
|
{ |
||||||
|
Sampler sampler{NoCreate}; |
||||||
|
CORRADE_VERIFY(!sampler.handle()); |
||||||
|
} |
||||||
|
|
||||||
|
/* Implicit construction is not allowed */ |
||||||
|
CORRADE_VERIFY(!std::is_convertible<NoCreateT, Sampler>::value); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::constructCopy() { |
||||||
|
CORRADE_VERIFY(!std::is_copy_constructible<Sampler>{}); |
||||||
|
CORRADE_VERIFY(!std::is_copy_assignable<Sampler>{}); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::debugFilter() { |
||||||
|
std::ostringstream out; |
||||||
|
Debug{&out} << SamplerFilter::Linear << SamplerFilter(-10007655); |
||||||
|
CORRADE_COMPARE(out.str(), "Vk::SamplerFilter::Linear Vk::SamplerFilter(-10007655)\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::debugMipmap() { |
||||||
|
std::ostringstream out; |
||||||
|
Debug{&out} << SamplerMipmap::Linear << SamplerMipmap(-10007655); |
||||||
|
CORRADE_COMPARE(out.str(), "Vk::SamplerMipmap::Linear Vk::SamplerMipmap(-10007655)\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerTest::debugWrapping() { |
||||||
|
std::ostringstream out; |
||||||
|
Debug{&out} << SamplerWrapping::MirrorClampToEdge << SamplerWrapping(-10007655); |
||||||
|
CORRADE_COMPARE(out.str(), "Vk::SamplerWrapping::MirrorClampToEdge Vk::SamplerWrapping(-10007655)\n"); |
||||||
|
} |
||||||
|
|
||||||
|
}}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Vk::Test::SamplerTest) |
||||||
@ -0,0 +1,100 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Corrade/Containers/Reference.h> |
||||||
|
|
||||||
|
#include "Magnum/Vk/SamplerCreateInfo.h" |
||||||
|
#include "Magnum/Vk/Result.h" |
||||||
|
#include "Magnum/Vk/VulkanTester.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Vk { namespace Test { namespace { |
||||||
|
|
||||||
|
struct SamplerVkTest: VulkanTester { |
||||||
|
explicit SamplerVkTest(); |
||||||
|
|
||||||
|
void construct(); |
||||||
|
void constructMove(); |
||||||
|
|
||||||
|
void wrap(); |
||||||
|
}; |
||||||
|
|
||||||
|
SamplerVkTest::SamplerVkTest() { |
||||||
|
addTests({&SamplerVkTest::construct, |
||||||
|
&SamplerVkTest::constructMove, |
||||||
|
|
||||||
|
&SamplerVkTest::wrap}); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerVkTest::construct() { |
||||||
|
{ |
||||||
|
Sampler fence{device(), SamplerCreateInfo{} |
||||||
|
.setMinificationFilter(SamplerFilter::Linear, SamplerMipmap::Linear) |
||||||
|
}; |
||||||
|
CORRADE_VERIFY(fence.handle()); |
||||||
|
CORRADE_COMPARE(fence.handleFlags(), HandleFlag::DestroyOnDestruction); |
||||||
|
} |
||||||
|
|
||||||
|
/* Shouldn't crash or anything */ |
||||||
|
CORRADE_VERIFY(true); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerVkTest::constructMove() { |
||||||
|
Sampler a{device(), SamplerCreateInfo{}}; |
||||||
|
VkSampler handle = a.handle(); |
||||||
|
|
||||||
|
Sampler b = std::move(a); |
||||||
|
CORRADE_VERIFY(!a.handle()); |
||||||
|
CORRADE_COMPARE(b.handle(), handle); |
||||||
|
CORRADE_COMPARE(b.handleFlags(), HandleFlag::DestroyOnDestruction); |
||||||
|
|
||||||
|
Sampler c{NoCreate}; |
||||||
|
c = std::move(b); |
||||||
|
CORRADE_VERIFY(!b.handle()); |
||||||
|
CORRADE_COMPARE(b.handleFlags(), HandleFlags{}); |
||||||
|
CORRADE_COMPARE(c.handle(), handle); |
||||||
|
CORRADE_COMPARE(c.handleFlags(), HandleFlag::DestroyOnDestruction); |
||||||
|
|
||||||
|
CORRADE_VERIFY(std::is_nothrow_move_constructible<Sampler>::value); |
||||||
|
CORRADE_VERIFY(std::is_nothrow_move_assignable<Sampler>::value); |
||||||
|
} |
||||||
|
|
||||||
|
void SamplerVkTest::wrap() { |
||||||
|
VkSampler fence{}; |
||||||
|
CORRADE_COMPARE(Result(device()->CreateSampler(device(), |
||||||
|
SamplerCreateInfo{}, |
||||||
|
nullptr, &fence)), Result::Success); |
||||||
|
|
||||||
|
auto wrapped = Sampler::wrap(device(), fence, HandleFlag::DestroyOnDestruction); |
||||||
|
CORRADE_COMPARE(wrapped.handle(), fence); |
||||||
|
|
||||||
|
/* Release the handle again, destroy by hand */ |
||||||
|
CORRADE_COMPARE(wrapped.release(), fence); |
||||||
|
CORRADE_VERIFY(!wrapped.handle()); |
||||||
|
device()->DestroySampler(device(), fence, nullptr); |
||||||
|
} |
||||||
|
|
||||||
|
}}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Vk::Test::SamplerVkTest) |
||||||
Loading…
Reference in new issue