Merge pull request #143 from hanton/master

Separate categories from MVKOSExtensions
diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
index 120f26b..827c3d6 100644
--- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
+++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
@@ -7,6 +7,12 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		4044125A2090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = 404412582090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.h */; };
+		4044125B2090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = 404412592090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.m */; };
+		404412612090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = 4044125F2090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.h */; };
+		404412622090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = 404412602090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.m */; };
+		404412652090BB1600715344 /* CAMetalLayer+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = 404412632090BB1600715344 /* CAMetalLayer+MoltenVK.h */; };
+		404412662090BB1600715344 /* CAMetalLayer+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = 404412642090BB1600715344 /* CAMetalLayer+MoltenVK.m */; };
 		A9096E5E1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
 		A9096E5F1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
 		A90C8DEA1F45354D009CB32C /* MVKCommandEncodingPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A90C8DE81F45354D009CB32C /* MVKCommandEncodingPool.h */; };
@@ -228,6 +234,12 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		404412582090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MTLTextureDescriptor+MoltenVK.h"; sourceTree = "<group>"; };
+		404412592090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MTLTextureDescriptor+MoltenVK.m"; sourceTree = "<group>"; };
+		4044125F2090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MTLSamplerDescriptor+MoltenVK.h"; sourceTree = "<group>"; };
+		404412602090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MTLSamplerDescriptor+MoltenVK.m"; sourceTree = "<group>"; };
+		404412632090BB1600715344 /* CAMetalLayer+MoltenVK.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CAMetalLayer+MoltenVK.h"; sourceTree = "<group>"; };
+		404412642090BB1600715344 /* CAMetalLayer+MoltenVK.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CAMetalLayer+MoltenVK.m"; sourceTree = "<group>"; };
 		A9096E5C1F81E16300DFBEA6 /* MVKCmdDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKCmdDispatch.h; sourceTree = "<group>"; };
 		A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdDispatch.mm; sourceTree = "<group>"; };
 		A90C8DE81F45354D009CB32C /* MVKCommandEncodingPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCommandEncodingPool.h; sourceTree = "<group>"; };
@@ -465,6 +477,12 @@
 				A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */,
 				A98149471FB6A3F7005F00B4 /* MVKOSExtensions.h */,
 				A98149481FB6A3F7005F00B4 /* MVKOSExtensions.mm */,
+				404412582090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.h */,
+				404412592090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.m */,
+				4044125F2090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.h */,
+				404412602090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.m */,
+				404412632090BB1600715344 /* CAMetalLayer+MoltenVK.h */,
+				404412642090BB1600715344 /* CAMetalLayer+MoltenVK.m */,
 				A98149491FB6A3F7005F00B4 /* MVKWatermark.h */,
 				A981494A1FB6A3F7005F00B4 /* MVKWatermark.mm */,
 				A981494B1FB6A3F7005F00B4 /* MVKWatermarkShaderSource.h */,
@@ -544,6 +562,7 @@
 				A94FB7D81C7DFB4800632CA3 /* MVKCommandPipelineStateFactoryShaderSource.h in Headers */,
 				A94FB7E01C7DFB4800632CA3 /* MVKDescriptorSet.h in Headers */,
 				A94FB8041C7DFB4800632CA3 /* MVKRenderPass.h in Headers */,
+				404412652090BB1600715344 /* CAMetalLayer+MoltenVK.h in Headers */,
 				A9F042A61FB4CF83009FCCB8 /* MVKLogging.h in Headers */,
 				A94FB8001C7DFB4800632CA3 /* MVKQueue.h in Headers */,
 				A94FB7EC1C7DFB4800632CA3 /* MVKFramebuffer.h in Headers */,
@@ -571,10 +590,12 @@
 				A98149631FB6A3F7005F00B4 /* MVKWatermarkTextureContent.h in Headers */,
 				A98149531FB6A3F7005F00B4 /* MVKFoundation.h in Headers */,
 				A94FB7E81C7DFB4800632CA3 /* MVKDeviceMemory.h in Headers */,
+				404412612090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.h in Headers */,
 				A98149591FB6A3F7005F00B4 /* MVKOSExtensions.h in Headers */,
 				A9E4B7891E1D8AF10046A4CE /* MVKMTLResourceBindings.h in Headers */,
 				A90C8DEA1F45354D009CB32C /* MVKCommandEncodingPool.h in Headers */,
 				A94FB8081C7DFB4800632CA3 /* MVKResource.h in Headers */,
