VirtualBox

Ignore:
Timestamp:
Nov 28, 2010 10:12:07 PM (14 years ago)
Author:
vboxsync
Message:

Additions/WINNT/Graphics and Additions/common/VBoxVideo: move the base VBVA support functions into the common driver code

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp

    r34438 r34440  
    11/* $Id$ */
    22/** @file
    3  * Display - VirtualBox Win 2000/XP guest display driver, support functions.
     3 * VirtualBox Video driver, common code - VBVA initialisation and helper
     4 * functions.
    45 */
    56
    67/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     8 * Copyright (C) 2006-2010 Oracle Corporation
    89 *
    910 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1617 */
    1718
    18 #include "driver.h"
    19 
    20 #include <VBox/VMMDev.h>
    21 #include <VBox/VBoxGuest.h>
     19#include <VBox/VBoxVideoGuest.h>
     20#include <VBox/VBoxVideo.h>
    2221#include <VBox/err.h>
    2322#include <VBox/log.h>
    24 #include <iprt/asm.h>
    25 #include <iprt/asm-amd64-x86.h>
    2623#include <iprt/assert.h>
    2724
     25#include <string.h>
     26
    2827/*
    29  * There is a hardware ring buffer in the VBox VMMDev PCI memory space.
     28 * There is a hardware ring buffer in the graphics device video RAM, formerly
     29 * in the VBox VMMDev PCI memory space.
    3030 * All graphics commands go there serialized by VBoxVBVABufferBeginUpdate.
    3131 * and vboxHwBufferEndUpdate.
     
    365365    if (!pVBVA)
    366366    {
    367         return FALSE;
     367        return false;
    368368    }
    369369
     
    373373    }
    374374
    375     return FALSE;
     375    return false;
    376376}
    377377
     
    414414    }
    415415}
    416 
    417 void VBoxProcessDisplayInfo (PPDEV ppdev)
    418 {
    419     if (ppdev->bHGSMISupported)
    420     {
    421         VBoxHGSMIProcessDisplayInfo(&ppdev->guestCtx, ppdev->iDevice,
    422                                      ppdev->ptlDevOrg.x, ppdev->ptlDevOrg.y, 0,
    423                                        ppdev->lDeltaScreen > 0
    424                                      ? ppdev->lDeltaScreen
    425                                      : -ppdev->lDeltaScreen, ppdev->cxScreen,
    426                                      ppdev->cyScreen,
    427                                      (uint16_t)ppdev->ulBitCount);
    428     }
    429 
    430     return;
    431 }
    432 
    433 #ifdef VBOX_WITH_VIDEOHWACCEL
    434 
    435 VBOXVHWACMD* vboxVHWACommandCreate (PPDEV ppdev, VBOXVHWACMD_TYPE enmCmd, VBOXVHWACMD_LENGTH cbCmd)
    436 {
    437     VBOXVHWACMD* pHdr = (VBOXVHWACMD*)VBoxHGSMIBufferAlloc(&ppdev->guestCtx,
    438                               cbCmd + VBOXVHWACMD_HEADSIZE(),
    439                               HGSMI_CH_VBVA,
    440                               VBVA_VHWA_CMD);
    441     if (!pHdr)
    442     {
    443         LogFunc(("HGSMIHeapAlloc failed\n"));
    444     }
    445     else
    446     {
    447         memset(pHdr, 0, sizeof(VBOXVHWACMD));
    448         pHdr->iDisplay = ppdev->iDevice;
    449         pHdr->rc = VERR_GENERAL_FAILURE;
    450         pHdr->enmCmd = enmCmd;
    451         pHdr->cRefs = 1;
    452     }
    453 
    454     /* temporary hack */
    455     vboxVHWACommandCheckHostCmds(ppdev);
    456 
    457     return pHdr;
    458 }
    459 
    460 void vboxVHWACommandFree (PPDEV ppdev, VBOXVHWACMD* pCmd)
    461 {
    462     VBoxHGSMIBufferFree(&ppdev->guestCtx, pCmd);
    463 }
    464 
    465 static DECLCALLBACK(void) vboxVHWACommandCompletionCallbackEvent(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
    466 {
    467     VBOXPEVENT pEvent = (VBOXPEVENT)pContext;
    468     LONG oldState = ppdev->VideoPortProcs.pfnSetEvent(ppdev->pVideoPortContext, pEvent);
    469     Assert(!oldState);
    470 }
    471 
    472 static int vboxVHWAHanldeVHWACmdCompletion(PPDEV ppdev, VBVAHOSTCMD * pHostCmd)
    473 {
    474     VBVAHOSTCMDVHWACMDCOMPLETE * pComplete = VBVAHOSTCMD_BODY(pHostCmd, VBVAHOSTCMDVHWACMDCOMPLETE);
    475     VBOXVHWACMD* pComplCmd = (VBOXVHWACMD*)HGSMIOffsetToPointer (&ppdev->guestCtx.heapCtx.area, pComplete->offCmd);
    476     PFNVBOXVHWACMDCOMPLETION pfnCompletion = (PFNVBOXVHWACMDCOMPLETION)pComplCmd->GuestVBVAReserved1;
    477     void * pContext = (void *)pComplCmd->GuestVBVAReserved2;
    478 
    479     pfnCompletion(ppdev, pComplCmd, pContext);
    480 
    481     vboxVBVAHostCommandComplete(ppdev, pHostCmd);
    482 
    483     return 0;
    484 }
    485 
    486 static void vboxVBVAHostCommandHanlder(PPDEV ppdev, VBVAHOSTCMD * pCmd)
    487 {
    488     int rc = VINF_SUCCESS;
    489     switch(pCmd->customOpCode)
    490     {
    491 # ifdef VBOX_WITH_VIDEOHWACCEL /** @todo why is this ifdef nested within itself? */
    492         case VBVAHG_DCUSTOM_VHWA_CMDCOMPLETE:
    493         {
    494             vboxVHWAHanldeVHWACmdCompletion(ppdev, pCmd);
    495             break;
    496         }
    497 # endif
    498         default:
    499         {
    500             Assert(0);
    501             vboxVBVAHostCommandComplete(ppdev, pCmd);
    502         }
    503     }
    504 }
    505 
    506 void vboxVHWACommandCheckHostCmds(PPDEV ppdev)
    507 {
    508     VBVAHOSTCMD * pCmd, * pNextCmd;
    509     int rc = ppdev->pfnHGSMIRequestCommands(ppdev->hMpHGSMI, HGSMI_CH_VBVA, ppdev->iDevice, &pCmd);
    510     /* don't assert here, otherwise NT4 will be unhappy */
    511     if(RT_SUCCESS(rc))
    512     {
    513         for(;pCmd; pCmd = pNextCmd)
    514         {
    515             pNextCmd = pCmd->u.pNext;
    516             vboxVBVAHostCommandHanlder(ppdev, pCmd);
    517         }
    518     }
    519 }
    520 
    521 void vboxVHWACommandSubmitAsynchByEvent (PPDEV ppdev, VBOXVHWACMD* pCmd, VBOXPEVENT pEvent)
    522 {
    523 //    Assert(0);
    524     pCmd->GuestVBVAReserved1 = (uintptr_t)pEvent;
    525     pCmd->GuestVBVAReserved2 = 0;
    526     /* ensure the command is not removed until we're processing it */
    527     vbvaVHWACommandRetain(ppdev, pCmd);
    528 
    529     /* complete it asynchronously by setting event */
    530     pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_EVENT;
    531     VBoxHGSMIBufferSubmit(&ppdev->guestCtx, pCmd);
    532 
    533     if(!(ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags)  & VBOXVHWACMD_FLAG_HG_ASYNCH))
    534     {
    535         /* the command is completed */
    536         ppdev->VideoPortProcs.pfnSetEvent(ppdev->pVideoPortContext, pEvent);
    537     }
    538 
    539     vbvaVHWACommandRelease(ppdev, pCmd);
    540 }
    541 
    542 BOOL vboxVHWACommandSubmit (PPDEV ppdev, VBOXVHWACMD* pCmd)
    543 {
    544     VBOXPEVENT pEvent;
    545     VBOXVP_STATUS rc = ppdev->VideoPortProcs.pfnCreateEvent(ppdev->pVideoPortContext, VBOXNOTIFICATION_EVENT, NULL, &pEvent);
    546     /* don't assert here, otherwise NT4 will be unhappy */
    547     if(rc == VBOXNO_ERROR)
    548     {
    549         pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ;
    550         vboxVHWACommandSubmitAsynchByEvent (ppdev, pCmd, pEvent);
    551 
    552         rc = ppdev->VideoPortProcs.pfnWaitForSingleObject(ppdev->pVideoPortContext, pEvent,
    553                 NULL /*IN PLARGE_INTEGER  pTimeOut*/
    554                 );
    555         Assert(rc == VBOXNO_ERROR);
    556         if(rc == VBOXNO_ERROR)
    557         {
    558             ppdev->VideoPortProcs.pfnDeleteEvent(ppdev->pVideoPortContext, pEvent);
    559         }
    560     }
    561     return rc == VBOXNO_ERROR;
    562 }
    563 
    564 /* do not wait for completion */
    565 void vboxVHWACommandSubmitAsynch (PPDEV ppdev, VBOXVHWACMD* pCmd, PFNVBOXVHWACMDCOMPLETION pfnCompletion, void * pContext)
    566 {
    567 //    Assert(0);
    568     pCmd->GuestVBVAReserved1 = (uintptr_t)pfnCompletion;
    569     pCmd->GuestVBVAReserved2 = (uintptr_t)pContext;
    570     vbvaVHWACommandRetain(ppdev, pCmd);
    571 
    572     VBoxHGSMIBufferSubmit(&ppdev->guestCtx, pCmd);
    573 
    574     if(!(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH))
    575     {
    576         /* the command is completed */
    577         pfnCompletion(ppdev, pCmd, pContext);
    578     }
    579 
    580     vbvaVHWACommandRelease(ppdev, pCmd);
    581 }
    582 
    583 static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
    584 {
    585     vbvaVHWACommandRelease(ppdev, pCmd);
    586 }
    587 
    588 void vboxVHWACommandSubmitAsynchAndComplete (PPDEV ppdev, VBOXVHWACMD* pCmd)
    589 {
    590 //    Assert(0);
    591     pCmd->GuestVBVAReserved1 = (uintptr_t)vboxVHWAFreeCmdCompletion;
    592 
    593     vbvaVHWACommandRetain(ppdev, pCmd);
    594 
    595     pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION;
    596 
    597     VBoxHGSMIBufferSubmit(&ppdev->guestCtx, pCmd);
    598 
    599     if(!(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH)
    600             || pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED)
    601     {
    602         /* the command is completed */
    603         vboxVHWAFreeCmdCompletion(ppdev, pCmd, NULL);
    604     }
    605 
    606     vbvaVHWACommandRelease(ppdev, pCmd);
    607 }
    608 
    609 void vboxVHWAFreeHostInfo1(PPDEV ppdev, VBOXVHWACMD_QUERYINFO1* pInfo)
    610 {
    611     VBOXVHWACMD* pCmd = VBOXVHWACMD_HEAD(pInfo);
    612     vbvaVHWACommandRelease (ppdev, pCmd);
    613 }
    614 
    615 void vboxVHWAFreeHostInfo2(PPDEV ppdev, VBOXVHWACMD_QUERYINFO2* pInfo)
    616 {
    617     VBOXVHWACMD* pCmd = VBOXVHWACMD_HEAD(pInfo);
    618     vbvaVHWACommandRelease (ppdev, pCmd);
    619 }
    620 
    621 VBOXVHWACMD_QUERYINFO1* vboxVHWAQueryHostInfo1(PPDEV ppdev)
    622 {
    623     VBOXVHWACMD* pCmd = vboxVHWACommandCreate (ppdev, VBOXVHWACMD_TYPE_QUERY_INFO1, sizeof(VBOXVHWACMD_QUERYINFO1));
    624     VBOXVHWACMD_QUERYINFO1 *pInfo1;
    625     if (!pCmd)
    626     {
    627         DISPDBG((0, "VBoxDISP::vboxVHWAQueryHostInfo1: vboxVHWACommandCreate failed\n"));
    628         return NULL;
    629     }
    630 
    631     if (!pCmd)
    632     {
    633         DISPDBG((0, "VBoxDISP::vboxVHWAQueryHostInfo1: vboxVHWACommandCreate failed\n"));
    634         return NULL;
    635     }
    636 
    637     pInfo1 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
    638     pInfo1->u.in.guestVersion.maj = VBOXVHWA_VERSION_MAJ;
    639     pInfo1->u.in.guestVersion.min = VBOXVHWA_VERSION_MIN;
    640     pInfo1->u.in.guestVersion.bld = VBOXVHWA_VERSION_BLD;
    641     pInfo1->u.in.guestVersion.reserved = VBOXVHWA_VERSION_RSV;
    642 
    643     if(vboxVHWACommandSubmit (ppdev, pCmd))
    644     {
    645         if(RT_SUCCESS(pCmd->rc))
    646         {
    647             return VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
    648         }
    649     }
    650 
    651     vbvaVHWACommandRelease (ppdev, pCmd);
    652     return NULL;
    653 }
    654 
    655 VBOXVHWACMD_QUERYINFO2* vboxVHWAQueryHostInfo2(PPDEV ppdev, uint32_t numFourCC)
    656 {
    657     VBOXVHWACMD* pCmd = vboxVHWACommandCreate (ppdev, VBOXVHWACMD_TYPE_QUERY_INFO2, VBOXVHWAINFO2_SIZE(numFourCC));
    658     VBOXVHWACMD_QUERYINFO2 *pInfo2;
    659     if (!pCmd)
    660     {
    661         DISPDBG((0, "VBoxDISP::vboxVHWAQueryHostInfo2: vboxVHWACommandCreate failed\n"));
    662         return NULL;
    663     }
    664 
    665     pInfo2 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
    666     pInfo2->numFourCC = numFourCC;
    667 
    668     if(vboxVHWACommandSubmit (ppdev, pCmd))
    669     {
    670         if(RT_SUCCESS(pCmd->rc))
    671         {
    672             if(pInfo2->numFourCC == numFourCC)
    673             {
    674                 return pInfo2;
    675             }
    676         }
    677     }
    678 
    679     vbvaVHWACommandRelease (ppdev, pCmd);
    680     return NULL;
    681 }
    682 
    683 int vboxVHWAInitHostInfo1(PPDEV ppdev)
    684 {
    685     VBOXVHWACMD_QUERYINFO1* pInfo;
    686 
    687     if (!ppdev->bHGSMISupported)
    688         return VERR_NOT_SUPPORTED;
    689 
    690     pInfo = vboxVHWAQueryHostInfo1(ppdev);
    691     if(!pInfo)
    692     {
    693         ppdev->vhwaInfo.bVHWAEnabled = false;
    694         return VERR_OUT_OF_RESOURCES;
    695     }
    696 
    697     ppdev->vhwaInfo.caps = pInfo->u.out.caps;
    698     ppdev->vhwaInfo.caps2 = pInfo->u.out.caps2;
    699     ppdev->vhwaInfo.colorKeyCaps = pInfo->u.out.colorKeyCaps;
    700     ppdev->vhwaInfo.stretchCaps = pInfo->u.out.stretchCaps;
    701     ppdev->vhwaInfo.surfaceCaps = pInfo->u.out.surfaceCaps;
    702     ppdev->vhwaInfo.numOverlays = pInfo->u.out.numOverlays;
    703     ppdev->vhwaInfo.numFourCC = pInfo->u.out.numFourCC;
    704     ppdev->vhwaInfo.bVHWAEnabled = (pInfo->u.out.cfgFlags & VBOXVHWA_CFG_ENABLED);
    705     vboxVHWAFreeHostInfo1(ppdev, pInfo);
    706     return VINF_SUCCESS;
    707 }
    708 
    709 int vboxVHWAInitHostInfo2(PPDEV ppdev, DWORD *pFourCC)
    710 {
    711     VBOXVHWACMD_QUERYINFO2* pInfo;
    712     int rc = VINF_SUCCESS;
    713 
    714     if (!ppdev->bHGSMISupported)
    715         return VERR_NOT_SUPPORTED;
    716 
    717     pInfo = vboxVHWAQueryHostInfo2(ppdev, ppdev->vhwaInfo.numFourCC);
    718 
    719     Assert(pInfo);
    720     if(!pInfo)
    721         return VERR_OUT_OF_RESOURCES;
    722 
    723     if(ppdev->vhwaInfo.numFourCC)
    724     {
    725         memcpy(pFourCC, pInfo->FourCC, ppdev->vhwaInfo.numFourCC * sizeof(pFourCC[0]));
    726     }
    727     else
    728     {
    729         Assert(0);
    730         rc = VERR_GENERAL_FAILURE;
    731     }
    732 
    733     vboxVHWAFreeHostInfo2(ppdev, pInfo);
    734 
    735     return rc;
    736 }
    737 
    738 int vboxVHWAEnable(PPDEV ppdev)
    739 {
    740     int rc = VERR_GENERAL_FAILURE;
    741     VBOXVHWACMD* pCmd;
    742 
    743     if (!ppdev->bHGSMISupported)
    744         return VERR_NOT_SUPPORTED;
    745 
    746     pCmd = vboxVHWACommandCreate (ppdev, VBOXVHWACMD_TYPE_ENABLE, 0);
    747     if (!pCmd)
    748     {
    749         DISPDBG((0, "VBoxDISP::vboxVHWAEnable: vboxVHWACommandCreate failed\n"));
    750         return rc;
    751     }
    752 
    753     if(vboxVHWACommandSubmit (ppdev, pCmd))
    754     {
    755         if(RT_SUCCESS(pCmd->rc))
    756         {
    757             rc = VINF_SUCCESS;
    758         }
    759     }
    760 
    761     vbvaVHWACommandRelease (ppdev, pCmd);
    762     return rc;
    763 }
    764 
    765 int vboxVHWADisable(PPDEV ppdev)
    766 {
    767     int rc = VERR_GENERAL_FAILURE;
    768     VBOXVHWACMD* pCmd;
    769 
    770     if (!ppdev->bHGSMISupported)
    771         return VERR_NOT_SUPPORTED;
    772 
    773     pCmd = vboxVHWACommandCreate (ppdev, VBOXVHWACMD_TYPE_DISABLE, 0);
    774     if (!pCmd)
    775     {
    776         DISPDBG((0, "VBoxDISP::vboxVHWADisable: vboxVHWACommandCreate failed\n"));
    777         return rc;
    778     }
    779 
    780     if(vboxVHWACommandSubmit (ppdev, pCmd))
    781     {
    782         if(RT_SUCCESS(pCmd->rc))
    783         {
    784             rc = VINF_SUCCESS;
    785         }
    786     }
    787 
    788     vbvaVHWACommandRelease (ppdev, pCmd);
    789 
    790     vboxVHWACommandCheckHostCmds(ppdev);
    791 
    792     return rc;
    793 }
    794 
    795 void vboxVHWAInit(PPDEV ppdev)
    796 {
    797     VHWAQUERYINFO info;
    798     DWORD returnedDataLength;
    799     DWORD err;
    800 
    801     memset(&info, 0, sizeof (info));
    802 
    803     err = EngDeviceIoControl(ppdev->hDriver,
    804             IOCTL_VIDEO_VHWA_QUERY_INFO,
    805             NULL,
    806             0,
    807             &info,
    808             sizeof(info),
    809             &returnedDataLength);
    810     Assert(!err);
    811     if(!err)
    812     {
    813         ppdev->vhwaInfo.offVramBase = info.offVramBase;
    814         ppdev->vhwaInfo.bVHWAInited = TRUE;
    815     }
    816     else
    817         ppdev->vhwaInfo.bVHWAInited = FALSE;
    818 }
    819 
    820 #endif
    821 
    822 void vboxVBVAHostCommandComplete(PPDEV ppdev, VBVAHOSTCMD * pCmd)
    823 {
    824     ppdev->pfnHGSMICommandComplete(ppdev->hMpHGSMI, pCmd);
    825 }
    826 
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