Refactor multiview support to remove some redundancy

Bug: b/119621736
Change-Id: I9be8dc680f68622e795fccf4ff8213dccd5debb2
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/35488
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkFramebuffer.cpp b/src/Vulkan/VkFramebuffer.cpp
index a879a78..8af5cc9 100644
--- a/src/Vulkan/VkFramebuffer.cpp
+++ b/src/Vulkan/VkFramebuffer.cpp
@@ -17,7 +17,6 @@
 #include "VkRenderPass.hpp"
 #include <algorithm>
 #include <memory.h>
-#include <System/Math.hpp>
 
 namespace vk
 {
@@ -65,34 +64,24 @@
 								  (clearStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
 				if (renderPass->isMultiView())
 				{
-					auto viewMask = renderPass->getAttachmentViewMask(i);
-					while (viewMask)
-					{
-						uint32_t view = sw::log2i(viewMask);
-						viewMask &= ~(1 << view);
-						VkClearRect r{renderArea, view, 1};
-						attachments[i]->clear(pClearValues[i], aspectMask, r);
-					}
+					attachments[i]->clearWithLayerMask(pClearValues[i], aspectMask, renderArea, renderPass->getAttachmentViewMask(i));
 				}
 				else
+				{
 					attachments[i]->clear(pClearValues[i], aspectMask, renderArea);
+				}
 			}
 		}
 		else if(attachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
 		{
 			if (renderPass->isMultiView())
 			{
-				auto viewMask = renderPass->getAttachmentViewMask(i);
-				while (viewMask)
-				{
-					uint32_t view = sw::log2i(viewMask);
-					viewMask &= ~(1 << view);
-					VkClearRect r{renderArea, view, 1};
-					attachments[i]->clear(pClearValues[i], VK_IMAGE_ASPECT_COLOR_BIT, r);
-				}
+				attachments[i]->clearWithLayerMask(pClearValues[i], VK_IMAGE_ASPECT_COLOR_BIT, renderArea, renderPass->getAttachmentViewMask(i));
 			}
 			else
+			{
 				attachments[i]->clear(pClearValues[i], VK_IMAGE_ASPECT_COLOR_BIT, renderArea);
+			}
 		}
 	}
 }
