VBoxMPWddm.cpp revision 00ef464add2ac67ce0d698c9d02f720ef9e9a372
05afe08870681beb0792f384475077c988916762vboxsync * VBox WDDM Miniport driver
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2011-2013 Oracle Corporation
05afe08870681beb0792f384475077c988916762vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
05afe08870681beb0792f384475077c988916762vboxsync * available from http://www.virtualbox.org. This file is free software;
05afe08870681beb0792f384475077c988916762vboxsync * you can redistribute it and/or modify it under the terms of the GNU
05afe08870681beb0792f384475077c988916762vboxsync * General Public License (GPL) as published by the Free Software
05afe08870681beb0792f384475077c988916762vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
05afe08870681beb0792f384475077c988916762vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
05afe08870681beb0792f384475077c988916762vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
05afe08870681beb0792f384475077c988916762vboxsync#include <wingdi.h> /* needed for RGNDATA definition */
05afe08870681beb0792f384475077c988916762vboxsync#include <VBoxDisplay.h> /* this is from Additions/WINNT/include/ to include escape codes */
05afe08870681beb0792f384475077c988916762vboxsync#define VBOXWDDM_DUMMY_DMABUFFER_SIZE (sizeof (VBOXCMDVBVA_HDR) / 2)
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync return ExAllocatePoolWithTag(NonPagedPool, cbSize, VBOXWDDM_MEMTAG);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncDECLINLINE(void) VBoxWddmOaHostIDReleaseLocked(PVBOXWDDM_OPENALLOCATION pOa)
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync PVBOXWDDM_ALLOCATION pAllocation = pOa->pAllocation;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync Assert(pAllocation->AllocData.cHostIDRefs >= pOa->cHostIDRefs);
05afe08870681beb0792f384475077c988916762vboxsyncDECLINLINE(void) VBoxWddmOaHostIDCheckReleaseLocked(PVBOXWDDM_OPENALLOCATION pOa)
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncDECLINLINE(void) VBoxWddmOaRelease(PVBOXWDDM_OPENALLOCATION pOa)
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync PVBOXWDDM_ALLOCATION pAllocation = pOa->pAllocation;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync KeAcquireSpinLock(&pAllocation->OpenLock, &OldIrql);
05afe08870681beb0792f384475077c988916762vboxsync KeReleaseSpinLock(&pAllocation->OpenLock, OldIrql);
05afe08870681beb0792f384475077c988916762vboxsync KeReleaseSpinLock(&pAllocation->OpenLock, OldIrql);
05afe08870681beb0792f384475077c988916762vboxsyncDECLINLINE(PVBOXWDDM_OPENALLOCATION) VBoxWddmOaSearchLocked(PVBOXWDDM_DEVICE pDevice, PVBOXWDDM_ALLOCATION pAllocation)
05afe08870681beb0792f384475077c988916762vboxsync for (PLIST_ENTRY pCur = pAllocation->OpenList.Flink; pCur != &pAllocation->OpenList; pCur = pCur->Flink)
05afe08870681beb0792f384475077c988916762vboxsync PVBOXWDDM_OPENALLOCATION pCurOa = CONTAINING_RECORD(pCur, VBOXWDDM_OPENALLOCATION, ListEntry);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncDECLINLINE(PVBOXWDDM_OPENALLOCATION) VBoxWddmOaSearch(PVBOXWDDM_DEVICE pDevice, PVBOXWDDM_ALLOCATION pAllocation)
05afe08870681beb0792f384475077c988916762vboxsync KeAcquireSpinLock(&pAllocation->OpenLock, &OldIrql);
05afe08870681beb0792f384475077c988916762vboxsync pOa = VBoxWddmOaSearchLocked(pDevice, pAllocation);
05afe08870681beb0792f384475077c988916762vboxsync KeReleaseSpinLock(&pAllocation->OpenLock, OldIrql);
05afe08870681beb0792f384475077c988916762vboxsyncDECLINLINE(int) VBoxWddmOaSetHostID(PVBOXWDDM_DEVICE pDevice, PVBOXWDDM_ALLOCATION pAllocation, uint32_t hostID, uint32_t *pHostID)
05afe08870681beb0792f384475077c988916762vboxsync KeAcquireSpinLock(&pAllocation->OpenLock, &OldIrql);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync pOa = VBoxWddmOaSearchLocked(pDevice, pAllocation);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync KeReleaseSpinLock(&pAllocation->OpenLock, OldIrql);;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync WARN(("hostID differ: alloc(%d), trying to assign(%d)", pAllocation->AllocData.hostID, hostID));
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync KeReleaseSpinLock(&pAllocation->OpenLock, OldIrql);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncDECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromHandle(PVBOXMP_DEVEXT pDevExt, D3DKMT_HANDLE hAllocation)
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync return (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncDECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromAllocList(PVBOXMP_DEVEXT pDevExt, DXGK_ALLOCATIONLIST *pAllocList)
05afe08870681beb0792f384475077c988916762vboxsync PVBOXWDDM_OPENALLOCATION pOa = (PVBOXWDDM_OPENALLOCATION)pAllocList->hDeviceSpecificAllocation;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncstatic void vboxWddmPopulateDmaAllocInfo(PVBOXWDDM_DMA_ALLOCINFO pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pDmaAlloc)
05afe08870681beb0792f384475077c988916762vboxsync pInfo->offAlloc = (VBOXVIDEOOFFSET)pDmaAlloc->PhysicalAddress.QuadPart;
05afe08870681beb0792f384475077c988916762vboxsync pInfo->srcId = pAlloc->AllocData.SurfDesc.VidPnSourceId;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncstatic void vboxWddmPopulateDmaAllocInfoWithOffset(PVBOXWDDM_DMA_ALLOCINFO pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pDmaAlloc, uint32_t offStart)
09776500e6fe37b0613ab81ad127c6c14639386bvboxsync pInfo->offAlloc = (VBOXVIDEOOFFSET)pDmaAlloc->PhysicalAddress.QuadPart + offStart;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync pInfo->srcId = pAlloc->AllocData.SurfDesc.VidPnSourceId;
09776500e6fe37b0613ab81ad127c6c14639386bvboxsyncint vboxWddmGhDisplayPostInfoScreen(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData, const POINT * pVScreenPos, uint16_t fFlags)
05afe08870681beb0792f384475077c988916762vboxsync void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
05afe08870681beb0792f384475077c988916762vboxsync int rc = vboxWddmScreenInfoInit(pScreen, pAllocData, pVScreenPos, fFlags);
05afe08870681beb0792f384475077c988916762vboxsync pScreen->u32StartOffset = 0; //(uint32_t)offVram; /* we pretend the view is located at the start of each framebuffer */
05afe08870681beb0792f384475077c988916762vboxsync rc = VBoxHGSMIBufferSubmit (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync VBoxHGSMIBufferFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
05afe08870681beb0792f384475077c988916762vboxsyncint vboxWddmGhDisplayPostInfoView(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData)
05afe08870681beb0792f384475077c988916762vboxsync VBOXVIDEOOFFSET offVram = vboxWddmAddrFramOffset(&pAllocData->Addr);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync /* Issue the screen info command. */
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync pView->u32ViewIndex = pAllocData->SurfDesc.VidPnSourceId;
05afe08870681beb0792f384475077c988916762vboxsync pView->u32ViewOffset = (uint32_t)offVram; /* we pretend the view is located at the start of each framebuffer */
05afe08870681beb0792f384475077c988916762vboxsync pView->u32ViewSize = vboxWddmVramCpuVisibleSegmentSize(pDevExt)/VBoxCommonFromDeviceExt(pDevExt)->cDisplays;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync int rc = VBoxHGSMIBufferSubmit (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync VBoxHGSMIBufferFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncNTSTATUS vboxWddmGhDisplayPostResizeLegacy(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData, const POINT * pVScreenPos, uint16_t fFlags)
05afe08870681beb0792f384475077c988916762vboxsync rc = vboxWddmGhDisplayPostInfoView(pDevExt, pAllocData);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync WARN(("vboxWddmGhDisplayPostInfoView failed %d", rc));
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync rc = vboxWddmGhDisplayPostInfoScreen(pDevExt, pAllocData, pVScreenPos, fFlags);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync WARN(("vboxWddmGhDisplayPostInfoScreen failed %d", rc));
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncNTSTATUS vboxWddmGhDisplayPostResizeNew(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData, const uint32_t *pTargetMap, const POINT * pVScreenPos, uint16_t fFlags)
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync int rc = VBoxCmdVbvaConCmdResize(pDevExt, pAllocData, pTargetMap, pVScreenPos, fFlags);
05afe08870681beb0792f384475077c988916762vboxsyncNTSTATUS vboxWddmGhDisplaySetMode(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData)
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync VBOXVIDEOOFFSET offVram = vboxWddmAddrFramOffset(&pAllocData->Addr);;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync ULONG cbLine = VBOXWDDM_ROUNDBOUND(((width * bpp) + 7) / 8, 4);
05afe08870681beb0792f384475077c988916762vboxsync VBoxVideoSetModeRegisters(width, height, width, bpp, 0, (uint16_t)xOffset, (uint16_t)yOffset);
05afe08870681beb0792f384475077c988916762vboxsync /*@todo read back from port to check if mode switch was successful */
05afe08870681beb0792f384475077c988916762vboxsyncNTSTATUS vboxWddmGhDisplaySetInfoLegacy(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData, const POINT * pVScreenPos, uint8_t u8CurCyncState)
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync uint16_t fu16Flags = fEnabled ? VBVA_SCREEN_F_ACTIVE : VBVA_SCREEN_F_DISABLED;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync if ((u8CurCyncState & VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY) == VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync Status = vboxVdmaTexPresentSetAlloc(pDevExt, pAllocData);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync WARN(("vboxVdmaTexPresentSetAlloc failed, Status 0x%x", Status));
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync Status = vboxWddmGhDisplaySetMode(pDevExt, pAllocData);
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync Status = vboxWddmGhDisplayPostResizeLegacy(pDevExt, pAllocData, pVScreenPos,
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync Status = vboxVdmaTexPresentSetAlloc(pDevExt, pAllocData);
05afe08870681beb0792f384475077c988916762vboxsync WARN(("vboxVdmaTexPresentSetAlloc failed, Status 0x%x", Status));
05afe08870681beb0792f384475077c988916762vboxsync WARN(("vboxWddmGhDisplayPostResize failed, Status 0x%x", Status));
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync WARN(("vboxWddmGhDisplaySetMode failed, Status 0x%x", Status));
95e56b6db151d1f9011694dcc552a6012f305a2avboxsyncNTSTATUS vboxWddmGhDisplaySetInfoNew(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData, const uint32_t *pTargetMap, const POINT * pVScreenPos, uint8_t u8CurCyncState)
05afe08870681beb0792f384475077c988916762vboxsync uint16_t fu16Flags = fEnabled ? VBVA_SCREEN_F_ACTIVE : VBVA_SCREEN_F_DISABLED;
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync if ((u8CurCyncState & VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY) == VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY
95e56b6db151d1f9011694dcc552a6012f305a2avboxsync Status = vboxVdmaTexPresentSetAlloc(pDevExt, pAllocData);
05afe08870681beb0792f384475077c988916762vboxsync WARN(("vboxVdmaTexPresentSetAlloc failed, Status 0x%x", Status));
e0e7da0420be1398d23ffa9953686d3a43619abdvboxsync Status = vboxWddmGhDisplaySetMode(pDevExt, pAllocData);
#ifdef VBOX_WITH_CROGL
return STATUS_SUCCESS;
return STATUS_SUCCESS;
return Status;
bool vboxWddmGhDisplayCheckSetInfoFromSourceNew(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, bool fReportTargets)
if (fReportTargets)
NTSTATUS Status = vboxWddmGhDisplaySetInfoNew(pDevExt, &pSource->AllocData, pTargetMap, &pSource->VScreenPos, pSource->u8SyncState);
if (fReportTargets && (pSource->u8SyncState & VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY) != VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY)
VBoxVidPnStTIterInit(pSource, pDevExt->aTargets, VBoxCommonFromDeviceExt(pDevExt)->cDisplays, &Iter);
bool vboxWddmGhDisplayCheckSetInfoFromSourceLegacy(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, bool fReportTargets)
if (!fReportTargets)
VBoxVidPnStTIterInit(pSource, pDevExt->aTargets, VBoxCommonFromDeviceExt(pDevExt)->cDisplays, &Iter);
NTSTATUS Status = vboxWddmGhDisplaySetInfoLegacy(pDevExt, &AllocData, &pSource->VScreenPos, pSource->u8SyncState | pTarget->u8SyncState);
u8SyncState = 0;
bool vboxWddmGhDisplayCheckSetInfoFromSourceEx(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, bool fReportTargets)
bool fFound = false;
Assert(pTarget->VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
fFound = true;
if (!fFound)
Assert(pTarget->VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
bool fFound = false;
Assert(pTarget->VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
fFound = true;
return fFound;
if (fReportTargets)
if (fReportTargets)
#ifdef VBOX_WITH_VDMA
return NULL;
#ifdef VBOX_WITH_VDMA
VBOXWDDM_HGSMICMD_TYPE vboxWddmHgsmiGetCmdTypeFromOffset(PVBOXMP_DEVEXT pDevExt, HGSMIOFFSET offCmd)
#ifdef VBOX_WITH_VDMA
return VBOXWDDM_HGSMICMD_TYPE_DMACMD;
return VBOXWDDM_HGSMICMD_TYPE_CTL;
return VBOXWDDM_HGSMICMD_TYPE_UNDEFINED;
typedef struct VBOXWDDM_HWRESOURCES
NTSTATUS vboxWddmPickResources(PVBOXMP_DEVEXT pDevExt, PDXGK_DEVICE_INFO pDeviceInfo, PVBOXWDDM_HWRESOURCES pHwResources)
if (VBoxHGSMIIsSupported ())
case CmResourceTypePort:
case CmResourceTypeInterrupt:
case CmResourceTypeMemory:
case CmResourceTypeDma:
case CmResourceTypeBusNumber:
return Status;
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_VDMA_WITH_WATCHDOG
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
if (ulRatio)
#ifdef VBOX_WITH_CROGL
return STATUS_UNSUCCESSFUL;
WARN(("too few VRAM memory %d, cmdVbva %d, while approximately needed %d, trying to adjust", cbAvailable, cbCmdVbva, cbCmdVbvaApprox));
return STATUS_UNSUCCESSFUL;
return STATUS_SUCCESS;
return STATUS_UNSUCCESSFUL;
#ifdef VBOX_WITH_CROGL
return Status;
return STATUS_UNSUCCESSFUL;
#ifdef VBOX_VDMA_WITH_WATCHDOG
return rc;
PAGED_CODE();
&cbRegKeyBuf);
pDevExt = (PVBOXMP_DEVEXT)vboxWddmMemAllocZero(VBOXWDDM_ROUNDBOUND(sizeof(VBOXMP_DEVEXT), 8) + cbRegKeyBuf);
if (pDevExt)
return Status;
PAGED_CODE();
/* Save DeviceHandle and function pointers supplied by the DXGKRNL_INTERFACE structure passed to DxgkInterface. */
/* Allocate a DXGK_DEVICE_INFO structure, and call DxgkCbGetDeviceInformation to fill in the members of that structure, which include the registry path, the PDO, and a list of translated resources for the display adapter represented by MiniportDeviceContext. Save selected members (ones that the display miniport driver will need later)
Status = pDevExt->u.primary.DxgkInterface.DxgkCbGetDeviceInformation (pDevExt->u.primary.DxgkInterface.DeviceHandle, &DeviceInfo);
#ifdef VBOX_WITH_CROGL
#ifdef VBOX_WITH_VIDEOHWACCEL
#ifdef VBOX_WITH_CROGL
#ifdef VBOX_WITH_CROGL
if (hKey)
else if (hKey)
if (hKey)
#ifdef VBOX_WDDM_WIN8
Status = pDevExt->u.primary.DxgkInterface.DxgkCbAcquirePostDisplayOwnership(pDevExt->u.primary.DxgkInterface.DeviceHandle,
&DisplayInfo);
return Status;
PAGED_CODE();
#ifdef VBOX_WITH_CROGL
#ifdef VBOX_WITH_VIDEOHWACCEL
return Status;
PAGED_CODE();
return STATUS_SUCCESS;
LOGF(("ENTER, context(0x%p), ctl(0x%x)", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
return TRUE;
return TRUE;
LOGF(("LEAVE, context(0x%p), ctl(0x%x)", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
return STATUS_SUCCESS;
#ifdef VBOX_WITH_CROGL
return FALSE;
#ifdef VBOX_WITH_VIDEOHWACCEL
if (bOur)
uint8_t *pvCmd = HGSMIBufferDataAndChInfoFromOffset (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, offCmd, &chInfo);
if (!pvCmd)
switch (chInfo)
case VBVA_CMDVBVA_CTL:
int rc = VBoxSHGSMICommandProcessCompletion (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, (VBOXSHGSMIHEADER*)pvCmd, TRUE /*bool bIrq*/ , &CtlList);
#ifdef VBOX_WITH_VIDEOHWACCEL
case VBVA_VHWA_CMD:
if (bOur)
#ifdef VBOX_VDMA_WITH_WATCHDOG
Assert(0);
Assert(0);
pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, ¬ify);
if (bNeedDpc)
return bOur;
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_WITH_VIDEOHWACCEL
if (bOur)
switch (enmType)
#ifdef VBOX_WITH_VDMA
if (pHeap)
if (pvCmd)
switch (chInfo)
#ifdef VBOX_WITH_VDMA
case VBVA_VDMA_CMD:
case VBVA_VDMA_CTL:
int rc = VBoxSHGSMICommandProcessCompletion (pHeap, (VBOXSHGSMIHEADER*)pvCmd, TRUE /*bool bIrq*/ , pList);
#ifdef VBOX_WITH_VIDEOHWACCEL
case VBVA_VHWA_CMD:
#ifdef VBOX_WITH_VDMA
if (bOur)
#ifdef VBOX_VDMA_WITH_WATCHDOG
Assert(0);
Assert(0);
pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, ¬ify);
/* this is not entirely correct since host may concurrently complete some commands and raise a new IRQ while we are here,
if (bNeedDpc)
return bOur;
typedef struct VBOXWDDM_DPCDATA
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_WITH_VIDEOHWACCEL
typedef struct VBOXWDDM_GETDPCDATA_CONTEXT
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_WITH_VIDEOHWACCEL
#ifdef VBOX_WITH_CROGL
return TRUE;
#ifdef VBOX_WITH_CROGL
&context,
&bRet);
int rc = VBoxSHGSMICommandPostprocessCompletion (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, &context.data.CtlList);
#ifdef VBOX_WITH_VIDEOHWACCEL
&context,
&bRet);
int rc = VBoxSHGSMICommandPostprocessCompletion (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, &context.data.CtlList);
#ifdef VBOX_WITH_VDMA
int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.Vdma.CmdHeap, &context.data.DmaCmdList);
#ifdef VBOX_WITH_VIDEOHWACCEL
PAGED_CODE();
Assert(ChildRelationsSize == (VBoxCommonFromDeviceExt(pDevExt)->cDisplays + 1)*sizeof(DXGK_CHILD_DESCRIPTOR));
ChildRelations[i].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = D3DKMDT_VOT_HD15; /* VGA */
ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_NONE; //D3DKMDT_MOA_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/
ChildRelations[i].ChildCapabilities.HpdAwareness = HpdAwarenessInterruptible; /* ?? HpdAwarenessAlwaysConnected; */
return STATUS_SUCCESS;
PAGED_CODE();
case StatusConnection:
case StatusRotation:
return Status;
PAGED_CODE();
return STATUS_MONITOR_NO_DESCRIPTOR;
PAGED_CODE();
return STATUS_SUCCESS;
return STATUS_SUCCESS;
PAGED_CODE();
#ifdef VBOX_WITH_CROGL
VBoxVrTerm();
if (pLogger)
if (pLogger)
return STATUS_NOT_SUPPORTED;
PAGED_CODE();
case DXGKQAITYPE_DRIVERCAPS:
#ifdef VBOX_WDDM_WIN8
#ifdef RT_ARCH_AMD64
pCaps->PointerCaps.Value = 3; /* Monochrome , Color*/ /* MaskedColor == Value | 4, disable for now */
#ifdef VBOX_WDDM_WIN8
if (!g_VBoxDisplayOnly)
#ifdef VBOX_WITH_VIDEOHWACCEL
#ifdef VBOX_WDDM_WIN8
#ifdef VBOX_WDDM_WIN8
case DXGKQAITYPE_QUERYSEGMENT:
#ifdef VBOX_WDDM_WIN8
if (!g_VBoxDisplayOnly)
/* no need for DXGK_QUERYSEGMENTIN as it contains AGP aperture info, which (AGP aperture) we do not support
++pDr;
#ifdef VBOX_WDDM_WIN8
#ifdef VBOX_WDDM_WIN8
if (!g_VBoxDisplayOnly)
#ifdef VBOX_WITH_CROGL
#ifdef VBOX_WITH_VIDEOHWACCEL
WARN(("incorrect buffer size %d, expected %d", pQueryAdapterInfo->OutputDataSize, sizeof (VBOXWDDM_QI)));
#ifdef VBOX_WDDM_WIN8
#ifdef VBOX_WDDM_WIN8
return Status;
PAGED_CODE();
return Status;
PVBOXWDDM_RESOURCE pResource = (PVBOXWDDM_RESOURCE)vboxWddmMemAllocZero(RT_OFFSETOF(VBOXWDDM_RESOURCE, aAllocations[pRcInfo->cAllocInfos]));
if (!pResource)
AssertFailed();
return NULL;
return pResource;
if (!cRefs)
void vboxWddmAllocationDeleteFromResource(PVBOXWDDM_RESOURCE pResource, PVBOXWDDM_ALLOCATION pAllocation)
if (pResource)
vboxWddmAssignPrimary(&pDevExt->aSources[pAllocation->AllocData.SurfDesc.VidPnSourceId], NULL, pAllocation->AllocData.SurfDesc.VidPnSourceId);
#ifdef VBOX_WITH_CROGL
if (pSwapchain)
PAGED_CODE();
PVBOXWDDM_ALLOCATION vboxWddmAllocationCreateFromResource(PVBOXWDDM_RESOURCE pResource, uint32_t iIndex)
if (pResource)
if (pAllocation)
if (pResource)
return pAllocation;
NTSTATUS vboxWddmAllocationCreate(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_RESOURCE pResource, uint32_t iIndex, DXGK_ALLOCATIONINFO* pAllocationInfo)
PAGED_CODE();
if (pAllocation)
#ifdef VBOX_WITH_VIDEOHWACCEL
LOGREL(("ERROR: PrivateDriverDataSize(%d) less than header size(%d)", pAllocationInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
return Status;
PAGED_CODE();
return STATUS_INVALID_PARAMETER;
WARN(("invalid number of allocations passed in, (%d), expected (%d)", pRcInfo->cAllocInfos, pCreateAllocation->NumAllocations));
return STATUS_INVALID_PARAMETER;
/* a check to ensure we do not get the allocation size which is too big to overflow the 32bit value */
WARN(("number of allocations passed too big (%d), max is (%d)", pRcInfo->cAllocInfos, VBOXWDDM_TRAILARRAY_MAXELEMENTSU32(VBOXWDDM_RESOURCE, aAllocations)));
return STATUS_INVALID_PARAMETER;
pResource = (PVBOXWDDM_RESOURCE)vboxWddmMemAllocZero(RT_OFFSETOF(VBOXWDDM_RESOURCE, aAllocations[pRcInfo->cAllocInfos]));
if (!pResource)
return STATUS_NO_MEMORY;
for (UINT j = 0; j < i; ++j)
PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation;
return Status;
PAGED_CODE();
if (pRc)
if (pRc)
return Status;
memset (&pDescribeAllocation->MultisampleMethod, 0, sizeof (pDescribeAllocation->MultisampleMethod));
return STATUS_SUCCESS;
PAGED_CODE();
pAllocInfo->SurfDesc.width = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Width;
pAllocInfo->SurfDesc.height = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Height;
pAllocInfo->SurfDesc.format = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Format;
pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Width, pAllocInfo->SurfDesc.format);
pAllocInfo->SurfDesc.cbSize = vboxWddmCalcSize(pAllocInfo->SurfDesc.pitch, pAllocInfo->SurfDesc.height, pAllocInfo->SurfDesc.format);
pAllocInfo->SurfDesc.RefreshRate = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->RefreshRate;
pAllocInfo->SurfDesc.VidPnSourceId = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->VidPnSourceId;
UINT bpp = vboxWddmCalcBitsPerPixel(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format);
if (bpp != 0)
UINT Pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format);
pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, pAllocInfo->SurfDesc.format);
pAllocInfo->SurfDesc.cbSize = vboxWddmCalcSize(pAllocInfo->SurfDesc.pitch, pAllocInfo->SurfDesc.height, pAllocInfo->SurfDesc.format);
LOGREL(("Invalid format (%d)", pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format));
pAllocInfo->SurfDesc.format = D3DDDIFMT_X8R8G8B8; /* staging has always always D3DDDIFMT_X8R8G8B8 */
pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Width, pAllocInfo->SurfDesc.format);
pAllocInfo->SurfDesc.cbSize = vboxWddmCalcSize(pAllocInfo->SurfDesc.pitch, pAllocInfo->SurfDesc.height, pAllocInfo->SurfDesc.format);
return Status;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
#ifdef VBOX_WITH_CROGL
static NTSTATUS
PAGED_CODE();
uint8_t * pPrivateBuf = (uint8_t*)((uint8_t*)pPatch->pDmaBufferPrivateData + pPatch->DmaBufferPrivateDataSubmissionStartOffset);
UINT cbPatchBuff = pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset;
for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
return STATUS_INVALID_PARAMETER;
Assert(!(pAllocationList->PhysicalAddress.QuadPart & 0xfffUL)); /* <- just a check to ensure allocation offset does not go here */
return STATUS_SUCCESS;
static NTSTATUS
PAGED_CODE();
if (pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
VBOXWDDM_DMA_PRIVATEDATA_BASEHDR *pPrivateDataBase = (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR*)((uint8_t*)pPatch->pDmaBufferPrivateData + pPatch->DmaBufferPrivateDataSubmissionStartOffset);
const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
const DXGK_ALLOCATIONLIST *pSrcAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
const DXGK_ALLOCATIONLIST *pSrcAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
case VBOXVDMACMD_TYPE_DMA_NOP:
for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
DXGK_ALLOCATIONLIST *pAllocation2Patch = (DXGK_ALLOCATIONLIST*)(pPrivateBuf + pPatchList->PatchOffset);
pAllocation2Patch->PhysicalAddress.QuadPart = pAllocationList->PhysicalAddress.QuadPart + pPatchList->AllocationOffset;
Assert(!(pAllocationList->PhysicalAddress.QuadPart & 0xfffUL)); /* <- just a check to ensure allocation offset does not go here */
for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
Assert(pPatchList->PatchOffset < (pPatch->DmaBufferSubmissionEndOffset - pPatch->DmaBufferSubmissionStartOffset));
*((VBOXVIDEOOFFSET*)(pBuf+pPatchList->PatchOffset)) = (VBOXVIDEOOFFSET)pAllocationList->PhysicalAddress.QuadPart;
Assert(i == 0);
else if (pPatch->DmaBufferPrivateDataSubmissionEndOffset == pPatch->DmaBufferPrivateDataSubmissionStartOffset)
return STATUS_SUCCESS;
WARN(("DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR) (%d)",
sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
return STATUS_INVALID_PARAMETER;
return Status;
typedef struct VBOXWDDM_CALL_ISR
#ifdef VBOX_WITH_CROGL
&context,
&bRet);
return Status;
#ifdef VBOX_WITH_CRHGSMI
DECLCALLBACK(VOID) vboxWddmDmaCompleteChromiumCmd(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
#ifdef VBOX_WITH_CROGL
static NTSTATUS
#ifdef DEBUG
uint32_t cbCmd = pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset;
uint32_t cbDma = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset;
return STATUS_INVALID_PARAMETER;
cbCurDma = 0;
pHdr = (VBOXCMDVBVA_HDR*)(((uint8_t*)pSubmitCommand->pDmaBufferPrivateData) + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset);
return STATUS_INVALID_PARAMETER;
if (!pDstHdr)
return STATUS_UNSUCCESSFUL;
if (!pDstHdr)
return STATUS_UNSUCCESSFUL;
phAddr.QuadPart = pSubmitCommand->DmaBufferPhysicalAddress.QuadPart + pSubmitCommand->DmaBufferSubmissionStartOffset;
return STATUS_INVALID_PARAMETER;
pSysMem->phCmd = (VBOXCMDVBVAPHADDR)(pSubmitCommand->DmaBufferPhysicalAddress.QuadPart + pSubmitCommand->DmaBufferSubmissionStartOffset);
#ifdef DEBUG
if (!cbCmd)
if (cbDma)
u32FenceId = 0;
return Status;
static NTSTATUS
if (pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
pPrivateDataBase = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)((uint8_t*)pSubmitCommand->pDmaBufferPrivateData + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset);
else if (pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset == pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset)
WARN(("DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR) (%d)",
sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
return STATUS_INVALID_PARAMETER;
switch (enmCmd)
VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
fDstChanged = vboxWddmAddrSetVram(&pDstAlloc->AllocData.Addr, pBlt->Blt.DstAlloc.segmentIdAlloc, pBlt->Blt.DstAlloc.offAlloc);
fSrcChanged = vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pBlt->Blt.SrcAlloc.segmentIdAlloc, pBlt->Blt.SrcAlloc.offAlloc);
if (fDstChanged)
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId,
vboxWddmAddrSetVram(&pAlloc->AllocData.Addr, pFlip->Flip.Alloc.segmentIdAlloc, pFlip->Flip.Alloc.offAlloc);
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId,
vboxWddmAddrSetVram(&pCF->ClrFill.Alloc.pAlloc->AllocData.Addr, pCF->ClrFill.Alloc.segmentIdAlloc, pCF->ClrFill.Alloc.offAlloc);
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId,
case VBOXVDMACMD_TYPE_DMA_NOP:
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
if (!pDr)
return STATUS_INSUFFICIENT_RESOURCES;
pDr->cbBuf = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset;
if (pPrivateData)
pDr->Location.phBuf = pSubmitCommand->DmaBufferPhysicalAddress.QuadPart + pSubmitCommand->DmaBufferSubmissionStartOffset;
return Status;
#ifdef VBOX_WITH_CROGL
static NTSTATUS
return STATUS_SUCCESS;
static NTSTATUS
AssertFailed();
return STATUS_SUCCESS;
#ifdef VBOX_WITH_CROGL
static NTSTATUS
PAGED_CODE();
return STATUS_INVALID_PARAMETER;
case DXGK_OPERATION_TRANSFER:
return STATUS_GRAPHICS_ALLOCATION_BUSY;
return STATUS_INVALID_PARAMETER;
if ((!pBuildPagingBuffer->Transfer.Source.SegmentId) == (!pBuildPagingBuffer->Transfer.Destination.SegmentId))
WARN(("we only support RAM <-> VRAM moves, Src Seg(%d), Dst Seg(%d)", pBuildPagingBuffer->Transfer.Source.SegmentId, pBuildPagingBuffer->Transfer.Destination.SegmentId));
return STATUS_INVALID_PARAMETER;
if (!pAlloc)
return STATUS_INVALID_PARAMETER;
WARN(("pBuildPagingBuffer->DmaSize(%d) < sizeof VBOXCMDVBVA_PAGING_TRANSFER (%d)", pBuildPagingBuffer->DmaSize , sizeof (VBOXCMDVBVA_PAGING_TRANSFER)));
return STATUS_INVALID_PARAMETER;
VBOXCMDVBVA_PAGING_TRANSFER *pPaging = (VBOXCMDVBVA_PAGING_TRANSFER*)pBuildPagingBuffer->pDmaBuffer;
offVRAM += pBuildPagingBuffer->Transfer.TransferOffset + (pBuildPagingBuffer->MultipassOffset << PAGE_SHIFT);
if (fIn)
cbBuffer = VBoxCVDdiPTransferVRamSysBuildEls(pPaging, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaSize, &cPagesWritten);
VBOXCMDVBVA_SYSMEMCMD *pSysMemCmd = (VBOXCMDVBVA_SYSMEMCMD*)pBuildPagingBuffer->pDmaBufferPrivateData;
case DXGK_OPERATION_FILL:
if (!pAlloc)
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
VBOXCMDVBVA_PAGING_FILL *pFill = (VBOXCMDVBVA_PAGING_FILL*)pBuildPagingBuffer->pDmaBufferPrivateData;
if (!pAlloc)
return STATUS_INVALID_PARAMETER;
Assert(cbPrivateData >= sizeof (VBOXCMDVBVA_HDR) || pBuildPagingBuffer->Operation == DXGK_OPERATION_DISCARD_CONTENT);
Assert(cbBuffer == 0 || cbBuffer >= sizeof (VBOXCMDVBVA_PAGING_TRANSFER) || cbBuffer == VBOXWDDM_DUMMY_DMABUFFER_SIZE);
pBuildPagingBuffer->pDmaBufferPrivateData = ((uint8_t*)pBuildPagingBuffer->pDmaBufferPrivateData) + cbPrivateData;
return STATUS_SUCCESS;
static NTSTATUS
PAGED_CODE();
case DXGK_OPERATION_TRANSFER:
#ifdef VBOX_WITH_VDMA
if ((!pBuildPagingBuffer->Transfer.Source.SegmentId) != (!pBuildPagingBuffer->Transfer.Destination.SegmentId))
PVBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS pBody = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS);
uint32_t sbBufferUsed = vboxWddmBpbTransferVRamSysBuildEls(pBody, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaSize, &cPagesRemaining);
if (pAlloc
if (pDr)
case DXGK_OPERATION_FILL:
// pBuildPagingBuffer->pDmaBuffer = (uint8_t*)pBuildPagingBuffer->pDmaBuffer + VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_BPB_FILL);
if (cbCmdDma)
return Status;
return STATUS_SUCCESS;
BOOL vboxWddmPointerCopyColorData(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVIDEO_POINTER_ATTRIBUTES pPointerAttributes)
ULONG x, y;
LOGREL(("VBOXWDDM_POINTER_ATTRIBUTES_SIZE(%d) < cbPointerAttributes(%d)", VBOXWDDM_POINTER_ATTRIBUTES_SIZE, cbPointerAttributes));
return FALSE;
pDst = pPointerAttributes->Pixels + RT_ALIGN_T(dstBytesPerLine*pPointerAttributes->Height, 4, ULONG);
return TRUE;
BOOL vboxWddmPointerCopyMonoData(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVIDEO_POINTER_ATTRIBUTES pPointerAttributes)
ULONG x, y;
pDst = pPointerAttributes->Pixels + RT_ALIGN_T(dstBytesPerLine*pPointerAttributes->Height, 4, ULONG);
*(ULONG*)&pDst[y*dstBytesPerLine+x*4] = (pSrc[y*pSetPointerShape->Pitch+x/8] & RT_BIT(bit)) ? 0x00FFFFFF : 0;
return TRUE;
static BOOLEAN vboxVddmPointerShapeToAttributes(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVBOXWDDM_POINTER_INFO pPointerInfo)
return FALSE;
return FALSE;
return FALSE;
return TRUE;
PVBOXWDDM_POINTER_INFO pPointerInfo = &pDevExt->aSources[pSetPointerPosition->VidPnSourceId].PointerInfo;
BOOLEAN fScreenChanged = pGlobalPointerInfo->iLastReportedScreen != pSetPointerPosition->VidPnSourceId;
if (!fScreenVisState)
if (fScreenVisState)
if (fScreenChanged)
BOOLEAN bResult = VBoxMPCmnUpdatePointerShape(VBoxCommonFromDeviceExt(pDevExt), &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE);
BOOLEAN bResult = VBoxMPCmnUpdatePointerShape(VBoxCommonFromDeviceExt(pDevExt), &PointerAttributes, sizeof (PointerAttributes));
return STATUS_SUCCESS;
if (VBoxQueryHostWantsAbsolute())
PVBOXWDDM_POINTER_INFO pPointerInfo = &pDevExt->aSources[pSetPointerShape->VidPnSourceId].PointerInfo;
if (VBoxMPCmnUpdatePointerShape(VBoxCommonFromDeviceExt(pDevExt), &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE))
return Status;
return STATUS_SUCCESS;
PAGED_CODE();
#ifdef VBOX_WITH_CRHGSMI
case VBOXESC_UHGSMI_SUBMIT:
&& pEscape->PrivateDriverDataSize == RT_OFFSETOF(VBOXDISPIFESCAPE_UHGSMI_SUBMIT, aBuffers[pEscapeHdr->u32CmdSpecific]));
&& pEscape->PrivateDriverDataSize == RT_OFFSETOF(VBOXDISPIFESCAPE_UHGSMI_SUBMIT, aBuffers[pEscapeHdr->u32CmdSpecific]))
Status = vboxVideoAMgrCtxAllocSubmit(pDevExt, &pContext->AllocContext, pEscapeHdr->u32CmdSpecific, pSubmit->aBuffers);
case VBOXESC_UHGSMI_ALLOCATE:
Assert(pEscape->PrivateDriverDataSize > RT_OFFSETOF(VBOXDISPIFESCAPE_CRHGSMICTLCON_CALL, CallInfo));
int rc = VBoxMpCrCtlConCallUserData(&pDevExt->CrCtlCon, &pCall->CallInfo, pEscape->PrivateDriverDataSize - RT_OFFSETOF(VBOXDISPIFESCAPE_CRHGSMICTLCON_CALL, CallInfo));
Status = STATUS_SUCCESS; /* <- always return success here, otherwise the private data buffer modifications
if (!pContext)
return STATUS_INVALID_PARAMETER;
case VBOXESC_SETVISIBLEREGION:
#ifdef VBOX_DISPIF_WITH_OPCONTEXT
if (!pContext)
int rc;
WARN(("VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)", cbRects, lpRgnData->rdh.nCount));
case VBOXESC_ISVRDPACTIVE:
#ifdef VBOX_WITH_CROGL
case VBOXESC_SETCTXHOSTID:
if (!pContext)
if (hostID <= 0)
case VBOXESC_SWAPCHAININFO:
Status = vboxWddmSwapchainCtxEscape(pDevExt, pContext, (PVBOXDISPIFESCAPE_SWAPCHAININFO)pEscapeHdr, pEscape->PrivateDriverDataSize);
case VBOXESC_REINITVIDEOMODES:
#ifdef VBOX_DISPIF_WITH_OPCONTEXT
if (!pContext)
#ifdef VBOX_DISPIF_WITH_OPCONTEXT
if (!pContext)
PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK pData = (PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK)pEscapeHdr;
case VBOXESC_CONFIGURETARGETS:
#ifdef VBOX_DISPIF_WITH_OPCONTEXT
if (!pContext)
++cAdjusted;
WARN(("VBOXESC_CONFIGURETARGETS vboxWddmChildStatusConnectSecondaries failed Status 0x%x\n", Status));
if (!hKey)
WARN(("VBOXESC_CONFIGURETARGETS vboxWddmRegSetValueDword (%d) failed Status 0x%x\n", aNameBuf, Status));
if (hKey)
case VBOXESC_ADJUSTVIDEOMODES:
|| pEscape->PrivateDriverDataSize != RT_OFFSETOF(VBOXDISPIFESCAPE_ADJUSTVIDEOMODES, aScreenInfos[cModes]))
case VBOXESC_SETALLOCHOSTID:
if (!pDevice)
PVBOXWDDM_ALLOCATION pAlloc = vboxWddmGetAllocationFromHandle(pDevExt, (D3DKMT_HANDLE)pSetHostID->hAlloc);
if (!pAlloc)
pSetHostID->rc = VBoxWddmOaSetHostID(pDevice, pAlloc, pSetHostID->hostID, &pSetHostID->EscapeHdr.u32CmdSpecific);
Assert(pAlloc->AllocData.SurfDesc.VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
case VBOXESC_SHRC_ADDREF:
case VBOXESC_SHRC_RELEASE:
if (!pDevice)
/* query whether the allocation represanted by the given [wine-generated] shared resource handle still exists */
PVBOXWDDM_ALLOCATION pAlloc = vboxWddmGetAllocationFromHandle(pDevExt, (D3DKMT_HANDLE)pShRcRef->hAlloc);
if (!pAlloc)
if (!pOa)
#ifdef DEBUG
#ifdef DEBUG
case VBOXESC_ISANYX:
case VBOXESC_DBGPRINT:
/* only do DbgPrint when pEscape->PrivateDriverDataSize > RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[1])
case VBOXESC_DBGDUMPBUF:
WARN(("pEscape->PrivateDriverDataSize(%d) < (%d)", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE)));
return Status;
return STATUS_SUCCESS;
typedef struct VBOXWDDM_QUERYCURFENCE_CB
return bRc;
#ifdef VBOX_WITH_CROGL
static NTSTATUS
u32FenceCompleted = VBoxCmdVbvaCheckCompleted(pDevExt, &pDevExt->CmdVbva, false, &u32FenceSubmitted);
if (!u32FenceCompleted)
return STATUS_UNSUCCESSFUL;
WARN(("uncompleted fences, u32FenceSubmitted(%d), u32FenceCompleted(%d)", u32FenceSubmitted, u32FenceCompleted));
return STATUS_SUCCESS;
static NTSTATUS
&context,
&bRet);
return STATUS_SUCCESS;
PAGED_CODE();
Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pIsSupportedVidPnArg->hDesiredVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
return Status;
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn("\n>>>>IS SUPPORTED VidPN : >>>>", pDevExt, pIsSupportedVidPnArg->hDesiredVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<");
Status = pVidPnInterface->pfnGetTopology(pIsSupportedVidPnArg->hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
return Status;
return Status;
if (!fSupported)
#ifdef VBOXWDDM_DEBUG_VIDPN
LOGREL(("The Given VidPn is %ssupported\n", pIsSupportedVidPnArg->IsVidPnSupported ? "" : "!!NOT!! "));
return Status;
PAGED_CODE();
#ifdef DEBUG_misha
Assert(0);
PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo = pRecommendFunctionalVidPnArg->PrivateDriverDataSize >= sizeof (VBOXWDDM_RECOMMENDVIDPN) ?
Status = vboxVidPnCheckAddMonitorModes(pDevExt, i, D3DKMDT_MCO_DRIVER, pInfo->aResolutions, pInfo->cResolutions, pInfo->iPreferredResolution);
Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
return Status;
Status = vboxVidPnPathAdd(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, pVidPnInterface, i, i);
return Status;
Status = VBoxWddmGetModesForResolution(pInfo->aModes, pInfo->cModes, pInfo->iPreferredMode, &Resolution,
if (pResModes)
if (!pResModes)
Status = VBoxWddmGetModesForResolution(pInfo->aModes, pInfo->cModes, pInfo->iPreferredMode, &Resolution,
Status = vboxVidPnCreatePopulateVidPnPathFromLegacy(pDevExt, pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, pVidPnInterface,
if(pResModes)
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn("\n>>>>Recommended VidPN: >>>>", pDevExt, pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
return Status;
PAGED_CODE();
NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pEnumCofuncModalityArg->hConstrainingVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
return Status;
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn(">>>>MODALITY VidPN (IN) : >>>>\n", pDevExt, pEnumCofuncModalityArg->hConstrainingVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
Status = pVidPnInterface->pfnGetTopology(pEnumCofuncModalityArg->hConstrainingVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
return Status;
#ifdef DEBUG_misha
return Status;
return Status;
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn("\n>>>>MODALITY VidPN (OUT) : >>>>\n", pDevExt, pEnumCofuncModalityArg->hConstrainingVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n\n");
return Status;
PAGED_CODE();
WARN(("invalid VidPnSourceId (%d), for displays(%d)", pSetVidPnSourceAddress->VidPnSourceId, VBoxCommonFromDeviceExt(pDevExt)->cDisplays));
return STATUS_INVALID_PARAMETER;
if (pAllocation)
vboxWddmAddrSetVram(&pAllocation->AllocData.Addr, pSetVidPnSourceAddress->PrimarySegment, (VBOXVIDEOOFFSET)pSetVidPnSourceAddress->PrimaryAddress.QuadPart);
#ifdef VBOX_WDDM_WIN8
#ifdef VBOX_WDDM_WIN8
return Status;
PAGED_CODE();
Assert((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays > pSetVidPnSourceVisibility->VidPnSourceId);
WARN(("invalid VidPnSourceId (%d), for displays(%d)", pSetVidPnSourceVisibility->VidPnSourceId, VBoxCommonFromDeviceExt(pDevExt)->cDisplays));
return STATUS_INVALID_PARAMETER;
if (pAllocation)
return Status;
VBOXWDDM_SOURCE *paSources = (VBOXWDDM_SOURCE*)RTMemAlloc(sizeof (VBOXWDDM_SOURCE) * VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
if (!paSources)
return STATUS_NO_MEMORY;
VBOXWDDM_TARGET *paTargets = (VBOXWDDM_TARGET*)RTMemAlloc(sizeof (VBOXWDDM_TARGET) * VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
if (!paTargets)
return STATUS_NO_MEMORY;
Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn("\n>>>>COMMIT VidPN: >>>>", pDevExt, pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
return Status;
return STATUS_SUCCESS;
PVBOXWDDM_VIDEOMODES_INFO pInfo = VBoxWddmGetVideoModesInfo(pDevExt, pRecommendMonitorModesArg->VideoPresentTargetId);
return Status;
#ifdef DEBUG_misha
return Status;
return STATUS_SUCCESS;
switch (InterruptType)
return Status;
if (pOverlay)
int rc = vboxVhwaHlpOverlayCreate(pDevExt, pCreateOverlay->VidPnSourceId, &pCreateOverlay->OverlayInfo, pOverlay);
return Status;
PAGED_CODE();
return STATUS_SUCCESS;
PAGED_CODE();
UINT i = 0;
if (!pAllocation)
#ifdef DEBUG
if (pRcInfo)
#ifdef VBOX_WITH_VIDEOHWACCEL
if (pOa)
if (!pOa)
if (!pConcurrentOa)
if (pConcurrentOa)
for (UINT j = 0; j < i; ++j)
PVBOXWDDM_OPENALLOCATION pOa2Free = (PVBOXWDDM_OPENALLOCATION)pInfo2Free->hDeviceSpecificAllocation;
return Status;
PAGED_CODE();
return STATUS_SUCCESS;
#ifdef VBOX_WITH_CROGL
static NTSTATUS
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
if (pRender->AllocationListSize >= (UINT32_MAX - RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos))/ RT_SIZEOFMEMB(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[0]))
return STATUS_INVALID_PARAMETER;
if (pRender->CommandLength != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize]))
WARN(("pRender->CommandLength (%d) != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize](%d)",
pRender->CommandLength, RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize])));
return STATUS_INVALID_PARAMETER;
if (pRender->AllocationListSize >= (UINT32_MAX - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers))/ RT_SIZEOFMEMB(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[0]))
return STATUS_INVALID_PARAMETER;
WARN(("pRender->DmaBufferPrivateDataSize too small %d, requested %d", pRender->DmaBufferPrivateDataSize, cbPrivateData));
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
WARN(("pRender->PatchLocationListOutSize too small %d, requested %d", pRender->PatchLocationListOutSize, pRender->AllocationListSize));
return STATUS_INVALID_PARAMETER;
PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pUmCmd = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pInputHdr;
for (UINT i = 0; i < pRender->AllocationListSize; ++i, ++pRender->pPatchLocationListOut, ++pAllocationList, ++pSubmInfo, ++pSubmUmInfo)
return STATUS_INVALID_PARAMETER;
case VBOXVDMACMD_TYPE_DMA_NOP:
WARN(("pRender->DmaBufferPrivateDataSize too small %d, requested %d", pRender->DmaBufferPrivateDataSize, cbPrivateData));
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return Status;
static void vboxWddmPatchLocationInit(D3DDDI_PATCHLOCATIONLIST *pPatchLocationListOut, UINT idx, UINT offPatch)
static NTSTATUS
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
case VBOXVDMACMD_TYPE_DMA_NOP:
PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pDmaBufferPrivateData;
pRender->pDmaBufferPrivateData = (uint8_t*)pRender->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR);
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
return Status;
#define VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(_c) (VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[_c]))
#ifdef VBOX_WITH_VDMA
DECLINLINE(VOID) vboxWddmSurfDescFromAllocation(PVBOXWDDM_ALLOCATION pAllocation, PVBOXVDMA_SURF_DESC pDesc)
#ifdef VBOX_WITH_CROGL
DECLINLINE(void) VBoxCVDdiFillAllocDescHostID(VBOXCMDVBVA_ALLOCDESC *pDesc, const VBOXWDDM_ALLOCATION *pAlloc)
DECLINLINE(void) VBoxCVDdiFillAllocInfoOffVRAM(VBOXCMDVBVA_ALLOCINFO *pInfo, const DXGK_ALLOCATIONLIST *pList)
DECLINLINE(void) VBoxCVDdiFillAllocDescOffVRAM(VBOXCMDVBVA_ALLOCDESC *pDesc, const VBOXWDDM_ALLOCATION *pAlloc, const DXGK_ALLOCATIONLIST *pList)
static NTSTATUS vboxWddmCmCmdBltIdNotIdFill(VBOXCMDVBVA_BLT_HDR *pBltHdr, const VBOXWDDM_ALLOCATION *pIdAlloc, const VBOXWDDM_ALLOCATION *pAlloc, const DXGK_ALLOCATIONLIST *pList,
return STATUS_INVALID_PARAMETER;
if (fToId)
return STATUS_SUCCESS;
static NTSTATUS vboxWddmCmCmdBltNotIdNotIdFill(VBOXCMDVBVA_BLT_HDR *pBltHdr, const VBOXWDDM_ALLOCATION *pSrcAlloc, const DXGK_ALLOCATIONLIST *pSrcList,
return STATUS_SUCCESS;
static NTSTATUS
PAGED_CODE();
WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
return STATUS_INVALID_PARAMETER;
WARN(("Present->DmaSize(%d) < VBOXWDDM_DUMMY_DMABUFFER_SIZE (%d)", pPresent->DmaSize , VBOXWDDM_DUMMY_DMABUFFER_SIZE));
return STATUS_INVALID_PARAMETER;
if (!pSrcAlloc)
WARN(("failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
return STATUS_INVALID_HANDLE;
if (!pDstAlloc)
WARN(("failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
return STATUS_INVALID_HANDLE;
WARN(("Present->DmaBufferPrivateDataSize(%d) < (%d)", pPresent->DmaBufferPrivateDataSize , VBOXCMDVBVA_SIZEOF_BLTSTRUCT_MAX));
return STATUS_INVALID_PARAMETER;
pHdr->u8Flags |= VBOXCMDVBVA_OPF_BLT_TYPE_OFFPRIMSZFMT_OR_ID | VBOXCMDVBVA_OPF_OPERAND1_ISID | VBOXCMDVBVA_OPF_OPERAND2_ISID;
NTSTATUS Status = vboxWddmCmCmdBltIdNotIdFill(pBltHdr, pSrcAlloc, pDstAlloc, pDst, FALSE, &u32DstPatch, &cbPrivateData);
return Status;
NTSTATUS Status = vboxWddmCmCmdBltIdNotIdFill(pBltHdr, pDstAlloc, pSrcAlloc, pSrc, TRUE, &u32SrcPatch, &cbPrivateData);
return Status;
vboxWddmCmCmdBltNotIdNotIdFill(pBltHdr, pSrcAlloc, pSrc, pDstAlloc, pDst, &u32SrcPatch, &u32DstPatch, &cbPrivateData);
if (fDstPrimary)
else if (fSrcPrimary)
WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_FLIP (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_FLIP)));
return STATUS_INVALID_PARAMETER;
if (!pSrcAlloc)
WARN(("failed to get pSrc Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
return STATUS_INVALID_HANDLE;
Assert((UINT)pSrcAlloc->AllocData.SurfDesc.VidPnSourceId < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
#ifdef DEBUG_misha
Assert(pPresent->Flags.Value == 2); /* only ColorFill is set, we do not support anything else for now */
if (!pDstAlloc)
WARN(("failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
return STATUS_INVALID_HANDLE;
WARN(("Present->DmaBufferPrivateDataSize(%d) < VBOXCMDVBVA_SIZEOF_CLRFILLSTRUCT_MAX (%d)", pPresent->DmaBufferPrivateDataSize , VBOXCMDVBVA_SIZEOF_CLRFILLSTRUCT_MAX));
return STATUS_INVALID_PARAMETER;
if (fDstPrimary)
return STATUS_NOT_SUPPORTED;
if (paRects)
if (fPatchSrc)
if (fPatchDst)
return STATUS_SUCCESS;
static NTSTATUS
PAGED_CODE();
LOGREL(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)));
return STATUS_INVALID_PARAMETER;
PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)pPresent->pDmaBufferPrivateData;
if (!pSrcAlloc)
WARN(("failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
goto done;
if (!pDstAlloc)
WARN(("failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
goto done;
memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], &pPresent->pDstSubRects[pPresent->MultipassOffset], cbRects);
memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], &pPresent->pDstSubRects[pPresent->MultipassOffset], cbFitingRects);
if (!pSrcAlloc)
WARN(("failed to get pSrc Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
goto done;
Assert(pPresent->Flags.Value == 2); /* only ColorFill is set, we do not support anything else for now */
if (!pDstAlloc)
WARN(("failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
goto done;
memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
done:
return Status;
return Status;
return Status;
return Status;
PAGED_CODE();
WARN(("Invalid NodeOrdinal (%d), expected to be less that (%d)\n", pCreateContext->NodeOrdinal, VBOXWDDM_NUM_NODES));
return STATUS_INVALID_PARAMETER;
if (pContext)
#ifdef VBOX_WITH_CROGL
int rc = VBoxMpCrCtlConConnect(pDevExt, &pDevExt->CrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pContext->u32CrConClientID);
PVBOXWDDM_CREATECONTEXT_INFO pInfo = (PVBOXWDDM_CREATECONTEXT_INFO)pCreateContext->pPrivateDriverData;
#ifdef VBOX_WITH_CROGL
Status = vboxVideoCmCtxAdd(&pDevice->pAdapter->CmMgr, &pContext->CmContext, (HANDLE)pInfo->hUmEvent, pInfo->u64UmInfo);
Status = vboxVideoCmCtxAdd(&pDevice->pAdapter->SeamlessCtxMgr, &pContext->CmContext, (HANDLE)pInfo->hUmEvent, pInfo->u64UmInfo);
return Status;
if (!cContexts)
#ifdef VBOX_WITH_CROGL
#ifdef VBOX_WITH_CROGL
return Status;
return STATUS_NOT_IMPLEMENTED;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
#ifdef VBOX_WDDM_WIN8
return STATUS_SUCCESS;
if (!bUpdateRectInited)
vboxVdmaGgDmaBltPerform(pDevExt, &SrcAllocData, &pPresentDisplayOnly->pMoves[i].DestRect, &pSource->AllocData, &pPresentDisplayOnly->pMoves[i].DestRect);
vboxVdmaGgDmaBltPerform(pDevExt, &SrcAllocData, &pPresentDisplayOnly->pDirtyRect[i], &pSource->AllocData, &pPresentDisplayOnly->pDirtyRect[i]);
if (!bUpdateRectInited)
return STATUS_SUCCESS;
return STATUS_NOT_SUPPORTED;
return STATUS_NOT_SUPPORTED;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
static NTSTATUS vboxWddmInitDisplayOnlyDriver(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
DriverInitializationData.DxgkDdiStopDeviceAndReleasePostDisplayOwnership = DxgkDdiStopDeviceAndReleasePostDisplayOwnership;
return Status;
static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath, BOOLEAN fCmdVbva)
#ifdef VBOX_WITH_CROGL
DriverInitializationData.DxgkDdiInterruptRoutine = VBOXWDDM_CALLBACK_NAME(DxgkDdiInterruptRoutine, fCmdVbva);
DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = DxgkDdiGetStandardAllocationDriverData;
DriverInitializationData.DxgkDdiSubmitCommand = VBOXWDDM_CALLBACK_NAME(DxgkDdiSubmitCommand, fCmdVbva);
DriverInitializationData.DxgkDdiPreemptCommand = VBOXWDDM_CALLBACK_NAME(DxgkDdiPreemptCommand, fCmdVbva);
DriverInitializationData.DxgkDdiBuildPagingBuffer = VBOXWDDM_CALLBACK_NAME(DxgkDdiBuildPagingBuffer, fCmdVbva);
DriverInitializationData.DxgkDdiQueryCurrentFence = VBOXWDDM_CALLBACK_NAME(DxgkDdiQueryCurrentFence, fCmdVbva);
DriverInitializationData.DxgkDdiSetDisplayPrivateDriverFormat = DxgkDdiSetDisplayPrivateDriverFormat;
// DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = DxgkDdiUpdateActiveVidPnPresentPath;
return Status;
PAGED_CODE();
#ifdef VBOX_WDDM_WIN8
LOGREL(("VBox WDDM Driver for Windows 8, %d bit; Built %s %s", (sizeof (void*) << 3), __DATE__, __TIME__));
LOGREL(("VBox WDDM Driver for Windows Vista and 7, %d bit; Built %s %s", (sizeof (void*) << 3), __DATE__, __TIME__));
return STATUS_INVALID_PARAMETER;
#ifdef VBOX_WITH_CROGL
if (!VBoxMpCrCtlConIs3DSupported())
#ifdef VBOX_WDDM_WIN8
if (f3DRequired)
LOGREL(("3D is NOT supported by the host, but is required for the current guest version using this driver.."));
LOGREL(("3D is NOT supported by the host, but is NOT required for the current guest version using this driver, continuing with Disabled 3D.."));
LOGREL(("Current win8 video driver only supports display-only mode no matter whether or not host 3D is enabled!"));
#ifdef VBOX_WITH_CROGL
#ifdef VBOX_WDDM_WIN8
if (g_VBoxDisplayOnly)
#ifdef VBOX_WITH_CROGL
return Status;
#ifdef VBOX_WITH_CROGL
VBoxVrTerm();
#ifdef VBOX_WITH_CROGL
if (pLogger)
if (pLogger)
return Status;