9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBox WDDM Miniport driver
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2011-2013 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync/* simple handle -> value table API */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmHTableCreate(PVBOXWDDM_HTABLE pTbl, uint32_t cSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->paData = (PVOID*)vboxWddmMemAllocZero(sizeof (pTbl->paData[0]) * cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(VBOXWDDM_HANDLE) vboxWddmHTableIndex2Handle(uint32_t iIndex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(uint32_t) vboxWddmHTableHandle2Index(VBOXWDDM_HANDLE hHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmHTableRealloc(PVBOXWDDM_HTABLE pTbl, uint32_t cNewSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID *pvNewData = (PVOID*)vboxWddmMemAllocZero(sizeof (pTbl->paData[0]) * cNewSize);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync WARN(("vboxWddmMemAllocZero failed for size (%d)", sizeof (pTbl->paData[0]) * cNewSize));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pvNewData, pTbl->paData, sizeof (pTbl->paData[0]) * pTbl->cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVBOXWDDM_HANDLE vboxWddmHTablePut(PVBOXWDDM_HTABLE pTbl, PVOID pvData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxWddmHTableRealloc(pTbl, pTbl->cSize + RT_MAX(10, pTbl->cSize/4));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (UINT i = pTbl->iNext2Search; ; ++i, i %= pTbl->cSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncPVOID vboxWddmHTableRemove(PVBOXWDDM_HTABLE pTbl, VBOXWDDM_HANDLE hHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t iIndex = vboxWddmHTableHandle2Index(hHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncPVOID vboxWddmHTableGet(PVBOXWDDM_HTABLE pTbl, VBOXWDDM_HANDLE hHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t iIndex = vboxWddmHTableHandle2Index(hHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmHTableIterInit(PVBOXWDDM_HTABLE pTbl, PVBOXWDDM_HTABLE_ITERATOR pIter)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncBOOL vboxWddmHTableIterHasNext(PVBOXWDDM_HTABLE_ITERATOR pIter)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncPVOID vboxWddmHTableIterNext(PVBOXWDDM_HTABLE_ITERATOR pIter, VBOXWDDM_HANDLE *phHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (uint32_t i = pIter->iCur+1; i < pIter->pTbl->cSize ; ++i)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_HANDLE hHandle = vboxWddmHTableIndex2Handle(i);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncPVOID vboxWddmHTableIterRemoveCur(PVBOXWDDM_HTABLE_ITERATOR pIter)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_HANDLE hHandle = vboxWddmHTableIndex2Handle(pIter->iCur);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID pRet = vboxWddmHTableRemove(pIter->pTbl, hHandle);
e6ad2e18e663b076aeabfec994947514566a7accvboxsyncPVBOXWDDM_SWAPCHAIN vboxWddmSwapchainCreate(UINT w, UINT h)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmMemAllocZero(sizeof (VBOXWDDM_SWAPCHAIN));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->enmState = VBOXWDDM_OBJSTATE_TYPE_INITIALIZED;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync /* init to some invalid value so that the pos get submitted */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pSwapchain->Pos.x = pSwapchain->Pos.y = VBOXWDDM_INVALID_COORD;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(BOOLEAN) vboxWddmSwapchainRetainLocked(PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSwapchain->enmState == VBOXWDDM_OBJSTATE_TYPE_INITIALIZED)
41fcf8465b641c7083d3b440451f17c1210fce33vboxsyncBOOLEAN vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
41fcf8465b641c7083d3b440451f17c1210fce33vboxsyncVOID vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync const uint32_t cRefs = ASMAtomicDecU32(&pSwapchain->cRefs);
41fcf8465b641c7083d3b440451f17c1210fce33vboxsyncPVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAllocData(PVBOXMP_DEVEXT pDevExt, const struct VBOXWDDM_ALLOC_DATA *pAllocData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSwapchain && !vboxWddmSwapchainRetainLocked(pSwapchain))
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsyncPVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOCATION *pAlloc)
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync return vboxWddmSwapchainRetainByAllocData(pDevExt, &pAlloc->AllocData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainAllocRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc)
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync Assert(pAlloc->AllocData.pSwapchain == pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncBOOLEAN vboxWddmSwapchainAllocAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InsertTailList(&pSwapchain->AllocList, &pAlloc->SwapchainEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXSCENTRY_2_ALLOC(_pE) ((PVBOXWDDM_ALLOCATION)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_ALLOCATION, SwapchainEntry)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic VOID vboxWddmSwapchainAllocRemoveAllInternal(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, BOOLEAN bOnDestroy)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXWDDM_ALLOCATION pAlloc = VBOXSCENTRY_2_ALLOC(pEntry);
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync Assert(pAlloc->AllocData.pSwapchain == pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->enmState = VBOXWDDM_OBJSTATE_TYPE_TERMINATED;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainAllocRemoveAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainAllocRemoveAllInternal(pDevExt, pSwapchain, FALSE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainAllocRemoveAllInternal(pDevExt, pSwapchain, TRUE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic BOOLEAN vboxWddmSwapchainCtxAddLocked(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->hSwapchainKm = vboxWddmHTablePut(&pContext->Swapchains, pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InsertHeadList(&pDevExt->SwapchainList3D, &pSwapchain->DevExtListEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic VOID vboxWddmSwapchainCtxRemoveLocked(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync void * pTst = vboxWddmHTableRemove(&pContext->Swapchains, pSwapchain->hSwapchainKm);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync/* adds the given swapchain to the context's swapchain list
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync * @return true on success */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncBOOLEAN vboxWddmSwapchainCtxAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync/* removes the given swapchain from the context's swapchain list
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainCtxRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync/* destroys all swapchains for the given context
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainCtxDestroyAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
4dcca394d4e08728bcb38374a62f0ab6af7cf1a9vboxsync vboxWddmHTableIterInit(&pContext->Swapchains, &Iter);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableIterNext(&Iter, NULL);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync /* yes, we can call remove locked even when using iterator */
db31571ec38a249cccfa0712989d810a68a9300fvboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync /* we must not do vboxWddmSwapchainDestroy inside a context mutex */
db31571ec38a249cccfa0712989d810a68a9300fvboxsync /* start from the very beginning, we will quit the loop when no swapchains left */
db31571ec38a249cccfa0712989d810a68a9300fvboxsync } while (1);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync /* no swapchains left, we exiteed the while loop via the "break", and we still owning the mutex */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync/* process the swapchain info passed from user-mode display driver & synchronizes the driver state with it */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmSwapchainCtxEscape(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXDISPIFESCAPE_SWAPCHAININFO pSwapchainInfo, UINT cbSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbSize < RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[0]))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbSize < RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[pSwapchainInfo->SwapchainInfo.cAllocs]))
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync WARN(("vboxWddmSwapchainCtxEscape: no context specified"));
2943a10881454db9563b304a24c971b4a929922fvboxsync /* ensure we do not overflow the 32bit buffer size value */
93f01a6d7a5f94cdcf9b71f4a7eb5fc59a9616aavboxsync if (VBOXWDDM_ARRAY_MAXELEMENTSU32(VBOXWDDM_ALLOCATION) < pSwapchainInfo->SwapchainInfo.cAllocs)
93f01a6d7a5f94cdcf9b71f4a7eb5fc59a9616aavboxsync WARN(("number of allocations passed in too big (%d), max is (%d)", pSwapchainInfo->SwapchainInfo.cAllocs, VBOXWDDM_ARRAY_MAXELEMENTSU32(VBOXWDDM_ALLOCATION)));
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync apAlloc = (PVBOXWDDM_ALLOCATION *)vboxWddmMemAlloc(sizeof (PVBOXWDDM_ALLOCATION) * pSwapchainInfo->SwapchainInfo.cAllocs);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync GhData.hObject = pSwapchainInfo->SwapchainInfo.ahAllocs[i];
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableGet(&pContext->Swapchains, (VBOXWDDM_HANDLE)pSwapchainInfo->SwapchainInfo.hSwapchainKm);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(pSwapchain->hSwapchainKm == pSwapchainInfo->SwapchainInfo.hSwapchainKm);
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pSwapchain = vboxWddmSwapchainCreate(apAlloc[0]->AllocData.SurfDesc.width, apAlloc[0]->AllocData.SurfDesc.height);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync BOOLEAN bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
a316239ff79e32378f26a4c9b77b5906d4653850vboxsync /* do not zero up the view rect since it may still be valid */
a316239ff79e32378f26a4c9b77b5906d4653850vboxsync// memset(&pSwapchain->ViewRect, 0, sizeof (pSwapchain->ViewRect));
e6ad2e18e663b076aeabfec994947514566a7accvboxsync /* @todo: do we really need to zero this up here ? */
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxWddmSwapchainAllocRemoveAll(pDevExt, pSwapchain);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxWddmSwapchainAllocAdd(pDevExt, pSwapchain, apAlloc[i]);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pSwapchain->hSwapchainUm = pSwapchainInfo->SwapchainInfo.hSwapchainUm;
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync if (pSwapchain->winHostID != pSwapchainInfo->SwapchainInfo.winHostID)
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync pSwapchain->winHostID = pSwapchainInfo->SwapchainInfo.winHostID;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pSwapchainInfo->SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync } while (0);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync /* cleanup */
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsyncNTSTATUS vboxWddmSwapchainCtxInit(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync NTSTATUS Status = vboxWddmHTableCreate(&pContext->Swapchains, 4);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync WARN(("vboxWddmHTableCreate failes, Status (x%x)", Status));
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsyncVOID vboxWddmSwapchainCtxTerm(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool bFallback = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pBuf, VBOXWDDM_REG_DRVKEY_PREFIX, sizeof (VBOXWDDM_REG_DRVKEY_PREFIX));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSuffix = pBuf + (sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2)/2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = IoGetDeviceProperty (pDevExt->pPDO,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pcbResult = cbBuf + sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegQueryDisplaySettingsKeyName(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool bFallback = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UNICODE_STRING* pVGuid = vboxWddmVGuidGet(pDevExt);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pKeyPrefix = VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbKeyPrefix = sizeof (VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pKeyPrefix = VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbKeyPrefix = sizeof (VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG cbResult = cbKeyPrefix + pVGuid->Length + 2 + 8; // L"\\" + "XXXX"
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsyncNTSTATUS vboxWddmRegQueryVideoGuidString(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DEVICE, GENERIC_READ, &hKey);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync memcpy(pBuf, KeyData.Info.Data, KeyData.Info.DataLength + 2);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync WARN(("ZwQueryValueKey failed, Status 0x%x", Status));
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync WARN(("IoOpenDeviceRegistryKey failed Status 0x%x", Status));
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync WARN(("failed to acquire the VideoID, falling back to the old impl"));
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync Status = vboxWddmRegOpenKey(&hKey, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY, GENERIC_READ);
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync //Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WCHAR KeyBuf[sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY)/2 + 256 + 64];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wcscpy(KeyBuf, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = ZwEnumerateKey(hKey, i, KeyBasicInformation, &Buf, sizeof (Buf), &ResultLength);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* we should not encounter STATUS_NO_MORE_ENTRIES here since this would mean we did not find our entry */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PWCHAR pSubBuf = KeyBuf + (sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY) - 2)/2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pSubBuf, Buf.Name.Name, Buf.Name.NameLength);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pSubBuf, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY, sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmRegOpenKey(&hSubKey, KeyBuf, GENERIC_READ);
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync //Assert(Status == STATUS_SUCCESS);
0593640ab087e5bf747a2576b1752a2046be83aavboxsync UCHAR Buf[sizeof (VBOX_WDDM_DRIVERNAME)]; /* should be enough */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS || STATUS_BUFFER_TOO_SMALL || STATUS_BUFFER_OVERFLOW);
0593640ab087e5bf747a2576b1752a2046be83aavboxsync if (KeyData.Info.DataLength == sizeof (VBOX_WDDM_DRIVERNAME))
0593640ab087e5bf747a2576b1752a2046be83aavboxsync if (!wcscmp(VBOX_WDDM_DRIVERNAME, (PWCHAR)KeyData.Info.Data))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pBuf, Buf.Name.Name, Buf.Name.NameLength + 2);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsyncNTSTATUS vboxWddmRegOpenKeyEx(OUT PHANDLE phKey, IN HANDLE hRootKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, hRootKey, NULL);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsyncNTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync return vboxWddmRegOpenKeyEx(phKey, NULL, pName, fAccess);
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsyncNTSTATUS vboxWddmRegOpenDisplaySettingsKey(IN PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, OUT PHANDLE phKey)
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync NTSTATUS Status = vboxWddmRegQueryDisplaySettingsKeyName(pDevExt, VidPnSourceId, cbBuf, Buf, &cbBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmRegOpenKey(phKey, Buf, GENERIC_READ);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* fall-back to make the subsequent VBoxVideoCmnRegXxx calls treat the fail accordingly
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * basically needed to make as less modifications to the current XPDM code as possible */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegDisplaySettingsQueryRelX(HANDLE hKey, int * pResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX, &dwVal);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegDisplaySettingsQueryRelY(HANDLE hKey, int * pResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY, &dwVal);
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsyncNTSTATUS vboxWddmDisplaySettingsQueryPos(IN PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, POINT * pPos)
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync NTSTATUS Status = vboxWddmRegOpenDisplaySettingsKey(pDevExt, VidPnSourceId, &hKey);
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync //Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmRegDisplaySettingsQueryRelX(hKey, &x);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmRegDisplaySettingsQueryRelY(hKey, &y);
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsyncvoid vboxWddmDisplaySettingsCheckPos(IN PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync NTSTATUS Status = vboxWddmDisplaySettingsQueryPos(pDevExt, VidPnSourceId, &Pos);
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync Log(("vboxWddmDisplaySettingsQueryPos failed %#x", Status));
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync if (!memcmp(&pSource->VScreenPos, &Pos, sizeof (Pos)))
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncNTSTATUS vboxWddmRegDrvFlagsSet(PVBOXMP_DEVEXT pDevExt, DWORD fVal)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_WRITE, &hKey);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Status = vboxWddmRegSetValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, fVal);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync WARN(("vboxWddmRegSetValueDword failed, Status = 0x%x", Status));
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncDWORD vboxWddmRegDrvFlagsGet(PVBOXMP_DEVEXT pDevExt, DWORD fDefault)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_READ, &hKey);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, &dwVal);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync WARN(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncNTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, IN DWORD val)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncUNICODE_STRING* vboxWddmVGuidGet(PVBOXMP_DEVEXT pDevExt)
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync NTSTATUS Status = vboxWddmRegQueryVideoGuidString(pDevExt ,cbVideoGuidBuf, VideoGuidBuf, &cbVideoGuidBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PWCHAR pBuf = (PWCHAR)vboxWddmMemAllocZero(cbVideoGuidBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cbBuffer = VBOXWDDM_ROUNDBOUND(cPages, 8) >> 3;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PULONG pBuf = (PULONG)vboxWddmMemAllocZero(cbBuffer);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG iPage = RtlFindClearBitsAndSet(&pMm->BitMap, cPages, 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxMmFree(PVBOXWDDM_MM pMm, UINT iPage, UINT cPages)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(RtlAreBitsSet(&pMm->BitMap, iPage, cPages));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoCmAllocAlloc(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t offData = pMgr->offData + (iPage << PAGE_SHIFT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(offData + cbSize <= pMgr->offData + pMgr->cbData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAlloc->hGlobalHandle = vboxWddmHTablePut(&pMgr->AllocTable, pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (VBOXWDDM_HANDLE_INVALID != pAlloc->hGlobalHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxVideoCmAllocDealloc(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT iPage = BYTES_TO_PAGES(pAlloc->offData - pMgr->offData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmHTableRemove(&pMgr->AllocTable, pAlloc->hGlobalHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrAllocCreate(PVBOXVIDEOCM_ALLOC_MGR pMgr, UINT cbSize, PVBOXVIDEOCM_ALLOC *ppAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC pAlloc = (PVBOXVIDEOCM_ALLOC)vboxWddmMemAllocZero(sizeof (*pAlloc));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxVideoAMgrAllocDestroy(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocMap(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, PVBOXVIDEOCM_ALLOC pAlloc, PVBOXVIDEOCM_UM_ALLOC pUmAlloc)
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync Status = ObReferenceObjectByHandle((HANDLE)pUmAlloc->hSynch, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID BaseVa = pMgr->pvData + pAlloc->offData - pMgr->offData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmMemAllocZero(sizeof (*pAllocRef) + sizeof (PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseVa, cbLength));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MmInitializeMdl(&pAllocRef->Mdl, BaseVa, cbLength);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MmProbeAndLockPages(&pAllocRef->Mdl, KernelMode, IoWriteAccess);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID pvUm = MmMapLockedPagesSpecifyCache(&pAllocRef->Mdl, UserMode, MmNonCached,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAllocRef->hSessionHandle = vboxWddmHTablePut(&pContext->AllocTable, pAllocRef);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (VBOXWDDM_HANDLE_INVALID != pAllocRef->hSessionHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocUnmap(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle, PVBOXVIDEOCM_ALLOC *ppAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmHTableRemove(&pContext->AllocTable, hSesionHandle);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync /* wait for the dereference, i.e. for all commands involving this allocation to complete */
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync MmUnmapLockedPages(pAllocRef->pvUm, &pAllocRef->Mdl);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic PVBOXVIDEOCM_ALLOC_REF vboxVideoAMgrCtxAllocRefAcquire(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmHTableGet(&pContext->AllocTable, hSesionHandle);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsyncstatic VOID vboxVideoAMgrCtxAllocRefRelease(PVBOXVIDEOCM_ALLOC_REF pRef)
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync Assert(cRefs >= 1); /* we do not do cleanup-on-zero here, instead we wait for the cRefs to reach 1 in vboxVideoAMgrCtxAllocUnmap before unmapping */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocCreate(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, PVBOXVIDEOCM_UM_ALLOC pUmAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxVideoAMgrAllocCreate(pMgr, pUmAlloc->cbData, &pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxVideoAMgrCtxAllocMap(pContext, pAlloc, pUmAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocDestroy(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxVideoAMgrCtxAllocUnmap(pContext, hSesionHandle, &pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic DECLCALLBACK(VOID) vboxVideoAMgrAllocSubmitCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* we should be called from our DPC routine */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)pvContext;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync PVBOXVIDEOCM_ALLOC_REF pRef = (PVBOXVIDEOCM_ALLOC_REF)pBufCmd->u64GuestData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* signal completion */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync/* submits a set of chromium uhgsmi buffers to host for processing */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_CONTEXT pContext, UINT cBuffers, VBOXWDDM_UHGSMI_BUFFER_UI_INFO_ESCAPE *paBuffers)
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync /* ensure we do not overflow the 32bit buffer size value */
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync if (VBOXWDDM_TRAILARRAY_MAXELEMENTSU32(VBOXVDMACMD_CHROMIUM_CMD, aBuffers) < cBuffers)
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync WARN(("number of buffers passed too big (%d), max is (%d)", cBuffers, VBOXWDDM_TRAILARRAY_MAXELEMENTSU32(VBOXVDMACMD_CHROMIUM_CMD, aBuffers)));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[cBuffers]));
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // vboxVdmaCBufDrCreate zero initializes the pDr
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_UHGSMI_BUFFER_UI_INFO_ESCAPE *pBufInfo = &paBuffers[i];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pRef = vboxVideoAMgrCtxAllocRefAcquire(pContext, pBufInfo->hAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pBufCmd->offBuffer = pRef->pAlloc->offData + pBufInfo->Info.offData;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync WARN(("vboxVideoAMgrCtxAllocRefAcquire failed for hAlloc(0x%x)\n", pBufInfo->hAlloc));
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync /* release all previously acquired aloc references */
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync for (UINT j = 0; j < i; ++j)
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmdJ = &pBody->aBuffers[j];
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync PVBOXVIDEOCM_ALLOC_REF pRefJ = (PVBOXVIDEOCM_ALLOC_REF)pBufCmdJ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxVideoAMgrAllocSubmitCompletion, pDr);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync WARN(("vboxVdmaCBufDrSubmit failed with rc (%d)\n", rc));
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync /* failure branch */
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync /* release all previously acquired aloc references */
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync PVBOXVIDEOCM_ALLOC_REF pRef = (PVBOXVIDEOCM_ALLOC_REF)pBufCmd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* @todo: try flushing.. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCreate(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_MGR pMgr, uint32_t offData, uint32_t cbData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxWddmHTableCreate(&pMgr->AllocTable, 64);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxMmInit(&pMgr->Mm, BYTES_TO_PAGES(cbData));
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync PhysicalAddress.QuadPart = VBoxCommonFromDeviceExt(pDevExt)->phVRAM.QuadPart + offData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMgr->pvData = (uint8_t*)MmMapIoSpace(PhysicalAddress, cbData, MmNonCached);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_MGR pMgr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxCreate(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC_CONTEXT pCtx)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmHTableCreate(&pCtx->AllocTable, 32);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxDestroy(PVBOXVIDEOCM_ALLOC_CONTEXT pCtx)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmHTableIterNext(&Iter, NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxVideoAMgrCtxAllocDestroy(pCtx, pRef->hSessionHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // vboxWddmHTableIterRemoveCur(&Iter);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (1);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync KeDelayExecutionThread(KernelMode, FALSE, &Interval);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncVOID vboxWddmCounterU32Wait(uint32_t volatile * pu32, uint32_t u32Val)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync while ((u32CurVal = ASMAtomicReadU32(pu32)) != u32Val)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync KeDelayExecutionThread(KernelMode, FALSE, &Interval);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync/* dump user-mode driver debug info */
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncstatic VBOXDISPIFESCAPE_DBGDUMPBUF_FLAGS g_VBoxUmdD3DCAPS9Flags;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncstatic void vboxUmdDumpDword(DWORD *pvData, DWORD cData)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync sprintf(aBuf, "0x%08x, 0x%08x, 0x%08x, 0x%08x,\n", dw1, dw2, dw3, dw4);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync sprintf(aBuf, "0x%08x, 0x%08x, 0x%08x\n", dw1, dw2, dw3);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncstatic void vboxUmdDumpD3DCAPS9(void *pvData, PVBOXDISPIFESCAPE_DBGDUMPBUF_FLAGS pFlags)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync AssertCompile(!(sizeof (g_aVBoxUmdD3DCAPS9) % sizeof (DWORD)));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync vboxUmdDumpDword((DWORD*)pvData, sizeof (g_aVBoxUmdD3DCAPS9) / sizeof (DWORD));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncNTSTATUS vboxUmdDumpBuf(PVBOXDISPIFESCAPE_DBGDUMPBUF pBuf, uint32_t cbBuffer)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync if (cbBuffer < RT_OFFSETOF(VBOXDISPIFESCAPE_DBGDUMPBUF, aBuf[0]))
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync uint32_t cbString = cbBuffer - RT_OFFSETOF(VBOXDISPIFESCAPE_DBGDUMPBUF, aBuf[0]);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync WARN(("wrong caps size, expected %d, but was %d", sizeof (g_aVBoxUmdD3DCAPS9), cbString));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync if (!memcmp(g_aVBoxUmdD3DCAPS9, pBuf->aBuf, sizeof (g_aVBoxUmdD3DCAPS9)))
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync memcpy(g_aVBoxUmdD3DCAPS9, pBuf->aBuf, sizeof (g_aVBoxUmdD3DCAPS9));
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncBOOLEAN vboxShRcTreePut(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync bool bRc = RTAvlPVInsert(&pDevExt->ShRcTree, &pAlloc->ShRcTreeEntry);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync#define PVBOXWDDM_ALLOCATION_FROM_SHRCTREENODE(_p) ((PVBOXWDDM_ALLOCATION)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXWDDM_ALLOCATION, ShRcTreeEntry)))
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncPVBOXWDDM_ALLOCATION vboxShRcTreeGet(PVBOXMP_DEVEXT pDevExt, HANDLE hSharedRc)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync PAVLPVNODECORE pNode = RTAvlPVGet(&pDevExt->ShRcTree, (AVLPVKEY)hSharedRc);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync PVBOXWDDM_ALLOCATION pAlloc = PVBOXWDDM_ALLOCATION_FROM_SHRCTREENODE(pNode);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncBOOLEAN vboxShRcTreeRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync PAVLPVNODECORE pNode = RTAvlPVRemove(&pDevExt->ShRcTree, (AVLPVKEY)hSharedRc);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync PVBOXWDDM_ALLOCATION pRetAlloc = PVBOXWDDM_ALLOCATION_FROM_SHRCTREENODE(pNode);
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsyncNTSTATUS vboxWddmDrvCfgInit(PUNICODE_STRING pRegStr)
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync InitializeObjectAttributes(&ObjAttr, pRegStr, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync NTSTATUS Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjAttr);
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync WARN(("ZwOpenKey for settings key failed, Status 0x%x", Status));
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_CFG_STR_LOG_UM, &dwValue);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS vboxWddmThreadCreate(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncstatic int vboxWddmWdProgram(PVBOXMP_DEVEXT pDevExt, uint32_t cMillis)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMICommandAlloc(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, sizeof (VBOXVDMA_CTL), HGSMI_CH_VBVA, VBVA_VDMA_CTL);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pCmd);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBoxVideoCmnPortWriteUlong(VBoxCommonFromDeviceExt(pDevExt)->guestCtx.port, offCmd);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = VBoxSHGSMICommandDoneSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync /* fail to submit, cancel it */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBoxSHGSMICommandCancelSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync } while (0);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBoxSHGSMICommandFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pCmd);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync/* if null g_VBoxWdTimeout / 2 is used */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = vboxWddmWdProgram(pDevExt, g_VBoxWdTimeout /* ms */);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = vboxWddmWdProgram(pDevExt, 0 /* to disable WatchDog */);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync uint32_t timerTimeOut = g_VBoxWdTimerPeriod ? g_VBoxWdTimerPeriod : g_VBoxWdTimeout / 2;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync Timeout.QuadPart = 10000ULL * timerTimeOut /* ms */;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync NTSTATUS Status = KeWaitForSingleObject(&pDevExt->WdEvent, Executive, KernelMode, FALSE, &Timeout);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeInitializeEvent(&pDevExt->WdEvent, NotificationEvent, FALSE);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync NTSTATUS Status = vboxWddmThreadCreate(&pDevExt->pWdThread, vboxWddmWdThread, pDevExt);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync WARN(("vboxWddmThreadCreate failed, Status 0x%x", Status));
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeWaitForSingleObject(pDevExt->pWdThread, Executive, KernelMode, FALSE, NULL);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncstatic int vboxWddmSlConfigure(PVBOXMP_DEVEXT pDevExt, uint32_t fFlags)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync PHGSMIGUESTCOMMANDCONTEXT pCtx = &VBoxCommonFromDeviceExt(pDevExt)->guestCtx;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync /* Allocate the IO buffer. */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pCfg = (VBVASCANLINECFG *)VBoxHGSMIBufferAlloc(pCtx,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync /* Prepare data to be sent to the host. */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync /* Free the IO buffer. */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS VBoxWddmSlEnableVSyncNotification(PVBOXMP_DEVEXT pDevExt, BOOLEAN fEnable)
f566a1c9e055abedd946dae571515798986ed5c5vboxsync KeQuerySystemTime((PLARGE_INTEGER)&pDevExt->VSyncTime);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync KeSetTimerEx(&pDevExt->VSyncTimer, DueTime, 16, &pDevExt->VSyncDpc);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS VBoxWddmSlGetScanLine(PVBOXMP_DEVEXT pDevExt, DXGKARG_GETSCANLINE *pGetScanLine)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync Assert((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays > pGetScanLine->VidPnTargetId);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[pGetScanLine->VidPnTargetId];
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync DevVSyncTime.QuadPart = ASMAtomicReadU64((volatile uint64_t*)&pDevExt->VSyncTime.QuadPart);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync WARN(("vsync time is less than the one stored in device"));
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync VSyncTime.QuadPart = VSyncTime.QuadPart - DevVSyncTime.QuadPart;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync /* time is in 100ns, */
359416647a711739d1b14addbf399178949a1a60vboxsync curScanLine = (uint32_t)((pTarget->Size.cy * VSyncTime.QuadPart) / DevVSyncTime.QuadPart);
359416647a711739d1b14addbf399178949a1a60vboxsync bVBlank = (!curScanLine || curScanLine > pTarget->Size.cy);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsyncstatic BOOLEAN vboxWddmSlVSyncIrqCb(PVOID pvContext)
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvContext;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync memset(¬ify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, ¬ify);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)DeferredContext;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync 0, /* IN ULONG MessageNumber */
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync WARN(("DxgkCbSynchronizeExecution failed Status %#x", Status));
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync ASMAtomicWriteU64((volatile uint64_t*)&pDevExt->VSyncTime.QuadPart, VSyncTime.QuadPart);
f566a1c9e055abedd946dae571515798986ed5c5vboxsync KeQuerySystemTime((PLARGE_INTEGER)&pDevExt->VSyncTime);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeInitializeDpc(&pDevExt->VSyncDpc, vboxWddmSlVSyncDpc, pDevExt);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncvoid vboxWddmDiInitDefault(DXGK_DISPLAY_INFORMATION *pInfo, PHYSICAL_ADDRESS PhAddr, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncvoid vboxWddmDiToAllocData(PVBOXMP_DEVEXT pDevExt, const DXGK_DISPLAY_INFORMATION *pInfo, PVBOXWDDM_ALLOC_DATA pAllocData)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pInfo->ColorFormat);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.cbSize = pInfo->Pitch * pInfo->Height;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.VidPnSourceId = pInfo->TargetId;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.RefreshRate.Numerator = 60000;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.RefreshRate.Denominator = 1000;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync /* the address here is not a VRAM offset! so convert it to offset */
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync vboxWddmVramAddrToOffset(pDevExt, pInfo->PhysicAddress));
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsyncvoid vboxWddmDmSetupDefaultVramLocation(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID ModifiedVidPnSourceId, VBOXWDDM_SOURCE *paSources)
359416647a711739d1b14addbf399178949a1a60vboxsync PVBOXWDDM_SOURCE pSource = &paSources[ModifiedVidPnSourceId];
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync ULONG offVram = vboxWddmVramCpuVisibleSegmentSize(pDevExt);
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync offVram /= VBoxCommonFromDeviceExt(pDevExt)->cDisplays;
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync if (vboxWddmAddrSetVram(&pSource->AllocData.Addr, 1, offVram))