+				4044125A2090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.h in Headers */,
 				A981496B1FB6A998005F00B4 /* MVKStrings.h in Headers */,
 				A94FB81C1C7DFB4800632CA3 /* MVKLayers.h in Headers */,
 			);
@@ -798,11 +819,13 @@
 				A94FB8321C7DFB4800632CA3 /* vulkan.mm in Sources */,
 				A94FB8121C7DFB4800632CA3 /* MVKSurface.mm in Sources */,
 				A94FB7FE1C7DFB4800632CA3 /* MVKQueryPool.mm in Sources */,
+				404412662090BB1600715344 /* CAMetalLayer+MoltenVK.m in Sources */,
 				A94FB7F61C7DFB4800632CA3 /* MVKInstance.mm in Sources */,
 				A94FB7EA1C7DFB4800632CA3 /* MVKDeviceMemory.mm in Sources */,
 				A94FB7F21C7DFB4800632CA3 /* MVKImage.mm in Sources */,
 				A94FB7D61C7DFB4800632CA3 /* MVKCommandPool.mm in Sources */,
 				A94FB7CA1C7DFB4800632CA3 /* MVKCmdDraw.mm in Sources */,
+				404412622090BAB500715344 /* MTLSamplerDescriptor+MoltenVK.m in Sources */,
 				A94FB7D21C7DFB4800632CA3 /* MVKCommandBuffer.mm in Sources */,
 				A94FB7C61C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */,
 				A94FB7DE1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
@@ -825,6 +848,7 @@
 				A94FB7EE1C7DFB4800632CA3 /* MVKFramebuffer.mm in Sources */,
 				A9C96DD21DDC20C20053187F /* MVKMTLBufferAllocation.mm in Sources */,
 				A981495B1FB6A3F7005F00B4 /* MVKOSExtensions.mm in Sources */,
+				4044125B2090BA4F00715344 /* MTLTextureDescriptor+MoltenVK.m in Sources */,
 				A9096E5E1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index 1145240..e551339 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -35,6 +35,7 @@
 #include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
 #include "mvk_datatypes.h"
 #include "vk_mvk_moltenvk.h"
+#import "CAMetalLayer+MoltenVK.h"
 
 using namespace std;
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 2a2d046..f215c14 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -19,10 +19,11 @@
 #include "MVKImage.h"
 #include "MVKSwapchain.h"
 #include "MVKCommandBuffer.h"
-#include "MVKOSExtensions.h"
 #include "mvk_datatypes.h"
 #include "MVKFoundation.h"
 #include "MVKLogging.h"
+#import "MTLTextureDescriptor+MoltenVK.h"
+#import "MTLSamplerDescriptor+MoltenVK.h"
 
 using namespace std;
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
index 8f4380b..a7cb99f 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
@@ -26,6 +26,7 @@
 #include "MVKWatermarkShaderSource.h"
 #include "mvk_datatypes.h"
 #include "MVKLogging.h"
+#import "CAMetalLayer+MoltenVK.h"
 
 using namespace std;
 
diff --git a/MoltenVK/MoltenVK/Utility/CAMetalLayer+MoltenVK.h b/MoltenVK/MoltenVK/Utility/CAMetalLayer+MoltenVK.h
new file mode 100644
index 0000000..a56fee1
--- /dev/null
+++ b/MoltenVK/MoltenVK/Utility/CAMetalLayer+MoltenVK.h
@@ -0,0 +1,39 @@
+/*
+ * CAMetalLayer+MoltenVK.h
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#import <QuartzCore/QuartzCore.h>
+
+/** Extensions to CAMetalLayer to support MoltenVK. */
+@interface CAMetalLayer (MoltenVK)
+
+/**
+ * Ensures the drawableSize property of this layer is up to date, by combining the size
+ * of the bounds property and the contentScale property, and returns the updated value.
+ */
+-(CGSize) updatedDrawableSizeMVK;
+
+/**
+ * Replacement for the displaySyncEnabled property.
+ *
+ * This property allows support under all OS versions. Delegates to the displaySyncEnabled
+ * property if it is available. otherwise, returns YES when read and does nothing when set.
+ */
+@property(nonatomic, readwrite) BOOL displaySyncEnabledMVK;
+
+@end
diff --git a/MoltenVK/MoltenVK/Utility/CAMetalLayer+MoltenVK.m b/MoltenVK/MoltenVK/Utility/CAMetalLayer+MoltenVK.m
new file mode 100644
index 0000000..14a0282
--- /dev/null
+++ b/MoltenVK/MoltenVK/Utility/CAMetalLayer+MoltenVK.m
@@ -0,0 +1,52 @@
+/*
+ * CAMetalLayer+MoltenVK.m
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#import "CAMetalLayer+MoltenVK.h"
+
+@implementation CAMetalLayer (MoltenVK)
+
+-(CGSize) updatedDrawableSizeMVK {
+    CGSize drawSize = self.bounds.size;
+    CGFloat scaleFactor = self.contentsScale;
+    drawSize.width = trunc(drawSize.width * scaleFactor);
+    drawSize.height = trunc(drawSize.height * scaleFactor);
+    
+    // Only update property value if it needs to be, in case
+    // updating to same value causes internal reconfigurations.
+    if ( !CGSizeEqualToSize(drawSize, self.drawableSize) ) {
+        self.drawableSize = drawSize;
+    }
+    
+    return drawSize;
+}
+
+-(BOOL) displaySyncEnabledMVK {
+#if MVK_MACOS
+    if ( [self respondsToSelector: @selector(displaySyncEnabled)]) { return self.displaySyncEnabled; }
+#endif
+    return YES;
+}
+
+-(void) setDisplaySyncEnabledMVK: (BOOL) enabled {
+#if MVK_MACOS
+    if ( [self respondsToSelector: @selector(setDisplaySyncEnabled:)]) { self.displaySyncEnabled = enabled; }
+#endif
+}
+
+@end
diff --git a/MoltenVK/MoltenVK/Utility/MTLSamplerDescriptor+MoltenVK.h b/MoltenVK/MoltenVK/Utility/MTLSamplerDescriptor+MoltenVK.h
new file mode 100644
index 0000000..be20245
--- /dev/null
+++ b/MoltenVK/MoltenVK/Utility/MTLSamplerDescriptor+MoltenVK.h
@@ -0,0 +1,34 @@
+/*
+ * MTLSamplerDescriptor+MoltenVK.h
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#import <Metal/Metal.h>
+
+/** Extensions to MTLSamplerDescriptor to support MoltenVK. */
+@interface MTLSamplerDescriptor (MoltenVK)
+
+/**
+ * Replacement for the compareFunction property.
+ *
+ * This property allows support under all OS versions. Delegates to the compareFunction
+ * property if it is available. otherwise, returns MTLTextureUsageUnknown when read and
+ * does nothing when set.
+ */
+@property(nonatomic, readwrite) MTLCompareFunction compareFunctionMVK;
+
+@end
diff --git a/MoltenVK/MoltenVK/Utility/MTLSamplerDescriptor+MoltenVK.m b/MoltenVK/MoltenVK/Utility/MTLSamplerDescriptor+MoltenVK.m
new file mode 100644
index 0000000..71b2680
--- /dev/null
+++ b/MoltenVK/MoltenVK/Utility/MTLSamplerDescriptor+MoltenVK.m
@@ -0,0 +1,42 @@
+/*
+ * MTLSamplerDescriptor+MoltenVK.m
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#import "MTLSamplerDescriptor+MoltenVK.h"
+
+@implementation MTLTextureDescriptor (MoltenVK)
+
+-(MTLTextureUsage) usageMVK {
+    if ( [self respondsToSelector: @selector(usage)]) { return self.usage; }
+    return MTLTextureUsageUnknown;
+}
+
+-(void) setUsageMVK: (MTLTextureUsage) usage {
+    if ( [self respondsToSelector: @selector(setUsage:)]) { self.usage = usage; }
+}
+
+-(MTLStorageMode) storageModeMVK {
+    if ( [self respondsToSelector: @selector(storageMode)]) { return self.storageMode; }
+    return MTLStorageModeShared;
+}
+
+-(void) setStorageModeMVK: (MTLStorageMode) storageMode {
+    if ( [self respondsToSelector: @selector(setStorageMode:)]) { self.storageMode = storageMode; }
+}
+
+@end
diff --git a/MoltenVK/MoltenVK/Utility/MTLTextureDescriptor+MoltenVK.h b/MoltenVK/MoltenVK/Utility/MTLTextureDescriptor+MoltenVK.h
new file mode 100644
index 0000000..3dd7e0a
--- /dev/null
+++ b/MoltenVK/MoltenVK/Utility/MTLTextureDescriptor+MoltenVK.h
@@ -0,0 +1,42 @@
+/*
+ * MTLTextureDescriptor+MoltenVK.h
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#import <Metal/Metal.h>
+
+/** Extensions to MTLTextureDescriptor to support MoltenVK. */
+@interface MTLTextureDescriptor (MoltenVK)
+
+/**
+ * Replacement for the usage property.
+ *
+ * This property allows support under all OS versions. Delegates to the usage property if it
+ * is available. otherwise, returns MTLTextureUsageUnknown when read and does nothing when set.
+ */
+@property(nonatomic, readwrite) MTLTextureUsage usageMVK;
+
+/**
+ * Replacement for the storageMode property.
+ *
+ * This property allows support under all OS versions. Delegates to the storageMode
+ * property if it is available. otherwise, returns MTLStorageModeShared when read
+ * and does nothing when set.
+ */
+@property(nonatomic, readwrite) MTLStorageMode storageModeMVK;
+
+@end
diff --git a/MoltenVK/MoltenVK/Utility/MTLTextureDescriptor+MoltenVK.m b/MoltenVK/MoltenVK/Utility/MTLTextureDescriptor+MoltenVK.m
new file mode 100644
index 0000000..4ca501b
--- /dev/null
+++ b/MoltenVK/MoltenVK/Utility/MTLTextureDescriptor+MoltenVK.m
@@ -0,0 +1,33 @@
+/*
+ * MTLTextureDescriptor+MoltenVK.m
+ *
+ * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#import "MTLTextureDescriptor+MoltenVK.h"
+
+@implementation MTLSamplerDescriptor (MoltenVK)
+
+-(MTLCompareFunction) compareFunctionMVK {
+    if ( [self respondsToSelector: @selector(compareFunction)]) { return self.compareFunction; }
+    return MTLCompareFunctionNever;
+}
+
+-(void) setCompareFunctionMVK: (MTLCompareFunction) cmpFunc {
+    if ( [self respondsToSelector: @selector(setCompareFunction:)]) { self.compareFunction = cmpFunc; }
+}
+
+@end
diff --git a/MoltenVK/MoltenVK/Utility/MVKOSExtensions.h b/MoltenVK/MoltenVK/Utility/MVKOSExtensions.h
index 3da0641..16217c1 100644
--- a/MoltenVK/MoltenVK/Utility/MVKOSExtensions.h
+++ b/MoltenVK/MoltenVK/Utility/MVKOSExtensions.h
@@ -25,7 +25,6 @@
 #include <vulkan/vulkan.h>
 
 #import <Metal/Metal.h>
-#import <QuartzCore/CAMetalLayer.h>
 
 
 typedef float MVKOSVersion;
@@ -64,73 +63,6 @@
 
 
 #pragma mark -
-#pragma mark MTLTextureDescriptor
-
-/** Extensions to MTLTextureDescriptor to support MoltenVK. */
-@interface MTLTextureDescriptor (MoltenVK)
-
-/** 
- * Replacement for the usage property.
- *
- * This property allows support under all OS versions. Delegates to the usage property if it
- * is available. otherwise, returns MTLTextureUsageUnknown when read and does nothing when set.
- */
-@property(nonatomic, readwrite) MTLTextureUsage usageMVK;
-
-/**
- * Replacement for the storageMode property.
- *
- * This property allows support under all OS versions. Delegates to the storageMode
- * property if it is available. otherwise, returns MTLStorageModeShared when read
- * and does nothing when set.
- */
-@property(nonatomic, readwrite) MTLStorageMode storageModeMVK;
-
-@end
-
-
-#pragma mark -
-#pragma mark MTLSamplerDescriptor
-
-/** Extensions to MTLSamplerDescriptor to support MoltenVK. */
-@interface MTLSamplerDescriptor (MoltenVK)
-
-/**
- * Replacement for the compareFunction property.
- *
- * This property allows support under all OS versions. Delegates to the compareFunction
- * property if it is available. otherwise, returns MTLTextureUsageUnknown when read and
- * does nothing when set.
- */
-@property(nonatomic, readwrite) MTLCompareFunction compareFunctionMVK;
-
-@end
-
-
-#pragma mark -
-#pragma mark CAMetalLayer
-
-/** Extensions to CAMetalLayer to support MoltenVK. */
-@interface CAMetalLayer (MoltenVK)
-
-/**
- * Ensures the drawableSize property of this layer is up to date, by combining the size
- * of the bounds property and the contentScale property, and returns the updated value.
- */
--(CGSize) updatedDrawableSizeMVK;
-
-/**
- * Replacement for the displaySyncEnabled property.
- *
- * This property allows support under all OS versions. Delegates to the displaySyncEnabled
- * property if it is available. otherwise, returns YES when read and does nothing when set.
- */
-@property(nonatomic, readwrite) BOOL displaySyncEnabledMVK;
-
-@end
-
-
-#pragma mark -
 #pragma mark MTLDevice
 
 /** Returns an approximation of how much memory, in bytes, the device can use with good performance. */
diff --git a/MoltenVK/MoltenVK/Utility/MVKOSExtensions.mm b/MoltenVK/MoltenVK/Utility/MVKOSExtensions.mm
index 5beaae7..4e88f3f 100644
--- a/MoltenVK/MoltenVK/Utility/MVKOSExtensions.mm
+++ b/MoltenVK/MoltenVK/Utility/MVKOSExtensions.mm
@@ -83,85 +83,6 @@
 
 
 #pragma mark -
-#pragma mark MTLTextureDescriptor
-
-@implementation MTLTextureDescriptor (MoltenVK)
-
--(MTLTextureUsage) usageMVK {
-	if ( [self respondsToSelector: @selector(usage)]) { return self.usage; }
-	return MTLTextureUsageUnknown;
-}
-
--(void) setUsageMVK: (MTLTextureUsage) usage {
-	if ( [self respondsToSelector: @selector(setUsage:)]) { self.usage = usage; }
-}
-
--(MTLStorageMode) storageModeMVK {
-	if ( [self respondsToSelector: @selector(storageMode)]) { return self.storageMode; }
-	return MTLStorageModeShared;
-}
-
--(void) setStorageModeMVK: (MTLStorageMode) storageMode {
-	if ( [self respondsToSelector: @selector(setStorageMode:)]) { self.storageMode = storageMode; }
-}
-
-@end
-
-
-#pragma mark -
-#pragma mark MTLSamplerDescriptor
-
-@implementation MTLSamplerDescriptor (MoltenVK)
-
--(MTLCompareFunction) compareFunctionMVK {
-	if ( [self respondsToSelector: @selector(compareFunction)]) { return self.compareFunction; }
-	return MTLCompareFunctionNever;
-}
-
--(void) setCompareFunctionMVK: (MTLCompareFunction) cmpFunc {
-	if ( [self respondsToSelector: @selector(setCompareFunction:)]) { self.compareFunction = cmpFunc; }
-}
-
-@end
-
-
-#pragma mark -
-#pragma mark CAMetalLayer
-
-@implementation CAMetalLayer (MoltenVK)
-
--(CGSize) updatedDrawableSizeMVK {
-    CGSize drawSize = self.bounds.size;
-    CGFloat scaleFactor = self.contentsScale;
-    drawSize.width = trunc(drawSize.width * scaleFactor);
-    drawSize.height = trunc(drawSize.height * scaleFactor);
-
-    // Only update property value if it needs to be, in case
-    // updating to same value causes internal reconfigurations.
-    if ( !CGSizeEqualToSize(drawSize, self.drawableSize) ) {
-        self.drawableSize = drawSize;
-    }
-
-    return drawSize;
-}
-
--(BOOL) displaySyncEnabledMVK {
-#if MVK_MACOS
-	if ( [self respondsToSelector: @selector(displaySyncEnabled)]) { return self.displaySyncEnabled; }
-#endif
-	return YES;
-}
-
--(void) setDisplaySyncEnabledMVK: (BOOL) enabled {
-#if MVK_MACOS
-	if ( [self respondsToSelector: @selector(setDisplaySyncEnabled:)]) { self.displaySyncEnabled = enabled; }
-#endif
-}
-
-@end
-
-
-#pragma mark -
 #pragma mark MTLDevice
 
 uint64_t mvkRecommendedMaxWorkingSetSize(id<MTLDevice> mtlDevice) {
diff --git a/MoltenVK/MoltenVK/Utility/MVKWatermark.mm b/MoltenVK/MoltenVK/Utility/MVKWatermark.mm
index 21b5f5f..aa13be2 100644
--- a/MoltenVK/MoltenVK/Utility/MVKWatermark.mm
+++ b/MoltenVK/MoltenVK/Utility/MVKWatermark.mm
@@ -20,6 +20,7 @@
 #include "MVKWatermark.h"
 #include "MVKOSExtensions.h"
 #include "MVKLogging.h"
+#include "MTLTextureDescriptor+MoltenVK.h"
 
 
 /** The structure to hold shader uniforms. */