Allow sampling usage when querying linear image format properties.

Currently, VkImages with VK_IMAGE_TILING_OPTIMAL tiling actually
also have a linear texel layout in our current implementation,
thus it can be sampled or used as blit source. And we would
like to add support to sampling features for linear images when
calling vkGetPhysicalDeviceImageFormatProperties() to query image
format properties.

Exceptions include images with compressed formats and images
created to be used as cube maps.

This will unblock SwiftShader users like AEMU/FEMU from sampling
host-visible memory shared between guest processes.

Bug: b/171299814
Bug: fuchsia:54153
Bug: fuchsia:68365
Test: dEQP-VK.*

Change-Id: Id9019fc9d9239fc85d0d2b086d4efd468844d254
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/49108
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Commit-Queue: Yilong Li <liyl@google.com>
Tested-by: Yilong Li <liyl@google.com>
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 9b76407..cd879c9 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -1290,6 +1290,18 @@
 	{
 		pFormatProperties->linearTilingFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
 		                                          VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
+
+		if(!format.isCompressed())
+		{
+			if(pFormatProperties->optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
+			{
+				pFormatProperties->linearTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
+			}
+			if(pFormatProperties->optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)
+			{
+				pFormatProperties->linearTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
+			}
+		}
 	}
 }
 
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index e98d8d0..7be1f7b 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -3243,6 +3243,25 @@
 	                              VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
 	ASSERT(!(usage & ~(allRecognizedUsageBits)));
 
+	if(usage & VK_IMAGE_USAGE_SAMPLED_BIT)
+	{
+		if(tiling == VK_IMAGE_TILING_LINEAR)
+		{
+			// TODO(b/171299814): Compressed formats and cube maps are not supported for sampling using VK_IMAGE_TILING_LINEAR; otherwise, sampling
+			// in linear tiling is always supported as long as it can be sampled when using VK_IMAGE_TILING_OPTIMAL.
+			if(!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ||
+			   vk::Format(format).isCompressed() ||
+			   (flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT))
+			{
+				return VK_ERROR_FORMAT_NOT_SUPPORTED;
+			}
+		}
+		else if(!(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
+		{
+			return VK_ERROR_FORMAT_NOT_SUPPORTED;
+		}
+	}
+
 	// "Images created with tiling equal to VK_IMAGE_TILING_LINEAR have further restrictions on their limits and capabilities
 	//  compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL."
 	if(tiling == VK_IMAGE_TILING_LINEAR)