Fix issue of reseting CAMetalDrawable and MTLTexture of peer swapchain images.

Add MVKPresentableSwapchainImage and MVKPeerSwapchainImage subclasses to
MVKSwapchainImage, with MVKPresentableSwapchainImage instances created inside
swapchain, and MVKPeerSwapchainImage instances created using vkCreateImage().
MVKPeerSwapchainImage retrieve and share CAMetalDrawable from corresponding
MVKPresentableSwapchainImage.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index c50838c..92649bc 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -32,6 +32,7 @@
 - Fix issue causing screen captures from swapchain image to deadlock.
 - Fix memory estimates for iOS 13+.
 - Broaden conditions for host read sync for image memory barriers on macOS.
+- Fix issue of reseting `CAMetalDrawable` and `MTLTexture` of peer swapchain images.
 - Fix the `make install` build command to overwrite the existing framework in the system
   framework library, and update `README.md` to clarify the instructions for using `make install`. 
 - Update the `README.md` and `MoltenVK_Runtime_UserGuide.md` documents to clarify that 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
index 95bbad2..d177101 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
@@ -42,7 +42,7 @@
 class MVKBuffer;
 class MVKBufferView;
 class MVKImage;
-class MVKSwapchainImage;
+class MVKPresentableSwapchainImage;
 class MVKImageView;
 class MVKSwapchain;
 class MVKDeviceMemory;
@@ -450,12 +450,12 @@
 	void destroySwapchain(MVKSwapchain* mvkSwpChn,
 						  const VkAllocationCallbacks* pAllocator);
 
-	MVKSwapchainImage* createSwapchainImage(const VkImageCreateInfo* pCreateInfo,
-											MVKSwapchain* swapchain,
-											uint32_t swapchainIndex,
-											const VkAllocationCallbacks* pAllocator);
-	void destroySwapchainImage(MVKSwapchainImage* mvkImg,
-							   const VkAllocationCallbacks* pAllocator);
+	MVKPresentableSwapchainImage* createPresentableSwapchainImage(const VkImageCreateInfo* pCreateInfo,
+																  MVKSwapchain* swapchain,
+																  uint32_t swapchainIndex,
+																  const VkAllocationCallbacks* pAllocator);
+	void destroyPresentableSwapchainImage(MVKPresentableSwapchainImage* mvkImg,
+										  const VkAllocationCallbacks* pAllocator);
 
 	MVKFence* createFence(const VkFenceCreateInfo* pCreateInfo,
 						  const VkAllocationCallbacks* pAllocator);
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index d093636..c9781fd 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -2138,7 +2138,7 @@
 		}
 	}
 	if (swapchainInfo) {
-		return createSwapchainImage(pCreateInfo, (MVKSwapchain*)swapchainInfo->swapchain, uint32_t(-1), pAllocator);
+		return (MVKImage*)addResource(new MVKPeerSwapchainImage(this, pCreateInfo, (MVKSwapchain*)swapchainInfo->swapchain, uint32_t(-1)));
 	}
 	return (MVKImage*)addResource(new MVKImage(this, pCreateInfo));
 }
@@ -2169,15 +2169,15 @@
 	mvkSwpChn->destroy();
 }
 
