VBoxVideo.cpp revision c9caddc020c26660df7abb29da66f5161e0d850d
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * VirtualBox Video miniport driver for NT/2k/XP
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Based on DDK sample code.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * available from http://www.virtualbox.org. This file is free software;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * you can redistribute it and/or modify it under the terms of the GNU
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * General Public License (GPL) as published by the Free Software
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * additional information or have any questions.
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync#if _MSC_VER >= 1400 /* bird: MS fixed swprintf to be standard-conforming... */
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsyncextern "C" int __cdecl swprintf(wchar_t *, const wchar_t *, ...);
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsyncstatic WCHAR VBoxAdapterString[] = L"VirtualBox Video Adapter";
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsyncstatic WCHAR VBoxBiosString[] = L"Version 0xB0C2 or later";
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * Globals for the last custom resolution set. This is important
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * for system startup so that we report the last currently set
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * custom resolution and Windows can use it again.
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsyncint vboxVbvaEnable (PDEVICE_EXTENSION pDevExt, ULONG ulEnable, VBVAENABLERESULT *pVbvaResult);
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsyncULONG DriverEntry(IN PVOID Context1, IN PVOID Context2)
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync dprintf(("VBoxVideo::DriverEntry. Built %s %s\n", __DATE__, __TIME__));
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync VideoPortZeroMemory(&InitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync // nowhere documented but without the following line, NT4 SP0 will choke
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync InitData.HwGetVideoChildDescriptor = VBoxVideoGetChildDescriptor;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync InitData.HwDeviceExtensionSize = sizeof(DEVICE_EXTENSION);
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync // our DDK is at the Win2k3 level so we have to take special measures
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync // for backwards compatibility
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync InitData.HwInitDataSize = SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync InitData.HwInitDataSize = SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync rc = VideoPortInitialize(Context1, Context2, &InitData, NULL);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo::DriverEntry: returning with rc = 0x%x\n", rc));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncRoutine Description:
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync This routine is used to read back various registry values.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync HwDeviceExtension
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync Supplies a pointer to the miniport's device extension.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync Context value passed to the get registry parameters routine.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync If this is not null assume it's a ULONG* and save the data value in it.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync Name of the value requested.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync Pointer to the requested data.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ValueLength
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync Length of the requested data.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncReturn Value:
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync If the variable doesn't exist return an error,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if a context is supplied assume it's a PULONG and fill in the value
32c16cab49ef1ab1aea3b3340fbc133b99ee8b20vboxsync and return no error, else if the value is non-zero return an error.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncVP_STATUS VBoxRegistryCallback(PVOID HwDeviceExtension, PVOID Context,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync PWSTR ValueName, PVOID ValueData, ULONG ValueLength)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync //dprintf(("VBoxVideo::VBoxRegistryCallback: Context: %p, ValueName: %S, ValueData: %p, ValueLength: %d\n",
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // Context, ValueName, ValueData, ValueLength));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Global list of supported standard video modes. It will be
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * filled dynamically.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncstatic VIDEO_MODE_INFORMATION VideoModes[MAX_VIDEO_MODES + 2] = { 0 };
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/* number of available video modes, set by VBoxBuildModesTable */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncstatic uint32_t g_xresNoVRAM = 0, g_yresNoVRAM = 0, g_bppNoVRAM = 0;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Helper function to dynamically build our table of standard video
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * modes. We take the amount of VRAM and create modes with standard
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * geometries until we've either reached the maximum number of modes
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * or the available VRAM does not allow for additional modes.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncVOID VBoxBuildModesTable(PDEVICE_EXTENSION DeviceExtension)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* we need this static counter to always have a new mode index for our */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* custom video mode, otherwise Windows thinks there is no mode switch */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync static int gInvocationCounter = 0;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* the resolution matrix */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* standard modes */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* multi screen modes with 1280x1024 */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* multi screen modes with 1600x1200 */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync size_t matrixSize = sizeof(resolutionMatrix) / sizeof(resolutionMatrix[0]);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* there are 4 color depths: 8, 16, 24 and 32bpp and we reserve 50% of the modes for other sources */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync size_t maxModesPerColorDepth = MAX_VIDEO_MODES / 2 / 4;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* size of the VRAM in bytes */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ULONG vramSize = DeviceExtension->pPrimary->u.primary.ulMaxFrameBufferSize;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Query the y-offset from the host
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * 8 bit video modes
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync while (numModesCurrentColorDepth < maxModesPerColorDepth)
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync /* are there any modes left in the matrix? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* does the mode fit into the VRAM? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (resolutionMatrix[matrixIndex].xRes * resolutionMatrix[matrixIndex].yRes * 1 > (LONG)vramSize)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* does the host like that mode? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 8))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenWidth = resolutionMatrix[matrixIndex].xRes;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ScreenStride = resolutionMatrix[matrixIndex].xRes * 1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN |
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = resolutionMatrix[matrixIndex].xRes;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* a new mode has been filled in */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* advance to the next mode matrix entry */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync#endif /* VBOX_WITH_8BPP_MODES */
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync * 16 bit video modes
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync while (numModesCurrentColorDepth < maxModesPerColorDepth)
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync /* are there any modes left in the matrix? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* does the mode fit into the VRAM? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (resolutionMatrix[matrixIndex].xRes * resolutionMatrix[matrixIndex].yRes * 2 > (LONG)vramSize)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* does the host like that mode? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 16))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenWidth = resolutionMatrix[matrixIndex].xRes;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ScreenStride = resolutionMatrix[matrixIndex].xRes * 2;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = resolutionMatrix[matrixIndex].xRes;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* a new mode has been filled in */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* advance to the next mode matrix entry */
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * 24 bit video modes
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync while (numModesCurrentColorDepth < maxModesPerColorDepth)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* are there any modes left in the matrix? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* does the mode fit into the VRAM? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (resolutionMatrix[matrixIndex].xRes * resolutionMatrix[matrixIndex].yRes * 3 > (LONG)vramSize)
885b661364d7f51d087003dccaccb6d24610f654vboxsync /* does the host like that mode? */
885b661364d7f51d087003dccaccb6d24610f654vboxsync if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 24))
885b661364d7f51d087003dccaccb6d24610f654vboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
885b661364d7f51d087003dccaccb6d24610f654vboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenWidth = resolutionMatrix[matrixIndex].xRes;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ScreenStride = resolutionMatrix[matrixIndex].xRes * 3;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = resolutionMatrix[matrixIndex].xRes;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* a new mode has been filled in */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* advance to the next mode matrix entry */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * 32 bit video modes
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync while (numModesCurrentColorDepth < maxModesPerColorDepth)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* are there any modes left in the matrix? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* does the mode fit into the VRAM? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (resolutionMatrix[matrixIndex].xRes * resolutionMatrix[matrixIndex].yRes * 4 > (LONG)vramSize)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* does the host like that mode? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 32))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenWidth = resolutionMatrix[matrixIndex].xRes;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ScreenStride = resolutionMatrix[matrixIndex].xRes * 4;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = resolutionMatrix[matrixIndex].xRes;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* a new mode has been filled in */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* advance to the next mode matrix entry */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Next, check the registry for additional modes
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* check if there is space in the mode list */
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync status = VideoPortGetRegistryParameters(DeviceExtension->pPrimary,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* upon the first error, we give up */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync swprintf(keyname, L"CustomMode%dHeight", curKeyNo);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync status = VideoPortGetRegistryParameters(DeviceExtension->pPrimary,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* upon the first error, we give up */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync status = VideoPortGetRegistryParameters(DeviceExtension->pPrimary,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* upon the first error, we give up */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo: custom mode %u returned: xres = %u, yres = %u, bpp = %u\n",
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* first test: do the values make sense? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* round down width to be a multiple of 8 */
ad0efafe1c9e639fa7c26b9a956f20119031ca10vboxsync /* second test: does it fit within our VRAM? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* third test: does the host like the video mode? */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo: adding mode from registry: xres = %d, yres = %d, bpp = %d\n", xres, yres, bpp));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Build mode entry.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Note that we have to apply the y offset for the custom mode.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
15760030457c4d8548d42a9d543646b27eae7040vboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VisScreenHeight = yres - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ScreenStride = xres * (bpp / 8);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = xres;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = yres - yOffset;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* next run */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* only support 128 modes for now */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync } while(1);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Now we ask the host for a display change request. If there's one,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * this will be appended as a special mode so that it can be used by
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * the Additions service process. The mode table is guaranteed to have
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * two spare entries for this mode (alternating index thus 2).
15760030457c4d8548d42a9d543646b27eae7040vboxsync dprintf(("VBoxVideo: adding custom video mode as #%d, current mode: %d \n", gNumVideoModes + 1, DeviceExtension->CurrentMode));
15760030457c4d8548d42a9d543646b27eae7040vboxsync /* handle the startup case */
15760030457c4d8548d42a9d543646b27eae7040vboxsync dprintf(("VBoxVideo: using stored custom resolution %dx%dx%d\n", xres, yres, bpp));
15760030457c4d8548d42a9d543646b27eae7040vboxsync /* round down to multiple of 8 */
15760030457c4d8548d42a9d543646b27eae7040vboxsync dprintf(("VBoxVideo: rounding down xres from %d to %d\n", xres, xres & 0xfff8));
15760030457c4d8548d42a9d543646b27eae7040vboxsync /* take the current values for the fields that are not set */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* does the host like that mode? */
15760030457c4d8548d42a9d543646b27eae7040vboxsync /* we must have a valid video mode by now and it must fit within the VRAM */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* we need an alternating index */
ae97b5da9d2761f5713bbf37a466793bf9d89223vboxsync dprintf(("VBoxVideo: setting special mode to xres = %d, yres = %d, bpp = %d\n", xres, yres, bpp));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Build mode entry.
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync * Note that we do not apply the y offset for the custom mode. It is
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * only used for the predefined modes that the user can configure in
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * the display properties dialog.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ScreenStride = xres * (bpp / 8);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = xres;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = yres;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsync /* for the startup case, we need this mode twice due to the alternating mode number */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo: making a copy of the custom mode as #%d\n", gNumVideoModes + 1));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync memcpy(&VideoModes[gNumVideoModes], &VideoModes[gNumVideoModes - 1], sizeof(VIDEO_MODE_INFORMATION));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* store this video mode as the last custom video mode */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync status = VideoPortSetRegistryParameters(DeviceExtension, L"CustomXRes",
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync dprintf(("VBoxVideo: error %d writing CustomXRes\n", status));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync status = VideoPortSetRegistryParameters(DeviceExtension, L"CustomYRes",
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo: error %d writing CustomYRes\n", status));
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync status = VideoPortSetRegistryParameters(DeviceExtension, L"CustomBPP",
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo: error %d writing CustomBPP\n", status));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo: invalid parameters for special mode: (xres = %d, yres = %d, bpp = %d, vramSize = %d)\n",
ae97b5da9d2761f5713bbf37a466793bf9d89223vboxsync && (xres != g_xresNoVRAM || yres != g_yresNoVRAM || bpp != g_bppNoVRAM))
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync LogRel(("VBoxVideo: not enough VRAM for video mode %dx%dx%dbpp. Available: %d bytes. Required: more than %d bytes.\n",
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xres, yres, bpp, vramSize, xres * yres * (bpp / 8)));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo: host does not like special mode: (xres = %d, yres = %d, bpp = %d)\n",
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync dprintf(("VBoxVideo: VideoModes (CurrentMode = %d)\n", DeviceExtension->CurrentMode));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoModes[i].VisScreenHeight, VideoModes[i].BitsPerPlane));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/* Computes the size of a framebuffer. DualView has a few framebuffers of the computed size. */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid VBoxComputeFrameBufferSizes (PDEVICE_EXTENSION PrimaryExtension)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ULONG ulAvailable = PrimaryExtension->u.primary.cbVRAM
1b7486b51fc3d0e625fab9db6d46ee0113911adevboxsync ULONG ulAvailable = PrimaryExtension->u.primary.cbVRAM
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync#endif /* VBOX_WITH_HGSMI */
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync /* Size of a framebuffer. */
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync ULONG ulSize = ulAvailable / PrimaryExtension->u.primary.cDisplays;
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync /* Align down to 4096 bytes. */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo::VBoxComputeFrameBufferSizes: cbVRAM = 0x%08X, cDisplays = %d, ulSize = 0x%08X, ulSize * cDisplays = 0x%08X, slack = 0x%08X\n",
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync PrimaryExtension->u.primary.cbVRAM, PrimaryExtension->u.primary.cDisplays,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ulSize, ulSize * PrimaryExtension->u.primary.cDisplays,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ulAvailable - ulSize * PrimaryExtension->u.primary.cDisplays));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* Compute the size of the framebuffer. */
1b7486b51fc3d0e625fab9db6d46ee0113911adevboxsync /* Should not really get here. But still do it safely. */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync#endif /* !VBOX_WITH_HGSMI */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* Update the primary info. */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync PrimaryExtension->u.primary.ulMaxFrameBufferSize = ulSize;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync PrimaryExtension->u.primary.ulDisplayInformationSize = VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync#endif /* !VBOX_WITH_HGSMI */
0a6257a55820e2433e68420ff1a1ad89c398ce28vboxsync /* Update the per extension info. */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync Extension->ulFrameBufferOffset = ulFrameBufferOffset;
1b7486b51fc3d0e625fab9db6d46ee0113911adevboxsync /* That is assigned when a video mode is set. */
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync dprintf(("VBoxVideo::VBoxComputeFrameBufferSizes: [%d] ulFrameBufferOffset 0x%08X\n",
1b7486b51fc3d0e625fab9db6d46ee0113911adevboxsync ulFrameBufferOffset += PrimaryExtension->u.primary.ulMaxFrameBufferSize
1b7486b51fc3d0e625fab9db6d46ee0113911adevboxsync + PrimaryExtension->u.primary.ulDisplayInformationSize;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ulFrameBufferOffset += PrimaryExtension->u.primary.ulMaxFrameBufferSize;
ae97b5da9d2761f5713bbf37a466793bf9d89223vboxsync#endif /* VBOX_WITH_HGSMI */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncint VBoxMapAdapterMemory (PDEVICE_EXTENSION PrimaryExtension, void **ppv, ULONG ulOffset, ULONG ulSize)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo::VBoxMapAdapterMemory 0x%08X[0x%X]\n", ulOffset, ulSize));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync FrameBuffer.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS + ulOffset;
cafbe3edf3ba3d13bad27f9570b0b57c18f3c57fvboxsync VP_STATUS Status = VideoPortMapMemory (PrimaryExtension, FrameBuffer,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo::VBoxMapAdapterMemory rc = %d\n", Status));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid VBoxUnmapAdapterMemory (PDEVICE_EXTENSION PrimaryExtension, void **ppv)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VideoPortUnmapMemory(PrimaryExtension, *ppv, NULL);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncstatic void vboxQueryConf (PDEVICE_EXTENSION PrimaryExtension, uint32_t u32Index, ULONG *pulValue)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync dprintf(("VBoxVideo::vboxQueryConf: u32Index = %d\n", u32Index));
while (Extension)
VOID VBoxSetupDisplays(PDEVICE_EXTENSION PrimaryExtension, PVIDEO_PORT_CONFIG_INFO pConfigInfo, ULONG AdapterMemorySize)
dprintf(("VBoxVideo::VBoxSetupDisplays: VBoxMapAdapterMemory pvAdapterInfoirrmation failed rc = %d\n",
rc));
dprintf(("VBoxVideo::VBoxSetupDisplays: cbMiniportHeap = 0x%08X, PrimaryExtension->u.primary.cbMiniportHeap = 0x%08X, cbMiniportHeapMaxSize = 0x%08X\n",
cDisplays));
rc = pfnCreateSecondaryDisplay (PrimaryExtension, (PVOID*)&SecondaryExtension, VIDEO_DUALVIEW_REMOVABLE);
dprintf(("VBoxVideo::VBoxSetupDisplays: VideoPortCreateSecondaryDisplay returned %#x, SecondaryExtension = %p\n",
sizeof(VBoxChipType));
sizeof(VBoxDACType));
sizeof(ULONG));
sizeof(VBoxAdapterString));
sizeof(VBoxBiosString));
#ifndef VBOX_WITH_HGSMI
if (VBoxHGSMIIsSupported ())
return rc;
&gCustomXRes);
gCustomXRes = 0;
&gCustomYRes);
gCustomYRes = 0;
&gCustomBPP);
gCustomBPP = 0;
dprintf(("VBoxVideo: got stored custom resolution %dx%dx%d\n", gCustomXRes, gCustomYRes, gCustomBPP));
return TRUE;
return TRUE;
case IOCTL_VIDEO_RESET_DEVICE:
return TRUE;
return TRUE;
dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_SHARE_VIDEO_MEMORY: ERROR_INSUFFICIENT_BUFFER\n"));
|| ((pShareMemory->ViewOffset + pShareMemory->ViewSize) > pDevExt->pPrimary->u.primary.ulMaxFrameBufferSize) ) {
dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_SHARE_VIDEO_MEMORY - ERROR_INVALID_PARAMETER %x:%x size %x\n", pShareMemory->ViewOffset, pShareMemory->ViewSize, pDevExt->pPrimary->u.primary.ulMaxFrameBufferSize));
status = VideoPortMapMemory(HwDeviceExtension, shareAddress, &sharedViewSize, &inIoSpace, &virtualAddress);
dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY: ERROR_INSUFFICIENT_BUFFER\n"));
status = VideoPortUnmapMemory(HwDeviceExtension, pShareMemory->RequestedVirtualAddress, pShareMemory->ProcessHandle);
return TRUE;
return TRUE;
sizeof(VIDEO_CLUT))
return TRUE;
return TRUE;
if (vboxQueryHostWantsAbsolute())
#ifndef VBOX_WITH_HGSMI
Result = vboxUpdatePointerShape((PDEVICE_EXTENSION)HwDeviceExtension, &PointerAttributes, sizeof (PointerAttributes));
if (!Result)
if (vboxQueryHostWantsAbsolute())
#ifndef VBOX_WITH_HGSMI
Result = vboxUpdatePointerShape((PDEVICE_EXTENSION)HwDeviceExtension, &PointerAttributes, sizeof (PointerAttributes));
if (!Result)
dprintf(("VBoxVideo::VBoxVideoStartIO: Input buffer too small (%d bytes)\n", RequestPacket->InputBufferLength));
return TRUE;
if (vboxQueryHostWantsAbsolute())
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES)RequestPacket->InputBuffer;
dprintf(("\tBytes attached: %d\n", RequestPacket->InputBufferLength - sizeof(VIDEO_POINTER_ATTRIBUTES)));
#ifndef VBOX_WITH_HGSMI
Result = vboxUpdatePointerShape((PDEVICE_EXTENSION)HwDeviceExtension, pPointerAttributes, RequestPacket->InputBufferLength);
if (!Result)
if (vboxQueryHostWantsAbsolute())
return TRUE;
if (!Result)
return TRUE;
dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_SWITCH_DUALVIEW[%d] (%ld)\n", pDevExt->iDevice, ulAttach));
VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE + pDevExt->iDevice);
#ifndef VBOX_WITH_HGSMI
return FALSE;
case IOCTL_VIDEO_VBVA_ENABLE:
int rc;
return FALSE;
return FALSE;
return FALSE;
int rc;
dprintf(("VBoxVideo::IOCTL_VIDEO_VBOX_SETVISIBLEREGION: Output buffer too small: %d needed: %d!!!\n",
return FALSE;
dprintf(("VBoxVideo::VBoxVideoStartIO: Failed with rc=%x (hdr.rc=%x)\n", rc, (req) ? req->header.rc : -1));
return FALSE;
#ifdef VBOX_WITH_HGSMI
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
if (Result)
return TRUE;
return TRUE;
VbglTerminate ();
return TRUE;
return NO_ERROR;
return NO_ERROR;
int rc;
sizeof (VMMDevReqGuestCapabilities2),
dprintf(("VBoxVideoSetGraphicsCap: request failed, rc = %Rrc, VMMDev rc = %Rrc\n", rc, req->header.rc));
return TRUE;
VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
return TRUE;
return TRUE;
return TRUE;
#ifndef VBOX_WITH_HGSMI
#ifdef VBOX_WITH_HGSMI
return TRUE;
return FALSE;
#ifdef VBOX_WITH_HGSMI
return TRUE;
return TRUE;
return TRUE;
return TRUE;
dprintf(("VBoxVideo::VBoxVideoSetColorRegisters first entry %d num entries %d\n", ColorLookUpTable->FirstEntry, ColorLookUpTable->NumEntries));
return FALSE;
Entry++)
return TRUE;
return VIDEO_ENUM_MORE_DEVICES;
return ERROR_NO_MORE_DEVICES;
if (pPrimaryDevExt)
if (req)
dprintf(("VBoxVideo::vboxVbvaEnable: VbglQueryVMMDevMemory rc = %d, pVMMDevMemory = %p\n", rc, pVMMDevMemory));
if ( ulEnable
return rc;
sizeof (VMMDevVideoAccelFlush),
sizeof (VMMDevVideoAccelEnable),
return rc;