Merge pull request #1359 from billhollings/sampler-borders
Cleanup handling of sampler border color and mirror edge clamp.
diff --git a/MoltenVK/MoltenVK/API/mvk_datatypes.h b/MoltenVK/MoltenVK/API/mvk_datatypes.h
index 08b42b4..186a459 100644
--- a/MoltenVK/MoltenVK/API/mvk_datatypes.h
+++ b/MoltenVK/MoltenVK/API/mvk_datatypes.h
@@ -286,13 +286,10 @@
#pragma mark Samplers
-/**
- * Returns the Metal MTLSamplerAddressMode corresponding to the specified Vulkan VkSamplerAddressMode,
- * or returns MTLSamplerAddressModeMirrorClampToEdge if no corresponding MTLSamplerAddressMode exists.
- */
+/** Returns the Metal MTLSamplerAddressMode corresponding to the specified Vulkan VkSamplerAddressMode. */
MTLSamplerAddressMode mvkMTLSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode vkMode);
-#if MVK_MACOS_OR_IOS
+#if MVK_MACOS_OR_IOS
/**
* Returns the Metal MTLSamplerBorderColor corresponding to the specified Vulkan VkBorderColor,
* or returns MTLSamplerBorderColorTransparentBlack if no corresponding MTLSamplerBorderColor exists.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
index d8dd620..ff719db 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -695,7 +695,6 @@
/** Returns the number of planes if this is a ycbcr conversion or 0 otherwise. */
inline uint8_t getPlaneCount() { return (_ycbcrConversion) ? _ycbcrConversion->getPlaneCount() : 0; }
-
/**
* 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.
@@ -705,6 +704,9 @@
/** Returns whether this sampler must be implemented as a hardcoded constant sampler in the shader MSL code. */
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() override;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 435d78e..b5a503b 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -1909,16 +1909,29 @@
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.
// It is the caller's responsibility to release the returned descriptor object.
MTLSamplerDescriptor* MVKSampler::newMTLSamplerDescriptor(const VkSamplerCreateInfo* pCreateInfo) {
MTLSamplerDescriptor* mtlSampDesc = [MTLSamplerDescriptor new]; // retained
- mtlSampDesc.sAddressMode = mvkMTLSamplerAddressModeFromVkSamplerAddressMode(pCreateInfo->addressModeU);
- mtlSampDesc.tAddressMode = mvkMTLSamplerAddressModeFromVkSamplerAddressMode(pCreateInfo->addressModeV);
+ mtlSampDesc.sAddressMode = getMTLSamplerAddressMode(pCreateInfo->addressModeU);
+ mtlSampDesc.tAddressMode = getMTLSamplerAddressMode(pCreateInfo->addressModeV);
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.magFilter = mvkMTLSamplerMinMagFilterFromVkFilter(pCreateInfo->magFilter);
mtlSampDesc.mipFilter = (pCreateInfo->unnormalizedCoordinates
@@ -1940,20 +1953,6 @@
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;
}
diff --git a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
index e68c4a6..9953aa2 100644
--- a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
+++ b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
@@ -282,12 +282,12 @@
switch (vkMode) {
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_BORDER: return MTLSamplerAddressModeClampToZero;
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_CLAMP_TO_BORDER: return MTLSamplerAddressModeClampToBorderColor;
#endif
- default: return MTLSamplerAddressModeClampToZero;
+ default: return MTLSamplerAddressModeClampToZero;
}
}