[Mesa-dev] [PATCH v4 07/12] anv: add new formats KHR_sampler_ycbcr_conversion
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Thu Oct 5 16:30:23 UTC 2017
Adding new downsampling factors for each planes.
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
src/intel/vulkan/anv_formats.c | 158 ++++++++++++++++++++++++++++++++++++--
src/intel/vulkan/anv_private.h | 10 +++
src/intel/vulkan/vk_format_info.h | 27 +++++++
3 files changed, 189 insertions(+), 6 deletions(-)
diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_formats.c
index e623b4f6324..795055b52ff 100644
--- a/src/intel/vulkan/anv_formats.c
+++ b/src/intel/vulkan/anv_formats.c
@@ -22,6 +22,7 @@
*/
#include "anv_private.h"
+#include "vk_enum_to_str.h"
#include "vk_format_info.h"
#include "vk_util.h"
@@ -44,14 +45,12 @@
#define BGRA _ISL_SWIZZLE(BLUE, GREEN, RED, ALPHA)
#define RGB1 _ISL_SWIZZLE(RED, GREEN, BLUE, ONE)
-#define _fmt(__hw_fmt, __swizzle) \
- { .isl_format = __hw_fmt, \
- .swizzle = __swizzle }
-
#define swiz_fmt1(__vk_fmt, __hw_fmt, __swizzle) \
[VK_ENUM_OFFSET(__vk_fmt)] = { \
.planes = { \
- { .isl_format = __hw_fmt, .swizzle = __swizzle }, \
+ { .isl_format = __hw_fmt, .swizzle = __swizzle, \
+ .denominator_scales = { 1, 1, }, \
+ }, \
}, \
.n_planes = 1, \
}
@@ -64,9 +63,11 @@
.planes = { \
{ .isl_format = __fmt1, \
.swizzle = RGBA, \
+ .denominator_scales = { 1, 1, }, \
}, \
{ .isl_format = __fmt2, \
.swizzle = RGBA, \
+ .denominator_scales = { 1, 1, }, \
}, \
}, \
.n_planes = 2, \
@@ -79,6 +80,31 @@
}, \
}
+#define y_plane(__hw_fmt, __swizzle, __ycbcr_swizzle, dhs, dvs) \
+ { .isl_format = __hw_fmt, \
+ .swizzle = __swizzle, \
+ .ycbcr_swizzle = __ycbcr_swizzle, \
+ .denominator_scales = { dhs, dvs, }, \
+ .has_chroma = false, \
+ }
+
+#define chroma_plane(__hw_fmt, __swizzle, __ycbcr_swizzle, dhs, dvs) \
+ { .isl_format = __hw_fmt, \
+ .swizzle = __swizzle, \
+ .ycbcr_swizzle = __ycbcr_swizzle, \
+ .denominator_scales = { dhs, dvs, }, \
+ .has_chroma = true, \
+ }
+
+#define ycbcr_fmt(__vk_fmt, __n_planes, ...) \
+ [VK_ENUM_OFFSET(__vk_fmt)] = { \
+ .planes = { \
+ __VA_ARGS__, \
+ }, \
+ .n_planes = __n_planes, \
+ .can_ycbcr = true, \
+ }
+
/* HINT: For array formats, the ISL name should match the VK name. For
* packed formats, they should have the channels in reverse order from each
* other. The reason for this is that, for packed formats, the ISL (and
@@ -275,6 +301,76 @@ static const struct anv_format main_formats[] = {
fmt1(VK_FORMAT_B8G8R8A8_SRGB, ISL_FORMAT_B8G8R8A8_UNORM_SRGB),
};
+static const struct anv_format ycbcr_formats[] = {
+ ycbcr_fmt(VK_FORMAT_G8B8G8R8_422_UNORM_KHR, 1,
+ y_plane(ISL_FORMAT_YCRCB_SWAPUV, RGBA, _ISL_SWIZZLE(BLUE, GREEN, RED, ZERO), 1, 1)),
+ ycbcr_fmt(VK_FORMAT_B8G8R8G8_422_UNORM_KHR, 1,
+ y_plane(ISL_FORMAT_YCRCB_SWAPUVY, RGBA, _ISL_SWIZZLE(BLUE, GREEN, RED, ZERO), 1, 1)),
+ ycbcr_fmt(VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR, 3,
+ y_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 2, 2),
+ chroma_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 2, 2)),
+ ycbcr_fmt(VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR, 2,
+ y_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R8G8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, RED, ZERO, ZERO), 2, 2)),
+ ycbcr_fmt(VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR, 3,
+ y_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 2, 1),
+ chroma_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 2, 1)),
+ ycbcr_fmt(VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR, 2,
+ y_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R8G8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, RED, ZERO, ZERO), 2, 1)),
+ ycbcr_fmt(VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR, 3,
+ y_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 1, 1)),
+
+ fmt_unsupported(VK_FORMAT_R10X6_UNORM_PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_R12X4_UNORM_PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR),
+ fmt_unsupported(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR),
+ /* TODO: it is possible to enable the following 2 formats, but that
+ * requires further refactoring of how we handle multiplanar formats.
+ */
+ fmt_unsupported(VK_FORMAT_G16B16G16R16_422_UNORM_KHR),
+ fmt_unsupported(VK_FORMAT_B16G16R16G16_422_UNORM_KHR),
+
+ ycbcr_fmt(VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR, 3,
+ y_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 2, 2),
+ chroma_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 2, 2)),
+ ycbcr_fmt(VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR, 2,
+ y_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R16G16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, RED, ZERO, ZERO), 2, 2)),
+ ycbcr_fmt(VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR, 3,
+ y_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 2, 1),
+ chroma_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 2, 1)),
+ ycbcr_fmt(VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR, 2,
+ y_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R16G16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, RED, ZERO, ZERO), 2, 1)),
+ ycbcr_fmt(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR, 3,
+ y_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 1, 1),
+ chroma_plane(ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 1, 1)),
+};
+
#undef _fmt
#undef swiz_fmt1
#undef fmt1
@@ -284,7 +380,10 @@ static const struct {
const struct anv_format *formats;
uint32_t n_formats;
} anv_formats[] = {
- [0] = { .formats = main_formats, .n_formats = ARRAY_SIZE(main_formats), },
+ [0] = { .formats = main_formats,
+ .n_formats = ARRAY_SIZE(main_formats), },
+ [_VK_KHR_sampler_ycbcr_conversion_number] = { .formats = ycbcr_formats,
+ .n_formats = ARRAY_SIZE(ycbcr_formats), },
};
const struct anv_format *
@@ -496,6 +595,53 @@ anv_physical_device_get_format_properties(struct anv_physical_device *physical_d
linear = 0;
}
+ if (format && format->can_ycbcr) {
+ VkFormatFeatureFlags ycbcr_features = 0;
+
+ /* The sampler doesn't have support for mid point when it handles YUV on
+ * its own.
+ */
+ if (isl_format_is_yuv(format->planes[0].isl_format)) {
+ /* TODO: We've disabled linear implicit reconstruction with the
+ * sampler. The failures show a slightly out of range values on the
+ * bottom left of the sampled image.
+ */
+ ycbcr_features |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
+ } else {
+ ycbcr_features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR |
+ VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR |
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR;
+ }
+
+ /* We can support cosited chroma locations when handle planes with our
+ * own shader snippets.
+ */
+ for (unsigned p = 0; p < format->n_planes; p++) {
+ if (format->planes[p].denominator_scales[0] > 1 ||
+ format->planes[p].denominator_scales[1] > 1) {
+ ycbcr_features |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR;
+ break;
+ }
+ }
+
+ if (format->n_planes > 1)
+ ycbcr_features |= VK_FORMAT_FEATURE_DISJOINT_BIT_KHR;
+
+ linear |= ycbcr_features;
+ tiled |= ycbcr_features;
+
+ const VkFormatFeatureFlags disallowed_ycbcr_image_features =
+ VK_FORMAT_FEATURE_BLIT_SRC_BIT |
+ VK_FORMAT_FEATURE_BLIT_DST_BIT |
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT |
+ VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
+
+ linear &= ~disallowed_ycbcr_image_features;
+ tiled &= ~disallowed_ycbcr_image_features;
+ buffer = 0;
+ }
+
out_properties->linearTilingFeatures = linear;
out_properties->optimalTilingFeatures = tiled;
out_properties->bufferFeatures = buffer;
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 879f481f2a1..36aa86141fc 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2172,12 +2172,22 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
struct anv_format_plane {
enum isl_format isl_format:16;
struct isl_swizzle swizzle;
+
+ /* Whether this plane contains chroma channels */
+ bool has_chroma;
+
+ /* For downscaling of YUV planes */
+ uint8_t denominator_scales[2];
+
+ /* How to map sampled ycbcr planes to a single 4 component element. */
+ struct isl_swizzle ycbcr_swizzle;
};
struct anv_format {
struct anv_format_plane planes[3];
uint8_t n_planes;
+ bool can_ycbcr;
};
static inline uint32_t
diff --git a/src/intel/vulkan/vk_format_info.h b/src/intel/vulkan/vk_format_info.h
index a680a6f24b3..167938ac109 100644
--- a/src/intel/vulkan/vk_format_info.h
+++ b/src/intel/vulkan/vk_format_info.h
@@ -47,6 +47,33 @@ vk_format_aspects(VkFormat format)
case VK_FORMAT_D32_SFLOAT:
return VK_IMAGE_ASPECT_DEPTH_BIT;
+ case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
+ case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
+ case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
+ case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
+ case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
+ case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
+ return (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR |
+ VK_IMAGE_ASPECT_PLANE_1_BIT_KHR |
+ VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
+
+ case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
+ case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
+ case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
+ case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
+ case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
+ return (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR |
+ VK_IMAGE_ASPECT_PLANE_1_BIT_KHR);
+
default:
return VK_IMAGE_ASPECT_COLOR_BIT;
}
--
2.14.2
More information about the mesa-dev
mailing list