OvmfPkg/VirtioGpuDxe: query native display resolution from host

Try query native display resolution from the host.  When successful,
setup PcdVideoHorizontalResolution and PcdVideoVerticalResolution
accordingly and add the video mode to the GOP mode list if needed.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
Gerd Hoffmann 2022-04-08 10:23:33 +02:00 committed by mergify[bot]
parent 86de090b99
commit 916f90baa5
3 changed files with 99 additions and 5 deletions

View File

@ -9,6 +9,7 @@
**/
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include "VirtioGpu.h"
@ -192,6 +193,47 @@ STATIC CONST GOP_RESOLUTION mGopResolutions[] = {
#define VGPU_GOP_FROM_GOP(GopPointer) \
CR (GopPointer, VGPU_GOP, Gop, VGPU_GOP_SIG)
STATIC
VOID
EFIAPI
GopNativeResolution (
IN VGPU_GOP *VgpuGop,
OUT UINT32 *XRes,
OUT UINT32 *YRes
)
{
volatile VIRTIO_GPU_RESP_DISPLAY_INFO DisplayInfo;
EFI_STATUS Status;
UINTN Index;
Status = VirtioGpuGetDisplayInfo (VgpuGop->ParentBus, &DisplayInfo);
if (Status != EFI_SUCCESS) {
return;
}
for (Index = 0; Index < VIRTIO_GPU_MAX_SCANOUTS; Index++) {
if (!DisplayInfo.Pmodes[Index].Enabled ||
!DisplayInfo.Pmodes[Index].Rectangle.Width ||
!DisplayInfo.Pmodes[Index].Rectangle.Height)
{
continue;
}
DEBUG ((
DEBUG_INFO,
"%a: #%d: %dx%d\n",
__FUNCTION__,
Index,
DisplayInfo.Pmodes[Index].Rectangle.Width,
DisplayInfo.Pmodes[Index].Rectangle.Height
));
if ((*XRes == 0) || (*YRes == 0)) {
*XRes = DisplayInfo.Pmodes[Index].Rectangle.Width;
*YRes = DisplayInfo.Pmodes[Index].Rectangle.Height;
}
}
}
STATIC
VOID
EFIAPI
@ -199,7 +241,9 @@ GopInitialize (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This
)
{
VGPU_GOP *VgpuGop;
VGPU_GOP *VgpuGop;
EFI_STATUS Status;
UINT32 XRes = 0, YRes = 0, Index;
VgpuGop = VGPU_GOP_FROM_GOP (This);
@ -216,6 +260,37 @@ GopInitialize (
VgpuGop->GopMode.SizeOfInfo = sizeof VgpuGop->GopModeInfo;
VgpuGop->GopModeInfo.PixelFormat = PixelBltOnly;
//
// query host for display resolution
//
GopNativeResolution (VgpuGop, &XRes, &YRes);
if ((XRes == 0) || (YRes == 0)) {
return;
}
if (PcdGet8 (PcdVideoResolutionSource) == 0) {
Status = PcdSet32S (PcdVideoHorizontalResolution, XRes);
ASSERT_RETURN_ERROR (Status);
Status = PcdSet32S (PcdVideoVerticalResolution, YRes);
ASSERT_RETURN_ERROR (Status);
Status = PcdSet8S (PcdVideoResolutionSource, 2);
ASSERT_RETURN_ERROR (Status);
}
VgpuGop->NativeXRes = XRes;
VgpuGop->NativeYRes = YRes;
for (Index = 0; Index < ARRAY_SIZE (mGopResolutions); Index++) {
if ((mGopResolutions[Index].Width == XRes) &&
(mGopResolutions[Index].Height == YRes))
{
// native resolution already is in mode list
return;
}
}
// add to mode list
VgpuGop->GopMode.MaxMode++;
}
//
@ -242,10 +317,17 @@ GopQueryMode (
return EFI_OUT_OF_RESOURCES;
}
GopModeInfo->HorizontalResolution = mGopResolutions[ModeNumber].Width;
GopModeInfo->VerticalResolution = mGopResolutions[ModeNumber].Height;
GopModeInfo->PixelFormat = PixelBltOnly;
GopModeInfo->PixelsPerScanLine = mGopResolutions[ModeNumber].Width;
if (ModeNumber < ARRAY_SIZE (mGopResolutions)) {
GopModeInfo->HorizontalResolution = mGopResolutions[ModeNumber].Width;
GopModeInfo->VerticalResolution = mGopResolutions[ModeNumber].Height;
} else {
VGPU_GOP *VgpuGop = VGPU_GOP_FROM_GOP (This);
GopModeInfo->HorizontalResolution = VgpuGop->NativeXRes;
GopModeInfo->VerticalResolution = VgpuGop->NativeYRes;
}
GopModeInfo->PixelFormat = PixelBltOnly;
GopModeInfo->PixelsPerScanLine = GopModeInfo->HorizontalResolution;
*SizeOfInfo = sizeof *GopModeInfo;
*Info = GopModeInfo;

View File

@ -151,6 +151,12 @@ struct VGPU_GOP_STRUCT {
// BackingStore is non-NULL.
//
VOID *BackingStoreMap;
//
// native display resolution
//
UINT32 NativeXRes;
UINT32 NativeYRes;
};
//

View File

@ -25,6 +25,7 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
@ -43,3 +44,8 @@
gEfiGraphicsOutputProtocolGuid ## BY_START
gEfiPciIoProtocolGuid ## TO_START
gVirtioDeviceProtocolGuid ## TO_START
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution