Cleanup handling of sampler border color and mirror edge clamp.

mvkMTLSamplerAddressModeFromVkSamplerAddressMode() support
MTLSamplerAddressModeClampToBorderColor and
MTLSamplerAddressModeMirrorClampToEdge if available.
Add MVKSampler::getMTLSamplerAddressMode() to test for device feature availability.
Remove special border color handling in MVKSampler::newMTLSamplerDescriptor().
This commit is contained in:
Bill Hollings 2021-05-13 15:06:35 -04:00
parent 77ce400b26
commit ea1d21a939
4 changed files with 24 additions and 26 deletions

View File

@ -286,13 +286,10 @@ VkExtent3D mvkMipmapBaseSizeFromLevelSize3D(VkExtent3D levelSize, uint32_t level
#pragma mark Samplers #pragma mark Samplers
/** /** Returns the Metal MTLSamplerAddressMode corresponding to the specified Vulkan VkSamplerAddressMode. */
* Returns the Metal MTLSamplerAddressMode corresponding to the specified Vulkan VkSamplerAddressMode,
* or returns MTLSamplerAddressModeMirrorClampToEdge if no corresponding MTLSamplerAddressMode exists.
*/
MTLSamplerAddressMode mvkMTLSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode vkMode); MTLSamplerAddressMode mvkMTLSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode vkMode);
#if MVK_MACOS_OR_IOS #if MVK_MACOS_OR_IOS
/** /**
* Returns the Metal MTLSamplerBorderColor corresponding to the specified Vulkan VkBorderColor, * Returns the Metal MTLSamplerBorderColor corresponding to the specified Vulkan VkBorderColor,
* or returns MTLSamplerBorderColorTransparentBlack if no corresponding MTLSamplerBorderColor exists. * or returns MTLSamplerBorderColorTransparentBlack if no corresponding MTLSamplerBorderColor exists.

View File

@ -695,7 +695,6 @@ public:
/** Returns the number of planes if this is a ycbcr conversion or 0 otherwise. */ /** Returns the number of planes if this is a ycbcr conversion or 0 otherwise. */
inline uint8_t getPlaneCount() { return (_ycbcrConversion) ? _ycbcrConversion->getPlaneCount() : 0; } inline uint8_t getPlaneCount() { return (_ycbcrConversion) ? _ycbcrConversion->getPlaneCount() : 0; }
/** /**
* If this sampler requires hardcoding in MSL, populates the hardcoded sampler in the resource binding. * If this sampler requires hardcoding in MSL, populates the hardcoded sampler in the resource binding.
* Returns whether this sampler requires hardcoding in MSL, and the constant sampler was populated. * Returns whether this sampler requires hardcoding in MSL, and the constant sampler was populated.
@ -705,6 +704,9 @@ public:
/** Returns whether this sampler must be implemented as a hardcoded constant sampler in the shader MSL code. */ /** Returns whether this sampler must be implemented as a hardcoded constant sampler in the shader MSL code. */
inline bool getRequiresConstExprSampler() { return _requiresConstExprSampler; } inline bool getRequiresConstExprSampler() { return _requiresConstExprSampler; }
/** Returns the Metal MTLSamplerAddressMode corresponding to the specified Vulkan VkSamplerAddressMode. */
MTLSamplerAddressMode getMTLSamplerAddressMode(VkSamplerAddressMode vkMode);
MVKSampler(MVKDevice* device, const VkSamplerCreateInfo* pCreateInfo); MVKSampler(MVKDevice* device, const VkSamplerCreateInfo* pCreateInfo);
~MVKSampler() override; ~MVKSampler() override;

View File

@ -1909,16 +1909,29 @@ bool MVKSampler::getConstexprSampler(mvk::MSLResourceBinding& resourceBinding) {
return _requiresConstExprSampler; return _requiresConstExprSampler;
} }
// Ensure available Metal features.
MTLSamplerAddressMode MVKSampler::getMTLSamplerAddressMode(VkSamplerAddressMode vkMode) {
if ((vkMode == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER && !_device->_pMetalFeatures->samplerClampToBorder) ||
(vkMode == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE && !_device->_pMetalFeatures->samplerMirrorClampToEdge)) {
return MTLSamplerAddressModeClampToZero;
}
return mvkMTLSamplerAddressModeFromVkSamplerAddressMode(vkMode);
}
// Returns an Metal sampler descriptor constructed from the properties of this image. // Returns an Metal sampler descriptor constructed from the properties of this image.
// It is the caller's responsibility to release the returned descriptor object. // It is the caller's responsibility to release the returned descriptor object.
MTLSamplerDescriptor* MVKSampler::newMTLSamplerDescriptor(const VkSamplerCreateInfo* pCreateInfo) { MTLSamplerDescriptor* MVKSampler::newMTLSamplerDescriptor(const VkSamplerCreateInfo* pCreateInfo) {
MTLSamplerDescriptor* mtlSampDesc = [MTLSamplerDescriptor new]; // retained MTLSamplerDescriptor* mtlSampDesc = [MTLSamplerDescriptor new]; // retained
mtlSampDesc.sAddressMode = mvkMTLSamplerAddressModeFromVkSamplerAddressMode(pCreateInfo->addressModeU); mtlSampDesc.sAddressMode = getMTLSamplerAddressMode(pCreateInfo->addressModeU);
mtlSampDesc.tAddressMode = mvkMTLSamplerAddressModeFromVkSamplerAddressMode(pCreateInfo->addressModeV); mtlSampDesc.tAddressMode = getMTLSamplerAddressMode(pCreateInfo->addressModeV);
if (!pCreateInfo->unnormalizedCoordinates) { if (!pCreateInfo->unnormalizedCoordinates) {
mtlSampDesc.rAddressMode = mvkMTLSamplerAddressModeFromVkSamplerAddressMode(pCreateInfo->addressModeW); mtlSampDesc.rAddressMode = getMTLSamplerAddressMode(pCreateInfo->addressModeW);
} }
#if MVK_MACOS_OR_IOS
mtlSampDesc.borderColorMVK = mvkMTLSamplerBorderColorFromVkBorderColor(pCreateInfo->borderColor);
#endif
mtlSampDesc.minFilter = mvkMTLSamplerMinMagFilterFromVkFilter(pCreateInfo->minFilter); mtlSampDesc.minFilter = mvkMTLSamplerMinMagFilterFromVkFilter(pCreateInfo->minFilter);
mtlSampDesc.magFilter = mvkMTLSamplerMinMagFilterFromVkFilter(pCreateInfo->magFilter); mtlSampDesc.magFilter = mvkMTLSamplerMinMagFilterFromVkFilter(pCreateInfo->magFilter);
mtlSampDesc.mipFilter = (pCreateInfo->unnormalizedCoordinates mtlSampDesc.mipFilter = (pCreateInfo->unnormalizedCoordinates
@ -1940,20 +1953,6 @@ MTLSamplerDescriptor* MVKSampler::newMTLSamplerDescriptor(const VkSamplerCreateI
mtlSampDesc.compareFunctionMVK = mvkMTLCompareFunctionFromVkCompareOp(pCreateInfo->compareOp); mtlSampDesc.compareFunctionMVK = mvkMTLCompareFunctionFromVkCompareOp(pCreateInfo->compareOp);
} }
#if MVK_MACOS_OR_IOS
mtlSampDesc.borderColorMVK = mvkMTLSamplerBorderColorFromVkBorderColor(pCreateInfo->borderColor);
if (getPhysicalDevice()->getMetalFeatures()->samplerClampToBorder) {
if (pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
mtlSampDesc.sAddressMode = MTLSamplerAddressModeClampToBorderColor;
}
if (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
mtlSampDesc.tAddressMode = MTLSamplerAddressModeClampToBorderColor;
}
if (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
mtlSampDesc.rAddressMode = MTLSamplerAddressModeClampToBorderColor;
}
}
#endif
return mtlSampDesc; return mtlSampDesc;
} }

View File

@ -282,12 +282,12 @@ MVK_PUBLIC_SYMBOL MTLSamplerAddressMode mvkMTLSamplerAddressModeFromVkSamplerAdd
switch (vkMode) { switch (vkMode) {
case VK_SAMPLER_ADDRESS_MODE_REPEAT: return MTLSamplerAddressModeRepeat; case VK_SAMPLER_ADDRESS_MODE_REPEAT: return MTLSamplerAddressModeRepeat;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return MTLSamplerAddressModeClampToEdge; case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return MTLSamplerAddressModeClampToEdge;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return MTLSamplerAddressModeClampToZero;
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return MTLSamplerAddressModeMirrorRepeat; case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return MTLSamplerAddressModeMirrorRepeat;
#if MVK_MACOS #if MVK_MACOS || (MVK_IOS && MVK_XCODE_12)
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return MTLSamplerAddressModeMirrorClampToEdge; case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return MTLSamplerAddressModeMirrorClampToEdge;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return MTLSamplerAddressModeClampToBorderColor;
#endif #endif
default: return MTLSamplerAddressModeClampToZero; default: return MTLSamplerAddressModeClampToZero;
} }
} }