virtgpu_virgl: strip scanout if necessary in resolve_use_flags

For guest running 3d virtgpu_virgl atop 2d virtgpu_virgl as host gbm
backend. Common and required scanout capable formats on the guest side
will fail virgl_supports_combination_natively check, resulting in
advertising no scanout support to the guest.

This change adds the same logic to resolve_use_flags before checking
support or asking for allocation to accommodate accordingly. Then
whether to strip scanout use_flag can align with native support on those
guest side scanout capable formats.

Advertising scanout for NV12 needs to go through virgl_add_combination
as well for the native support check. This is fixed by this CL.

The logic to strip scanout needs to be scanout use_flag specific to
avoid accidentally stripping scanout when the format fails texture check
but later passes the emulation check because scanout has been stripped.
This is also fixed by this CL.

BUG=b:200969382
TEST=CQ and camera interop works

Change-Id: I9126773a1ee49d4cdaf1f7186612d5f4f5c6200e
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/3180981
Tested-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Lepton Wu <lepton@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Yiwei Zhang <zzyiwei@chromium.org>
This commit is contained in:
Yiwei Zhang 2021-09-24 06:24:30 +00:00 committed by Commit Bot
parent b73dd1deac
commit 9420ffe3db
5 changed files with 38 additions and 19 deletions

2
drv.c
View file

@ -662,7 +662,7 @@ uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_fl
uint64_t drv_resolve_use_flags(struct driver *drv, uint32_t format, uint64_t use_flags)
{
if (drv->backend->resolve_use_flags)
return drv->backend->resolve_use_flags(format, use_flags);
return drv->backend->resolve_use_flags(drv, format, use_flags);
return use_flags;
}

View file

@ -91,7 +91,7 @@ struct backend {
int (*bo_invalidate)(struct bo *bo, struct mapping *mapping);
int (*bo_flush)(struct bo *bo, struct mapping *mapping);
uint32_t (*resolve_format)(uint32_t format, uint64_t use_flags);
uint64_t (*resolve_use_flags)(uint32_t format, uint64_t use_flags);
uint64_t (*resolve_use_flags)(struct driver *drv, uint32_t format, uint64_t use_flags);
size_t (*num_planes_from_modifier)(struct driver *drv, uint32_t format, uint64_t modifier);
int (*resource_info)(struct bo *bo, uint32_t strides[DRV_MAX_PLANES],
uint32_t offsets[DRV_MAX_PLANES], uint64_t *format_modifier);

View file

@ -666,7 +666,7 @@ uint32_t drv_resolve_format_helper(uint32_t format, uint64_t use_flags)
}
}
uint64_t drv_resolve_use_flags_helper(uint32_t format, uint64_t use_flags)
uint64_t drv_resolve_use_flags_helper(struct driver *drv, uint32_t format, uint64_t use_flags)
{
if (format == DRM_FORMAT_YVU420_ANDROID)
return use_flags & ~BO_USE_SCANOUT;

View file

@ -52,7 +52,7 @@ uint64_t drv_pick_modifier(const uint64_t *modifiers, uint32_t count,
bool drv_has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier);
uint32_t drv_get_standard_fourcc(uint32_t fourcc_internal);
uint32_t drv_resolve_format_helper(uint32_t format, uint64_t use_flags);
uint64_t drv_resolve_use_flags_helper(uint32_t format, uint64_t use_flags);
uint64_t drv_resolve_use_flags_helper(struct driver *drv, uint32_t format, uint64_t use_flags);
#ifdef __cplusplus
}

View file

@ -36,8 +36,8 @@ static const uint32_t dumb_texture_source_formats[] = {
};
static const uint32_t texture_source_formats[] = {
DRM_FORMAT_NV12, DRM_FORMAT_NV21, DRM_FORMAT_R8, DRM_FORMAT_R16,
DRM_FORMAT_RG88, DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR16161616F
DRM_FORMAT_NV21, DRM_FORMAT_R8, DRM_FORMAT_R16, DRM_FORMAT_RG88,
DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR16161616F
};
extern struct virtgpu_param params[];
@ -334,12 +334,10 @@ static bool virgl_supports_combination_through_emulation(struct driver *drv, uin
static void virgl_add_combination(struct driver *drv, uint32_t drm_format,
struct format_metadata *metadata, uint64_t use_flags)
{
struct virgl_priv *priv = (struct virgl_priv *)drv->priv;
if (params[param_3d].value && priv->caps.max_version >= 1) {
if ((use_flags & BO_USE_SCANOUT) && priv->caps_is_v2 &&
!virgl_supports_combination_natively(drv, drm_format, use_flags)) {
drv_log("Scanout format: %d\n", drm_format);
if (params[param_3d].value) {
if ((use_flags & BO_USE_SCANOUT) &&
!virgl_supports_combination_natively(drv, drm_format, BO_USE_SCANOUT)) {
drv_log("Strip scanout on format: %d\n", drm_format);
use_flags &= ~BO_USE_SCANOUT;
}
@ -580,10 +578,12 @@ static int virgl_init(struct driver *drv)
virgl_add_combinations(drv, texture_source_formats,
ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA,
BO_USE_TEXTURE_MASK);
drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE |
BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER |
BO_USE_SCANOUT);
/* NV12 with scanout must flow through virgl_add_combination, so that the native
* support is checked and scanout use_flag can be conditionally stripped. */
virgl_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,
BO_USE_TEXTURE_MASK | BO_USE_CAMERA_READ |
BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
BO_USE_HW_VIDEO_ENCODER | BO_USE_SCANOUT);
} else {
/* Virtio primary plane only allows this format. */
virgl_add_combination(drv, DRM_FORMAT_XRGB8888, &LINEAR_METADATA,
@ -953,7 +953,7 @@ static uint32_t virgl_resolve_format(uint32_t format, uint64_t use_flags)
}
}
static uint64_t virgl_resolve_use_flags(uint32_t format, uint64_t use_flags)
static uint64_t virgl_resolve_use_flags(struct driver *drv, uint32_t format, uint64_t use_flags)
{
if (format == DRM_FORMAT_YVU420_ANDROID) {
use_flags &= ~BO_USE_SCANOUT;
@ -967,8 +967,27 @@ static uint64_t virgl_resolve_use_flags(uint32_t format, uint64_t use_flags)
return use_flags;
}
if (!params[param_3d].value && format != DRM_FORMAT_XRGB8888)
return use_flags & ~BO_USE_SCANOUT;
if (params[param_3d].value) {
switch (format) {
/* formats need to support scanout */
case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_RGB565:
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_NV12:
/* strip scanout use_flag if necessary */
if ((use_flags & BO_USE_SCANOUT) &&
!virgl_supports_combination_natively(drv, format, BO_USE_SCANOUT))
return use_flags & ~BO_USE_SCANOUT;
break;
default:
break;
}
} else {
if (format != DRM_FORMAT_XRGB8888)
return use_flags & ~BO_USE_SCANOUT;
}
return use_flags;
}