VirtualBox

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


Ignore:
Timestamp:
Jun 19, 2007 9:40:23 AM (17 years ago)
Author:
vboxsync
Message:

Multimonitor support.

Location:
trunk/src/VBox/Additions/WINNT/Graphics
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h

    r2558 r3153  
    2323#include "../Miniport/vboxioctl.h"
    2424
     25#include <VBox/VBoxVideo.h>
     26
    2527/* Forward declaration. */
    2628struct _PDEV;
    2729typedef struct _PDEV PDEV;
    2830typedef PDEV *PPDEV;
     31
     32typedef struct _VBOXDISPLAYINFO
     33{
     34    VBOXVIDEOINFOHDR         hdrLink;
     35    VBOXVIDEOINFOLINK        link;
     36    VBOXVIDEOINFOHDR         hdrScreen;
     37    VBOXVIDEOINFOSCREEN      screen;
     38    VBOXVIDEOINFOHDR         hdrHostEvents;
     39    VBOXVIDEOINFOHOSTEVENTS  hostEvents;
     40    VBOXVIDEOINFOHDR         hdrEnd;
     41} VBOXDISPLAYINFO;
    2942
    3043#include "vbvavrdp.h"
     
    5265    POINTL  ptlOrg;                     // Where this display is anchored in
    5366                                        //   the virtual desktop.
     67    POINTL  ptlDevOrg;                  // Device origin for DualView (0,0 for primary view).
    5468    ULONG   ulMode;                     // Mode the mini-port driver is in.
    5569    LONG    lDeltaScreen;               // Distance from one scan to the next.
     
    7488   
    7589    VBVAENABLERESULT vbva;
    76     HSEMAPHORE       hsemHwBuffer;
     90    uint32_t         u32VRDPResetFlag;
    7791    BOOL             fHwBufferOverflow;
    7892    VBVARECORD       *pRecord;
     
    8195    ULONG cSSB;                 // Number of active saved screen bits records in the following array.
    8296    SSB aSSB[4];                // LIFO type stack for saved screen areas.
     97
     98    VBOXDISPLAYINFO *pInfo;
     99    ULONG iDevice;
    83100};
     101
     102/* The global semaphore handle for all driver instances. */
     103extern HSEMAPHORE ghsemHwBuffer;
     104
    84105
    85106DWORD getAvailableModes(HANDLE, PVIDEO_MODE_INFORMATION *, DWORD *);
     
    126147BOOL vboxOrderSupported (PPDEV ppdev, unsigned code);
    127148
     149void VBoxProcessDisplayInfo(PPDEV ppdev);
     150void VBoxUpdateDisplayInfo (PPDEV ppdev);
    128151
    129152void drvLoadEng (void);
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/drv.c

    r2981 r3153  
    9999        PPDEV ppdev = (PPDEV)__psoDest->dhpdev;                       \
    100100                                                                      \
    101         if (vboxHwBufferBeginUpdate (ppdev))                          \
     101        if (ppdev->pInfo && vboxHwBufferBeginUpdate (ppdev))          \
    102102        {                                                             \
    103103            vbva##__fn __a;                                           \
    104104                                                                      \
    105             if (ppdev->vbva.pVbvaMemory->fu32ModeFlags                \
    106                 & VBVA_F_MODE_VRDP_RESET)                             \
     105            if (  ppdev->pInfo->hostEvents.fu32Events                 \
     106                & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)           \
    107107            {                                                         \
    108108                vrdpReset (ppdev);                                    \
    109109                                                                      \
    110                 ppdev->vbva.pVbvaMemory->fu32ModeFlags &=             \
    111                     ~VBVA_F_MODE_VRDP_RESET;                          \
     110                ppdev->pInfo->hostEvents.fu32Events &=                \
     111                          ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;  \
    112112            }                                                         \
    113113                                                                      \
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c

    r2558 r3153  
    167167    {   INDEX_DrvSaveScreenBits,        (PFN) DrvSaveScreenBits     },  // 40 0x28
    168168    {   INDEX_DrvGetModes,              (PFN) DrvGetModes           },  // 41 0x29
     169    {   INDEX_DrvNotify,                (PFN) DrvNotify             },  // 87 0x57
    169170//     /* Experimental. */
    170171//     {   0x7,                            (PFN) DrvResetPDEV          },       // 0x7
     
    191192#define HOOKS_BMF32BPP gflHooks
    192193
     194HSEMAPHORE ghsemHwBuffer = 0;
     195
    193196/******************************Public*Routine******************************\
    194197* DrvEnableDriver
     
    238241            DDI_DRIVER_VERSION_NT4;
    239242
     243    if (!ghsemHwBuffer)
     244    {
     245        ghsemHwBuffer = EngCreateSemaphore ();
     246    }
     247
    240248    return(TRUE);
    241249}
     
    252260{
    253261    DISPDBG((0, "VBoxDisp::DrvDisableDriver called.\n"));
     262
     263    if (ghsemHwBuffer)
     264    {
     265        EngDeleteSemaphore (ghsemHwBuffer);
     266        ghsemHwBuffer = NULL;
     267    }
     268
    254269    return;
    255270}
     
    822837}
    823838
     839/******************************Public*Routine******************************\
     840* DrvNotify
     841*
     842* Called by GDI to notify us of certain "interesting" events
     843*
     844* DN_DEVICE_ORIGIN is used to communicate the X/Y offsets of individual monitors
     845*                  when DualView is in effect.
     846*
     847\**************************************************************************/
     848
     849VOID DrvNotify(
     850SURFOBJ *pso,
     851ULONG iType,
     852PVOID pvData)
     853{
     854    PDEV*   ppdev = (PDEV*) pso->dhpdev;
     855
     856    DISPDBG((0, "VBoxDisp::DrvNotify called.\n"));
     857
     858    switch(iType)
     859    {
     860        case DN_DEVICE_ORIGIN:
     861            ppdev->ptlDevOrg = *(PPOINTL)pvData;
     862            DISPDBG((3, "DN_DEVICE_ORIGIN: %d, %d (PSO = %p, pInfo = %p)\n", ppdev->ptlDevOrg.x,
     863                     ppdev->ptlDevOrg.y, pso, ppdev->pInfo));
     864            if (ppdev->pInfo)
     865            {
     866                ppdev->pInfo->screen.xOrigin = ppdev->ptlDevOrg.x;
     867                ppdev->pInfo->screen.yOrigin = ppdev->ptlDevOrg.y;
     868                VBoxProcessDisplayInfo(ppdev);
     869            }
     870            break;
     871        case DN_DRAWING_BEGIN:
     872            DISPDBG((3, "DN_DRAWING_BEGIN (PSO = %p)\n", pso));
     873            break;
     874    }
     875}
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c

    r1 r3153  
    3535};
    3636
     37/* Setup display information after remapping. */
     38static void vboxSetupDisplayInfo (PPDEV ppdev, VIDEO_MEMORY_INFORMATION *pMemoryInformation)
     39{
     40    VBOXDISPLAYINFO *pInfo;
     41    uint8_t *pu8;
     42   
     43    DWORD returnedDataLength;
     44    QUERYDISPLAYINFORESULT DispInfo;
     45    RtlZeroMemory(&DispInfo, sizeof (DispInfo));
     46    if (EngDeviceIoControl(ppdev->hDriver,
     47                           IOCTL_VIDEO_QUERY_DISPLAY_INFO,
     48                           NULL,
     49                           0,
     50                           &DispInfo,
     51                           sizeof(DispInfo),
     52                           &returnedDataLength))
     53    {
     54        DISPDBG((1, "DISP bInitSURF failed IOCTL_VIDEO_QUERY_DISPLAY_INFO\n"));
     55        ppdev->pInfo = NULL;
     56        return;
     57    }
     58   
     59    if (returnedDataLength != sizeof (QUERYDISPLAYINFORESULT)
     60        || DispInfo.u32DisplayInfoSize >= pMemoryInformation->VideoRamLength)
     61    {
     62        DISPDBG((1, "DISP bInitSURF failed DispInfo.u32DisplayInfoSize 0x%x >= pMemoryInformation->VideoRamLength 0x%x\n",
     63                 DispInfo.u32DisplayInfoSize, pMemoryInformation->VideoRamLength));
     64        ppdev->pInfo = NULL;
     65        return;
     66    }
     67   
     68    ppdev->iDevice = DispInfo.iDevice;
     69
     70    pu8 = (uint8_t *)pMemoryInformation->VideoRamBase;
     71    pu8 += pMemoryInformation->VideoRamLength - DispInfo.u32DisplayInfoSize;
     72
     73    pInfo = (VBOXDISPLAYINFO *)pu8;
     74    pu8 += sizeof (VBOXDISPLAYINFO);
     75
     76    pInfo->hdrLink.u8Type     = VBOX_VIDEO_INFO_TYPE_LINK;
     77    pInfo->hdrLink.u8Reserved = 0;
     78    pInfo->hdrLink.u16Length  = sizeof (VBOXVIDEOINFOLINK);
     79    pInfo->link.i32Offset = 0;
     80
     81    pInfo->hdrScreen.u8Type     = VBOX_VIDEO_INFO_TYPE_SCREEN;
     82    pInfo->hdrScreen.u8Reserved = 0;
     83    pInfo->hdrScreen.u16Length  = sizeof (VBOXVIDEOINFOSCREEN);
     84    DISPDBG((1, "Setup: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
     85    pInfo->screen.xOrigin      = ppdev->ptlDevOrg.x;
     86    pInfo->screen.yOrigin      = ppdev->ptlDevOrg.y;
     87    pInfo->screen.u32LineSize  = 0;
     88    pInfo->screen.u16Width     = 0;
     89    pInfo->screen.u16Height    = 0;
     90    pInfo->screen.bitsPerPixel = 0;
     91    pInfo->screen.u8Flags      = VBOX_VIDEO_INFO_SCREEN_F_NONE;
     92   
     93    pInfo->hdrHostEvents.u8Type     = VBOX_VIDEO_INFO_TYPE_HOST_EVENTS;
     94    pInfo->hdrHostEvents.u8Reserved = 0;
     95    pInfo->hdrHostEvents.u16Length  = sizeof (VBOXVIDEOINFOHOSTEVENTS);
     96    pInfo->hostEvents.fu32Events = VBOX_VIDEO_INFO_HOST_EVENTS_F_NONE;
     97
     98    pInfo->hdrEnd.u8Type     = VBOX_VIDEO_INFO_TYPE_END;
     99    pInfo->hdrEnd.u8Reserved = 0;
     100    pInfo->hdrEnd.u16Length  = 0;
     101
     102    ppdev->pInfo = pInfo;
     103}
     104
     105
     106static void vboxUpdateDisplayInfo (PPDEV ppdev)
     107{
     108    if (ppdev->pInfo)
     109    {
     110        ppdev->pInfo->screen.u32LineSize  = ppdev->lDeltaScreen;
     111        ppdev->pInfo->screen.u16Width     = (uint16_t)ppdev->cxScreen;
     112        ppdev->pInfo->screen.u16Height    = (uint16_t)ppdev->cyScreen;
     113        ppdev->pInfo->screen.bitsPerPixel = (uint8_t)ppdev->ulBitCount;
     114        ppdev->pInfo->screen.u8Flags      = VBOX_VIDEO_INFO_SCREEN_F_ACTIVE;
     115
     116        DISPDBG((1, "Update: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
     117        VBoxProcessDisplayInfo(ppdev);
     118    }
     119}
     120
     121
    37122/******************************Public*Routine******************************\
    38123* bInitSURF
     
    155240        ppdev->pPointerAttributes->Row = 0;
    156241        ppdev->pPointerAttributes->Enable = 0;
     242
     243        /* Setup the display information. */
     244        vboxSetupDisplayInfo (ppdev, &videoMemoryInformation);
    157245    }
    158246
     
    164252        || ppdev->ulBitCount == 32)
    165253    {
    166         /* Enable VBVA for this video mode. */
    167         vboxVbvaEnable (ppdev);
     254        if (ppdev->pInfo) /* Do not use VBVA on old hosts. */
     255        {
     256            /* Enable VBVA for this video mode. */
     257            vboxVbvaEnable (ppdev);
     258        }
    168259    }
    169260
    170261    DISPDBG((1, "DISP bInitSURF success\n"));
     262
     263    /* Update the display information. */
     264    vboxUpdateDisplayInfo (ppdev);
    171265   
    172266    return(TRUE);
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c

    r2981 r3153  
    5555
    5656    DISPDBG((1, "VBoxDisp::vboxVbvaEnable called\n"));
     57   
     58    if (!ghsemHwBuffer)
     59    {
     60        return FALSE;
     61    }
    5762
    5863    if (EngDeviceIoControl(ppdev->hDriver,
     
    7176            && ppdev->vbva.pvFlush)
    7277        {
    73             if (!ppdev->hsemHwBuffer)
    74             {
    75                 ppdev->hsemHwBuffer = EngCreateSemaphore ();
    76             }
    77 
    78             if (ppdev->hsemHwBuffer)
    79             {
    80                 ppdev->fHwBufferOverflow = FALSE;
    81                 ppdev->pRecord           = NULL;
    82 
    83                 /* All have been initialized. */
    84                 bRc = TRUE;
    85             }
    86             else
    87             {
    88                 DISPDBG((1, "VBoxDisp::vboxVbvaEnable failed to create semaphore!!!\n"));
    89             }
     78            ppdev->fHwBufferOverflow = FALSE;
     79            ppdev->pRecord           = NULL;
     80
     81            /* All have been initialized. */
     82            bRc = TRUE;
    9083        }
    9184    }
     
    10497
    10598    RtlZeroMemory (&ppdev->vbva, sizeof (ppdev->vbva));
    106 
    107     if (ppdev->hsemHwBuffer)
    108     {
    109         EngDeleteSemaphore (ppdev->hsemHwBuffer);
    110         ppdev->hsemHwBuffer = NULL;
    111     }
    11299
    113100    ppdev->fHwBufferOverflow = FALSE;
     
    130117        uint32_t indexRecordNext;
    131118
    132         EngAcquireSemaphore (ppdev->hsemHwBuffer);
     119        EngAcquireSemaphore (ghsemHwBuffer);
    133120
    134121        VBVA_ASSERT (!ppdev->fHwBufferOverflow);
     
    148135            DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate no space in the queue of records!!! first %d, last %d\n",
    149136                     pVbvaMemory->indexRecordFirst, pVbvaMemory->indexRecordFree));
    150             EngReleaseSemaphore (ppdev->hsemHwBuffer);
     137            EngReleaseSemaphore (ghsemHwBuffer);
    151138        }
    152139        else
     
    190177    ppdev->pRecord = NULL;
    191178
    192     EngReleaseSemaphore (ppdev->hsemHwBuffer);
     179    EngReleaseSemaphore (ghsemHwBuffer);
    193180
    194181    return;
     
    336323}
    337324
     325void VBoxProcessDisplayInfo(PPDEV ppdev)
     326{
     327    DWORD returnedDataLength;
     328
     329    DISPDBG((1, "Process: %d,%d\n", ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y));
     330
     331    EngDeviceIoControl(ppdev->hDriver,
     332                       IOCTL_VIDEO_INTERPRET_DISPLAY_MEMORY,
     333                       NULL,
     334                       0,
     335                       NULL,
     336                       0,
     337                       &returnedDataLength);
     338}
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vbva.c

    r2981 r3153  
    2323#include "driver.h"
    2424
    25 void vboxReportDirtyRect (PPDEV ppdev, RECTL *pRect)
     25void vboxReportDirtyRect (PPDEV ppdev, RECTL *pRectOrig)
    2626{
    2727    if (ppdev)
    2828    {
    2929        VBVACMDHDR hdr;
    30 
    31         hdr.x = (int16_t)pRect->left;
    32         hdr.y = (int16_t)pRect->top;
    33         hdr.w = (uint16_t)(pRect->right - pRect->left);
    34         hdr.h = (uint16_t)(pRect->bottom - pRect->top);
     30       
     31        RECTL rect = *pRectOrig;
     32
     33        if (rect.left < 0) rect.left = 0;
     34        if (rect.top < 0) rect.top = 0;
     35        if (rect.right > (int)ppdev->cxScreen) rect.right = ppdev->cxScreen;
     36        if (rect.bottom > (int)ppdev->cyScreen) rect.bottom = ppdev->cyScreen;
     37
     38        hdr.x = (int16_t)rect.left;
     39        hdr.y = (int16_t)rect.top;
     40        hdr.w = (uint16_t)(rect.right - rect.left);
     41        hdr.h = (uint16_t)(rect.bottom - rect.top);
     42
     43        hdr.x += (int16_t)ppdev->ptlDevOrg.x;
     44        hdr.y += (int16_t)ppdev->ptlDevOrg.y;
    3545
    3646        vboxWrite (ppdev, &hdr, sizeof(hdr));
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vrdp.c

    r2981 r3153  
    304304            DISPDBG((1, "%d rects\n", cRects));
    305305
    306             VBVA_ASSERT(cRects > 0);
    307 
    308             for (; cRects != 0; cRects--, prclClipSrc++)
    309             {
    310                 vrdpIntersectRects (prclClipDst, prclClipSrc, &pClipRects->rclDst);
    311 
    312                 if (vrdpIsRectEmpty (prclClipDst))
     306            if (cRects > 0)
     307            {
     308                for (; cRects != 0; cRects--, prclClipSrc++)
    313309                {
    314                     pClipRects->rects.c--;
     310                    vrdpIntersectRects (prclClipDst, prclClipSrc, &pClipRects->rclDst);
     311
     312                    if (vrdpIsRectEmpty (prclClipDst))
     313                    {
     314                        pClipRects->rects.c--;
     315                    }
     316                    else
     317                    {
     318                        prclClipDst++;
     319                    }
    315320                }
    316                 else
    317                 {
    318                     prclClipDst++;
    319                 }
     321            }
     322            else
     323            {
     324                pClipRects->rclDst.left = pClipRects->rclDst.right = 0;
    320325            }
    321326        }
     
    757762    memcpy (order.pattern, pBrush->u.pat.au8Pattern, sizeof (order.pattern));
    758763
    759     vrdpReportOrderGeneric (ppdev, pClipRects, &order, sizeof (order), VBVA_VRDP_PATBLT_BRUSH);
     764    vrdpReportOrderGeneric (ppdev, pClipRects, &order, sizeof (order), VBVA_VRDP_PATBLTBRUSH);
    760765}
    761766
     
    10511056                int cacheResult;
    10521057
     1058                DISPDBG((1, "VRDP::vrdpBitBlt: MEMBLT.\n"));
    10531059                if (   (psoSrc->fjBitmap & BMF_DONTCACHE) != 0
    10541060                    || psoSrc->iUniq == 0)
     
    10591065                else
    10601066                {
     1067                    DISPDBG((1, "VRDP::vrdpBitBlt: going to cache.\n"));
    10611068                    cacheResult = vrdpbmpCacheSurface (&ppdev->cache, psoSrc, &hash, &hashDeleted);
    10621069                }
     
    17421749void vrdpReset (PPDEV ppdev)
    17431750{
     1751    DISPDBG((1, "vrdpReset %p\n", ppdev));
     1752
    17441753    vrdpbmpReset (&ppdev->cache);
    17451754
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vrdpbmp.c

    r2981 r3153  
    138138{
    139139    BOOL bRc = FALSE;
     140    VRDPBCENTRY *pEntry;
     141
     142    DISPDBG((1, "insert hash cache %p, tail %p.\n", pCache, pCache->tail));
    140143
    141144    /* Get the free entry to be used. Try tail, that should be */
    142     VRDPBCENTRY *pEntry = pCache->tail;
     145    pEntry = pCache->tail;
     146   
     147    if (pEntry == NULL)
     148    {
     149        return bRc;
     150    }
    143151
    144152    if (pEntry->fUsed)
     
    172180    BOOL bResult = bcComputeHash (pso, &hash);
    173181
     182    DISPDBG((1, "vrdpbmpCacheSurface: compute hash %d.\n", bResult));
    174183    if (!bResult)
    175184    {
     
    180189    bResult = bcFindHash (pCache, &hash);
    181190
     191    DISPDBG((1, "vrdpbmpCacheSurface: find hash %d.\n", bResult));
    182192    *phash = hash;
    183193
     
    191201    bResult = bcInsertHash (pCache, &hash, phashDeleted);
    192202
     203    DISPDBG((1, "vrdpbmpCacheSurface: insert hash %d.\n", bResult));
    193204    if (bResult)
    194205    {
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp

    r3118 r3153  
    2424
    2525#include <VBox/VBoxGuest.h>
     26#include <VBox/VBoxVideo.h>
    2627
    2728#include <VBox/VBoxGuestLib.h>
     
    195196
    196197    /* size of the VRAM in bytes */
    197     ULONG totalVramSize = VideoPortReadPortUlong((PULONG)VBE_DISPI_IOPORT_DATA);
    198     ULONG vramSize;
    199 
    200     /* Split up VRAM for DualView */
    201     vramSize = totalVramSize / gNumDisplays;
    202     dprintf(("VBoxVideo: Total VRAM %u bytes, per display %u bytes\n", totalVramSize, vramSize));
     198    ULONG vramSize = DeviceExtension->ulMaxFrameBufferSize;
    203199
    204200    gNumVideoModes = 0;
     
    685681}
    686682
     683/* Computes the size of a framebuffer. DualView has a few framebuffers of the computed size. */
     684static ULONG VBoxVideoComputeMaxFrameBufferSize (ULONG AdapterMemorySize)
     685{
     686    /* The VRAM layout:
     687     *     Last 4096 bytes - Adapter information area.
     688     *     Slack - what left after dividing the VRAM.
     689     *     4096 bytes aligned framebuffers:
     690     *       last 4096 bytes of each framebuffer is the display information area.
     691     */
     692
     693    /* Size of a framebuffer. */
     694    ULONG ulSize = (AdapterMemorySize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE) / gNumDisplays;
     695   
     696    /* Align down to 4096 bytes. */
     697    ulSize &= ~0xFFF;
     698   
     699    dprintf(("VBoxVideo::VBoxVideoComputeMaxFrameBufferSize: AdapterMemorySize = 0x%08X, gNumDisplays = %d, ulSize = 0x%08X, ulSize * gNumDisplays = 0x%08X, slack = 0x%08X\n",
     700             AdapterMemorySize, gNumDisplays, ulSize, ulSize * gNumDisplays, (AdapterMemorySize - 4096) - ulSize * gNumDisplays));
     701   
     702    if (ulSize > VBOX_VIDEO_DISPLAY_INFORMATION_SIZE)
     703    {
     704        /* Compute the size of the framebuffer. */
     705        ulSize -= VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
     706    }
     707    else
     708    {
     709        ulSize = 0;
     710    }
     711   
     712    return ulSize;
     713}
     714
     715static VOID VBoxMapAdapterInfo (PDEVICE_EXTENSION PrimaryExtension, ULONG AdapterMemorySize)
     716{
     717    PHYSICAL_ADDRESS FrameBuffer;
     718    ULONG inIoSpace = 0;
     719    VP_STATUS Status;
     720
     721    dprintf(("VBoxVideo::VBoxSetupAdapterInfo\n"));
     722
     723    FrameBuffer.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS + AdapterMemorySize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE;
     724
     725    PVOID VideoRamBase = NULL;
     726    ULONG VideoRamLength = VBOX_VIDEO_ADAPTER_INFORMATION_SIZE;
     727
     728    Status = VideoPortMapMemory(PrimaryExtension, FrameBuffer,
     729       &VideoRamLength, &inIoSpace,
     730       &VideoRamBase);
     731
     732    if (Status == NO_ERROR)
     733    {
     734        PrimaryExtension->AdapterInformation = VideoRamBase;
     735    }
     736    else
     737    {
     738        PrimaryExtension->AdapterInformation = NULL;
     739    }
     740}
     741
     742static VOID VBoxSetupAdapterInfo (PDEVICE_EXTENSION PrimaryExtension)
     743{
     744    if (!PrimaryExtension->AdapterInformation)
     745    {
     746        return;
     747    }
     748   
     749    /* That dublicates the code in VBoxSetupDisplays, better would be to have
     750     * linked list of device extestions and fill the adapter memory with
     751     * information from these extension structures.
     752     */
     753    uint8_t *pu8 = (uint8_t *)PrimaryExtension->AdapterInformation;
     754    uint32_t u32Offset = 0;
     755   
     756    VBOXVIDEOINFOHDR *pHdr;
     757    int iDisplay;
     758
     759    for (iDisplay = 0; iDisplay < gNumDisplays; ++iDisplay)
     760    {
     761        pHdr = (VBOXVIDEOINFOHDR *)pu8;
     762        pu8 += sizeof (VBOXVIDEOINFOHDR);
     763
     764        pHdr->u8Type     = VBOX_VIDEO_INFO_TYPE_DISPLAY;
     765        pHdr->u8Reserved = 0;
     766        pHdr->u16Length  = sizeof (VBOXVIDEOINFODISPLAY);
     767
     768        VBOXVIDEOINFODISPLAY *pDisplay = (VBOXVIDEOINFODISPLAY *)pu8;
     769        pu8 += sizeof (VBOXVIDEOINFODISPLAY);
     770
     771        pDisplay->u32Index           = iDisplay;
     772        pDisplay->u32Offset          = u32Offset;
     773        pDisplay->u32FramebufferSize = PrimaryExtension->ulMaxFrameBufferSize;
     774        pDisplay->u32InformationSize = VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
     775       
     776        u32Offset += PrimaryExtension->ulMaxFrameBufferSize + VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
     777    }
     778
     779    pHdr = (VBOXVIDEOINFOHDR *)pu8;
     780    pu8 += sizeof (VBOXVIDEOINFOHDR);
     781
     782    pHdr->u8Type     = VBOX_VIDEO_INFO_TYPE_END;
     783    pHdr->u8Reserved = 0;
     784    pHdr->u16Length  = 0;
     785
     786    /* Inform the host about the display configuration. */
     787    VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_CMONITORS);
     788    VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY);
     789}
     790
    687791/**
    688792 * Helper function to register secondary displays (DualView). Note that this will not
     
    690794 * intentionally crippled.
    691795 */
    692 VOID VBoxRegisterSecondaryDisplays(PDEVICE_EXTENSION PrimaryExtension, PVIDEO_PORT_CONFIG_INFO pConfigInfo)
     796VOID VBoxSetupDisplays(PDEVICE_EXTENSION PrimaryExtension, PVIDEO_PORT_CONFIG_INFO pConfigInfo)
    693797{
    694798   typedef VP_STATUS (*pCreateSecDisp)(PVOID, PVOID *, ULONG);
     
    698802   VP_STATUS rc;
    699803   PDEVICE_EXTENSION pSecExt;
    700 
    701    dprintf(("VBoxVideo::VBoxRegisterSecondaryDisplays\n"));
    702 
    703    /* Initialize DualView related stuff in device extension (must be done always!) */
     804   ULONG AdapterMemorySize;
     805
     806   dprintf(("VBoxVideo::VBoxRegisterSecondaryDisplays: PrimaryExtension = %p\n", PrimaryExtension));
     807
     808   AdapterMemorySize = VideoPortReadPortUlong((PULONG)VBE_DISPI_IOPORT_DATA);
     809
     810   /* Initialize DualView related stuff in device extension for 1 monitor (must be done always!).
     811    * Assume that the is no dual view and initialize the maximum possible frame buffer size.
     812    * Also assume no VBox extension support.
     813    */
    704814   PrimaryExtension->iDevice      = 0;
    705815   PrimaryExtension->pvPrimaryExt = PrimaryExtension;
     816
     817   PrimaryExtension->ulFrameBufferOffset = 0;
     818   PrimaryExtension->ulMaxFrameBufferSize = AdapterMemorySize -
     819                                            VBOX_VIDEO_ADAPTER_INFORMATION_SIZE -
     820                                            VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
     821   PrimaryExtension->bDualViewSupported = FALSE;
     822   PrimaryExtension->AdapterInformation = NULL;
     823   
     824   /* Verify that the HW support VirtualBox extensions. */
     825   VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
     826   VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_VBOX_VIDEO);
     827   if (VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA) != VBE_DISPI_ID_VBOX_VIDEO)
     828   {
     829       dprintf(("VBoxVideo::VBoxSetupDisplays: virtual hardware do not support VBox extensions!!!\n"));
     830       return;
     831   }
     832
     833   /* Map the adapter information memory. */
     834   VBoxMapAdapterInfo (PrimaryExtension, AdapterMemorySize);
     835   
     836   if (!PrimaryExtension->AdapterInformation)
     837   {
     838       dprintf(("VBoxVideo::VBoxSetupDisplays: failed to map adapter memory!!!\n"));
     839       return;
     840   }
    706841
    707842   /* Dynamically query the VideoPort import to be binary compatible across Windows versions */
     
    725860      dprintf(("VBoxVideo::VBoxRegisterSecondaryDisplays: gNumDisplays = %d\n", gNumDisplays));
    726861
     862      PrimaryExtension->bDualViewSupported = (gNumDisplays != 0);
     863
     864      /* Now when the number of monitors is known, update the maximum size. */
     865      PrimaryExtension->ulMaxFrameBufferSize = VBoxVideoComputeMaxFrameBufferSize (AdapterMemorySize);
     866
    727867      for (iDisplay = 1; iDisplay < gNumDisplays; ++iDisplay)
    728868      {
    729869         rc = pVPCreateSecDisp(PrimaryExtension, (PVOID*)&pSecExt, VIDEO_DUALVIEW_REMOVABLE);
    730          dprintf(("VBoxVideo::VBoxRegisterSecondaryDisplays: VideoPortCreateSecondaryDisplay returned %#x\n", rc));
     870         dprintf(("VBoxVideo::VBoxRegisterSecondaryDisplays: VideoPortCreateSecondaryDisplay returned %#x, pSecExt = %p\n", rc, pSecExt));
    731871         if (rc != NO_ERROR)   /* Failure to create secondary displays is not fatal */
    732872            break;
     
    734874         pSecExt->iDevice = iDisplay;
    735875         pSecExt->pvPrimaryExt = PrimaryExtension;
     876
     877         pSecExt->ulFrameBufferOffset = iDisplay * (PrimaryExtension->ulMaxFrameBufferSize + VBOX_VIDEO_DISPLAY_INFORMATION_SIZE);
     878         pSecExt->ulMaxFrameBufferSize = PrimaryExtension->ulMaxFrameBufferSize;
     879         pSecExt->bDualViewSupported = PrimaryExtension->bDualViewSupported;
     880         pSecExt->AdapterInformation = PrimaryExtension->AdapterInformation;
    736881      }
    737882   }
     883
     884   VBoxSetupAdapterInfo (PrimaryExtension);
    738885}
    739886
     
    819966
    820967      /* Attempt to register secondary displays */
    821       VBoxRegisterSecondaryDisplays((PDEVICE_EXTENSION)HwDeviceExtension, ConfigInfo);
     968      VBoxSetupDisplays((PDEVICE_EXTENSION)HwDeviceExtension, ConfigInfo);
    822969
    823970      // pretend success to make the driver work.
     
    12131360        }
    12141361
     1362        case IOCTL_VIDEO_INTERPRET_DISPLAY_MEMORY:
     1363        {
     1364            dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_INTERPRET_DISPLAY_MEMORY\n"));
     1365
     1366            if (pDevExt->bDualViewSupported)
     1367            {
     1368                /* The display driver must have prepared the monitor information. */
     1369                VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_CMONITORS);
     1370                VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE + pDevExt->iDevice);
     1371            }
     1372            else
     1373            {
     1374                RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
     1375            }
     1376            Result = pDevExt->bDualViewSupported;
     1377            break;
     1378        }
     1379
     1380        case IOCTL_VIDEO_QUERY_DISPLAY_INFO:
     1381        {
     1382            dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_QUERY_DISPLAY_INFO\n"));
     1383
     1384            if (RequestPacket->OutputBufferLength < sizeof(QUERYDISPLAYINFORESULT))
     1385            {
     1386                dprintf(("VBoxVideo::VBoxVideoStartIO: output buffer too small: %d needed: %d!!!\n",
     1387                         RequestPacket->OutputBufferLength, sizeof(QUERYDISPLAYINFORESULT)));
     1388                RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
     1389                return FALSE;
     1390            }
     1391
     1392            QUERYDISPLAYINFORESULT *pDispInfo = (QUERYDISPLAYINFORESULT *)RequestPacket->OutputBuffer;
     1393           
     1394            pDispInfo->iDevice = pDevExt->iDevice;
     1395            pDispInfo->u32DisplayInfoSize = VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
     1396
     1397            RequestPacket->StatusBlock->Information = sizeof(QUERYDISPLAYINFORESULT);
     1398            Result = TRUE;
     1399
     1400            break;
     1401        }
     1402
    12151403        case IOCTL_VIDEO_VBVA_ENABLE:
    12161404        {
     
    12561444
    12571445        default:
    1258             dprintf(("VBoxVideo::VBoxVideoStartIO: unsupported %p\n", RequestPacket->IoControlCode));
     1446            dprintf(("VBoxVideo::VBoxVideoStartIO: unsupported %p, fn %d(0x%x)\n",
     1447                      RequestPacket->IoControlCode,
     1448                      (RequestPacket->IoControlCode >> 2) & 0xFFF,
     1449                      (RequestPacket->IoControlCode >> 2) & 0xFFF));
    12591450            RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
    12601451            return FALSE;
     
    12791470{
    12801471    dprintf(("VBoxVideo::VBoxVideoResetHW\n"));
     1472
     1473    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)HwDeviceExtension;
     1474
     1475    if (pDevExt->iDevice > 0)
     1476    {
     1477        dprintf(("VBoxVideo::VBoxVideoResetHW: Skipping for non-primary display %d\n",
     1478                 pDevExt->iDevice));
     1479        return TRUE;
     1480    }
     1481
    12811482    VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
    12821483    VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED);
    12831484
    1284     PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)HwDeviceExtension;
    12851485    if (pDevExt->pvReqFlush != NULL)
    12861486    {
     
    13351535             ModeInfo->VisScreenHeight, ModeInfo->BitsPerPlane));
    13361536
    1337     if (DeviceExtension->iDevice > 0) {
     1537    if (DeviceExtension->iDevice > 0)
     1538    {
    13381539        dprintf(("VBoxVideo::VBoxVideoSetCurrentMode: Skipping for non-primary display %d\n",
    13391540                 DeviceExtension->iDevice));
     
    13691570   dprintf(("VBoxVideo::VBoxVideoResetDevice\n"));
    13701571
     1572    if (DeviceExtension->iDevice > 0)
     1573    {
     1574        /* If the device is the secondary display, however, it is recommended that no action be taken. */
     1575        dprintf(("VBoxVideo::VBoxVideoResetDevice: Skipping for non-primary display %d\n",
     1576                 DeviceExtension->iDevice));
     1577        return TRUE;
     1578    }
     1579
    13711580#if 0
    13721581   /* Don't disable the extended video mode. This would only switch the video mode
     
    13931602    PHYSICAL_ADDRESS FrameBuffer;
    13941603    ULONG inIoSpace = 0;
    1395     ULONG ulOffset;
    1396     ULONG AdapterMemorySize;
    13971604    VP_STATUS Status;
    13981605
    13991606    dprintf(("VBoxVideo::VBoxVideoMapVideoMemory\n"));
    14001607
    1401     AdapterMemorySize = VideoPortReadPortUlong((PULONG)VBE_DISPI_IOPORT_DATA);
    1402 
    1403     FrameBuffer.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
     1608    FrameBuffer.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS + DeviceExtension->ulFrameBufferOffset;
     1609
    14041610    MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
    1405     MapInformation->VideoRamLength = AdapterMemorySize;
    1406 //       VideoModes[DeviceExtension->CurrentMode - 1].VideoMemoryBitmapHeight *
    1407 //       VideoModes[DeviceExtension->CurrentMode - 1].ScreenStride;
     1611    MapInformation->VideoRamLength = DeviceExtension->ulMaxFrameBufferSize + VBOX_VIDEO_DISPLAY_INFORMATION_SIZE;
    14081612
    14091613    Status = VideoPortMapMemory(DeviceExtension, FrameBuffer,
     
    14131617    if (Status == NO_ERROR)
    14141618    {
    1415         /* Calculate VRAM offset for DualView */
    1416         ulOffset = AdapterMemorySize / gNumDisplays * DeviceExtension->iDevice;
    1417 
    1418         MapInformation->FrameBufferBase = (PUCHAR)MapInformation->VideoRamBase + ulOffset;
     1619        MapInformation->FrameBufferBase = (PUCHAR)MapInformation->VideoRamBase;
    14191620        MapInformation->FrameBufferLength =
    14201621            VideoModes[DeviceExtension->CurrentMode - 1].VisScreenHeight *
     
    15411742   PULONG pUnused)
    15421743{
    1543     dprintf(("VBoxVideo::VBoxVideoGetChildDescriptor\n"));
     1744   dprintf(("VBoxVideo::VBoxVideoGetChildDescriptor: HwDeviceExtension = %p, ChildEnumInfo = %p\n",
     1745            HwDeviceExtension, ChildEnumInfo));
    15441746
    15451747    DEVICE_EXTENSION *pDevExt = (DEVICE_EXTENSION *)HwDeviceExtension;
     
    15651767{
    15661768    DEVICE_EXTENSION *pDevExt = (DEVICE_EXTENSION *)pvFlush;
    1567 
    1568     if (pDevExt && pDevExt->pvReqFlush)
    1569     {
    1570         VMMDevVideoAccelFlush *req = (VMMDevVideoAccelFlush *)pDevExt->pvReqFlush;
    1571 
    1572         int rc = VbglGRPerform (&req->header);
    1573 
    1574         if (VBOX_FAILURE(rc) || VBOX_FAILURE(req->header.rc))
    1575         {
    1576             dprintf(("VBoxVideo::vbvaFlush: rc = %Vrc, VMMDev rc = %Vrc!!!\n", rc, req->header.rc));
     1769    DEVICE_EXTENSION *pPrimaryDevExt = (DEVICE_EXTENSION *)(pDevExt? pDevExt->pvPrimaryExt: NULL);
     1770
     1771    if (pPrimaryDevExt)
     1772    {
     1773        VMMDevVideoAccelFlush *req = (VMMDevVideoAccelFlush *)pPrimaryDevExt->pvReqFlush;
     1774
     1775        if (req)
     1776        {
     1777            int rc = VbglGRPerform (&req->header);
     1778
     1779            if (VBOX_FAILURE(rc) || VBOX_FAILURE(req->header.rc))
     1780            {
     1781                dprintf(("VBoxVideo::vbvaFlush: rc = %Vrc, VMMDev rc = %Vrc!!!\n", rc, req->header.rc));
     1782            }
    15771783        }
    15781784    }
     
    15961802    dprintf(("VBoxVideo::vboxVbvaEnable: VbglQueryVMMDevMemory rc = %d, pVMMDevMemory = %p\n", rc, pVMMDevMemory));
    15971803   
     1804    if (pDevExt->iDevice > 0)
     1805    {
     1806        DEVICE_EXTENSION *pPrimaryDevExt = (DEVICE_EXTENSION *)pDevExt->pvPrimaryExt;
     1807
     1808        dprintf(("VBoxVideo::vboxVbvaEnable: Skipping for non-primary display %d\n",
     1809                 pDevExt->iDevice));
     1810       
     1811        if (   ulEnable
     1812            && pPrimaryDevExt->ulVbvaEnabled)
     1813        {
     1814            pVbvaResult->pVbvaMemory = &pVMMDevMemory->vbvaMemory;
     1815            pVbvaResult->pfnFlush    = vboxVbvaFlush;
     1816            pVbvaResult->pvFlush     = pDevExt;
     1817        }
     1818        else
     1819        {
     1820            VideoPortZeroMemory(&pVbvaResult, sizeof(VBVAENABLERESULT));
     1821        }
     1822
     1823        return rc;
     1824    }
     1825
    15981826    if (VBOX_SUCCESS(rc))
    15991827    {
     
    16241852    if (VBOX_SUCCESS(rc))
    16251853    {
     1854        ULONG ulEnabled = 0;
     1855
    16261856        /*
    16271857         * Tell host that VBVA status is changed.
     
    16531883                        pVbvaResult->pfnFlush    = vboxVbvaFlush;
    16541884                        pVbvaResult->pvFlush     = pDevExt;
     1885                        ulEnabled = 1;
    16551886                    }
    16561887                    else
     
    16841915                }
    16851916            }
     1917
     1918            VbglGRFree (&req->header);
    16861919        }
    16871920        else
     
    16891922            dprintf(("VBoxVideo::vboxVbvaEnable: VbglGRAlloc rc = %Vrc!!!\n", rc));
    16901923        }
     1924
     1925        pDevExt->ulVbvaEnabled = ulEnabled;
    16911926    }
    16921927
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h

    r2981 r3153  
    4545#define VBE_DISPI_INDEX_CMONITORS       0xa
    4646#define VBE_DISPI_ID2                   0xB0C2
     47/* The VBOX interface id. Indicates support for VBE_DISPI_INDEX_CMONITORS. */
     48#define VBE_DISPI_ID_VBOX_VIDEO         0xBE00
    4749#define VBE_DISPI_DISABLED              0x00
    4850#define VBE_DISPI_ENABLED               0x01
     
    6668   PVOID pvPrimaryExt;  /* Pointer to primary device extension */
    6769   BOOLEAN bEnabled;    /* Device enabled flag */
     70
     71   ULONG ulFrameBufferOffset;
     72   ULONG ulMaxFrameBufferSize;
     73
     74   BOOLEAN bDualViewSupported;
     75   
     76   PVOID AdapterInformation;
     77   
     78   ULONG ulVbvaEnabled;
    6879} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    6980
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/vboxioctl.h

    r2981 r3153  
    2525
    2626#include <VBox/VBoxGuest.h>
     27
     28#define IOCTL_VIDEO_INTERPRET_DISPLAY_MEMORY \
     29    CTL_CODE(FILE_DEVICE_VIDEO, 0x420, METHOD_BUFFERED, FILE_ANY_ACCESS)
     30
     31#define IOCTL_VIDEO_QUERY_DISPLAY_INFO \
     32    CTL_CODE(FILE_DEVICE_VIDEO, 0x421, METHOD_BUFFERED, FILE_ANY_ACCESS)
    2733
    2834/** Called by the display driver when it is ready to
     
    5965
    6066} VBVAENABLERESULT;
     67
     68/**
     69 * Data returned by IOCTL_VIDEO_QUERY_DISPLAY_INFO.
     70 *
     71 */
     72typedef struct _QUERYDISPLAYINFORESULT
     73{
     74    /* Device index (0 for primary) */
     75    ULONG iDevice;
     76
     77    /* Size of the display information area. */
     78    uint32_t u32DisplayInfoSize;
     79} QUERYDISPLAYINFORESULT;
    6180#pragma pack()
    6281
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