]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/VirtioGpuDxe: query native display resolution from host
authorGerd Hoffmann <kraxel@redhat.com>
Fri, 8 Apr 2022 08:23:33 +0000 (10:23 +0200)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Mon, 25 Apr 2022 21:01:13 +0000 (21:01 +0000)
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>
OvmfPkg/VirtioGpuDxe/Gop.c
OvmfPkg/VirtioGpuDxe/VirtioGpu.h
OvmfPkg/VirtioGpuDxe/VirtioGpu.inf

index 05daefcbfbc825adb2d4ed60ed670e488c97c315..70a81c10c8b536c8598005569e4f43d40567da20 100644 (file)
@@ -9,6 +9,7 @@
 **/\r
 \r
 #include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
 \r
 #include "VirtioGpu.h"\r
 \r
@@ -192,6 +193,47 @@ STATIC CONST GOP_RESOLUTION  mGopResolutions[] = {
 #define VGPU_GOP_FROM_GOP(GopPointer) \\r
           CR (GopPointer, VGPU_GOP, Gop, VGPU_GOP_SIG)\r
 \r
+STATIC\r
+VOID\r
+EFIAPI\r
+GopNativeResolution (\r
+  IN  VGPU_GOP  *VgpuGop,\r
+  OUT UINT32    *XRes,\r
+  OUT UINT32    *YRes\r
+  )\r
+{\r
+  volatile VIRTIO_GPU_RESP_DISPLAY_INFO  DisplayInfo;\r
+  EFI_STATUS                             Status;\r
+  UINTN                                  Index;\r
+\r
+  Status = VirtioGpuGetDisplayInfo (VgpuGop->ParentBus, &DisplayInfo);\r
+  if (Status != EFI_SUCCESS) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < VIRTIO_GPU_MAX_SCANOUTS; Index++) {\r
+    if (!DisplayInfo.Pmodes[Index].Enabled ||\r
+        !DisplayInfo.Pmodes[Index].Rectangle.Width ||\r
+        !DisplayInfo.Pmodes[Index].Rectangle.Height)\r
+    {\r
+      continue;\r
+    }\r
+\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "%a: #%d: %dx%d\n",\r
+      __FUNCTION__,\r
+      Index,\r
+      DisplayInfo.Pmodes[Index].Rectangle.Width,\r
+      DisplayInfo.Pmodes[Index].Rectangle.Height\r
+      ));\r
+    if ((*XRes == 0) || (*YRes == 0)) {\r
+      *XRes = DisplayInfo.Pmodes[Index].Rectangle.Width;\r
+      *YRes = DisplayInfo.Pmodes[Index].Rectangle.Height;\r
+    }\r
+  }\r
+}\r
+\r
 STATIC\r
 VOID\r
 EFIAPI\r
@@ -199,7 +241,9 @@ GopInitialize (
   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL  *This\r
   )\r
 {\r
-  VGPU_GOP  *VgpuGop;\r
+  VGPU_GOP    *VgpuGop;\r
+  EFI_STATUS  Status;\r
+  UINT32      XRes = 0, YRes = 0, Index;\r
 \r
   VgpuGop = VGPU_GOP_FROM_GOP (This);\r
 \r
@@ -216,6 +260,37 @@ GopInitialize (
   VgpuGop->GopMode.SizeOfInfo = sizeof VgpuGop->GopModeInfo;\r
 \r
   VgpuGop->GopModeInfo.PixelFormat = PixelBltOnly;\r
+\r
+  //\r
+  // query host for display resolution\r
+  //\r
+  GopNativeResolution (VgpuGop, &XRes, &YRes);\r
+  if ((XRes == 0) || (YRes == 0)) {\r
+    return;\r
+  }\r
+\r
+  if (PcdGet8 (PcdVideoResolutionSource) == 0) {\r
+    Status = PcdSet32S (PcdVideoHorizontalResolution, XRes);\r
+    ASSERT_RETURN_ERROR (Status);\r
+    Status = PcdSet32S (PcdVideoVerticalResolution, YRes);\r
+    ASSERT_RETURN_ERROR (Status);\r
+    Status = PcdSet8S (PcdVideoResolutionSource, 2);\r
+    ASSERT_RETURN_ERROR (Status);\r
+  }\r
+\r
+  VgpuGop->NativeXRes = XRes;\r
+  VgpuGop->NativeYRes = YRes;\r
+  for (Index = 0; Index < ARRAY_SIZE (mGopResolutions); Index++) {\r
+    if ((mGopResolutions[Index].Width == XRes) &&\r
+        (mGopResolutions[Index].Height == YRes))\r
+    {\r
+      // native resolution already is in mode list\r
+      return;\r
+    }\r
+  }\r
+\r
+  // add to mode list\r
+  VgpuGop->GopMode.MaxMode++;\r
 }\r
 \r
 //\r
@@ -242,10 +317,17 @@ GopQueryMode (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  GopModeInfo->HorizontalResolution = mGopResolutions[ModeNumber].Width;\r
-  GopModeInfo->VerticalResolution   = mGopResolutions[ModeNumber].Height;\r
-  GopModeInfo->PixelFormat          = PixelBltOnly;\r
-  GopModeInfo->PixelsPerScanLine    = mGopResolutions[ModeNumber].Width;\r
+  if (ModeNumber < ARRAY_SIZE (mGopResolutions)) {\r
+    GopModeInfo->HorizontalResolution = mGopResolutions[ModeNumber].Width;\r
+    GopModeInfo->VerticalResolution   = mGopResolutions[ModeNumber].Height;\r
+  } else {\r
+    VGPU_GOP  *VgpuGop = VGPU_GOP_FROM_GOP (This);\r
+    GopModeInfo->HorizontalResolution = VgpuGop->NativeXRes;\r
+    GopModeInfo->VerticalResolution   = VgpuGop->NativeYRes;\r
+  }\r
+\r
+  GopModeInfo->PixelFormat       = PixelBltOnly;\r
+  GopModeInfo->PixelsPerScanLine = GopModeInfo->HorizontalResolution;\r
 \r
   *SizeOfInfo = sizeof *GopModeInfo;\r
   *Info       = GopModeInfo;\r
index 1d781088bb3f90f37a4bf59500320d0505b6dcfe..45da56415297ba430f9c3d35454fad1925c46a5a 100644 (file)
@@ -151,6 +151,12 @@ struct VGPU_GOP_STRUCT {
   // BackingStore is non-NULL.\r
   //\r
   VOID                                    *BackingStoreMap;\r
+\r
+  //\r
+  // native display resolution\r
+  //\r
+  UINT32                                  NativeXRes;\r
+  UINT32                                  NativeYRes;\r
 };\r
 \r
 //\r
index 9e66bcd4b97f9182f1681682a2a67b39b3c6acf8..d88c87e129f0da5ec7a936eb9e1d18b8c3518278 100644 (file)
@@ -25,6 +25,7 @@
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
   OvmfPkg/OvmfPkg.dec\r
 \r
 [LibraryClasses]\r
@@ -43,3 +44,8 @@
   gEfiGraphicsOutputProtocolGuid ## BY_START\r
   gEfiPciIoProtocolGuid          ## TO_START\r
   gVirtioDeviceProtocolGuid      ## TO_START\r
+\r
+[Pcd]\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution\r