9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* $Id$ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @file
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBox WDDM Miniport driver
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2011-2013 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
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.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include "VBoxMPWddm.h"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <VBox/Hardware/VBoxVideoVBE.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <stdio.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync/* simple handle -> value table API */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmHTableCreate(PVBOXWDDM_HTABLE pTbl, uint32_t cSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memset(pTbl, 0, sizeof (*pTbl));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->paData = (PVOID*)vboxWddmMemAllocZero(sizeof (pTbl->paData[0]) * cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pTbl->paData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->cSize = cSize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_NO_MEMORY;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmHTableDestroy(PVBOXWDDM_HTABLE pTbl)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (!pTbl->paData)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync return;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pTbl->paData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(VBOXWDDM_HANDLE) vboxWddmHTableIndex2Handle(uint32_t iIndex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return iIndex+1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(uint32_t) vboxWddmHTableHandle2Index(VBOXWDDM_HANDLE hHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return hHandle-1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmHTableRealloc(PVBOXWDDM_HTABLE pTbl, uint32_t cNewSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cNewSize > pTbl->cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cNewSize > pTbl->cSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID *pvNewData = (PVOID*)vboxWddmMemAllocZero(sizeof (pTbl->paData[0]) * cNewSize);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (!pvNewData)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync {
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync WARN(("vboxWddmMemAllocZero failed for size (%d)", sizeof (pTbl->paData[0]) * cNewSize));
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync return STATUS_NO_MEMORY;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pvNewData, pTbl->paData, sizeof (pTbl->paData[0]) * pTbl->cSize);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync vboxWddmMemFree(pTbl->paData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->iNext2Search = pTbl->cSize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->cSize = cNewSize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->paData = pvNewData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (cNewSize >= pTbl->cData)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync {
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync AssertFailed();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_NOT_IMPLEMENTED;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_INVALID_PARAMETER;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVBOXWDDM_HANDLE vboxWddmHTablePut(PVBOXWDDM_HTABLE pTbl, PVOID pvData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pTbl->cSize == pTbl->cData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxWddmHTableRealloc(pTbl, pTbl->cSize + RT_MAX(10, pTbl->cSize/4));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status != STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VBOXWDDM_HANDLE_INVALID;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (UINT i = pTbl->iNext2Search; ; ++i, i %= pTbl->cSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(i < pTbl->cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pTbl->paData[i])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->paData[i] = pvData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ++pTbl->cData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pTbl->cData <= pTbl->cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ++pTbl->iNext2Search;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->iNext2Search %= pTbl->cSize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return vboxWddmHTableIndex2Handle(i);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VBOXWDDM_HANDLE_INVALID;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncPVOID vboxWddmHTableRemove(PVBOXWDDM_HTABLE pTbl, VBOXWDDM_HANDLE hHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t iIndex = vboxWddmHTableHandle2Index(hHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(iIndex < pTbl->cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iIndex < pTbl->cSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID pvData = pTbl->paData[iIndex];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->paData[iIndex] = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync --pTbl->cData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pTbl->cData <= pTbl->cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pTbl->iNext2Search = iIndex;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pvData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncPVOID vboxWddmHTableGet(PVBOXWDDM_HTABLE pTbl, VBOXWDDM_HANDLE hHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t iIndex = vboxWddmHTableHandle2Index(hHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(iIndex < pTbl->cSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iIndex < pTbl->cSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pTbl->paData[iIndex];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmHTableIterInit(PVBOXWDDM_HTABLE pTbl, PVBOXWDDM_HTABLE_ITERATOR pIter)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pIter->pTbl = pTbl;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pIter->iCur = ~0UL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pIter->cLeft = pTbl->cData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncBOOL vboxWddmHTableIterHasNext(PVBOXWDDM_HTABLE_ITERATOR pIter)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pIter->cLeft;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncPVOID vboxWddmHTableIterNext(PVBOXWDDM_HTABLE_ITERATOR pIter, VBOXWDDM_HANDLE *phHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (vboxWddmHTableIterHasNext(pIter))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (uint32_t i = pIter->iCur+1; i < pIter->pTbl->cSize ; ++i)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pIter->pTbl->paData[i])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pIter->iCur = i;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync --pIter->cLeft;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_HANDLE hHandle = vboxWddmHTableIndex2Handle(i);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(hHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (phHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *phHandle = hHandle;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pIter->pTbl->paData[i];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!vboxWddmHTableIterHasNext(pIter));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (phHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *phHandle = VBOXWDDM_HANDLE_INVALID;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncPVOID vboxWddmHTableIterRemoveCur(PVBOXWDDM_HTABLE_ITERATOR pIter)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_HANDLE hHandle = vboxWddmHTableIndex2Handle(pIter->iCur);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(hHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (hHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID pRet = vboxWddmHTableRemove(pIter->pTbl, hHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pRet);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pRet;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
ad290511521ce8388a9926b165241ecf83c330a7vboxsync#ifdef VBOX_WITH_CROGL
e6ad2e18e663b076aeabfec994947514566a7accvboxsyncPVBOXWDDM_SWAPCHAIN vboxWddmSwapchainCreate(UINT w, UINT h)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmMemAllocZero(sizeof (VBOXWDDM_SWAPCHAIN));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&pSwapchain->AllocList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->enmState = VBOXWDDM_OBJSTATE_TYPE_INITIALIZED;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->cRefs = 1;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync /* init to some invalid value so that the pos get submitted */
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pSwapchain->Pos.x = pSwapchain->Pos.y = VBOXWDDM_INVALID_COORD;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pSwapchain->width = w;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pSwapchain->height = h;
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync VBoxVrListInit(&pSwapchain->VisibleRegions);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pSwapchain;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(BOOLEAN) vboxWddmSwapchainRetainLocked(PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSwapchain->enmState == VBOXWDDM_OBJSTATE_TYPE_INITIALIZED)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ASMAtomicIncU32(&pSwapchain->cRefs);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return TRUE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return FALSE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
41fcf8465b641c7083d3b440451f17c1210fce33vboxsyncBOOLEAN vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KIRQL OldIrql;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BOOLEAN bRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bRc = vboxWddmSwapchainRetainLocked(pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return bRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
41fcf8465b641c7083d3b440451f17c1210fce33vboxsyncVOID vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync const uint32_t cRefs = ASMAtomicDecU32(&pSwapchain->cRefs);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cRefs < UINT32_MAX/2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!cRefs)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync VBoxVrListClear(&pSwapchain->VisibleRegions);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
41fcf8465b641c7083d3b440451f17c1210fce33vboxsyncPVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAllocData(PVBOXMP_DEVEXT pDevExt, const struct VBOXWDDM_ALLOC_DATA *pAllocData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KIRQL OldIrql;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXWDDM_SWAPCHAIN pSwapchain;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync pSwapchain = pAllocData->pSwapchain;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSwapchain && !vboxWddmSwapchainRetainLocked(pSwapchain))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pSwapchain;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsyncPVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOCATION *pAlloc)
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync{
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync return vboxWddmSwapchainRetainByAllocData(pDevExt, &pAlloc->AllocData);
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync}
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainAllocRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KIRQL OldIrql;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync Assert(pAlloc->AllocData.pSwapchain == pSwapchain);
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync pAlloc->AllocData.pSwapchain = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(&pAlloc->SwapchainEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainRelease(pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncBOOLEAN vboxWddmSwapchainAllocAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KIRQL OldIrql;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BOOLEAN bRc;
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync Assert(!pAlloc->AllocData.pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bRc = vboxWddmSwapchainRetainLocked(pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync if (pAlloc->AllocData.pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(&pAlloc->SwapchainEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InsertTailList(&pSwapchain->AllocList, &pAlloc->SwapchainEntry);
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync pAlloc->AllocData.pSwapchain = pSwapchain;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return bRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXSCENTRY_2_ALLOC(_pE) ((PVBOXWDDM_ALLOCATION)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_ALLOCATION, SwapchainEntry)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic VOID vboxWddmSwapchainAllocRemoveAllInternal(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, BOOLEAN bOnDestroy)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KIRQL OldIrql;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cRemoved = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PLIST_ENTRY pEntry = pSwapchain->AllocList.Flink;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync do
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pEntry != &pSwapchain->AllocList)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXWDDM_ALLOCATION pAlloc = VBOXSCENTRY_2_ALLOC(pEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pEntry = pEntry->Flink;
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync Assert(pAlloc->AllocData.pSwapchain == pSwapchain);
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync pAlloc->AllocData.pSwapchain = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(&pAlloc->SwapchainEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ++cRemoved;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bOnDestroy)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->enmState = VBOXWDDM_OBJSTATE_TYPE_TERMINATED;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (UINT i = 0; i < cRemoved; ++i)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainRelease(pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainAllocRemoveAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainAllocRemoveAllInternal(pDevExt, pSwapchain, FALSE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainAllocRemoveAllInternal(pDevExt, pSwapchain, TRUE);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainRelease(pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic BOOLEAN vboxWddmSwapchainCtxAddLocked(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (vboxWddmSwapchainRetain(pDevExt, pSwapchain))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pSwapchain->hSwapchainKm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pSwapchain->pContext);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->pContext = pContext;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->hSwapchainKm = vboxWddmHTablePut(&pContext->Swapchains, pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InsertHeadList(&pDevExt->SwapchainList3D, &pSwapchain->DevExtListEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return TRUE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return FALSE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic VOID vboxWddmSwapchainCtxRemoveLocked(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pSwapchain->hSwapchainKm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pSwapchain->pContext);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync void * pTst = vboxWddmHTableRemove(&pContext->Swapchains, pSwapchain->hSwapchainKm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pTst == pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(&pSwapchain->DevExtListEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSwapchain->hSwapchainKm = NULL;
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync VBoxVrListClear(&pSwapchain->VisibleRegions);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainRelease(pSwapchain);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
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{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BOOLEAN bRc;
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_DATA
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_LOCK(pDevExt);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return bRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync/* removes the given swapchain from the context's swapchain list
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync * */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainCtxRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_DATA
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_LOCK(pDevExt);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync/* destroys all swapchains for the given context
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync * */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmSwapchainCtxDestroyAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_HTABLE_ITERATOR Iter;
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_DATA
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync do
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_LOCK(pDevExt);
4dcca394d4e08728bcb38374a62f0ab6af7cf1a9vboxsync vboxWddmHTableIterInit(&pContext->Swapchains, &Iter);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableIterNext(&Iter, NULL);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync if (!pSwapchain)
db31571ec38a249cccfa0712989d810a68a9300fvboxsync break;
db31571ec38a249cccfa0712989d810a68a9300fvboxsync
db31571ec38a249cccfa0712989d810a68a9300fvboxsync /* yes, we can call remove locked even when using iterator */
db31571ec38a249cccfa0712989d810a68a9300fvboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync /* we must not do vboxWddmSwapchainDestroy inside a context mutex */
db31571ec38a249cccfa0712989d810a68a9300fvboxsync vboxWddmSwapchainDestroy(pDevExt, pSwapchain);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync /* start from the very beginning, we will quit the loop when no swapchains left */
db31571ec38a249cccfa0712989d810a68a9300fvboxsync } while (1);
db31571ec38a249cccfa0712989d810a68a9300fvboxsync
db31571ec38a249cccfa0712989d810a68a9300fvboxsync /* no swapchains left, we exiteed the while loop via the "break", and we still owning the mutex */
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
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{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbSize < RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[0]))
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync {
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync WARN(("invalid cbSize1 %d", cbSize));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_INVALID_PARAMETER;
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync }
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbSize < RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[pSwapchainInfo->SwapchainInfo.cAllocs]))
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_INVALID_PARAMETER;
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync WARN(("invalid cbSize2 %d", cbSize));
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync if (!pSwapchainInfo->SwapchainInfo.winHostID)
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync {
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync WARN(("Zero winHostID specified!"));
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync return STATUS_INVALID_PARAMETER;
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync }
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync if (!pContext)
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync {
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync WARN(("vboxWddmSwapchainCtxEscape: no context specified"));
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync return STATUS_INVALID_PARAMETER;
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync }
ea1cc8df95dba6fca9c36c94f565ef95c7802a36vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXWDDM_SWAPCHAIN pSwapchain = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXWDDM_ALLOCATION *apAlloc = NULL;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync NTSTATUS Status = STATUS_SUCCESS;
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_DATA
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync do {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (pSwapchainInfo->SwapchainInfo.cAllocs)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
2943a10881454db9563b304a24c971b4a929922fvboxsync /* ensure we do not overflow the 32bit buffer size value */
93f01a6d7a5f94cdcf9b71f4a7eb5fc59a9616aavboxsync if (VBOXWDDM_ARRAY_MAXELEMENTSU32(VBOXWDDM_ALLOCATION) < pSwapchainInfo->SwapchainInfo.cAllocs)
2943a10881454db9563b304a24c971b4a929922fvboxsync {
93f01a6d7a5f94cdcf9b71f4a7eb5fc59a9616aavboxsync WARN(("number of allocations passed in too big (%d), max is (%d)", pSwapchainInfo->SwapchainInfo.cAllocs, VBOXWDDM_ARRAY_MAXELEMENTSU32(VBOXWDDM_ALLOCATION)));
2943a10881454db9563b304a24c971b4a929922fvboxsync Status = STATUS_INVALID_PARAMETER;
2943a10881454db9563b304a24c971b4a929922fvboxsync break;
2943a10881454db9563b304a24c971b4a929922fvboxsync }
2943a10881454db9563b304a24c971b4a929922fvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync apAlloc = (PVBOXWDDM_ALLOCATION *)vboxWddmMemAlloc(sizeof (PVBOXWDDM_ALLOCATION) * pSwapchainInfo->SwapchainInfo.cAllocs);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(apAlloc);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (!apAlloc)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Status = STATUS_NO_MEMORY;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync DXGKARGCB_GETHANDLEDATA GhData;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync GhData.hObject = pSwapchainInfo->SwapchainInfo.ahAllocs[i];
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync GhData.Type = DXGK_HANDLE_ALLOCATION;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync GhData.Flags.Value = 0;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(pAlloc);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (!pAlloc)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Status = STATUS_INVALID_PARAMETER;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync apAlloc[i] = pAlloc;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (!NT_SUCCESS(Status))
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (pSwapchainInfo->SwapchainInfo.hSwapchainKm)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_LOCK(pDevExt);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableGet(&pContext->Swapchains, (VBOXWDDM_HANDLE)pSwapchainInfo->SwapchainInfo.hSwapchainKm);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(pSwapchain);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (!pSwapchain)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Status = STATUS_INVALID_PARAMETER;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(pSwapchain->hSwapchainKm == pSwapchainInfo->SwapchainInfo.hSwapchainKm);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(pSwapchain->pContext == pContext);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (pSwapchain->pContext != pContext)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Status = STATUS_INVALID_PARAMETER;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync else if (pSwapchainInfo->SwapchainInfo.cAllocs)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync pSwapchain = vboxWddmSwapchainCreate(apAlloc[0]->AllocData.SurfDesc.width, apAlloc[0]->AllocData.SurfDesc.height);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (!pSwapchain)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Status = STATUS_NO_MEMORY;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_LOCK(pDevExt);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync BOOLEAN bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(bRc);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync else
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Status = STATUS_INVALID_PARAMETER;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
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 ? */
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync VBoxVrListClear(&pSwapchain->VisibleRegions);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxWddmSwapchainAllocRemoveAll(pDevExt, pSwapchain);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (pSwapchainInfo->SwapchainInfo.cAllocs)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxWddmSwapchainAllocAdd(pDevExt, pSwapchain, apAlloc[i]);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pSwapchain->hSwapchainUm = pSwapchainInfo->SwapchainInfo.hSwapchainUm;
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync if (pSwapchain->winHostID != pSwapchainInfo->SwapchainInfo.winHostID)
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync {
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync pSwapchain->fExposed = FALSE;
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync pSwapchain->winHostID = pSwapchainInfo->SwapchainInfo.winHostID;
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync else
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (pSwapchainInfo->SwapchainInfo.cAllocs)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(pSwapchain->pContext);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(pSwapchain->hSwapchainKm);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pSwapchainInfo->SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync else
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxWddmSwapchainDestroy(pDevExt, pSwapchain);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pSwapchainInfo->SwapchainInfo.hSwapchainKm = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(Status == STATUS_SUCCESS);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync } while (0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync /* cleanup */
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (apAlloc)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxWddmMemFree(apAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsyncNTSTATUS vboxWddmSwapchainCtxInit(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync{
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync NTSTATUS Status = vboxWddmHTableCreate(&pContext->Swapchains, 4);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync if (!NT_SUCCESS(Status))
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync {
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync WARN(("vboxWddmHTableCreate failes, Status (x%x)", Status));
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync return Status;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync }
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync return STATUS_SUCCESS;
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync}
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsyncVOID vboxWddmSwapchainCtxTerm(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync{
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync vboxWddmSwapchainCtxDestroyAll(pDevExt, pContext);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync vboxWddmHTableDestroy(&pContext->Swapchains);
441b60f8b0601cc1718368c9c3ef082223ad12a2vboxsync}
ad290511521ce8388a9926b165241ecf83c330a7vboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WCHAR fallBackBuf[2];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PWCHAR pSuffix;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool bFallback = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbBuf > sizeof(VBOXWDDM_REG_DRVKEY_PREFIX))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pBuf, VBOXWDDM_REG_DRVKEY_PREFIX, sizeof (VBOXWDDM_REG_DRVKEY_PREFIX));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSuffix = pBuf + (sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2)/2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbBuf -= sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSuffix = fallBackBuf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbBuf = sizeof (fallBackBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bFallback = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = IoGetDeviceProperty (pDevExt->pPDO,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DevicePropertyDriverKeyName,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbBuf,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSuffix,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &cbBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS && bFallback)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_BUFFER_TOO_SMALL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_BUFFER_TOO_SMALL)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pcbResult = cbBuf + sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegQueryDisplaySettingsKeyName(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PWCHAR pSuffix;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool bFallback = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync const WCHAR* pKeyPrefix;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cbKeyPrefix;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UNICODE_STRING* pVGuid = vboxWddmVGuidGet(pDevExt);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pVGuid);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pVGuid)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_UNSUCCESSFUL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWinVersion_t ver = VBoxQueryWinVersion();
6fd13c2e3e855d7f5a7147cb0414af050e1503e6vboxsync if (ver == WINVERSION_VISTA)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pKeyPrefix = VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbKeyPrefix = sizeof (VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
6fd13c2e3e855d7f5a7147cb0414af050e1503e6vboxsync Assert(ver > WINVERSION_VISTA);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pKeyPrefix = VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbKeyPrefix = sizeof (VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG cbResult = cbKeyPrefix + pVGuid->Length + 2 + 8; // L"\\" + "XXXX"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbBuf >= cbResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wcscpy(pBuf, pKeyPrefix);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSuffix = pBuf + (cbKeyPrefix-2)/2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pSuffix, pVGuid->Buffer, pVGuid->Length);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSuffix += pVGuid->Length/2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSuffix[0] = L'\\';
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSuffix += 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync swprintf(pSuffix, L"%04d", VidPnSourceId);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_BUFFER_TOO_SMALL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pcbResult = cbResult;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsyncNTSTATUS vboxWddmRegQueryVideoGuidString(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync BOOLEAN fNewMethodSucceeded = FALSE;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync HANDLE hKey = NULL;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DEVICE, GENERIC_READ, &hKey);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync if (NT_SUCCESS(Status))
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync {
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync struct
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync {
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync KEY_VALUE_PARTIAL_INFORMATION Info;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync UCHAR Buf[1024]; /* should be enough */
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync } KeyData;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync ULONG cbResult;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync UNICODE_STRING RtlStr;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync RtlInitUnicodeString(&RtlStr, L"VideoID");
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync Status = ZwQueryValueKey(hKey,
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync &RtlStr,
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync KeyValuePartialInformation,
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync &KeyData.Info,
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync sizeof(KeyData),
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync &cbResult);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync if (NT_SUCCESS(Status))
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync {
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync if (KeyData.Info.Type == REG_SZ)
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync {
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync fNewMethodSucceeded = TRUE;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync *pcbResult = KeyData.Info.DataLength + 2;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync if (cbBuf >= KeyData.Info.DataLength)
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync {
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync memcpy(pBuf, KeyData.Info.Data, KeyData.Info.DataLength + 2);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync Status = STATUS_SUCCESS;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync }
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync else
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync Status = STATUS_BUFFER_TOO_SMALL;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync }
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync }
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync else
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync {
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync WARN(("ZwQueryValueKey failed, Status 0x%x", Status));
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync }
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync NTSTATUS tmpStatus = ZwClose(hKey);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync Assert(tmpStatus == STATUS_SUCCESS);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync }
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync else
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync {
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync WARN(("IoOpenDeviceRegistryKey failed Status 0x%x", Status));
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync }
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync if (fNewMethodSucceeded)
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync return Status;
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync else
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync WARN(("failed to acquire the VideoID, falling back to the old impl"));
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync Status = vboxWddmRegOpenKey(&hKey, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY, GENERIC_READ);
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync //Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync struct
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KEY_BASIC_INFORMATION Name;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WCHAR Buf[256];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } Buf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WCHAR KeyBuf[sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY)/2 + 256 + 64];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wcscpy(KeyBuf, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG ResultLength;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BOOL bFound = FALSE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (ULONG i = 0; !bFound; ++i)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RtlZeroMemory(&Buf, sizeof (Buf));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = ZwEnumerateKey(hKey, i, KeyBasicInformation, &Buf, sizeof (Buf), &ResultLength);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* we should not encounter STATUS_NO_MORE_ENTRIES here since this would mean we did not find our entry */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status != STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HANDLE hSubKey;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PWCHAR pSubBuf = KeyBuf + (sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY) - 2)/2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pSubBuf, Buf.Name.Name, Buf.Name.NameLength);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSubBuf += Buf.Name.NameLength/2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pSubBuf, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY, sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmRegOpenKey(&hSubKey, KeyBuf, GENERIC_READ);
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync //Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync struct
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KEY_VALUE_PARTIAL_INFORMATION Info;
0593640ab087e5bf747a2576b1752a2046be83aavboxsync UCHAR Buf[sizeof (VBOX_WDDM_DRIVERNAME)]; /* should be enough */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } KeyData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG cbResult;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UNICODE_STRING RtlStr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RtlInitUnicodeString(&RtlStr, L"Service");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = ZwQueryValueKey(hSubKey,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &RtlStr,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeyValuePartialInformation,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &KeyData.Info,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync sizeof(KeyData),
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &cbResult);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS || STATUS_BUFFER_TOO_SMALL || STATUS_BUFFER_OVERFLOW);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (KeyData.Info.Type == REG_SZ)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
0593640ab087e5bf747a2576b1752a2046be83aavboxsync if (KeyData.Info.DataLength == sizeof (VBOX_WDDM_DRIVERNAME))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
0593640ab087e5bf747a2576b1752a2046be83aavboxsync if (!wcscmp(VBOX_WDDM_DRIVERNAME, (PWCHAR)KeyData.Info.Data))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bFound = TRUE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pcbResult = Buf.Name.NameLength + 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbBuf >= Buf.Name.NameLength + 2)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pBuf, Buf.Name.Name, Buf.Name.NameLength + 2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_BUFFER_TOO_SMALL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS tmpStatus = ZwClose(hSubKey);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(tmpStatus == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS tmpStatus = ZwClose(hKey);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(tmpStatus == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsyncNTSTATUS vboxWddmRegOpenKeyEx(OUT PHANDLE phKey, IN HANDLE hRootKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync OBJECT_ATTRIBUTES ObjAttr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UNICODE_STRING RtlStr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RtlInitUnicodeString(&RtlStr, pName);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, hRootKey, NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return ZwOpenKey(phKey, fAccess, &ObjAttr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsyncNTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync{
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync return vboxWddmRegOpenKeyEx(phKey, NULL, pName, fAccess);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync}
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsyncNTSTATUS vboxWddmRegOpenDisplaySettingsKey(IN PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, OUT PHANDLE phKey)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WCHAR Buf[512];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG cbBuf = sizeof(Buf);
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync NTSTATUS Status = vboxWddmRegQueryDisplaySettingsKeyName(pDevExt, VidPnSourceId, cbBuf, Buf, &cbBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmRegOpenKey(phKey, Buf, GENERIC_READ);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if(Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
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 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *phKey = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegDisplaySettingsQueryRelX(HANDLE hKey, int * pResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD dwVal;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX, &dwVal);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pResult = (int)dwVal;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegDisplaySettingsQueryRelY(HANDLE hKey, int * pResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD dwVal;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY, &dwVal);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pResult = (int)dwVal;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsyncNTSTATUS vboxWddmDisplaySettingsQueryPos(IN PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, POINT * pPos)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HANDLE hKey;
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync NTSTATUS Status = vboxWddmRegOpenDisplaySettingsKey(pDevExt, VidPnSourceId, &hKey);
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync //Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int x, y;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmRegDisplaySettingsQueryRelX(hKey, &x);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmRegDisplaySettingsQueryRelY(hKey, &y);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pPos->x = x;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pPos->y = y;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS tmpStatus = ZwClose(hKey);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(tmpStatus == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
0593640ab087e5bf747a2576b1752a2046be83aavboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsyncvoid vboxWddmDisplaySettingsCheckPos(IN PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync{
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync POINT Pos = {0};
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync NTSTATUS Status = vboxWddmDisplaySettingsQueryPos(pDevExt, VidPnSourceId, &Pos);
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync if (!NT_SUCCESS(Status))
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync {
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync Log(("vboxWddmDisplaySettingsQueryPos failed %#x", Status));
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync return;
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync }
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync if (!memcmp(&pSource->VScreenPos, &Pos, sizeof (Pos)))
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync return;
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync pSource->VScreenPos = Pos;
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync}
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncNTSTATUS vboxWddmRegDrvFlagsSet(PVBOXMP_DEVEXT pDevExt, DWORD fVal)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync HANDLE hKey = NULL;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_WRITE, &hKey);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!NT_SUCCESS(Status))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return Status;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Status = vboxWddmRegSetValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, fVal);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!NT_SUCCESS(Status))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync WARN(("vboxWddmRegSetValueDword failed, Status = 0x%x", Status));
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync NTSTATUS tmpStatus = ZwClose(hKey);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(tmpStatus == STATUS_SUCCESS);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return Status;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncDWORD vboxWddmRegDrvFlagsGet(PVBOXMP_DEVEXT pDevExt, DWORD fDefault)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync HANDLE hKey = NULL;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_READ, &hKey);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!NT_SUCCESS(Status))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return fDefault;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync DWORD dwVal = 0;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, &dwVal);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!NT_SUCCESS(Status))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync WARN(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status));
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync dwVal = fDefault;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync NTSTATUS tmpStatus = ZwClose(hKey);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(tmpStatus == STATUS_SUCCESS);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return dwVal;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync struct
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KEY_VALUE_PARTIAL_INFORMATION Info;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UCHAR Buf[32]; /* should be enough */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } Buf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG cbBuf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UNICODE_STRING RtlStr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RtlInitUnicodeString(&RtlStr, pName);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = ZwQueryValueKey(hKey,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &RtlStr,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeyValuePartialInformation,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &Buf.Info,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync sizeof(Buf),
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &cbBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Buf.Info.Type == REG_DWORD)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Buf.Info.DataLength == 4);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pDword = *((PULONG)Buf.Info.Data);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_INVALID_PARAMETER;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncNTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, IN DWORD val)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UNICODE_STRING RtlStr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RtlInitUnicodeString(&RtlStr, pName);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return ZwSetValueKey(hKey, &RtlStr,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NULL, /* IN ULONG TitleIndex OPTIONAL, reserved */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync REG_DWORD,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &val,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync sizeof(val));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncUNICODE_STRING* vboxWddmVGuidGet(PVBOXMP_DEVEXT pDevExt)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pDevExt->VideoGuid.Buffer)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return &pDevExt->VideoGuid;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WCHAR VideoGuidBuf[512];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG cbVideoGuidBuf = sizeof (VideoGuidBuf);
56a67728661fcf47fd03bafdc7b5b33050c4a551vboxsync NTSTATUS Status = vboxWddmRegQueryVideoGuidString(pDevExt ,cbVideoGuidBuf, VideoGuidBuf, &cbVideoGuidBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PWCHAR pBuf = (PWCHAR)vboxWddmMemAllocZero(cbVideoGuidBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pBuf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(pBuf, VideoGuidBuf, cbVideoGuidBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RtlInitUnicodeString(&pDevExt->VideoGuid, pBuf);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return &pDevExt->VideoGuid;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxWddmVGuidFree(PVBOXMP_DEVEXT pDevExt)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pDevExt->VideoGuid.Buffer)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pDevExt->VideoGuid.Buffer);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDevExt->VideoGuid.Buffer = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* mm */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxMmInit(PVBOXWDDM_MM pMm, UINT cPages)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cbBuffer = VBOXWDDM_ROUNDBOUND(cPages, 8) >> 3;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbBuffer = VBOXWDDM_ROUNDBOUND(cbBuffer, 4);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PULONG pBuf = (PULONG)vboxWddmMemAllocZero(cbBuffer);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pBuf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_NO_MEMORY;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RtlInitializeBitMap(&pMm->BitMap, pBuf, cPages);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMm->cPages = cPages;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMm->cAllocs = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMm->pBuffer = pBuf;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncULONG vboxMmAlloc(PVBOXWDDM_MM pMm, UINT cPages)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ULONG iPage = RtlFindClearBitsAndSet(&pMm->BitMap, cPages, 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iPage == 0xFFFFFFFF)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VBOXWDDM_MM_VOID;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ++pMm->cAllocs;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return iPage;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxMmFree(PVBOXWDDM_MM pMm, UINT iPage, UINT cPages)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(RtlAreBitsSet(&pMm->BitMap, iPage, cPages));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RtlClearBits(&pMm->BitMap, iPage, cPages);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync --pMm->cAllocs;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pMm->cAllocs < UINT32_MAX);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxMmTerm(PVBOXWDDM_MM pMm)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pMm->cAllocs);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pMm->pBuffer);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMm->pBuffer = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct VBOXVIDEOCM_ALLOC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_HANDLE hGlobalHandle;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t offData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync} VBOXVIDEOCM_ALLOC, *PVBOXVIDEOCM_ALLOC;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct VBOXVIDEOCM_ALLOC_REF
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_CONTEXT pContext;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_HANDLE hSessionHandle;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC pAlloc;
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync PKEVENT pSynchEvent;
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync volatile uint32_t cRefs;
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync PVOID pvUm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MDL Mdl;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync} VBOXVIDEOCM_ALLOC_REF, *PVBOXVIDEOCM_ALLOC_REF;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoCmAllocAlloc(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_UNSUCCESSFUL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cbSize = pAlloc->cbData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cPages = BYTES_TO_PAGES(cbSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExAcquireFastMutex(&pMgr->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT iPage = vboxMmAlloc(&pMgr->Mm, cPages);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (iPage != VBOXWDDM_MM_VOID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t offData = pMgr->offData + (iPage << PAGE_SHIFT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(offData + cbSize <= pMgr->offData + pMgr->cbData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAlloc->offData = offData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAlloc->hGlobalHandle = vboxWddmHTablePut(&pMgr->AllocTable, pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExReleaseFastMutex(&pMgr->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (VBOXWDDM_HANDLE_INVALID != pAlloc->hGlobalHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_NO_MEMORY;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxMmFree(&pMgr->Mm, iPage, cPages);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExReleaseFastMutex(&pMgr->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxVideoCmAllocDealloc(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cbSize = pAlloc->cbData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cPages = BYTES_TO_PAGES(cbSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT iPage = BYTES_TO_PAGES(pAlloc->offData - pMgr->offData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExAcquireFastMutex(&pMgr->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmHTableRemove(&pMgr->AllocTable, pAlloc->hGlobalHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxMmFree(&pMgr->Mm, iPage, cPages);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExReleaseFastMutex(&pMgr->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrAllocCreate(PVBOXVIDEOCM_ALLOC_MGR pMgr, UINT cbSize, PVBOXVIDEOCM_ALLOC *ppAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC pAlloc = (PVBOXVIDEOCM_ALLOC)vboxWddmMemAllocZero(sizeof (*pAlloc));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAlloc->cbData = cbSize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxVideoCmAllocAlloc(pMgr, pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *ppAlloc = pAlloc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_NO_MEMORY;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncVOID vboxVideoAMgrAllocDestroy(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoCmAllocDealloc(pMgr, pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocMap(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, PVBOXVIDEOCM_ALLOC pAlloc, PVBOXVIDEOCM_UM_ALLOC pUmAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_MGR pMgr = pContext->pMgr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_SUCCESS;
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync PKEVENT pSynchEvent = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync if (pUmAlloc->hSynch)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync Status = ObReferenceObjectByHandle((HANDLE)pUmAlloc->hSynch, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync (PVOID*)&pSynchEvent,
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync NULL);
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync Assert(Status == STATUS_SUCCESS);
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync Assert(pSynchEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID BaseVa = pMgr->pvData + pAlloc->offData - pMgr->offData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync SIZE_T cbLength = pAlloc->cbData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmMemAllocZero(sizeof (*pAllocRef) + sizeof (PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseVa, cbLength));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pAllocRef)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync pAllocRef->cRefs = 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MmInitializeMdl(&pAllocRef->Mdl, BaseVa, cbLength);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync __try
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MmProbeAndLockPages(&pAllocRef->Mdl, KernelMode, IoWriteAccess);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync __except(EXCEPTION_EXECUTE_HANDLER)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_UNSUCCESSFUL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVOID pvUm = MmMapLockedPagesSpecifyCache(&pAllocRef->Mdl, UserMode, MmNonCached,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NULL, /* PVOID BaseAddress */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync FALSE, /* ULONG BugCheckOnFailure */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NormalPagePriority);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pvUm)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync pAllocRef->pvUm = pvUm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAllocRef->pContext = pContext;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAllocRef->pAlloc = pAlloc;
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync pAllocRef->fUhgsmiType = pUmAlloc->fUhgsmiType;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAllocRef->pSynchEvent = pSynchEvent;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExAcquireFastMutex(&pContext->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pAllocRef->hSessionHandle = vboxWddmHTablePut(&pContext->AllocTable, pAllocRef);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExReleaseFastMutex(&pContext->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (VBOXWDDM_HANDLE_INVALID != pAllocRef->hSessionHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pUmAlloc->hAlloc = pAllocRef->hSessionHandle;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pUmAlloc->cbData = pAlloc->cbData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pUmAlloc->pvData = (uint64_t)pvUm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync MmUnmapLockedPages(pvUm, &pAllocRef->Mdl);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MmUnlockPages(&pAllocRef->Mdl);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pAllocRef);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_NO_MEMORY;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSynchEvent)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ObDereferenceObject(pSynchEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocUnmap(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle, PVBOXVIDEOCM_ALLOC *ppAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExAcquireFastMutex(&pContext->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmHTableRemove(&pContext->AllocTable, hSesionHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExReleaseFastMutex(&pContext->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pAllocRef)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync /* wait for the dereference, i.e. for all commands involving this allocation to complete */
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync vboxWddmCounterU32Wait(&pAllocRef->cRefs, 1);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync MmUnmapLockedPages(pAllocRef->pvUm, &pAllocRef->Mdl);
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MmUnlockPages(&pAllocRef->Mdl);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *ppAlloc = pAllocRef->pAlloc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pAllocRef->pSynchEvent)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ObDereferenceObject(pAllocRef->pSynchEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pAllocRef);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_INVALID_PARAMETER;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic PVBOXVIDEOCM_ALLOC_REF vboxVideoAMgrCtxAllocRefAcquire(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExAcquireFastMutex(&pContext->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmHTableGet(&pContext->AllocTable, hSesionHandle);
89e7cf07867002de412e51705596d0d84f90f0d9vboxsync if (pAllocRef)
89e7cf07867002de412e51705596d0d84f90f0d9vboxsync ASMAtomicIncU32(&pAllocRef->cRefs);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExReleaseFastMutex(&pContext->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pAllocRef;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsyncstatic VOID vboxVideoAMgrCtxAllocRefRelease(PVBOXVIDEOCM_ALLOC_REF pRef)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync uint32_t cRefs = ASMAtomicDecU32(&pRef->cRefs);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync Assert(cRefs < UINT32_MAX/2);
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 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocCreate(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, PVBOXVIDEOCM_UM_ALLOC pUmAlloc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC pAlloc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_MGR pMgr = pContext->pMgr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxVideoAMgrAllocCreate(pMgr, pUmAlloc->cbData, &pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxVideoAMgrCtxAllocMap(pContext, pAlloc, pUmAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoAMgrAllocDestroy(pMgr, pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxAllocDestroy(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC pAlloc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_MGR pMgr = pContext->pMgr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxVideoAMgrCtxAllocUnmap(pContext, hSesionHandle, &pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoAMgrAllocDestroy(pMgr, pAlloc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#ifdef VBOX_WITH_CRHGSMI
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic DECLCALLBACK(VOID) vboxVideoAMgrAllocSubmitCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* we should be called from our DPC routine */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync
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 UINT cBufs = pBody->cBuffers;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (UINT i = 0; i < cBufs; ++i)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync PVBOXVIDEOCM_ALLOC_REF pRef = (PVBOXVIDEOCM_ALLOC_REF)pBufCmd->u64GuestData;
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync if (!pBufCmd->u32GuestData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* signal completion */
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync if (pRef->pSynchEvent)
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync KeSetEvent(pRef->pSynchEvent, 3, FALSE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync vboxVideoAMgrCtxAllocRefRelease(pRef);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
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)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync /* ensure we do not overflow the 32bit buffer size value */
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync if (VBOXWDDM_TRAILARRAY_MAXELEMENTSU32(VBOXVDMACMD_CHROMIUM_CMD, aBuffers) < cBuffers)
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync {
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync WARN(("number of buffers passed too big (%d), max is (%d)", cBuffers, VBOXWDDM_TRAILARRAY_MAXELEMENTSU32(VBOXVDMACMD_CHROMIUM_CMD, aBuffers)));
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync return STATUS_INVALID_PARAMETER;
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync }
c7b7a1b4cf96bfc77188e54d0e510190424d5d14vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[cBuffers]));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pDr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // vboxVdmaCBufDrCreate zero initializes the pDr
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDr->cbBuf = cbCmd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pDr->rc = VERR_NOT_IMPLEMENTED;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr->u32CmdSpecific = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pBody->cBuffers = cBuffers;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (UINT i = 0; i < cBuffers; ++i)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
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 if (pRef)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync#ifdef DEBUG_misha
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync Assert(pRef->cRefs == 2);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pBufCmd->offBuffer = pRef->pAlloc->offData + pBufInfo->Info.offData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pBufCmd->cbBuffer = pBufInfo->Info.cbData;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pBufCmd->u32GuestData = 0;
521d8df5a1a304406b911c2e2c7bf9214d6d9200vboxsync pBufCmd->u64GuestData = (uint64_t)pRef;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
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 {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmdJ = &pBody->aBuffers[j];
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync PVBOXVIDEOCM_ALLOC_REF pRefJ = (PVBOXVIDEOCM_ALLOC_REF)pBufCmdJ;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync vboxVideoAMgrCtxAllocRefRelease(pRefJ);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_INVALID_PARAMETER;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
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 vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync WARN(("vboxVdmaCBufDrSubmit failed with rc (%d)\n", rc));
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync /* failure branch */
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync /* release all previously acquired aloc references */
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync for (UINT i = 0; i < cBuffers; ++i)
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync PVBOXVIDEOCM_ALLOC_REF pRef = (PVBOXVIDEOCM_ALLOC_REF)pBufCmd;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync vboxVideoAMgrCtxAllocRefRelease(pRef);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* @todo: try flushing.. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LOGREL(("vboxVdmaCBufDrCreate returned NULL"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCreate(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_MGR pMgr, uint32_t offData, uint32_t cbData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!(offData & (PAGE_SIZE -1)));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!(cbData & (PAGE_SIZE -1)));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offData = VBOXWDDM_ROUNDBOUND(offData, PAGE_SIZE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbData &= (~(PAGE_SIZE -1));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cbData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!cbData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_INVALID_PARAMETER;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExInitializeFastMutex(&pMgr->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = vboxWddmHTableCreate(&pMgr->AllocTable, 64);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxMmInit(&pMgr->Mm, BYTES_TO_PAGES(cbData));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PHYSICAL_ADDRESS PhysicalAddress = {0};
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync PhysicalAddress.QuadPart = VBoxCommonFromDeviceExt(pDevExt)->phVRAM.QuadPart + offData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMgr->pvData = (uint8_t*)MmMapIoSpace(PhysicalAddress, cbData, MmNonCached);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pMgr->pvData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pMgr->pvData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMgr->offData = offData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMgr->cbData = cbData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_UNSUCCESSFUL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxMmTerm(&pMgr->Mm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmHTableDestroy(&pMgr->AllocTable);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_MGR pMgr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MmUnmapIoSpace(pMgr->pvData, pMgr->cbData);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxMmTerm(&pMgr->Mm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmHTableDestroy(&pMgr->AllocTable);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxCreate(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC_CONTEXT pCtx)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_NOT_SUPPORTED;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pMgr->pvData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ExInitializeFastMutex(&pCtx->Mutex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxWddmHTableCreate(&pCtx->AllocTable, 32);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCtx->pMgr = pMgr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoAMgrCtxDestroy(PVBOXVIDEOCM_ALLOC_CONTEXT pCtx)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pCtx->pMgr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXWDDM_HTABLE_ITERATOR Iter;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmHTableIterInit(&pCtx->AllocTable, &Iter);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync do
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_ALLOC_REF pRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmHTableIterNext(&Iter, NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pRef)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync Assert(0);
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = vboxVideoAMgrCtxAllocDestroy(pCtx, pRef->hSessionHandle);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status != STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // vboxWddmHTableIterRemoveCur(&Iter);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmHTableDestroy(&pCtx->AllocTable);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsyncVOID vboxWddmSleep(uint32_t u32Val)
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync{
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync LARGE_INTEGER Interval;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync KeDelayExecutionThread(KernelMode, FALSE, &Interval);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync}
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsyncVOID vboxWddmCounterU32Wait(uint32_t volatile * pu32, uint32_t u32Val)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync{
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync LARGE_INTEGER Interval;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync uint32_t u32CurVal;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync while ((u32CurVal = ASMAtomicReadU32(pu32)) != u32Val)
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync {
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync Assert(u32CurVal >= u32Val);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync Assert(u32CurVal < UINT32_MAX/2);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync KeDelayExecutionThread(KernelMode, FALSE, &Interval);
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync }
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync}
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync/* dump user-mode driver debug info */
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncstatic char g_aVBoxUmdD3DCAPS9[304];
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncstatic VBOXDISPIFESCAPE_DBGDUMPBUF_FLAGS g_VBoxUmdD3DCAPS9Flags;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncstatic BOOLEAN g_bVBoxUmdD3DCAPS9IsInited = FALSE;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncstatic void vboxUmdDumpDword(DWORD *pvData, DWORD cData)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync{
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync char aBuf[16*4];
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync DWORD dw1, dw2, dw3, dw4;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync for (UINT i = 0; i < (cData & (~3)); i+=4)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync {
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw1 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw2 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw3 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw4 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync sprintf(aBuf, "0x%08x, 0x%08x, 0x%08x, 0x%08x,\n", dw1, dw2, dw3, dw4);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync LOGREL(("%s", aBuf));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync }
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync cData = cData % 4;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync switch (cData)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync {
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync case 3:
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw1 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw2 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw3 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync sprintf(aBuf, "0x%08x, 0x%08x, 0x%08x\n", dw1, dw2, dw3);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync LOGREL(("%s", aBuf));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync break;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync case 2:
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw1 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw2 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync sprintf(aBuf, "0x%08x, 0x%08x\n", dw1, dw2);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync LOGREL(("%s", aBuf));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync break;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync case 1:
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync dw1 = *pvData++;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync sprintf(aBuf, "0x%8x\n", dw1);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync LOGREL(("%s", aBuf));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync break;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync default:
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync break;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync }
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync}
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncstatic void vboxUmdDumpD3DCAPS9(void *pvData, PVBOXDISPIFESCAPE_DBGDUMPBUF_FLAGS pFlags)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync{
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync AssertCompile(!(sizeof (g_aVBoxUmdD3DCAPS9) % sizeof (DWORD)));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync LOGREL(("*****Start Dumping D3DCAPS9:*******"));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync LOGREL(("WoW64 flag(%d)", (UINT)pFlags->WoW64));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync vboxUmdDumpDword((DWORD*)pvData, sizeof (g_aVBoxUmdD3DCAPS9) / sizeof (DWORD));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync LOGREL(("*****End Dumping D3DCAPS9**********"));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync}
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsyncNTSTATUS vboxUmdDumpBuf(PVBOXDISPIFESCAPE_DBGDUMPBUF pBuf, uint32_t cbBuffer)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync{
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync if (cbBuffer < RT_OFFSETOF(VBOXDISPIFESCAPE_DBGDUMPBUF, aBuf[0]))
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync {
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync WARN(("Buffer too small"));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync return STATUS_BUFFER_TOO_SMALL;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync }
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync NTSTATUS Status = STATUS_SUCCESS;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync uint32_t cbString = cbBuffer - RT_OFFSETOF(VBOXDISPIFESCAPE_DBGDUMPBUF, aBuf[0]);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync switch (pBuf->enmType)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync {
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync case VBOXDISPIFESCAPE_DBGDUMPBUF_TYPE_D3DCAPS9:
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync {
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync if (cbString != sizeof (g_aVBoxUmdD3DCAPS9))
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync {
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync WARN(("wrong caps size, expected %d, but was %d", sizeof (g_aVBoxUmdD3DCAPS9), cbString));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync Status = STATUS_INVALID_PARAMETER;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync break;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync }
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync if (g_bVBoxUmdD3DCAPS9IsInited)
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync {
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync if (!memcmp(g_aVBoxUmdD3DCAPS9, pBuf->aBuf, sizeof (g_aVBoxUmdD3DCAPS9)))
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync break;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync WARN(("caps do not match!"));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync vboxUmdDumpD3DCAPS9(pBuf->aBuf, &pBuf->Flags);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync break;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync }
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync memcpy(g_aVBoxUmdD3DCAPS9, pBuf->aBuf, sizeof (g_aVBoxUmdD3DCAPS9));
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync g_VBoxUmdD3DCAPS9Flags = pBuf->Flags;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync g_bVBoxUmdD3DCAPS9IsInited = TRUE;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync vboxUmdDumpD3DCAPS9(pBuf->aBuf, &pBuf->Flags);
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync }
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync }
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync return Status;
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync}
706ec8d33965b04fc59fb0b1b0981b81ae23600dvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync#if 0
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncVOID vboxShRcTreeInit(PVBOXMP_DEVEXT pDevExt)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync{
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync ExInitializeFastMutex(&pDevExt->ShRcTreeMutex);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pDevExt->ShRcTree = NULL;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync}
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncVOID vboxShRcTreeTerm(PVBOXMP_DEVEXT pDevExt)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync{
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync Assert(!pDevExt->ShRcTree);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pDevExt->ShRcTree = NULL;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync}
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncBOOLEAN vboxShRcTreePut(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync{
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync HANDLE hSharedRc = pAlloc->hSharedHandle;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (!hSharedRc)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync {
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync WARN(("invalid call with zero shared handle!"));
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return FALSE;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync }
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync pAlloc->ShRcTreeEntry.Key = (AVLPVKEY)hSharedRc;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync ExAcquireFastMutex(&pDevExt->ShRcTreeMutex);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync bool bRc = RTAvlPVInsert(&pDevExt->ShRcTree, &pAlloc->ShRcTreeEntry);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync ExReleaseFastMutex(&pDevExt->ShRcTreeMutex);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync Assert(bRc);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return (BOOLEAN)bRc;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync}
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
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{
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync ExAcquireFastMutex(&pDevExt->ShRcTreeMutex);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync PAVLPVNODECORE pNode = RTAvlPVGet(&pDevExt->ShRcTree, (AVLPVKEY)hSharedRc);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync ExReleaseFastMutex(&pDevExt->ShRcTreeMutex);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (!pNode)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return NULL;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync PVBOXWDDM_ALLOCATION pAlloc = PVBOXWDDM_ALLOCATION_FROM_SHRCTREENODE(pNode);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return pAlloc;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync}
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncBOOLEAN vboxShRcTreeRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync{
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync HANDLE hSharedRc = pAlloc->hSharedHandle;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (!hSharedRc)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync {
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync WARN(("invalid call with zero shared handle!"));
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return FALSE;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync }
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync ExAcquireFastMutex(&pDevExt->ShRcTreeMutex);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync PAVLPVNODECORE pNode = RTAvlPVRemove(&pDevExt->ShRcTree, (AVLPVKEY)hSharedRc);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync ExReleaseFastMutex(&pDevExt->ShRcTreeMutex);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (!pNode)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return NULL;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync PVBOXWDDM_ALLOCATION pRetAlloc = PVBOXWDDM_ALLOCATION_FROM_SHRCTREENODE(pNode);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync Assert(pRetAlloc == pAlloc);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return !!pRetAlloc;
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync}
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync#endif
e6ad2e18e663b076aeabfec994947514566a7accvboxsync
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsyncNTSTATUS vboxWddmDrvCfgInit(PUNICODE_STRING pRegStr)
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync{
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync HANDLE hKey;
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync OBJECT_ATTRIBUTES ObjAttr;
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync InitializeObjectAttributes(&ObjAttr, pRegStr, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync NTSTATUS Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjAttr);
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync if (!NT_SUCCESS(Status))
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync {
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync WARN(("ZwOpenKey for settings key failed, Status 0x%x", Status));
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync return Status;
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync }
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync DWORD dwValue = 0;
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_CFG_STR_LOG_UM, &dwValue);
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync if (NT_SUCCESS(Status))
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync g_VBoxLogUm = dwValue;
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync ZwClose(hKey);
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync return Status;
2088626fab9fc35bf666c34053fe9fdce1da1203vboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS vboxWddmThreadCreate(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync NTSTATUS fStatus;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync HANDLE hThread;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync OBJECT_ATTRIBUTES fObjectAttributes;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync NULL, NULL);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync &fObjectAttributes, NULL, NULL,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync (PKSTART_ROUTINE) pStartRoutine, pStartContext);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (!NT_SUCCESS(fStatus))
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return fStatus;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KernelMode, (PVOID*) ppThread, NULL);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync ZwClose(hThread);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return STATUS_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync#ifdef VBOX_VDMA_WITH_WATCHDOG
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncstatic int vboxWddmWdProgram(PVBOXMP_DEVEXT pDevExt, uint32_t cMillis)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync int rc = VINF_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMICommandAlloc(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, sizeof (VBOXVDMA_CTL), HGSMI_CH_VBVA, VBVA_VDMA_CTL);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (pCmd)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pCmd->enmCtl = VBOXVDMA_CTL_TYPE_WATCHDOG;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pCmd->u32Offset = cMillis;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pCmd->i32Result = VERR_NOT_SUPPORTED;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pCmd);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync Assert(pHdr);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (pHdr)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync do
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync Assert(offCmd != HGSMIOFFSET_VOID);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (offCmd != HGSMIOFFSET_VOID)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBoxVideoCmnPortWriteUlong(VBoxCommonFromDeviceExt(pDevExt)->guestCtx.port, offCmd);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = VBoxSHGSMICommandDoneSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync AssertRC(rc);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (RT_SUCCESS(rc))
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = pCmd->i32Result;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync AssertRC(rc);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync break;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync else
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = VERR_INVALID_PARAMETER;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync /* fail to submit, cancel it */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBoxSHGSMICommandCancelSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync } while (0);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBoxSHGSMICommandFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pCmd);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync else
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync LOGREL(("HGSMIHeapAlloc failed"));
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = VERR_OUT_OF_RESOURCES;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return rc;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncstatic uint32_t g_VBoxWdTimeout = 4000;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync/* if null g_VBoxWdTimeout / 2 is used */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncstatic uint32_t g_VBoxWdTimerPeriod = 0;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncstatic VOID vboxWddmWdThread(PVOID pvUser)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvUser;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync BOOLEAN bExit = FALSE;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync int rc;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync while (1)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (!bExit)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = vboxWddmWdProgram(pDevExt, g_VBoxWdTimeout /* ms */);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync AssertRC(rc);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync else
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = vboxWddmWdProgram(pDevExt, 0 /* to disable WatchDog */);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync AssertRC(rc);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync break;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync LARGE_INTEGER Timeout;
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 if (Status != STATUS_TIMEOUT)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync bExit = TRUE;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS vboxWddmWdInit(PVBOXMP_DEVEXT pDevExt)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeInitializeEvent(&pDevExt->WdEvent, NotificationEvent, FALSE);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync NTSTATUS Status = vboxWddmThreadCreate(&pDevExt->pWdThread, vboxWddmWdThread, pDevExt);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (!NT_SUCCESS(Status))
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync WARN(("vboxWddmThreadCreate failed, Status 0x%x", Status));
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pDevExt->pWdThread = NULL;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return Status;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS vboxWddmWdTerm(PVBOXMP_DEVEXT pDevExt)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (!pDevExt->pWdThread)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return STATUS_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeSetEvent(&pDevExt->WdEvent, 0, FALSE);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeWaitForSingleObject(pDevExt->pWdThread, Executive, KernelMode, FALSE, NULL);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync ObDereferenceObject(pDevExt->pWdThread);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pDevExt->pWdThread = NULL;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return STATUS_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync#endif
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncstatic int vboxWddmSlConfigure(PVBOXMP_DEVEXT pDevExt, uint32_t fFlags)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync PHGSMIGUESTCOMMANDCONTEXT pCtx = &VBoxCommonFromDeviceExt(pDevExt)->guestCtx;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBVASCANLINECFG *pCfg;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync int rc = VINF_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync /* Allocate the IO buffer. */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pCfg = (VBVASCANLINECFG *)VBoxHGSMIBufferAlloc(pCtx,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync sizeof (VBVASCANLINECFG), HGSMI_CH_VBVA,
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBVA_SCANLINE_CFG);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (pCfg)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync /* Prepare data to be sent to the host. */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pCfg->rc = VERR_NOT_IMPLEMENTED;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pCfg->fFlags = fFlags;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = VBoxHGSMIBufferSubmit(pCtx, pCfg);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (RT_SUCCESS(rc))
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync AssertRC(pCfg->rc);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = pCfg->rc;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync /* Free the IO buffer. */
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBoxHGSMIBufferFree(pCtx, pCfg);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync else
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync rc = VERR_NO_MEMORY;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return rc;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS VBoxWddmSlEnableVSyncNotification(PVBOXMP_DEVEXT pDevExt, BOOLEAN fEnable)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync if (!pDevExt->bVSyncTimerEnabled == !fEnable)
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync return STATUS_SUCCESS;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (!fEnable)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeCancelTimer(&pDevExt->VSyncTimer);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync else
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
f566a1c9e055abedd946dae571515798986ed5c5vboxsync KeQuerySystemTime((PLARGE_INTEGER)&pDevExt->VSyncTime);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync LARGE_INTEGER DueTime;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync DueTime.QuadPart = -166666LL; /* 60 Hz */
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync KeSetTimerEx(&pDevExt->VSyncTimer, DueTime, 16, &pDevExt->VSyncDpc);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pDevExt->bVSyncTimerEnabled = !!fEnable;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return STATUS_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS VBoxWddmSlGetScanLine(PVBOXMP_DEVEXT pDevExt, DXGKARG_GETSCANLINE *pGetScanLine)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync Assert((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays > pGetScanLine->VidPnTargetId);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[pGetScanLine->VidPnTargetId];
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(pTarget->Size.cx);
359416647a711739d1b14addbf399178949a1a60vboxsync Assert(pTarget->Size.cy);
359416647a711739d1b14addbf399178949a1a60vboxsync if (pTarget->Size.cy)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync uint32_t curScanLine;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync BOOL bVBlank;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync LARGE_INTEGER DevVSyncTime;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync DevVSyncTime.QuadPart = ASMAtomicReadU64((volatile uint64_t*)&pDevExt->VSyncTime.QuadPart);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync LARGE_INTEGER VSyncTime;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync KeQuerySystemTime(&VSyncTime);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync if (VSyncTime.QuadPart < DevVSyncTime.QuadPart)
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync {
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync WARN(("vsync time is less than the one stored in device"));
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync curScanLine = 0;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync }
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync else
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync {
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync VSyncTime.QuadPart = VSyncTime.QuadPart - DevVSyncTime.QuadPart;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync /* time is in 100ns, */
359416647a711739d1b14addbf399178949a1a60vboxsync curScanLine = (uint32_t)((pTarget->Size.cy * VSyncTime.QuadPart) / DevVSyncTime.QuadPart);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync if (pDevExt->bVSyncTimerEnabled)
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync if (curScanLine >= pTarget->Size.cy)
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync curScanLine = 0;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync }
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync else
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync curScanLine %= pTarget->Size.cy;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync }
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync bVBlank = (!curScanLine || curScanLine > pTarget->Size.cy);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pGetScanLine->ScanLine = curScanLine;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pGetScanLine->InVerticalBlank = bVBlank;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync else
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pGetScanLine->InVerticalBlank = TRUE;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pGetScanLine->ScanLine = 0;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return STATUS_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsyncstatic BOOLEAN vboxWddmSlVSyncIrqCb(PVOID pvContext)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvContext;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync BOOLEAN bNeedDpc = FALSE;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync if (pTarget->fConnected)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
8dae3060fb3284c5fbd949cc1a9f823017629ffevboxsync#ifdef VBOX_WDDM_WIN8
8dae3060fb3284c5fbd949cc1a9f823017629ffevboxsync notify.InterruptType = g_VBoxDisplayOnly?
8dae3060fb3284c5fbd949cc1a9f823017629ffevboxsync DXGK_INTERRUPT_DISPLAYONLY_VSYNC:
8dae3060fb3284c5fbd949cc1a9f823017629ffevboxsync DXGK_INTERRUPT_CRTC_VSYNC;
8dae3060fb3284c5fbd949cc1a9f823017629ffevboxsync#else
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync notify.InterruptType = DXGK_INTERRUPT_CRTC_VSYNC;
8dae3060fb3284c5fbd949cc1a9f823017629ffevboxsync#endif
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync notify.CrtcVsync.VidPnTargetId = i;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync bNeedDpc = TRUE;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync if (bNeedDpc)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync {
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync }
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync return FALSE;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync}
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsyncstatic VOID vboxWddmSlVSyncDpc(
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync __in struct _KDPC *Dpc,
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync __in_opt PVOID DeferredContext,
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync __in_opt PVOID SystemArgument1,
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync __in_opt PVOID SystemArgument2
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync)
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync{
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)DeferredContext;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync Assert(!pDevExt->fVSyncInVBlank);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync ASMAtomicWriteU32(&pDevExt->fVSyncInVBlank, 1);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync BOOLEAN bDummy;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pDevExt->u.primary.DxgkInterface.DeviceHandle,
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync vboxWddmSlVSyncIrqCb,
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pDevExt,
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync 0, /* IN ULONG MessageNumber */
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync &bDummy);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync if (!NT_SUCCESS(Status))
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync WARN(("DxgkCbSynchronizeExecution failed Status %#x", Status));
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync LARGE_INTEGER VSyncTime;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync KeQuerySystemTime(&VSyncTime);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync ASMAtomicWriteU64((volatile uint64_t*)&pDevExt->VSyncTime.QuadPart, VSyncTime.QuadPart);
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync ASMAtomicWriteU32(&pDevExt->fVSyncInVBlank, 0);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS VBoxWddmSlInit(PVBOXMP_DEVEXT pDevExt)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pDevExt->bVSyncTimerEnabled = FALSE;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pDevExt->fVSyncInVBlank = 0;
f566a1c9e055abedd946dae571515798986ed5c5vboxsync KeQuerySystemTime((PLARGE_INTEGER)&pDevExt->VSyncTime);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeInitializeTimer(&pDevExt->VSyncTimer);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeInitializeDpc(&pDevExt->VSyncDpc, vboxWddmSlVSyncDpc, pDevExt);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return STATUS_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsyncNTSTATUS VBoxWddmSlTerm(PVBOXMP_DEVEXT pDevExt)
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync{
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync KeCancelTimer(&pDevExt->VSyncTimer);
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync return STATUS_SUCCESS;
e637cb22e348f5665d5473dae55ed785aa7b6e9avboxsync}
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync#ifdef VBOX_WDDM_WIN8
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncvoid vboxWddmDiInitDefault(DXGK_DISPLAY_INFORMATION *pInfo, PHYSICAL_ADDRESS PhAddr, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync{
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pInfo->Width = 1024;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pInfo->Height = 768;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pInfo->Pitch = pInfo->Width * 4;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pInfo->ColorFormat = D3DDDIFMT_A8R8G8B8;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pInfo->PhysicAddress = PhAddr;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pInfo->TargetId = VidPnSourceId;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pInfo->AcpiId = 0;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync}
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncvoid vboxWddmDiToAllocData(PVBOXMP_DEVEXT pDevExt, const DXGK_DISPLAY_INFORMATION *pInfo, PVBOXWDDM_ALLOC_DATA pAllocData)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync{
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.width = pInfo->Width;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.height = pInfo->Height;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.format = pInfo->ColorFormat;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pInfo->ColorFormat);
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.pitch = pInfo->Pitch;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.depth = 1;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pAllocData->SurfDesc.slicePitch = pInfo->Pitch;
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
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync /* the address here is not a VRAM offset! so convert it to offset */
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync vboxWddmAddrSetVram(&pAllocData->Addr, 1,
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync vboxWddmVramAddrToOffset(pDevExt, pInfo->PhysicAddress));
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync}
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsyncvoid vboxWddmDmSetupDefaultVramLocation(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID ModifiedVidPnSourceId, VBOXWDDM_SOURCE *paSources)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync PVBOXWDDM_SOURCE pSource = &paSources[ModifiedVidPnSourceId];
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync AssertRelease(g_VBoxDisplayOnly);
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync ULONG offVram = vboxWddmVramCpuVisibleSegmentSize(pDevExt);
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync offVram /= VBoxCommonFromDeviceExt(pDevExt)->cDisplays;
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync offVram &= ~PAGE_OFFSET_MASK;
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync offVram *= ModifiedVidPnSourceId;
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync if (vboxWddmAddrSetVram(&pSource->AllocData.Addr, 1, offVram))
28cbd612d23d0c7c9c909206f050919495d29a2cvboxsync pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync}
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync#endif