Support VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16

... to support AHARDWAREBUFFER_FORMAT_YCbCr_P010 sampling for
client composition (SurfaceFlinger composition using OpenGL)
which occurs when camera produces HDR P010 buffers.

Bug: b/219756793
Test: launch Cuttlefish and run Camera2Video sample app
Test: dEQP-VK.ycbcr.format.*
Change-Id: I5e2567a88df134b71ce75b554c5994a755173e87
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/63748
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Presubmit-Ready: Jason Macnak <natsu@google.com>
Tested-by: Jason Macnak <natsu@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Commit-Queue: Jason Macnak <natsu@google.com>
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 510d062..d091ea5 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -1733,48 +1733,95 @@
 		Pointer<Byte> bufferV = *Pointer<Pointer<Byte>>(mipmap + 2 * sizeof(Mipmap) + OFFSET(Mipmap, buffer));
 
 		// Luminance
-		Int c0 = Int(bufferY[index[0]]);
-		Int c1 = Int(bufferY[index[1]]);
-		Int c2 = Int(bufferY[index[2]]);
-		Int c3 = Int(bufferY[index[3]]);
-		c0 = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
-		UShort4 Y = As<UShort4>(Unpack(As<Byte4>(c0)));
-
-		UShort4 Cb, Cr;
+		UShort4 Y;
+		{
+			switch(state.textureFormat)
+			{
+			case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
+			case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+				{
+					Int c0 = Int(bufferY[index[0]]);
+					Int c1 = Int(bufferY[index[1]]);
+					Int c2 = Int(bufferY[index[2]]);
+					Int c3 = Int(bufferY[index[3]]);
+					c0 = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
+					Y = As<UShort4>(Unpack(As<Byte4>(c0)));
+				}
+				break;
+			case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+				{
+					Y = Insert(Y, Pointer<UShort>(bufferY)[index[0]], 0);  // TODO: Insert(UShort4, UShort)
+					Y = Insert(Y, Pointer<UShort>(bufferY)[index[1]], 1);
+					Y = Insert(Y, Pointer<UShort>(bufferY)[index[2]], 2);
+					Y = Insert(Y, Pointer<UShort>(bufferY)[index[3]], 3);
+					// Top 10 bits of each 16 bits:
+					Y = (Y & UShort4(0xFFC0u)) >> 6;
+					// Scale from 10 bits to 16 bits:
+					Y = Y << 6;
+				}
+				break;
+			default:
+				UNSUPPORTED("state.textureFormat %d", (int)state.textureFormat);
+				break;
+			}
+		}
 
 		// Chroma
+		UShort4 Cb, Cr;
 		{
 			computeIndices(index, uuuu, vvvv, wwww, layerIndex, offset, sample, mipmap + sizeof(Mipmap));
 			UShort4 U, V;
 
-			if(state.textureFormat == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)
+			switch(state.textureFormat)
 			{
-				c0 = Int(bufferU[index[0]]);
-				c1 = Int(bufferU[index[1]]);
-				c2 = Int(bufferU[index[2]]);
-				c3 = Int(bufferU[index[3]]);
-				c0 = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
-				U = As<UShort4>(Unpack(As<Byte4>(c0)));
+			case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
+				{
+					Int c0 = Int(bufferU[index[0]]);
+					Int c1 = Int(bufferU[index[1]]);
+					Int c2 = Int(bufferU[index[2]]);
+					Int c3 = Int(bufferU[index[3]]);
+					c0 = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
+					U = As<UShort4>(Unpack(As<Byte4>(c0)));
 
-				c0 = Int(bufferV[index[0]]);
-				c1 = Int(bufferV[index[1]]);
-				c2 = Int(bufferV[index[2]]);
-				c3 = Int(bufferV[index[3]]);
-				c0 = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
-				V = As<UShort4>(Unpack(As<Byte4>(c0)));
-			}
-			else if(state.textureFormat == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM)
-			{
-				Short4 UV;
-				UV = Insert(UV, Pointer<Short>(bufferU)[index[0]], 0);  // TODO: Insert(UShort4, UShort)
-				UV = Insert(UV, Pointer<Short>(bufferU)[index[1]], 1);
-				UV = Insert(UV, Pointer<Short>(bufferU)[index[2]], 2);
-				UV = Insert(UV, Pointer<Short>(bufferU)[index[3]], 3);
-				U = (UV & Short4(0x00FFu)) | (UV << 8);
-				V = (UV & Short4(0xFF00u)) | As<Short4>(As<UShort4>(UV) >> 8);
-			}
-			else
+					c0 = Int(bufferV[index[0]]);
+					c1 = Int(bufferV[index[1]]);
+					c2 = Int(bufferV[index[2]]);
+					c3 = Int(bufferV[index[3]]);
+					c0 = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
+					V = As<UShort4>(Unpack(As<Byte4>(c0)));
+				}
+				break;
+			case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+				{
+					Short4 UV;
+					UV = Insert(UV, Pointer<Short>(bufferU)[index[0]], 0);  // TODO: Insert(UShort4, UShort)
+					UV = Insert(UV, Pointer<Short>(bufferU)[index[1]], 1);
+					UV = Insert(UV, Pointer<Short>(bufferU)[index[2]], 2);
+					UV = Insert(UV, Pointer<Short>(bufferU)[index[3]], 3);
+					U = (UV & Short4(0x00FFu)) | (UV << 8);
+					V = (UV & Short4(0xFF00u)) | As<Short4>(As<UShort4>(UV) >> 8);
+				}
+				break;
+			case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+				{
+					UInt4 UV;
+					UV = Insert(UV, Pointer<UInt>(bufferU)[index[0]], 0);
+					UV = Insert(UV, Pointer<UInt>(bufferU)[index[1]], 1);
+					UV = Insert(UV, Pointer<UInt>(bufferU)[index[2]], 2);
+					UV = Insert(UV, Pointer<UInt>(bufferU)[index[3]], 3);
+					// Top 10 bits of first 16 bits:
+					U = UShort4((UV & UInt4(0x0000FFC0u)) >> 6);  // TODO: UnpackLower(UInt4)
+					// Top 10 bits of second 16 bits:
+					V = UShort4((UV & UInt4(0xFFC00000u)) >> 22);  // TODO: UnpackUpper(UInt4)
+					// Scale from 10 bits to 16 bits:
+					U = U << 6;
+					V = V << 6;
+				}
+				break;
+			default:
 				UNSUPPORTED("state.textureFormat %d", (int)state.textureFormat);
+				break;
+			}
 
 			if(!state.swappedChroma)
 			{
@@ -2574,6 +2621,7 @@
 	{
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		return sw::float4(0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF);
 	default:
 		break;
diff --git a/src/Reactor/Reactor.cpp b/src/Reactor/Reactor.cpp
index 2f2b336..41268a9 100644
--- a/src/Reactor/Reactor.cpp
+++ b/src/Reactor/Reactor.cpp
@@ -2138,6 +2138,11 @@
 	return RValue<UShort4>(Nucleus::createNot(val.value()));
 }
 
+RValue<UShort4> Insert(RValue<UShort4> val, RValue<UShort> element, int i)
+{
+	return RValue<UShort4>(Nucleus::createInsertElement(val.value(), element.value(), i));
+}
+
 Short8::Short8(short c)
 {
 	int64_t constantVector[8] = { c, c, c, c, c, c, c, c };
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 70ab92c..453684e 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -1050,6 +1050,7 @@
 //	RValue<UShort4> operator--(UShort4 &val, int);   // Post-decrement
 //	const UShort4 &operator--(UShort4 &val);   // Pre-decrement
 
+RValue<UShort4> Insert(RValue<UShort4> val, RValue<UShort> element, int i);
 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y);
 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y);
 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y);
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index dc38d8e..8fe7e31 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -786,9 +786,15 @@
 		position += Bytes.size();
 	}
 
-	uint64_t tell() const override { return position; }
+	uint64_t tell() const override
+	{
+		return position;
+	}
 
-	void seek(uint64_t Off) override { position = Off; }
+	void seek(uint64_t Off) override
+	{
+		position = Off;
+	}
 
 	std::vector<EntryPoint> loadImageAndGetEntryPoints(const std::vector<const char *> &functionNames)
 	{
@@ -2839,11 +2845,6 @@
 	return RValue<UShort>(Nucleus::createExtractElement(val.value(), UShort::type(), i));
 }
 
-RValue<UShort4> Insert(RValue<UShort4> val, RValue<UShort> element, int i)
-{
-	return RValue<UShort4>(Nucleus::createInsertElement(val.value(), element.value(), i));
-}
-
 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
diff --git a/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp b/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
index 7e57476..3efbafd 100644
--- a/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
+++ b/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
@@ -53,6 +53,8 @@
 		return AHARDWAREBUFFER_FORMAT_S8_UINT;
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 		return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+		return AHARDWAREBUFFER_FORMAT_YCbCr_P010;
 	default:
 		UNSUPPORTED("AHardwareBufferExternalMemory::VkFormat %d", int(format));
 		return 0;
@@ -380,6 +382,8 @@
 	case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
 	case AHARDWAREBUFFER_FORMAT_YV12:
 		return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
+	case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
+		return VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
 	default:
 		UNSUPPORTED("AHardwareBufferExternalMemory::AHardwareBuffer_Format %d", int(ahbFormat));
 		return VK_FORMAT_UNDEFINED;
@@ -401,7 +405,8 @@
 
 	// YUV formats are not listed in the AHardwareBuffer Format Equivalence table in the Vulkan spec.
 	// Clients must use VkExternalFormatANDROID.
-	if(pFormat->format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)
+	if(pFormat->format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM ||
+	   pFormat->format == VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16)
 	{
 		pFormat->format = VK_FORMAT_UNDEFINED;
 	}
@@ -472,6 +477,7 @@
 	{
 	case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
 	case AHARDWAREBUFFER_FORMAT_YV12:
+	case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
 		switch(aspect)
 		{
 		case VK_IMAGE_ASPECT_PLANE_0_BIT:
@@ -500,6 +506,7 @@
 	{
 	case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
 	case AHARDWAREBUFFER_FORMAT_YV12:
+	case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
 		switch(aspect)
 		{
 		case VK_IMAGE_ASPECT_PLANE_0_BIT:
diff --git a/src/Vulkan/VkFormat.cpp b/src/Vulkan/VkFormat.cpp
index f36e351..d551bd1 100644
--- a/src/Vulkan/VkFormat.cpp
+++ b/src/Vulkan/VkFormat.cpp
@@ -47,6 +47,7 @@
 	case VK_FORMAT_D16_UNORM:
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		return true;
 	default:
 		// sRGB encoded formats are also unsigned normalized.
@@ -157,6 +158,7 @@
 		aspects = VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT;
 		break;
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		aspects = VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT;
 		break;
 	default:
@@ -219,6 +221,8 @@
 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
 			return VK_FORMAT_R8_UNORM;
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+			return VK_FORMAT_R10X6_UNORM_PACK16;
 		default:
 			UNSUPPORTED("format %d", int(format));
 			break;
@@ -234,6 +238,8 @@
 		case VK_FORMAT_R8G8_UNORM:
 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
 			return VK_FORMAT_R8G8_UNORM;
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+			return VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
 		case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
 			return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
 		default:
@@ -456,6 +462,7 @@
 	case VK_FORMAT_D24_UNORM_S8_UINT:
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		return false;
 	case VK_FORMAT_R16_SFLOAT:
 	case VK_FORMAT_R16G16_SFLOAT:
@@ -487,6 +494,7 @@
 	{
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		return true;
 	default:
 		return false;
@@ -1225,6 +1233,7 @@
 	case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 	case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
 	case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
 	case VK_FORMAT_BC6H_UFLOAT_BLOCK:
@@ -1490,6 +1499,7 @@
 	// expects chroma components to be in range [-0.5, 0.5]
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		return false;
 	case VK_FORMAT_R8_SNORM:
 	case VK_FORMAT_R8_USCALED:
@@ -1565,6 +1575,7 @@
 	case VK_FORMAT_R8G8_UINT:
 	case VK_FORMAT_R8G8_SINT:
 	case VK_FORMAT_R8G8_SRGB:
+	case VK_FORMAT_R10X6_UNORM_PACK16:
 		return 2;
 	case VK_FORMAT_R8G8B8A8_UNORM:
 	case VK_FORMAT_R8G8B8A8_SNORM:
@@ -1599,6 +1610,7 @@
 	case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
 	case VK_FORMAT_A2B10G10R10_UINT_PACK32:
 	case VK_FORMAT_A2B10G10R10_SINT_PACK32:
+	case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
 		return 4;
 	case VK_FORMAT_R16_UNORM:
 	case VK_FORMAT_R16_SNORM:
@@ -1738,6 +1750,9 @@
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
 		// TODO: ASSERT to ensure this is only called per-aspect?
 		return 1;  // Y plane only
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+		// TODO: ASSERT to ensure this is only called per-aspect?
+		return 2;  // Y plane only
 	default:
 		UNSUPPORTED("Format: %d", int(format));
 	}
@@ -1815,6 +1830,7 @@
 		return 16 * ((width + 11) / 12);
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		return sw::align<16>(width);  // Y plane only  // TODO: ASSERT to ensure this is only called per-aspect?
 	default:
 		return bytes() * width;
@@ -1886,6 +1902,7 @@
 		return pitchB(width, border) * ((height + 11) / 12);  // Pitch computed per 12 rows
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		// "Images in this format must be defined with a width and height that is a multiple of two."
 		return pitchB(width, border) * (height + height / 2);  // U and V planes are 1/4 size of Y plane.
 	default:
@@ -2305,6 +2322,7 @@
 	case VK_FORMAT_R16G16B16A16_SFLOAT:
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 	case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
 	case VK_FORMAT_A2B10G10R10_UINT_PACK32:
 	case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
@@ -2369,6 +2387,7 @@
 	case VK_FORMAT_R32G32B32A32_SFLOAT:
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 	case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
 	case VK_FORMAT_A2B10G10R10_UINT_PACK32:
 	case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
@@ -2459,6 +2478,7 @@
 	case VK_FORMAT_R32G32B32A32_SFLOAT:
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 	case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
 	case VK_FORMAT_A2B10G10R10_UINT_PACK32:
 	case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
@@ -2547,6 +2567,7 @@
 	case VK_FORMAT_R32G32B32A32_SFLOAT:
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 	case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
 	case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
 		return component < 3;
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp
index 55b6e55..b99ca22 100644
--- a/src/Vulkan/VkImage.cpp
+++ b/src/Vulkan/VkImage.cpp
@@ -838,6 +838,7 @@
 		{
 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 			ASSERT(mipLevelExtent.width % 2 == 0 && mipLevelExtent.height % 2 == 0);  // Vulkan 1.1: "Images in this format must be defined with a width and height that is a multiple of two."
 			// Vulkan 1.1 Table 31. Plane Format Compatibility Table:
 			// Half-resolution U and V planes.
@@ -944,6 +945,7 @@
 		}
 		// Fall through to 2PLANE case:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		if(aspect == VK_IMAGE_ASPECT_PLANE_1_BIT)
 		{
 			return getStorageSize(VK_IMAGE_ASPECT_PLANE_0_BIT);
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 0c04adf..64b8055 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -1504,6 +1504,7 @@
 	// YCbCr formats:
 	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
 	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
 		pFormatProperties->optimalTilingFeatures |=
 		    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
 		    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |