Only perform attachment load/store ops for used attachments

Tracks the first subpass to touch an attachment.

Test: dEQP-VK.renderpass.suballocation.unused*
Change-Id: Idc0998da022fd4c0b1785f6020c795916ba475f7
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31308
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkRenderPass.hpp b/src/Vulkan/VkRenderPass.hpp
index 8a8a63d..4b5677c 100644
--- a/src/Vulkan/VkRenderPass.hpp
+++ b/src/Vulkan/VkRenderPass.hpp
@@ -17,6 +17,8 @@
 
 #include "VkObject.hpp"
 
+#include <vector>
+
 namespace vk
 {
 
@@ -29,7 +31,7 @@
 
 	static size_t ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo);
 
-	void getRenderAreaGranularity(VkExtent2D* pGranularity) const;

+	void getRenderAreaGranularity(VkExtent2D* pGranularity) const;
 
 	void begin();
 	void nextSubpass();
@@ -70,6 +72,11 @@
 		return dependencies[i];
 	}
 
+	bool isAttachmentUsed(uint32_t i) const
+	{
+		return attachmentFirstUse[i] >= 0;
+	}
+
 private:
 	uint32_t                 attachmentCount = 0;
 	VkAttachmentDescription* attachments = nullptr;
@@ -78,6 +85,7 @@
 	uint32_t                 dependencyCount = 0;
 	VkSubpassDependency*     dependencies = nullptr;
 	uint32_t                 currentSubpass = 0;
+	int*                     attachmentFirstUse = nullptr;
 };
 
 static inline RenderPass* Cast(VkRenderPass object)