Changeset 4027 in vbox for trunk/src/VBox/Additions/WINNT
- Timestamp:
- Aug 3, 2007 7:53:12 PM (17 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Display/dd.c
r3397 r4027 16 16 17 17 #ifdef DEBUG 18 #define LOG_ENABLED 18 #define LOG_ENABLED 1 19 19 #endif 20 20 … … 65 65 { 66 66 PPDEV pDev = (PPDEV)dhpdev; 67 BOOL bDefineDDrawHeap = FALSE; 68 DWORD cHeaps = 0; 69 VIDEOMEMORY *pVm = NULL; 67 70 68 71 DISPDBG((0, "%s: %p, %p, %p, %p, %p. %p\n", __FUNCTION__, dhpdev, pHalInfo, pdwNumHeaps, pvmList, pdwNumFourCCCodes, pdwFourCC)); … … 77 80 if (!(pvmList && pdwFourCC)) 78 81 { 82 memset(&pHalInfo->ddCaps, 0, sizeof(DDNTCORECAPS)); 83 pHalInfo->ddCaps.dwSize = sizeof(DDNTCORECAPS); 84 pHalInfo->ddCaps.dwVidMemTotal = pDev->cScreenSize - pDev->cFrameBufferSize; 85 pHalInfo->ddCaps.dwVidMemFree = pHalInfo->ddCaps.dwVidMemTotal; 86 87 pHalInfo->ddCaps.dwCaps = 0; 88 pHalInfo->ddCaps.dwCaps2 = 0; 89 90 /* Declare we can handle textures wider than the primary */ 91 pHalInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES; 92 93 pHalInfo->ddCaps.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 94 79 95 /* Create primary surface attributes */ 80 96 pHalInfo->vmiData.pvPrimary = pDev->pjScreen; … … 108 124 pHalInfo->vmiData.dwTextureAlign = 4; 109 125 } 110 memset(&pHalInfo->ddCaps, 0, sizeof(DDNTCORECAPS)); 111 pHalInfo->ddCaps.dwSize = sizeof(DDNTCORECAPS); 112 pHalInfo->ddCaps.dwVidMemTotal = pDev->cScreenSize; 113 pHalInfo->ddCaps.dwVidMemFree = pDev->cScreenSize; 114 115 pHalInfo->ddCaps.dwCaps = 0; 116 pHalInfo->ddCaps.dwCaps2 = 0; 117 118 /* Declare we can handle textures wider than the primary */ 119 pHalInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES; 120 121 pHalInfo->ddCaps.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 126 127 cHeaps = 0; 128 129 /* Do we have sufficient videomemory to create an off-screen heap for DDraw? */ 130 if (pDev->cScreenSize > pDev->cFrameBufferSize) 131 { 132 bDefineDDrawHeap = TRUE; 133 cHeaps++; 134 } 135 136 pDev->cHeaps = cHeaps; 137 *pdwNumHeaps = cHeaps; 138 139 // If pvmList is not NULL then we can go ahead and fill out the VIDEOMEMORY 140 // structures which define our requested heaps. 141 142 if(pvmList) { 143 144 pVm=pvmList; 145 146 // 147 // Snag a pointer to the video-memory list so that we can use it to 148 // call back to DirectDraw to allocate video memory: 149 // 150 pDev->pvmList = pVm; 151 152 // 153 // Define the heap for DirectDraw 154 // 155 if ( bDefineDDrawHeap ) 156 { 157 pVm->dwFlags = VIDMEM_ISLINEAR ; 158 pVm->fpStart = pDev->cFrameBufferSize; 159 pVm->fpEnd = pDev->cScreenSize; 160 161 pVm->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; 162 DISPDBG((0, "fpStart %ld fpEnd %ld\n", pVm->fpStart, pVm->fpEnd)); 163 164 pVm++; 165 } 166 } 122 167 123 168 #if 0 /* not mandatory */ … … 172 217 pCallBacks->dwFlags = 0; 173 218 174 /*175 219 pCallBacks->dwFlags = DDHAL_CB32_CREATESURFACE | DDHAL_CB32_CANCREATESURFACE; 176 220 pCallBacks->CreateSurface = DdCreateSurface; 177 221 pCallBacks->CanCreateSurface = DdCanCreateSurface; 178 pCallBacks->WaitForVerticalBlank = DdWaitForVerticalBlank; 179 pCallBacks->GetScanLine = DdGetScanLine; 180 pCallBacks->MapMemory = DdMapMemory; 181 DDHAL_CB32_WAITFORVERTICALBLANK | DDHAL_CB32_MAPMEMORY | DDHAL_CB32_GETSCANLINE 182 */ 222 // pCallBacks->WaitForVerticalBlank = DdWaitForVerticalBlank; 223 // pCallBacks->GetScanLine = DdGetScanLine; 224 // pCallBacks->MapMemory = DdMapMemory; 225 // DDHAL_CB32_WAITFORVERTICALBLANK | DDHAL_CB32_MAPMEMORY | DDHAL_CB32_GETSCANLINE 183 226 /* Note: pCallBacks->SetMode & pCallBacks->DestroyDriver are unused in Windows 2000 and up */ 184 227 … … 652 695 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev)); 653 696 654 // remember setting of exclusive mode in p pdev,697 // remember setting of exclusive mode in pDev, 655 698 // so GDI can stop to promote DeviceBitmaps into 656 699 // video memory -
trunk/src/VBox/Additions/WINNT/Graphics/Display/debug.c
r3389 r4027 15 15 #include "driver.h" 16 16 17 #ifdef DEBUG17 #ifdef LOG_ENABLED 18 18 19 19 #ifdef VBOX -
trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h
r3423 r4027 70 70 ULONG cScreenSize; // size of video memory, including 71 71 // offscreen memory. 72 ULONG cFrameBufferSize; // size of screen video memory 72 73 PVOID pOffscreenList; // linked list of DCI offscreen surfaces. 73 74 FLONG flRed; // For bitfields device, Red Mask … … 98 99 VBOXDISPLAYINFO *pInfo; 99 100 ULONG iDevice; 101 ULONG cbDisplayInformation; 100 102 #ifdef VBOX_WITH_DDRAW 101 103 BOOL bDdExclusiveMode; 102 104 DWORD dwNewDDSurfaceOffset; 105 DWORD cHeaps; 106 VIDEOMEMORY* pvmList; 103 107 #endif 104 108 }; -
trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c
r3560 r4027 13 13 \**************************************************************************/ 14 14 #ifdef DEBUG 15 #define LOG_ENABLED 15 #define LOG_ENABLED 1 16 16 #endif 17 17 … … 1000 1000 { 1001 1001 PPDEV pDev = (PPDEV)pDirectDraw->dhpdev; 1002 HBITMAP hbmDevice;1002 // HBITMAP hbmDevice; 1003 1003 DD_SURFACE_GLOBAL* pSurfaceGlobal; 1004 SIZEL sizl;1004 // SIZEL sizl; 1005 1005 1006 1006 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev)); -
trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c
r3380 r4027 66 66 DispInfo.u32DisplayInfoSize, pMemoryInformation->VideoRamLength)); 67 67 ppdev->pInfo = NULL; 68 ppdev->cbDisplayInformation = 0; 68 69 return; 69 70 } 70 71 71 72 ppdev->iDevice = DispInfo.iDevice; 73 ppdev->cbDisplayInformation = DispInfo.u32DisplayInfoSize; 72 74 73 75 pu8 = (uint8_t *)pMemoryInformation->VideoRamBase; … … 195 197 } 196 198 197 ppdev->cScreenSize = videoMemoryInformation.VideoRamLength;198 199 199 // 200 200 // Initialize the head of the offscreen list to NULL. … … 246 246 /* Setup the display information. */ 247 247 vboxSetupDisplayInfo (ppdev, &videoMemoryInformation); 248 249 ppdev->cScreenSize = videoMemoryInformation.VideoRamLength - ppdev->cbDisplayInformation; 250 ppdev->cFrameBufferSize = videoMemoryInformation.FrameBufferLength; 248 251 } 249 252 -
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp
r3563 r4027 43 43 static WCHAR VBoxBiosString[] = L"Version 0xB0C2 or later"; 44 44 45 /* Number of reported monitors. Defaults to 1 (no DualView) */46 static int gNumDisplays = 1;47 48 45 /* 49 46 * Globals for the last custom resolution set. This is important … … 197 194 198 195 /* size of the VRAM in bytes */ 199 ULONG vramSize = DeviceExtension-> ulMaxFrameBufferSize;196 ULONG vramSize = DeviceExtension->pPrimary->u.primary.ulMaxFrameBufferSize; 200 197 201 198 gNumVideoModes = 0; … … 700 697 701 698 /* Computes the size of a framebuffer. DualView has a few framebuffers of the computed size. */ 702 static ULONG VBoxVideoComputeMaxFrameBufferSize (ULONG AdapterMemorySize) 703 { 704 /* The VRAM layout: 705 * Last 4096 bytes - Adapter information area. 706 * Slack - what left after dividing the VRAM. 707 * 4096 bytes aligned framebuffers: 708 * last 4096 bytes of each framebuffer is the display information area. 709 */ 699 static void vboxComputeFrameBufferSizes (PDEVICE_EXTENSION PrimaryExtension) 700 { 701 ULONG ulAvailable = PrimaryExtension->u.primary.cbVRAM 702 - PrimaryExtension->u.primary.cbMiniportHeap 703 - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 710 704 711 705 /* Size of a framebuffer. */ 712 ULONG ulSize = (AdapterMemorySize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE) / gNumDisplays; 706 707 ULONG ulSize = ulAvailable / PrimaryExtension->u.primary.cDisplays; 713 708 714 709 /* Align down to 4096 bytes. */ 715 710 ulSize &= ~0xFFF; 716 711 717 dprintf(("VBoxVideo::VBoxVideoComputeMaxFrameBufferSize: AdapterMemorySize = 0x%08X, gNumDisplays = %d, ulSize = 0x%08X, ulSize * gNumDisplays = 0x%08X, slack = 0x%08X\n", 718 AdapterMemorySize, gNumDisplays, ulSize, ulSize * gNumDisplays, (AdapterMemorySize - 4096) - ulSize * gNumDisplays)); 712 dprintf(("VBoxVideo::vboxComputeFrameBufferSizes: cbVRAM = 0x%08X, cDisplays = %d, ulSize = 0x%08X, ulSize * cDisplays = 0x%08X, slack = 0x%08X\n", 713 PrimaryExtension->u.primary.cbVRAM, PrimaryExtension->u.primary.cDisplays, 714 ulSize, ulSize * PrimaryExtension->u.primary.cDisplays, 715 ulAvailable - ulSize * PrimaryExtension->u.primary.cDisplays)); 719 716 720 717 if (ulSize > VBOX_VIDEO_DISPLAY_INFORMATION_SIZE) … … 725 722 else 726 723 { 724 /* Should not really get here. But still do it safely. */ 727 725 ulSize = 0; 728 726 } 729 727 730 return ulSize; 731 } 732 733 static VOID VBoxMapAdapterInfo (PDEVICE_EXTENSION PrimaryExtension, ULONG AdapterMemorySize) 734 { 728 /* Update the primary info. */ 729 PrimaryExtension->u.primary.ulMaxFrameBufferSize = ulSize; 730 PrimaryExtension->u.primary.ulDisplayInformationSize = VBOX_VIDEO_DISPLAY_INFORMATION_SIZE; 731 732 /* Update the per extension info. */ 733 PDEVICE_EXTENSION Extension = PrimaryExtension; 734 ULONG ulFrameBufferOffset = 0; 735 while (Extension) 736 { 737 Extension->ulFrameBufferOffset = ulFrameBufferOffset; 738 /* That is assigned when a video mode is set. */ 739 Extension->ulFrameBufferSize = 0; 740 741 dprintf(("VBoxVideo::vboxComputeFrameBufferSizes: [%d] ulFrameBufferOffset 0x%08X\n", 742 ulFrameBufferOffset)); 743 744 ulFrameBufferOffset += PrimaryExtension->u.primary.ulMaxFrameBufferSize 745 + PrimaryExtension->u.primary.ulDisplayInformationSize; 746 747 Extension = Extension->pNext; 748 } 749 } 750 751 static int vboxMapAdapterMemory (PDEVICE_EXTENSION PrimaryExtension) 752 { 753 dprintf(("VBoxVideo::vboxMapAdapterMemory\n")); 754 735 755 PHYSICAL_ADDRESS FrameBuffer; 756 FrameBuffer.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS 757 + PrimaryExtension->u.primary.cbVRAM 758 - PrimaryExtension->u.primary.cbMiniportHeap 759 - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 760 761 PVOID VideoRamBase = NULL; 736 762 ULONG inIoSpace = 0; 737 VP_STATUS Status; 738 739 dprintf(("VBoxVideo::VBoxSetupAdapterInfo\n")); 740 741 FrameBuffer.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS + AdapterMemorySize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 742 743 PVOID VideoRamBase = NULL; 744 ULONG VideoRamLength = VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 745 746 Status = VideoPortMapMemory(PrimaryExtension, FrameBuffer, 747 &VideoRamLength, &inIoSpace, 748 &VideoRamBase); 763 ULONG VideoRamLength = PrimaryExtension->u.primary.cbMiniportHeap 764 + VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 765 766 VP_STATUS Status = VideoPortMapMemory (PrimaryExtension, FrameBuffer, 767 &VideoRamLength, &inIoSpace, 768 &VideoRamBase); 749 769 750 770 if (Status == NO_ERROR) 751 771 { 752 PrimaryExtension->AdapterInformation = VideoRamBase; 753 } 754 else 755 { 756 PrimaryExtension->AdapterInformation = NULL; 757 } 758 } 759 760 static VOID VBoxSetupAdapterInfo (PDEVICE_EXTENSION PrimaryExtension) 761 { 762 if (!PrimaryExtension->AdapterInformation) 763 { 764 return; 772 PrimaryExtension->u.primary.pvMiniportHeap = VideoRamBase; 773 PrimaryExtension->u.primary.pvAdapterInformation = (uint8_t *)VideoRamBase 774 + PrimaryExtension->u.primary.cbMiniportHeap; 765 775 } 766 776 767 /* That dublicates the code in VBoxSetupDisplays, better would be to have 768 * linked list of device extestions and fill the adapter memory with 769 * information from these extension structures. 770 */ 771 uint8_t *pu8 = (uint8_t *)PrimaryExtension->AdapterInformation; 772 uint32_t u32Offset = 0; 777 dprintf(("VBoxVideo::vboxMapAdapterMemory rc = %d\n", Status)); 778 779 return Status; 780 } 781 782 static void vboxUnmapAdapterMemory (PDEVICE_EXTENSION PrimaryExtension) 783 { 784 dprintf(("VBoxVideo::vboxMapAdapterMemory\n")); 785 786 if (PrimaryExtension->u.primary.pvMiniportHeap) 787 { 788 VideoPortUnmapMemory(PrimaryExtension, PrimaryExtension->u.primary.pvMiniportHeap, NULL); 789 } 790 791 PrimaryExtension->u.primary.pvMiniportHeap = NULL; 792 PrimaryExtension->u.primary.pvAdapterInformation = NULL; 793 } 794 795 static void vboxSetupAdapterInfo (PDEVICE_EXTENSION PrimaryExtension) 796 { 797 dprintf(("VBoxVideo::vboxSetupAdapterInfo\n")); 773 798 774 799 VBOXVIDEOINFOHDR *pHdr; 775 int iDisplay; 776 777 for (iDisplay = 0; iDisplay < gNumDisplays; ++iDisplay) 800 801 uint8_t *pu8 = (uint8_t *)PrimaryExtension->u.primary.pvAdapterInformation; 802 803 PDEVICE_EXTENSION Extension = PrimaryExtension; 804 while (Extension) 778 805 { 779 806 pHdr = (VBOXVIDEOINFOHDR *)pu8; … … 787 814 pu8 += sizeof (VBOXVIDEOINFODISPLAY); 788 815 789 pDisplay->u32Index = iDisplay; 790 pDisplay->u32Offset = u32Offset; 791 pDisplay->u32FramebufferSize = PrimaryExtension->ulMaxFrameBufferSize; 792 pDisplay->u32InformationSize = VBOX_VIDEO_DISPLAY_INFORMATION_SIZE; 816 pDisplay->u32Index = Extension->iDevice; 817 pDisplay->u32Offset = Extension->ulFrameBufferOffset; 818 pDisplay->u32FramebufferSize = PrimaryExtension->u.primary.ulMaxFrameBufferSize; 819 pDisplay->u32InformationSize = PrimaryExtension->u.primary.ulDisplayInformationSize; 820 821 Extension = Extension->pNext; 822 } 823 824 825 /* The heap description. */ 826 pHdr = (VBOXVIDEOINFOHDR *)pu8; 827 pu8 += sizeof (VBOXVIDEOINFOHDR); 828 829 pHdr->u8Type = VBOX_VIDEO_INFO_TYPE_NV_HEAP; 830 pHdr->u8Reserved = 0; 831 pHdr->u16Length = sizeof (VBOXVIDEOINFONVHEAP); 832 833 VBOXVIDEOINFONVHEAP *pHeap = (VBOXVIDEOINFONVHEAP *)pu8; 834 pu8 += sizeof (VBOXVIDEOINFONVHEAP); 835 836 pHeap->u32HeapOffset = PrimaryExtension->u.primary.cbVRAM 837 - PrimaryExtension->u.primary.cbMiniportHeap 838 - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 839 pHeap->u32HeapSize = PrimaryExtension->u.primary.cbMiniportHeap; 793 840 794 u32Offset += PrimaryExtension->ulMaxFrameBufferSize + VBOX_VIDEO_DISPLAY_INFORMATION_SIZE; 795 } 796 841 842 /* The END marker. */ 797 843 pHdr = (VBOXVIDEOINFOHDR *)pu8; 798 844 pu8 += sizeof (VBOXVIDEOINFOHDR); … … 803 849 804 850 /* Inform the host about the display configuration. */ 805 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ CMONITORS);851 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VBOX_VIDEO); 806 852 VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY); 853 854 dprintf(("VBoxVideo::vboxSetupAdapterInfo finished\n")); 807 855 } 808 856 … … 812 860 * intentionally crippled. 813 861 */ 814 VOID VBoxSetupDisplays(PDEVICE_EXTENSION PrimaryExtension, PVIDEO_PORT_CONFIG_INFO pConfigInfo) 815 { 816 typedef VP_STATUS (*pCreateSecDisp)(PVOID, PVOID *, ULONG); 817 pCreateSecDisp pVPCreateSecDisp; 818 PVOID pFunc; 819 int iDisplay; 820 VP_STATUS rc; 821 PDEVICE_EXTENSION pSecExt; 822 ULONG AdapterMemorySize; 823 824 dprintf(("VBoxVideo::VBoxRegisterSecondaryDisplays: PrimaryExtension = %p\n", PrimaryExtension)); 825 826 AdapterMemorySize = VideoPortReadPortUlong((PULONG)VBE_DISPI_IOPORT_DATA); 827 828 /* Initialize DualView related stuff in device extension for 1 monitor (must be done always!). 829 * Assume that the is no dual view and initialize the maximum possible frame buffer size. 830 * Also assume no VBox extension support. 831 */ 832 PrimaryExtension->iDevice = 0; 833 PrimaryExtension->pvPrimaryExt = PrimaryExtension; 834 835 PrimaryExtension->ulFrameBufferOffset = 0; 836 PrimaryExtension->ulMaxFrameBufferSize = AdapterMemorySize - 837 VBOX_VIDEO_ADAPTER_INFORMATION_SIZE - 838 VBOX_VIDEO_DISPLAY_INFORMATION_SIZE; 839 PrimaryExtension->bDualViewSupported = FALSE; 840 PrimaryExtension->AdapterInformation = NULL; 841 842 /* Verify that the HW support VirtualBox extensions. */ 843 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID); 844 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_VBOX_VIDEO); 845 if (VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA) != VBE_DISPI_ID_VBOX_VIDEO) 846 { 847 dprintf(("VBoxVideo::VBoxSetupDisplays: virtual hardware do not support VBox extensions!!!\n")); 848 return; 849 } 850 851 /* Map the adapter information memory. */ 852 VBoxMapAdapterInfo (PrimaryExtension, AdapterMemorySize); 853 854 if (!PrimaryExtension->AdapterInformation) 855 { 856 dprintf(("VBoxVideo::VBoxSetupDisplays: failed to map adapter memory!!!\n")); 857 return; 858 } 859 860 /* Dynamically query the VideoPort import to be binary compatible across Windows versions */ 861 if (vboxQueryWinVersion() <= WINNT4) 862 { 863 pFunc = NULL; 864 } 865 else 866 { 867 /* This bluescreens on NT4, hence the above version check */ 868 pFunc = (pConfigInfo->VideoPortGetProcAddress)(PrimaryExtension, 869 (PUCHAR)"VideoPortCreateSecondaryDisplay"); 870 } 871 872 if (pFunc != NULL) { 873 pVPCreateSecDisp = (pCreateSecDisp)pFunc; 874 875 /* Query the configured number of displays */ 876 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_CMONITORS); 877 gNumDisplays = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA); 878 dprintf(("VBoxVideo::VBoxRegisterSecondaryDisplays: gNumDisplays = %d\n", gNumDisplays)); 879 880 PrimaryExtension->bDualViewSupported = (gNumDisplays != 0); 881 882 /* Now when the number of monitors is known, update the maximum size. */ 883 PrimaryExtension->ulMaxFrameBufferSize = VBoxVideoComputeMaxFrameBufferSize (AdapterMemorySize); 884 885 for (iDisplay = 1; iDisplay < gNumDisplays; ++iDisplay) 886 { 887 rc = pVPCreateSecDisp(PrimaryExtension, (PVOID*)&pSecExt, VIDEO_DUALVIEW_REMOVABLE); 888 dprintf(("VBoxVideo::VBoxRegisterSecondaryDisplays: VideoPortCreateSecondaryDisplay returned %#x, pSecExt = %p\n", rc, pSecExt)); 889 if (rc != NO_ERROR) /* Failure to create secondary displays is not fatal */ 890 break; 891 892 pSecExt->iDevice = iDisplay; 893 pSecExt->pvPrimaryExt = PrimaryExtension; 894 895 pSecExt->ulFrameBufferOffset = iDisplay * (PrimaryExtension->ulMaxFrameBufferSize + VBOX_VIDEO_DISPLAY_INFORMATION_SIZE); 896 pSecExt->ulMaxFrameBufferSize = PrimaryExtension->ulMaxFrameBufferSize; 897 pSecExt->bDualViewSupported = PrimaryExtension->bDualViewSupported; 898 pSecExt->AdapterInformation = PrimaryExtension->AdapterInformation; 899 } 900 } 901 902 VBoxSetupAdapterInfo (PrimaryExtension); 862 VOID VBoxSetupDisplays(PDEVICE_EXTENSION PrimaryExtension, PVIDEO_PORT_CONFIG_INFO pConfigInfo, ULONG AdapterMemorySize) 863 { 864 VP_STATUS rc = NO_ERROR; 865 866 dprintf(("VBoxVideo::VBoxSetupDisplays: PrimaryExtension = %p\n", 867 PrimaryExtension)); 868 869 /* Preinitialize the primary extension. */ 870 PrimaryExtension->pNext = NULL; 871 PrimaryExtension->pPrimary = PrimaryExtension; 872 PrimaryExtension->iDevice = 0; 873 PrimaryExtension->ulFrameBufferOffset = 0; 874 PrimaryExtension->ulFrameBufferSize = 0; 875 PrimaryExtension->u.primary.ulVbvaEnabled = 0; 876 PrimaryExtension->u.primary.bVBoxVideoSupported = FALSE; 877 PrimaryExtension->u.primary.cDisplays = 1; 878 PrimaryExtension->u.primary.cbVRAM = AdapterMemorySize; 879 PrimaryExtension->u.primary.cbMiniportHeap = 0; 880 PrimaryExtension->u.primary.pvMiniportHeap = NULL; 881 PrimaryExtension->u.primary.pvAdapterInformation = NULL; 882 PrimaryExtension->u.primary.ulMaxFrameBufferSize = 0; 883 PrimaryExtension->u.primary.ulDisplayInformationSize = 0; 884 885 886 /* Verify whether the HW supports VirtualBox extensions. */ 887 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID); 888 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_VBOX_VIDEO); 889 890 if (VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA) == VBE_DISPI_ID_VBOX_VIDEO) 891 { 892 PrimaryExtension->u.primary.bVBoxVideoSupported = TRUE; 893 } 894 895 dprintf(("VBoxVideo::VBoxSetupDisplays: bVBoxVideoSupported = %d\n", 896 PrimaryExtension->u.primary.bVBoxVideoSupported)); 897 898 /* Setup the non-volatile heap and the adapter memory. */ 899 if (PrimaryExtension->u.primary.bVBoxVideoSupported) 900 { 901 /* Query the size of the non-volatile heap. */ 902 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VBOX_VIDEO); 903 VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_QUERY_OFFSCREEN_HEAP_SIZE); 904 905 ULONG cbMiniportHeap = VideoPortReadPortUlong((PULONG)VBE_DISPI_IOPORT_DATA); 906 907 /* Do not allow too big heap. 50% of VRAM should be enough. */ 908 ULONG cbMiniportHeapMaxSize = AdapterMemorySize / 2 - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE; 909 910 if (cbMiniportHeap > cbMiniportHeapMaxSize) 911 { 912 cbMiniportHeap = cbMiniportHeapMaxSize; 913 } 914 915 /* Round up to 4096. */ 916 PrimaryExtension->u.primary.cbMiniportHeap = (cbMiniportHeap + 0xFFF) & ~0xFFF; 917 918 dprintf(("VBoxVideo::VBoxSetupDisplays: cbMiniportHeap = 0x%08X, PrimaryExtension->u.primary.cbMiniportHeap = 0x%08X, cbMiniportHeapMaxSize = 0x%08X\n", 919 cbMiniportHeap, PrimaryExtension->u.primary.cbMiniportHeap, cbMiniportHeapMaxSize)); 920 921 /* Map the heap region and the adapter information area. 922 * 923 * Note: the heap will be used by display drivers, possibly by a few instances 924 * in multimonitor configuration, but the memory is mapped here ones. 925 * It is assumed that all display drivers and the miniport has the SAME 926 * virtual address space. 927 * 928 */ 929 rc = vboxMapAdapterMemory (PrimaryExtension); 930 931 if (rc != NO_ERROR) 932 { 933 PrimaryExtension->u.primary.cbMiniportHeap = 0; 934 PrimaryExtension->u.primary.bVBoxVideoSupported = FALSE; 935 } 936 } 937 938 /* Check whether the guest supports multimonitors. */ 939 if (PrimaryExtension->u.primary.bVBoxVideoSupported) 940 { 941 typedef VP_STATUS (*PFNCREATESECONDARYDISPLAY)(PVOID, PVOID *, ULONG); 942 PFNCREATESECONDARYDISPLAY pfnCreateSecondaryDisplay = NULL; 943 944 /* Dynamically query the VideoPort import to be binary compatible across Windows versions */ 945 if (vboxQueryWinVersion() > WINNT4) 946 { 947 /* This bluescreens on NT4, hence the above version check */ 948 pfnCreateSecondaryDisplay = (PFNCREATESECONDARYDISPLAY)(pConfigInfo->VideoPortGetProcAddress) 949 (PrimaryExtension, 950 (PUCHAR)"VideoPortCreateSecondaryDisplay"); 951 } 952 953 if (pfnCreateSecondaryDisplay != NULL) 954 { 955 /* Query the configured number of displays. */ 956 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VBOX_VIDEO); 957 int cDisplays = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA); 958 959 dprintf(("VBoxVideo::VBoxSetupDisplays: cDisplays = %d\n", 960 cDisplays)); 961 962 if (cDisplays == 0 || cDisplays > VBOX_VIDEO_MAX_SCREENS) 963 { 964 /* Host reported some bad value. Continue in the 1 screen mode. */ 965 cDisplays = 1; 966 } 967 968 PDEVICE_EXTENSION pPrev = PrimaryExtension; 969 970 int iDisplay; 971 for (iDisplay = 1; iDisplay < cDisplays; iDisplay++) 972 { 973 PDEVICE_EXTENSION SecondaryExtension = NULL; 974 rc = pfnCreateSecondaryDisplay (PrimaryExtension, (PVOID*)&SecondaryExtension, VIDEO_DUALVIEW_REMOVABLE); 975 976 dprintf(("VBoxVideo::VBoxSetupDisplays: VideoPortCreateSecondaryDisplay returned %#x, SecondaryExtension = %p\n", 977 rc, SecondaryExtension)); 978 979 if (rc != NO_ERROR) 980 { 981 break; 982 } 983 984 SecondaryExtension->pNext = NULL; 985 SecondaryExtension->pPrimary = PrimaryExtension; 986 SecondaryExtension->iDevice = iDisplay; 987 SecondaryExtension->ulFrameBufferOffset = 0; 988 SecondaryExtension->ulFrameBufferSize = 0; 989 SecondaryExtension->u.secondary.bEnabled = FALSE; 990 991 /* Update the list pointers. */ 992 pPrev->pNext = SecondaryExtension; 993 pPrev = SecondaryExtension; 994 995 /* Take the successfully created display into account. */ 996 PrimaryExtension->u.primary.cDisplays++; 997 } 998 999 /* Failure to create secondary displays is not fatal */ 1000 rc = NO_ERROR; 1001 } 1002 } 1003 1004 /* Now when the number of monitors is known and extensions are created, 1005 * calculate the layout of framebuffers. 1006 */ 1007 vboxComputeFrameBufferSizes (PrimaryExtension); 1008 1009 if (PrimaryExtension->u.primary.bVBoxVideoSupported) 1010 { 1011 /* Setup the information for the host. */ 1012 vboxSetupAdapterInfo (PrimaryExtension); 1013 } 1014 1015 dprintf(("VBoxVideo::VBoxSetupDisplays: finished\n")); 903 1016 } 904 1017 … … 983 1096 dprintf(("VBoxVideo::VBoxVideoFindAdapter: VbglInit returned 0x%x\n", rc)); 984 1097 985 /* Attempt to register secondary displays*/986 VBoxSetupDisplays((PDEVICE_EXTENSION)HwDeviceExtension, ConfigInfo );1098 /* Setup the Device Extension and if possible secondary displays. */ 1099 VBoxSetupDisplays((PDEVICE_EXTENSION)HwDeviceExtension, ConfigInfo, AdapterMemorySize); 987 1100 988 1101 // pretend success to make the driver work. … … 1012 1125 1013 1126 /* Initialize the request pointer. */ 1014 pDevExt-> pvReqFlush = NULL;1127 pDevExt->u.primary.pvReqFlush = NULL; 1015 1128 1016 1129 /* … … 1371 1484 1372 1485 ulAttach = *((PULONG)RequestPacket->InputBuffer); 1373 dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_SWITCH_DUALVIEW (%ld)\n", ulAttach)); 1374 1375 pDevExt->bEnabled = (BOOLEAN)ulAttach; 1486 dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_SWITCH_DUALVIEW[%d] (%ld)\n", pDevExt->iDevice, ulAttach)); 1487 1488 if (pDevExt->iDevice > 0) 1489 { 1490 pDevExt->u.secondary.bEnabled = (BOOLEAN)ulAttach; 1491 } 1376 1492 Result = TRUE; 1377 1493 break; … … 1382 1498 dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_INTERPRET_DISPLAY_MEMORY\n")); 1383 1499 1384 if (pDevExt-> bDualViewSupported)1500 if (pDevExt->pPrimary->u.primary.bVBoxVideoSupported) 1385 1501 { 1386 1502 /* The display driver must have prepared the monitor information. */ 1387 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ CMONITORS);1503 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VBOX_VIDEO); 1388 1504 VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE + pDevExt->iDevice); 1389 1505 } … … 1392 1508 RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION; 1393 1509 } 1394 Result = pDevExt-> bDualViewSupported;1510 Result = pDevExt->pPrimary->u.primary.bVBoxVideoSupported; 1395 1511 break; 1396 1512 } … … 1411 1527 1412 1528 pDispInfo->iDevice = pDevExt->iDevice; 1413 pDispInfo->u32DisplayInfoSize = VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;1529 pDispInfo->u32DisplayInfoSize = pDevExt->pPrimary->u.primary.ulDisplayInformationSize; 1414 1530 1415 1531 RequestPacket->StatusBlock->Information = sizeof(QUERYDISPLAYINFORESULT); … … 1543 1659 VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED); 1544 1660 1545 if (pDevExt-> pvReqFlush != NULL)1546 { 1547 VbglGRFree ((VMMDevRequestHeader *)pDevExt-> pvReqFlush);1548 pDevExt-> pvReqFlush = NULL;1661 if (pDevExt->u.primary.pvReqFlush != NULL) 1662 { 1663 VbglGRFree ((VMMDevRequestHeader *)pDevExt->u.primary.pvReqFlush); 1664 pDevExt->u.primary.pvReqFlush = NULL; 1549 1665 } 1550 1666 1551 1667 VbglTerminate (); 1668 1669 vboxUnmapAdapterMemory (pDevExt); 1552 1670 1553 1671 return TRUE; … … 1669 1787 1670 1788 MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress; 1671 MapInformation->VideoRamLength = DeviceExtension->ulMaxFrameBufferSize + VBOX_VIDEO_DISPLAY_INFORMATION_SIZE; 1789 MapInformation->VideoRamLength = DeviceExtension->pPrimary->u.primary.ulMaxFrameBufferSize 1790 + DeviceExtension->pPrimary->u.primary.ulDisplayInformationSize; 1672 1791 1673 1792 Status = VideoPortMapMemory(DeviceExtension, FrameBuffer, … … 1802 1921 PULONG pUnused) 1803 1922 { 1804 dprintf(("VBoxVideo::VBoxVideoGetChildDescriptor: HwDeviceExtension = %p, ChildEnumInfo = %p\n",1805 HwDeviceExtension, ChildEnumInfo));1923 dprintf(("VBoxVideo::VBoxVideoGetChildDescriptor: HwDeviceExtension = %p, ChildEnumInfo = %p\n", 1924 HwDeviceExtension, ChildEnumInfo)); 1806 1925 1807 1926 DEVICE_EXTENSION *pDevExt = (DEVICE_EXTENSION *)HwDeviceExtension; … … 1809 1928 if (ChildEnumInfo->ChildIndex > 0) 1810 1929 { 1811 if ( (ChildEnumInfo->ChildIndex == 1 && gNumDisplays == 0) 1812 || ((int)ChildEnumInfo->ChildIndex <= gNumDisplays) 1813 ) 1930 if ((int)ChildEnumInfo->ChildIndex <= pDevExt->pPrimary->u.primary.cDisplays) 1814 1931 { 1815 1932 *VideoChildType = Monitor; … … 1827 1944 { 1828 1945 DEVICE_EXTENSION *pDevExt = (DEVICE_EXTENSION *)pvFlush; 1829 DEVICE_EXTENSION *pPrimaryDevExt = (DEVICE_EXTENSION *)(pDevExt? pDevExt->pvPrimaryExt: NULL);1946 DEVICE_EXTENSION *pPrimaryDevExt = pDevExt? pDevExt->pPrimary: NULL; 1830 1947 1831 1948 if (pPrimaryDevExt) 1832 1949 { 1833 VMMDevVideoAccelFlush *req = (VMMDevVideoAccelFlush *)pPrimaryDevExt-> pvReqFlush;1950 VMMDevVideoAccelFlush *req = (VMMDevVideoAccelFlush *)pPrimaryDevExt->u.primary.pvReqFlush; 1834 1951 1835 1952 if (req) … … 1864 1981 if (pDevExt->iDevice > 0) 1865 1982 { 1866 DEVICE_EXTENSION *pPrimaryDevExt = (DEVICE_EXTENSION *)pDevExt->pvPrimaryExt;1983 DEVICE_EXTENSION *pPrimaryDevExt = pDevExt->pPrimary; 1867 1984 1868 1985 dprintf(("VBoxVideo::vboxVbvaEnable: Skipping for non-primary display %d\n", … … 1870 1987 1871 1988 if ( ulEnable 1872 && pPrimaryDevExt->u lVbvaEnabled)1989 && pPrimaryDevExt->u.primary.ulVbvaEnabled) 1873 1990 { 1874 1991 pVbvaResult->pVbvaMemory = &pVMMDevMemory->vbvaMemory; … … 1887 2004 { 1888 2005 /* Allocate the memory block for VMMDevReq_VideoAccelFlush request. */ 1889 if (pDevExt-> pvReqFlush == NULL)2006 if (pDevExt->u.primary.pvReqFlush == NULL) 1890 2007 { 1891 2008 VMMDevVideoAccelFlush *req = NULL; … … 1897 2014 if (VBOX_SUCCESS (rc)) 1898 2015 { 1899 pDevExt-> pvReqFlush = req;2016 pDevExt->u.primary.pvReqFlush = req; 1900 2017 } 1901 2018 else … … 1983 2100 } 1984 2101 1985 pDevExt-> ulVbvaEnabled = ulEnabled;2102 pDevExt->pPrimary->u.primary.ulVbvaEnabled = ulEnabled; 1986 2103 } 1987 2104 -
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h
r3153 r4027 43 43 #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 44 44 #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 45 #define VBE_DISPI_INDEX_ CMONITORS0xa45 #define VBE_DISPI_INDEX_VBOX_VIDEO 0xa 46 46 #define VBE_DISPI_ID2 0xB0C2 47 /* The VBOX interface id. Indicates support for VBE_DISPI_INDEX_ CMONITORS. */47 /* The VBOX interface id. Indicates support for VBE_DISPI_INDEX_VBOX_VIDEO. */ 48 48 #define VBE_DISPI_ID_VBOX_VIDEO 0xBE00 49 49 #define VBE_DISPI_DISABLED 0x00 … … 55 55 #define VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES (VBE_DISPI_TOTAL_VIDEO_MEMORY_KB * 1024) 56 56 57 typedef struct 57 typedef struct _DEVICE_EXTENSION 58 58 { 59 // Saved information about video modes 60 ULONG CurrentMode; 61 62 /* Pointer to preallocated generic request structure for VMMDevReq_VideoAccelFlush. 63 * Allocated when VBVA status is changed. Deallocated on HwReset. 64 */ 65 void *pvReqFlush; 66 67 ULONG iDevice; /* Device index (0 for primary) */ 68 PVOID pvPrimaryExt; /* Pointer to primary device extension */ 69 BOOLEAN bEnabled; /* Device enabled flag */ 70 71 ULONG ulFrameBufferOffset; 72 ULONG ulMaxFrameBufferSize; 73 74 BOOLEAN bDualViewSupported; 59 struct _DEVICE_EXTENSION *pNext; /* Next extension in the DualView extension list. 60 * The primary extension is the first one. 61 */ 62 63 struct _DEVICE_EXTENSION *pPrimary; /* Pointer to the primary device extension. */ 64 65 ULONG iDevice; /* Device index: 0 for primary, otherwise a secondary device. */ 66 67 68 ULONG CurrentMode; /* Saved information about video modes */ 69 70 ULONG ulFrameBufferOffset; /* The framebuffer position in the VRAM. */ 71 ULONG ulFrameBufferSize; /* The size of the current framebuffer. */ 72 73 union { 74 /* Information that is only relevant to the primary device or is the same for all devices. */ 75 struct { 76 77 void *pvReqFlush; /* Pointer to preallocated generic request structure for 78 * VMMDevReq_VideoAccelFlush. Allocated when VBVA status 79 * is changed. Deallocated on HwReset. 80 */ 81 82 83 ULONG ulVbvaEnabled; /* Indicates that VBVA mode is enabled. */ 84 85 BOOLEAN bVBoxVideoSupported; /* TRUE if VBoxVideo extensions, including DualView, are supported by the host. */ 86 87 int cDisplays; /* Number of displays. */ 88 89 ULONG cbVRAM; /* The VRAM size. */ 90 91 ULONG cbMiniportHeap; /* The size of reserved VRAM for miniport driver heap. 92 * It is at offset: 93 * cbAdapterMemorySize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE - cbMiniportHeap 94 */ 95 PVOID pvMiniportHeap; /* The pointer to the miniport heap VRAM. 96 * This is mapped by miniport as one block together with adapter info. 97 */ 98 99 PVOID pvAdapterInformation; /* The pointer to the last 4K of VRAM. Calculated as 100 * (uint8_t *)pvMiniportHeap + cbMiniportHeap 101 */ 102 103 ULONG ulMaxFrameBufferSize; /* The size of the VRAM allocated for the a single framebuffer. */ 104 105 ULONG ulDisplayInformationSize; /* The size of the Display information, which is at offset: 106 * ulFrameBufferOffset + ulMaxFrameBufferSize. 107 */ 108 109 } primary; 75 110 76 PVOID AdapterInformation; 77 78 ULONG ulVbvaEnabled; 111 /* Secondary device information. */ 112 struct { 113 BOOLEAN bEnabled; /* Device enabled flag */ 114 } secondary; 115 } u; 79 116 } DEVICE_EXTENSION, *PDEVICE_EXTENSION; 80 117
Note:
See TracChangeset
for help on using the changeset viewer.