Changeset 34440 in vbox for trunk/src/VBox/Additions/common/VBoxVideo
- Timestamp:
- Nov 28, 2010 10:12:07 PM (14 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp
r34438 r34440 1 1 /* $Id$ */ 2 2 /** @file 3 * Display - VirtualBox Win 2000/XP guest display driver, support functions. 3 * VirtualBox Video driver, common code - VBVA initialisation and helper 4 * functions. 4 5 */ 5 6 6 7 /* 7 * Copyright (C) 2006-20 07Oracle Corporation8 * Copyright (C) 2006-2010 Oracle Corporation 8 9 * 9 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 16 17 */ 17 18 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> 22 21 #include <VBox/err.h> 23 22 #include <VBox/log.h> 24 #include <iprt/asm.h>25 #include <iprt/asm-amd64-x86.h>26 23 #include <iprt/assert.h> 27 24 25 #include <string.h> 26 28 27 /* 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. 30 30 * All graphics commands go there serialized by VBoxVBVABufferBeginUpdate. 31 31 * and vboxHwBufferEndUpdate. … … 365 365 if (!pVBVA) 366 366 { 367 return FALSE;367 return false; 368 368 } 369 369 … … 373 373 } 374 374 375 return FALSE;375 return false; 376 376 } 377 377 … … 414 414 } 415 415 } 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 > 0424 ? ppdev->lDeltaScreen425 : -ppdev->lDeltaScreen, ppdev->cxScreen,426 ppdev->cyScreen,427 (uint16_t)ppdev->ulBitCount);428 }429 430 return;431 }432 433 #ifdef VBOX_WITH_VIDEOHWACCEL434 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 else446 {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 # endif498 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 else728 {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 else817 ppdev->vhwaInfo.bVHWAInited = FALSE;818 }819 820 #endif821 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.