-MVKSwapchainImage* MVKDevice::createSwapchainImage(const VkImageCreateInfo* pCreateInfo,
-												   MVKSwapchain* swapchain,
-												   uint32_t swapchainIndex,
-												   const VkAllocationCallbacks* pAllocator) {
-	return (MVKSwapchainImage*)addResource(new MVKSwapchainImage(this, pCreateInfo, swapchain, swapchainIndex));
+MVKPresentableSwapchainImage* MVKDevice::createPresentableSwapchainImage(const VkImageCreateInfo* pCreateInfo,
+																		 MVKSwapchain* swapchain,
+																		 uint32_t swapchainIndex,
+																		 const VkAllocationCallbacks* pAllocator) {
+	return (MVKPresentableSwapchainImage*)addResource(new MVKPresentableSwapchainImage(this, pCreateInfo, swapchain, swapchainIndex));
 }
 
-void MVKDevice::destroySwapchainImage(MVKSwapchainImage* mvkImg,
-									  const VkAllocationCallbacks* pAllocator) {
+void MVKDevice::destroyPresentableSwapchainImage(MVKPresentableSwapchainImage* mvkImg,
+												 const VkAllocationCallbacks* pAllocator) {
 	removeResource(mvkImg);
 	mvkImg->destroy();
 }
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
index c44f478..89e5af0 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -274,6 +274,41 @@
 #pragma mark -
 #pragma mark MVKSwapchainImage
 
+/** Abstract class of Vulkan image used as a rendering destination within a swapchain. */
+class MVKSwapchainImage : public MVKImage {
+
+public:
+
+	/** Binds this resource to the specified offset within the specified memory allocation. */
+	VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) override;
+
+#pragma mark Metal
+
+	/** Returns the Metal texture used by the CAMetalDrawable underlying this image. */
+	id<MTLTexture> getMTLTexture() override;
+
+
+#pragma mark Construction
+
+	/** Constructs an instance for the specified device and swapchain. */
+	MVKSwapchainImage(MVKDevice* device,
+					  const VkImageCreateInfo* pCreateInfo,
+					  MVKSwapchain* swapchain,
+					  uint32_t swapchainIndex);
+
+protected:
+	friend class MVKPeerSwapchainImage;
+
+	virtual id<CAMetalDrawable> getCAMetalDrawable() = 0;
+
+	MVKSwapchain* _swapchain;
+	uint32_t _swapchainIndex;
+};
+
+
+#pragma mark -
+#pragma mark MVKPresentableSwapchainImage
+
 /** Indicates the relative availability of each image in the swapchain. */
 typedef struct MVKSwapchainImageAvailability {
 	uint64_t acquisitionID;			/**< When this image was last made available, relative to the other images in the swapchain. Smaller value is earlier. */
@@ -286,23 +321,13 @@
 typedef std::pair<MVKSemaphore*, MVKFence*> MVKSwapchainSignaler;
 
 
-/** Represents a Vulkan image used as a rendering destination within a swapchain. */
-class MVKSwapchainImage : public MVKImage {
+/** Represents a Vulkan swapchain image that can be submitted to the presentation engine. */
+class MVKPresentableSwapchainImage : public MVKSwapchainImage {
 
 public:
 
-	/** Binds this resource to the specified offset within the specified memory allocation. */
-	VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) override;
-
-	/** Binds this resource according to the specified bind information. */
-	VkResult bindDeviceMemory2(const void* pBindInfo) override;
-
-
 #pragma mark Metal
 
-	/** Returns the Metal texture used by the CAMetalDrawable underlying this image. */
-	id<MTLTexture> getMTLTexture() override;
-
 	/**
 	 * Presents the contained drawable to the OS, releases the Metal drawable and its
 	 * texture back to the Metal layer's pool, and makes the image memory available for new use.
@@ -317,17 +342,17 @@
 #pragma mark Construction
 
 	/** Constructs an instance for the specified device and swapchain. */
-	MVKSwapchainImage(MVKDevice* device,
-					  const VkImageCreateInfo* pCreateInfo,
-					  MVKSwapchain* swapchain,
-					  uint32_t swapchainIndex);
+	MVKPresentableSwapchainImage(MVKDevice* device,
+								 const VkImageCreateInfo* pCreateInfo,
+								 MVKSwapchain* swapchain,
+								 uint32_t swapchainIndex);
 
-	~MVKSwapchainImage() override;
+	~MVKPresentableSwapchainImage() override;
 
 protected:
 	friend MVKSwapchain;
 
-	id<CAMetalDrawable> getCAMetalDrawable();
+	id<CAMetalDrawable> getCAMetalDrawable() override;
 	void releaseMetalDrawable();
 	MVKSwapchainImageAvailability getAvailability();
 	void makeAvailable();
@@ -338,8 +363,6 @@
 	static void unmarkAsTracked(MVKSwapchainSignaler& signaler);
 	void renderWatermark(id<MTLCommandBuffer> mtlCmdBuff);
 
-	MVKSwapchain* _swapchain;
-	uint32_t _swapchainIndex;
 	id<CAMetalDrawable> _mtlDrawable;
 	MVKSwapchainImageAvailability _availability;
 	MVKVectorInline<MVKSwapchainSignaler, 1> _availabilitySignalers;
@@ -349,6 +372,32 @@
 
 
 #pragma mark -
+#pragma mark MVKPeerSwapchainImage
+
+/** Represents a Vulkan swapchain image that can be associated as a peer to a swapchain image. */
+class MVKPeerSwapchainImage : public MVKSwapchainImage {
+
+public:
+
+	/** Binds this resource according to the specified bind information. */
+	VkResult bindDeviceMemory2(const void* pBindInfo) override;
+
+
+#pragma mark Construction
+
+	/** Constructs an instance for the specified device and swapchain. */
+	MVKPeerSwapchainImage(MVKDevice* device,
+						  const VkImageCreateInfo* pCreateInfo,
+						  MVKSwapchain* swapchain,
+						  uint32_t swapchainIndex);
+
+protected:
+	id<CAMetalDrawable> getCAMetalDrawable() override;
+
+};
+
+
+#pragma mark -
 #pragma mark MVKImageView
 
 /** Represents a Vulkan image view. */
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 65637b5..97c52e7 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -794,37 +794,38 @@
 #pragma mark -
 #pragma mark MVKSwapchainImage
 
+VkResult MVKSwapchainImage::bindDeviceMemory(MVKDeviceMemory*, VkDeviceSize) {
+	return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+}
+
+
+#pragma mark Metal
+
+// Overridden to always retrieve the MTLTexture directly from the CAMetalDrawable.
+id<MTLTexture> MVKSwapchainImage::getMTLTexture() { return [getCAMetalDrawable() texture]; }
+
+
+#pragma mark Construction
+
+MVKSwapchainImage::MVKSwapchainImage(MVKDevice* device,
+									 const VkImageCreateInfo* pCreateInfo,
+									 MVKSwapchain* swapchain,
+									 uint32_t swapchainIndex) : MVKImage(device, pCreateInfo) {
+	_swapchain = swapchain;
+	_swapchainIndex = swapchainIndex;
+}
+
+
+#pragma mark -
+#pragma mark MVKPresentableSwapchainImage
+
 bool MVKSwapchainImageAvailability::operator< (const MVKSwapchainImageAvailability& rhs) const {
 	if (  isAvailable && !rhs.isAvailable) { return true; }
 	if ( !isAvailable &&  rhs.isAvailable) { return false; }
 	return acquisitionID < rhs.acquisitionID;
 }
 
-VkResult MVKSwapchainImage::bindDeviceMemory(MVKDeviceMemory*, VkDeviceSize) {
-	return VK_ERROR_OUT_OF_DEVICE_MEMORY;
-}
-
-VkResult MVKSwapchainImage::bindDeviceMemory2(const void* pBindInfo) {
-	const auto* imageInfo = (const VkBindImageMemoryInfo*)pBindInfo;
-	const VkBindImageMemorySwapchainInfoKHR* swapchainInfo = nullptr;
-	for (const auto* next = (const VkBaseInStructure*)imageInfo->pNext; next; next = next->pNext) {
-		switch (next->sType) {
-			case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR:
-				swapchainInfo = (const VkBindImageMemorySwapchainInfoKHR*)next;
-				break;
-			default:
-				break;
-		}
-		if (swapchainInfo) { break; }
-	}
-	if (!swapchainInfo) {
-		return VK_ERROR_OUT_OF_DEVICE_MEMORY;
-	}
-	_swapchainIndex = swapchainInfo->imageIndex;
-	return VK_SUCCESS;
-}
-
-MVKSwapchainImageAvailability MVKSwapchainImage::getAvailability() {
+MVKSwapchainImageAvailability MVKPresentableSwapchainImage::getAvailability() {
 	lock_guard<mutex> lock(_availabilityLock);
 
 	return _availability;
@@ -833,7 +834,7 @@
 // Makes an image available for acquisition by the app.
 // If any semaphores are waiting to be signaled when this image becomes available, the
 // earliest semaphore is signaled, and this image remains unavailable for other uses.
-void MVKSwapchainImage::makeAvailable() {
+void MVKPresentableSwapchainImage::makeAvailable() {
 	lock_guard<mutex> lock(_availabilityLock);
 
 	// Mark when this event happened, relative to that of other images
@@ -864,7 +865,7 @@
 //	MVKLogDebug("Signaling%s swapchain image %p semaphore %p from present, with %lu remaining semaphores.", (_availability.isAvailable ? " pre-signaled" : ""), this, signaler.first, _availabilitySignalers.size());
 }
 
-void MVKSwapchainImage::acquireAndSignalWhenAvailable(MVKSemaphore* semaphore, MVKFence* fence) {
+void MVKPresentableSwapchainImage::acquireAndSignalWhenAvailable(MVKSemaphore* semaphore, MVKFence* fence) {
 	lock_guard<mutex> lock(_availabilityLock);
 
 	// Now that this image is being acquired, release the existing drawable and its texture.
@@ -897,7 +898,7 @@
 }
 
 // If present, signal the semaphore for the first waiter for the given image.
-void MVKSwapchainImage::signalPresentationSemaphore(id<MTLCommandBuffer> mtlCmdBuff) {
+void MVKPresentableSwapchainImage::signalPresentationSemaphore(id<MTLCommandBuffer> mtlCmdBuff) {
 	lock_guard<mutex> lock(_availabilityLock);
 
 	if ( !_availabilitySignalers.empty() ) {
@@ -907,19 +908,19 @@
 }
 
 // Signal either or both of the semaphore and fence in the specified tracker pair.
-void MVKSwapchainImage::signal(MVKSwapchainSignaler& signaler, id<MTLCommandBuffer> mtlCmdBuff) {
+void MVKPresentableSwapchainImage::signal(MVKSwapchainSignaler& signaler, id<MTLCommandBuffer> mtlCmdBuff) {
 	if (signaler.first) { signaler.first->encodeSignal(mtlCmdBuff); }
 	if (signaler.second) { signaler.second->signal(); }
 }
 
 // Tell the semaphore and fence that they are being tracked for future signaling.
-void MVKSwapchainImage::markAsTracked(MVKSwapchainSignaler& signaler) {
+void MVKPresentableSwapchainImage::markAsTracked(MVKSwapchainSignaler& signaler) {
 	if (signaler.first) { signaler.first->retain(); }
 	if (signaler.second) { signaler.second->retain(); }
 }
 
 // Tell the semaphore and fence that they are no longer being tracked for future signaling.
-void MVKSwapchainImage::unmarkAsTracked(MVKSwapchainSignaler& signaler) {
+void MVKPresentableSwapchainImage::unmarkAsTracked(MVKSwapchainSignaler& signaler) {
 	if (signaler.first) { signaler.first->release(); }
 	if (signaler.second) { signaler.second->release(); }
 }
@@ -927,10 +928,7 @@
 
 #pragma mark Metal
 
-// Overridden to always retrieve the MTLTexture directly from the CAMetalDrawable.
-id<MTLTexture> MVKSwapchainImage::getMTLTexture() { return [getCAMetalDrawable() texture]; }
-
-id<CAMetalDrawable> MVKSwapchainImage::getCAMetalDrawable() {
+id<CAMetalDrawable> MVKPresentableSwapchainImage::getCAMetalDrawable() {
 	while ( !_mtlDrawable ) {
 		@autoreleasepool {      // Reclaim auto-released drawable object before end of loop
 			uint64_t startTime = _device->getPerformanceTimestamp();
@@ -945,7 +943,7 @@
 }
 
 // Present the drawable and make myself available only once the command buffer has completed.
-void MVKSwapchainImage::presentCAMetalDrawable(id<MTLCommandBuffer> mtlCmdBuff) {
+void MVKPresentableSwapchainImage::presentCAMetalDrawable(id<MTLCommandBuffer> mtlCmdBuff) {
 	_swapchain->willPresentSurface(getMTLTexture(), mtlCmdBuff);
 
 	NSString* scName = _swapchain->getDebugName();
@@ -963,7 +961,7 @@
 }
 
 // Resets the MTLTexture and CAMetalDrawable underlying this image.
-void MVKSwapchainImage::releaseMetalDrawable() {
+void MVKPresentableSwapchainImage::releaseMetalDrawable() {
 	releaseMTLTexture();			// Release texture first so drawable will be last to release it
 	[_mtlDrawable release];
 	_mtlDrawable = nil;
@@ -972,12 +970,12 @@
 
 #pragma mark Construction
 
-MVKSwapchainImage::MVKSwapchainImage(MVKDevice* device,
-									 const VkImageCreateInfo* pCreateInfo,
-									 MVKSwapchain* swapchain,
-									 uint32_t swapchainIndex) : MVKImage(device, pCreateInfo) {
-	_swapchain = swapchain;
-	_swapchainIndex = swapchainIndex;
+MVKPresentableSwapchainImage::MVKPresentableSwapchainImage(MVKDevice* device,
+														   const VkImageCreateInfo* pCreateInfo,
+														   MVKSwapchain* swapchain,
+														   uint32_t swapchainIndex) :
+	MVKSwapchainImage(device, pCreateInfo, swapchain, swapchainIndex) {
+
 	_mtlDrawable = nil;
 
 	_availability.acquisitionID = _swapchain->getNextAcquisitionID();
@@ -985,12 +983,53 @@
 	_preSignaler = make_pair(nullptr, nullptr);
 }
 
-MVKSwapchainImage::~MVKSwapchainImage() {
+MVKPresentableSwapchainImage::~MVKPresentableSwapchainImage() {
 	releaseMetalDrawable();
 }
 
 
 #pragma mark -
+#pragma mark MVKPeerSwapchainImage
+
+VkResult MVKPeerSwapchainImage::bindDeviceMemory2(const void* pBindInfo) {
+	const auto* imageInfo = (const VkBindImageMemoryInfo*)pBindInfo;
+	const VkBindImageMemorySwapchainInfoKHR* swapchainInfo = nullptr;
+	for (const auto* next = (const VkBaseInStructure*)imageInfo->pNext; next; next = next->pNext) {
+		switch (next->sType) {
+			case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR:
+				swapchainInfo = (const VkBindImageMemorySwapchainInfoKHR*)next;
+				break;
+			default:
+				break;
+		}
+		if (swapchainInfo) { break; }
+	}
+	if (!swapchainInfo) {
+		return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+	}
+	_swapchainIndex = swapchainInfo->imageIndex;
+	return VK_SUCCESS;
+}
+
+
+#pragma mark Metal
+
+id<CAMetalDrawable> MVKPeerSwapchainImage::getCAMetalDrawable() {
+	return ((MVKSwapchainImage*)_swapchain->getPresentableImage(_swapchainIndex))->getCAMetalDrawable();
+}
+
+
+#pragma mark Construction
+
+MVKPeerSwapchainImage::MVKPeerSwapchainImage(MVKDevice* device,
+											 const VkImageCreateInfo* pCreateInfo,
+											 MVKSwapchain* swapchain,
+											 uint32_t swapchainIndex) :
+	MVKSwapchainImage(device, pCreateInfo, swapchain, swapchainIndex) {}
+
+
+
+#pragma mark -
 #pragma mark MVKImageView
 
 void MVKImageView::propogateDebugName() { setLabelIfNotNil(_mtlTexture, _debugName); }
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
index 9dda53c..c705a9d 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
@@ -228,6 +228,6 @@
 protected:
 	id<MTLCommandBuffer> getMTLCommandBuffer();
 
-	MVKVectorInline<MVKSwapchainImage*, 4> _surfaceImages;
+	MVKVectorInline<MVKPresentableSwapchainImage*, 4> _presentableImages;
 };
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
index 794c944..4c71d02 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
@@ -339,7 +339,7 @@
 	// The semaphores know what to do.
 	id<MTLCommandBuffer> mtlCmdBuff = getMTLCommandBuffer();
 	for (auto& ws : _waitSemaphores) { ws->encodeWait(mtlCmdBuff); }
-	for (auto& si : _surfaceImages) { si->presentCAMetalDrawable(mtlCmdBuff); }
+	for (auto& img : _presentableImages) { img->presentCAMetalDrawable(mtlCmdBuff); }
 	for (auto& ws : _waitSemaphores) { ws->encodeWait(nil); }
 	[mtlCmdBuff commit];
 
@@ -363,10 +363,10 @@
 		: MVKQueueSubmission(queue, pPresentInfo->waitSemaphoreCount, pPresentInfo->pWaitSemaphores) {
 
 	// Populate the array of swapchain images, testing each one for a change in surface size
-	_surfaceImages.reserve(pPresentInfo->swapchainCount);
+	_presentableImages.reserve(pPresentInfo->swapchainCount);
 	for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
 		MVKSwapchain* mvkSC = (MVKSwapchain*)pPresentInfo->pSwapchains[i];
-		_surfaceImages.push_back(mvkSC->getImage(pPresentInfo->pImageIndices[i]));
+		_presentableImages.push_back(mvkSC->getPresentableImage(pPresentInfo->pImageIndices[i]));
 		// Surface loss takes precedence over out-of-date errors.
 		if (mvkSC->getIsSurfaceLost()) {
 			setConfigurationResult(VK_ERROR_SURFACE_LOST_KHR);
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
index 8b88c64..8a33045 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
@@ -42,10 +42,10 @@
 	VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT; }
 
 	/** Returns the number of images in this swapchain. */
-	inline uint32_t getImageCount() { return (uint32_t)_surfaceImages.size(); }
+	inline uint32_t getImageCount() { return (uint32_t)_presentableImages.size(); }
 
 	/** Returns the image at the specified index. */
-	inline MVKSwapchainImage* getImage(uint32_t index) { return _surfaceImages[index]; }
+	inline MVKPresentableSwapchainImage* getPresentableImage(uint32_t index) { return _presentableImages[index]; }
 
 	/**
 	 * Returns the array of presentable images associated with this swapchain.
@@ -89,7 +89,7 @@
 	~MVKSwapchain() override;
 
 protected:
-	friend class MVKSwapchainImage;
+	friend class MVKPresentableSwapchainImage;
 
 	void propogateDebugName() override;
 	void initCAMetalLayer(const VkSwapchainCreateInfoKHR* pCreateInfo, uint32_t imgCnt);
@@ -103,7 +103,7 @@
 
 	CAMetalLayer* _mtlLayer;
     MVKWatermark* _licenseWatermark;
-	MVKVectorInline<MVKSwapchainImage*, kMVKMaxSwapchainImageCount> _surfaceImages;
+	MVKVectorInline<MVKPresentableSwapchainImage*, kMVKMaxSwapchainImageCount> _presentableImages;
 	std::atomic<uint64_t> _currentAcquisitionID;
     CGSize _mtlLayerOrigDrawSize;
     MVKSwapchainPerformance _performanceStatistics;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
index 13041b3..ddf6d27 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
@@ -40,10 +40,10 @@
 
 void MVKSwapchain::propogateDebugName() {
 	if (_debugName) {
-		size_t imgCnt = _surfaceImages.size();
+		size_t imgCnt = _presentableImages.size();
 		for (size_t imgIdx = 0; imgIdx < imgCnt; imgIdx++) {
 			NSString* nsName = [[NSString alloc] initWithFormat: @"%@(%lu)", _debugName, imgIdx];	// temp retain
-			_surfaceImages[imgIdx]->setDebugName(nsName.UTF8String);
+			_presentableImages[imgIdx]->setDebugName(nsName.UTF8String);
 			[nsName release];																		// release temp string
 		}
 	}
@@ -66,7 +66,7 @@
 
 	// Now populate the images
 	for (uint32_t imgIdx = 0; imgIdx < *pCount; imgIdx++) {
-		pSwapchainImages[imgIdx] = (VkImage)_surfaceImages[imgIdx];
+		pSwapchainImages[imgIdx] = (VkImage)_presentableImages[imgIdx];
 	}
 
 	return result;
@@ -81,11 +81,11 @@
 	if ( getIsSurfaceLost() ) { return VK_ERROR_SURFACE_LOST_KHR; }
 
 	// Find the image that has the shortest wait by finding the smallest availability measure.
-	MVKSwapchainImage* minWaitImage = nullptr;
+	MVKPresentableSwapchainImage* minWaitImage = nullptr;
 	MVKSwapchainImageAvailability minAvailability = { kMVKUndefinedLargeUInt64, false };
 	uint32_t imgCnt = getImageCount();
 	for (uint32_t imgIdx = 0; imgIdx < imgCnt; imgIdx++) {
-		MVKSwapchainImage* img = getImage(imgIdx);
+		auto* img = getPresentableImage(imgIdx);
 		auto imgAvail = img->getAvailability();
 		if (imgAvail < minAvailability) {
 			minAvailability = imgAvail;
@@ -382,7 +382,7 @@
 	}
 
 	for (uint32_t imgIdx = 0; imgIdx < imgCnt; imgIdx++) {
-		_surfaceImages.push_back(_device->createSwapchainImage(&imgInfo, this, imgIdx, NULL));
+		_presentableImages.push_back(_device->createPresentableSwapchainImage(&imgInfo, this, imgIdx, NULL));
 	}
 
     MVKLogInfo("Created %d swapchain images with initial size (%d, %d).", imgCnt, imgExtent.width, imgExtent.height);
@@ -403,7 +403,7 @@
 }
 
 MVKSwapchain::~MVKSwapchain() {
-	for (auto& img : _surfaceImages) { _device->destroySwapchainImage(img, NULL); }
+	for (auto& img : _presentableImages) { _device->destroyPresentableSwapchainImage(img, NULL); }
 
     if (_licenseWatermark) { _licenseWatermark->destroy(); }
     [this->_layerObserver release];