**/\r
\r
#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
\r
#include "VirtioGpu.h"\r
\r
#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
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
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
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