VBoxVideoWddm.cpp revision b9efdf4f2f5a547f76dc2e254656d83cab80ce73
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2010 Oracle Corporation
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#include "../Helper.h"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#include <wingdi.h> /* needed for RGNDATA definition */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#include <VBoxDisplay.h> /* this is from Additions/WINNT/include/ to include escape codes */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return ExAllocatePoolWithTag(NonPagedPool, cbSize, VBOXWDDM_MEMTAG);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromOpenData(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OPENALLOCATION pOa)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromAllocList(PDEVICE_EXTENSION pDevExt, DXGK_ALLOCATIONLIST *pAllocList)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return vboxWddmGetAllocationFromOpenData(pDevExt, (PVBOXWDDM_OPENALLOCATION)pAllocList->hDeviceSpecificAllocation);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic void vboxWddmPopulateDmaAllocInfo(PVBOXWDDM_DMA_ALLOCINFO pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pDmaAlloc)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pInfo->offAlloc = (VBOXVIDEOOFFSET)pDmaAlloc->PhysicalAddress.QuadPart;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic void vboxWddmPopulateDmaAllocInfoWithOffset(PVBOXWDDM_DMA_ALLOCINFO pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pDmaAlloc, uint32_t offStart)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pInfo->offAlloc = (VBOXVIDEOOFFSET)pDmaAlloc->PhysicalAddress.QuadPart + offStart;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync//VBOXVIDEOOFFSET vboxWddmVRAMAddressToOffset(PDEVICE_EXTENSION pDevExt, PHYSICAL_ADDRESS phAddress)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// Assert(phAddress.QuadPart >= VBE_DISPI_LFB_PHYSICAL_ADDRESS);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// if (phAddress.QuadPart < VBE_DISPI_LFB_PHYSICAL_ADDRESS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// return VBOXVIDEOOFFSET_VOID;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// VBOXVIDEOOFFSET off = phAddress.QuadPart - VBE_DISPI_LFB_PHYSICAL_ADDRESS;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// Assert(off < pDevExt->u.primary.cbVRAM);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// if (off >= pDevExt->u.primary.cbVRAM)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// return VBOXVIDEOOFFSET_VOID;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// return off;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncVBOXVIDEOOFFSET vboxWddmValidatePrimary(PVBOXWDDM_ALLOCATION pAllocation)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf((__FUNCTION__": no allocation specified for Source\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf((__FUNCTION__": allocation is not paged in\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf((__FUNCTION__": VRAM pffset is not defined\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncNTSTATUS vboxWddmGhDisplayPostInfoScreenBySDesc (PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SURFACE_DESC pDesc, POINT * pVScreenPos, uint16_t fFlags)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync void *p = vboxHGSMIBufferAlloc (&commonFromDeviceExt(pDevExt)->guestCtx,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pScreen->u32StartOffset = 0; //(uint32_t)offVram; /* we pretend the view is located at the start of each framebuffer */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync vboxHGSMIBufferSubmit (&commonFromDeviceExt(pDevExt)->guestCtx, p);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync vboxHGSMIBufferFree (&commonFromDeviceExt(pDevExt)->guestCtx, p);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncNTSTATUS vboxWddmGhDisplayPostInfoScreen (PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation, POINT * pVScreenPos)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NTSTATUS Status = vboxWddmGhDisplayPostInfoScreenBySDesc(pDevExt, &pAllocation->SurfDesc, pVScreenPos, VBVA_SCREEN_F_ACTIVE);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncNTSTATUS vboxWddmGhDisplayPostInfoView(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Issue the screen info command. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync void *p = vboxHGSMIBufferAlloc (&commonFromDeviceExt(pDevExt)->guestCtx,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pView->u32ViewIndex = pAllocation->SurfDesc.VidPnSourceId;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pView->u32ViewOffset = (uint32_t)offVram; /* we pretend the view is located at the start of each framebuffer */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pView->u32ViewSize = vboxWddmVramCpuVisibleSegmentSize(pDevExt)/commonFromDeviceExt(pDevExt)->cDisplays;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync vboxHGSMIBufferSubmit (&commonFromDeviceExt(pDevExt)->guestCtx, p);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync vboxHGSMIBufferFree (&commonFromDeviceExt(pDevExt)->guestCtx, p);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncNTSTATUS vboxWddmGhDisplaySetMode(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimaryInfo = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (/*pPrimaryInfo->*/pAllocation->SurfDesc.VidPnSourceId)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (VBoxVideoSetCurrentModePerform(pDevExt, pAllocation->SurfDesc.width,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pAllocation->SurfDesc.height, pAllocation->SurfDesc.bpp,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf((__FUNCTION__": VBoxVideoSetCurrentModePerform failed\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncNTSTATUS vboxWddmGhDisplayUpdateScreenPos(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, POINT *pVScreenPos)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PVBOXWDDM_ALLOCATION pAllocation = VBOXWDDM_FB_ALLOCATION(pSource);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NTSTATUS Status = vboxWddmGhDisplayPostInfoScreen(pDevExt, pAllocation, &pSource->VScreenPos);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncNTSTATUS vboxWddmGhDisplaySetInfo(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PVBOXWDDM_ALLOCATION pAllocation = VBOXWDDM_FB_ALLOCATION(pSource);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VBOXVIDEOOFFSET offVram = vboxWddmValidatePrimary(pAllocation);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Set the current mode into the hardware.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// NTSTATUS Status= vboxWddmDisplaySettingsQueryPos(pDevExt, VidPnSourceId, &pSource->VScreenPos);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync// Assert(Status == STATUS_SUCCESS);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NTSTATUS Status = vboxWddmGhDisplaySetMode(pDevExt, pAllocation);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Status = vboxWddmGhDisplayPostInfoView(pDevExt, pAllocation);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Status = vboxWddmGhDisplayPostInfoScreen(pDevExt, pAllocation, &pSource->VScreenPos);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf((__FUNCTION__": vboxWddmGhDisplayPostInfoScreen failed\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf((__FUNCTION__": vboxWddmGhDisplayPostInfoView failed\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf((__FUNCTION__": vboxWddmGhDisplaySetMode failed\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncbool vboxWddmCheckUpdateShadowAddress(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, UINT SegmentId, VBOXVIDEOOFFSET offVram)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pSource->pPrimaryAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NTSTATUS Status = vboxWddmGhDisplaySetInfo(pDevExt, pSource, VidPnSourceId);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf((__FUNCTION__": vboxWddmGhDisplaySetInfo failed, Status (0x%x)\n", Status));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return true;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncHGSMIHEAP* vboxWddmHgsmiGetHeapFromCmdOffset(PDEVICE_EXTENSION pDevExt, HGSMIOFFSET offCmd)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if(HGSMIAreaContainsOffset(&pDevExt->u.primary.Vdma.CmdHeap.area, offCmd))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (HGSMIAreaContainsOffset(&commonFromDeviceExt(pDevExt)->guestCtx.heapCtx.area, offCmd))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return &commonFromDeviceExt(pDevExt)->guestCtx.heapCtx;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef enum
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncVBOXWDDM_HGSMICMD_TYPE vboxWddmHgsmiGetCmdTypeFromOffset(PDEVICE_EXTENSION pDevExt, HGSMIOFFSET offCmd)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if(HGSMIAreaContainsOffset(&pDevExt->u.primary.Vdma.CmdHeap.area, offCmd))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (HGSMIAreaContainsOffset(&commonFromDeviceExt(pDevExt)->guestCtx.heapCtx.area, offCmd))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncNTSTATUS vboxWddmPickResources(PDEVICE_EXTENSION pContext, PDXGK_DEVICE_INFO pDeviceInfo, PULONG pAdapterMemorySize)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *pAdapterMemorySize = VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID2);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync DispiId = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Write some hardware information to registry, so that
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * it's visible in Windows property dialog.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Query the adapter's memory size. It's a bit of a hack, we just read
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * an ULONG from the data port without setting an index before.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *pAdapterMemorySize = VBoxVideoCmnPortReadUlong(VBE_DISPI_IOPORT_DATA);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PCM_RESOURCE_LIST pRcList = pDeviceInfo->TranslatedResourceList;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* @todo: verify resources */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PCM_FULL_RESOURCE_DESCRIPTOR pFRc = &pRcList->List[i];
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync for (ULONG j = 0; j < pFRc->PartialResourceList.Count; ++j)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PCM_PARTIAL_RESOURCE_DESCRIPTOR pPRc = &pFRc->PartialResourceList.PartialDescriptors[j];
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf(("VBoxVideoWddm: HGSMI unsupported, returning err\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* @todo: report a better status */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf(("VBoxVideoWddm:: VBE card not found, returning err\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic void vboxWddmDevExtZeroinit(PDEVICE_EXTENSION pDevExt, CONST PDEVICE_OBJECT pPDO)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PWCHAR pName = (PWCHAR)(((uint8_t*)pDevExt) + VBOXWDDM_ROUNDBOUND(sizeof (DEVICE_EXTENSION), 8));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync for (int i = 0; i < RT_ELEMENTS(pDevExt->aSources); ++i)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDevExt->aSources[i].offVram = VBOXVIDEOOFFSET_VOID;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic void vboxWddmSetupDisplays(PDEVICE_EXTENSION pDevExt)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* For WDDM, we simply store the number of monitors as we will deal with
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VidPN stuff later */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ULONG ulAvailable = commonFromDeviceExt(pDevExt)->cbVRAM
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Align down to 4096 bytes. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = vboxVdmaCreate (pDevExt, &pDevExt->u.primary.Vdma
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* can enable it right away since the host does not need any screen/FB info
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * for basic DMA functionality */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = vboxVdmaEnable(pDevExt, &pDevExt->u.primary.Vdma);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync vboxVdmaDestroy(pDevExt, &pDevExt->u.primary.Vdma);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync NTSTATUS Status = vboxVideoAMgrCreate(pDevExt, &pDevExt->AllocMgr, offset, ulSize);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* todo: ?? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Assert(ulSize * commonFromDeviceExt(pDevExt)->cDisplays < ulAvailable);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync for (int i = commonFromDeviceExt(pDevExt)->cDisplays-1; i >= 0; --i)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = vboxVbvaCreate(pDevExt, &pDevExt->aSources[i].Vbva, offset, ulSize, i);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = vboxVbvaEnable(pDevExt, &pDevExt->aSources[i].Vbva);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* @todo: de-initialize */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = VBoxMapAdapterMemory(commonFromDeviceExt(pDevExt), (void**)&pDevExt->pvVisibleVram,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic int vboxWddmFreeDisplays(PDEVICE_EXTENSION pDevExt)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VBoxUnmapAdapterMemory(commonFromDeviceExt(pDevExt), (void**)&pDevExt->pvVisibleVram);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync for (int i = commonFromDeviceExt(pDevExt)->cDisplays-1; i >= 0; --i)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = vboxVbvaDisable(pDevExt, &pDevExt->aSources[i].Vbva);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = vboxVbvaDestroy(pDevExt, &pDevExt->aSources[i].Vbva);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* @todo: */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = vboxVdmaDisable(pDevExt, &pDevExt->u.primary.Vdma);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = vboxVdmaDestroy(pDevExt, &pDevExt->u.primary.Vdma);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/* driver callbacks */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* The DxgkDdiAddDevice function should be made pageable. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dfprintf(("==> "__FUNCTION__ ", pdo(0x%x)\n", PhysicalDeviceObject));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Status = IoGetDeviceProperty (PhysicalDeviceObject,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pDevExt = (PDEVICE_EXTENSION)vboxWddmMemAllocZero(VBOXWDDM_ROUNDBOUND(sizeof (DEVICE_EXTENSION), 8) + cbRegKeyBuf);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PWCHAR pName = (PWCHAR)(((uint8_t*)pDevExt) + VBOXWDDM_ROUNDBOUND(sizeof (DEVICE_EXTENSION), 8));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync vboxWddmDevExtZeroinit(pDevExt, PhysicalDeviceObject);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync drprintf(("VBoxVideoWddm: ERROR, failed to create context\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dfprintf(("<== "__FUNCTION__ ", Status(0x%x), pDevExt(0x%x)\n", Status, pDevExt));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* The DxgkDdiStartDevice function should be made pageable. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)MiniportDeviceContext;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Save DeviceHandle and function pointers supplied by the DXGKRNL_INTERFACE structure passed to DxgkInterface. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync memcpy(&pContext->u.primary.DxgkInterface, DxgkInterface, sizeof (DXGKRNL_INTERFACE));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* 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)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * of the DXGK_DEVICE_INFO structure in the context block represented by MiniportDeviceContext. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Status = pContext->u.primary.DxgkInterface.DxgkCbGetDeviceInformation (pContext->u.primary.DxgkInterface.DeviceHandle, &DeviceInfo);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Status = vboxWddmPickResources(pContext, &DeviceInfo, &AdapterMemorySize);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Initialize VBoxGuest library, which is used for requests which go through VMMDev. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Guest supports only HGSMI, the old VBVA via VMMDev is not supported.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * The host will however support both old and new interface to keep compatibility
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * with old guest additions.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VBoxSetupDisplaysHGSMI(commonFromDeviceExt(pContext),
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VBoxFreeDisplaysHGSMI(commonFromDeviceExt(pContext));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *NumberOfVideoPresentSources = commonFromDeviceExt(pContext)->cDisplays;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *NumberOfChildren = commonFromDeviceExt(pContext)->cDisplays;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideoWddm: sources(%d), children(%d)\n", *NumberOfVideoPresentSources, *NumberOfChildren));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync vboxVdmaDdiQueueInit(pContext, &pContext->DdiCmdQueue);
drprintf(("VBoxVideoWddm: DxgkCbGetDeviceInformation failed Status(0x%x), returning err\n", Status));
return Status;
PAGED_CODE();
#ifdef VBOX_WITH_VIDEOHWACCEL
return Status;
PAGED_CODE();
return STATUS_SUCCESS;
dfprintf(("==> "__FUNCTION__ ", context(0x%p), ctl(0x%x)\n", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
return TRUE;
return TRUE;
dfprintf(("<== "__FUNCTION__ ", context(0x%p), ctl(0x%x)\n", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
return STATUS_SUCCESS;
// dfprintf(("==> "__FUNCTION__ ", context(0x%p), msg(0x%x)\n", MiniportDeviceContext, MessageNumber));
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_WITH_VIDEOHWACCEL
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 DEBUG_misha
/* this is not entirely correct since host may concurrently complete some commands and raise a new IRQ while we are here,
if (bNeedDpc)
BOOLEAN bDpcQueued = pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
// dfprintf(("<== "__FUNCTION__ ", context(0x%p), bOur(0x%x)\n", MiniportDeviceContext, (ULONG)bOur));
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
return TRUE;
&context,
&bRet);
int rc = VBoxSHGSMICommandPostprocessCompletion (&commonFromDeviceExt(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
vboxVdmaDdiCmdHandleCompletedList(pDevExt, &pDevExt->DdiCmdQueue, &context.data.CompletedDdiCmdQueue);
PAGED_CODE();
Assert(ChildRelationsSize == (commonFromDeviceExt(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_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/
ChildRelations[i].ChildCapabilities.HpdAwareness = HpdAwarenessAlwaysConnected; //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();
return STATUS_NOT_SUPPORTED;
PAGED_CODE();
dfprintf(("==> "__FUNCTION__ ", context(0x%x), Query type (%d)\n", hAdapter, pQueryAdapterInfo->Type));
case DXGKQAITYPE_DRIVERCAPS:
pCaps->PointerCaps.Value = 3; /* Monochrome , Color*/ /* MaskedColor == Value | 4, dosable for now */
#ifdef VBOX_WITH_VIDEOHWACCEL
case DXGKQAITYPE_QUERYSEGMENT:
/* no need for DXGK_QUERYSEGMENTIN as it contains AGP aperture info, which (AGP aperture) we do not support
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
++pDr;
#ifdef VBOX_WITH_VIDEOHWACCEL
return Status;
PAGED_CODE();
// drprintf((__FUNCTION__ ": we do not support custom devices for now, hAdapter (0x%x)\n", hAdapter));
return Status;
PVBOXWDDM_ALLOCATION vboxWddmAllocationCreateFromResource(PVBOXWDDM_RESOURCE pResource, uint32_t iIndex)
if (pResource)
if (pAllocation)
if (pResource)
return pAllocation;
void vboxWddmAllocationDeleteFromResource(PVBOXWDDM_RESOURCE pResource, PVBOXWDDM_ALLOCATION pAllocation)
if (pResource)
PAGED_CODE();
vboxWddmAssignPrimary(pDevExt, &pDevExt->aSources[pAllocation->SurfDesc.VidPnSourceId], NULL, pAllocation->SurfDesc.VidPnSourceId);
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
vboxWddmAssignShadow(pDevExt, &pDevExt->aSources[pAllocation->SurfDesc.VidPnSourceId], NULL, pAllocation->SurfDesc.VidPnSourceId);
if (pSwapchain)
return STATUS_SUCCESS;
NTSTATUS vboxWddmCreateAllocation(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_RESOURCE pResource, uint32_t iIndex, DXGK_ALLOCATIONINFO* pAllocationInfo)
PAGED_CODE();
if (pAllocation)
#ifndef VBOXWDDM_RENDER_FROM_SHADOW
#ifdef VBOX_WITH_VIDEOHWACCEL
Status = ObReferenceObjectByHandle(pAllocInfo->hSynch, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
NULL);
Status = ObReferenceObjectByHandle(pAllocInfo->hSynch, EVENT_MODIFY_STATE, *ExSemaphoreObjectType, UserMode,
NULL);
drprintf((__FUNCTION__ ": ERROR: PrivateDriverDataSize(%d) less than header size(%d)\n", pAllocationInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
return Status;
PAGED_CODE();
pResource = (PVBOXWDDM_RESOURCE)vboxWddmMemAllocZero(RT_OFFSETOF(VBOXWDDM_RESOURCE, aAllocations[pRcInfo->cAllocInfos]));
if (pResource)
for (UINT j = 0; j < i; ++j)
vboxWddmDestroyAllocation(pDevExt, (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.bpp);
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, bpp);
pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, pAllocInfo->SurfDesc.bpp);
drprintf((__FUNCTION__ ": Invalid format (%d)\n", pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format));
pAllocInfo->SurfDesc.format = D3DDDIFMT_X8R8G8B8; /* staging has always always D3DDDIFMT_X8R8G8B8 */
pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Width, pAllocInfo->SurfDesc.bpp);
drprintf((__FUNCTION__ ": Invalid allocation type (%d)\n", pGetStandardAllocationDriverData->StandardAllocationType));
return Status;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
PAGED_CODE();
Assert(pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR));
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);
PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateDataBase;
const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
const DXGK_ALLOCATIONLIST *pSrcAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
pS2P->Shadow2Primary.ShadowAlloc.offAlloc = (VBOXVIDEOOFFSET)pSrcAllocationList->PhysicalAddress.QuadPart;
// const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
// pPrivateData->DstAllocInfo.segmentIdAlloc = pDstAllocationList->SegmentId;
// pPrivateData->DstAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pDstAllocationList->PhysicalAddress.QuadPart;
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);
drprintf((__FUNCTION__": DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR) (%d)\n",
sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
return STATUS_INVALID_PARAMETER;
return Status;
typedef struct VBOXWDDM_CALL_ISR
&context,
&bRet);
return Status;
return Status;
static NTSTATUS vboxWddmSubmitBltCmd(PDEVICE_EXTENSION pDevExt, VBOXWDDM_CONTEXT *pContext, UINT u32FenceId, PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt, VBOXVDMAPIPE_FLAGS_DMACMD fBltFlags)
PVBOXVDMAPIPE_CMD_DMACMD_BLT pBltCmd = (PVBOXVDMAPIPE_CMD_DMACMD_BLT)vboxVdmaGgCmdCreate(&pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_DMACMD, RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_BLT, Blt.DstRects.UpdateRects.aRects[pBlt->Blt.DstRects.UpdateRects.cRects]));
if (pBltCmd)
memcpy(&pBltCmd->Blt, &pBlt->Blt, RT_OFFSETOF(VBOXVDMA_BLT, DstRects.UpdateRects.aRects[pBlt->Blt.DstRects.UpdateRects.cRects]));
return Status;
#ifdef VBOX_WITH_VDMA
DECLCALLBACK(VOID) vboxWddmDmaCompleteChromiumCmd(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
FALSE);
Assert(0);
Assert(pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR));
if (pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
drprintf((__FUNCTION__": DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR) (%d)\n",
sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
return STATUS_INVALID_PARAMETER;
PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pPrivateDataBase = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)((uint8_t*)pSubmitCommand->pDmaBufferPrivateData + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset);
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateDataBase;
if (!cUnlockedVBVADisabled)
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
if (!cUnlockedVBVADisabled)
Status = vboxWddmSubmitBltCmd(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, pBlt, fBltFlags);
Status = vboxWddmSubmitBltCmd(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, pBlt, fBltFlags);
if (bComplete)
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
#ifdef VBOX_WITH_VDMA
VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD *pChromiumCmd = (VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD*)pPrivateDataBase;
UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[pChromiumCmd->Base.u32CmdReserved]));
if (!pDr)
return STATUS_INSUFFICIENT_RESOURCES;
vboxVdmaDdiCmdInit(pDdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxWddmDmaCompleteChromiumCmd, pDr);
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
&pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_DMACMD, sizeof (VBOXVDMAPIPE_CMD_DMACMD_FLIP));
if (pFlipCmd)
vboxVdmaDdiCmdInit(&pFlipCmd->Hdr.DdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxVdmaGgDdiCmdDestroy, pFlipCmd);
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
if (pCFCmd)
// VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pFlip->Flip.Alloc.srcId];
vboxVdmaDdiCmdInit(&pCFCmd->Hdr.DdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxVdmaGgDdiCmdDestroy, pCFCmd);
memcpy(&pCFCmd->ClrFill, &pCF->ClrFill, RT_OFFSETOF(VBOXVDMA_CLRFILL, Rects.aRects[pCF->ClrFill.Rects.cRects]));
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
case VBOXVDMACMD_TYPE_DMA_NOP:
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, 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;
return STATUS_SUCCESS;
static uint32_t vboxWddmSysMemElBuild(PVBOXVDMACMD_SYSMEMEL pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesRemaining)
--cPages;
bool bArrayMode = false;
while (cPages)
if (!bArrayMode)
++cBufs;
--cPages;
bArrayMode = true;
++cBufs;
--cPages;
if (bArrayMode)
Assert(0);
static uint32_t vboxWddmBpbTransferVRamSysBuildEls(PVBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesRemaining)
uint32_t cbBufferUsed = vboxWddmSysMemElBuild(&pCmd->FirstEl, pMdl, iPfn, cPages, cbBuffer, &cPages);
if (cbBufferUsed)
while (cPages)
cbBufferUsed = vboxWddmSysMemElBuild(pEl, pMdl, iPfn + cInitPages - cPages, cPages, cbBuffer - cbBufferUsed, &cPages);
if (cbBufferUsed)
++cEls;
Assert(0);
return cbBufferUsed;
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);
return Status;
return STATUS_SUCCESS;
BOOL vboxWddmPointerCopyColorData(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVIDEO_POINTER_ATTRIBUTES pPointerAttributes)
drprintf((__FUNCTION__": VBOXWDDM_POINTER_ATTRIBUTES_SIZE(%d) < cbPointerAttributes(%d)\n", VBOXWDDM_POINTER_ATTRIBUTES_SIZE, cbPointerAttributes));
return FALSE;
if (bitmask == 0)
return TRUE;
BOOL vboxWddmPointerCopyMonoData(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVIDEO_POINTER_ATTRIBUTES pPointerAttributes)
if (bitmask == 0)
return TRUE;
static BOOLEAN vboxVddmPointerShapeToAttributes(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVBOXWDDM_POINTER_INFO pPointerInfo)
return FALSE;
return FALSE;
drprintf((__FUNCTION__": unsupported pointer type Flags.Value(0x%x)\n", pSetPointerShape->Flags.Value));
return FALSE;
return TRUE;
PVBOXWDDM_POINTER_INFO pPointerInfo = &pDevExt->aSources[pSetPointerPosition->VidPnSourceId].PointerInfo;
BOOLEAN bResult = vboxUpdatePointerShapeWrap(commonFromDeviceExt(pDevExt), &PointerAttributes, sizeof (PointerAttributes));
return STATUS_SUCCESS;
if (vboxQueryHostWantsAbsolute())
PVBOXWDDM_POINTER_INFO pPointerInfo = &pDevExt->aSources[pSetPointerShape->VidPnSourceId].PointerInfo;
if (vboxUpdatePointerShapeWrap (commonFromDeviceExt(pDevExt), &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE))
return Status;
return STATUS_SUCCESS;
PAGED_CODE();
#ifdef VBOX_WITH_VDMA
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:
case VBOXESC_SETVISIBLEREGION:
int rc;
drprintf((__FUNCTION__": VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)\n", cbRects, lpRgnData->rdh.nCount));
case VBOXESC_ISVRDPACTIVE:
case VBOXESC_SCREENLAYOUT:
drprintf((__FUNCTION__": VBOXESC_SCREENLAYOUT: incorrect buffer size (%d) < sizeof (VBOXDISPIFESCAPE_SCREENLAYOUT) (%d)\n",
case VBOXESC_SWAPCHAININFO:
Status = vboxWddmSwapchainCtxEscape(pDevExt, pContext, (PVBOXDISPIFESCAPE_SWAPCHAININFO)pEscapeHdr, pEscape->PrivateDriverDataSize);
case VBOXESC_REINITVIDEOMODES:
case VBOXESC_DBGPRINT:
/* only do DbgPrint when pEscape->PrivateDriverDataSize > RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[1])
Assert(0);
drprintf((__FUNCTION__": pEscape->PrivateDriverDataSize(%d) < (%d)\n", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE)));
return Status;
return STATUS_SUCCESS;
typedef struct VBOXWDDM_QUERYCURFENCE_CB
return bRc;
&context,
&bRet);
return STATUS_SUCCESS;
PAGED_CODE();
NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pIsSupportedVidPnArg->hDesiredVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn("\n>>>>IS SUPPORTED VidPN : >>>>\n", pContext, pIsSupportedVidPnArg->hDesiredVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
Status = pVidPnInterface->pfnGetTopology(pIsSupportedVidPnArg->hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
Status = vboxVidPnCheckTopology(pContext, pIsSupportedVidPnArg->hDesiredVidPn, hVidPnTopology, pVidPnTopologyInterface, &bSupported);
id,
Status = vboxVidPnCheckSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnSourceModeSet, pVidPnSourceModeSetInterface, &bSupported);
pVidPnInterface->pfnReleaseSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnSourceModeSet);
drprintf(("VBoxVideoWddm: Warning: pfnAcquireSourceModeSet returned STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE, continuing\n"));
Status = vboxVidPnCheckTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnTargetModeSet, pVidPnTargetModeSetInterface, &bSupported);
pVidPnInterface->pfnReleaseTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnTargetModeSet);
drprintf(("VBoxVideoWddm: Warning: pfnAcquireSourceModeSet returned STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE, continuing\n"));
#ifdef VBOXWDDM_DEBUG_VIDPN
drprintf(("The Given VidPn is %ssupported\n\n", pIsSupportedVidPnArg->IsVidPnSupported ? "" : "!!NOT!! "));
return Status;
PAGED_CODE();
PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo = pRecommendFunctionalVidPnArg->PrivateDriverDataSize >= sizeof (VBOXWDDM_RECOMMENDVIDPN) ?
Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
Status = vboxWddmGetModesForResolution(pInfo->aModes, pInfo->cModes, pInfo->iPreferredMode, &Resolution,
if (pResModes)
if (!pResModes)
Status = vboxWddmGetModesForResolution(pInfo->aModes, pInfo->cModes, pInfo->iPreferredMode, &Resolution,
Status = vboxVidPnCreatePopulateVidPnFromLegacy(pDevExt, pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, pVidPnInterface,
if(pResModes)
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn("\n>>>>Recommended VidPN: >>>>\n", pDevExt, pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n\n");
return Status;
PAGED_CODE();
NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pEnumCofuncModalityArg->hConstrainingVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn(">>>>MODALITY VidPN (IN) : >>>>\n", pDevExt, pEnumCofuncModalityArg->hConstrainingVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n\n");
NTSTATUS Status = pVidPnInterface->pfnGetTopology(pEnumCofuncModalityArg->hConstrainingVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
Status = vboxVidPnCheckTopology(pDevExt, pEnumCofuncModalityArg->hConstrainingVidPn, hVidPnTopology, pVidPnTopologyInterface, &bSupported);
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn("\n>>>>MODALITY VidPN (OUT) : >>>>\n", pDevExt, pEnumCofuncModalityArg->hConstrainingVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n\n");
return Status;
PAGED_CODE();
Status= vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceAddress->VidPnSourceId, &pSource->VScreenPos);
if (pAllocation)
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceAddress->VidPnSourceId, commonFromDeviceExt(pDevExt)->cDisplays));
return Status;
PAGED_CODE();
Status= vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceVisibility->VidPnSourceId, &pSource->VScreenPos);
if (pAllocation)
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
#ifdef VBOX_WITH_VDMA
drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceVisibility->VidPnSourceId, commonFromDeviceExt(pDevExt)->cDisplays));
return Status;
NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
#ifdef VBOXWDDM_DEBUG_VIDPN
vboxVidPnDumpVidPn("\n>>>>COMMIT VidPN: >>>>\n", pDevExt, pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n\n");
NTSTATUS Status = pVidPnInterface->pfnGetTopology(pCommitVidPnArg->hFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
return Status;
return STATUS_SUCCESS;
PVBOXWDDM_VIDEOMODES_INFO pInfo = vboxWddmGetVideoModesInfo(pDevExt, pRecommendMonitorModesArg->VideoPresentTargetId);
FALSE);
return Status;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
if (pOverlay)
int rc = vboxVhwaHlpOverlayCreate(pDevExt, pCreateOverlay->VidPnSourceId, &pCreateOverlay->OverlayInfo, pOverlay);
return Status;
PAGED_CODE();
return STATUS_SUCCESS;
PAGED_CODE();
PVBOXWDDM_OPENALLOCATION pOa = (PVBOXWDDM_OPENALLOCATION)vboxWddmMemAllocZero(sizeof (VBOXWDDM_OPENALLOCATION));
if (pRcInfo)
#ifdef VBOX_WITH_VIDEOHWACCEL
if (pAllocation)
for (UINT j = 0; j < i; ++j)
PVBOXWDDM_OPENALLOCATION pOa2Free = (PVBOXWDDM_OPENALLOCATION)pInfo2Free->hDeviceSpecificAllocation;
return Status;
PAGED_CODE();
return STATUS_SUCCESS;
drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)\n",
return STATUS_INVALID_PARAMETER;
Assert(0);
drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)\n",
return STATUS_INVALID_PARAMETER;
if (pRender->CommandLength != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pInputHdr->u32CmdReserved]))
Assert(0);
return STATUS_INVALID_PARAMETER;
PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pUmCmd = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pInputHdr;
PVBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD pChromiumCmd = (PVBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD)pRender->pDmaBufferPrivateData;
const uint32_t cbDma = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD, aBufInfos[pInputHdr->u32CmdReserved]);
Assert(0);
return STATUS_INVALID_PARAMETER;
Assert(0);
return STATUS_INVALID_PARAMETER;
Assert(0);
return STATUS_INVALID_PARAMETER;
vboxWddmPopulateDmaAllocInfoWithOffset(&pSubmInfo->Alloc, pAlloc, pAllocationList, pSubmUmInfo->offData);
++pPLL;
++pSubmInfo;
++pSubmUmInfo;
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;
#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)
DECLINLINE(bool) vboxWddmCheckForVisiblePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
PAGED_CODE();
drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR (%d)\n", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)));
return STATUS_INVALID_PARAMETER;
PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)pPresent->pDmaBufferPrivateData;
if (pSrcAlloc)
if (pDstAlloc)
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
* otherwise we would need info about all rects being updated on primary for visible rect reporting */
if (!cContexts3D)
#ifdef VBOX_WITH_VIDEOHWACCEL
pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY);
PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateData;
memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
#ifdef VBOX_WITH_VDMA
pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offSrc);
pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offDst);
UINT i = 0;
Assert(i);
vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
Assert(i);
pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR);
drprintf((__FUNCTION__": unsupported format conversion from(%d) to (%d)\n",pSrcAlloc->SurfDesc.format, pDstAlloc->SurfDesc.format));
drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
drprintf((__FUNCTION__": failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
if (pSrcAlloc)
if (pDstAlloc)
pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offSrc);
pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offDst);
UINT i = 0;
Assert(i);
vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
Assert(i);
pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATEDATA_HDR);
drprintf((__FUNCTION__": unsupported format conversion from(%d) to (%d)\n",pSrcAlloc->SurfDesc.format, pDstAlloc->SurfDesc.format));
drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
drprintf((__FUNCTION__": failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
if (pSrcAlloc)
drprintf((__FUNCTION__": failed to get pSrc Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
Assert(pPresent->Flags.Value == 2); /* only ColorFill is set, we do not support anything else for now */
if (pDstAlloc)
memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
drprintf((__FUNCTION__": failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
return Status;
return Status;
return Status;
return Status;
PAGED_CODE();
if (pContext)
PVBOXWDDM_CREATECONTEXT_INFO pInfo = (PVBOXWDDM_CREATECONTEXT_INFO)pCreateContext->pPrivateDriverData;
Status = vboxVideoCmCtxAdd(&pDevice->pAdapter->CmMgr, &pContext->CmContext, (HANDLE)pInfo->hUmEvent, pInfo->u64UmInfo);
Assert(0);
return Status;
return Status;
return STATUS_NOT_IMPLEMENTED;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
PAGED_CODE();
return STATUS_INVALID_PARAMETER;
DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = DxgkDdiGetStandardAllocationDriverData;
DriverInitializationData.DxgkDdiSetDisplayPrivateDriverFormat = DxgkDdiSetDisplayPrivateDriverFormat;