VirtualBox

Changeset 49591 in vbox


Ignore:
Timestamp:
Nov 20, 2013 5:53:55 PM (11 years ago)
Author:
vboxsync
Message:

wddm: more on new comand mechanism, guest side almost done, some cleanup

Location:
trunk
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxVideo.h

    r49507 r49591  
    15691569/* CrHgsmi command */
    15701570#define VBOXCMDVBVA_OPTYPE_CRCMD                        1
    1571 /* special case for blitting to primary */
    1572 #define VBOXCMDVBVA_OPTYPE_BLT_TOPRIMARY                2
    15731571/* blit command that does blitting of allocations identified by VRAM offset or host id
    15741572 * for VRAM-offset ones the size and format are same as primary */
    1575 #define VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID       3
     1573#define VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID       2
     1574/* flip */
     1575#define VBOXCMDVBVA_OPTYPE_FLIP                         3
     1576/* ColorFill */
     1577#define VBOXCMDVBVA_OPTYPE_CLRFILL                      4
    15761578/* allocation paging transfer request */
    1577 #define VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER              4
     1579#define VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER              5
    15781580/* allocation paging fill request */
    1579 #define VBOXCMDVBVA_OPTYPE_PAGING_FILL                  5
     1581#define VBOXCMDVBVA_OPTYPE_PAGING_FILL                  6
    15801582/* same as VBOXCMDVBVA_OPTYPE_NOP, but contains VBOXCMDVBVA_HDR data */
    1581 #define VBOXCMDVBVA_OPTYPE_NOPCMD                       6
     1583#define VBOXCMDVBVA_OPTYPE_NOPCMD                       7
    15821584
    15831585/* nop - is a one-bit command. The buffer size to skip is determined by VBVA buffer size */
     
    15931595#define VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN              0x20
    15941596
     1597/* VBOXCMDVBVA_OPTYPE_BLT_PRIMARY specific flags*/
     1598/* if set - src is a primary id */
     1599#define VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY               0x20
     1600/* if set - dst is a primary id */
     1601#define VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY               0x10
     1602
    15951603
    15961604/* trying to make the header as small as possible,
     
    15991607typedef struct VBOXCMDVBVA_HDR
    16001608{
    1601     /* one VBOXCMDVBVA_OPTYPE_XXX, ecxept NOP, see comments above */
     1609    /* one VBOXCMDVBVA_OPTYPE_XXX, except NOP, see comments above */
    16021610    uint8_t u8OpCode;
    16031611    /* command-specific
    1604      * VBOXCMDVBVA_OPTYPE_CRCMD - must be null
    1605      * VBOXCMDVBVA_OPTYPE_BLT_TOPRIMARY - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
    1606      * VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
    1607      * VBOXCMDVBVA_OPTYPE_NOP - must be null */
     1612     * VBOXCMDVBVA_OPTYPE_CRCMD                     - must be null
     1613     * VBOXCMDVBVA_OPTYPE_BLT_PRIMARY             - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
     1614     * VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID    - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags
     1615     * VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER           - must be null
     1616     * VBOXCMDVBVA_OPTYPE_PAGING_FILL               - must be null
     1617     * VBOXCMDVBVA_OPTYPE_NOPCMD                    - must be null
     1618     * VBOXCMDVBVA_OPTYPE_NOP                       - not applicable (as the entire VBOXCMDVBVA_HDR is not valid) */
    16081619    uint8_t u8Flags;
    16091620    /* one of VBOXCMDVBVA_STATE_XXX*/
     
    16161627    };
    16171628    /* DXGK DDI fence ID */
    1618     uint32_t u32FenceID;
     1629    volatile uint32_t u32FenceID;
    16191630} VBOXCMDVBVA_HDR;
    16201631
     
    16221633typedef uint64_t VBOXCMDVBVAPHADDR;
    16231634
     1635typedef struct VBOXCMDVBVA_CRCMD_BUFFER
     1636{
     1637    uint32_t cbBuffer;
     1638    VBOXCMDVBVAOFFSET offBuffer;
     1639} VBOXCMDVBVA_CRCMD_BUFFER;
     1640
     1641typedef struct VBOXCMDVBVA_CRCMD_CMD
     1642{
     1643    uint32_t cBuffers;
     1644    VBOXCMDVBVA_CRCMD_BUFFER aBuffers[1];
     1645} VBOXCMDVBVA_CRCMD_CMD;
     1646
    16241647typedef struct VBOXCMDVBVA_CRCMD
    16251648{
    16261649    VBOXCMDVBVA_HDR Hdr;
    1627     VBOXCMDVBVAOFFSET offCmd;
     1650    VBOXCMDVBVA_CRCMD_CMD Cmd;
    16281651} VBOXCMDVBVA_CRCMD;
    16291652
     
    16401663{
    16411664   /** Coordinates of affected rectangle. */
    1642    int16_t x;
    1643    int16_t y;
    1644    uint16_t w;
    1645    uint16_t h;
     1665   int16_t xLeft;
     1666   int16_t yTop;
     1667   int16_t xRight;
     1668   int16_t yBottom;
    16461669} VBOXCMDVBVA_RECT;
    16471670
    1648 typedef struct VBOXCMDVBVA_BLT_TOPRIMARY
     1671typedef struct VBOXCMDVBVA_BLT_PRIMARY
    16491672{
    16501673    VBOXCMDVBVA_HDR Hdr;
    1651     VBOXCMDVBVA_ALLOCINFO src;
     1674    VBOXCMDVBVA_ALLOCINFO alloc;
    16521675    /* the rects count is determined from the command size */
    16531676    VBOXCMDVBVA_RECT aRects[1];
    1654 } VBOXCMDVBVA_BLT_TOPRIMARY;
     1677} VBOXCMDVBVA_BLT_PRIMARY;
    16551678
    16561679typedef struct VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID
     
    16631686} VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID;
    16641687
     1688typedef struct VBOXCMDVBVA_FLIP
     1689{
     1690    VBOXCMDVBVA_HDR Hdr;
     1691    VBOXCMDVBVA_ALLOCINFO src;
     1692} VBOXCMDVBVA_FLIP;
     1693
     1694typedef struct VBOXCMDVBVA_CLRFILL
     1695{
     1696    VBOXCMDVBVA_HDR Hdr;
     1697    VBOXCMDVBVA_ALLOCINFO dst;
     1698    VBOXCMDVBVA_RECT aRects[1];
     1699} VBOXCMDVBVA_CLRFILL;
     1700
     1701#define VBOXCMDVBVA_SYSMEMEL_CPAGES_MAX  0x1000
     1702
     1703typedef struct VBOXCMDVBVA_SYSMEMEL
     1704{
     1705    uint32_t cPagesAfterFirst  : 12;
     1706    VBOXCMDVBVAPHADDR iPage    : 52;
     1707} VBOXCMDVBVA_SYSMEMEL;
     1708
    16651709typedef struct VBOXCMDVBVA_PAGING_TRANSFER
    16661710{
    16671711    VBOXCMDVBVA_HDR Hdr;
    1668     VBOXCMDVBVAPHADDR Addr;
    16691712    /* for now can only contain offVRAM.
    16701713     * paging transfer can NOT be initiated for allocations having host 3D object (hostID) associated */
    16711714    VBOXCMDVBVA_ALLOCINFO Alloc;
     1715    uint32_t cSysMem;
     1716    VBOXCMDVBVA_SYSMEMEL aSysMem[1];
    16721717} VBOXCMDVBVA_PAGING_TRANSFER;
    16731718
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h

    r49244 r49591  
    3535
    3636/* One would increase this whenever definitions in this file are changed */
    37 #define VBOXVIDEOIF_VERSION 19
     37#define VBOXVIDEOIF_VERSION 20
    3838
    3939#define VBOXWDDM_NODE_ID_SYSTEM           0
     
    115115        {
    116116            uint32_t cbBuffer;
    117             uint64_t hSynch;
    118117            VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType;
    119118        };
     
    183182typedef struct VBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO
    184183{
    185     uint32_t bDoNotSignalCompletion;
    186184    uint32_t offData;
    187185    uint32_t cbData;
     
    193191    VBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO aBufInfos[1];
    194192} VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, *PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD;
     193
    195194
    196195#define VBOXVHWA_F_ENABLED  0x00000001
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp

    r44529 r49591  
    6262    if (pHgsmiGL)
    6363    {
    64 #if 0
    6564        HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
    66 #else
    67         HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
    68 #endif
    6965        Log(("CrHgsmi: faled to create KmtEsc VBOXUHGSMI instance, hr (0x%x)\n", hr));
    7066        if (hr == S_OK)
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp

    r45403 r49591  
    165165        pContext->pDevice = pDevice;
    166166        if (fIsCrContext)
    167             vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice);
     167        {
     168            if (pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_CMDVBVA)
     169                vboxUhgsmiD3DInit(&pDevice->Uhgsmi, pDevice);
     170            else
     171                vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice);
     172        }
    168173    }
    169174    else
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp

    r48070 r49591  
    7272        bSupported &= !!(pCallbacks->pfnD3DKMTEscape);
    7373
    74         pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice");
     74        pCallbacks->pfnD3DKMTQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO)GetProcAddress(pCallbacks->hGdi32, "D3DKMTQueryAdapterInfo");
     75        Log((__FUNCTION__": pfnD3DKMTQueryAdapterInfo = %p\n", pCallbacks->pfnD3DKMTQueryAdapterInfo));
     76        bSupported &= !!(pCallbacks->pfnD3DKMTQueryAdapterInfo);
     77
     78                pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice");
    7579        Log((__FUNCTION__": pfnD3DKMTCreateDevice = %p\n", pCallbacks->pfnD3DKMTCreateDevice));
    7680        bSupported &= !!(pCallbacks->pfnD3DKMTCreateDevice);
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h

    r48070 r49591  
    7171    PFND3DKMT_ESCAPE pfnD3DKMTEscape;
    7272
     73    PFND3DKMT_QUERYADAPTERINFO pfnD3DKMTQueryAdapterInfo;
     74
    7375    PFND3DKMT_CREATEDEVICE pfnD3DKMTCreateDevice;
    7476    PFND3DKMT_DESTROYDEVICE pfnD3DKMTDestroyDevice;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp

    r49332 r49591  
    178178        PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuf = VBOXUHGSMIESCBASE_GET_BUFFER(pBufInfo->pBuf);
    179179        pSubmInfo->hAlloc = pBuf->Alloc.hAlloc;
    180         pSubmInfo->Info.bDoNotSignalCompletion = 0;
    181180        if (pBufInfo->fFlags.bEntireBuffer)
    182181        {
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h

    r49332 r49591  
    142142}
    143143
     144DECLINLINE(void) vboxUhgsmiBaseDxAllocInfoFill(D3DDDI_ALLOCATIONINFO *pDdiAllocInfo, VBOXWDDM_ALLOCINFO *pAllocInfo, uint32_t cbBuffer, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType)
     145{
     146    pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
     147    pDdiAllocInfo->PrivateDriverDataSize = sizeof (*pAllocInfo);
     148    pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
     149    pAllocInfo->cbBuffer = cbBuffer;
     150    pAllocInfo->fUhgsmiType = fUhgsmiType;
     151
     152}
     153
    144154DECLINLINE(int) vboxUhgsmiBaseDxDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers,
    145155        VOID* pCommandBuffer, UINT *pCommandBufferSize,
     
    163173    PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pHdr = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pCommandBuffer;
    164174    pHdr->Base.enmCmd = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
    165     pHdr->Base.u32CmdReserved = cBuffers;
     175    pHdr->Base.u32CmdReserved = 0;
    166176
    167177    PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pBufSubmInfo = pHdr->aBufInfos;
     
    177187        pAllocationList->WriteOperation = !pBufInfo->fFlags.bHostReadOnly;
    178188        pAllocationList->DoNotRetireInstance = pBufInfo->fFlags.bDoNotRetire;
    179         pBufSubmInfo->bDoNotSignalCompletion = 0;
    180189        if (pBufInfo->fFlags.bEntireBuffer)
    181190        {
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp

    r49332 r49591  
    118118        DdiAlloc.NumAllocations = 1;
    119119        DdiAlloc.pAllocationInfo = &DdiAllocInfo;
    120         DdiAllocInfo.pPrivateDriverData = &AllocInfo;
    121         DdiAllocInfo.PrivateDriverDataSize = sizeof (AllocInfo);
    122         AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
    123         AllocInfo.cbBuffer = cbBuf;
    124         AllocInfo.hSynch = 0;
    125         AllocInfo.fUhgsmiType = fType;
     120        vboxUhgsmiBaseDxAllocInfoFill(&DdiAllocInfo, &AllocInfo, cbBuf, fType);
    126121
    127122        HRESULT hr = pPrivate->pDevice->RtCallbacks.pfnAllocateCb(pPrivate->pDevice->hDevice, &DdiAlloc);
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp

    r49332 r49591  
    2828#endif
    2929
    30 #if 0
    31 typedef struct VBOXUHGSMI_BUFFER_PRIVATE_KMT
    32 {
    33     VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate;
    34     CRITICAL_SECTION CritSect;
    35 } VBOXUHGSMI_BUFFER_PRIVATE_KMT, *PVBOXUHGSMI_BUFFER_PRIVATE_KMT;
    36 
    37 
    38 #define VBOXUHGSMIKMT_GET_BUFFER(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_KMT)
    3930
    4031DECLCALLBACK(int) vboxUhgsmiKmtBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
    4132{
    42     PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
     33    PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
     34    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
     35
    4336    D3DKMT_DESTROYALLOCATION DdiDealloc;
    44     DdiDealloc.hDevice = pBuffer->pHgsmi->Device.hDevice;
     37    DdiDealloc.hDevice = pPrivate->Device.hDevice;
    4538    DdiDealloc.hResource = NULL;
    46     DdiDealloc.phAllocationList = &pBuffer->BasePrivate.hAllocation;
     39    DdiDealloc.phAllocationList = &pBuffer->hAllocation;
    4740    DdiDealloc.AllocationCount = 1;
    48     NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTDestroyAllocation(&DdiDealloc);
    49     if (NT_SUCCESS(Status))
    50     {
    51         if (pBuffer->BasePrivate.hSynch)
    52             CloseHandle(pBuffer->BasePrivate.hSynch);
     41    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTDestroyAllocation(&DdiDealloc);
     42    if (NT_SUCCESS(Status))
     43    {
    5344        RTMemFree(pBuffer);
    5445        return VINF_SUCCESS;
     
    6354DECLCALLBACK(int) vboxUhgsmiKmtBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock)
    6455{
    65     PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
     56    PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
     57    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
    6658    D3DKMT_LOCK DdiLock = {0};
    67     DdiLock.hDevice = pBuffer->pHgsmi->Device.hDevice;
    68     DdiLock.hAllocation = pBuffer->BasePrivate.hAllocation;
     59    DdiLock.hDevice = pPrivate->Device.hDevice;
     60    DdiLock.hAllocation = pBuffer->hAllocation;
    6961    DdiLock.PrivateDriverData = NULL;
    7062
    71     EnterCriticalSection(&pBuffer->CritSect);
    72 
    73     int rc = vboxUhgsmiBaseDxLockData(&pBuffer->BasePrivate, offLock, cbLock, fFlags,
     63    int rc = vboxUhgsmiBaseDxLockData(pBuffer, offLock, cbLock, fFlags,
    7464                                         &DdiLock.Flags, &DdiLock.NumPages);
    75     AssertRC(rc);
    76     if (RT_FAILURE(rc))
     65    if (!RT_SUCCESS(rc))
     66    {
     67        WARN(("vboxUhgsmiBaseDxLockData failed rc %d", rc));
    7768        return rc;
     69    }
     70
    7871
    7972    if (DdiLock.NumPages)
     
    8275        DdiLock.pPages = NULL;
    8376
    84     NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTLock(&DdiLock);
    85     LeaveCriticalSection(&pBuffer->CritSect);
     77    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTLock(&DdiLock);
    8678    if (NT_SUCCESS(Status))
    8779    {
     
    9991DECLCALLBACK(int) vboxUhgsmiKmtBufferUnlock(PVBOXUHGSMI_BUFFER pBuf)
    10092{
    101     PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
     93    PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
    10294    D3DKMT_UNLOCK DdiUnlock;
    10395
    104     DdiUnlock.hDevice = pBuffer->pHgsmi->Device.hDevice;
     96    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
     97    DdiUnlock.hDevice = pPrivate->Device.hDevice;
    10598    DdiUnlock.NumAllocations = 1;
    106     DdiUnlock.phAllocations = &pBuffer->BasePrivate.hAllocation;
    107     NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTUnlock(&DdiUnlock);
     99    DdiUnlock.phAllocations = &pBuffer->hAllocation;
     100    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTUnlock(&DdiUnlock);
    108101    if (NT_SUCCESS(Status))
    109102        return VINF_SUCCESS;
     
    114107}
    115108
    116 DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf)
    117 {
    118     HANDLE hSynch = NULL;
     109DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf)
     110{
    119111    if (!cbBuf)
    120112        return VERR_INVALID_PARAMETER;
    121113
    122     int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch);
    123     AssertRC(rc);
    124     if (RT_FAILURE(rc))
    125         return rc;
     114    int rc = VINF_SUCCESS;
    126115
    127116    cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000);
     
    131120
    132121    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi);
    133     PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_KMT)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_KMT, aLockPageIndices[cPages]));
    134     Assert(pBuf);
    135     if (pBuf)
    136     {
    137         struct
    138         {
    139             D3DKMT_CREATEALLOCATION DdiAlloc;
    140             D3DDDI_ALLOCATIONINFO DdiAllocInfo;
    141             VBOXWDDM_ALLOCINFO AllocInfo;
    142         } Buf;
    143         memset(&Buf, 0, sizeof (Buf));
    144         Buf.DdiAlloc.hDevice = pPrivate->Device.hDevice;
    145         Buf.DdiAlloc.NumAllocations = 1;
    146         Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo;
    147         Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo;
    148         Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo);
    149         Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
    150         Buf.AllocInfo.cbBuffer = cbBuf;
    151         Buf.AllocInfo.hSynch = (uint64_t)hSynch;
    152         Buf.AllocInfo.fUhgsmiType = fUhgsmiType;
    153 
    154         NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&Buf.DdiAlloc);
    155         if (NT_SUCCESS(Status))
    156         {
    157             InitializeCriticalSection(&pBuf->CritSect);
    158 
    159             Assert(Buf.DdiAllocInfo.hAllocation);
    160             pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock;
    161             pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock;
    162 //            pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiKmtBufferAdjustValidDataRange;
    163             pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy;
    164 
    165             pBuf->BasePrivate.Base.fType = fUhgsmiType;
    166             pBuf->BasePrivate.Base.cbBuffer = cbBuf;
    167 
    168             pBuf->pHgsmi = pPrivate;
    169             pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation;
    170 
    171             *ppBuf = &pBuf->BasePrivate.Base;
    172 
    173             return VINF_SUCCESS;
    174         }
    175         else
    176         {
    177             WARN(("pfnD3DKMTCreateAllocation failes, Status(0x%x)", Status));
    178             rc = VERR_OUT_OF_RESOURCES;
    179         }
    180 
    181         RTMemFree(pBuf);
    182     }
    183     else
    184         rc = VERR_NO_MEMORY;
    185 
    186     if (hSynch)
    187         CloseHandle(hSynch);
     122    PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, aLockPageIndices[cPages]));
     123    if (!pBuf)
     124    {
     125        WARN(("RTMemAllocZ failed"));
     126        return VERR_NO_MEMORY;
     127    }
     128
     129    D3DKMT_CREATEALLOCATION DdiAlloc;
     130    D3DDDI_ALLOCATIONINFO DdiAllocInfo;
     131    VBOXWDDM_ALLOCINFO AllocInfo;
     132
     133    memset(&DdiAlloc, 0, sizeof (DdiAlloc));
     134    DdiAlloc.hDevice = pPrivate->Device.hDevice;
     135    DdiAlloc.NumAllocations = 1;
     136    DdiAlloc.pAllocationInfo = &DdiAllocInfo;
     137
     138    vboxUhgsmiBaseDxAllocInfoFill(&DdiAllocInfo, &AllocInfo, cbBuf, fType);
     139
     140    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&DdiAlloc);
     141    if (NT_SUCCESS(Status))
     142    {
     143        Assert(DdiAllocInfo.hAllocation);
     144        pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock;
     145        pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock;
     146        pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy;
     147
     148        pBuf->BasePrivate.Base.fType = fType;
     149        pBuf->BasePrivate.Base.cbBuffer = cbBuf;
     150
     151        pBuf->hAllocation = DdiAllocInfo.hAllocation;
     152
     153        *ppBuf = &pBuf->BasePrivate.Base;
     154
     155        return VINF_SUCCESS;
     156    }
     157    else
     158    {
     159        WARN(("pfnD3DKMTCreateAllocation failes, Status(0x%x)", Status));
     160        rc = VERR_OUT_OF_RESOURCES;
     161    }
     162
     163    RTMemFree(pBuf);
    188164
    189165    return rc;
     
    198174            pHg->Context.pAllocationList, pHg->Context.AllocationListSize,
    199175            pHg->Context.pPatchLocationList, pHg->Context.PatchLocationListSize);
    200     AssertRC(rc);
    201176    if (RT_FAILURE(rc))
     177    {
     178        WARN(("vboxUhgsmiBaseDxDmaFill failed, rc %d", rc));
    202179        return rc;
     180    }
    203181
    204182    D3DKMT_RENDER DdiRender = {0};
     
    228206    return VERR_GENERAL_FAILURE;
    229207}
    230 #endif
     208
    231209
    232210static HRESULT vboxUhgsmiKmtEngineCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
     
    297275}
    298276
     277static void vboxUhgsmiKmtSetupCallbacks(PVBOXUHGSMI_PRIVATE_KMT pHgsmi)
     278{
     279    pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiKmtBufferCreate;
     280    pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiKmtBufferSubmit;
     281     /* no escapes (for now) */
     282    pHgsmi->BasePrivate.pfnEscape = NULL;
     283}
     284
     285static void vboxUhgsmiKmtEscSetupCallbacks(PVBOXUHGSMI_PRIVATE_KMT pHgsmi)
     286{
     287    vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
     288}
     289
    299290#if 0
    300291HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
    301292{
    302     vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
    303 #error "port me!"
     293    vboxUhgsmiKmtSetupCallbacks(pHgsmi);
    304294    return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
    305295}
     296
     297HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
     298{
     299    vboxUhgsmiKmtEscSetupCallbacks(pHgsmi);
     300    return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
     301}
    306302#endif
    307303
    308 HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
    309 {
    310     vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
    311     return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
     304static HRESULT vboxUhgsmiKmtQueryCaps(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, uint32_t *pu32Caps)
     305{
     306    VBOXWDDM_QI Query;
     307    D3DKMT_QUERYADAPTERINFO Info;
     308    Info.hAdapter = pHgsmi->Adapter.hAdapter;
     309    Info.Type = KMTQAITYPE_UMDRIVERPRIVATE;
     310    Info.pPrivateDriverData = &Query;
     311    Info.PrivateDriverDataSize = sizeof (Query);
     312
     313    NTSTATUS Status = pHgsmi->Callbacks.pfnD3DKMTQueryAdapterInfo(&Info);
     314    if (!NT_SUCCESS(Status))
     315    {
     316        WARN(("pfnD3DKMTQueryAdapterInfo failed, Status %#x", Status));
     317        return Status;
     318    }
     319
     320    if (Query.u32Version != VBOXVIDEOIF_VERSION)
     321    {
     322        WARN(("Version mismatch"));
     323        return E_FAIL;
     324    }
     325
     326    *pu32Caps = Query.u32VBox3DCaps;
     327
     328    return S_OK;
     329}
     330
     331HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
     332{
     333    HRESULT hr = vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
     334    if (!SUCCEEDED(hr))
     335        return hr;
     336
     337    uint32_t u32Caps = 0;
     338    hr = vboxUhgsmiKmtQueryCaps(pHgsmi, &u32Caps);
     339    if (!SUCCEEDED(hr))
     340    {
     341        WARN(("vboxUhgsmiKmtQueryCaps failed hr %#x", hr));
     342        return hr;
     343    }
     344
     345    if (u32Caps & CR_VBOX_CAP_CMDVBVA)
     346        vboxUhgsmiKmtSetupCallbacks(pHgsmi);
     347    else
     348        vboxUhgsmiKmtEscSetupCallbacks(pHgsmi);
     349
     350    return S_OK;
    312351}
    313352
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h

    r44529 r49591  
    3535#define VBOXUHGSMIKMT_GET(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_KMT)
    3636
    37 #if 0
    38 HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
    39 #endif
    4037HRESULT vboxUhgsmiKmtDestroy(PVBOXUHGSMI_PRIVATE_KMT pHgsmi);
    4138
    42 HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
    43 
     39HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
    4440
    4541#endif /* #ifndef ___VBoxUhgsmiKmt_h__ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h

    r49458 r49591  
    128128   BOOLEAN f3DEnabled;
    129129   BOOLEAN fTexPresentEnabled;
     130   BOOLEAN fCmdVbvaEnabled;
    130131
    131132   uint32_t u32CrConDefaultClientID;
     133
     134   VBOXCMDVBVA CmdVbva;
    132135
    133136   VBOXMP_CRCTLCON CrCtlCon;
     
    213216DECLINLINE(ULONG) vboxWddmVramCpuVisibleSize(PVBOXMP_DEVEXT pDevExt)
    214217{
    215 #ifdef VBOXWDDM_RENDER_FROM_SHADOW
     218    if (pDevExt->fCmdVbvaEnabled)
     219    {
     220        /* all memory layout info should be initialized */
     221        Assert(pDevExt->CmdVbva.Vbva.offVRAMBuffer);
     222        /* page aligned */
     223        Assert(!(pDevExt->CmdVbva.Vbva.offVRAMBuffer & 0xfff));
     224
     225        return (ULONG)(pDevExt->CmdVbva.Vbva.offVRAMBuffer & ~0xfffULL);
     226    }
    216227    /* all memory layout info should be initialized */
    217228    Assert(pDevExt->aSources[0].Vbva.Vbva.offVRAMBuffer);
     
    220231
    221232    return (ULONG)(pDevExt->aSources[0].Vbva.Vbva.offVRAMBuffer & ~0xfffULL);
    222 #else
    223     /* all memory layout info should be initialized */
    224     Assert(pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase);
    225     /* page aligned */
    226     Assert(!(pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase & 0xfff));
    227 
    228     return pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase & ~0xfffUL;
    229 #endif
    230233}
    231234
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp

    r47603 r49591  
    893893    }
    894894
     895#if 1 /*def DEBUG_misha*/
     896    g_VBoxMpCrHostCaps &= ~CR_VBOX_CAP_CMDVBVA;
     897#endif
     898
    895899    rc = VBoxMpCrCtlConDisconnect(&CrCtlCon, u32ClientID);
    896900    if (RT_FAILURE(rc))
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp

    r48070 r49591  
    13751375                pBufCmd->offBuffer = pRef->pAlloc->offData + pBufInfo->Info.offData;
    13761376                pBufCmd->cbBuffer = pBufInfo->Info.cbData;
    1377                 pBufCmd->u32GuestData = pBufInfo->Info.bDoNotSignalCompletion;
     1377                pBufCmd->u32GuestData = 0;
    13781378                pBufCmd->u64GuestData = (uint64_t)pRef;
    13791379            }
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h

    r49244 r49591  
    183183#endif
    184184    VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType;
    185     PKEVENT pSynchEvent;
    186185} VBOXWDDM_ALLOCATION, *PVBOXWDDM_ALLOCATION;
    187186
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp

    r49365 r49591  
    702702    PVBOXMP_DEVEXT pDevExt;
    703703    VBOXCMDVBVA *pVbva;
    704     UINT u32FenceId;
     704    volatile UINT *pu32FenceId;
    705705    DXGK_INTERRUPT_TYPE enmComplType;
    706706} VBOXCMDVBVA_NOTIFYCOMPLETED_CB, *PVBOXCMDVBVA_NOTIFYCOMPLETED_CB;
     
    709709{
    710710    PVBOXCMDVBVA_NOTIFYCOMPLETED_CB pData = (PVBOXCMDVBVA_NOTIFYCOMPLETED_CB)pvContext;
    711     vboxCmdVbvaDdiNotifyCompleteIrq(pData->pDevExt, pData->pVbva, pData->u32FenceId, pData->enmComplType);
    712 
    713     pData->pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pData->pDevExt->u.primary.DxgkInterface.DeviceHandle);
    714     return TRUE;
    715 }
    716 
    717 static int vboxCmdVbvaDdiNotifyComplete(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, UINT u32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
     711    if (*pData->pu32FenceId)
     712    {
     713        UINT u32FenceId = *pData->pu32FenceId;
     714        *pData->pu32FenceId = 0;
     715
     716        vboxCmdVbvaDdiNotifyCompleteIrq(pData->pDevExt, pData->pVbva, u32FenceId, pData->enmComplType);
     717
     718        pData->pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pData->pDevExt->u.primary.DxgkInterface.DeviceHandle);
     719
     720        return TRUE;
     721    }
     722
     723    return FALSE;
     724}
     725
     726static int vboxCmdVbvaDdiNotifyComplete(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, volatile UINT *pu32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
    718727{
    719728    VBOXCMDVBVA_NOTIFYCOMPLETED_CB Data;
    720729    Data.pDevExt = pDevExt;
    721730    Data.pVbva = pVbva;
    722     Data.u32FenceId = u32FenceId;
     731    Data.pu32FenceId = pu32FenceId;
    723732    Data.enmComplType = enmComplType;
    724733    BOOLEAN bDummy;
     
    759768}
    760769
    761 static void vboxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, bool fPingHost, HGSMIGUESTCOMMANDCONTEXT *pCtx, bool fBufferOverflow)
     770typedef struct VBOXCMDVBVA_CHECK_COMPLETED_CB
     771{
     772    PVBOXMP_DEVEXT pDevExt;
     773    VBOXCMDVBVA *pVbva;
     774    uint32_t u32FenceID;
     775} VBOXCMDVBVA_CHECK_COMPLETED_CB;
     776
     777static BOOLEAN vboxCmdVbvaCheckCompletedIrqCb(PVOID pContext)
     778{
     779    VBOXCMDVBVA_CHECK_COMPLETED_CB *pCompleted = (VBOXCMDVBVA_CHECK_COMPLETED_CB*)pContext;
     780    BOOLEAN bRc = DxgkDdiInterruptRoutineNew(pCompleted->pDevExt, 0);
     781    if (pCompleted->pVbva)
     782        pCompleted->u32FenceID = pCompleted->pVbva->u32FenceCompleted;
     783    return bRc;
     784}
     785
     786
     787static uint32_t vboxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost, HGSMIGUESTCOMMANDCONTEXT *pCtx, bool fBufferOverflow)
    762788{
    763789    if (fPingHost)
    764790        vboxCmdVbvaFlush(pDevExt, pCtx, fBufferOverflow);
    765791
    766     vboxWddmCallIsr(pDevExt);
     792    VBOXCMDVBVA_CHECK_COMPLETED_CB context;
     793    context.pDevExt = pDevExt;
     794    context.pVbva = pVbva;
     795    context.u32FenceID = 0;
     796    BOOLEAN bRet;
     797    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
     798                            pDevExt->u.primary.DxgkInterface.DeviceHandle,
     799                            vboxCmdVbvaCheckCompletedIrqCb,
     800                            &context,
     801                            0, /* IN ULONG MessageNumber */
     802                            &bRet);
     803    Assert(Status == STATUS_SUCCESS);
     804
     805    return context.u32FenceID;
    767806}
    768807
     
    771810    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvFlush;
    772811
    773     vboxCmdVbvaCheckCompleted(pDevExt, true /*fPingHost*/, pHGSMICtx, true /*fBufferOverflow*/);
     812    vboxCmdVbvaCheckCompleted(pDevExt, NULL,  true /*fPingHost*/, pHGSMICtx, true /*fBufferOverflow*/);
    774813}
    775814
     
    899938
    900939        if (!ASMAtomicCmpXchgU8(&pCmd->u8State, VBOXCMDVBVA_STATE_CANCELLED, VBOXCMDVBVA_STATE_SUBMITTED))
     940        {
    901941            Assert(pCmd->u8State == VBOXCMDVBVA_STATE_IN_PROGRESS);
    902 
    903         /* we have cancelled the command successfully */
    904         vboxCmdVbvaDdiNotifyComplete(pDevExt, pVbva, u32FenceID, DXGK_INTERRUPT_DMA_PREEMPTED);
     942            break;
     943        }
     944
     945        /* we have canceled the command successfully */
     946        vboxCmdVbvaDdiNotifyComplete(pDevExt, pVbva, &pCmd->u32FenceID, DXGK_INTERRUPT_DMA_PREEMPTED);
    905947        return true;
    906948    }
     
    939981        if (u8State == VBOXCMDVBVA_STATE_IN_PROGRESS)
    940982        {
    941             pVbva->u32FenceCompleted = u32FenceID;
     983            if (u32FenceID)
     984                pVbva->u32FenceCompleted = u32FenceID;
    942985            enmDdiNotify = DXGK_INTERRUPT_DMA_COMPLETED;
    943986        }
    944987        else
     988        {
     989            Assert(u8State == VBOXCMDVBVA_STATE_CANCELLED);
    945990            enmDdiNotify = DXGK_INTERRUPT_DMA_PREEMPTED;
    946 
    947         vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, pCmd->u32FenceID, enmDdiNotify);
     991            /* to prevent concurrent notifications from DdiPreemptCommand */
     992            pCmd->u32FenceID = 0;
     993        }
     994
     995        if (u32FenceID)
     996            vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, u32FenceID, enmDdiNotify);
    948997
    949998        fHasCommandsCompletedPreempted = true;
     
    9531002}
    9541003
    955 void VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, bool fPingHost)
    956 {
    957     vboxCmdVbvaCheckCompleted(pDevExt, fPingHost, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, false /* fBufferOverflow */);
    958 }
     1004uint32_t VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost)
     1005{
     1006    return vboxCmdVbvaCheckCompleted(pDevExt, pVbva, fPingHost, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, false /* fBufferOverflow */);
     1007}
     1008
     1009
     1010static uint32_t vboxCVDdiSysMemElBuild(VBOXCMDVBVA_SYSMEMEL *pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages)
     1011{
     1012    PFN_NUMBER cur = MmGetMdlPfnArray(pMdl)[iPfn];
     1013    uint32_t cbEl = sizeof (*pEl);
     1014    uint32_t cStoredPages = 1;
     1015    pEl->iPage = cur;
     1016    --cPages;
     1017    for ( ; cPages && cStoredPages < VBOXCMDVBVA_SYSMEMEL_CPAGES_MAX; --cPages, ++cStoredPages)
     1018    {
     1019        PFN_NUMBER next = MmGetMdlPfnArray(pMdl)[iPfn+cStoredPages];
     1020        if (next != cur+1)
     1021            break;
     1022
     1023        cur = next;
     1024        ++cStoredPages;
     1025        --cPages;
     1026    }
     1027
     1028    Assert(cStoredPages);
     1029    pEl->cPagesAfterFirst = cStoredPages - 1;
     1030
     1031    return cPages;
     1032}
     1033
     1034uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten)
     1035{
     1036    uint32_t cInitPages = cPages;
     1037    uint32_t cbInitBuffer = cbBuffer;
     1038    uint32_t cEls = 0;
     1039    VBOXCMDVBVA_SYSMEMEL *pEl = pCmd->aSysMem;
     1040
     1041    if (cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
     1042    {
     1043        WARN(("cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER)"));
     1044        goto done;
     1045    }
     1046
     1047    cbBuffer -= RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aSysMem);
     1048    uint32_t i = 0;
     1049
     1050    for (; cPages && cbBuffer >= sizeof (VBOXCMDVBVA_PAGING_TRANSFER); ++cEls, cbBuffer-=sizeof (VBOXCMDVBVA_SYSMEMEL), ++pEl, ++i)
     1051    {
     1052        cPages = vboxCVDdiSysMemElBuild(pEl, pMdl, iPfn + cInitPages - cPages, cPages);
     1053    }
     1054
     1055    pCmd->cSysMem = i;
     1056
     1057done:
     1058    *pcPagesWritten = cInitPages - cPages;
     1059    return cbInitBuffer - cbBuffer;
     1060}
     1061
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h

    r49365 r49591  
    115115} VBVAEXBUFFERBACKWARDITER, *PVBVAEXBUFFERBACKWARDITER;
    116116
     117#define VBOXCMDVBVA_BUFFERSIZE(_cbCmdApprox) (RT_OFFSETOF(VBVABUFFER, au8Data) + ((RT_SIZEOFMEMB(VBVABUFFER, aRecords)/RT_SIZEOFMEMB(VBVABUFFER, aRecords[0])) * (_cbCmdApprox)))
    117118
    118119typedef struct VBOXCMDVBVA
     
    203204int VBoxCmdVbvaSubmit(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, struct VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd);
    204205bool VBoxCmdVbvaPreempt(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, uint32_t u32FenceID);
    205 void VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, bool fPingHost);
     206uint32_t VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost);
    206207bool VBoxCmdVbvaCheckCompletedIrq(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
    207208
     209/*helper functions for filling vbva commands */
     210DECLINLINE(void) VBoxCVDdiPackRect(VBOXCMDVBVA_RECT *pVbvaRect, const RECT *pRect)
     211{
     212    pVbvaRect->xLeft = (int16_t)pRect->left;
     213    pVbvaRect->yTop = (int16_t)pRect->top;
     214    pVbvaRect->xRight = (int16_t)pRect->right;
     215    pVbvaRect->yBottom = (int16_t)pRect->bottom;
     216}
     217
     218DECLINLINE(void) VBoxCVDdiPackRects(VBOXCMDVBVA_RECT *paVbvaRects, const RECT *paRects, uint32_t cRects)
     219{
     220    for (uint32_t i = 0; i < cRects; ++i)
     221    {
     222        VBoxCVDdiPackRect(&paVbvaRects[i], &paRects[i]);
     223    }
     224
     225}
     226
     227uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten);
     228
    208229#endif /* #ifndef ___VBoxMPVbva_h___ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp

    r49259 r49591  
    3232
    3333#include <stdio.h>
     34
     35#define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof (RECT)
    3436
    3537DWORD g_VBoxLogUm = 0;
     
    660662}
    661663
    662 static void vboxWddmSetupDisplays(PVBOXMP_DEVEXT pDevExt)
     664static void vboxWddmSetupDisplaysLegacy(PVBOXMP_DEVEXT pDevExt)
    663665{
    664666    /* For WDDM, we simply store the number of monitors as we will deal with
     
    770772            VBoxCommonFromDeviceExt(pDevExt)->bHGSMI = FALSE;
    771773    }
     774}
     775
     776static NTSTATUS vboxWddmSetupDisplaysNew(PVBOXMP_DEVEXT pDevExt)
     777{
     778    if (!VBoxCommonFromDeviceExt(pDevExt)->bHGSMI)
     779        return STATUS_UNSUCCESSFUL;
     780
     781    ULONG cbAvailable = VBoxCommonFromDeviceExt(pDevExt)->cbVRAM
     782                            - VBoxCommonFromDeviceExt(pDevExt)->cbMiniportHeap
     783                            - VBVA_ADAPTER_INFORMATION_SIZE;
     784
     785    ULONG cbCmdVbva = cbAvailable / 2;
     786    ULONG cbCmdVbvaApprox = VBOXCMDVBVA_BUFFERSIZE(4096);
     787    if (cbCmdVbvaApprox > cbCmdVbva)
     788    {
     789        WARN(("too few VRAM memory %d, cmdVbva %d, while approximately needed %d, trying to adjust", cbAvailable, cbCmdVbva, cbCmdVbvaApprox));
     790        cbCmdVbva = cbCmdVbvaApprox;
     791    }
     792
     793    cbCmdVbva = VBOXWDDM_ROUNDBOUND(cbCmdVbva, 0x1000);
     794    if (cbCmdVbva > cbAvailable - 0x1000)
     795    {
     796        WARN(("too few VRAM memory fatal, %d, requested for CmdVbva %d", cbAvailable, cbCmdVbva));
     797        return STATUS_UNSUCCESSFUL;
     798    }
     799
     800
     801    ULONG offCmdVbva = cbAvailable - cbCmdVbva;
     802
     803    int rc = VBoxCmdVbvaCreate(pDevExt, &pDevExt->CmdVbva, offCmdVbva, cbCmdVbva);
     804    if (RT_SUCCESS(rc))
     805    {
     806        rc = VBoxCmdVbvaEnable(pDevExt, &pDevExt->CmdVbva);
     807        if (RT_SUCCESS(rc))
     808        {
     809            rc = VBoxMPCmnMapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pDevExt->pvVisibleVram,
     810                                           0, vboxWddmVramCpuVisibleSize(pDevExt));
     811            if (RT_SUCCESS(rc))
     812                return STATUS_SUCCESS;
     813            else
     814                WARN(("VBoxMPCmnMapAdapterMemory failed, rc %d", rc));
     815
     816            VBoxCmdVbvaDisable(pDevExt, &pDevExt->CmdVbva);
     817        }
     818        else
     819            WARN(("VBoxCmdVbvaEnable failed, rc %d", rc));
     820
     821        VBoxCmdVbvaDestroy(pDevExt, &pDevExt->CmdVbva);
     822    }
     823    else
     824        WARN(("VBoxCmdVbvaCreate failed, rc %d", rc));
     825
     826    return STATUS_UNSUCCESSFUL;
     827}
     828
     829static NTSTATUS vboxWddmSetupDisplays(PVBOXMP_DEVEXT pDevExt)
     830{
     831    if (pDevExt->fCmdVbvaEnabled)
     832    {
     833        NTSTATUS Status = vboxWddmSetupDisplaysNew(pDevExt);
     834        if (!NT_SUCCESS(Status))
     835            VBoxCommonFromDeviceExt(pDevExt)->bHGSMI = FALSE;
     836        return Status;
     837    }
     838
     839    vboxWddmSetupDisplaysLegacy(pDevExt);
     840    return VBoxCommonFromDeviceExt(pDevExt)->bHGSMI ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
     841        return STATUS_UNSUCCESSFUL;
    772842}
    773843
     
    899969            if (Status == STATUS_SUCCESS)
    900970            {
     971                pDevExt->f3DEnabled = VBoxMpCrCtlConIs3DSupported();
     972
     973                if (pDevExt->f3DEnabled)
     974                {
     975                    pDevExt->fTexPresentEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_TEX_PRESENT);
     976                    pDevExt->fCmdVbvaEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_CMDVBVA);
     977                }
     978                else
     979                {
     980                    pDevExt->fTexPresentEnabled = FALSE;
     981                    pDevExt->fCmdVbvaEnabled = FALSE;
     982                }
     983
    901984                /* Guest supports only HGSMI, the old VBVA via VMMDev is not supported.
    902985                 * The host will however support both old and new interface to keep compatibility
     
    9441027                    VBoxMpCrShgsmiTransportCreate(&pDevExt->CrHgsmiTransport, pDevExt);
    9451028
    946                     pDevExt->f3DEnabled = VBoxMpCrCtlConIs3DSupported();
    947 
    948                     if (pDevExt->f3DEnabled)
    949                     {
    950                         pDevExt->fTexPresentEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_TEX_PRESENT);
    951                     }
    952                     else
    953                         pDevExt->fTexPresentEnabled = FALSE;
    9541029
    9551030                    for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     
    12271302}
    12281303
    1229 BOOLEAN DxgkDdiInterruptRoutine(
     1304
     1305BOOLEAN DxgkDdiInterruptRoutineNew(
     1306    IN CONST PVOID MiniportDeviceContext,
     1307    IN ULONG MessageNumber
     1308    )
     1309{
     1310//    LOGF(("ENTER, context(0x%p), msg(0x%x)", MiniportDeviceContext, MessageNumber));
     1311
     1312    vboxVDbgBreakFv();
     1313
     1314    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
     1315    BOOLEAN bOur = FALSE;
     1316    bool bNeedDpc = FALSE;
     1317    if (!VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags) /* If HGSMI is enabled at all. */
     1318    {
     1319        WARN(("ISR called with hgsmi disabled!"));
     1320        return FALSE;
     1321    }
     1322
     1323    uint32_t flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags;
     1324    bOur = (flags & HGSMIHOSTFLAGS_IRQ);
     1325
     1326    if (bOur)
     1327        VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pDevExt)->hostCtx);
     1328
     1329    bNeedDpc |= VBoxCmdVbvaCheckCompletedIrq(pDevExt, &pDevExt->CmdVbva);
     1330
     1331    if (bNeedDpc)
     1332        pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
     1333
     1334//    LOGF(("LEAVE, context(0x%p), bOur(0x%x)", MiniportDeviceContext, (ULONG)bOur));
     1335
     1336    return bOur;
     1337}
     1338
     1339
     1340static BOOLEAN DxgkDdiInterruptRoutineLegacy(
    12301341    IN CONST PVOID MiniportDeviceContext,
    12311342    IN ULONG MessageNumber
     
    14501561}
    14511562
    1452 VOID DxgkDdiDpcRoutine(
     1563static VOID DxgkDdiDpcRoutineNew(
     1564    IN CONST PVOID  MiniportDeviceContext
     1565    )
     1566{
     1567//    LOGF(("ENTER, context(0x%p)", MiniportDeviceContext));
     1568
     1569    vboxVDbgBreakFv();
     1570
     1571    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
     1572
     1573    pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
     1574
     1575//    LOGF(("LEAVE, context(0x%p)", MiniportDeviceContext));
     1576}
     1577
     1578
     1579static VOID DxgkDdiDpcRoutineLegacy(
    14531580    IN CONST PVOID  MiniportDeviceContext
    14541581    )
     
    20202147        case VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER:
    20212148        {
    2022             if (pAllocation->pSynchEvent)
    2023                 ObDereferenceObject(pAllocation->pSynchEvent);
    20242149            break;
    20252150        }
     
    22152340//                    pAllocationInfo->Flags.SynchronousPaging = 1;
    22162341                    pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_MAXIMUM;
    2217                     if (pAllocInfo->hSynch)
    2218                     {
    2219                         Status = ObReferenceObjectByHandle((HANDLE)pAllocInfo->hSynch, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
    2220                                 (PVOID*)&pAllocation->pSynchEvent,
    2221                                 NULL);
    2222                         Assert(Status == STATUS_SUCCESS);
    2223                     }
    22242342                    break;
    22252343                }
     
    25612679}
    25622680
    2563 NTSTATUS
     2681static NTSTATUS
    25642682APIENTRY
    2565 DxgkDdiPatch(
     2683DxgkDdiPatchNew(
     2684    CONST HANDLE  hAdapter,
     2685    CONST DXGKARG_PATCH*  pPatch)
     2686{
     2687    /* DxgkDdiPatch should be made pageable. */
     2688    PAGED_CODE();
     2689
     2690    LOGF(("ENTER, context(0x%x)", hAdapter));
     2691
     2692    vboxVDbgBreakFv();
     2693
     2694    uint8_t * pPrivateBuf = (uint8_t*)((uint8_t*)pPatch->pDmaBufferPrivateData + pPatch->DmaBufferPrivateDataSubmissionStartOffset);
     2695    UINT cbPatchBuff = pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset;
     2696
     2697    for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
     2698    {
     2699        const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[i];
     2700        Assert(pPatchList->AllocationIndex < pPatch->AllocationListSize);
     2701        const DXGK_ALLOCATIONLIST *pAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
     2702        if (!pAllocationList->SegmentId)
     2703        {
     2704            WARN(("no segment id specified"));
     2705            continue;
     2706        }
     2707
     2708        if (pPatchList->PatchOffset == ~0UL)
     2709        {
     2710            /* this is a dummy patch request, ignore */
     2711            continue;
     2712        }
     2713
     2714        if (pPatchList->PatchOffset >= cbPatchBuff)
     2715        {
     2716            WARN(("pPatchList->PatchOffset(%d) >= cbPatchBuff(%d)", pPatchList->PatchOffset, cbPatchBuff));
     2717            return STATUS_INVALID_PARAMETER;
     2718        }
     2719
     2720        VBOXCMDVBVAOFFSET *poffVram = (VBOXCMDVBVAOFFSET*)(pPrivateBuf + pPatchList->PatchOffset);
     2721        Assert(pAllocationList->SegmentId);
     2722        Assert(!pAllocationList->PhysicalAddress.HighPart);
     2723        Assert(!(pAllocationList->PhysicalAddress.QuadPart & 0xfffUL)); /* <- just a check to ensure allocation offset does not go here */
     2724        *poffVram = pAllocationList->PhysicalAddress.LowPart + pPatchList->AllocationOffset;;
     2725    }
     2726
     2727    return STATUS_SUCCESS;
     2728}
     2729
     2730
     2731static NTSTATUS
     2732APIENTRY
     2733DxgkDdiPatchLegacy(
    25662734    CONST HANDLE  hAdapter,
    25672735    CONST DXGKARG_PATCH*  pPatch)
     
    27292897{
    27302898    PVBOXWDDM_CALL_ISR pdc = (PVBOXWDDM_CALL_ISR)Context;
    2731     return DxgkDdiInterruptRoutine(pdc->pDevExt, pdc->MessageNumber);
     2899    if (pdc->pDevExt->fCmdVbvaEnabled)
     2900        return DxgkDdiInterruptRoutineNew(pdc->pDevExt, pdc->MessageNumber);
     2901    return DxgkDdiInterruptRoutineLegacy(pdc->pDevExt, pdc->MessageNumber);
    27322902}
    27332903
     
    27552925    VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
    27562926    UINT cBufs = pBody->cBuffers;
    2757     for (UINT i = 0; i < cBufs; ++i)
    2758     {
    2759         VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
    2760         if (!pBufCmd->u32GuestData)
    2761         {
    2762             /* signal completion */
    2763             PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBufCmd->u64GuestData;
    2764             if (pAlloc->pSynchEvent)
    2765                 KeSetEvent(pAlloc->pSynchEvent, 3, FALSE);
    2766         }
    2767     }
    2768 
    27692927    vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
    27702928}
    27712929#endif
    27722930
    2773 NTSTATUS
     2931static NTSTATUS
    27742932APIENTRY
    2775 DxgkDdiSubmitCommand(
     2933DxgkDdiSubmitCommandNew(
     2934    CONST HANDLE  hAdapter,
     2935    CONST DXGKARG_SUBMITCOMMAND*  pSubmitCommand)
     2936{
     2937    /* DxgkDdiSubmitCommand runs at dispatch, should not be pageable. */
     2938
     2939//    LOGF(("ENTER, context(0x%x)", hAdapter));
     2940
     2941    vboxVDbgBreakFv();
     2942
     2943    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
     2944#ifdef DEBUG
     2945    PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
     2946    Assert(pContext);
     2947    Assert(pContext->pDevice);
     2948    Assert(pContext->pDevice->pAdapter == pDevExt);
     2949    Assert(!pSubmitCommand->DmaBufferSegmentId);
     2950#endif
     2951
     2952    /* the DMA command buffer is located in system RAM, the host will need to pick it from there */
     2953    //BufInfo.fFlags = 0; /* see VBOXVDMACBUF_FLAG_xx */
     2954    uint32_t cbCmd = pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset;
     2955    if (cbCmd < sizeof (VBOXCMDVBVA_HDR))
     2956    {
     2957        WARN(("DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXCMDVBVA_HDR) (%d)",
     2958                pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset,
     2959                pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset,
     2960                sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
     2961        return STATUS_INVALID_PARAMETER;
     2962    }
     2963
     2964    VBOXCMDVBVA_HDR *pHdr = (VBOXCMDVBVA_HDR*)((uint8_t*)pSubmitCommand->pDmaBufferPrivateData + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset);
     2965    pHdr->u32FenceID = pSubmitCommand->SubmissionFenceId;
     2966    int rc = VBoxCmdVbvaSubmit(pDevExt, &pDevExt->CmdVbva, pHdr, cbCmd);
     2967    if (RT_SUCCESS(rc))
     2968        return STATUS_SUCCESS;
     2969
     2970    WARN(("VBoxCmdVbvaSubmit failed rc %d", rc));
     2971    return STATUS_UNSUCCESSFUL;
     2972}
     2973
     2974static NTSTATUS
     2975APIENTRY
     2976DxgkDdiSubmitCommandLegacy(
    27762977    CONST HANDLE  hAdapter,
    27772978    CONST DXGKARG_SUBMITCOMMAND*  pSubmitCommand)
     
    28873088            break;
    28883089        }
    2889         case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
    2890         {
    2891 #ifdef VBOX_WITH_CRHGSMI
    2892             VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD *pChromiumCmd = (VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD*)pPrivateDataBase;
    2893             UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[pChromiumCmd->Base.u32CmdReserved]));
    2894 
    2895             PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate (&pDevExt->u.primary.Vdma, cbCmd);
    2896             if (!pDr)
    2897             {
    2898                 /* @todo: try flushing.. */
    2899                 LOGREL(("vboxVdmaCBufDrCreate returned NULL"));
    2900                 return STATUS_INSUFFICIENT_RESOURCES;
    2901             }
    2902             // vboxVdmaCBufDrCreate zero initializes the pDr
    2903             pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
    2904             pDr->cbBuf = cbCmd;
    2905             pDr->rc = VERR_NOT_IMPLEMENTED;
    2906 
    2907             PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
    2908             pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
    2909             pHdr->u32CmdSpecific = 0;
    2910             VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
    2911             pBody->cBuffers = pChromiumCmd->Base.u32CmdReserved;
    2912             for (UINT i = 0; i < pChromiumCmd->Base.u32CmdReserved; ++i)
    2913             {
    2914                 VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
    2915                 VBOXWDDM_UHGSMI_BUFFER_SUBMIT_INFO *pBufInfo = &pChromiumCmd->aBufInfos[i];
    2916 
    2917                 pBufCmd->offBuffer = pBufInfo->Alloc.offAlloc;
    2918                 pBufCmd->cbBuffer = pBufInfo->cbData;
    2919                 pBufCmd->u32GuestData = pBufInfo->bDoNotSignalCompletion;
    2920                 pBufCmd->u64GuestData = (uint64_t)pBufInfo->Alloc.pAlloc;
    2921             }
    2922 
    2923             PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
    2924             vboxVdmaDdiCmdInit(pDdiCmd, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, vboxWddmDmaCompleteChromiumCmd, pDr);
    2925             NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, pDdiCmd);
    2926             Assert(Status == STATUS_SUCCESS);
    2927             if (Status == STATUS_SUCCESS)
    2928             {
    2929                 int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
    2930                 Assert(rc == VINF_SUCCESS);
    2931             }
    2932             else
    2933             {
    2934                 vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
    2935             }
    2936 #else
    2937             Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
    2938             Assert(Status == STATUS_SUCCESS);
    2939 #endif
    2940             break;
    2941         }
    29423090        case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
    29433091        {
     
    30053153}
    30063154
    3007 NTSTATUS
     3155static NTSTATUS
    30083156APIENTRY
    3009 DxgkDdiPreemptCommand(
     3157DxgkDdiPreemptCommandNew(
    30103158    CONST HANDLE  hAdapter,
    30113159    CONST DXGKARG_PREEMPTCOMMAND*  pPreemptCommand)
     
    30133161    LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
    30143162
     3163    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
     3164
     3165    VBoxCmdVbvaPreempt(pDevExt, &pDevExt->CmdVbva, pPreemptCommand->PreemptionFenceId);
     3166
     3167    LOGF(("LEAVE, hAdapter(0x%x)", hAdapter));
     3168
     3169    return STATUS_SUCCESS;
     3170}
     3171
     3172
     3173static NTSTATUS
     3174APIENTRY
     3175DxgkDdiPreemptCommandLegacy(
     3176    CONST HANDLE  hAdapter,
     3177    CONST DXGKARG_PREEMPTCOMMAND*  pPreemptCommand)
     3178{
     3179    LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
     3180
    30153181    AssertFailed();
    30163182    /* @todo: fixme: implement */
     
    30213187}
    30223188
    3023 #if 0
    3024 static uint32_t vboxWddmSysMemElBuild(PVBOXVDMACMD_SYSMEMEL pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesRemaining)
    3025 {
    3026     uint32_t cbInitialBuffer = cbBuffer;
    3027     if (cbBuf >= sizeof (*pEl))
    3028     {
    3029         PFN_NUMBER cur = MmGetMdlPfnArray(pMdl)[iPfn];
    3030         uint32_t cbEl = sizeof (*pEl);
    3031         uint32_t cBufs = 1;
    3032         pEl->phBuf[0] = (cur << 12);
    3033         --cPages;
    3034         cbBuffer -= sizeof (*pEl);
    3035         bool bArrayMode = false;
    3036         while (cPages)
    3037         {
    3038             PFN_NUMBER next = MmGetMdlPfnArray(pMdl)[iPfn+cBufs];
    3039             if (!bArrayMode)
    3040             {
    3041                 if (next == cur+1)
    3042                 {
    3043                     cur = next;
    3044                     ++cBufs;
    3045                     --cPages;
    3046                 }
    3047                 else if (cBufs > 1)
    3048                 {
    3049                     break;
    3050                 }
    3051                 else
    3052                 {
    3053                     bArrayMode = true;
    3054                 }
    3055             }
    3056 
    3057             /* array mode */
    3058             if (cbBuffer < sizeof (pEl->phBuf[0]))
    3059             {
    3060                 break;
    3061             }
    3062 
    3063             pEl->phBuf[cBufs] = (next << 12);
    3064             cbBuffer -= sizeof (pEl->phBuf[0]);
    3065             ++cBufs;
    3066             --cPages;
    3067         }
    3068 
    3069         pEl->cPages = cPages;
    3070         if (bArrayMode)
    3071             pEl->fFlags = VBOXVDMACMD_SYSMEMEL_F_PAGELIST;
    3072         else
    3073             pEl->fFlags = 0;
    3074     }
    3075     else
    3076     {
    3077         Assert(0);
    3078     }
    3079 
    3080     *pcPagesRemaining = cPages;
    3081     return cbInitialBuffer - cbBuffer;
    3082 }
    3083 
    3084 static uint32_t vboxWddmBpbTransferVRamSysBuildEls(PVBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesRemaining)
    3085 {
    3086     uint32_t cInitPages = cPages;
    3087     uint32_t cbBufferUsed = vboxWddmSysMemElBuild(&pCmd->FirstEl, pMdl, iPfn, cPages, cbBuffer, &cPages);
    3088     if (cbBufferUsed)
    3089     {
    3090         uint32_t cEls = 1;
    3091         PVBOXVDMACMD_SYSMEMEL pEl = &pCmd->FirstEl;
    3092         while (cPages)
    3093         {
    3094             PVBOXVDMACMD_SYSMEMEL pEl = VBOXVDMACMD_SYSMEMEL_NEXT(pEl);
    3095             cbBufferUsed = vboxWddmSysMemElBuild(pEl, pMdl, iPfn + cInitPages - cPages, cPages, cbBuffer - cbBufferUsed, &cPages);
    3096             if (cbBufferUsed)
    3097             {
    3098                 ++cEls;
    3099             }
    3100             else
    3101                 break;
    3102         }
    3103     }
    3104     else
    3105     {
    3106         Assert(0);
    3107     }
    3108 
    3109     pCmd->cTransferPages = (cInitPages - cPages);
    3110     *pcPagesRemaining = cPages;
    3111     return cbBufferUsed;
    3112 }
    3113 #endif
    31143189/*
    31153190 * DxgkDdiBuildPagingBuffer
    31163191 */
    3117 NTSTATUS
     3192static NTSTATUS
    31183193APIENTRY
    3119 DxgkDdiBuildPagingBuffer(
     3194DxgkDdiBuildPagingBufferNew(
     3195    CONST HANDLE  hAdapter,
     3196    DXGKARG_BUILDPAGINGBUFFER*  pBuildPagingBuffer)
     3197{
     3198    /* DxgkDdiBuildPagingBuffer should be made pageable. */
     3199    PAGED_CODE();
     3200
     3201    vboxVDbgBreakFv();
     3202
     3203    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
     3204    uint32_t cbBuffer = 0, cbPrivateData = 0;
     3205
     3206    LOGF(("ENTER, context(0x%x)", hAdapter));
     3207
     3208    /* paging buffer transfer is nop for hostID allocations */
     3209    if (pBuildPagingBuffer->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
     3210    {
     3211        WARN(("pBuildPagingBuffer->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)", pBuildPagingBuffer->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
     3212        /* @todo: can this actually happen? what status to return? */
     3213        return STATUS_INVALID_PARAMETER;
     3214    }
     3215
     3216    switch (pBuildPagingBuffer->Operation)
     3217    {
     3218        case DXGK_OPERATION_TRANSFER:
     3219        {
     3220            VBOXCMDVBVA_HDR *pHdr = (VBOXCMDVBVA_HDR*)pBuildPagingBuffer->pDmaBuffer;
     3221            pHdr->u8Flags = 0;
     3222            pHdr->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
     3223            /* sanity */
     3224            pHdr->u32FenceID = 0;
     3225
     3226            if ((!pBuildPagingBuffer->Transfer.Source.SegmentId) == (!pBuildPagingBuffer->Transfer.Destination.SegmentId))
     3227            {
     3228                WARN(("we only support RAM <-> VRAM moves, Src Seg(%d), Dst Seg(%d)", pBuildPagingBuffer->Transfer.Source.SegmentId, pBuildPagingBuffer->Transfer.Destination.SegmentId));
     3229                return STATUS_INVALID_PARAMETER;
     3230            }
     3231
     3232            PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Transfer.hAllocation;
     3233            if (!pAlloc)
     3234            {
     3235                WARN(("allocation is null"));
     3236                return STATUS_INVALID_PARAMETER;
     3237            }
     3238
     3239            if (pAlloc->AllocData.hostID)
     3240            {
     3241                pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_NOPCMD;
     3242                cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     3243                cbPrivateData = sizeof (*pHdr);
     3244                break;
     3245            }
     3246
     3247            if (pBuildPagingBuffer->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
     3248            {
     3249                WARN(("pBuildPagingBuffer->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_PAGING_TRANSFER (%d)", pBuildPagingBuffer->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_PAGING_TRANSFER)));
     3250                /* @todo: can this actually happen? what status to return? */
     3251                return STATUS_INVALID_PARAMETER;
     3252            }
     3253
     3254            VBOXCMDVBVA_PAGING_TRANSFER *pPaging = (VBOXCMDVBVA_PAGING_TRANSFER*)pBuildPagingBuffer->pDmaBuffer;
     3255            pPaging->Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER;
     3256
     3257            PMDL pMdl;
     3258            uint32_t offVRAM;
     3259            BOOLEAN fIn;
     3260
     3261            if (pBuildPagingBuffer->Transfer.Source.SegmentId)
     3262            {
     3263                Assert(!pBuildPagingBuffer->Transfer.Destination.SegmentId);
     3264                Assert(!pBuildPagingBuffer->Transfer.Source.SegmentAddress.HighPart);
     3265                offVRAM = pBuildPagingBuffer->Transfer.Source.SegmentAddress.LowPart;
     3266                pMdl = pBuildPagingBuffer->Transfer.Destination.pMdl;
     3267                fIn = FALSE;
     3268            }
     3269            else
     3270            {
     3271                Assert(pBuildPagingBuffer->Transfer.Destination.SegmentId);
     3272                Assert(!pBuildPagingBuffer->Transfer.Source.SegmentId);
     3273                Assert(!pBuildPagingBuffer->Transfer.Destination.SegmentAddress.HighPart);
     3274                offVRAM = pBuildPagingBuffer->Transfer.Destination.SegmentAddress.LowPart;
     3275                pMdl = pBuildPagingBuffer->Transfer.Source.pMdl;
     3276                fIn = TRUE;
     3277            }
     3278
     3279            uint32_t cPages = (uint32_t)((pBuildPagingBuffer->Transfer.TransferSize + 0xfff) >> PAGE_SHIFT);
     3280            uint32_t cTotalPages = cPages;
     3281            cPages -= pBuildPagingBuffer->MultipassOffset;
     3282            uint32_t iFirstPage = pBuildPagingBuffer->Transfer.MdlOffset + pBuildPagingBuffer->MultipassOffset;
     3283            uint32_t cPagesWritten;
     3284            offVRAM += pBuildPagingBuffer->Transfer.TransferOffset + pBuildPagingBuffer->MultipassOffset;
     3285
     3286            pPaging->Alloc.offVRAM = offVRAM;
     3287            if (fIn)
     3288                pPaging->Hdr.u8Flags |= VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN;
     3289            cbPrivateData = VBoxCVDdiPTransferVRamSysBuildEls(pPaging, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaBufferPrivateDataSize, &cPagesWritten);
     3290            if (cPagesWritten != cPages)
     3291                pBuildPagingBuffer->MultipassOffset += cPagesWritten;
     3292            else
     3293                pBuildPagingBuffer->MultipassOffset = 0;
     3294
     3295            cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     3296            break;
     3297        }
     3298        case DXGK_OPERATION_FILL:
     3299        {
     3300            Assert(pBuildPagingBuffer->Fill.FillPattern == 0);
     3301            PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation;
     3302            if (!pAlloc)
     3303            {
     3304                WARN(("allocation is null"));
     3305                return STATUS_INVALID_PARAMETER;
     3306            }
     3307            /** @todo: add necessary bits */
     3308            break;
     3309        }
     3310        case DXGK_OPERATION_DISCARD_CONTENT:
     3311        {
     3312            PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->DiscardContent.hAllocation;
     3313            if (!pAlloc)
     3314            {
     3315                WARN(("allocation is null"));
     3316                return STATUS_INVALID_PARAMETER;
     3317            }
     3318            break;
     3319        }
     3320        default:
     3321        {
     3322            WARN(("unsupported op (%d)", pBuildPagingBuffer->Operation));
     3323            break;
     3324        }
     3325    }
     3326
     3327    pBuildPagingBuffer->pDmaBuffer = ((uint8_t*)pBuildPagingBuffer->pDmaBuffer) + cbBuffer;
     3328    pBuildPagingBuffer->pDmaBufferPrivateData = ((uint8_t*)pBuildPagingBuffer->pDmaBufferPrivateData) + cbPrivateData;
     3329
     3330    LOGF(("LEAVE, context(0x%x)", hAdapter));
     3331
     3332    if (pBuildPagingBuffer->MultipassOffset)
     3333        return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
     3334    return STATUS_SUCCESS;
     3335}
     3336
     3337
     3338static NTSTATUS
     3339APIENTRY
     3340DxgkDdiBuildPagingBufferLegacy(
    31203341    CONST HANDLE  hAdapter,
    31213342    DXGKARG_BUILDPAGINGBUFFER*  pBuildPagingBuffer)
     
    36323853            case VBOXESC_UHGSMI_SUBMIT:
    36333854            {
     3855                if (pDevExt->fCmdVbvaEnabled)
     3856                {
     3857                    WARN(("VBOXESC_UHGSMI_SUBMIT not supported for CmdVbva mode"));
     3858                    Status = STATUS_INVALID_PARAMETER;
     3859                    break;
     3860                }
    36343861                /* submit VBOXUHGSMI command */
    36353862                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
     
    36523879            {
    36533880                /* allocate VBOXUHGSMI buffer */
     3881                if (pDevExt->fCmdVbvaEnabled)
     3882                {
     3883                    WARN(("VBOXESC_UHGSMI_ALLOCATE not supported for CmdVbva mode"));
     3884                    Status = STATUS_INVALID_PARAMETER;
     3885                    break;
     3886                }
     3887
    36543888                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
    36553889                PVBOXDISPIFESCAPE_UHGSMI_ALLOCATE pAlocate = (PVBOXDISPIFESCAPE_UHGSMI_ALLOCATE)pEscapeHdr;
     
    36683902            case VBOXESC_UHGSMI_DEALLOCATE:
    36693903            {
     3904                if (pDevExt->fCmdVbvaEnabled)
     3905                {
     3906                    WARN(("VBOXESC_UHGSMI_DEALLOCATE not supported for CmdVbva mode"));
     3907                    Status = STATUS_INVALID_PARAMETER;
     3908                    break;
     3909                }
    36703910                /* deallocate VBOXUHGSMI buffer */
    36713911                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
     
    36853925            case VBOXESC_GETVBOXVIDEOCMCMD:
    36863926            {
     3927                if (pDevExt->fCmdVbvaEnabled || pDevExt->fTexPresentEnabled)
     3928                {
     3929                    WARN(("VBOXESC_GETVBOXVIDEOCMCMD not supported for CmdVbva or TexPresent mode"));
     3930                    Status = STATUS_INVALID_PARAMETER;
     3931                    break;
     3932                }
     3933
    36873934                /* get the list of r0->r3 commands (d3d window visible regions reporting )*/
    36883935                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
     
    37103957            case VBOXESC_CRHGSMICTLCON_CALL:
    37113958            {
     3959                if (pDevExt->fCmdVbvaEnabled)
     3960                {
     3961                    WARN(("VBOXESC_CRHGSMICTLCON_CALL not supported for CmdVbva mode"));
     3962                    Status = STATUS_INVALID_PARAMETER;
     3963                    break;
     3964                }
     3965
    37123966                PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
    37133967                PVBOXDISPIFESCAPE_CRHGSMICTLCON_CALL pCall = (PVBOXDISPIFESCAPE_CRHGSMICTLCON_CALL)pEscapeHdr;
     
    42884542{
    42894543    PVBOXWDDM_QUERYCURFENCE_CB pdc = (PVBOXWDDM_QUERYCURFENCE_CB)Context;
    4290     BOOL bRc = DxgkDdiInterruptRoutine(pdc->pDevExt, pdc->MessageNumber);
     4544    BOOL bRc = DxgkDdiInterruptRoutineLegacy(pdc->pDevExt, pdc->MessageNumber);
    42914545    pdc->uLastCompletedCmdFenceId = pdc->pDevExt->u.primary.Vdma.uLastCompletedPagingBufferCmdFenceId;
    42924546    return bRc;
    42934547}
    42944548
    4295 NTSTATUS
     4549static NTSTATUS
    42964550APIENTRY
    4297 DxgkDdiQueryCurrentFence(
     4551DxgkDdiQueryCurrentFenceNew(
     4552    CONST HANDLE  hAdapter,
     4553    DXGKARG_QUERYCURRENTFENCE*  pCurrentFence)
     4554{
     4555    LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
     4556
     4557    vboxVDbgBreakF();
     4558
     4559    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
     4560    pCurrentFence->CurrentFence = VBoxCmdVbvaCheckCompleted(pDevExt, &pDevExt->CmdVbva, false);
     4561
     4562    LOGF(("LEAVE, hAdapter(0x%x)", hAdapter));
     4563
     4564    return STATUS_SUCCESS;
     4565}
     4566
     4567
     4568static NTSTATUS
     4569APIENTRY
     4570DxgkDdiQueryCurrentFenceLegacy(
    42984571    CONST HANDLE  hAdapter,
    42994572    DXGKARG_QUERYCURRENTFENCE*  pCurrentFence)
     
    52545527}
    52555528
    5256 NTSTATUS
     5529static NTSTATUS
    52575530APIENTRY
    5258 DxgkDdiRender(
     5531DxgkDdiRenderNew(
     5532    CONST HANDLE  hContext,
     5533    DXGKARG_RENDER  *pRender)
     5534{
     5535//    LOGF(("ENTER, hContext(0x%x)", hContext));
     5536
     5537    if (pRender->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
     5538    {
     5539        WARN(("pRender->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)",
     5540                pRender->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
     5541        /* @todo: can this actually happen? what status to return? */
     5542        return STATUS_INVALID_PARAMETER;
     5543    }
     5544    if (pRender->CommandLength < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
     5545    {
     5546        WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
     5547                pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
     5548        /* @todo: can this actually happen? what status to return? */
     5549        return STATUS_INVALID_PARAMETER;
     5550    }
     5551
     5552    PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pInputHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pCommand;
     5553    NTSTATUS Status = STATUS_SUCCESS;
     5554
     5555    uint32_t cbBuffer = 0;
     5556    uint32_t cbCmdDma = 0;
     5557    VBOXCMDVBVA_HDR* pCmd = (VBOXCMDVBVA_HDR*)pRender->pDmaBufferPrivateData;
     5558
     5559    switch (pInputHdr->enmCmd)
     5560    {
     5561        case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
     5562        {
     5563            if (pRender->AllocationListSize >= (UINT32_MAX - RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos))/ RT_SIZEOFMEMB(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[0]))
     5564            {
     5565                WARN(("Invalid AllocationListSize %d", pRender->AllocationListSize));
     5566                return STATUS_INVALID_PARAMETER;
     5567            }
     5568
     5569            if (pRender->CommandLength != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize]))
     5570            {
     5571                WARN(("pRender->CommandLength (%d) != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize](%d)",
     5572                        pRender->CommandLength, RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize])));
     5573                return STATUS_INVALID_PARAMETER;
     5574            }
     5575
     5576            if (pRender->AllocationListSize >= (UINT32_MAX - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers))/ RT_SIZEOFMEMB(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[0]))
     5577            {
     5578                WARN(("Invalid AllocationListSize %d", pRender->AllocationListSize));
     5579                return STATUS_INVALID_PARAMETER;
     5580            }
     5581
     5582            cbBuffer = RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[pRender->AllocationListSize]);
     5583            if (cbBuffer > 4096)
     5584            {
     5585                /* this should not be bigger actually */
     5586                WARN(("too big command buffer %d", cbBuffer));
     5587                return STATUS_INVALID_PARAMETER;
     5588            }
     5589
     5590            cbCmdDma = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     5591
     5592            if (pRender->DmaBufferPrivateDataSize < cbBuffer)
     5593            {
     5594                WARN(("pRender->DmaBufferPrivateDataSize too small %d, requested %d", pRender->DmaBufferPrivateDataSize, cbBuffer));
     5595                return STATUS_INVALID_PARAMETER;
     5596            }
     5597
     5598            if (pRender->DmaSize < cbCmdDma)
     5599            {
     5600                WARN(("dma buffer %d too small", pRender->DmaSize));
     5601                return STATUS_INVALID_PARAMETER;
     5602            }
     5603
     5604            Assert(pRender->PatchLocationListOutSize == pRender->AllocationListSize);
     5605
     5606            if (pRender->PatchLocationListOutSize < pRender->AllocationListSize)
     5607            {
     5608                WARN(("pRender->PatchLocationListOutSize too small %d, requested %d", pRender->PatchLocationListOutSize, pRender->AllocationListSize));
     5609                return STATUS_INVALID_PARAMETER;
     5610            }
     5611
     5612            PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pUmCmd = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pInputHdr;
     5613            VBOXCMDVBVA_CRCMD* pChromiumCmd = (VBOXCMDVBVA_CRCMD*)pRender->pDmaBufferPrivateData;
     5614
     5615            PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
     5616            PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
     5617            PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
     5618
     5619            pChromiumCmd->Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_CRCMD;
     5620            pChromiumCmd->Hdr.u8Flags = 0;
     5621            pChromiumCmd->Cmd.cBuffers = pRender->AllocationListSize;
     5622
     5623            DXGK_ALLOCATIONLIST *pAllocationList = pRender->pAllocationList;
     5624            VBOXCMDVBVA_CRCMD_BUFFER *pSubmInfo = pChromiumCmd->Cmd.aBuffers;
     5625            PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pSubmUmInfo = pUmCmd->aBufInfos;
     5626
     5627            for (UINT i = 0; i < pRender->AllocationListSize; ++i, ++pRender->pPatchLocationListOut, ++pAllocationList, ++pSubmInfo, ++pSubmUmInfo)
     5628            {
     5629                D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
     5630                PVBOXWDDM_ALLOCATION pAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pAllocationList);
     5631                if (pSubmUmInfo->offData >= pAlloc->AllocData.SurfDesc.cbSize
     5632                        || pSubmUmInfo->cbData > pAlloc->AllocData.SurfDesc.cbSize
     5633                        || pSubmUmInfo->offData + pSubmUmInfo->cbData > pAlloc->AllocData.SurfDesc.cbSize)
     5634                {
     5635                    WARN(("invalid data"));
     5636                    return STATUS_INVALID_PARAMETER;
     5637                }
     5638
     5639                memset(pPLL, 0, sizeof (*pPLL));
     5640
     5641                if (pAllocationList->SegmentId)
     5642                    pSubmInfo->offBuffer = pAllocationList->PhysicalAddress.LowPart + pSubmUmInfo->offData;
     5643
     5644                pSubmInfo->cbBuffer = pSubmUmInfo->cbData;
     5645
     5646                pPLL->AllocationIndex = i;
     5647                pPLL->PatchOffset = RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[i].offBuffer);
     5648                pPLL->AllocationOffset = pSubmUmInfo->offData;
     5649            }
     5650
     5651            break;
     5652        }
     5653        case VBOXVDMACMD_TYPE_DMA_NOP:
     5654        {
     5655            cbBuffer = sizeof (VBOXCMDVBVA_HDR);
     5656            cbCmdDma = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     5657
     5658            if (pRender->DmaBufferPrivateDataSize < cbBuffer)
     5659            {
     5660                WARN(("pRender->DmaBufferPrivateDataSize too small %d, requested %d", pRender->DmaBufferPrivateDataSize, cbBuffer));
     5661                return STATUS_INVALID_PARAMETER;
     5662            }
     5663
     5664            if (pRender->DmaSize < cbCmdDma)
     5665            {
     5666                WARN(("dma buffer %d too small", pRender->DmaSize));
     5667                return STATUS_INVALID_PARAMETER;
     5668            }
     5669
     5670            pCmd->u8OpCode = VBOXCMDVBVA_OPTYPE_NOPCMD;
     5671            pCmd->u8Flags = 0;
     5672
     5673            for (UINT i = 0; i < pRender->AllocationListSize; ++i, ++pRender->pPatchLocationListOut)
     5674            {
     5675                D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
     5676                memset(pPLL, 0, sizeof (*pPLL));
     5677                pPLL->AllocationIndex = i;
     5678                pPLL->PatchOffset = ~0UL;
     5679                pPLL->AllocationOffset = 0;
     5680            }
     5681
     5682            break;
     5683        }
     5684        default:
     5685        {
     5686            WARN(("unsupported render command %d", pInputHdr->enmCmd));
     5687            return STATUS_INVALID_PARAMETER;
     5688        }
     5689    }
     5690
     5691    pRender->pDmaBufferPrivateData = ((uint8_t*)pRender->pDmaBufferPrivateData) + cbBuffer;
     5692    pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + cbCmdDma;
     5693
     5694    pCmd->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
     5695    /* sanity */
     5696    pCmd->u32FenceID = 0;
     5697
     5698//    LOGF(("LEAVE, hContext(0x%x)", hContext));
     5699
     5700    return STATUS_SUCCESS;
     5701}
     5702
     5703
     5704static NTSTATUS
     5705APIENTRY
     5706DxgkDdiRenderLegacy(
    52595707    CONST HANDLE  hContext,
    52605708    DXGKARG_RENDER  *pRender)
     
    52835731    switch (pInputHdr->enmCmd)
    52845732    {
    5285         case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
    5286         {
    5287             if (pRender->CommandLength != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pInputHdr->u32CmdReserved]))
    5288             {
    5289                 Assert(0);
    5290                 return STATUS_INVALID_PARAMETER;
    5291             }
    5292             PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pUmCmd = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pInputHdr;
    5293             PVBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD pChromiumCmd = (PVBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD)pRender->pDmaBufferPrivateData;
    5294             const uint32_t cbDma = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD, aBufInfos[pInputHdr->u32CmdReserved]);
    5295             if (pRender->DmaBufferPrivateDataSize < cbDma)
    5296             {
    5297                 Assert(0);
    5298                 return STATUS_INVALID_PARAMETER;
    5299             }
    5300             if (pRender->DmaSize < cbDma)
    5301             {
    5302                 Assert(0);
    5303                 return STATUS_INVALID_PARAMETER;
    5304             }
    5305 
    5306             if (pRender->PatchLocationListOutSize < pInputHdr->u32CmdReserved)
    5307             {
    5308                 Assert(0);
    5309                 return STATUS_INVALID_PARAMETER;
    5310             }
    5311 
    5312             PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
    5313             PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
    5314             PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
    5315 
    5316             pChromiumCmd->Base.enmCmd = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
    5317             pChromiumCmd->Base.u32CmdReserved = pInputHdr->u32CmdReserved;
    5318             pRender->pDmaBufferPrivateData = (uint8_t*)pRender->pDmaBufferPrivateData + cbDma;
    5319             pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + cbDma;
    5320             D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
    5321             memset(pPLL, 0, sizeof (*pPLL) * pChromiumCmd->Base.u32CmdReserved);
    5322             pRender->pPatchLocationListOut += pInputHdr->u32CmdReserved;
    5323             PVBOXWDDM_UHGSMI_BUFFER_SUBMIT_INFO pSubmInfo = pChromiumCmd->aBufInfos;
    5324             PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pSubmUmInfo = pUmCmd->aBufInfos;
    5325             DXGK_ALLOCATIONLIST *pAllocationList = pRender->pAllocationList;
    5326             for (UINT i = 0; i < pChromiumCmd->Base.u32CmdReserved; ++i)
    5327             {
    5328                 PVBOXWDDM_ALLOCATION pAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pAllocationList);
    5329                 vboxWddmPopulateDmaAllocInfoWithOffset(&pSubmInfo->Alloc, pAlloc, pAllocationList, pSubmUmInfo->offData);
    5330 
    5331                 pSubmInfo->cbData = pSubmUmInfo->cbData;
    5332                 pSubmInfo->bDoNotSignalCompletion = pSubmUmInfo->bDoNotSignalCompletion;
    5333 
    5334                 pPLL->AllocationIndex = i;
    5335                 pPLL->PatchOffset = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD, aBufInfos[i].Alloc);
    5336                 pPLL->AllocationOffset = pSubmUmInfo->offData;
    5337 
    5338                 ++pPLL;
    5339                 ++pSubmInfo;
    5340                 ++pSubmUmInfo;
    5341                 ++pAllocationList;
    5342             }
    5343 
    5344             break;
    5345         }
    53465733        case VBOXVDMACMD_TYPE_DMA_NOP:
    53475734        {
     
    53595746        }
    53605747        default:
     5748        {
     5749            WARN(("unsupported command %d", pInputHdr->enmCmd));
    53615750            return STATUS_INVALID_PARAMETER;
     5751        }
    53625752    }
    53635753
     
    54035793}
    54045794
     5795DECLINLINE(bool) VBoxCVDdiFillAllocInfo(VBOXCMDVBVA_HDR* pHdr,
     5796        VBOXCMDVBVA_ALLOCINFO *pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pList, bool fDst)
     5797{
     5798    if (pAlloc->AllocData.hostID)
     5799    {
     5800        pHdr->u8Flags |= (fDst ? VBOXCMDVBVA_OPF_ALLOC_DSTID : VBOXCMDVBVA_OPF_ALLOC_SRCID);
     5801        pInfo->id = pAlloc->AllocData.hostID;
     5802        return false;
     5803    }
     5804
     5805    Assert(!pList->PhysicalAddress.HighPart);
     5806    pInfo->offVRAM = pList->PhysicalAddress.LowPart;
     5807    return true;
     5808}
     5809
    54055810/**
    54065811 * DxgkDdiPresent
    54075812 */
    5408 NTSTATUS
     5813static NTSTATUS
    54095814APIENTRY
    5410 DxgkDdiPresent(
     5815DxgkDdiPresentNew(
     5816    CONST HANDLE  hContext,
     5817    DXGKARG_PRESENT  *pPresent)
     5818{
     5819    PAGED_CODE();
     5820
     5821//    LOGF(("ENTER, hContext(0x%x)", hContext));
     5822
     5823    vboxVDbgBreakFv();
     5824
     5825    PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
     5826    PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
     5827    PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
     5828
     5829    if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
     5830    {
     5831        WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
     5832        /* @todo: can this actually happen? what status to return? */
     5833        return STATUS_INVALID_PARAMETER;
     5834    }
     5835
     5836    VBOXCMDVBVA_HDR* pHdr = (VBOXCMDVBVA_HDR*)pPresent->pDmaBufferPrivateData;
     5837
     5838    UINT u32SrcPatch = ~0UL;
     5839    UINT u32DstPatch = ~0UL;
     5840    BOOLEAN fPatchSrc = false;
     5841    BOOLEAN fPatchDst = false;
     5842    VBOXCMDVBVA_RECT *paRects = NULL;
     5843    uint32_t cbMaxRects;
     5844
     5845    if (pPresent->DmaSize < VBOXWDDM_DUMMY_DMABUFFER_SIZE)
     5846    {
     5847        WARN(("Present->DmaSize(%d) < VBOXWDDM_DUMMY_DMABUFFER_SIZE (%d)", pPresent->DmaSize , VBOXWDDM_DUMMY_DMABUFFER_SIZE));
     5848        /* @todo: can this actually happen? what status to return? */
     5849        return STATUS_INVALID_PARAMETER;
     5850    }
     5851
     5852    if (pPresent->Flags.Blt)
     5853    {
     5854        Assert(pPresent->Flags.Value == 1); /* only Blt is set, we do not support anything else for now */
     5855        DXGK_ALLOCATIONLIST *pSrc =  &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
     5856        DXGK_ALLOCATIONLIST *pDst =  &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
     5857        PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
     5858        if (!pSrcAlloc)
     5859        {
     5860            /* this should not happen actually */
     5861            WARN(("failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
     5862            return STATUS_INVALID_HANDLE;
     5863        }
     5864
     5865        PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
     5866        if (!pDstAlloc)
     5867        {
     5868            /* this should not happen actually */
     5869            WARN(("failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
     5870            return STATUS_INVALID_HANDLE;
     5871        }
     5872
     5873        fPatchSrc = TRUE;
     5874        fPatchDst = TRUE;
     5875
     5876        BOOLEAN fDstPrimary = (!pDstAlloc->AllocData.hostID
     5877                && pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
     5878                && pDstAlloc->bAssigned);
     5879        BOOLEAN fSrcPrimary = (!pSrcAlloc->AllocData.hostID
     5880                && pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
     5881                && pSrcAlloc->bAssigned);
     5882
     5883        pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID;
     5884        pHdr->u8Flags = 0;
     5885
     5886        if (fDstPrimary || fSrcPrimary)
     5887        {
     5888            if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_BLT_PRIMARY))
     5889            {
     5890                WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_BLT_PRIMARY (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_BLT_PRIMARY)));
     5891                /* @todo: can this actually happen? what status to return? */
     5892                return STATUS_INVALID_PARAMETER;
     5893            }
     5894
     5895            VBOXCMDVBVA_BLT_PRIMARY *pBlt = (VBOXCMDVBVA_BLT_PRIMARY*)pHdr;
     5896
     5897            /* this is the most common case, so we optimize it a bit with VBOXCMDVBVA_BLT_PRIMARY */
     5898
     5899            if (fSrcPrimary)
     5900            {
     5901                pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY;
     5902                pBlt->Hdr.u8PrimaryID = pSrcAlloc->AllocData.SurfDesc.VidPnSourceId;
     5903
     5904                if (fDstPrimary)
     5905                {
     5906                    pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY;
     5907                    pBlt->alloc.id = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
     5908                }
     5909                else if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->alloc, pDstAlloc, pDst, true))
     5910                    u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, alloc.offVRAM);
     5911            }
     5912            else
     5913            {
     5914                Assert(fDstPrimary);
     5915                pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY;
     5916                pBlt->Hdr.u8PrimaryID = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
     5917
     5918                if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->alloc, pSrcAlloc, pSrc, false))
     5919                    u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, alloc.offVRAM);
     5920            }
     5921
     5922            paRects = pBlt->aRects;
     5923            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects);
     5924        }
     5925        else
     5926        {
     5927            if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID))
     5928            {
     5929                WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID)));
     5930                /* @todo: can this actually happen? what status to return? */
     5931                return STATUS_INVALID_PARAMETER;
     5932            }
     5933
     5934            VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID *pBlt = (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID*)pHdr;
     5935
     5936            if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->src, pSrcAlloc, pSrc, false))
     5937                u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, src.offVRAM);
     5938
     5939            if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->dst, pDstAlloc, pDst, true))
     5940                u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, dst.offVRAM);
     5941
     5942            paRects = pBlt->aRects;
     5943            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects);
     5944        }
     5945    }
     5946    else if (pPresent->Flags.Flip)
     5947    {
     5948        if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_FLIP))
     5949        {
     5950            WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_FLIP (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_FLIP)));
     5951            /* @todo: can this actually happen? what status to return? */
     5952            return STATUS_INVALID_PARAMETER;
     5953        }
     5954
     5955        fPatchSrc = TRUE;
     5956
     5957        Assert(pPresent->Flags.Value == 4); /* only Blt is set, we do not support anything else for now */
     5958        Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
     5959        DXGK_ALLOCATIONLIST *pSrc =  &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
     5960        PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
     5961
     5962        if (!pSrcAlloc)
     5963        {
     5964            /* this should not happen actually */
     5965            WARN(("failed to get pSrc Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
     5966            return STATUS_INVALID_HANDLE;
     5967        }
     5968
     5969        Assert(pDevExt->cContexts3D);
     5970        pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_FLIP;
     5971        pHdr->u8Flags = 0;
     5972        VBOXCMDVBVA_FLIP *pFlip = (VBOXCMDVBVA_FLIP*)pHdr;
     5973
     5974        if (VBoxCVDdiFillAllocInfo(pHdr, &pFlip->src, pSrcAlloc, pSrc, false))
     5975            u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_FLIP, src.offVRAM);
     5976    }
     5977    else if (pPresent->Flags.ColorFill)
     5978    {
     5979        if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_CLRFILL))
     5980        {
     5981            WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_CLRFILL (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_CLRFILL)));
     5982            /* @todo: can this actually happen? what status to return? */
     5983            return STATUS_INVALID_PARAMETER;
     5984        }
     5985
     5986        fPatchDst = TRUE;
     5987
     5988        Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_2D);
     5989        Assert(pPresent->Flags.Value == 2); /* only ColorFill is set, we do not support anything else for now */
     5990        DXGK_ALLOCATIONLIST *pDst =  &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
     5991        PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
     5992        if (!pDstAlloc)
     5993        {
     5994            /* this should not happen actually */
     5995            WARN(("failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
     5996            return STATUS_INVALID_HANDLE;
     5997        }
     5998
     5999        pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_CLRFILL;
     6000        pHdr->u8Flags = 0;
     6001        VBOXCMDVBVA_CLRFILL *pCFill = (VBOXCMDVBVA_CLRFILL*)pHdr;
     6002
     6003        if (VBoxCVDdiFillAllocInfo(pHdr, &pCFill->dst, pDstAlloc, pDst, true))
     6004            u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, dst.offVRAM);
     6005
     6006        paRects = pCFill->aRects;
     6007        cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, aRects);
     6008    }
     6009    else
     6010    {
     6011        WARN(("cmd NOT IMPLEMENTED!! Flags(0x%x)", pPresent->Flags.Value));
     6012        return STATUS_NOT_SUPPORTED;
     6013    }
     6014
     6015    if (paRects)
     6016    {
     6017        UINT iStartRect = pPresent->MultipassOffset;
     6018        UINT cMaxRects = cbMaxRects / sizeof (VBOXCMDVBVA_RECT);
     6019        Assert(pPresent->SubRectCnt > iStartRect);
     6020        UINT cRects = pPresent->SubRectCnt - iStartRect;
     6021        if (cRects > cMaxRects)
     6022        {
     6023            pPresent->MultipassOffset += cMaxRects;
     6024            cRects = cMaxRects;
     6025        }
     6026        else
     6027            pPresent->MultipassOffset = 0;
     6028
     6029        const RECT *paDstSubRects = &pPresent->pDstSubRects[iStartRect];
     6030        VBoxCVDdiPackRects(paRects, paDstSubRects, cRects);
     6031    }
     6032
     6033    if (fPatchSrc)
     6034    {
     6035        memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
     6036        pPresent->pPatchLocationListOut->PatchOffset = u32SrcPatch;
     6037        pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
     6038        ++pPresent->pPatchLocationListOut;
     6039    }
     6040
     6041    if (fPatchDst)
     6042    {
     6043        memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
     6044        pPresent->pPatchLocationListOut->PatchOffset = u32DstPatch;
     6045        pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
     6046        ++pPresent->pPatchLocationListOut;
     6047    }
     6048
     6049    pHdr->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
     6050    /* sanity */
     6051    pHdr->u32FenceID = 0;
     6052
     6053    pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     6054
     6055    if (pPresent->MultipassOffset)
     6056        return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
     6057    return STATUS_SUCCESS;
     6058}
     6059
     6060/**
     6061 * DxgkDdiPresent
     6062 */
     6063static NTSTATUS
     6064APIENTRY
     6065DxgkDdiPresentLegacy(
    54116066    CONST HANDLE  hContext,
    54126067    DXGKARG_PRESENT  *pPresent)
     
    54346089    pPrivateData->BaseHdr.fFlags.Value = 0;
    54356090    uint32_t cContexts2D = ASMAtomicReadU32(&pDevExt->cContexts2D);
    5436 #define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof(RECT)
    54376091
    54386092    if (pPresent->Flags.Blt)
     
    62186872    DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
    62196873    DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
    6220     DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
    6221     DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
     6874    DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutineNew;
     6875    DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutineNew;
    62226876    DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
    62236877    DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
     
    62656919#endif
    62666920
    6267 static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
    6268 {
     6921static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath, BOOLEAN fCmdVbva)
     6922{
     6923#define VBOXWDDM_CALLBACK_NAME(_base, _fCmdVbva) ((_fCmdVbva) ? _base##New : _base##Legacy)
     6924
    62696925    DRIVER_INITIALIZATION_DATA DriverInitializationData = {'\0'};
    62706926
     
    62776933    DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
    62786934    DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
    6279     DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
    6280     DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
     6935    DriverInitializationData.DxgkDdiInterruptRoutine = VBOXWDDM_CALLBACK_NAME(DxgkDdiInterruptRoutine, fCmdVbva);
     6936    DriverInitializationData.DxgkDdiDpcRoutine = VBOXWDDM_CALLBACK_NAME(DxgkDdiDpcRoutine, fCmdVbva);
    62816937    DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
    62826938    DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
     
    62976953    DriverInitializationData.DxgkDdiAcquireSwizzlingRange = DxgkDdiAcquireSwizzlingRange;
    62986954    DriverInitializationData.DxgkDdiReleaseSwizzlingRange = DxgkDdiReleaseSwizzlingRange;
    6299     DriverInitializationData.DxgkDdiPatch = DxgkDdiPatch;
    6300     DriverInitializationData.DxgkDdiSubmitCommand = DxgkDdiSubmitCommand;
    6301     DriverInitializationData.DxgkDdiPreemptCommand = DxgkDdiPreemptCommand;
    6302     DriverInitializationData.DxgkDdiBuildPagingBuffer = DxgkDdiBuildPagingBuffer;
     6955    DriverInitializationData.DxgkDdiPatch = VBOXWDDM_CALLBACK_NAME(DxgkDdiPatch, fCmdVbva);
     6956    DriverInitializationData.DxgkDdiSubmitCommand = VBOXWDDM_CALLBACK_NAME(DxgkDdiSubmitCommand, fCmdVbva);
     6957    DriverInitializationData.DxgkDdiPreemptCommand = VBOXWDDM_CALLBACK_NAME(DxgkDdiPreemptCommand, fCmdVbva);
     6958    DriverInitializationData.DxgkDdiBuildPagingBuffer = VBOXWDDM_CALLBACK_NAME(DxgkDdiBuildPagingBuffer, fCmdVbva);
    63036959    DriverInitializationData.DxgkDdiSetPalette = DxgkDdiSetPalette;
    63046960    DriverInitializationData.DxgkDdiSetPointerPosition = DxgkDdiSetPointerPosition;
     
    63086964    DriverInitializationData.DxgkDdiEscape = DxgkDdiEscape;
    63096965    DriverInitializationData.DxgkDdiCollectDbgInfo = DxgkDdiCollectDbgInfo;
    6310     DriverInitializationData.DxgkDdiQueryCurrentFence = DxgkDdiQueryCurrentFence;
     6966    DriverInitializationData.DxgkDdiQueryCurrentFence = VBOXWDDM_CALLBACK_NAME(DxgkDdiQueryCurrentFence, fCmdVbva);
    63116967    DriverInitializationData.DxgkDdiIsSupportedVidPn = DxgkDdiIsSupportedVidPn;
    63126968    DriverInitializationData.DxgkDdiRecommendFunctionalVidPn = DxgkDdiRecommendFunctionalVidPn;
     
    63266982    DriverInitializationData.DxgkDdiOpenAllocation = DxgkDdiOpenAllocation;
    63276983    DriverInitializationData.DxgkDdiCloseAllocation = DxgkDdiCloseAllocation;
    6328     DriverInitializationData.DxgkDdiRender = DxgkDdiRender;
    6329     DriverInitializationData.DxgkDdiPresent = DxgkDdiPresent;
     6984    DriverInitializationData.DxgkDdiRender = VBOXWDDM_CALLBACK_NAME(DxgkDdiRender, fCmdVbva);
     6985    DriverInitializationData.DxgkDdiPresent = VBOXWDDM_CALLBACK_NAME(DxgkDdiPresent, fCmdVbva);
    63306986
    63316987    DriverInitializationData.DxgkDdiUpdateOverlay = DxgkDdiUpdateOverlay;
     
    64677123#endif
    64687124                {
    6469                     Status = vboxWddmInitFullGraphicsDriver(DriverObject, RegistryPath);
     7125                    Status = vboxWddmInitFullGraphicsDriver(DriverObject, RegistryPath, !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_CMDVBVA));
    64707126                }
    64717127
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h

    r48070 r49591  
    128128DECLINLINE(void) vboxWddmAssignShadow(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
    129129{
     130    if (pDevExt->fCmdVbvaEnabled)
     131    {
     132        WARN(("Trying to assign shadow surface for CmdVbva enabled mode!"));
     133        return;
     134    }
     135
    130136    if (pSource->pShadowAllocation == pAllocation && pSource->fGhSynced > 0)
    131137    {
     
    221227
    222228#define VBOXWDDMENTRY_2_SWAPCHAIN(_pE) ((PVBOXWDDM_SWAPCHAIN)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_SWAPCHAIN, DevExtListEntry)))
     229
     230BOOLEAN DxgkDdiInterruptRoutineNew(
     231    IN CONST PVOID MiniportDeviceContext,
     232    IN ULONG MessageNumber
     233    );
    223234
    224235#ifdef VBOX_WDDM_WIN8
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_protocol.h

    r49476 r49591  
    2525/* new TexPresent mechanism is available */
    2626#define CR_VBOX_CAP_TEX_PRESENT    0x00000001
    27 /* no DWM support available, required for Win8 guests to switch to display-only mode gracefully */
    28 #define CR_VBOX_CAP_NO_DWM_SUPPORT 0x00000002
     27/* vbva command submission mechanism supported */
     28#define CR_VBOX_CAP_CMDVBVA        0x00000002
    2929
    3030
     
    9999#ifdef VBOX_WITH_CRHGSMI
    100100typedef struct CRVBOXHGSMI_CMDDATA {
    101     struct VBOXVDMACMD_CHROMIUM_CMD *pCmd;
     101    union
     102    {
     103        struct VBOXVDMACMD_CHROMIUM_CMD *pHgsmiCmd;
     104        struct VBOXCMDVBVA_CRCMD_CMD *pVbvaCmd;
     105        void *pvCmd;
     106    };
    102107    int          *pCmdRc;
    103108    char         *pWriteback;
    104109    unsigned int *pcbWriteback;
    105110    unsigned int cbWriteback;
    106     bool fCompleteNeeded;
     111    bool fHgsmiCmd;
    107112} CRVBOXHGSMI_CMDDATA, *PCRVBOXHGSMI_CMDDATA;
    108113
    109114#ifdef DEBUG
    110115# define CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData)  do { \
    111         CRASSERT(!(_pData)->pCmd == !(_pData)->pCmdRc); \
     116        CRASSERT(!(_pData)->pvCmd == !(_pData)->pCmdRc); \
    112117        CRASSERT(!(_pData)->pWriteback == !(_pData)->pcbWriteback); \
    113118        CRASSERT(!(_pData)->pWriteback == !(_pData)->cbWriteback); \
    114119        if ((_pData)->pWriteback) \
    115120        { \
    116             CRASSERT((_pData)->pCmd); \
     121            CRASSERT((_pData)->pvCmd); \
    117122        } \
    118123    } while (0)
    119124
    120125# define CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(_pData)  do { \
    121         CRASSERT(!(_pData)->pCmd); \
     126        CRASSERT(!(_pData)->pvCmd); \
    122127        CRASSERT(!(_pData)->pCmdRc); \
    123128        CRASSERT(!(_pData)->pWriteback); \
     
    142147#endif
    143148
    144 #define CRVBOXHGSMI_CMDDATA_IS_COMPLETE_NEEDED(_pData) (!!(_pData)->fCompleteNeeded)
    145 #define CRVBOXHGSMI_CMDDATA_IS_SET(_pData) (!!(_pData)->pCmd)
     149#define CRVBOXHGSMI_CMDDATA_IS_HGSMICMD(_pData) (!!(_pData)->fHgsmiCmd)
     150#define CRVBOXHGSMI_CMDDATA_IS_SET(_pData) (!!(_pData)->pvCmd)
    146151#define CRVBOXHGSMI_CMDDATA_IS_SETWB(_pData) (!!(_pData)->pWriteback)
    147152
     
    152157    } while (0)
    153158
    154 #define CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fCompleteNeeded) do { \
     159#define CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fHgsmiCmd) do { \
    155160        CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(_pData); \
    156         (_pData)->pCmd = (_pCmd); \
     161        (_pData)->pvCmd = (_pCmd); \
    157162        (_pData)->pCmdRc = &(_pHdr)->result; \
    158         (_pData)->fCompleteNeeded = _fCompleteNeeded; \
    159         CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \
    160     } while (0)
    161 
    162 #define CRVBOXHGSMI_CMDDATA_SETWB(_pData, _pCmd, _pHdr, _pWb, _cbWb, _pcbWb, _fCompleteNeeded) do { \
    163         CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fCompleteNeeded); \
     163        (_pData)->fHgsmiCmd = (_fHgsmiCmd); \
     164        CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \
     165    } while (0)
     166
     167#define CRVBOXHGSMI_CMDDATA_SETWB(_pData, _pCmd, _pHdr, _pWb, _cbWb, _pcbWb, _fHgsmiCmd) do { \
     168        CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fHgsmiCmd); \
    164169        (_pData)->pWriteback = (_pWb); \
    165170        (_pData)->pcbWriteback = (_pcbWb); \
  • trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c

    r49088 r49591  
    196196    CR_VBOXHGCM_MEMORY,
    197197    CR_VBOXHGCM_MEMORY_BIG
    198 #ifdef RT_OS_WINDOWS
    199     ,CR_VBOXHGCM_DDRAW_SURFACE
    200 #endif
    201198#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
    202199    ,CR_VBOXHGCM_UHGSMI_BUFFER
     
    221218#endif
    222219    };
    223 #ifdef RT_OS_WINDOWS
    224     LPDIRECTDRAWSURFACE  pDDS;
    225 #endif
    226220} CRVBOXHGCMBUFFER;
    227221
     
    706700                        (unsigned int)sizeof(CRVBOXHGCMBUFFER) + conn->buffer_size);
    707701
    708 #if defined(IN_GUEST) && defined(RT_OS_WINDOWS)
    709         /* Try to start DDRAW on guest side */
    710         if (!g_crvboxhgcm.pDirectDraw && 0)
    711         {
    712             HRESULT hr;
    713 
    714             hr = DirectDrawCreate(NULL, &g_crvboxhgcm.pDirectDraw, NULL);
    715             if (hr != DD_OK)
    716             {
    717                 crWarning("Failed to create DirectDraw interface (%x)\n", hr);
    718                 g_crvboxhgcm.pDirectDraw = NULL;
    719             }
    720             else
    721             {
    722                 hr = IDirectDraw_SetCooperativeLevel(g_crvboxhgcm.pDirectDraw, NULL, DDSCL_NORMAL);
    723                 if (hr != DD_OK)
    724                 {
    725                     crWarning("Failed to SetCooperativeLevel (%x)\n", hr);
    726                     IDirectDraw_Release(g_crvboxhgcm.pDirectDraw);
    727                     g_crvboxhgcm.pDirectDraw = NULL;
    728                 }
    729                 crDebug("Created DirectDraw and set CooperativeLevel successfully\n");
    730             }
    731         }
    732 
    733         /* Try to allocate buffer via DDRAW */
    734         if (g_crvboxhgcm.pDirectDraw)
    735         {
    736             DDSURFACEDESC       ddsd;
    737             HRESULT             hr;
    738             LPDIRECTDRAWSURFACE lpDDS;
    739 
    740             memset(&ddsd, 0, sizeof(ddsd));
    741             ddsd.dwSize  = sizeof(ddsd);
    742 
    743             /* @todo DDSCAPS_VIDEOMEMORY ain't working for some reason
    744              * also, it would be better to request dwLinearSize but it fails too
    745              * ddsd.dwLinearSize = sizeof(CRVBOXHGCMBUFFER) + conn->buffer_size;
    746              */
    747 
    748             ddsd.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
    749             ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    750             /* use 1 byte per pixel format */
    751             ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
    752             ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
    753             ddsd.ddpfPixelFormat.dwRGBBitCount = 8;
    754             ddsd.ddpfPixelFormat.dwRBitMask = 0xFF;
    755             ddsd.ddpfPixelFormat.dwGBitMask = 0;
    756             ddsd.ddpfPixelFormat.dwBBitMask = 0;
    757             /* request given buffer size, rounded to 1k */
    758             ddsd.dwWidth = 1024;
    759             ddsd.dwHeight = (sizeof(CRVBOXHGCMBUFFER) + conn->buffer_size + ddsd.dwWidth-1)/ddsd.dwWidth;
    760 
    761             hr = IDirectDraw_CreateSurface(g_crvboxhgcm.pDirectDraw, &ddsd, &lpDDS, NULL);
    762             if (hr != DD_OK)
    763             {
    764                 crWarning("Failed to create DirectDraw surface (%x)\n", hr);
    765             }
    766             else
    767             {
    768                 crDebug("Created DirectDraw surface (%x)\n", lpDDS);
    769 
    770                 hr = IDirectDrawSurface_Lock(lpDDS, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
    771                 if (hr != DD_OK)
    772                 {
    773                     crWarning("Failed to lock DirectDraw surface (%x)\n", hr);
    774                     IDirectDrawSurface_Release(lpDDS);
    775                 }
    776                 else
    777                 {
    778                     uint32_t cbLocked;
    779                     cbLocked = (ddsd.dwFlags & DDSD_LINEARSIZE) ? ddsd.dwLinearSize : ddsd.lPitch*ddsd.dwHeight;
    780 
    781                     crDebug("Locked %d bytes DirectDraw surface\n", cbLocked);
    782 
    783                     buf = (CRVBOXHGCMBUFFER *) ddsd.lpSurface;
    784                     CRASSERT(buf);
    785                     buf->magic = CR_VBOXHGCM_BUFFER_MAGIC;
    786                     buf->kind  = CR_VBOXHGCM_DDRAW_SURFACE;
    787                     buf->allocated = cbLocked;
    788                     buf->pDDS = lpDDS;
    789                 }
    790             }
    791         }
    792 #endif
    793 
    794702        /* We're either on host side, or we failed to allocate DDRAW buffer */
    795703        if (!buf)
     
    801709            buf->kind  = CR_VBOXHGCM_MEMORY;
    802710            buf->allocated = conn->buffer_size;
    803 #ifdef RT_OS_WINDOWS
    804             buf->pDDS = NULL;
    805 #endif
    806711        }
    807712    }
     
    945850    parms.hdr.cParms      = SHCRGL_CPARMS_WRITE_READ;
    946851
    947     //if (bufferKind != CR_VBOXHGCM_DDRAW_SURFACE)
    948     {
    949         parms.pBuffer.type                   = VMMDevHGCMParmType_LinAddr_In;
    950         parms.pBuffer.u.Pointer.size         = len;
    951         parms.pBuffer.u.Pointer.u.linearAddr = (uintptr_t) buf;
    952     }
    953     /*else ///@todo it fails badly, have to check why. bird: This fails because buf isn't a physical address?
    954     {
    955         parms.pBuffer.type                 = VMMDevHGCMParmType_PhysAddr;
    956         parms.pBuffer.u.Pointer.size       = len;
    957         parms.pBuffer.u.Pointer.u.physAddr = (uintptr_t) buf;
    958     }*/
     852    parms.pBuffer.type                   = VMMDevHGCMParmType_LinAddr_In;
     853    parms.pBuffer.u.Pointer.size         = len;
     854    parms.pBuffer.u.Pointer.u.linearAddr = (uintptr_t) buf;
    959855
    960856    CRASSERT(!conn->pBuffer); //make sure there's no data to process
     
    12031099    {
    12041100        case CR_VBOXHGCM_MEMORY:
    1205 #ifdef RT_OS_WINDOWS
    1206         case CR_VBOXHGCM_DDRAW_SURFACE:
    1207 #endif
    12081101#ifdef CHROMIUM_THREADSAFE
    12091102            crLockMutex(&g_crvboxhgcm.mutex);
     
    12841177    {
    12851178        /* we should NEVER have redir_ptr disabled with HGSMI command now */
    1286         CRASSERT(!conn->CmdData.pCmd);
     1179        CRASSERT(!conn->CmdData.pvCmd);
    12871180        if ( len <= conn->buffer_size )
    12881181        {
     
    12991192            hgcm_buffer->kind      = CR_VBOXHGCM_MEMORY_BIG;
    13001193            hgcm_buffer->allocated = sizeof(CRVBOXHGCMBUFFER) + len;
    1301 # ifdef RT_OS_WINDOWS
    1302             hgcm_buffer->pDDS      = NULL;
    1303 # endif
    13041194        }
    13051195
     
    24212311void crVBoxHGCMBufferFree(void *data)
    24222312{
    2423 #ifdef RT_OS_WINDOWS
    2424     LPDIRECTDRAWSURFACE lpDDS;
    2425 #endif
    24262313    CRVBOXHGCMBUFFER *hgcm_buffer = (CRVBOXHGCMBUFFER *) data;
    24272314
     
    24332320            crFree( hgcm_buffer );
    24342321            break;
    2435 #ifdef RT_OS_WINDOWS
    2436         case CR_VBOXHGCM_DDRAW_SURFACE:
    2437             lpDDS = hgcm_buffer->pDDS;
    2438             CRASSERT(lpDDS);
    2439             IDirectDrawSurface_Unlock(lpDDS, NULL);
    2440             IDirectDrawSurface_Release(lpDDS);
    2441             crDebug("DDraw surface freed (%x)\n", lpDDS);
    2442             break;
    2443 #endif
    24442322        case CR_VBOXHGCM_MEMORY_BIG:
    24452323            crFree( hgcm_buffer );
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h

    r49474 r49591  
    4242
    4343#define VBOXCRHGSMI_CMD_COMPLETE(_pData, _rc) do { \
     44        Assert(CRVBOXHGSMI_CMDDATA_IS_HGSMICMD(_pData)); \
    4445        CRVBOXHGSMI_CMDDATA_ASSERT_ISSET(_pData); \
    4546        CRVBOXHGSMI_CMDDATA_RC(_pData, _rc); \
    46         crServerCrHgsmiCmdComplete((_pData)->pCmd, VINF_SUCCESS); \
     47        crServerCrHgsmiCmdComplete((_pData)->pHgsmiCmd, VINF_SUCCESS); \
    4748    } while (0)
    4849
    4950#define VBOXCRHGSMI_CMD_CHECK_COMPLETE(_pData, _rc) do { \
    50         if (CRVBOXHGSMI_CMDDATA_IS_COMPLETE_NEEDED(_pData) && CRVBOXHGSMI_CMDDATA_IS_SET(_pData)) { \
     51        Assert(CRVBOXHGSMI_CMDDATA_IS_HGSMICMD(_pData)); \
     52        if (CRVBOXHGSMI_CMDDATA_IS_SET(_pData)) { \
    5153            VBOXCRHGSMI_CMD_COMPLETE(_pData, _rc); \
    5254        } \
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c

    r48793 r49591  
    247247    {
    248248        cr_server.u32Caps = crServerVBoxParseNumerics(env, 0);
    249         cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_NO_DWM_SUPPORT*/);
     249        cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT | CR_VBOX_CAP_CMDVBVA);
    250250    }
    251251    else
    252252    {
    253         cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_NO_DWM_SUPPORT*/;
     253        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_CMDVBVA*/;
     254#ifdef DEBUG_misha
     255        cr_server.u32Caps |= CR_VBOX_CAP_CMDVBVA;
     256#endif
     257
    254258    }
    255259
     
    411415    {
    412416        cr_server.u32Caps = crServerVBoxParseNumerics(env, 0);
    413         cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_NO_DWM_SUPPORT*/);
     417        cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT | CR_VBOX_CAP_CMDVBVA);
    414418    }
    415419    else
    416420    {
    417         cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_NO_DWM_SUPPORT*/;
     421        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT/* | CR_VBOX_CAP_CMDVBVA*/;
     422#ifdef DEBUG_misha
     423        cr_server.u32Caps |= CR_VBOX_CAP_CMDVBVA;
     424#endif
    418425    }
    419426
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r49476 r49591  
    30563056 * NOTE: it is ALWAYS responsibility of the crVBoxServerCrHgsmiCmd to complete the command!
    30573057 * */
    3058 static int32_t crVBoxServerCrHgsmiCmdProcess(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, bool fCompleteNeeded)
     3058static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd)
    30593059{
    30603060    int32_t rc;
     
    30703070    {
    30713071        crWarning("g_pvVRamBase is not initialized");
    3072         if (!fCompleteNeeded)
    3073             return VERR_INVALID_STATE;
    3074 
    3075         crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_STATE);
    3076         return VINF_SUCCESS;
     3072        return VERR_INVALID_STATE;
    30773073    }
    30783074
     
    30803076    {
    30813077        crWarning("zero buffers passed in!");
    3082         if (!fCompleteNeeded)
    3083             return VERR_INVALID_PARAMETER;
    3084 
    3085         crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
    3086         return VINF_SUCCESS;
     3078        return VERR_INVALID_PARAMETER;
    30873079    }
    30883080
     
    30943086    {
    30953087        crWarning("invalid header buffer!");
    3096         if (!fCompleteNeeded)
    3097             return VERR_INVALID_PARAMETER;
    3098 
    3099         crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
    3100         return VINF_SUCCESS;
     3088        return VERR_INVALID_PARAMETER;
    31013089    }
    31023090
     
    31043092    {
    31053093        crWarning("invalid header buffer size!");
    3106         if (!fCompleteNeeded)
    3107             return VERR_INVALID_PARAMETER;
    3108 
    3109         crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
    3110         return VINF_SUCCESS;
     3094        return VERR_INVALID_PARAMETER;
    31113095    }
    31123096
     
    31243108            {
    31253109                CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
    3126                 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
     3110                VBOXCMDVBVA_CRCMD_BUFFER *pBuf = &pCmd->aBuffers[1];
    31273111                /* Fetch parameters. */
    31283112                uint32_t cbBuffer = pBuf->cbBuffer;
     
    31563140                pClient->conn->pBuffer = pBuffer;
    31573141                pClient->conn->cbBuffer = cbBuffer;
    3158                 CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, fCompleteNeeded);
     3142                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, false);
    31593143                rc = crVBoxServerInternalClientWriteRead(pClient);
    31603144                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     
    31803164                /* Fetch parameters. */
    31813165                uint32_t u32InjectClientID = pFnCmd->u32ClientID;
    3182                 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
     3166                VBOXCMDVBVA_CRCMD_BUFFER *pBuf = &pCmd->aBuffers[1];
    31833167                uint32_t cbBuffer = pBuf->cbBuffer;
    31843168                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
     
    32113195                pClient->conn->pBuffer = pBuffer;
    32123196                pClient->conn->cbBuffer = cbBuffer;
    3213                 CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, fCompleteNeeded);
     3197                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, false);
     3198                rc = crVBoxServerInternalClientWriteRead(pClient);
     3199                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     3200                return rc;
     3201            }
     3202
     3203            crWarning("invalid number of args");
     3204            rc = VERR_INVALID_PARAMETER;
     3205            break;
     3206        }
     3207
     3208        case SHCRGL_GUEST_FN_READ:
     3209        {
     3210            Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
     3211
     3212            /* @todo: Verify  */
     3213            if (cParams == 1)
     3214            {
     3215                CRVBOXHGSMIREAD *pFnCmd = (CRVBOXHGSMIREAD*)pHdr;
     3216                VBOXCMDVBVA_CRCMD_BUFFER *pBuf = &pCmd->aBuffers[1];
     3217                /* Fetch parameters. */
     3218                uint32_t cbBuffer = pBuf->cbBuffer;
     3219                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
     3220
     3221                if (cbHdr < sizeof (*pFnCmd))
     3222                {
     3223                    crWarning("invalid read cmd buffer size!");
     3224                    rc = VERR_INVALID_PARAMETER;
     3225                    break;
     3226                }
     3227
     3228
     3229                if (!pBuffer)
     3230                {
     3231                    crWarning("invalid buffer data received from guest!");
     3232                    rc = VERR_INVALID_PARAMETER;
     3233                    break;
     3234                }
     3235
     3236                rc = crVBoxServerClientGet(u32ClientID, &pClient);
     3237                if (RT_FAILURE(rc))
     3238                {
     3239                    break;
     3240                }
     3241
     3242                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     3243
     3244                rc = crVBoxServerInternalClientRead(pClient, pBuffer, &cbBuffer);
     3245
     3246                /* Return the required buffer size always */
     3247                pFnCmd->cbBuffer = cbBuffer;
     3248
     3249                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     3250
     3251                /* the read command is never pended, complete it right away */
     3252                pHdr->result = rc;
     3253
     3254                return VINF_SUCCESS;
     3255            }
     3256
     3257            crWarning("invalid number of args");
     3258            rc = VERR_INVALID_PARAMETER;
     3259            break;
     3260        }
     3261
     3262        case SHCRGL_GUEST_FN_WRITE_READ:
     3263        {
     3264            Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
     3265
     3266            /* @todo: Verify  */
     3267            if (cParams == 2)
     3268            {
     3269                CRVBOXHGSMIWRITEREAD *pFnCmd = (CRVBOXHGSMIWRITEREAD*)pHdr;
     3270                VBOXCMDVBVA_CRCMD_BUFFER *pBuf = &pCmd->aBuffers[1];
     3271                VBOXCMDVBVA_CRCMD_BUFFER *pWbBuf = &pCmd->aBuffers[2];
     3272
     3273                /* Fetch parameters. */
     3274                uint32_t cbBuffer = pBuf->cbBuffer;
     3275                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
     3276
     3277                uint32_t cbWriteback = pWbBuf->cbBuffer;
     3278                char *pWriteback  = VBOXCRHGSMI_PTR_SAFE(pWbBuf->offBuffer, cbWriteback, char);
     3279
     3280                if (cbHdr < sizeof (*pFnCmd))
     3281                {
     3282                    crWarning("invalid write_read cmd buffer size!");
     3283                    rc = VERR_INVALID_PARAMETER;
     3284                    break;
     3285                }
     3286
     3287
     3288                CRASSERT(cbBuffer);
     3289                if (!pBuffer)
     3290                {
     3291                    crWarning("invalid write buffer data received from guest!");
     3292                    rc = VERR_INVALID_PARAMETER;
     3293                    break;
     3294                }
     3295
     3296                CRASSERT(cbWriteback);
     3297                if (!pWriteback)
     3298                {
     3299                    crWarning("invalid writeback buffer data received from guest!");
     3300                    rc = VERR_INVALID_PARAMETER;
     3301                    break;
     3302                }
     3303                rc = crVBoxServerClientGet(u32ClientID, &pClient);
     3304                if (RT_FAILURE(rc))
     3305                {
     3306                    pHdr->result = rc;
     3307                    return VINF_SUCCESS;
     3308                }
     3309
     3310                /* This should never fire unless we start to multithread */
     3311                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
     3312                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     3313
     3314                pClient->conn->pBuffer = pBuffer;
     3315                pClient->conn->cbBuffer = cbBuffer;
     3316                CRVBOXHGSMI_CMDDATA_SETWB(&pClient->conn->CmdData, pCmd, pHdr, pWriteback, cbWriteback, &pFnCmd->cbWriteback, false);
     3317                rc = crVBoxServerInternalClientWriteRead(pClient);
     3318                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     3319                return rc;
     3320            }
     3321
     3322            crWarning("invalid number of args");
     3323            rc = VERR_INVALID_PARAMETER;
     3324            break;
     3325        }
     3326
     3327        case SHCRGL_GUEST_FN_SET_VERSION:
     3328        {
     3329            crWarning("invalid function");
     3330            rc = VERR_NOT_IMPLEMENTED;
     3331            break;
     3332        }
     3333
     3334        case SHCRGL_GUEST_FN_SET_PID:
     3335        {
     3336            crWarning("invalid function");
     3337            rc = VERR_NOT_IMPLEMENTED;
     3338            break;
     3339        }
     3340
     3341        default:
     3342        {
     3343            crWarning("invalid function");
     3344            rc = VERR_NOT_IMPLEMENTED;
     3345            break;
     3346        }
     3347
     3348    }
     3349
     3350    /* we can be on fail only here */
     3351    CRASSERT(RT_FAILURE(rc));
     3352    pHdr->result = rc;
     3353
     3354    return rc;
     3355}
     3356
     3357
     3358int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd)
     3359{
     3360
     3361    int32_t rc;
     3362    uint32_t cBuffers = pCmd->cBuffers;
     3363    uint32_t cParams;
     3364    uint32_t cbHdr;
     3365    CRVBOXHGSMIHDR *pHdr;
     3366    uint32_t u32Function;
     3367    uint32_t u32ClientID;
     3368    CRClient *pClient;
     3369
     3370    if (!g_pvVRamBase)
     3371    {
     3372        crWarning("g_pvVRamBase is not initialized");
     3373
     3374        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_STATE);
     3375        return VINF_SUCCESS;
     3376    }
     3377
     3378    if (!cBuffers)
     3379    {
     3380        crWarning("zero buffers passed in!");
     3381
     3382        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
     3383        return VINF_SUCCESS;
     3384    }
     3385
     3386    cParams = cBuffers-1;
     3387
     3388    cbHdr = pCmd->aBuffers[0].cbBuffer;
     3389    pHdr = VBOXCRHGSMI_PTR_SAFE(pCmd->aBuffers[0].offBuffer, cbHdr, CRVBOXHGSMIHDR);
     3390    if (!pHdr)
     3391    {
     3392        crWarning("invalid header buffer!");
     3393
     3394        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
     3395        return VINF_SUCCESS;
     3396    }
     3397
     3398    if (cbHdr < sizeof (*pHdr))
     3399    {
     3400        crWarning("invalid header buffer size!");
     3401
     3402        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
     3403        return VINF_SUCCESS;
     3404    }
     3405
     3406    u32Function = pHdr->u32Function;
     3407    u32ClientID = pHdr->u32ClientID;
     3408
     3409    switch (u32Function)
     3410    {
     3411        case SHCRGL_GUEST_FN_WRITE:
     3412        {
     3413            Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
     3414
     3415            /* @todo: Verify  */
     3416            if (cParams == 1)
     3417            {
     3418                CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
     3419                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
     3420                /* Fetch parameters. */
     3421                uint32_t cbBuffer = pBuf->cbBuffer;
     3422                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
     3423
     3424                if (cbHdr < sizeof (*pFnCmd))
     3425                {
     3426                    crWarning("invalid write cmd buffer size!");
     3427                    rc = VERR_INVALID_PARAMETER;
     3428                    break;
     3429                }
     3430
     3431                CRASSERT(cbBuffer);
     3432                if (!pBuffer)
     3433                {
     3434                    crWarning("invalid buffer data received from guest!");
     3435                    rc = VERR_INVALID_PARAMETER;
     3436                    break;
     3437                }
     3438
     3439                rc = crVBoxServerClientGet(u32ClientID, &pClient);
     3440                if (RT_FAILURE(rc))
     3441                {
     3442                    break;
     3443                }
     3444
     3445                /* This should never fire unless we start to multithread */
     3446                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
     3447                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     3448
     3449                pClient->conn->pBuffer = pBuffer;
     3450                pClient->conn->cbBuffer = cbBuffer;
     3451                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, true);
     3452                rc = crVBoxServerInternalClientWriteRead(pClient);
     3453                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     3454                return rc;
     3455            }
     3456            else
     3457            {
     3458                crWarning("invalid number of args");
     3459                rc = VERR_INVALID_PARAMETER;
     3460                break;
     3461            }
     3462            break;
     3463        }
     3464
     3465        case SHCRGL_GUEST_FN_INJECT:
     3466        {
     3467            Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
     3468
     3469            /* @todo: Verify  */
     3470            if (cParams == 1)
     3471            {
     3472                CRVBOXHGSMIINJECT *pFnCmd = (CRVBOXHGSMIINJECT*)pHdr;
     3473                /* Fetch parameters. */
     3474                uint32_t u32InjectClientID = pFnCmd->u32ClientID;
     3475                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
     3476                uint32_t cbBuffer = pBuf->cbBuffer;
     3477                uint8_t *pBuffer  = VBOXCRHGSMI_PTR_SAFE(pBuf->offBuffer, cbBuffer, uint8_t);
     3478
     3479                if (cbHdr < sizeof (*pFnCmd))
     3480                {
     3481                    crWarning("invalid inject cmd buffer size!");
     3482                    rc = VERR_INVALID_PARAMETER;
     3483                    break;
     3484                }
     3485
     3486                CRASSERT(cbBuffer);
     3487                if (!pBuffer)
     3488                {
     3489                    crWarning("invalid buffer data received from guest!");
     3490                    rc = VERR_INVALID_PARAMETER;
     3491                    break;
     3492                }
     3493
     3494                rc = crVBoxServerClientGet(u32InjectClientID, &pClient);
     3495                if (RT_FAILURE(rc))
     3496                {
     3497                    break;
     3498                }
     3499
     3500                /* This should never fire unless we start to multithread */
     3501                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
     3502                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     3503
     3504                pClient->conn->pBuffer = pBuffer;
     3505                pClient->conn->cbBuffer = cbBuffer;
     3506                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr, true);
    32143507                rc = crVBoxServerInternalClientWriteRead(pClient);
    32153508                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     
    32673560                /* the read command is never pended, complete it right away */
    32683561                pHdr->result = rc;
    3269 
    3270                 if (!fCompleteNeeded)
    3271                     return VINF_SUCCESS;
    32723562
    32733563                crServerCrHgsmiCmdComplete(pCmd, VINF_SUCCESS);
     
    33353625                pClient->conn->pBuffer = pBuffer;
    33363626                pClient->conn->cbBuffer = cbBuffer;
    3337                 CRVBOXHGSMI_CMDDATA_SETWB(&pClient->conn->CmdData, pCmd, pHdr, pWriteback, cbWriteback, &pFnCmd->cbWriteback, fCompleteNeeded);
     3627                CRVBOXHGSMI_CMDDATA_SETWB(&pClient->conn->CmdData, pCmd, pHdr, pWriteback, cbWriteback, &pFnCmd->cbWriteback, true);
    33383628                rc = crVBoxServerInternalClientWriteRead(pClient);
    33393629                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     
    33733663    pHdr->result = rc;
    33743664
    3375     if (!fCompleteNeeded)
    3376         return rc;
    3377 
    33783665    crServerCrHgsmiCmdComplete(pCmd, VINF_SUCCESS);
    33793666    return rc;
    3380 }
    3381 
    3382 int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd)
    3383 {
    3384     return crVBoxServerCrHgsmiCmdProcess(pCmd, true);
     3667
    33853668}
    33863669
     
    34333716        {
    34343717            VBOXCMDVBVA_CRCMD *pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd;
    3435             VBOXCMDVBVAOFFSET offCmd = pCrCmdDr->offCmd;
    3436             if (offCmd < g_cbVRam && offCmd + cbCmd < g_cbVRam)
     3718            VBOXCMDVBVA_CRCMD_CMD *pCrCmd = &pCrCmdDr->Cmd;
     3719            int rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd);
     3720            if (RT_SUCCESS(rc))
    34373721            {
    3438                 VBOXVDMACMD_CHROMIUM_CMD *pCrCmd = (VBOXVDMACMD_CHROMIUM_CMD*)(g_pvVRamBase + offCmd);
    3439                 crVBoxServerCrHgsmiCmdProcess(pCrCmd, false);
    3440                 /* success */
     3722            /* success */
    34413723                pCmd->i8Result = 0;
    34423724            }
    34433725            else
    34443726            {
    3445                 crWarning("incorrect command info!");
     3727                crWarning("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc);
    34463728                pCmd->i8Result = -1;
    34473729            }
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