VirtualBox

Changeset 49420 in vbox for trunk/src/VBox/Devices/Graphics


Ignore:
Timestamp:
Nov 8, 2013 3:54:02 PM (11 years ago)
Author:
vboxsync
Message:

forward-port and adopt VHWA fixes

Location:
trunk/src/VBox/Devices/Graphics
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r48468 r49420  
    49654965    if (pThis->cMilliesRefreshInterval)
    49664966        TMTimerSetMillies(pTimer, pThis->cMilliesRefreshInterval);
     4967
     4968#ifdef VBOX_WITH_VIDEOHWACCEL
     4969    vbvaTimerCb(pThis);
     4970#endif
     4971
    49674972}
    49684973
  • trunk/src/VBox/Devices/Graphics/DevVGA.h

    r45808 r49420  
    6464#endif /* VBOX_WITH_HGSMI */
    6565#include "DevVGASavedState.h"
     66
     67# include <iprt/list.h>
    6668
    6769#define MSR_COLOR_EMULATION 0x01
     
    196198#endif
    197199
     200#ifdef VBOX_WITH_VIDEOHWACCEL
     201#define VBOX_VHWA_MAX_PENDING_COMMANDS 1000
     202
     203typedef struct _VBOX_VHWA_PENDINGCMD
     204{
     205    RTLISTNODE Node;
     206    PVBOXVHWACMD pCommand;
     207} VBOX_VHWA_PENDINGCMD;
     208#endif
     209
    198210typedef struct VGAState {
    199211#ifndef VBOX
     
    420432#  endif
    421433# endif /* VBOX_WITH_HGSMI */
     434
     435    struct {
     436        uint32_t cPending;
     437        uint32_t Padding1;
     438        union
     439        {
     440            RTLISTNODE PendingList;
     441            /* make sure the structure sized cross different contexts correctly */
     442            struct
     443            {
     444                R3PTRTYPE(void *) dummy1;
     445                R3PTRTYPE(void *) dummy2;
     446            } dummy;
     447        };
     448    } pendingVhwaCommands;
    422449#endif /* VBOX */
    423450} VGAState;
     
    496523int vbvaVHWAReset (PVGASTATE pVGAState);
    497524
     525void vbvaTimerCb(PVGASTATE pVGAState);
     526
    498527int vboxVBVASaveStatePrep (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
    499528int vboxVBVASaveStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r49366 r49420  
    767767static VBOXVHWACMD* vbvaVHWAHHCommandCreate (PVGASTATE pVGAState, VBOXVHWACMD_TYPE enmCmd, int32_t iDisplay, VBOXVHWACMD_LENGTH cbCmd)
    768768{
    769     VBOXVHWACMD* pHdr = (VBOXVHWACMD*)RTMemAlloc(cbCmd + VBOXVHWACMD_HEADSIZE());
     769    VBOXVHWACMD* pHdr = (VBOXVHWACMD*)RTMemAllocZ(cbCmd + VBOXVHWACMD_HEADSIZE());
    770770    Assert(pHdr);
    771771    if (pHdr)
     
    789789}
    790790
    791 static unsigned vbvaVHWAHandleCommand (PVGASTATE pVGAState, VBVACONTEXT *pCtx, PVBOXVHWACMD pCmd)
    792 {
     791static void vbvaVHWACommandComplete(PVGASTATE pVGAState, PVBOXVHWACMD pCommand, bool fAsyncCommand)
     792{
     793    if (fAsyncCommand)
     794    {
     795        Assert(pCommand->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH);
     796        vbvaVHWACommandCompleteAsynch(&pVGAState->IVBVACallbacks, pCommand);
     797    }
     798    else
     799    {
     800        Log(("VGA Command <<< Sync rc %d %#p, %d\n", pCommand->rc, pCommand, pCommand->enmCmd));
     801        pCommand->Flags &= (~VBOXVHWACMD_FLAG_HG_ASYNCH);
     802    }
     803
     804}
     805
     806static void vbvaVHWACommandCompleteAllPending(PVGASTATE pVGAState, int rc)
     807{
     808    if (!pVGAState->pendingVhwaCommands.cPending)
     809        return;
     810
     811    VBOX_VHWA_PENDINGCMD *pIter, *pNext;
     812    RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
     813    {
     814        pIter->pCommand->rc = rc;
     815        vbvaVHWACommandComplete(pVGAState, pIter->pCommand, true);
     816
     817        /* the command is submitted/processed, remove from the pend list */
     818        RTListNodeRemove(&pIter->Node);
     819        --pVGAState->pendingVhwaCommands.cPending;
     820        RTMemFree(pIter);
     821    }
     822}
     823
     824static void vbvaVHWACommandCClearAllPending(PVGASTATE pVGAState)
     825{
     826    if (!pVGAState->pendingVhwaCommands.cPending)
     827        return;
     828
     829    VBOX_VHWA_PENDINGCMD *pIter, *pNext;
     830    RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
     831    {
     832        RTListNodeRemove(&pIter->Node);
     833        --pVGAState->pendingVhwaCommands.cPending;
     834        RTMemFree(pIter);
     835    }
     836}
     837
     838static void vbvaVHWACommandPend(PVGASTATE pVGAState, PVBOXVHWACMD pCommand)
     839{
     840    int rc = VERR_BUFFER_OVERFLOW;
     841
     842    if (pVGAState->pendingVhwaCommands.cPending < VBOX_VHWA_MAX_PENDING_COMMANDS)
     843    {
     844        VBOX_VHWA_PENDINGCMD *pPend = (VBOX_VHWA_PENDINGCMD*)RTMemAlloc(sizeof (*pPend));
     845        if (pPend)
     846        {
     847            pCommand->Flags |= VBOXVHWACMD_FLAG_HG_ASYNCH;
     848            pPend->pCommand = pCommand;
     849            RTListAppend(&pVGAState->pendingVhwaCommands.PendingList, &pPend->Node);
     850            ++pVGAState->pendingVhwaCommands.cPending;
     851            return;
     852        }
     853        else
     854            rc = VERR_NO_MEMORY;
     855    }
     856    else
     857    {
     858        LogRel(("Pending command count has reached its threshold, completing them all.."));
     859    }
     860
     861    vbvaVHWACommandCompleteAllPending(pVGAState, rc);
     862
     863    pCommand->rc = rc;
     864
     865    vbvaVHWACommandComplete(pVGAState, pCommand, false);
     866}
     867
     868static bool vbvaVHWACommandCanPend(PVBOXVHWACMD pCommand)
     869{
     870    switch (pCommand->enmCmd)
     871    {
     872        case VBOXVHWACMD_TYPE_HH_CONSTRUCT:
     873        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEBEGIN:
     874        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND:
     875        case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEPERFORM:
     876        case VBOXVHWACMD_TYPE_HH_SAVESTATE_LOADPERFORM:
     877            return false;
     878        default:
     879            return true;
     880    }
     881}
     882
     883static int vbvaVHWACommandSavePending(PVGASTATE pVGAState, PSSMHANDLE pSSM)
     884{
     885    int rc = SSMR3PutU32(pSSM, pVGAState->pendingVhwaCommands.cPending);
     886    AssertRCReturn(rc, rc);
     887    VBOX_VHWA_PENDINGCMD *pIter;
     888    RTListForEach(&pVGAState->pendingVhwaCommands.PendingList, pIter, VBOX_VHWA_PENDINGCMD, Node)
     889    {
     890        rc = SSMR3PutU32(pSSM, (uint32_t)(((uint8_t*)pIter->pCommand) - ((uint8_t*)pVGAState->vram_ptrR3)));
     891        AssertRCReturn(rc, rc);
     892    }
     893    return rc;
     894}
     895
     896static int vbvaVHWACommandLoadPending(PVGASTATE pVGAState, PSSMHANDLE pSSM, uint32_t u32Version)
     897{
     898    if (u32Version < VGA_SAVEDSTATE_VERSION_WITH_PENDVHWA)
     899        return VINF_SUCCESS;
     900
     901    int rc;
     902    uint32_t u32;
     903    rc = SSMR3GetU32(pSSM, &u32);
     904    AssertRCReturn(rc, rc);
     905    for (uint32_t i = 0; i < u32; ++i)
     906    {
     907        uint32_t off32;
     908        rc = SSMR3GetU32(pSSM, &off32);
     909        AssertRCReturn(rc, rc);
     910        PVBOXVHWACMD pCommand = (PVBOXVHWACMD)(((uint8_t*)pVGAState->vram_ptrR3) + off32);
     911        vbvaVHWACommandPend(pVGAState, pCommand);
     912    }
     913    return rc;
     914}
     915
     916
     917static bool vbvaVHWACommandSubmit(PVGASTATE pVGAState, PVBOXVHWACMD pCommand, bool fAsyncCommand)
     918{
     919    unsigned id = (unsigned)pCommand->iDisplay;
     920    int rc = VINF_SUCCESS;
     921    bool fPend = false;
     922
    793923    if (pVGAState->pDrv->pfnVHWACommandProcess)
    794         pVGAState->pDrv->pfnVHWACommandProcess(pVGAState->pDrv, pCmd);
    795 #ifdef DEBUG_misha
     924    {
     925        Log(("VGA Command >>> %#p, %d\n", pCommand, pCommand->enmCmd));
     926        int rc = pVGAState->pDrv->pfnVHWACommandProcess(pVGAState->pDrv, pCommand);
     927        if (rc == VINF_CALLBACK_RETURN)
     928        {
     929            Log(("VGA Command --- Going Async %#p, %d\n", pCommand, pCommand->enmCmd));
     930            return true; /* command will be completed asynchronously, return right away */
     931        }
     932        else if (rc == VERR_INVALID_STATE)
     933        {
     934            Log(("VGA Command --- Trying Pend %#p, %d\n", pCommand, pCommand->enmCmd));
     935            fPend = vbvaVHWACommandCanPend(pCommand);
     936            if (!fPend)
     937            {
     938                Log(("VGA Command --- Can NOT Pend %#p, %d\n", pCommand, pCommand->enmCmd));
     939                pCommand->rc = rc;
     940            }
     941            else
     942                Log(("VGA Command --- Can Pend %#p, %d\n", pCommand, pCommand->enmCmd));
     943        }
     944        else
     945        {
     946            Log(("VGA Command --- Going Complete Sync rc %d %#p, %d\n", rc, pCommand, pCommand->enmCmd));
     947            pCommand->rc = rc;
     948        }
     949
     950        /* the command was completed, take a special care about it (seee below) */
     951    }
    796952    else
     953    {
    797954        AssertFailed();
    798 #endif
    799     return 0;
     955        pCommand->rc = VERR_INVALID_STATE;
     956    }
     957
     958    if (fPend)
     959        return false;
     960
     961    vbvaVHWACommandComplete(pVGAState, pCommand, fAsyncCommand);
     962
     963    return true;
     964}
     965
     966static bool vbvaVHWACheckPendingCommands(PVGASTATE pVGAState)
     967{
     968    if (!pVGAState->pendingVhwaCommands.cPending)
     969        return true;
     970
     971    VBOX_VHWA_PENDINGCMD *pIter, *pNext;
     972    RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
     973    {
     974        if (!vbvaVHWACommandSubmit(pVGAState, pIter->pCommand, true))
     975            return false; /* the command should be pended still */
     976
     977        /* the command is submitted/processed, remove from the pend list */
     978        RTListNodeRemove(&pIter->Node);
     979        --pVGAState->pendingVhwaCommands.cPending;
     980        RTMemFree(pIter);
     981    }
     982
     983    return true;
     984}
     985
     986void vbvaTimerCb(PVGASTATE pVGAState)
     987{
     988    vbvaVHWACheckPendingCommands(pVGAState);
     989}
     990static void vbvaVHWAHandleCommand(PVGASTATE pVGAState, PVBOXVHWACMD pCmd)
     991{
     992    if (vbvaVHWACheckPendingCommands(pVGAState))
     993    {
     994        if (vbvaVHWACommandSubmit(pVGAState, pCmd, false))
     995            return;
     996    }
     997
     998    vbvaVHWACommandPend(pVGAState, pCmd);
    800999}
    8011000
     
    8151014        vbvaVHWAHHCommandRetain (pCmd);
    8161015        VBOXVHWA_HH_CALLBACK_SET(pCmd, vbvaVHWAHHCommandSetEventCallback, (void*)hComplEvent);
    817         vbvaVHWAHandleCommand(pVGAState, NULL, pCmd);
     1016        vbvaVHWAHandleCommand(pVGAState, pCmd);
    8181017        if((ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags)  & VBOXVHWACMD_FLAG_HG_ASYNCH) != 0)
    8191018        {
     
    8371036int vbvaVHWAConstruct (PVGASTATE pVGAState)
    8381037{
     1038    pVGAState->pendingVhwaCommands.cPending = 0;
     1039    RTListInit(&pVGAState->pendingVhwaCommands.PendingList);
    8391040    VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_CONSTRUCT, 0, sizeof(VBOXVHWACMD_HH_CONSTRUCT));
    8401041    Assert(pCmd);
     
    8901091int vbvaVHWAReset (PVGASTATE pVGAState)
    8911092{
     1093    vbvaVHWACommandCClearAllPending(pVGAState);
     1094
    8921095    /* ensure we have all pending cmds processed and h->g cmds disabled */
    8931096    VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_RESET, 0, 0);
     
    10091212{
    10101213    int rc;
     1214    Log(("VGA Command <<< Async rc %d %#p, %d\n", pCmd->rc, pCmd, pCmd->enmCmd));
     1215
    10111216    if((pCmd->Flags & VBOXVHWACMD_FLAG_HH_CMD) == 0)
    10121217    {
     
    13941599                if (RT_SUCCESS(rc))
    13951600                {
     1601                    rc = vbvaVHWACommandSavePending(pVGAState, pSSM);
     1602                    AssertRCReturn(rc, rc);
     1603
    13961604                    vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND, 0);
    13971605                    vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVASaveStateEndPreCb, NULL, &VhwaData);
     
    15881796                    vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVALoadStatePerformPreCb, vboxVBVALoadStatePerformPostCb, &VhwaData);
    15891797                    rc = VhwaData.rc;
    1590                     AssertRC(rc);
    15911798                    vbvaVHWAHHCommandRelease(pCmd);
     1799                    AssertRCReturn(rc, rc);
     1800
     1801                    rc = vbvaVHWACommandLoadPending(pVGAState, pSSM, u32Version);
     1802                    AssertRCReturn(rc, rc);
    15921803                }
    15931804                else
     
    19732184        case VBVA_VHWA_CMD:
    19742185        {
    1975             rc = vbvaVHWAHandleCommand (pVGAState, pCtx, (PVBOXVHWACMD)pvBuffer);
     2186            if (cbBuffer < sizeof (VBOXVHWACMD))
     2187            {
     2188                rc = VERR_INVALID_PARAMETER;
     2189                break;
     2190            }
     2191            vbvaVHWAHandleCommand(pVGAState, (PVBOXVHWACMD)pvBuffer);
     2192            rc = VINF_SUCCESS;
     2193            break;
    19762194        } break;
    19772195#endif
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