From 102d30db2d5064cc3b2e9f9a3ab66a6519953548 Mon Sep 17 00:00:00 2001
From: kd-11 <karokidii@gmail.com>
Date: Wed, 28 Sep 2022 02:40:31 +0300
Subject: [PATCH] vk: Update support for framebuffer loops to comply with
 current spec

---
 rpcs3/Emu/RSX/VK/VKRenderPass.cpp   |  4 ++--
 rpcs3/Emu/RSX/VK/VKRenderTargets.h  |  9 +++++++--
 rpcs3/Emu/RSX/VK/VulkanAPI.h        |  1 +
 rpcs3/Emu/RSX/VK/vkutils/device.cpp | 14 ++++++++++++++
 4 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/rpcs3/Emu/RSX/VK/VKRenderPass.cpp b/rpcs3/Emu/RSX/VK/VKRenderPass.cpp
index 2a946671d3..4c67347ad4 100644
--- a/rpcs3/Emu/RSX/VK/VKRenderPass.cpp
+++ b/rpcs3/Emu/RSX/VK/VKRenderPass.cpp
@@ -153,9 +153,9 @@ namespace vk
 
 			for (u32 i = 0, layout_offset = 0; i < 5; ++i, layout_offset += 3)
 			{
-				if (const auto layout = VkImageLayout((layout_blob >> layout_offset) & 0x7))
+				if (const auto layout_encoding = (layout_blob >> layout_offset) & 0x7)
 				{
-					result.push_back(layout);
+					result.push_back(decode_layout(layout_encoding));
 				}
 				else
 				{
diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h
index 1c6c2d40e5..1c7a63322f 100644
--- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h
+++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h
@@ -103,6 +103,12 @@ namespace vk
 				return {};
 			}
 
+			// If we have driver support for FBO loops, set the usage flag for it.
+			if (vk::get_current_renderer()->get_framebuffer_loops_support())
+			{
+				return { VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT, 0 };
+			}
+
 			// Workarounds to force transition to GENERAL to decompress.
 			// Fixes corruption in FBO loops for ANV and RADV.
 			switch (vk::get_driver_vendor())
@@ -117,8 +123,7 @@ namespace vk
 				break;
 			case driver_vendor::AMD:
 			case driver_vendor::RADV:
-				if ((vk::get_chip_family() >= chip_class::AMD_navi1x) &&
-					!vk::get_current_renderer()->get_framebuffer_loops_support())
+				if (vk::get_chip_family() >= chip_class::AMD_navi1x)
 				{
 					// Only needed for GFX10+
 					return { 0, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT };
diff --git a/rpcs3/Emu/RSX/VK/VulkanAPI.h b/rpcs3/Emu/RSX/VK/VulkanAPI.h
index 6346a48d54..70f8f267b6 100644
--- a/rpcs3/Emu/RSX/VK/VulkanAPI.h
+++ b/rpcs3/Emu/RSX/VK/VulkanAPI.h
@@ -27,6 +27,7 @@
 #define VK_EXT_attachment_feedback_loop_layout 1
 #define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME "VK_EXT_attachment_feedback_loop_layout"
 #define VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT static_cast<VkImageLayout>(1000339000)
+#define VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT 0x00080000
 #define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT static_cast<VkStructureType>(1000339000)
 
 typedef struct VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT {
diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.cpp b/rpcs3/Emu/RSX/VK/vkutils/device.cpp
index ee6595c172..70b5df91c2 100644
--- a/rpcs3/Emu/RSX/VK/vkutils/device.cpp
+++ b/rpcs3/Emu/RSX/VK/vkutils/device.cpp
@@ -451,6 +451,11 @@ namespace vk
 			requested_extensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
 		}
 
+		if (pgpu->framebuffer_loops_support)
+		{
+			requested_extensions.push_back(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME);
+		}
+
 		enabled_features.robustBufferAccess = VK_TRUE;
 		enabled_features.fullDrawIndexUint32 = VK_TRUE;
 		enabled_features.independentBlend = VK_TRUE;
@@ -616,6 +621,15 @@ namespace vk
 			device.pNext = &indexing_features;
 		}
 
+		VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT fbo_loop_features{};
+		if (pgpu->framebuffer_loops_support)
+		{
+			fbo_loop_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT;
+			fbo_loop_features.attachmentFeedbackLoopLayout = VK_TRUE;
+			fbo_loop_features.pNext = const_cast<void*>(device.pNext);
+			device.pNext = &fbo_loop_features;
+		}
+
 		CHECK_RESULT_EX(vkCreateDevice(*pgpu, &device, nullptr, &dev), message_on_error);
 
 		// Initialize queues