VirtualBox

Changeset 4027 in vbox for trunk/src/VBox/Additions/WINNT


Ignore:
Timestamp:
Aug 3, 2007 7:53:12 PM (17 years ago)
Author:
vboxsync
Message:

Direct draw heap and miniport heap memory reservation for Windows guest additions.

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  
    1616
    1717#ifdef DEBUG
    18 #define LOG_ENABLED
     18#define LOG_ENABLED 1
    1919#endif
    2020
     
    6565{
    6666    PPDEV pDev = (PPDEV)dhpdev;
     67    BOOL bDefineDDrawHeap = FALSE;
     68    DWORD cHeaps = 0;
     69    VIDEOMEMORY *pVm = NULL;
    6770
    6871    DISPDBG((0, "%s: %p, %p, %p, %p, %p. %p\n", __FUNCTION__, dhpdev, pHalInfo, pdwNumHeaps, pvmList, pdwNumFourCCCodes, pdwFourCC));
     
    7780    if (!(pvmList && pdwFourCC))
    7881    {
     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       
    7995        /* Create primary surface attributes */
    8096        pHalInfo->vmiData.pvPrimary                 = pDev->pjScreen;
     
    108124        pHalInfo->vmiData.dwTextureAlign            = 4;
    109125    }
    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    }
    122167
    123168#if 0 /* not mandatory */
     
    172217    pCallBacks->dwFlags               = 0;
    173218
    174     /*
    175219    pCallBacks->dwFlags               = DDHAL_CB32_CREATESURFACE | DDHAL_CB32_CANCREATESURFACE;
    176220    pCallBacks->CreateSurface         = DdCreateSurface;
    177221    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
    183226    /* Note: pCallBacks->SetMode & pCallBacks->DestroyDriver are unused in Windows 2000 and up */
    184227
     
    652695    DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
    653696
    654     // remember setting of exclusive mode in ppdev,
     697    // remember setting of exclusive mode in pDev,
    655698    // so GDI can stop to promote DeviceBitmaps into
    656699    // video memory
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/debug.c

    r3389 r4027  
    1515#include "driver.h"
    1616
    17 #ifdef DEBUG
     17#ifdef LOG_ENABLED
    1818
    1919#ifdef VBOX
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h

    r3423 r4027  
    7070    ULONG   cScreenSize;                // size of video memory, including
    7171                                        // offscreen memory.
     72    ULONG   cFrameBufferSize;           // size of screen video memory
    7273    PVOID   pOffscreenList;             // linked list of DCI offscreen surfaces.
    7374    FLONG   flRed;                      // For bitfields device, Red Mask
     
    9899    VBOXDISPLAYINFO *pInfo;
    99100    ULONG iDevice;
     101    ULONG cbDisplayInformation;
    100102#ifdef VBOX_WITH_DDRAW
    101103    BOOL             bDdExclusiveMode;
    102104    DWORD            dwNewDDSurfaceOffset;
     105    DWORD            cHeaps;
     106    VIDEOMEMORY*     pvmList;
    103107#endif
    104108};
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c

    r3560 r4027  
    1313\**************************************************************************/
    1414#ifdef DEBUG
    15 #define LOG_ENABLED
     15#define LOG_ENABLED 1
    1616#endif
    1717
     
    10001000{
    10011001    PPDEV               pDev = (PPDEV)pDirectDraw->dhpdev;
    1002     HBITMAP             hbmDevice;
     1002//    HBITMAP             hbmDevice;
    10031003    DD_SURFACE_GLOBAL*  pSurfaceGlobal;
    1004     SIZEL               sizl;
     1004//    SIZEL               sizl;
    10051005
    10061006    DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c

    r3380 r4027  
    6666                 DispInfo.u32DisplayInfoSize, pMemoryInformation->VideoRamLength));
    6767        ppdev->pInfo = NULL;
     68        ppdev->cbDisplayInformation = 0;
    6869        return;
    6970    }
    7071   
    7172    ppdev->iDevice = DispInfo.iDevice;
     73    ppdev->cbDisplayInformation = DispInfo.u32DisplayInfoSize;
    7274
    7375    pu8 = (uint8_t *)pMemoryInformation->VideoRamBase;
     
    195197        }
    196198
    197         ppdev->cScreenSize = videoMemoryInformation.VideoRamLength;
    198        
    199199        //
    200200        // Initialize the head of the offscreen list to NULL.
     
    246246        /* Setup the display information. */
    247247        vboxSetupDisplayInfo (ppdev, &videoMemoryInformation);
     248       
     249        ppdev->cScreenSize = videoMemoryInformation.VideoRamLength - ppdev->cbDisplayInformation;
     250        ppdev->cFrameBufferSize = videoMemoryInformation.FrameBufferLength;
    248251    }
    249252
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp

    r3563 r4027  
    4343static WCHAR VBoxBiosString[] = L"Version 0xB0C2 or later";
    4444
    45 /* Number of reported monitors. Defaults to 1 (no DualView) */
    46 static int gNumDisplays = 1;
    47 
    4845/*
    4946 * Globals for the last custom resolution set. This is important
     
    197194
    198195    /* size of the VRAM in bytes */
    199     ULONG vramSize = DeviceExtension->ulMaxFrameBufferSize;
     196    ULONG vramSize = DeviceExtension->pPrimary->u.primary.ulMaxFrameBufferSize;
    200197
    201198    gNumVideoModes = 0;
     
    700697
    701698/* 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      */
     699static void vboxComputeFrameBufferSizes (PDEVICE_EXTENSION PrimaryExtension)
     700{
     701    ULONG ulAvailable = PrimaryExtension->u.primary.cbVRAM
     702                        - PrimaryExtension->u.primary.cbMiniportHeap
     703                        - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE;
    710704
    711705    /* Size of a framebuffer. */
    712     ULONG ulSize = (AdapterMemorySize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE) / gNumDisplays;
     706   
     707    ULONG ulSize = ulAvailable / PrimaryExtension->u.primary.cDisplays;
    713708   
    714709    /* Align down to 4096 bytes. */
    715710    ulSize &= ~0xFFF;
    716711   
    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));
    719716   
    720717    if (ulSize > VBOX_VIDEO_DISPLAY_INFORMATION_SIZE)
     
    725722    else
    726723    {
     724        /* Should not really get here. But still do it safely. */
    727725        ulSize = 0;
    728726    }
    729727   
    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
     751static int vboxMapAdapterMemory (PDEVICE_EXTENSION PrimaryExtension)
     752{
     753    dprintf(("VBoxVideo::vboxMapAdapterMemory\n"));
     754
    735755    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;
    736762    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);
    749769
    750770    if (Status == NO_ERROR)
    751771    {
    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;
    765775    }
    766776   
    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
     782static 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
     795static void vboxSetupAdapterInfo (PDEVICE_EXTENSION PrimaryExtension)
     796{
     797    dprintf(("VBoxVideo::vboxSetupAdapterInfo\n"));
    773798   
    774799    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)
    778805    {
    779806        pHdr = (VBOXVIDEOINFOHDR *)pu8;
     
    787814        pu8 += sizeof (VBOXVIDEOINFODISPLAY);
    788815
    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;
    793840       
    794         u32Offset += PrimaryExtension->ulMaxFrameBufferSize + VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
    795     }
    796 
     841   
     842    /* The END marker. */
    797843    pHdr = (VBOXVIDEOINFOHDR *)pu8;
    798844    pu8 += sizeof (VBOXVIDEOINFOHDR);
     
    803849
    804850    /* 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);
    806852    VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY);
     853   
     854    dprintf(("VBoxVideo::vboxSetupAdapterInfo finished\n"));
    807855}
    808856
     
    812860 * intentionally crippled.
    813861 */
    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);
     862VOID 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"));
    9031016}
    9041017
     
    9831096      dprintf(("VBoxVideo::VBoxVideoFindAdapter: VbglInit returned 0x%x\n", rc));
    9841097
    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);
    9871100
    9881101      // pretend success to make the driver work.
     
    10121125
    10131126    /* Initialize the request pointer. */
    1014     pDevExt->pvReqFlush = NULL;
     1127    pDevExt->u.primary.pvReqFlush = NULL;
    10151128
    10161129    /*
     
    13711484
    13721485            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            }
    13761492            Result = TRUE;
    13771493            break;
     
    13821498            dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_INTERPRET_DISPLAY_MEMORY\n"));
    13831499
    1384             if (pDevExt->bDualViewSupported)
     1500            if (pDevExt->pPrimary->u.primary.bVBoxVideoSupported)
    13851501            {
    13861502                /* 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);
    13881504                VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE + pDevExt->iDevice);
    13891505            }
     
    13921508                RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
    13931509            }
    1394             Result = pDevExt->bDualViewSupported;
     1510            Result = pDevExt->pPrimary->u.primary.bVBoxVideoSupported;
    13951511            break;
    13961512        }
     
    14111527           
    14121528            pDispInfo->iDevice = pDevExt->iDevice;
    1413             pDispInfo->u32DisplayInfoSize = VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
     1529            pDispInfo->u32DisplayInfoSize = pDevExt->pPrimary->u.primary.ulDisplayInformationSize;
    14141530
    14151531            RequestPacket->StatusBlock->Information = sizeof(QUERYDISPLAYINFORESULT);
     
    15431659    VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED);
    15441660
    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;
    15491665    }
    15501666
    15511667    VbglTerminate ();
     1668   
     1669    vboxUnmapAdapterMemory (pDevExt);
    15521670
    15531671    return TRUE;
     
    16691787
    16701788    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;
    16721791
    16731792    Status = VideoPortMapMemory(DeviceExtension, FrameBuffer,
     
    18021921   PULONG pUnused)
    18031922{
    1804    dprintf(("VBoxVideo::VBoxVideoGetChildDescriptor: HwDeviceExtension = %p, ChildEnumInfo = %p\n",
    1805             HwDeviceExtension, ChildEnumInfo));
     1923    dprintf(("VBoxVideo::VBoxVideoGetChildDescriptor: HwDeviceExtension = %p, ChildEnumInfo = %p\n",
     1924             HwDeviceExtension, ChildEnumInfo));
    18061925
    18071926    DEVICE_EXTENSION *pDevExt = (DEVICE_EXTENSION *)HwDeviceExtension;
     
    18091928    if (ChildEnumInfo->ChildIndex > 0)
    18101929    {
    1811         if (   (ChildEnumInfo->ChildIndex == 1 && gNumDisplays == 0)
    1812             || ((int)ChildEnumInfo->ChildIndex <= gNumDisplays)
    1813            )
     1930        if ((int)ChildEnumInfo->ChildIndex <= pDevExt->pPrimary->u.primary.cDisplays)
    18141931        {
    18151932            *VideoChildType = Monitor;
     
    18271944{
    18281945    DEVICE_EXTENSION *pDevExt = (DEVICE_EXTENSION *)pvFlush;
    1829     DEVICE_EXTENSION *pPrimaryDevExt = (DEVICE_EXTENSION *)(pDevExt? pDevExt->pvPrimaryExt: NULL);
     1946    DEVICE_EXTENSION *pPrimaryDevExt = pDevExt? pDevExt->pPrimary: NULL;
    18301947
    18311948    if (pPrimaryDevExt)
    18321949    {
    1833         VMMDevVideoAccelFlush *req = (VMMDevVideoAccelFlush *)pPrimaryDevExt->pvReqFlush;
     1950        VMMDevVideoAccelFlush *req = (VMMDevVideoAccelFlush *)pPrimaryDevExt->u.primary.pvReqFlush;
    18341951
    18351952        if (req)
     
    18641981    if (pDevExt->iDevice > 0)
    18651982    {
    1866         DEVICE_EXTENSION *pPrimaryDevExt = (DEVICE_EXTENSION *)pDevExt->pvPrimaryExt;
     1983        DEVICE_EXTENSION *pPrimaryDevExt = pDevExt->pPrimary;
    18671984
    18681985        dprintf(("VBoxVideo::vboxVbvaEnable: Skipping for non-primary display %d\n",
     
    18701987       
    18711988        if (   ulEnable
    1872             && pPrimaryDevExt->ulVbvaEnabled)
     1989            && pPrimaryDevExt->u.primary.ulVbvaEnabled)
    18731990        {
    18741991            pVbvaResult->pVbvaMemory = &pVMMDevMemory->vbvaMemory;
     
    18872004    {
    18882005        /* Allocate the memory block for VMMDevReq_VideoAccelFlush request. */
    1889         if (pDevExt->pvReqFlush == NULL)
     2006        if (pDevExt->u.primary.pvReqFlush == NULL)
    18902007        {
    18912008            VMMDevVideoAccelFlush *req = NULL;
     
    18972014            if (VBOX_SUCCESS (rc))
    18982015            {
    1899                 pDevExt->pvReqFlush = req;
     2016                pDevExt->u.primary.pvReqFlush = req;
    19002017            }
    19012018            else
     
    19832100        }
    19842101
    1985         pDevExt->ulVbvaEnabled = ulEnabled;
     2102        pDevExt->pPrimary->u.primary.ulVbvaEnabled = ulEnabled;
    19862103    }
    19872104
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h

    r3153 r4027  
    4343#define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
    4444#define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
    45 #define VBE_DISPI_INDEX_CMONITORS       0xa
     45#define VBE_DISPI_INDEX_VBOX_VIDEO      0xa
    4646#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. */
    4848#define VBE_DISPI_ID_VBOX_VIDEO         0xBE00
    4949#define VBE_DISPI_DISABLED              0x00
     
    5555#define VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES      (VBE_DISPI_TOTAL_VIDEO_MEMORY_KB * 1024)
    5656
    57 typedef struct
     57typedef struct _DEVICE_EXTENSION
    5858{
    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;
    75110   
    76    PVOID AdapterInformation;
    77    
    78    ULONG ulVbvaEnabled;
     111       /* Secondary device information. */
     112       struct {
     113           BOOLEAN bEnabled;                   /* Device enabled flag */
     114       } secondary;
     115   } u;
    79116} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    80117
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette