Merge branch 'master' of https://github.com/billhollings/MoltenVK into xcode12
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
index 15e4b1f..56b7bf2 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
@@ -1130,6 +1130,15 @@
 	simd::float4 clearColors[kMVKClearAttachmentCount];
 
 	VkExtent2D fbExtent = cmdEncoder->_framebuffer->getExtent2D();
+	// I need to know if the 'renderTargetWidth' and 'renderTargetHeight' properties
+	// actually do something, but [MTLRenderPassDescriptor instancesRespondToSelector: @selector(renderTargetWidth)]
+	// returns NO even on systems that do support it. So we have to check an actual instance.
+	MTLRenderPassDescriptor* tempRPDesc = [MTLRenderPassDescriptor new];	// temp retain
+	if ([tempRPDesc respondsToSelector: @selector(renderTargetWidth)]) {
+		VkRect2D renderArea = cmdEncoder->clipToRenderArea({{0, 0}, fbExtent});
+		fbExtent = {renderArea.offset.x + renderArea.extent.width, renderArea.offset.y + renderArea.extent.height};
+	}
+	[tempRPDesc release];													// temp release
 	populateVertices(cmdEncoder, vertices, fbExtent.width, fbExtent.height);
 
 	MVKPixelFormats* pixFmts = cmdEncoder->getPixelFormats();
@@ -1345,20 +1354,41 @@
 				layerEnd = layerStart + layerCnt;
 			}
 
-            for (uint32_t layer = layerStart; layer < layerEnd; layer++) {
+            // If we can do layered rendering, I can clear all the layers at once.
+            if (cmdEncoder->getDevice()->_pMetalFeatures->layeredRendering &&
+                (_image->getSampleCount() == VK_SAMPLE_COUNT_1_BIT || cmdEncoder->getDevice()->_pMetalFeatures->multisampleLayeredRendering)) {
                 if (is3D) {
-                    mtlRPCADesc.depthPlane = layer;
-                    mtlRPDADesc.depthPlane = layer;
-                    mtlRPSADesc.depthPlane = layer;
+                    mtlRPCADesc.depthPlane = layerStart;
+                    mtlRPDADesc.depthPlane = layerStart;
+                    mtlRPSADesc.depthPlane = layerStart;
                 } else {
-                    mtlRPCADesc.slice = layer;
-                    mtlRPDADesc.slice = layer;
-                    mtlRPSADesc.slice = layer;
+                    mtlRPCADesc.slice = layerStart;
+                    mtlRPDADesc.slice = layerStart;
+                    mtlRPSADesc.slice = layerStart;
                 }
+                mtlRPDesc.renderTargetArrayLength = (layerCnt == VK_REMAINING_ARRAY_LAYERS
+                                                     ? (_image->getLayerCount() - layerStart)
+                                                     : layerCnt);
 
                 id<MTLRenderCommandEncoder> mtlRendEnc = [cmdEncoder->_mtlCmdBuffer renderCommandEncoderWithDescriptor: mtlRPDesc];
-				setLabelIfNotNil(mtlRendEnc, mtlRendEncName);
+                setLabelIfNotNil(mtlRendEnc, mtlRendEncName);
                 [mtlRendEnc endEncoding];
+            } else {
+                for (uint32_t layer = layerStart; layer < layerEnd; layer++) {
+                    if (is3D) {
+                        mtlRPCADesc.depthPlane = layer;
+                        mtlRPDADesc.depthPlane = layer;
+                        mtlRPSADesc.depthPlane = layer;
+                    } else {
+                        mtlRPCADesc.slice = layer;
+                        mtlRPDADesc.slice = layer;
+                        mtlRPSADesc.slice = layer;
+                    }
+
+                    id<MTLRenderCommandEncoder> mtlRendEnc = [cmdEncoder->_mtlCmdBuffer renderCommandEncoderWithDescriptor: mtlRPDesc];
+                    setLabelIfNotNil(mtlRendEnc, mtlRendEncName);
+                    [mtlRendEnc endEncoding];
+                }
             }
         }
     }
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index b99eef9..7db5dfd 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -54,13 +54,13 @@
         } else if (memoryBinding->_mtlTexelBuffer) {
             _mtlTexture = [memoryBinding->_mtlTexelBuffer
                            newTextureWithDescriptor: mtlTexDesc
-                           offset: memoryBinding->_mtlTexelBufferOffset
+                           offset: memoryBinding->_mtlTexelBufferOffset + _subresources[0].layout.offset
                            bytesPerRow: _subresources[0].layout.rowPitch];
         } else if (memoryBinding->_deviceMemory->getMTLHeap() && !_image->getIsDepthStencil()) {
             // Metal support for depth/stencil from heaps is flaky
             _mtlTexture = [memoryBinding->_deviceMemory->getMTLHeap()
                            newTextureWithDescriptor: mtlTexDesc
-                           offset: memoryBinding->getDeviceMemoryOffset()];
+                           offset: memoryBinding->getDeviceMemoryOffset() + _subresources[0].layout.offset];
             if (_image->_isAliasable) { [_mtlTexture makeAliasable]; }
         } else {
             _mtlTexture = [_image->getMTLDevice() newTextureWithDescriptor: mtlTexDesc];