@@ -101,48 +90,39 @@
 {
 	VkSubpassDescription subpass = renderPass->getSubpass(subpassIndex);
 
-	if(attachment.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
+	if (attachment.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
 	{
-		if(attachment.colorAttachment != VK_ATTACHMENT_UNUSED)
+		if (attachment.colorAttachment != VK_ATTACHMENT_UNUSED)
 		{
 			ASSERT(attachment.colorAttachment < subpass.colorAttachmentCount);
 			ASSERT(subpass.pColorAttachments[attachment.colorAttachment].attachment < attachmentCount);
+			ImageView *imageView = attachments[subpass.pColorAttachments[attachment.colorAttachment].attachment];
 
 			if (renderPass->isMultiView())
 			{
-				auto viewMask = renderPass->getViewMask(subpassIndex);
-				while (viewMask)
-				{
-					int view = sw::log2i(viewMask);
-					viewMask &= ~(1 << view);
-					VkClearRect r = rect;
-					r.baseArrayLayer = view;
-					attachments[subpass.pColorAttachments[attachment.colorAttachment].attachment]->clear(attachment.clearValue, attachment.aspectMask, r);
-				}
+				imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect,
+											  renderPass->getViewMask(subpassIndex));
 			}
 			else
-				attachments[subpass.pColorAttachments[attachment.colorAttachment].attachment]->clear(
-					attachment.clearValue, attachment.aspectMask, rect);
+			{
+				imageView->clear(attachment.clearValue, attachment.aspectMask, rect);
+			}
 		}
 	}
-	else if(attachment.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
+	else if (attachment.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
 	{
 		ASSERT(subpass.pDepthStencilAttachment->attachment < attachmentCount);
+		ImageView *imageView = attachments[subpass.pDepthStencilAttachment->attachment];
 
 		if (renderPass->isMultiView())
-			{
-				auto viewMask = renderPass->getViewMask(subpassIndex);
-				while (viewMask)
-				{
-					int view = sw::log2i(viewMask);
-					viewMask &= ~(1 << view);
-					VkClearRect r = rect;
-					r.baseArrayLayer = view;
-					attachments[subpass.pDepthStencilAttachment->attachment]->clear(attachment.clearValue, attachment.aspectMask, r);
-				}
-			}
+		{
+			imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect,
+										  renderPass->getViewMask(subpassIndex));
+		}
 		else
-			attachments[subpass.pDepthStencilAttachment->attachment]->clear(attachment.clearValue, attachment.aspectMask, rect);
+		{
+			imageView->clear(attachment.clearValue, attachment.aspectMask, rect);
+		}
 	}
 }
 
@@ -161,19 +141,15 @@
 			uint32_t resolveAttachment = subpass.pResolveAttachments[i].attachment;
 			if(resolveAttachment != VK_ATTACHMENT_UNUSED)
 			{
+				ImageView *imageView = attachments[subpass.pColorAttachments[i].attachment];
 				if (renderPass->isMultiView())
 				{
-					auto viewMask = renderPass->getViewMask(subpassIndex);
-					while (viewMask)
-					{
-						int view = sw::log2i(viewMask);
-						viewMask &= ~(1 << view);
-						attachments[subpass.pColorAttachments[i].attachment]->resolve(attachments[resolveAttachment], view);
-					}
+					imageView->resolveWithLayerMask(attachments[resolveAttachment],
+													renderPass->getViewMask(subpassIndex));
 				}
 				else
 				{
-					attachments[subpass.pColorAttachments[i].attachment]->resolve(attachments[resolveAttachment]);
+					imageView->resolve(attachments[resolveAttachment]);
 				}
 			}
 		}
diff --git a/src/Vulkan/VkImageView.cpp b/src/Vulkan/VkImageView.cpp
index b0216fd..d847aa7 100644
--- a/src/Vulkan/VkImageView.cpp
+++ b/src/Vulkan/VkImageView.cpp
@@ -14,6 +14,7 @@
 
 #include "VkImageView.hpp"
 #include "VkImage.hpp"
+#include <System/Math.hpp>
 
 namespace
 {
@@ -154,6 +155,18 @@
 	image->clear(clearValue, format, renderArea.rect, sr);
 }
 
+void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
+{
+	while (layerMask)
+	{
+		uint32_t layer = sw::log2i(layerMask);
+		layerMask &= ~(1 << layer);
+		VkClearRect r = {renderArea, layer, 1};
+		r.baseArrayLayer = layer;
+		clear(clearValue, aspectMask, r);
+	}
+}
+
 void ImageView::resolve(ImageView* resolveAttachment, int layer)
 {
 	if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
@@ -214,6 +227,16 @@
 	image->copyTo(resolveAttachment->image, region);
 }
 
+void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
+{
+	while (layerMask)
+	{
+		int layer = sw::log2i(layerMask);
+		layerMask &= ~(1 << layer);
+		resolve(resolveAttachment, layer);
+	}
+}
+
 const Image* ImageView::getImage(Usage usage) const
 {
 	switch(usage)
diff --git a/src/Vulkan/VkImageView.hpp b/src/Vulkan/VkImageView.hpp
index 3d9942c..aefce8b 100644
--- a/src/Vulkan/VkImageView.hpp
+++ b/src/Vulkan/VkImageView.hpp
@@ -41,8 +41,10 @@
 
 	void clear(const VkClearValue& clearValues, VkImageAspectFlags aspectMask, const VkRect2D& renderArea);
 	void clear(const VkClearValue& clearValue, VkImageAspectFlags aspectMask, const VkClearRect& renderArea);
+	void clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask);
 	void resolve(ImageView* resolveAttachment);
 	void resolve(ImageView* resolveAttachment, int layer);
+	void resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask);
 
 	VkImageViewType getType() const { return viewType; }
 	Format getFormat(Usage usage = RAW) const;