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/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include "VirtioGpu.h" #include "VirtioGpu.h"
@ -192,6 +193,47 @@ STATIC CONST GOP_RESOLUTION mGopResolutions[] = {
#define VGPU_GOP_FROM_GOP(GopPointer) \ #define VGPU_GOP_FROM_GOP(GopPointer) \
CR (GopPointer, VGPU_GOP, Gop, VGPU_GOP_SIG) 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 STATIC
VOID VOID
EFIAPI EFIAPI
@ -199,7 +241,9 @@ GopInitialize (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This 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); VgpuGop = VGPU_GOP_FROM_GOP (This);
@ -216,6 +260,37 @@ GopInitialize (
VgpuGop->GopMode.SizeOfInfo = sizeof VgpuGop->GopModeInfo; VgpuGop->GopMode.SizeOfInfo = sizeof VgpuGop->GopModeInfo;
VgpuGop->GopModeInfo.PixelFormat = PixelBltOnly; 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; return EFI_OUT_OF_RESOURCES;
} }
GopModeInfo->HorizontalResolution = mGopResolutions[ModeNumber].Width; if (ModeNumber < ARRAY_SIZE (mGopResolutions)) {
GopModeInfo->VerticalResolution = mGopResolutions[ModeNumber].Height; GopModeInfo->HorizontalResolution = mGopResolutions[ModeNumber].Width;
GopModeInfo->PixelFormat = PixelBltOnly; GopModeInfo->VerticalResolution = mGopResolutions[ModeNumber].Height;
GopModeInfo->PixelsPerScanLine = mGopResolutions[ModeNumber].Width; } 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; *SizeOfInfo = sizeof *GopModeInfo;
*Info = GopModeInfo; *Info = GopModeInfo;

View File

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

View File

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