VBoxVideoWddm.cpp revision 5cf075f1173d07b89c26db295070415dffc6109d
/*
* Copyright (C) 2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "../VBoxVideo.h"
#include "../Helper.h"
#include <VBox/VBoxGuestLib.h>
#include <VBox/VBoxVideo.h>
#include <wingdi.h> /* needed for RGNDATA definition */
#include <VBoxDisplay.h> /* this is from Additions/WINNT/include/ to include escape codes */
#define VBOXWDDM_MEMTAG 'MDBV'
{
}
{
return pvMem;
}
{
}
DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromOpenData(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OPENALLOCATION pOa)
{
}
DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromAllocList(PDEVICE_EXTENSION pDevExt, DXGK_ALLOCATIONLIST *pAllocList)
{
return vboxWddmGetAllocationFromOpenData(pDevExt, (PVBOXWDDM_OPENALLOCATION)pAllocList->hDeviceSpecificAllocation);
}
static void vboxWddmPopulateDmaAllocInfo(PVBOXWDDM_DMA_ALLOCINFO pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pDmaAlloc)
{
{
}
else
pInfo->segmentIdAlloc = 0;
}
//VBOXVIDEOOFFSET vboxWddmVRAMAddressToOffset(PDEVICE_EXTENSION pDevExt, PHYSICAL_ADDRESS phAddress)
//{
// Assert(phAddress.QuadPart >= VBE_DISPI_LFB_PHYSICAL_ADDRESS);
// if (phAddress.QuadPart < VBE_DISPI_LFB_PHYSICAL_ADDRESS)
// return VBOXVIDEOOFFSET_VOID;
//
// VBOXVIDEOOFFSET off = phAddress.QuadPart - VBE_DISPI_LFB_PHYSICAL_ADDRESS;
// Assert(off < pDevExt->u.primary.cbVRAM);
// if (off >= pDevExt->u.primary.cbVRAM)
// return VBOXVIDEOOFFSET_VOID;
//
// return off;
//}
{
if (!pAllocation)
{
return VBOXVIDEOOFFSET_VOID;
}
if (!pAllocation->SegmentId)
{
return VBOXVIDEOOFFSET_VOID;
}
if (offVram == VBOXVIDEOOFFSET_VOID)
return offVram;
}
NTSTATUS vboxWddmGhDisplayPostInfoScreenBySDesc (PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SURFACE_DESC pDesc, POINT * pVScreenPos, uint16_t fFlags)
{
sizeof (VBVAINFOSCREEN),
Assert(p);
if (p)
{
pScreen->u32StartOffset = 0; //(uint32_t)offVram; /* we pretend the view is located at the start of each framebuffer */
}
return STATUS_SUCCESS;
}
NTSTATUS vboxWddmGhDisplayPostInfoScreen (PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation, POINT * pVScreenPos)
{
NTSTATUS Status = vboxWddmGhDisplayPostInfoScreenBySDesc(pDevExt, &pAllocation->SurfDesc, pVScreenPos, VBVA_SCREEN_F_ACTIVE);
return Status;
}
{
if (offVram == VBOXVIDEOOFFSET_VOID)
return STATUS_INVALID_PARAMETER;
/* Issue the screen info command. */
sizeof (VBVAINFOVIEW),
Assert(p);
if (p)
{
pView->u32ViewOffset = (uint32_t)offVram; /* we pretend the view is located at the start of each framebuffer */
}
return STATUS_SUCCESS;
}
{
// PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimaryInfo = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
return STATUS_SUCCESS;
return STATUS_SUCCESS;
return STATUS_UNSUCCESSFUL;
}
NTSTATUS vboxWddmGhDisplayUpdateScreenPos(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, POINT *pVScreenPos)
{
return STATUS_SUCCESS;
return Status;
}
NTSTATUS vboxWddmGhDisplaySetInfo(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
{
if (offVram == VBOXVIDEOOFFSET_VOID)
return STATUS_INVALID_PARAMETER;
/*
* Set the current mode into the hardware.
*/
// NTSTATUS Status= vboxWddmDisplaySettingsQueryPos(pDevExt, VidPnSourceId, &pSource->VScreenPos);
// Assert(Status == STATUS_SUCCESS);
if (Status == STATUS_SUCCESS)
{
if (Status == STATUS_SUCCESS)
{
if (Status != STATUS_SUCCESS)
}
else
}
else
return Status;
}
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
{
{
return false;
}
return false;
if (Status != STATUS_SUCCESS)
return true;
}
#endif
{
#ifdef VBOX_WITH_VDMA
#endif
return NULL;
}
typedef enum
{
#ifdef VBOX_WITH_VDMA
#endif
VBOXWDDM_HGSMICMD_TYPE vboxWddmHgsmiGetCmdTypeFromOffset(PDEVICE_EXTENSION pDevExt, HGSMIOFFSET offCmd)
{
#ifdef VBOX_WITH_VDMA
return VBOXWDDM_HGSMICMD_TYPE_DMACMD;
#endif
return VBOXWDDM_HGSMICMD_TYPE_CTL;
return VBOXWDDM_HGSMICMD_TYPE_UNDEFINED;
}
{
if(!Reg)
return ERROR_INVALID_PARAMETER;
}
{
if(!Reg)
return ERROR_INVALID_PARAMETER;
}
{
if (Status == STATUS_SUCCESS)
{
if(Status == STATUS_SUCCESS)
return NO_ERROR;
}
/* fall-back to make the subsequent VBoxVideoCmnRegXxx calls treat the fail accordingly
* basically needed to make as less modifications to the current XPDM code as possible */
return ERROR_INVALID_PARAMETER;
}
{
switch (pInfo->BitsPerPlane)
{
case 32:
if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
{
return D3DDDIFMT_A8R8G8B8;
drprintf((__FUNCTION__": unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)\n", pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
}
else
{
}
break;
case 24:
if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
{
return D3DDDIFMT_R8G8B8;
drprintf((__FUNCTION__": unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)\n", pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
}
else
{
}
break;
case 16:
if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
{
return D3DDDIFMT_R5G6B5;
drprintf((__FUNCTION__": unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)\n", pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
}
else
{
}
break;
case 8:
if((pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && (pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
{
return D3DDDIFMT_P8;
}
else
{
}
break;
default:
break;
}
return D3DDDIFMT_UNKNOWN;
}
NTSTATUS vboxWddmPickResources(PDEVICE_EXTENSION pContext, PDXGK_DEVICE_INFO pDeviceInfo, PULONG pAdapterMemorySize)
{
if (DispiId == VBE_DISPI_ID2)
{
dprintf(("VBoxVideoWddm: found the VBE card\n"));
/*
* Write some hardware information to registry, so that
* it's visible in Windows property dialog.
*/
/*
* Query the adapter's memory size. It's a bit of a hack, we just read
* an ULONG from the data port without setting an index before.
*/
if (VBoxHGSMIIsSupported ())
{
/* @todo: verify resources */
{
{
{
case CmResourceTypePort:
break;
case CmResourceTypeInterrupt:
break;
case CmResourceTypeMemory:
break;
case CmResourceTypeDma:
break;
break;
case CmResourceTypeBusNumber:
break;
default:
break;
}
}
}
}
else
{
drprintf(("VBoxVideoWddm: HGSMI unsupported, returning err\n"));
/* @todo: report a better status */
}
}
else
{
drprintf(("VBoxVideoWddm:: VBE card not found, returning err\n"));
}
return Status;
}
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
{
}
#endif
}
/* driver callbacks */
)
{
/* The DxgkDdiAddDevice function should be made pageable. */
PAGED_CODE();
&cbRegKeyBuf);
if (Status == STATUS_SUCCESS)
{
pDevExt = (PDEVICE_EXTENSION)vboxWddmMemAllocZero(VBOXWDDM_ROUNDBOUND(sizeof (DEVICE_EXTENSION), 8) + cbRegKeyBuf);
if (pDevExt)
{
}
else
{
drprintf(("VBoxVideoWddm: ERROR, failed to create context\n"));
}
}
return Status;
}
)
{
/* The DxgkDdiStartDevice function should be made pageable. */
PAGED_CODE();
if ( ARGUMENT_PRESENT(MiniportDeviceContext) &&
)
{
/* 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)
* of the DXGK_DEVICE_INFO structure in the context block represented by MiniportDeviceContext. */
Status = pContext->u.primary.DxgkInterface.DxgkCbGetDeviceInformation (pContext->u.primary.DxgkInterface.DeviceHandle, &DeviceInfo);
if (Status == STATUS_SUCCESS)
{
if (Status == STATUS_SUCCESS)
{
/* Initialize VBoxGuest library, which is used for requests which go through VMMDev. */
VbglInit ();
/* Guest supports only HGSMI, the old VBVA via VMMDev is not supported. Old
* code will be ifdef'ed and later removed.
* The host will however support both old and new interface to keep compatibility
* with old guest additions.
*/
{
drprintf(("VBoxVideoWddm: using HGSMI\n"));
dprintf(("VBoxVideoWddm: sources(%d), children(%d)\n", *NumberOfVideoPresentSources, *NumberOfChildren));
pContext->cContexts3D = 0;
#ifdef VBOX_WITH_VIDEOHWACCEL
#endif
}
else
{
drprintf(("VBoxVideoWddm: HGSMI failed to initialize, returning err\n"));
/* @todo: report a better status */
}
}
else
{
}
}
else
{
drprintf(("VBoxVideoWddm: DxgkCbGetDeviceInformation failed Status(0x%x), returning err\n", Status));
}
}
else
{
drprintf(("VBoxVideoWddm: invalid parameter, returning err\n"));
}
return Status;
}
)
{
/* The DxgkDdiStopDevice function should be made pageable. */
PAGED_CODE();
/* do everything we did on DxgkDdiStartDevice in the reverse order */
#ifdef VBOX_WITH_VIDEOHWACCEL
#endif
if (RT_SUCCESS(rc))
{
/* revert back to the state we were right after the DxgkDdiAddDevice */
}
else
return Status;
}
)
{
/* DxgkDdiRemoveDevice should be made pageable. */
PAGED_CODE();
return STATUS_SUCCESS;
}
)
{
dfprintf(("==> "__FUNCTION__ ", context(0x%p), ctl(0x%x)\n", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
#if 0
switch (VideoRequestPacket->IoControlCode)
{
{
{
return TRUE;
}
pCaps->RedPhosphoreDecay = 0;
pCaps->GreenPhosphoreDecay = 0;
pCaps->BluePhosphoreDecay = 0;
pCaps->WhiteChromaticity_Y = 0;
pCaps->WhiteGamma = 0;
break;
}
#if 0
{
{
return TRUE;
}
break;
}
#endif
default:
}
#endif
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
#endif
#ifdef VBOX_WITH_VDMA
#endif
#ifdef VBOX_WITH_VIDEOHWACCEL
#endif
do
{
{
/* read the command offset */
if (offCmd != HGSMIOFFSET_VOID)
{
switch (enmType)
{
#ifdef VBOX_WITH_VDMA
pList = &DmaCmdList;
break;
#endif
break;
default:
}
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);
break;
}
#endif
#ifdef VBOX_WITH_VIDEOHWACCEL
case VBVA_VHWA_CMD:
{
break;
}
#endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
default:
}
}
}
}
}
else if (flags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
{
/* @todo: FIXME: implement !!! */
}
else
break;
} while (1);
if (!vboxSHGSMIListIsEmpty(&CtlList))
{
}
#ifdef VBOX_WITH_VDMA
if (!vboxSHGSMIListIsEmpty(&DmaCmdList))
{
}
#endif
if (!vboxSHGSMIListIsEmpty(&VhwaCmdList))
{
}
if (pDevExt->bNotifyDxDpc)
{
// Assert(bNeedDpc == TRUE);
// pDevExt->bNotifyDxDpc = TRUE;
// pDevExt->bSetNotifyDxDpc = FALSE;
}
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,
* still this allows to check that the host flags are correctly cleared after the ISR */
#endif
}
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
#endif
#ifdef VBOX_WITH_VIDEOHWACCEL
#endif
typedef struct VBOXWDDM_GETDPCDATA_CONTEXT
{
{
#ifdef VBOX_WITH_VDMA
#endif
#ifdef VBOX_WITH_VIDEOHWACCEL
#endif
return TRUE;
}
)
{
// dfprintf(("==> "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
/* get DPC data at IRQL */
&context,
0, /* IN ULONG MessageNumber */
&bRet);
{
int rc = VBoxSHGSMICommandPostprocessCompletion (&commonFromDeviceExt(pDevExt)->hgsmiAdapterHeap, &context.data.CtlList);
}
#ifdef VBOX_WITH_VDMA
{
int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.Vdma.CmdHeap, &context.data.DmaCmdList);
}
#endif
#ifdef VBOX_WITH_VIDEOHWACCEL
{
}
#endif
vboxVdmaDdiCmdHandleCompletedList(pDevExt, &pDevExt->DdiCmdQueue, &context.data.CompletedDdiCmdQueue);
// dfprintf(("<== "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
}
)
{
/* The DxgkDdiQueryChildRelations function should be made pageable. */
PAGED_CODE();
{
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 = HpdAwarenessInterruptible; /* ?? HpdAwarenessAlwaysConnected; */
}
return STATUS_SUCCESS;
}
)
{
/* The DxgkDdiQueryChildStatus should be made pageable. */
PAGED_CODE();
switch (ChildStatus->Type)
{
case StatusConnection:
dfprintf(("VBoxVideoWddm: StatusConnection\n"));
break;
case StatusRotation:
dfprintf(("VBoxVideoWddm: StatusRotation\n"));
break;
default:
break;
}
return Status;
}
)
{
/* The DxgkDdiQueryDeviceDescriptor should be made pageable. */
PAGED_CODE();
/* we do not support EDID */
return STATUS_MONITOR_NO_DESCRIPTOR;
}
)
{
/* The DxgkDdiSetPowerState function should be made pageable. */
PAGED_CODE();
/* @todo: */
// vboxVDbgBreakF();
return STATUS_SUCCESS;
}
)
{
return STATUS_SUCCESS;
}
)
{
/* DxgkDdiResetDevice can be called at any IRQL, so it must be in nonpageable memory. */
}
)
{
/* DxgkDdiUnload should be made pageable. */
PAGED_CODE();
}
)
{
return STATUS_NOT_SUPPORTED;
}
)
{
}
/**
* DxgkDdiQueryAdapterInfo
*/
{
/* The DxgkDdiQueryAdapterInfo should be made pageable. */
PAGED_CODE();
dfprintf(("==> "__FUNCTION__ ", context(0x%x), Query type (%d)\n", hAdapter, pQueryAdapterInfo->Type));
switch (pQueryAdapterInfo->Type)
{
case DXGKQAITYPE_DRIVERCAPS:
{
pCaps->PointerCaps.Value = 3; /* Monochrome , Color*/ /* MaskedColor == Value | 4, dosable for now */
pCaps->InterruptMessageNumber = 0;
pCaps->NumberOfSwizzlingRanges = 0;
pCaps->MaxOverlays = 0;
#ifdef VBOX_WITH_VIDEOHWACCEL
{
}
#endif
/* ? pCaps->FlipCaps.FlipOnVSyncWithNoWait = 1; */
/* we might need it for Aero.
* Setting this flag means we support DeviceContext, i.e.
* DxgkDdiCreateContext and DxgkDdiDestroyContext
*/
/* @todo: this corelates with pCaps->SchedulingCaps.MultiEngineAware */
/* @todo: this corelates with pCaps->SchedulingCaps.MultiEngineAware */
break;
}
case DXGKQAITYPE_QUERYSEGMENT:
{
/* no need for DXGK_QUERYSEGMENTIN as it contains AGP aperture info, which (AGP aperture) we do not support
* DXGK_QUERYSEGMENTIN *pQsIn = (DXGK_QUERYSEGMENTIN*)pQueryAdapterInfo->pInputData; */
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
# define VBOXWDDM_SEGMENTS_COUNT 2
#else
# define VBOXWDDM_SEGMENTS_COUNT 1
#endif
if (!pQsOut->pSegmentDescriptor)
{
/* we are requested to provide the number of segments we support */
}
{
}
else
{
/* we are requested to provide segment information */
/* make sure the size is page aligned */
/* @todo: need to setup VBVA buffers and adjust the mem size here */
pDr->pBankRangeTable = 0;
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
++pDr;
/* create cpu-invisible segment of the same size */
/* make sure the size is page aligned */
/* @todo: need to setup VBVA buffers and adjust the mem size here */
pDr->pBankRangeTable = 0;
#endif
pQsOut->PagingBufferSegmentId = 0;
}
break;
}
{
#ifdef VBOX_WITH_VIDEOHWACCEL
{
}
#endif
}
else
{
}
break;
default:
break;
}
return Status;
}
/**
* DxgkDdiCreateDevice
*/
{
/* DxgkDdiCreateDevice should be made pageable. */
PAGED_CODE();
// else
// {
// AssertBreakpoint(); /* we do not support custom contexts for now */
// 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)
{
{
}
}
else
if (pAllocation)
{
if (pResource)
{
}
}
return pAllocation;
}
void vboxWddmAllocationDeleteFromResource(PVBOXWDDM_RESOURCE pResource, PVBOXWDDM_ALLOCATION pAllocation)
{
if (pResource)
{
}
else
{
}
}
{
PAGED_CODE();
switch (pAllocation->enmType)
{
{
if (pAllocation->bAssigned)
{
/* @todo: do we need to notify host? */
vboxWddmAssignPrimary(pDevExt, &pDevExt->aSources[pAllocation->SurfDesc.VidPnSourceId], NULL, pAllocation->SurfDesc.VidPnSourceId);
}
break;
}
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
{
if (pAllocation->bAssigned)
{
/* @todo: do we need to notify host? */
vboxWddmAssignShadow(pDevExt, &pDevExt->aSources[pAllocation->SurfDesc.VidPnSourceId], NULL, pAllocation->SurfDesc.VidPnSourceId);
}
break;
}
#endif
//#ifdef VBOX_WITH_VIDEOHWACCEL
// case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
// {
// if (pAllocation->fRcFlags.Overlay)
// {
// vboxVhwaHlpDestroyOverlay(pDevExt, pAllocation);
// }
// break;
// }
//#endif
{
break;
}
default:
break;
}
if (pSwapchain)
{
}
return STATUS_SUCCESS;
}
NTSTATUS vboxWddmCreateAllocation(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_RESOURCE pResource, uint32_t iIndex, DXGK_ALLOCATIONINFO* pAllocationInfo)
{
PAGED_CODE();
{
if (pAllocation)
{
pAllocationInfo->Alignment = 0;
switch (pAllocInfo->enmType)
{
{
switch (pAllocInfo->enmType)
{
#if 0 //defined(VBOXWDDM_RENDER_FROM_SHADOW)
#endif
#ifndef VBOXWDDM_RENDER_FROM_SHADOW
#endif
break;
#ifdef VBOX_WITH_VIDEOHWACCEL
{
/* actually we can not "properly" issue create overlay commands to the host here
* because we do not know source VidPn id here, i.e.
* the primary which is supposed to be overlayed,
* however we need to get some info like pitch & size from the host here */
if (RT_SUCCESS(rc))
{
}
else
}
else
#endif
{
{
}
}
break;
break;
}
if (Status == STATUS_SUCCESS)
{
}
break;
}
{
switch (pAllocInfo->enmSynchType)
{
Status = ObReferenceObjectByHandle(pAllocInfo->hSynch, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
NULL);
break;
Status = ObReferenceObjectByHandle(pAllocInfo->hSynch, EVENT_MODIFY_STATE, *ExSemaphoreObjectType, UserMode,
NULL);
break;
Status == STATUS_SUCCESS;
break;
default:
break;
}
break;
}
default:
break;
}
if (Status != STATUS_SUCCESS)
}
else
{
}
}
else
{
drprintf((__FUNCTION__ ": ERROR: PrivateDriverDataSize(%d) less than header size(%d)\n", pAllocationInfo->PrivateDriverDataSize, sizeof (VBOXWDDM_ALLOCINFO)));
}
return Status;
}
{
/* DxgkDdiCreateAllocation should be made pageable. */
PAGED_CODE();
{
{
// Assert(pRcInfo->RcDesc.VidPnSourceId < pDevExt->u.primary.cDisplays);
pResource = (PVBOXWDDM_RESOURCE)vboxWddmMemAllocZero(RT_OFFSETOF(VBOXWDDM_RESOURCE, aAllocations[pRcInfo->cAllocInfos]));
if (pResource)
{
}
else
}
else
/* @todo: Implement Resource Data Handling */
}
if (Status == STATUS_SUCCESS)
{
{
if (Status != STATUS_SUCCESS)
{
/* note: i-th allocation is expected to be cleared in a fail handling code above */
for (UINT j = 0; j < i; ++j)
{
vboxWddmDestroyAllocation(pDevExt, (PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation);
}
}
}
}
return Status;
}
{
/* DxgkDdiDestroyAllocation should be made pageable. */
PAGED_CODE();
if (pRc)
{
}
{
}
if (pRc)
{
}
return Status;
}
/**
* DxgkDdiDescribeAllocation
*/
{
memset (&pDescribeAllocation->MultisampleMethod, 0, sizeof (pDescribeAllocation->MultisampleMethod));
return STATUS_SUCCESS;
}
/**
* DxgkDdiGetStandardAllocationDriverData
*/
{
/* DxgkDdiGetStandardAllocationDriverData should be made pageable. */
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;
}
break;
}
{
UINT bpp = vboxWddmCalcBitsPerPixel(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format);
if (bpp != 0)
{
UINT Pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, bpp);
/* @todo: need [d/q]word align?? */
{
pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, pAllocInfo->SurfDesc.bpp);
}
}
else
{
drprintf((__FUNCTION__ ": Invalid format (%d)\n", pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format));
}
break;
}
{
{
pAllocInfo->SurfDesc.format = D3DDDIFMT_X8R8G8B8; /* staging has always always D3DDDIFMT_X8R8G8B8 */
pAllocInfo->SurfDesc.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Width, pAllocInfo->SurfDesc.bpp);
}
break;
}
//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
// case D3DKMDT_STANDARDALLOCATION_GDISURFACE:
//# error port to Win7 DDI
// break;
//#endif
default:
drprintf((__FUNCTION__ ": Invalid allocation type (%d)\n", pGetStandardAllocationDriverData->StandardAllocationType));
break;
}
return Status;
}
{
return STATUS_SUCCESS;
}
{
return STATUS_SUCCESS;
}
{
/* DxgkDdiPatch should be made pageable. */
PAGED_CODE();
/* Value == 2 is Present
* Value == 4 is RedirectedPresent
* we do not expect any other flags to be set here */
// Assert(pPatch->Flags.Value == 2 || pPatch->Flags.Value == 4);
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);
switch (pPrivateDataBase->enmCmd)
{
{
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;
//
// pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart + 1];
// Assert(pPatchList->AllocationIndex == DXGK_PRESENT_DESTINATION_INDEX);
// Assert(pPatchList->PatchOffset == 4);
// const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
// Assert(pDstAllocationList->SegmentId);
// pPrivateData->DstAllocInfo.segmentIdAlloc = pDstAllocationList->SegmentId;
// pPrivateData->DstAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pDstAllocationList->PhysicalAddress.QuadPart;
break;
}
{
const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
const DXGK_ALLOCATIONLIST *pSrcAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
break;
}
{
const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
const DXGK_ALLOCATIONLIST *pSrcAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
break;
}
{
const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
break;
}
case VBOXVDMACMD_TYPE_DMA_NOP:
break;
{
for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
{
if (pAllocationList->SegmentId)
{
DXGK_ALLOCATIONLIST *pAllocation2Patch = (DXGK_ALLOCATIONLIST*)(pPrivateBuf + pPatchList->PatchOffset);
}
}
break;
}
default:
{
for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
{
if (pAllocationList->SegmentId)
{
Assert(pPatchList->PatchOffset < (pPatch->DmaBufferSubmissionEndOffset - pPatch->DmaBufferSubmissionStartOffset));
*((VBOXVIDEOOFFSET*)(pBuf+pPatchList->PatchOffset)) = (VBOXVIDEOOFFSET)pAllocationList->PhysicalAddress.QuadPart;
}
else
{
/* sanity */
Assert(i == 0);
}
}
break;
}
}
}
else
{
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.MessageNumber = 0;
&context,
0, /* IN ULONG MessageNumber */
&bRet);
return Status;
}
{
if (Status == STATUS_SUCCESS)
{
{
}
if (submStatus != STATUS_SUCCESS)
{
{
}
}
}
else
{
}
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]));
}
else
{
}
return Status;
}
#ifdef VBOX_WITH_VDMA
DECLCALLBACK(VOID) vboxWddmDmaCompleteChromiumCmd(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
{
{
if (!pBufCmd->u32GuesData)
{
/* signal completion */
switch (pAlloc->enmSynchType)
{
break;
3,
1,
FALSE);
break;
break;
default:
Assert(0);
}
}
}
}
#endif
{
/* DxgkDdiSubmitCommand runs at dispatch, should not be pageable. */
// dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
/* the DMA command buffer is located in system RAM, the host will need to pick it from there */
//BufInfo.fFlags = 0; /* see VBOXVDMACBUF_FLAG_xx */
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);
switch (pPrivateDataBase->enmCmd)
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
{
PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateDataBase;
if (!cUnlockedVBVADisabled)
else
{
}
/* get DPC data at IRQL */
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
break;
}
#endif
{
VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
{
{
{
{
{
{
{
{
}
}
else
if (!cUnlockedVBVADisabled)
else
{
}
}
else
{
}
{
Status = vboxWddmSubmitBltCmd(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, pBlt, fBltFlags);
}
break;
}
{
{
Status = vboxWddmSubmitBltCmd(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, pBlt, fBltFlags);
}
break;
}
default:
break;
}
}
break;
}
{
break;
}
{
break;
}
default:
break;
}
if (bComplete)
{
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
}
break;
}
{
#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)
{
/* @todo: try flushing.. */
return STATUS_INSUFFICIENT_RESOURCES;
}
// vboxVdmaCBufDrCreate zero initializes the pDr
pHdr->u32CmdSpecific = 0;
{
}
vboxVdmaDdiCmdInit(pDdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxWddmDmaCompleteChromiumCmd, pDr);
if (Status == STATUS_SUCCESS)
{
}
else
{
}
#else
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
#endif
break;
}
{
&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);
}
else
{
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
}
break;
}
{
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]));
}
else
{
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
}
break;
}
case VBOXVDMACMD_TYPE_DMA_NOP:
{
Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
break;
}
default:
{
#if 0 //def VBOX_WITH_VDMA
VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
if (!pDr)
{
/* @todo: try flushing.. */
return STATUS_INSUFFICIENT_RESOURCES;
}
// vboxVdmaCBufDrCreate zero initializes the pDr
//pDr->fFlags = 0;
pDr->cbBuf = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset;
if (pPrivateData)
// else // vboxVdmaCBufDrCreate zero initializes the pDr
// pDr->u64GuestContext = NULL;
pDr->Location.phBuf = pSubmitCommand->DmaBufferPhysicalAddress.QuadPart + pSubmitCommand->DmaBufferSubmissionStartOffset;
#endif
break;
}
}
// dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", hAdapter));
return Status;
}
{
/* @todo: fixme: implement */
return STATUS_SUCCESS;
}
/*
* DxgkDdiBuildPagingBuffer
*/
{
/* DxgkDdiBuildPagingBuffer should be made pageable. */
PAGED_CODE();
/* @todo: */
switch (pBuildPagingBuffer->Operation)
{
case DXGK_OPERATION_TRANSFER:
{
// pBuildPagingBuffer->pDmaBuffer = (uint8_t*)pBuildPagingBuffer->pDmaBuffer + VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_BPB_TRANSFER);
break;
}
case DXGK_OPERATION_FILL:
{
// pBuildPagingBuffer->pDmaBuffer = (uint8_t*)pBuildPagingBuffer->pDmaBuffer + VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_BPB_FILL);
break;
}
{
// AssertBreakpoint();
break;
}
default:
{
break;
}
}
return Status;
}
)
{
/* @todo: fixme: implement */
return STATUS_SUCCESS;
}
BOOL vboxWddmPointerCopyColorData(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVIDEO_POINTER_ATTRIBUTES pPointerAttributes)
{
/* Format of "hardware" pointer is:
* 1 bpp AND mask with byte aligned scanlines,
* B G R A bytes of XOR mask that starts on the next 4 byte aligned offset after AND mask.
*
* If fl & SPS_ALPHA then A bytes contain alpha channel information.
* Otherwise A bytes are undefined (but will be 0).
*
*/
// Make sure the new pointer isn't too big to handle,
// strip the size to 64x64 if necessary
/* Size of AND mask in bytes */
/* Pointer to XOR mask is 4-bytes aligned */
{
drprintf((__FUNCTION__": VBOXWDDM_POINTER_ATTRIBUTES_SIZE(%d) < cbPointerAttributes(%d)\n", VBOXWDDM_POINTER_ATTRIBUTES_SIZE, cbPointerAttributes));
return FALSE;
}
/* Init AND mask to 1 */
/*
* Emulate AND mask to provide viewable mouse pointer for
* hardware which does not support alpha channel.
*/
{
{
if (bitmask == 0)
{
bitmask = 0x80;
}
{
}
}
// Point to next source and dest scans
}
/*
* pso is 32 bit BGRX bitmap. Copy it to Pixels
*/
{
/* 32 bit bitmap is being copied */
/* Point to next source and dest scans */
}
return TRUE;
}
BOOL vboxWddmPointerCopyMonoData(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVIDEO_POINTER_ATTRIBUTES pPointerAttributes)
{
// Make sure the new pointer isn't too big to handle,
// strip the size to 64x64 if necessary
/* Size of AND mask in bytes */
/* Pointer to XOR mask is 4-bytes aligned */
/* Init AND mask to 1 */
/*
* Copy AND mask.
*/
{
// Point to next source and dest scans
}
{
{
if (bitmask == 0)
{
bitmask = 0x80;
}
{
}
else
{
}
}
// Point to next source and dest scans
}
return TRUE;
}
static BOOLEAN vboxVddmPointerShapeToAttributes(CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape, PVBOXWDDM_POINTER_INFO pPointerInfo)
{
/* pPointerAttributes maintains the visibility state, clear all except visibility */
{
{
}
else
{
return FALSE;
}
}
{
{
}
else
{
return FALSE;
}
}
else
{
drprintf((__FUNCTION__": unsupported pointer type Flags.Value(0x%x)\n", pSetPointerShape->Flags.Value));
return FALSE;
}
/*
* The hot spot coordinates and alpha flag will be encoded in the pPointerAttributes::Enable field.
* High word will contain hot spot info and low word - flags.
*/
return TRUE;
}
{
// dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
/* mouse integration is ON */
PVBOXWDDM_POINTER_INFO pPointerInfo = &pDevExt->aSources[pSetPointerPosition->VidPnSourceId].PointerInfo;
{
{
}
}
else
{
{
}
}
if (bNotifyVisibility && vboxQueryHostWantsAbsolute())
{
// tell the host to use the guest's pointer
/* Visible and No Shape means Show the pointer.
* It is enough to init only this field.
*/
}
// dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
return STATUS_SUCCESS;
}
{
// dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
if (vboxQueryHostWantsAbsolute())
{
/* mouse integration is ON */
PVBOXWDDM_POINTER_INFO pPointerInfo = &pDevExt->aSources[pSetPointerShape->VidPnSourceId].PointerInfo;
/* @todo: to avoid extra data copy and extra heap allocation,
* need to maintain the pre-allocated HGSMI buffer and convert the data directly to it */
{
if (vboxUpdatePointerShape (pDevExt, &pPointerInfo->Attributes.data, VBOXWDDM_POINTER_ATTRIBUTES_SIZE))
else
{
}
}
}
// dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
return Status;
}
{
/* @todo: fixme: implement */
return STATUS_SUCCESS;
}
/* the lpRgnData->Buffer comes to us as RECT
* to avoid extra memcpy we cast it to PRTRECT assuming
* they are identical */
{
PAGED_CODE();
// dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
{
switch (pEscapeHdr->escapeCode)
{
{
{
}
else
break;
}
case VBOXESC_SETVISIBLEREGION:
{
/* the lpRgnData->Buffer comes to us as RECT
* to avoid extra memcpy we cast it to PRTRECT assuming
* they are identical
* see AssertCompile's above */
int rc;
{
/*
* Inform the host about the visible region
*/
if (RT_SUCCESS(rc))
{
if (!RT_SUCCESS(rc))
{
}
}
else
{
}
}
else
{
drprintf((__FUNCTION__": VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)\n", cbRects, lpRgnData->rdh.nCount));
}
break;
}
case VBOXESC_ISVRDPACTIVE:
/* @todo: implement */
break;
case VBOXESC_SCREENLAYOUT:
{
{
{
{
}
}
break;
}
else
{
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);
break;
}
case VBOXESC_REINITVIDEOMODES:
break;
case VBOXESC_DBGPRINT:
{
/* use RT_OFFSETOF instead of sizeof since sizeof will give an aligned size that might
* be bigger than the VBOXDISPIFESCAPE_DBGPRINT with a data containing just a few chars */
/* only do DbgPrint when pEscape->PrivateDriverDataSize > RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[1])
* since == RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[1]) means the buffer contains just \0,
* i.e. no need to print it */
{
/* ensure the last char is \0*/
}
break;
}
default:
Assert(0);
break;
}
}
else
{
drprintf((__FUNCTION__": pEscape->PrivateDriverDataSize(%d) < (%d)\n", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE)));
}
// dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
return Status;
}
)
{
return STATUS_SUCCESS;
}
{
/* @todo: fixme: implement */
return STATUS_SUCCESS;
}
)
{
/* The DxgkDdiIsSupportedVidPn should be made pageable. */
PAGED_CODE();
NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pIsSupportedVidPnArg->hDesiredVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
if (Status == STATUS_SUCCESS)
{
Status = pVidPnInterface->pfnGetTopology(pIsSupportedVidPnArg->hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
if (Status == STATUS_SUCCESS)
{
Status = vboxVidPnCheckTopology(pIsSupportedVidPnArg->hDesiredVidPn, hVidPnTopology, pVidPnTopologyInterface, &bSupported);
{
{
id,
if (Status == STATUS_SUCCESS)
{
Status = vboxVidPnCheckSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnSourceModeSet, pVidPnSourceModeSetInterface, &bSupported);
pVidPnInterface->pfnReleaseSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnSourceModeSet);
break;
}
else if (Status == STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE)
{
drprintf(("VBoxVideoWddm: Warning: pfnAcquireSourceModeSet returned STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE, continuing\n"));
}
else
{
drprintf(("VBoxVideoWddm: pfnAcquireSourceModeSet failed Status(0x%x)\n"));
break;
}
}
{
{
id, /*__in CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId */
if (Status == STATUS_SUCCESS)
{
Status = vboxVidPnCheckTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnTargetModeSet, pVidPnTargetModeSetInterface, &bSupported);
pVidPnInterface->pfnReleaseTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnTargetModeSet);
break;
}
else if (Status == STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE)
{
drprintf(("VBoxVideoWddm: Warning: pfnAcquireSourceModeSet returned STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE, continuing\n"));
}
else
{
drprintf(("VBoxVideoWddm: pfnAcquireSourceModeSet failed Status(0x%x)\n"));
break;
}
}
}
}
}
else
{
drprintf(("VBoxVideoWddm: pfnGetTopology failed Status(0x%x)\n"));
}
}
else
{
drprintf(("VBoxVideoWddm: DxgkCbQueryVidPnInterface failed Status(0x%x)\n"));
}
return Status;
}
)
{
/* The DxgkDdiRecommendFunctionalVidPn should be made pageable. */
PAGED_CODE();
int iPreferredMode;
bool bFreeModes = false;
true, /* bool bRebuildTable*/
&pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
&cModes, /* uint32_t * pcModes */
&iPreferredMode, /* uint32_t * pPreferrableMode*/
&pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
&cResolutions /* uint32_t * pcResolutions */);
if (Status == STATUS_SUCCESS)
else if (Status == STATUS_BUFFER_TOO_SMALL)
{
pModeInfos = (VIDEO_MODE_INFORMATION*)vboxWddmMemAlloc(sizeof (VIDEO_MODE_INFORMATION) * cModeInfos);
if (pModeInfos)
{
bFreeModes = true;
if (Status != STATUS_SUCCESS)
drprintf((__FUNCTION__": second call to VBoxWddmGetModesForResolution failed Status(0x%x), cModeInfos(%d), cModeInfos2(%d)\n", Status, cModeInfos, cModeInfos2));
}
}
else
if (Status == STATUS_SUCCESS)
{
{
if (Status != STATUS_SUCCESS)
{
break;
}
}
if (Status == STATUS_SUCCESS)
{
Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
if (Status == STATUS_SUCCESS)
{
Assert (iPreferredModeInfo >= 0);
Status = vboxVidPnCreatePopulateVidPnFromLegacy(pDevExt, pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, pVidPnInterface,
&Resolution, 1);
if (Status != STATUS_SUCCESS)
}
else
}
}
if (bFreeModes)
return Status;
}
)
{
/* The DxgkDdiEnumVidPnCofuncModality function should be made pageable. */
PAGED_CODE();
NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pEnumCofuncModalityArg->hConstrainingVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
if (Status == STATUS_SUCCESS)
{
NTSTATUS Status = pVidPnInterface->pfnGetTopology(pEnumCofuncModalityArg->hConstrainingVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
if (Status == STATUS_SUCCESS)
{
VBOXVIDPNCOFUNCMODALITY CbContext = {0};
false, /* bool bRebuildTable*/
if (Status == STATUS_SUCCESS)
{
if (Status != STATUS_SUCCESS)
}
else
}
else
}
else
return Status;
}
)
{
/* The DxgkDdiSetVidPnSourceAddress function should be made pageable. */
PAGED_CODE();
Status= vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceAddress->VidPnSourceId, &pSource->VScreenPos);
{
{
}
else
if (pAllocation)
{
// Assert(pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE);
if (
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
/* this is the case of full-screen d3d, ensure we notify host */
#endif
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
/* to ensure the resize request gets issued in case we exit a full-screen D3D mode */
#else
/* should not generally happen, but still inform host*/
if (Status != STATUS_SUCCESS)
#endif
}
}
else
{
}
}
else
{
drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceAddress->VidPnSourceId, pDevExt->u.primary.cDisplays));
}
return Status;
}
)
{
/* DxgkDdiSetVidPnSourceVisibility should be made pageable. */
PAGED_CODE();
Status= vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceVisibility->VidPnSourceId, &pSource->VScreenPos);
{
if (pAllocation)
{
{
if (pAllocation->bVisible)
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
if (/* this is the case of full-screen d3d, ensure we notify host */
)
#endif
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
/* to ensure the resize request gets issued in case we exit a full-screen D3D mode */
#else
if (Status != STATUS_SUCCESS)
#endif
}
}
#ifdef VBOX_WITH_VDMA
else
{
}
#endif
}
}
else
{
}
}
else
{
drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceVisibility->VidPnSourceId, pDevExt->u.primary.cDisplays));
}
return Status;
}
)
{
NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
if (Status == STATUS_SUCCESS)
{
{
if (Status != STATUS_SUCCESS)
}
else
{
/* clear all current primaries */
{
}
NTSTATUS Status = pVidPnInterface->pfnGetTopology(pCommitVidPnArg->hFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
if (Status == STATUS_SUCCESS)
{
VBOXVIDPNCOMMIT CbContext = {0};
if (Status == STATUS_SUCCESS)
{
if (Status != STATUS_SUCCESS)
}
else
}
else
}
if (Status == STATUS_SUCCESS)
{
}
}
else
return Status;
}
)
{
return STATUS_SUCCESS;
}
)
{
false, /* bool bRebuildTable*/
&pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
&cModes, /* uint32_t * pcModes */
&iPreferredMode, /* uint32_t * pPreferrableMode*/
&pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
&cResolutions /* uint32_t * pcResolutions */);
for (uint32_t i = 0; i < cResolutions; i++)
{
if (Status == STATUS_SUCCESS)
{
&pResolutions[i],
FALSE);
if (Status == STATUS_SUCCESS)
{
if (Status == STATUS_SUCCESS)
continue;
}
/* error has occured, release & break */
break;
}
}
return Status;
}
)
{
}
{
if (pTarget->HeightTotal)
{
++pTarget->ScanLineState;
pTarget->ScanLineState = 0;
}
else
{
pGetScanLine->ScanLine = 0;
}
return STATUS_SUCCESS;
}
{
return STATUS_SUCCESS;
}
)
{
// AssertBreakpoint();
/* @todo: STATUS_NOT_IMPLEMENTED ?? */
return STATUS_SUCCESS;
}
{
if (pOverlay)
{
int rc = vboxVhwaHlpOverlayCreate(pDevExt, pCreateOverlay->VidPnSourceId, &pCreateOverlay->OverlayInfo, pOverlay);
if (RT_SUCCESS(rc))
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
/* ignore primary update failure */
#endif
}
else
{
}
}
else
return Status;
}
{
/* DxgkDdiDestroyDevice should be made pageable. */
PAGED_CODE();
return STATUS_SUCCESS;
}
/*
* DxgkDdiOpenAllocation
*/
{
/* DxgkDdiOpenAllocation should be made pageable. */
PAGED_CODE();
{
{
}
else
}
if (Status == STATUS_SUCCESS)
{
{
PVBOXWDDM_OPENALLOCATION pOa = (PVBOXWDDM_OPENALLOCATION)vboxWddmMemAllocZero(sizeof (VBOXWDDM_OPENALLOCATION));
if (pRcInfo)
{
#ifdef VBOX_WITH_VIDEOHWACCEL
{
{
if (pAllocation)
{
/* we have queried host for some surface info, like pitch & size,
* need to return it back to the UMD (User Mode Drive) */
/* success, just contionue */
continue;
}
else
}
else
/* we are here in case of error */
for (UINT j = 0; j < i; ++j)
{
PVBOXWDDM_OPENALLOCATION pOa2Free = (PVBOXWDDM_OPENALLOCATION)pInfo2Free->hDeviceSpecificAllocation;
}
}
#endif
}
}
}
return Status;
}
{
/* DxgkDdiCloseAllocation should be made pageable. */
PAGED_CODE();
{
}
return STATUS_SUCCESS;
}
{
{
drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)\n",
/* @todo: can this actually happen? what status to return? */
return STATUS_INVALID_PARAMETER;
}
{
Assert(0);
drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)\n",
/* @todo: can this actually happen? what status to return? */
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;
}
{
pPLL->AllocationIndex = i;
++pPLL;
++pSubmInfo;
++pSubmUmInfo;
}
break;
}
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);
break;
}
default:
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
{
}
{
return (VBOXVDMA_PIXEL_FORMAT)format;
}
DECLINLINE(VOID) vboxWddmSurfDescFromAllocation(PVBOXWDDM_ALLOCATION pAllocation, PVBOXVDMA_SURF_DESC pDesc)
{
}
#endif
{
}
#if 0
DECLINLINE(bool) vboxWddmCheckForVisiblePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
{
return false;
if (!pAllocation->bVisible)
return false;
return false;
return false;
return true;
}
#endif
/**
* DxgkDdiPresent
*/
{
PAGED_CODE();
// dfprintf(("==> "__FUNCTION__ ", hContext(0x%x)\n", hContext));
{
drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR (%d)\n", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)));
/* @todo: can this actually happen? what status tu return? */
return STATUS_INVALID_PARAMETER;
}
PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)pPresent->pDmaBufferPrivateData;
#define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof(RECT)
{
if (pSrcAlloc)
{
if (pDstAlloc)
{
do
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
#if 0
#else
{
}
#endif
/* issue VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE ONLY in case there are no 3D contexts currently
* otherwise we would need info about all rects being updated on primary for visible rect reporting */
if (!cContexts3D)
{
{
{
#ifdef VBOX_WITH_VIDEOHWACCEL
#endif
{
{
if (pPresent->SubRectCnt)
{
{
}
}
else
pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY);
PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateData;
/* we do not know the shadow address yet, perform dummy DMA cycle */
// vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst);
break;
}
else
{
break;
}
}
}
}
}
/* we're here because this is NOT a shadow->primary update
* or because there are d3d contexts and we need to report visible rects
* or because we have overlays active and we need a special handling for primary */
#endif
{
memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
}
else
{
memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
cbCmd -= cbFitingRects;
}
break;
#ifdef VBOX_WITH_VDMA
if (cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE())
{
{
// pPresent->pPatchLocationListOut->PatchOffset = 0;
// ++pPresent->pPatchLocationListOut;
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);
pCmd->u32CmdSpecific = 0;
UINT i = 0;
for (; i < pPresent->SubRectCnt; ++i)
{
if (cbCmd < sizeof (VBOXVDMA_RECTL))
{
Assert(i);
pPresent->MultipassOffset += i;
break;
}
vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
cbCmd -= sizeof (VBOXVDMA_RECTL);
}
Assert(i);
pTransfer->cDstSubRects = i;
pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR);
}
else
{
drprintf((__FUNCTION__": unsupported format conversion from(%d) to (%d)\n",pSrcAlloc->SurfDesc.format, pDstAlloc->SurfDesc.format));
}
}
else
{
/* this should not happen actually */
}
#endif
} while(0);
}
else
{
/* this should not happen actually */
drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
}
}
else
{
/* this should not happen actually */
drprintf((__FUNCTION__": failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
}
#if 0
if (cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE())
{
if (pSrcAlloc)
{
if (pDstAlloc)
{
{
// pPresent->pPatchLocationListOut->PatchOffset = 0;
// ++pPresent->pPatchLocationListOut;
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);
pCmd->u32CmdSpecific = 0;
UINT i = 0;
for (; i < pPresent->SubRectCnt; ++i)
{
if (cbCmd < sizeof (VBOXVDMA_RECTL))
{
Assert(i);
pPresent->MultipassOffset += i;
break;
}
vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
cbCmd -= sizeof (VBOXVDMA_RECTL);
}
Assert(i);
pTransfer->cDstSubRects = i;
pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATEDATA_HDR);
}
else
{
drprintf((__FUNCTION__": unsupported format conversion from(%d) to (%d)\n",pSrcAlloc->SurfDesc.format, pDstAlloc->SurfDesc.format));
}
}
else
{
/* this should not happen actually */
drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
}
}
else
{
/* this should not happen actually */
drprintf((__FUNCTION__": failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
}
}
else
{
/* this should not happen actually */
}
#endif
}
{
if (pSrcAlloc)
{
}
else
{
/* this should not happen actually */
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)
{
{
}
else
{
memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
cbCmd -= cbFitingRects;
}
}
else
{
/* this should not happen actually */
drprintf((__FUNCTION__": failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
}
}
else
{
}
// dfprintf(("<== "__FUNCTION__ ", hContext(0x%x), Status(0x%x)\n", hContext, Status));
return Status;
}
{
if (RT_SUCCESS(rc))
{
}
else
return Status;
}
{
if (RT_FAILURE(rc))
return Status;
}
{
if (RT_SUCCESS(rc))
else
return Status;
}
/**
* DxgkDdiCreateContext
*/
{
/* DxgkDdiCreateContext should be made pageable */
PAGED_CODE();
if (pContext)
{
{
{
}
}
else
{
{
PVBOXWDDM_CREATECONTEXT_INFO pInfo = (PVBOXWDDM_CREATECONTEXT_INFO)pCreateContext->pPrivateDriverData;
{
{
if (Status == STATUS_SUCCESS)
{
Status = vboxVideoCmCtxAdd(&pDevice->pAdapter->CmMgr, &pContext->CmContext, (HANDLE)pInfo->hUmEvent, pInfo->u64UmInfo);
if (Status == STATUS_SUCCESS)
{
// Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
// ExAcquireFastMutex(&pDevExt->ContextMutex);
// ExReleaseFastMutex(&pDevExt->ContextMutex);
}
else
{
}
}
break;
}
{
break;
}
default:
{
Assert(0);
break;
}
}
}
}
if (Status == STATUS_SUCCESS)
{
//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
//# error port to Win7 DDI
// //pCreateContext->ContextInfo.DmaBufferAllocationGroup = ???;
//#endif // DXGKDDI_INTERFACE_VERSION
}
else
}
else
return Status;
}
{
{
// ExAcquireFastMutex(&pDevExt->ContextMutex);
// RemoveEntryList(&pContext->ListEntry);
// ExReleaseFastMutex(&pDevExt->ContextMutex);
}
if (Status == STATUS_SUCCESS)
{
}
return Status;
}
)
{
return STATUS_NOT_IMPLEMENTED;
}
)
{
return STATUS_SUCCESS;
}
{
return STATUS_SUCCESS;
}
)
{
PAGED_CODE();
if (! ARGUMENT_PRESENT(DriverObject) ||
{
return STATUS_INVALID_PARAMETER;
}
// Fill in the DriverInitializationData structure and call DxgkInitialize()
DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = DxgkDdiGetStandardAllocationDriverData;
DriverInitializationData.DxgkDdiSetDisplayPrivateDriverFormat = DxgkDdiSetDisplayPrivateDriverFormat;
//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
//# error port to Win7 DDI
// DriverInitializationData.DxgkDdiRenderKm = DxgkDdiRenderKm;
// DriverInitializationData.DxgkDdiRestartFromTimeout = DxgkDdiRestartFromTimeout;
// DriverInitializationData.DxgkDdiSetVidPnSourceVisibility = DxgkDdiSetVidPnSourceVisibility;
// DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = DxgkDdiUpdateActiveVidPnPresentPath;
// DriverInitializationData.DxgkDdiQueryVidPnHWCapability = DxgkDdiQueryVidPnHWCapability;
//#endif
return DxgkInitialize(DriverObject,
}