VirtualBox

Changeset 27339 in vbox


Ignore:
Timestamp:
Mar 12, 2010 5:44:11 PM (15 years ago)
Author:
vboxsync
Message:

wddm: basics for DMA commands support in graphics device impl

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

Legend:

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

    r26969 r27339  
    65766576#endif /* VBOX_WITH_HGSMI */
    65776577
     6578#ifdef VBOXVDMA
     6579    if(rc == VINF_SUCCESS)
     6580    {
     6581        /* @todo: perhaps this should be done from some guest->host callback,
     6582        * that would as well specify the cmd pool size */
     6583        rc = vboxVDMAConstruct(pThis, &pThis->pVdma, 1024);
     6584        AssertRC(rc);
     6585    }
     6586#endif
    65786587    /*
    65796588     * Statistics.
  • trunk/src/VBox/Devices/Graphics/DevVGA.h

    r26969 r27339  
    492492
    493493# ifdef VBOXVDMA
    494 int vboxVDMAConstruct(PVGASTATE pVGAState, struct VBOXVDMAHOST *pVdma);
    495 int vboxVDMADestruct(PVGASTATE pVGAState, struct VBOXVDMAHOST *pVdma);
    496 void vboxVDMAControl(PVGASTATE pVGAState, struct VBOXVDMAHOST *pVdma, PVBOXVDMA_CTL pCmd);
    497 void vboxVDMACommand(PVGASTATE pVGAState, struct VBOXVDMAHOST *pVdma, PVBOXVDMACBUF_DR pCmd);
     494typedef struct VBOXVDMAHOST *PVBOXVDMAHOST;
     495int vboxVDMAConstruct(PVGASTATE pVGAState, struct VBOXVDMAHOST **ppVdma, uint32_t cPipeElements);
     496int vboxVDMADestruct(PVBOXVDMAHOST pVdma);
     497void vboxVDMAControl(PVBOXVDMAHOST pVdma, PVBOXVDMA_CTL pCmd);
     498void vboxVDMACommand(PVBOXVDMAHOST pVdma, PVBOXVDMACBUF_DR pCmd);
    498499# endif /* VBOXVDMA */
    499500
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r26969 r27339  
    12991299        {
    13001300            PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)VBoxSHGSMIBufferData ((PVBOXSHGSMIHEADER)pvBuffer);
    1301             vboxVDMACommand(pVGAState, pVGAState->pVdma, pCmd);
     1301            vboxVDMACommand(pVGAState->pVdma, pCmd);
    13021302            rc = VINF_SUCCESS;
    13031303            break;
     
    13061306        {
    13071307            PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMIBufferData ((PVBOXSHGSMIHEADER)pvBuffer);
    1308             vboxVDMAControl(pVGAState, pVGAState->pVdma, pCmd);
     1308            vboxVDMAControl(pVGAState->pVdma, pCmd);
    13091309            rc = VINF_SUCCESS;
    13101310            break;
  • trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp

    r26969 r27339  
    2121#include <VBox/pdmdev.h>
    2222#include <VBox/VBoxVideo.h>
     23#include <iprt/semaphore.h>
     24#include <iprt/thread.h>
     25#include <iprt/mem.h>
    2326
    2427#include "DevVGA.h"
     
    2629#include "HGSMI/HGSMIHostHlp.h"
    2730
     31typedef enum
     32{
     33    VBOXVDMAPIPE_STATE_CLOSED    = 0,
     34    VBOXVDMAPIPE_STATE_CREATED   = 1,
     35    VBOXVDMAPIPE_STATE_OPENNED   = 2,
     36    VBOXVDMAPIPE_STATE_CLOSING   = 3
     37} VBOXVDMAPIPE_STATE;
     38
    2839typedef struct VBOXVDMAPIPE
    2940{
    30     HGSMILIST List;
    31 
    3241    RTSEMEVENT hEvent;
    3342    /* critical section for accessing pipe properties */
    3443    RTCRITSECT hCritSect;
     44    VBOXVDMAPIPE_STATE enmState;
    3545    /* true iff the other end needs Event notification */
    3646    bool bNeedNotify;
    3747} VBOXVDMAPIPE, *PVBOXVDMAPIPE;
    3848
     49typedef enum
     50{
     51    VBOXVDMAPIPE_CMD_TYPE_UNDEFINED = 0,
     52    VBOXVDMAPIPE_CMD_TYPE_DMACMD    = 1,
     53    VBOXVDMAPIPE_CMD_TYPE_DMACTL    = 2
     54} VBOXVDMAPIPE_CMD_TYPE;
     55
     56typedef struct VBOXVDMAPIPE_CMD_BODY
     57{
     58    VBOXVDMAPIPE_CMD_TYPE enmType;
     59    union
     60    {
     61        PVBOXVDMACBUF_DR pDr;
     62        PVBOXVDMA_CTL    pCtl;
     63        void            *pvCmd;
     64    } u;
     65}VBOXVDMAPIPE_CMD_BODY, *PVBOXVDMAPIPE_CMD_BODY;
     66
     67typedef struct VBOXVDMAPIPE_CMD
     68{
     69    HGSMILISTENTRY Entry;
     70    VBOXVDMAPIPE_CMD_BODY Cmd;
     71} VBOXVDMAPIPE_CMD, *PVBOXVDMAPIPE_CMD;
     72
     73#define VBOXVDMAPIPE_CMD_FROM_ENTRY(_pE)  ( (PVBOXVDMAPIPE_CMD)((uint8_t *)(_pE) - RT_OFFSETOF(VBOXVDMAPIPE_CMD, Entry)) )
     74
     75typedef struct VBOXVDMAPIPE_CMD_POOL
     76{
     77    HGSMILIST List;
     78    uint32_t cCmds;
     79    VBOXVDMAPIPE_CMD aCmds[1];
     80} VBOXVDMAPIPE_CMD_POOL, *PVBOXVDMAPIPE_CMD_POOL;
     81
    3982typedef struct VBOXVDMAHOST
    4083{
    4184    VBOXVDMAPIPE Pipe;
     85    HGSMILIST PendingList;
    4286    RTTHREAD hWorkerThread;
     87    PHGSMIINSTANCE pHgsmi;
     88    VBOXVDMAPIPE_CMD_POOL CmdPool;
    4389} VBOXVDMAHOST, *PVBOXVDMAHOST;
    4490
    45 int vboxVDMAConstruct(PVGASTATE pVGAState, struct VBOXVDMAHOST **ppVdma)
    46 {
     91int vboxVDMAPipeConstruct(PVBOXVDMAPIPE pPipe)
     92{
     93    int rc = RTSemEventCreate(&pPipe->hEvent);
     94    AssertRC(rc);
     95    if (RT_SUCCESS(rc))
     96    {
     97        rc = RTCritSectInit(&pPipe->hCritSect);
     98        AssertRC(rc);
     99        if (RT_SUCCESS(rc))
     100        {
     101            pPipe->enmState = VBOXVDMAPIPE_STATE_CREATED;
     102            pPipe->bNeedNotify = true;
     103            return VINF_SUCCESS;
     104//            RTCritSectDelete(pPipe->hCritSect);
     105        }
     106        RTSemEventDestroy(pPipe->hEvent);
     107    }
     108    return rc;
     109}
     110
     111int vboxVDMAPipeOpenServer(PVBOXVDMAPIPE pPipe)
     112{
     113    int rc = RTCritSectEnter(&pPipe->hCritSect);
     114    AssertRC(rc);
     115    if (RT_SUCCESS(rc))
     116    {
     117        Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED);
     118        switch (pPipe->enmState)
     119        {
     120            case VBOXVDMAPIPE_STATE_CREATED:
     121                pPipe->enmState = VBOXVDMAPIPE_STATE_OPENNED;
     122                pPipe->bNeedNotify = false;
     123                rc = VINF_SUCCESS;
     124                break;
     125            case VBOXVDMAPIPE_STATE_OPENNED:
     126                pPipe->bNeedNotify = false;
     127                rc = VINF_ALREADY_INITIALIZED;
     128                break;
     129            default:
     130                AssertBreakpoint();
     131                rc = VERR_INVALID_STATE;
     132                break;
     133        }
     134
     135        RTCritSectLeave(&pPipe->hCritSect);
     136    }
     137    return rc;
     138}
     139
     140int vboxVDMAPipeCloseServer(PVBOXVDMAPIPE pPipe)
     141{
     142    int rc = RTCritSectEnter(&pPipe->hCritSect);
     143    AssertRC(rc);
     144    if (RT_SUCCESS(rc))
     145    {
     146        Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED
     147                || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING);
     148        switch (pPipe->enmState)
     149        {
     150            case VBOXVDMAPIPE_STATE_CLOSING:
     151                pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED;
     152                rc = VINF_SUCCESS;
     153                break;
     154            case VBOXVDMAPIPE_STATE_CLOSED:
     155                rc = VINF_ALREADY_INITIALIZED;
     156                break;
     157            default:
     158                AssertBreakpoint();
     159                rc = VERR_INVALID_STATE;
     160                break;
     161        }
     162
     163        RTCritSectLeave(&pPipe->hCritSect);
     164    }
     165    return rc;
     166}
     167
     168int vboxVDMAPipeCloseClient(PVBOXVDMAPIPE pPipe)
     169{
     170    int rc = RTCritSectEnter(&pPipe->hCritSect);
     171    AssertRC(rc);
     172    if (RT_SUCCESS(rc))
     173    {
     174        bool bNeedNotify = false;
     175        Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED
     176                || pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED
     177                ||  pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED);
     178        switch (pPipe->enmState)
     179        {
     180            case VBOXVDMAPIPE_STATE_OPENNED:
     181                pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSING;
     182                bNeedNotify = pPipe->bNeedNotify;
     183                pPipe->bNeedNotify = false;
     184                break;
     185            case VBOXVDMAPIPE_STATE_CREATED:
     186                pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED;
     187                pPipe->bNeedNotify = false;
     188                break;
     189            case VBOXVDMAPIPE_STATE_CLOSED:
     190                rc = VINF_ALREADY_INITIALIZED;
     191                break;
     192            default:
     193                AssertBreakpoint();
     194                rc = VERR_INVALID_STATE;
     195                break;
     196        }
     197
     198        RTCritSectLeave(&pPipe->hCritSect);
     199
     200        if (bNeedNotify)
     201        {
     202            rc = RTSemEventSignal(pPipe->hEvent);
     203            AssertRC(rc);
     204        }
     205    }
     206    return rc;
     207}
     208
     209
     210typedef DECLCALLBACK(bool) FNHVBOXVDMARWCB(PVBOXVDMAPIPE pPipe, void *pvCallback);
     211typedef FNHVBOXVDMARWCB *PFNHVBOXVDMARWCB;
     212
     213int vboxVDMAPipeModifyServer(PVBOXVDMAPIPE pPipe, PFNHVBOXVDMARWCB pfnCallback, void * pvCallback)
     214{
     215    int rc = RTCritSectEnter(&pPipe->hCritSect);
     216    AssertRC(rc);
     217    if (RT_SUCCESS(rc))
     218    {
     219        do
     220        {
     221            Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED
     222                    || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING);
     223
     224            if (pPipe->enmState >= VBOXVDMAPIPE_STATE_OPENNED)
     225            {
     226                bool bProcessing = pfnCallback(pPipe, pvCallback);
     227                pPipe->bNeedNotify = !bProcessing;
     228                if (bProcessing)
     229                {
     230                    RTCritSectLeave(&pPipe->hCritSect);
     231                    rc = VINF_SUCCESS;
     232                    break;
     233                }
     234                else if (pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING)
     235                {
     236                    pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED;
     237                    RTCritSectLeave(&pPipe->hCritSect);
     238                    rc = VINF_EOF;
     239                    break;
     240                }
     241            }
     242            else
     243            {
     244                AssertBreakpoint();
     245                rc = VERR_INVALID_STATE;
     246                RTCritSectLeave(&pPipe->hCritSect);
     247                break;
     248            }
     249
     250            RTCritSectLeave(&pPipe->hCritSect);
     251
     252            rc = RTSemEventWait(pPipe->hEvent, RT_INDEFINITE_WAIT);
     253            AssertRC(rc);
     254            if (!RT_SUCCESS(rc))
     255                break;
     256
     257            rc = RTCritSectEnter(&pPipe->hCritSect);
     258            AssertRC(rc);
     259            if (!RT_SUCCESS(rc))
     260                break;
     261        } while (1);
     262    }
     263
     264    return rc;
     265}
     266
     267int vboxVDMAPipeModifyClient(PVBOXVDMAPIPE pPipe, PFNHVBOXVDMARWCB pfnCallback, void * pvCallback)
     268{
     269    int rc = RTCritSectEnter(&pPipe->hCritSect);
     270    AssertRC(rc);
     271    if (RT_SUCCESS(rc))
     272    {
     273        bool bNeedNotify = false;
     274        Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED);
     275        if (pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED)
     276        {
     277            bool bModified = pfnCallback(pPipe, pvCallback);
     278            if (bModified)
     279            {
     280                bNeedNotify = pPipe->bNeedNotify;
     281                pPipe->bNeedNotify = false;
     282            }
     283        }
     284        else
     285            rc = VERR_INVALID_STATE;
     286
     287        RTCritSectLeave(&pPipe->hCritSect);
     288
     289        if (bNeedNotify)
     290        {
     291            rc = RTSemEventSignal(pPipe->hEvent);
     292            AssertRC(rc);
     293        }
     294    }
     295    return rc;
     296}
     297
     298int vboxVDMAPipeDestruct(PVBOXVDMAPIPE pPipe)
     299{
     300    Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED
     301            || pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED);
     302    /* ensure the pipe is closed */
     303    vboxVDMAPipeCloseClient(pPipe);
     304
     305    Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED);
     306
     307    if (pPipe->enmState != VBOXVDMAPIPE_STATE_CLOSED)
     308        return VERR_INVALID_STATE;
     309
     310    int rc = RTCritSectDelete(&pPipe->hCritSect);
     311    AssertRC(rc);
     312
     313    rc = RTSemEventDestroy(pPipe->hEvent);
     314    AssertRC(rc);
     315
    47316    return VINF_SUCCESS;
    48317}
    49318
    50 int vboxVDMADestruct(PVGASTATE pVGAState, struct VBOXVDMAHOST **pVdma)
    51 {
     319void vboxVDMACommandProcess(PVBOXVDMAHOST pVdma, PVBOXVDMACBUF_DR pCmd)
     320{
     321    PHGSMIINSTANCE pHgsmi = pVdma->pHgsmi;
     322    pCmd->rc = VINF_SUCCESS;
     323    int rc = VBoxSHGSMICommandComplete (pHgsmi, pCmd);
     324    AssertRC(rc);
     325}
     326
     327void vboxVDMAControlProcess(PVBOXVDMAHOST pVdma, PVBOXVDMA_CTL pCmd)
     328{
     329    PHGSMIINSTANCE pHgsmi = pVdma->pHgsmi;
     330    pCmd->i32Result = VINF_SUCCESS;
     331    int rc = VBoxSHGSMICommandComplete (pHgsmi, pCmd);
     332    AssertRC(rc);
     333}
     334
     335typedef struct
     336{
     337    struct VBOXVDMAHOST *pVdma;
     338    VBOXVDMAPIPE_CMD_BODY Cmd;
     339    bool bHasCmd;
     340} VBOXVDMACMD_PROCESS_CONTEXT, *PVBOXVDMACMD_PROCESS_CONTEXT;
     341
     342DECLCALLBACK(bool) vboxVDMACommandProcessCb(PVBOXVDMAPIPE pPipe, void *pvCallback)
     343{
     344    PVBOXVDMACMD_PROCESS_CONTEXT pContext = (PVBOXVDMACMD_PROCESS_CONTEXT)pvCallback;
     345    struct VBOXVDMAHOST *pVdma = pContext->pVdma;
     346    HGSMILISTENTRY *pEntry = hgsmiListRemoveHead(&pVdma->PendingList);
     347    if (pEntry)
     348    {
     349        PVBOXVDMAPIPE_CMD pPipeCmd = VBOXVDMAPIPE_CMD_FROM_ENTRY(pEntry);
     350        Assert(pPipeCmd);
     351        pContext->Cmd = pPipeCmd->Cmd;
     352        hgsmiListPrepend(&pVdma->CmdPool.List, pEntry);
     353        pContext->bHasCmd = true;
     354        return true;
     355    }
     356
     357    pContext->bHasCmd = false;
     358    return false;
     359}
     360
     361DECLCALLBACK(int) vboxVDMAWorkerThread(RTTHREAD ThreadSelf, void *pvUser)
     362{
     363    PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)pvUser;
     364    PHGSMIINSTANCE pHgsmi = pVdma->pHgsmi;
     365    VBOXVDMACMD_PROCESS_CONTEXT Context;
     366    Context.pVdma = pVdma;
     367
     368    int rc = vboxVDMAPipeOpenServer(&pVdma->Pipe);
     369    AssertRC(rc);
     370    if (RT_SUCCESS(rc))
     371    {
     372        do
     373        {
     374            rc = vboxVDMAPipeModifyServer(&pVdma->Pipe, vboxVDMACommandProcessCb, &Context);
     375            AssertRC(rc);
     376            if (RT_SUCCESS(rc))
     377            {
     378                switch (Context.Cmd.enmType)
     379                {
     380                    case VBOXVDMAPIPE_CMD_TYPE_DMACMD:
     381                    {
     382                        PVBOXVDMACBUF_DR pDr = Context.Cmd.u.pDr;
     383                        vboxVDMACommandProcess(pVdma, pDr);
     384                        break;
     385                    }
     386                    case VBOXVDMAPIPE_CMD_TYPE_DMACTL:
     387                    {
     388                        PVBOXVDMA_CTL pCtl = Context.Cmd.u.pCtl;
     389                        vboxVDMAControlProcess(pVdma, pCtl);
     390                        break;
     391                    }
     392                    default:
     393                        AssertBreakpoint();
     394                        break;
     395                }
     396
     397                if (rc == VINF_EOF)
     398                {
     399                    rc = VINF_SUCCESS;
     400                    break;
     401                }
     402            }
     403            else
     404                break;
     405        } while (1);
     406    }
     407
     408    /* always try to close the pipe to make sure the client side is notified */
     409    int tmpRc = vboxVDMAPipeCloseServer(&pVdma->Pipe);
     410    AssertRC(tmpRc);
     411    return rc;
     412}
     413
     414int vboxVDMAConstruct(PVGASTATE pVGAState, struct VBOXVDMAHOST **ppVdma, uint32_t cPipeElements)
     415{
     416    int rc;
     417    PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)RTMemAllocZ (RT_OFFSETOF(VBOXVDMAHOST, CmdPool.aCmds[cPipeElements]));
     418    Assert(pVdma);
     419    if (pVdma)
     420    {
     421        hgsmiListInit(&pVdma->PendingList);
     422        pVdma->pHgsmi = pVGAState->pHGSMI;
     423
     424        rc = vboxVDMAPipeConstruct(&pVdma->Pipe);
     425        AssertRC(rc);
     426        if (RT_SUCCESS(rc))
     427        {
     428            rc = RTThreadCreate(&pVdma->hWorkerThread, vboxVDMAWorkerThread, pVdma, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "VDMA");
     429            AssertRC(rc);
     430            if (RT_SUCCESS(rc))
     431            {
     432                hgsmiListInit(&pVdma->CmdPool.List);
     433                pVdma->CmdPool.cCmds = cPipeElements;
     434                for (uint32_t i = 0; i < cPipeElements; ++i)
     435                {
     436                    hgsmiListAppend(&pVdma->CmdPool.List, &pVdma->CmdPool.aCmds[i].Entry);
     437                }
     438                *ppVdma = pVdma;
     439                return VINF_SUCCESS;
     440            }
     441
     442            int tmpRc = vboxVDMAPipeDestruct(&pVdma->Pipe);
     443            AssertRC(tmpRc);
     444        }
     445
     446        RTMemFree(pVdma);
     447    }
     448    else
     449        rc = VERR_OUT_OF_RESOURCES;
     450
     451    return rc;
     452}
     453
     454int vboxVDMADestruct(struct VBOXVDMAHOST **pVdma)
     455{
     456    AssertBreakpoint();
    52457    return VINF_SUCCESS;
    53458}
    54459
    55 void vboxVDMAControl(PVGASTATE pVGAState, struct VBOXVDMAHOST *pVdma, PVBOXVDMA_CTL pCmd)
    56 {
    57     PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
     460typedef struct
     461{
     462    struct VBOXVDMAHOST *pVdma;
     463    VBOXVDMAPIPE_CMD_BODY Cmd;
     464    bool bQueued;
     465} VBOXVDMACMD_SUBMIT_CONTEXT, *PVBOXVDMACMD_SUBMIT_CONTEXT;
     466
     467DECLCALLBACK(bool) vboxVDMACommandSubmitCb(PVBOXVDMAPIPE pPipe, void *pvCallback)
     468{
     469    PVBOXVDMACMD_SUBMIT_CONTEXT pContext = (PVBOXVDMACMD_SUBMIT_CONTEXT)pvCallback;
     470    struct VBOXVDMAHOST *pVdma = pContext->pVdma;
     471    HGSMILISTENTRY *pEntry = hgsmiListRemoveHead(&pVdma->CmdPool.List);
     472    Assert(pEntry);
     473    if (pEntry)
     474    {
     475        PVBOXVDMAPIPE_CMD pPipeCmd = VBOXVDMAPIPE_CMD_FROM_ENTRY(pEntry);
     476        pPipeCmd->Cmd = pContext->Cmd;
     477        VBoxSHGSMICommandMarkAsynchCompletion(pContext->Cmd.u.pvCmd);
     478        pContext->bQueued = true;
     479        hgsmiListAppend(&pVdma->PendingList, pEntry);
     480        return true;
     481    }
     482
     483    /* @todo: should we try to flush some commands here? */
     484    pContext->bQueued = false;
     485    return false;
     486}
     487
     488void vboxVDMAControl(struct VBOXVDMAHOST *pVdma, PVBOXVDMA_CTL pCmd)
     489{
     490#if 0
     491    PHGSMIINSTANCE pIns = pVdma->pHgsmi;
    58492
    59493    switch (pCmd->enmCtl)
     
    73507    }
    74508
    75     int rc = VBoxSHGSMICommandCompleteSynch (pIns, pCmd);
    76     AssertRC(rc);
    77 }
    78 
    79 void vboxVDMACommand(PVGASTATE pVGAState, struct VBOXVDMAHOST *pVdma, PVBOXVDMACBUF_DR pCmd)
    80 {
    81     PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
    82     pCmd->rc = VINF_SUCCESS;
    83 
    84     /* @todo: submit command for processing thread */
    85 
    86     int rc = VBoxSHGSMICommandCompleteSynch (pIns, pCmd);
    87     AssertRC(rc);
    88 }
    89 
     509    int rc = VBoxSHGSMICommandComplete (pIns, pCmd);
     510    AssertRC(rc);
     511#else
     512    /* test asinch completion */
     513    VBOXVDMACMD_SUBMIT_CONTEXT Context;
     514    Context.pVdma = pVdma;
     515    Context.Cmd.enmType = VBOXVDMAPIPE_CMD_TYPE_DMACTL;
     516    Context.Cmd.u.pCtl = pCmd;
     517
     518    int rc = vboxVDMAPipeModifyClient(&pVdma->Pipe, vboxVDMACommandSubmitCb, &Context);
     519    AssertRC(rc);
     520    if (RT_SUCCESS(rc))
     521    {
     522        Assert(Context.bQueued);
     523        if (Context.bQueued)
     524        {
     525            /* success */
     526            return;
     527        }
     528        rc = VERR_OUT_OF_RESOURCES;
     529    }
     530
     531    /* failure */
     532    Assert(RT_FAILURE(rc));
     533    PHGSMIINSTANCE pIns = pVdma->pHgsmi;
     534    pCmd->i32Result = rc;
     535    int tmpRc = VBoxSHGSMICommandComplete (pIns, pCmd);
     536    AssertRC(tmpRc);
     537
     538#endif
     539}
     540
     541void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, PVBOXVDMACBUF_DR pCmd)
     542{
     543    VBOXVDMACMD_SUBMIT_CONTEXT Context;
     544    Context.pVdma = pVdma;
     545    Context.Cmd.enmType = VBOXVDMAPIPE_CMD_TYPE_DMACMD;
     546    Context.Cmd.u.pDr = pCmd;
     547
     548    int rc = vboxVDMAPipeModifyClient(&pVdma->Pipe, vboxVDMACommandSubmitCb, &Context);
     549    AssertRC(rc);
     550    if (RT_SUCCESS(rc))
     551    {
     552        Assert(Context.bQueued);
     553        if (Context.bQueued)
     554        {
     555            /* success */
     556            return;
     557        }
     558        rc = VERR_OUT_OF_RESOURCES;
     559    }
     560
     561    /* failure */
     562    Assert(RT_FAILURE(rc));
     563    PHGSMIINSTANCE pIns = pVdma->pHgsmi;
     564    pCmd->rc = rc;
     565    int tmpRc = VBoxSHGSMICommandComplete (pIns, pCmd);
     566    AssertRC(tmpRc);
     567}
     568
  • trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHostHlp.h

    r26969 r27339  
    4040
    4141void hgsmiListAppend (HGSMILIST *pList, HGSMILISTENTRY *pEntry);
     42DECLINLINE(void) hgsmiListPrepend (HGSMILIST *pList, HGSMILISTENTRY *pEntry)
     43{
     44    HGSMILISTENTRY * pHead = pList->pHead;
     45    pList->pHead = pEntry;
     46    pEntry->pNext = pHead;
     47    if (!pHead)
     48        pList->pTail = pEntry;
     49}
     50
    4251void hgsmiListRemove (HGSMILIST *pList, HGSMILISTENTRY *pEntry, HGSMILISTENTRY *pPrev);
    4352
     
    6372HGSMILISTENTRY * hgsmiListRemoveAll (HGSMILIST *pList, HGSMILISTENTRY ** ppTail /* optional */);
    6473
     74DECLINLINE(void) hgsmiListAppendAll (HGSMILIST *pList, HGSMILISTENTRY *pHead, HGSMILISTENTRY *pTail)
     75{
     76    if(hgsmiListIsEmpty (pList))
     77    {
     78        pList->pHead = pHead;
     79        pList->pTail = pTail;
     80    }
     81    else
     82    {
     83        pList->pTail->pNext = pHead;
     84        pList->pTail = pTail;
     85    }
     86}
     87
     88DECLINLINE(void) hgsmiListPrependAll (HGSMILIST *pList, HGSMILISTENTRY *pHead, HGSMILISTENTRY *pTail)
     89{
     90    HGSMILISTENTRY *pOldHead = pList->pHead;
     91    if(!pOldHead)
     92    {
     93        pList->pHead = pHead;
     94        pList->pTail = pTail;
     95    }
     96    else
     97    {
     98        pList->pHead = pHead;
     99        pTail->pNext = pOldHead;
     100    }
     101}
     102
     103DECLINLINE(void) hgsmiListCat (HGSMILIST *pList, HGSMILIST *pList2)
     104{
     105    hgsmiListAppendAll (pList, pList2->pHead, pList2->pTail);
     106    hgsmiListInit (pList2);
     107}
     108
     109DECLINLINE(void) hgsmiListPrepCat (HGSMILIST *pList, HGSMILIST *pList2)
     110{
     111    hgsmiListPrependAll (pList, pList2->pHead, pList2->pTail);
     112    hgsmiListInit (pList2);
     113}
     114
    65115
    66116#endif /* !__HGSMIHostHlp_h__*/
  • trunk/src/VBox/Devices/Graphics/HGSMI/SHGSMIHost.cpp

    r26969 r27339  
    4040}
    4141
    42 int VBoxSHGSMICommandCompleteAsynch (PHGSMIINSTANCE pIns, void *pvData)
     42int VBoxSHGSMICommandComplete (PHGSMIINSTANCE pIns, void *pvData)
    4343{
    4444    PVBOXSHGSMIHEADER pHdr = VBoxSHGSMIBufferHeader (pvData);
    45     Assert(!!(pHdr->fFlags & VBOXSHGSMI_FLAG_HG_ASYNCH));
    46     return vboxSHGSMICommandCompleteAsynch (pIns, pHdr);
    47 }
    48 
    49 int VBoxSHGSMICommandCompleteSynch (PHGSMIINSTANCE pIns, void *pvData)
    50 {
    51     PVBOXSHGSMIHEADER pHdr = VBoxSHGSMIBufferHeader (pvData);
    52     Assert(!(pHdr->fFlags & VBOXSHGSMI_FLAG_HG_ASYNCH));
    53     if (vboxSHGSMICommandCanCompleteSynch(pHdr))
     45    if (!(pHdr->fFlags & VBOXSHGSMI_FLAG_HG_ASYNCH) /* <- check if synchronous completion */
     46            && vboxSHGSMICommandCanCompleteSynch(pHdr)) /* <- check if can complete synchronously */
    5447        return VINF_SUCCESS;
    5548    pHdr->fFlags |= VBOXSHGSMI_FLAG_HG_ASYNCH;
  • trunk/src/VBox/Devices/Graphics/HGSMI/SHGSMIHost.h

    r26969 r27339  
    1919#include "HGSMIHost.h"
    2020
    21 int VBoxSHGSMICommandCompleteAsynch (PHGSMIINSTANCE pIns, void *pvData);
     21int VBoxSHGSMICommandComplete (PHGSMIINSTANCE pIns, void *pvData);
    2222
    2323void VBoxSHGSMICommandMarkAsynchCompletion (void *pvData);
    2424
    25 int VBoxSHGSMICommandCompleteSynch (PHGSMIINSTANCE pIns, void *pvData);
    26 
    2725#endif /* #ifndef ___SHGSMIHost_h___ */
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