From 916f90baa547b3ebef8fa87c530e2f0c8e35e1e3 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 8 Apr 2022 10:23:33 +0200 Subject: [PATCH] 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 Reviewed-by: Ard Biesheuvel --- OvmfPkg/VirtioGpuDxe/Gop.c | 92 ++++++++++++++++++++++++++++-- OvmfPkg/VirtioGpuDxe/VirtioGpu.h | 6 ++ OvmfPkg/VirtioGpuDxe/VirtioGpu.inf | 6 ++ 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/OvmfPkg/VirtioGpuDxe/Gop.c b/OvmfPkg/VirtioGpuDxe/Gop.c index 05daefcbfb..70a81c10c8 100644 --- a/OvmfPkg/VirtioGpuDxe/Gop.c +++ b/OvmfPkg/VirtioGpuDxe/Gop.c @@ -9,6 +9,7 @@ **/ #include +#include #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; diff --git a/OvmfPkg/VirtioGpuDxe/VirtioGpu.h b/OvmfPkg/VirtioGpuDxe/VirtioGpu.h index 1d781088bb..45da564152 100644 --- a/OvmfPkg/VirtioGpuDxe/VirtioGpu.h +++ b/OvmfPkg/VirtioGpuDxe/VirtioGpu.h @@ -151,6 +151,12 @@ struct VGPU_GOP_STRUCT { // BackingStore is non-NULL. // VOID *BackingStoreMap; + + // + // native display resolution + // + UINT32 NativeXRes; + UINT32 NativeYRes; }; // diff --git a/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf b/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf index 9e66bcd4b9..d88c87e129 100644 --- a/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf +++ b/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf @@ -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 -- 2.39.2