Disable use of MTLHeap by default.

Add MVK_CONFIG_USE_MTLHEAP environment variable to enable use of MTLHeap if needed.
Minor fixes to consistent use of MVK_SET_FROM_ENV_OR_BUILD_BOOL().
diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
index 321eea6..8302b2e 100644
--- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
+++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
@@ -503,8 +503,6 @@
 				A94FB7841C7DFB4800632CA3 /* MVKDevice.mm */,
 				A94FB7851C7DFB4800632CA3 /* MVKDeviceMemory.h */,
 				A94FB7861C7DFB4800632CA3 /* MVKDeviceMemory.mm */,
-				A9653FB724129C84005999D7 /* MVKPixelFormats.h */,
-				A9653FB924129C84005999D7 /* MVKPixelFormats.mm */,
 				A94FB7871C7DFB4800632CA3 /* MVKFramebuffer.h */,
 				A94FB7881C7DFB4800632CA3 /* MVKFramebuffer.mm */,
 				A94FB7891C7DFB4800632CA3 /* MVKImage.h */,
@@ -513,6 +511,8 @@
 				A94FB78C1C7DFB4800632CA3 /* MVKInstance.mm */,
 				A94FB78D1C7DFB4800632CA3 /* MVKPipeline.h */,
 				A94FB78E1C7DFB4800632CA3 /* MVKPipeline.mm */,
+				A9653FB724129C84005999D7 /* MVKPixelFormats.h */,
+				A9653FB924129C84005999D7 /* MVKPixelFormats.mm */,
 				A94FB78F1C7DFB4800632CA3 /* MVKQueryPool.h */,
 				A94FB7901C7DFB4800632CA3 /* MVKQueryPool.mm */,
 				A94FB7911C7DFB4800632CA3 /* MVKQueue.h */,
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index a988a15..95056cb 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -163,6 +163,18 @@
  *    a command is executed. This is a classic time-space trade off. When command pooling is
  *    active, the memory in the pool can be cleared via a call to the vkTrimCommandPoolKHR()
  *    command. This setting is enabled by default, and MoltenVK will pool command memory.
+ *
+ * 9. The MVK_CONFIG_USE_MTLHEAP runtime environment variable or MoltenVK compile-time build
+ *    setting controls whether MoltenVK should use MTLHeaps for allocating textures and buffers
+ *    from device memory. If this environment variable is enabled, and placement MTLHeaps are
+ *    available on the platform, MoltenVK will allocate a placement MTLHeap for each VkDeviceMemory
+ *    instance, and allocate textures and buffers from that placement heap. If this environment
+ *    variable is disabled, MoltenVK will allocate textures and buffers from general device memory.
+ *    Apple recommends that MTLHeaps should only be used for specific requirements such as aliasing
+ *    or hazard tracking, and MoltenVK testing has shown that allocating multiple textures of
+ *    different types or usages from one MTLHeap can occassionally cause corruption issues under
+ *    certain circumstances. Because of this, this setting is disabled by default, and MoltenVK
+ *    will allocate texures and buffers from general device memory.
  */
 typedef struct {
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index b49b4f1..d093636 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -773,7 +773,15 @@
 
 // Initializes the Metal-specific physical device features of this instance.
 void MVKPhysicalDevice::initMetalFeatures() {
-	mvkClear(&_metalFeatures);	// Start with everything cleared
+
+#	ifndef MVK_CONFIG_USE_MTLHEAP
+#   	define MVK_CONFIG_USE_MTLHEAP    0
+#	endif
+	bool useMTLHeaps;
+	MVK_SET_FROM_ENV_OR_BUILD_BOOL(useMTLHeaps, MVK_CONFIG_USE_MTLHEAP);
+
+	// Start with all Metal features cleared
+	mvkClear(&_metalFeatures);
 
 	_metalFeatures.maxPerStageBufferCount = 31;
     _metalFeatures.maxMTLBufferSize = (256 * MEBI);
@@ -848,7 +856,7 @@
 
 	if ( mvkOSVersionIsAtLeast(13.0) ) {
 		_metalFeatures.mslVersionEnum = MTLLanguageVersion2_2;
-		_metalFeatures.placementHeaps = true;
+		_metalFeatures.placementHeaps = useMTLHeaps;
 		if (supportsMTLGPUFamily(Apple4)) {
 			_metalFeatures.nativeTextureSwizzle = true;
 		}
@@ -904,7 +912,7 @@
 		_metalFeatures.native3DCompressedTextures = true;
 		if (supportsMTLGPUFamily(Mac2)) {
 			_metalFeatures.nativeTextureSwizzle = true;
-			_metalFeatures.placementHeaps = true;
+			_metalFeatures.placementHeaps = useMTLHeaps;
 		}
 	}
 
@@ -957,7 +965,6 @@
 			break;
 #endif
 	}
-
 }
 
 // Initializes the physical device features of this instance.
@@ -2656,10 +2663,9 @@
 	}
 	MVKLogInfo("Using %s for Vulkan semaphores.", _useMTLFenceForSemaphores ? "MTLFence" : (_useMTLEventForSemaphores ? "MTLEvent" : "emulation"));
 
-#ifndef MVK_CONFIG_USE_COMMAND_POOLING
-#   define MVK_CONFIG_USE_COMMAND_POOLING    1
-#endif
-	_useCommandPooling = MVK_CONFIG_USE_COMMAND_POOLING;
+#	ifndef MVK_CONFIG_USE_COMMAND_POOLING
+#   	define MVK_CONFIG_USE_COMMAND_POOLING    1
+#	endif
 	MVK_SET_FROM_ENV_OR_BUILD_BOOL(_useCommandPooling, MVK_CONFIG_USE_COMMAND_POOLING);
 
 #if MVK_MACOS
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
index 6f7bc0c..c231f2e 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
@@ -289,7 +289,7 @@
 #if MVK_MACOS
 	NSArray* rawMTLDevs = [MTLCopyAllDevices() autorelease];
 	if (rawMTLDevs) {
-		bool forceLowPower = MVK_CONFIG_FORCE_LOW_POWER_GPU;
+		bool forceLowPower;
 		MVK_SET_FROM_ENV_OR_BUILD_BOOL(forceLowPower, MVK_CONFIG_FORCE_LOW_POWER_GPU);
 
 		// Populate the array of appropriate MTLDevices