egl, mesa: add support for NV15 and NV20 textures
Support external images with 10 bit YUV in NV15 and NV20 formats. These are produced by some hardware decoders, so this will be useful. Signed-off-by: Eric R. Smith <eric.smith@collabora.com> Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31854>
This commit is contained in:
@@ -2332,6 +2332,9 @@ dri2_num_fourcc_format_planes(EGLint format)
|
||||
case DRM_FORMAT_NV21:
|
||||
case DRM_FORMAT_NV16:
|
||||
case DRM_FORMAT_NV61:
|
||||
case DRM_FORMAT_NV15:
|
||||
case DRM_FORMAT_NV20:
|
||||
case DRM_FORMAT_NV30:
|
||||
case DRM_FORMAT_P010:
|
||||
case DRM_FORMAT_P012:
|
||||
case DRM_FORMAT_P016:
|
||||
|
||||
@@ -856,6 +856,26 @@ static const struct dri2_format_mapping g8r8_b8r8_mapping = {
|
||||
{ 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } }
|
||||
};
|
||||
|
||||
static const struct dri2_format_mapping r10_g10b10_mapping = {
|
||||
DRM_FORMAT_NV15,
|
||||
__DRI_IMAGE_FORMAT_NONE,
|
||||
__DRI_IMAGE_COMPONENTS_Y_UV,
|
||||
PIPE_FORMAT_R10_G10B10_420_UNORM,
|
||||
2,
|
||||
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE },
|
||||
{ 1, 1, 1, __DRI_IMAGE_FORMAT_NONE } }
|
||||
};
|
||||
|
||||
static const struct dri2_format_mapping r10_g10b10_mapping_422 = {
|
||||
DRM_FORMAT_NV20,
|
||||
__DRI_IMAGE_FORMAT_NONE,
|
||||
__DRI_IMAGE_COMPONENTS_Y_UV,
|
||||
PIPE_FORMAT_R10_G10B10_422_UNORM,
|
||||
2,
|
||||
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE },
|
||||
{ 1, 1, 0, __DRI_IMAGE_FORMAT_NONE } }
|
||||
};
|
||||
|
||||
static enum __DRIFixedRateCompression
|
||||
to_dri_compression_rate(uint32_t rate)
|
||||
{
|
||||
@@ -944,6 +964,21 @@ dri_create_image_from_winsys(struct dri_screen *screen,
|
||||
tex_usage |= PIPE_BIND_SAMPLER_VIEW;
|
||||
}
|
||||
|
||||
/* For NV15, see if we have support for sampling r10_g10b10 */
|
||||
if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV15 &&
|
||||
pscreen->is_format_supported(pscreen, PIPE_FORMAT_R10_G10B10_420_UNORM,
|
||||
screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
|
||||
map = &r10_g10b10_mapping;
|
||||
tex_usage |= PIPE_BIND_SAMPLER_VIEW;
|
||||
}
|
||||
|
||||
if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV20 &&
|
||||
pscreen->is_format_supported(pscreen, PIPE_FORMAT_R10_G10B10_422_UNORM,
|
||||
screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
|
||||
map = &r10_g10b10_mapping_422;
|
||||
tex_usage |= PIPE_BIND_SAMPLER_VIEW;
|
||||
}
|
||||
|
||||
/* For YV12 and I420, see if we have support for sampling r8_b8_g8 or r8_g8_b8 */
|
||||
if (!tex_usage && map->pipe_format == PIPE_FORMAT_IYUV) {
|
||||
if (map->dri_fourcc == DRM_FORMAT_YUV420 &&
|
||||
|
||||
@@ -550,6 +550,18 @@ static const struct dri2_format_mapping dri2_format_table[] = {
|
||||
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
|
||||
{ 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } },
|
||||
|
||||
/* 10 bit 4:2:0 and 4:2:2 formats; the components
|
||||
are tightly packed, so the planes don't correspond
|
||||
to any native DRI format */
|
||||
{ DRM_FORMAT_NV15, __DRI_IMAGE_FORMAT_NONE,
|
||||
__DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV15, 2,
|
||||
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE },
|
||||
{ 1, 1, 1, __DRI_IMAGE_FORMAT_NONE } } },
|
||||
{ DRM_FORMAT_NV20, __DRI_IMAGE_FORMAT_NONE,
|
||||
__DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV20, 2,
|
||||
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE },
|
||||
{ 1, 1, 0, __DRI_IMAGE_FORMAT_NONE } } },
|
||||
|
||||
{ DRM_FORMAT_P010, __DRI_IMAGE_FORMAT_NONE,
|
||||
__DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P010, 2,
|
||||
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
|
||||
|
||||
@@ -167,7 +167,7 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format,
|
||||
}
|
||||
|
||||
static bool
|
||||
is_nv12_as_r8_g8b8_supported(struct pipe_screen *screen, struct st_egl_image *out,
|
||||
is_fmt_as_r8_g8b8_supported(struct pipe_screen *screen, struct st_egl_image *out,
|
||||
unsigned usage, bool *native_supported)
|
||||
{
|
||||
if (out->format == PIPE_FORMAT_NV12 &&
|
||||
@@ -205,6 +205,33 @@ is_nv12_as_r8_g8b8_supported(struct pipe_screen *screen, struct st_egl_image *ou
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_fmt_as_r10_g10b10_supported(struct pipe_screen *screen, struct st_egl_image *out,
|
||||
unsigned usage, bool *native_supported)
|
||||
{
|
||||
if (out->format == PIPE_FORMAT_NV15 &&
|
||||
out->texture->format == PIPE_FORMAT_R10_G10B10_420_UNORM &&
|
||||
screen->is_format_supported(screen, PIPE_FORMAT_R10_G10B10_420_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
out->texture->nr_samples,
|
||||
out->texture->nr_storage_samples,
|
||||
usage)) {
|
||||
*native_supported = false;
|
||||
return true;
|
||||
}
|
||||
if (out->format == PIPE_FORMAT_NV20 &&
|
||||
out->texture->format == PIPE_FORMAT_R10_G10B10_422_UNORM &&
|
||||
screen->is_format_supported(screen, PIPE_FORMAT_R10_G10B10_422_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
out->texture->nr_samples,
|
||||
out->texture->nr_storage_samples,
|
||||
usage)) {
|
||||
*native_supported = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_i420_as_r8_g8_b8_420_supported(struct pipe_screen *screen,
|
||||
struct st_egl_image *out,
|
||||
@@ -257,7 +284,8 @@ st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_nv12_as_r8_g8b8_supported(screen, out, usage, native_supported) &&
|
||||
if (!is_fmt_as_r8_g8b8_supported(screen, out, usage, native_supported) &&
|
||||
!is_fmt_as_r10_g10b10_supported(screen, out, usage, native_supported) &&
|
||||
!is_i420_as_r8_g8_b8_420_supported(screen, out, usage, native_supported) &&
|
||||
!is_format_supported(screen, out->format, out->texture->nr_samples,
|
||||
out->texture->nr_storage_samples, usage,
|
||||
@@ -404,6 +432,22 @@ st_bind_egl_image(struct gl_context *ctx,
|
||||
texObj->RequiredTextureImageUnits = 2;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_NV15:
|
||||
if (stimg->texture->format == PIPE_FORMAT_R10_G10B10_420_UNORM) {
|
||||
texFormat = MESA_FORMAT_R10G10B10X2_UNORM;
|
||||
texObj->RequiredTextureImageUnits = 1;
|
||||
} else {
|
||||
unreachable("NV15 emulation requires R10_G10B10_420_UNORM support");
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_NV20:
|
||||
if (stimg->texture->format == PIPE_FORMAT_R10_G10B10_422_UNORM) {
|
||||
texFormat = MESA_FORMAT_R10G10B10X2_UNORM;
|
||||
texObj->RequiredTextureImageUnits = 1;
|
||||
} else {
|
||||
unreachable("NV20 emulation requires R10_G10B10_422_UNORM support");
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_P010:
|
||||
case PIPE_FORMAT_P012:
|
||||
case PIPE_FORMAT_P016:
|
||||
|
||||
@@ -96,6 +96,12 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog)
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case PIPE_FORMAT_NV15:
|
||||
if (stObj->pt->format == PIPE_FORMAT_R10_G10B10_420_UNORM) {
|
||||
key.lower_yuv |= (1 << unit);
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case PIPE_FORMAT_P010:
|
||||
case PIPE_FORMAT_P012:
|
||||
case PIPE_FORMAT_P016:
|
||||
@@ -109,6 +115,12 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog)
|
||||
}
|
||||
key.lower_nv21 |= (1 << unit);
|
||||
break;
|
||||
case PIPE_FORMAT_NV20:
|
||||
if (stObj->pt->format == PIPE_FORMAT_R10_G10B10_422_UNORM) {
|
||||
key.lower_yuv |= (1 << unit);
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case PIPE_FORMAT_IYUV:
|
||||
if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM ||
|
||||
stObj->pt->format == PIPE_FORMAT_R8_B8_G8_420_UNORM) {
|
||||
|
||||
@@ -415,6 +415,18 @@ st_get_sampler_view_format(const struct st_context *st,
|
||||
}
|
||||
format = PIPE_FORMAT_R8_UNORM;
|
||||
break;
|
||||
case PIPE_FORMAT_NV15:
|
||||
if (texObj->pt->format == PIPE_FORMAT_R10_G10B10_420_UNORM) {
|
||||
format = PIPE_FORMAT_R10_G10B10_420_UNORM;
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case PIPE_FORMAT_NV20:
|
||||
if (texObj->pt->format == PIPE_FORMAT_R10_G10B10_422_UNORM) {
|
||||
format = PIPE_FORMAT_R10_G10B10_422_UNORM;
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case PIPE_FORMAT_P010:
|
||||
case PIPE_FORMAT_P012:
|
||||
case PIPE_FORMAT_P016:
|
||||
|
||||
@@ -1900,7 +1900,18 @@
|
||||
block: {width: 1, height: 1, depth: 1}
|
||||
channels: [UN8]
|
||||
swizzles: [X, 0, 0, 1]
|
||||
|
||||
- name: NV15
|
||||
layout: planar2
|
||||
colorspace: YUV
|
||||
block: {width: 1, height: 1, depth: 1}
|
||||
channels: []
|
||||
swizzles: [X, Y, Z, W]
|
||||
- name: NV20
|
||||
layout: planar2
|
||||
colorspace: YUV
|
||||
block: {width: 1, height: 1, depth: 1}
|
||||
channels: []
|
||||
swizzles: [X, Y, Z, W]
|
||||
|
||||
# RGB versions of NV12, YV12, P010, and P012 for hardware that supports sampling
|
||||
# from multiplane textures but needs color-space conversion in the shader.
|
||||
@@ -1922,6 +1933,18 @@
|
||||
block: {width: 1, height: 1, depth: 1}
|
||||
channels: [UN8]
|
||||
swizzles: [X, Y, Z, W]
|
||||
- name: R10_G10B10_420_UNORM
|
||||
layout: planar2
|
||||
colorspace: RGB
|
||||
block: {width: 4, height: 1, depth: 1}
|
||||
channels: [UN40]
|
||||
swizzles: [X, Y, Z, W]
|
||||
- name: R10_G10B10_422_UNORM
|
||||
layout: planar2
|
||||
colorspace: RGB
|
||||
block: {width: 4, height: 1, depth: 1}
|
||||
channels: [UN40]
|
||||
swizzles: [X, Y, Z, W]
|
||||
- name: R8_G8_B8_420_UNORM
|
||||
layout: planar3
|
||||
colorspace: RGB
|
||||
|
||||
@@ -86,6 +86,8 @@ def has_access(format):
|
||||
'nv12',
|
||||
'nv16',
|
||||
'nv21',
|
||||
'nv15',
|
||||
'nv20',
|
||||
'p010',
|
||||
'p012',
|
||||
'p016',
|
||||
@@ -118,6 +120,8 @@ def has_access(format):
|
||||
'r8_g8b8_420_unorm',
|
||||
'r8_b8g8_420_unorm',
|
||||
'g8_b8r8_420_unorm',
|
||||
'r10_g10b10_420_unorm',
|
||||
'r10_g10b10_422_unorm',
|
||||
'r8_g8_b8_420_unorm',
|
||||
'r8_b8_g8_420_unorm',
|
||||
'g8_b8_r8_420_unorm',
|
||||
|
||||
@@ -306,6 +306,8 @@ enum pipe_format {
|
||||
PIPE_FORMAT_NV12,
|
||||
PIPE_FORMAT_NV21,
|
||||
PIPE_FORMAT_NV16,
|
||||
PIPE_FORMAT_NV15,
|
||||
PIPE_FORMAT_NV20,
|
||||
|
||||
PIPE_FORMAT_Y8_400_UNORM,
|
||||
/* PIPE_FORMAT_Y8_U8_V8_420_UNORM = IYUV */
|
||||
@@ -526,6 +528,8 @@ enum pipe_format {
|
||||
PIPE_FORMAT_R8_G8B8_420_UNORM,
|
||||
PIPE_FORMAT_R8_B8G8_420_UNORM,
|
||||
PIPE_FORMAT_G8_B8R8_420_UNORM,
|
||||
PIPE_FORMAT_R10_G10B10_420_UNORM,
|
||||
PIPE_FORMAT_R10_G10B10_422_UNORM,
|
||||
PIPE_FORMAT_R8_G8_B8_420_UNORM,
|
||||
PIPE_FORMAT_R8_B8_G8_420_UNORM,
|
||||
PIPE_FORMAT_G8_B8_R8_420_UNORM,
|
||||
|
||||
Reference in New Issue
Block a user