static VkFormat
vk_format_for_size(int bs)
{
- /* Note: We intentionally use the 4-channel formats whenever we can.
- * This is so that, when we do a RGB <-> RGBX copy, the two formats will
- * line up even though one of them is 3/4 the size of the other.
+ /* The choice of UNORM and UINT formats is very intentional here. Most of
+ * the time, we want to use a UINT format to avoid any rounding error in
+ * the blit. For stencil blits, R8_UINT is required by the hardware.
+ * (It's the only format allowed in conjunction with W-tiling.) Also we
+ * intentionally use the 4-channel formats whenever we can. This is so
+ * that, when we do a RGB <-> RGBX copy, the two formats will line up even
+ * though one of them is 3/4 the size of the other. The choice of UNORM
+ * vs. UINT is also very intentional because Haswell doesn't handle 8 or
+ * 16-bit RGB UINT formats at all so we have to use UNORM there.
+ * Fortunately, the only time we should ever use two different formats in
+ * the table below is for RGB -> RGBA blits and so we will never have any
+ * UNORM/UINT mismatch.
*/
switch (bs) {
case 1: return VK_FORMAT_R8_UINT;
case 2: return VK_FORMAT_R8G8_UINT;
- case 3: return VK_FORMAT_R8G8B8_UINT;
- case 4: return VK_FORMAT_R8G8B8A8_UINT;
- case 6: return VK_FORMAT_R16G16B16_UINT;
- case 8: return VK_FORMAT_R16G16B16A16_UINT;
+ case 3: return VK_FORMAT_R8G8B8_UNORM;
+ case 4: return VK_FORMAT_R8G8B8A8_UNORM;
+ case 6: return VK_FORMAT_R16G16B16_UNORM;
+ case 8: return VK_FORMAT_R16G16B16A16_UNORM;
case 12: return VK_FORMAT_R32G32B32_UINT;
case 16: return VK_FORMAT_R32G32B32A32_UINT;
default: